0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / GccAna / GccAna_Circ2d3Tan_3.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <ElCLib.hxx>
17 #include <GccAna_Circ2d3Tan.hxx>
18 #include <GccAna_Lin2dBisec.hxx>
19 #include <GccEnt_BadQualifier.hxx>
20 #include <GccEnt_QualifiedCirc.hxx>
21 #include <GccEnt_QualifiedLin.hxx>
22 #include <gp_Circ2d.hxx>
23 #include <gp_Dir2d.hxx>
24 #include <gp_Lin2d.hxx>
25 #include <gp_Pnt2d.hxx>
26 #include <IntAna2d_AnaIntersection.hxx>
27 #include <IntAna2d_IntPoint.hxx>
28 #include <Standard_OutOfRange.hxx>
29 #include <StdFail_NotDone.hxx>
30 #include <TColStd_Array1OfReal.hxx>
31
32 //=========================================================================
33 //   Creation of a circle tangent to three straight lines.                +
34 //   Create Bissectrices at Qualified1 and Qualified2 and                 +
35 //          Bissectrices at Qualified1 and Qualified3.                    +
36 //   Intersect bissectrices calculated in this way ==> Center points      +
37 //   Choose the center point that corresponds to qualifiers and           +
38 //   construct the solution of radius equal to the distance between the   +
39 //   chosen center point and straight line Qualified1.                               +
40 //=========================================================================
41 GccAna_Circ2d3Tan::
42    GccAna_Circ2d3Tan (const GccEnt_QualifiedLin& Qualified1,
43                       const GccEnt_QualifiedLin& Qualified2,
44                       const GccEnt_QualifiedLin& Qualified3,
45                       const Standard_Real
46                      ):
47
48 //=========================================================================
49 //   Initialization of fields.                                           +
50 //=========================================================================
51
52    cirsol(1,4)     ,
53    qualifier1(1,4) ,
54    qualifier2(1,4) ,
55    qualifier3(1,4) ,
56    TheSame1(1,4)   ,
57    TheSame2(1,4)   ,
58    TheSame3(1,4)   ,
59    pnttg1sol(1,4)  ,
60    pnttg2sol(1,4)  ,
61    pnttg3sol(1,4)  ,
62    par1sol(1,4)    ,
63    par2sol(1,4)    ,
64    par3sol(1,4)    ,
65    pararg1(1,4)    ,
66    pararg2(1,4)    ,
67    pararg3(1,4)    
68 {
69
70    TheSame1.Init(0);
71    TheSame2.Init(0);
72    TheSame3.Init(0);
73    gp_Dir2d dirx(1.0,0.0);
74    WellDone = Standard_False;
75    NbrSol = 0;
76    if (!(Qualified1.IsEnclosed() ||
77          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
78        !(Qualified2.IsEnclosed() ||
79          Qualified2.IsOutside() || Qualified2.IsUnqualified()) ||
80        !(Qualified3.IsEnclosed() ||
81          Qualified3.IsOutside() || Qualified3.IsUnqualified())) {
82      throw GccEnt_BadQualifier();
83      return;
84    }
85
86 //=========================================================================
87 //   Processing.                                                          +
88 //=========================================================================
89
90    gp_Lin2d L1(Qualified1.Qualified());
91    gp_Lin2d L2(Qualified2.Qualified());
92    gp_Lin2d L3(Qualified3.Qualified());
93    gp_Pnt2d origin1(L1.Location());
94    gp_Dir2d dir1(L1.Direction());
95    gp_Dir2d normL1(-dir1.Y(),dir1.X());
96    gp_Pnt2d origin2(L2.Location());
97    gp_Dir2d dir2(L2.Direction());
98    gp_Dir2d normL2(-dir2.Y(),dir2.X());
99    gp_Pnt2d origin3(L3.Location());
100    gp_Dir2d dir3(L3.Direction());
101    gp_Dir2d normL3(-dir3.Y(),dir3.X());
102    Standard_Real xloc1 = origin1.X();
103    Standard_Real xloc2 = origin2.X();
104    Standard_Real xloc3 = origin3.X();
105    Standard_Real yloc1 = origin1.Y();
106    Standard_Real yloc2 = origin2.Y();
107    Standard_Real yloc3 = origin3.Y();
108    Standard_Real xdir1 = dir1.X();
109    Standard_Real xdir2 = dir2.X();
110    Standard_Real xdir3 = dir3.X();
111    Standard_Real ydir1 = dir1.Y();
112    Standard_Real ydir2 = dir2.Y();
113    Standard_Real ydir3 = dir3.Y();
114    GccAna_Lin2dBisec Bisec1(L1,L2);
115    GccAna_Lin2dBisec Bisec2(L1,L3);
116    Standard_Integer ncote1=0;
117    Standard_Integer ncote2=0;
118    Standard_Integer ncote3=0;
119    TColStd_Array1OfReal cote1(1,2);
120    TColStd_Array1OfReal cote2(1,2);
121    TColStd_Array1OfReal cote3(1,2);
122    Standard_Integer nbsol = 0;
123    if (Bisec1.IsDone() && Bisec2.IsDone()) {
124      for (Standard_Integer i = 1 ; i <= Bisec1.NbSolutions() ; i++) {
125        for (Standard_Integer j = 1 ; j <= Bisec2.NbSolutions() ; j++) {
126          IntAna2d_AnaIntersection Intp(Bisec1.ThisSolution(i),
127                                        Bisec2.ThisSolution(j));
128          if (Intp.IsDone()) {
129            if (!Intp.IsEmpty()) {
130              for (Standard_Integer k = 1 ; k <= Intp.NbPoints() ; k++) {
131                nbsol++;
132                Standard_Real Radius = (L1.Distance(Intp.Point(k).Value())+
133                               L2.Distance(Intp.Point(k).Value())+
134                               L3.Distance(Intp.Point(k).Value()))/3.0;
135                gp_Pnt2d Center(Intp.Point(k).Value());
136                Standard_Real cx = Center.X();
137                Standard_Real cy = Center.Y();
138                cirsol(nbsol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
139 //             ======================================================
140                gp_Dir2d dc1(origin1.XY()-Center.XY());
141                if (!Qualified1.IsUnqualified()) { 
142                  qualifier1(nbsol) = Qualified1.Qualifier();
143                }
144                else if (dc1.Dot(normL1) > 0.0) {
145                  qualifier1(nbsol) = GccEnt_outside;
146                }
147                else { qualifier1(nbsol) = GccEnt_enclosed; }
148                gp_Dir2d dc2(origin2.XY()-Center.XY());
149                if (!Qualified2.IsUnqualified()) { 
150                  qualifier2(nbsol) = Qualified2.Qualifier();
151                }
152                else if (dc2.Dot(normL2) > 0.0) {
153                  qualifier2(nbsol) = GccEnt_outside;
154                }
155                else { qualifier2(nbsol) = GccEnt_enclosed; }
156                gp_Dir2d dc3(origin3.XY()-Center.XY());
157                if (!Qualified3.IsUnqualified()) { 
158                  qualifier3(nbsol) = Qualified3.Qualifier();
159                }
160                else if (dc3.Dot(normL3) > 0.0) {
161                  qualifier3(nbsol) = GccEnt_outside;
162                }
163                else { qualifier3(nbsol) = GccEnt_enclosed; }
164                
165                Standard_Real cross1=gp_Dir2d(-ydir1,xdir1)
166                                    .Dot(gp_Dir2d(xloc1-cx,yloc1-cy));
167                Standard_Real cross2=gp_Dir2d(-ydir2,xdir2)
168                                    .Dot(gp_Dir2d(xloc2-cx,yloc2-cy));
169                Standard_Real cross3=gp_Dir2d(-ydir3,xdir3)
170                                    .Dot(gp_Dir2d(xloc3-cx,yloc3-cy));
171                if (cross1 != 0.0) {
172                  cross1 = cross1/Abs(cross1);
173                }
174                pnttg1sol(nbsol) = gp_Pnt2d(gp_XY(cx,cy)+
175                                            cross1*Radius*gp_XY(-ydir1,xdir1));
176                if (cross2 != 0.0) {
177                  cross2 = cross2/Abs(cross2);
178                }
179                pnttg2sol(nbsol) = gp_Pnt2d(gp_XY(cx,cy)+
180                                            cross2*Radius*gp_XY(-ydir2,xdir2));
181                if (cross3 != 0.0) {
182                  cross3 = cross3/Abs(cross3);
183                }
184                pnttg3sol(nbsol) = gp_Pnt2d(gp_XY(cx,cy)+
185                                            cross3*Radius*gp_XY(-ydir3,xdir3));
186                par1sol(nbsol)=ElCLib::Parameter(cirsol(nbsol),
187                                                 pnttg1sol(nbsol));
188                pararg1(nbsol)=ElCLib::Parameter(L1,pnttg1sol(nbsol));
189                par2sol(nbsol)=ElCLib::Parameter(cirsol(nbsol),
190                                                 pnttg2sol(nbsol));
191                pararg2(nbsol)=ElCLib::Parameter(L2,pnttg2sol(nbsol));
192                par3sol(nbsol)=ElCLib::Parameter(cirsol(nbsol),
193                                                 pnttg3sol(nbsol));
194                pararg3(nbsol)=ElCLib::Parameter(L3,pnttg3sol(nbsol));
195              }
196            }
197            WellDone = Standard_True;
198          }
199        }
200      }
201    }
202    if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed() && 
203 //  =========================================================
204        Qualified3.IsEnclosed()) {
205 //     ========================
206      ncote1 = 1;
207      ncote2 = 1;
208      ncote3 = 1;
209      cote1(1) = 1.0;
210      cote2(1) = 1.0;
211      cote3(1) = 1.0;
212    }
213    else if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed() && 
214 // ==============================================================
215             Qualified3.IsOutside()) {
216 //          =======================
217      ncote1 = 1;
218      ncote2 = 1;
219      ncote3 = 1;
220      cote1(1) = 1.0;
221      cote2(1) = 1.0;
222      cote3(1) = -1.0;
223    }
224    else if (Qualified1.IsEnclosed() && Qualified2.IsOutside() && 
225 // =============================================================
226             Qualified3.IsEnclosed()) {
227 //          ========================
228      ncote1 = 1;
229      ncote2 = 1;
230      ncote3 = 1;
231      cote1(1) = 1.0;
232      cote2(1) = -1.0;
233      cote3(1) = 1.0;
234    }
235    else if (Qualified1.IsEnclosed() && Qualified2.IsOutside() && 
236 // =============================================================
237             Qualified3.IsOutside()) {
238 //          =======================
239      ncote1 = 1;
240      ncote2 = 1;
241      ncote3 = 1;
242      cote1(1) = 1.0;
243      cote2(1) = -1.0;
244      cote3(1) = -1.0;
245    }
246    else if (Qualified1.IsOutside() && Qualified2.IsEnclosed() && 
247 // =============================================================
248             Qualified3.IsEnclosed()) {
249 //          ========================
250      ncote1 = 1;
251      ncote2 = 1;
252      ncote3 = 1;
253      cote1(1) = -1.0;
254      cote2(1) = 1.0;
255      cote3(1) = 1.0;
256    }
257    else if (Qualified1.IsOutside() && Qualified2.IsEnclosed() && 
258 // =============================================================
259             Qualified3.IsOutside()) {
260 //          =======================
261      ncote1 = 1;
262      ncote2 = 1;
263      ncote3 = 1;
264      cote1(1) = -1.0;
265      cote2(1) = 1.0;
266      cote3(1) = -1.0;
267    }
268    else if (Qualified1.IsOutside() && Qualified2.IsOutside() && 
269 // ============================================================
270             Qualified3.IsEnclosed()) {
271 //          ========================
272      ncote1 = 1;
273      ncote2 = 1;
274      ncote3 = 1;
275      cote1(1) = -1.0;
276      cote2(1) = -1.0;
277      cote3(1) = 1.0;
278    }
279    else if (Qualified1.IsOutside() && Qualified2.IsOutside() && 
280 // ============================================================
281             Qualified3.IsOutside()) {
282 //          =======================
283      ncote1 = 1;
284      ncote2 = 1;
285      ncote3 = 1;
286      cote1(1) = -1.0;
287      cote2(1) = -1.0;
288      cote3(1) = -1.0;
289    }
290    else {
291      if (Qualified1.IsUnqualified()) {
292 //   ====================================
293        ncote1 = 2;
294        cote1(1) = 1.0;
295        cote1(2) = -1.0;
296        if (Qualified2.IsUnqualified()) {
297 //     ===============================
298          ncote2 = 2;
299          cote2(1) = 1.0;
300          cote2(2) = -1.0;
301          if (Qualified3.IsUnqualified()) {
302 //       ===============================
303            ncote3 = 2;
304            cote2(1) = 1.0;
305            cote2(2) = -1.0;
306            NbrSol = nbsol;
307            WellDone = Standard_True;
308          }
309          else if (Qualified3.IsEnclosed()) {
310 //       ===============================
311            ncote3 = 1;
312            cote3(1) = 1.0;
313          }
314          else if (Qualified3.IsOutside()) {
315 //       ================================
316            ncote3 = 1;
317            cote3(1) = -1.0;
318          }
319        }
320        else if (Qualified2.IsEnclosed()) {
321 //     =================================
322          ncote2 = 1;
323          cote2(1) = 1.0;
324          if (Qualified3.IsUnqualified()) {
325 //       ===============================
326            ncote3 = 2;
327            cote3(1) = 1.0;
328            cote3(1) = -1.0;
329          }
330          else if (Qualified3.IsEnclosed()) {
331 //       =================================
332            ncote3 = 1;
333            cote3(1) = 1.0;
334          }
335          else if (Qualified3.IsOutside()) {
336 //       ================================
337            ncote3 = 1;
338            cote3(1) = -1.0;
339          }
340        }
341        else if (Qualified2.IsOutside()) {
342 //     ================================
343          ncote2 = 1;
344          cote2(1) = -1.0;
345          if (Qualified3.IsUnqualified()) {
346 //       ===============================
347            ncote3 = 2;
348            cote3(1) = 1.0;
349            cote3(2) = -1.0;
350          }
351          else if (Qualified3.IsEnclosed()) {
352 //       =================================
353            ncote3 = 1;
354            cote3(1) = 1.0;
355          }
356          else if (Qualified3.IsOutside()) {
357 //       ================================
358            ncote3 = 1;
359            cote3(1) = -1.0;
360          }
361        }
362      }
363      else if (Qualified2.IsUnqualified()) {
364 //   ===================================
365        ncote2 = 2;
366        cote2(1) = 1.0;
367        cote2(2) = -1.0;
368        if (Qualified1.IsEnclosed()) {
369 //     ============================
370          ncote1 = 1;
371          cote1(1) = 1.0;
372          if (Qualified3.IsUnqualified()) {
373 //       ===============================
374            ncote3 = 2;
375            cote3(1) = -1.0;
376            cote3(1) = -1.0;
377          }
378          else if (Qualified3.IsEnclosed()) {
379 //       =================================
380            ncote3 = 1;
381            cote3(1) = 1.0;
382          }
383          else if (Qualified3.IsOutside()) {
384 //       ================================
385            ncote3 = 1;
386            cote3(1) = -1.0;
387          }
388        }
389        else if (Qualified1.IsOutside()) {
390 //     ================================
391          ncote1 = 1;
392          cote1(1) = 1.0;
393          if (Qualified3.IsUnqualified()) {
394 //       ===============================
395            ncote3 = 2;
396            cote3(1) = 1.0;
397            cote3(2) = -1.0;
398          }
399          else if (Qualified3.IsEnclosed()) {
400 //       =================================
401            ncote3 = 1;
402            cote3(1) = 1.0;
403          }
404          else if (Qualified3.IsOutside()) {
405 //       ================================
406            ncote3 = 1;
407            cote3(1) = -1.0;
408          }
409        }
410      }
411      else if (Qualified3.IsUnqualified()) {
412 //   ===================================
413        ncote3 = 2;
414        cote3(1) = 1.0;
415        cote3(2) = -1.0;
416        if (Qualified1.IsEnclosed()) {
417 //     ============================
418          ncote1 = 1;
419          cote1(1) = 1.0;
420          if (Qualified2.IsEnclosed()) {
421 //       ============================
422            ncote2 = 1;
423            cote2(1) = 1.0;
424          }
425          else if (Qualified2.IsOutside()) {
426 //       ===============================
427            ncote2 = 1;
428            cote2(1) = -1.0;
429          }
430        }
431        else if (Qualified1.IsOutside()) {
432 //     ================================
433          ncote1 = 1;
434          cote1(1) = -1.0;
435          if (Qualified2.IsEnclosed()) {
436 //       ============================
437            ncote2 = 1;
438            cote2(1) = 1.0;
439          }
440          else if (Qualified2.IsOutside()) {
441 //       ===============================
442            ncote2 = 1;
443            cote2(1) = -1.0;
444          }
445        }
446      }
447    }
448    if (NbrSol > 0) { return; }
449    for (Standard_Integer i = 1 ; i <= nbsol ; i++) {
450      for (Standard_Integer j1 = 1 ; j1 <= ncote1 ; j1++) {
451        for (Standard_Integer j2 = 1 ; j2 <= ncote2 ; j2++) {
452          for (Standard_Integer j3 = 1 ; j3 <= ncote3 ; j3++) {
453            if ((cote2(j2)*((cirsol(i).Location().X()-origin2.X())*
454                (-dir2.Y())+(cirsol(i).Location().Y()-
455                origin2.Y())*(dir2.X())) > 0.0) &&
456                (cote3(j3)*((cirsol(i).Location().X()-origin3.X())*
457                (-dir3.Y())+(cirsol(i).Location().Y()-
458                origin3.Y())*(dir3.X())) > 0.0) &&
459                (cote1(j1)*((cirsol(i).Location().X()-origin1.X())*
460                (-dir1.Y())+(cirsol(i).Location().Y()-
461                origin1.Y())*(dir1.X())) > 0.0)) {
462              NbrSol++;
463              cirsol(NbrSol) = gp_Circ2d(cirsol(i));
464 //           =====================================
465              Standard_Real Radius = cirsol(NbrSol).Radius();
466              gp_Pnt2d Center(cirsol(NbrSol).Location());
467              gp_Dir2d dc(origin1.XY()-Center.XY());
468              Standard_Real sign = dc.Dot(gp_Dir2d(-dir1.Y(),dir1.X()));
469              dc = gp_Dir2d(sign*gp_XY(-dir1.Y(),dir1.X()));
470              pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY());
471              dc = gp_Dir2d(origin2.XY()-Center.XY());
472              sign = dc.Dot(gp_Dir2d(-dir2.Y(),dir2.X()));
473              dc = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X()));
474              pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY());
475              dc = gp_Dir2d(origin3.XY()-Center.XY());
476              sign = dc.Dot(gp_Dir2d(-dir3.Y(),dir3.X()));
477              dc = gp_Dir2d(sign*gp_XY(-dir3.Y(),dir3.X()));
478              pnttg3sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY());
479              par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
480                                               pnttg1sol(NbrSol));
481              pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
482              par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
483                                               pnttg2sol(NbrSol));
484              pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
485              par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
486                                               pnttg3sol(NbrSol));
487              pararg3(NbrSol)=ElCLib::Parameter(L3,pnttg3sol(NbrSol));
488            }
489          }
490        }
491      }
492    }
493  }