0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / GccIter / GccIter_Circ2d3Tan.gxx
1 // File:        GccIter_Circ2d3Tan.gxx
2 // Created:     Fri Dec 13 15:27:54 1991
3 // Author:      Remi GILET
4 //              <reg@topsn3>
5
6 //=========================================================================
7 //   Creation d un cercle tangent a deux elements : Droite.               +
8 //                                                  Cercle.               +
9 //                                                  Point.                +
10 //                                                  Courbes.              +
11 //                        centre sur un troisieme : Droite.               +
12 //                                                  Cercle.               +
13 //                                                  Courbes.              +
14 //=========================================================================
15
16 #include <gp_Dir2d.hxx>
17 #include <gp_Ax2d.hxx>
18 #include <gp_Vec2d.hxx>
19 #include <gp.hxx>
20 #include <StdFail_NotDone.hxx>
21 #include <GccEnt_BadQualifier.hxx>
22 #include <math_FunctionSetRoot.hxx>
23 #include <math_NewtonFunctionSetRoot.hxx>
24 #include <GccAna_Circ2d3Tan.hxx>
25
26 GccIter_Circ2d3Tan::
27    GccIter_Circ2d3Tan (const TheQualifiedCurve& Qualified1 , 
28                        const TheQualifiedCurve& Qualified2 ,
29                        const TheQualifiedCurve& Qualified3 , 
30                        const Standard_Real      Param1     ,
31                        const Standard_Real      Param2     ,
32                        const Standard_Real      Param3     ,
33                        const Standard_Real      Tolerance  ) {
34
35    TheSame1 = Standard_False;
36    TheSame2 = Standard_False;
37    TheSame3 = Standard_False;
38    par1sol = 0.;
39    par2sol = 0.;
40    par3sol = 0.;
41    pararg1 = 0.;
42    pararg2 = 0.;
43    pararg3 = 0.;
44
45    Standard_Real Tol = Abs(Tolerance);
46    WellDone = Standard_False;
47    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
48          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
49        !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || 
50          Qualified2.IsOutside() || Qualified2.IsUnqualified()) ||
51        !(Qualified3.IsEnclosed() || Qualified3.IsEnclosing() || 
52          Qualified3.IsOutside() || Qualified3.IsUnqualified())) {
53      GccEnt_BadQualifier::Raise();
54      return;
55    }
56    TheCurve Cu1 = Qualified1.Qualified();
57    TheCurve Cu2 = Qualified2.Qualified();
58    TheCurve Cu3 = Qualified3.Qualified();
59    GccIter_FuncTCuCuCu Func(Cu1,Cu2,Cu3);
60    math_Vector Umin(1,3);
61    math_Vector Umax(1,3);
62    math_Vector Ufirst(1,3);
63    math_Vector tol(1,3);
64    Umin(1) = TheCurveTool::FirstParameter(Cu1);
65    Umin(2) = TheCurveTool::FirstParameter(Cu2);
66    Umin(3) = TheCurveTool::FirstParameter(Cu3);
67    Umax(1) = TheCurveTool::LastParameter(Cu1);
68    Umax(2) = TheCurveTool::LastParameter(Cu2);
69    Umax(3) = TheCurveTool::LastParameter(Cu3);
70    Ufirst(1) = Param1;
71    Ufirst(2) = Param2;
72    Ufirst(3) = Param3;
73    tol(1) = TheCurveTool::EpsX(Cu1,Abs(Tolerance));
74    tol(2) = TheCurveTool::EpsX(Cu2,Abs(Tolerance));
75    tol(3) = TheCurveTool::EpsX(Cu3,Abs(Tolerance));   
76    math_FunctionSetRoot Root(Func,Ufirst,tol,Umin,Umax);
77    if (Root.IsDone()) {
78      Root.Root(Ufirst);
79 #ifdef DEB
80      Standard_Boolean Ok = Func.Value(Ufirst,Umin);
81 #else
82      Func.Value(Ufirst,Umin);
83 #endif
84      gp_Pnt2d point1,point2,point3;
85      gp_Vec2d Tan1,Tan2,Tan3;
86      TheCurveTool::D1(Cu1,Ufirst(1),point1,Tan1);
87      TheCurveTool::D1(Cu2,Ufirst(2),point2,Tan2);
88      TheCurveTool::D1(Cu3,Ufirst(3),point3,Tan3);
89      GccAna_Circ2d3Tan circ(point1,point2,point3,Tol);
90      if (circ.IsDone()) { 
91        cirsol = circ.ThisSolution(1);
92        gp_Pnt2d centre = cirsol.Location();
93        Standard_Real normetan1 = Tan1.Magnitude();
94        Standard_Real normetan2 = Tan2.Magnitude();
95        Standard_Real normetan3 = Tan3.Magnitude();
96        gp_Vec2d Vec1(point1,centre);
97        gp_Vec2d Vec2(point2,centre);
98        gp_Vec2d Vec3(point3,centre);
99        Standard_Real normevec1 = Vec1.Magnitude();
100        Standard_Real normevec2 = Vec2.Magnitude();
101        Standard_Real normevec3 = Vec3.Magnitude();
102        Standard_Real dot1,dot2,dot3;
103        if (normevec1 >= gp::Resolution() && normetan1 >= gp::Resolution()) {
104          dot1 = Vec1.Dot(Tan1)/(normevec1*normetan1);
105        }
106        else { dot1 = 0.; }
107        if (normevec2 >= gp::Resolution() && normetan2 >= gp::Resolution()) {
108          dot2 = Vec2.Dot(Tan2)/(normevec2*normetan2);
109        }
110        else { dot2 = 0.; }
111        if (normevec3 >= gp::Resolution() && normetan3 >= gp::Resolution()) {
112          dot3 = Vec3.Dot(Tan3)/(normevec3*normetan3);
113        }
114        else { dot3 = 0.; }
115        Tol = 1.e-12;
116        if (dot1 <= Tol && dot2 <=Tol && dot3 <= Tol) {
117          Standard_Real Angle1 = Vec1.Angle(Tan1);
118          if (Qualified1.IsUnqualified()||
119              (Qualified1.IsEnclosing()&&Angle1<=0.)||
120              (Qualified1.IsOutside() && Angle1 >= 0.) ||
121              (Qualified1.IsEnclosed() && Angle1 <= 0.)) {
122            Angle1 = Vec2.Angle(Tan2);
123            if (Qualified2.IsUnqualified() || 
124                (Qualified2.IsEnclosing()&&Angle1<=0.)||
125                (Qualified2.IsOutside() && Angle1 >= 0) ||
126                (Qualified2.IsEnclosed() && Angle1 <= 0.)) {
127              Angle1 = Vec3.Angle(Tan3);
128              if (Qualified3.IsUnqualified() || 
129                  (Qualified3.IsEnclosing()&&Angle1<=0.)||
130                  (Qualified3.IsOutside() && Angle1 >= 0) ||
131                  (Qualified3.IsEnclosed() && Angle1 <= 0.)) {
132                qualifier1 = Qualified1.Qualifier();
133                qualifier2 = Qualified2.Qualifier();
134                qualifier3 = Qualified3.Qualifier();
135                pararg1 = Ufirst(1);
136                par1sol = 0.;
137                pnttg1sol = point1;
138                pararg2 = Ufirst(2);
139                pnttg2sol = point2;
140                par2sol = pnttg2sol.Distance(pnttg1sol);
141                pnttg3sol = point3;
142                pararg3 = Ufirst(3);
143                par3sol = pnttg3sol.Distance(pnttg1sol);
144                WellDone = Standard_True;
145              }
146            }
147          }
148        }
149      }
150    }
151  }
152
153 GccIter_Circ2d3Tan::
154    GccIter_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1 , 
155                           const TheQualifiedCurve& Qualified2 ,
156                           const TheQualifiedCurve& Qualified3 , 
157                           const Standard_Real      Param1     ,
158                           const Standard_Real      Param2     ,
159                           const Standard_Real      Param3     ,
160                           const Standard_Real      Tolerance     ) {
161
162    TheSame1 = Standard_False;
163    TheSame2 = Standard_False;
164    TheSame3 = Standard_False;
165    par1sol = 0.;
166    par2sol = 0.;
167    par3sol = 0.;
168    pararg1 = 0.;
169    pararg2 = 0.;
170    pararg3 = 0.;
171
172    Standard_Real Tol = Abs(Tolerance);
173    WellDone = Standard_False;
174    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
175          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
176        !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || 
177          Qualified2.IsOutside() || Qualified2.IsUnqualified()) ||
178        !(Qualified3.IsEnclosed() || Qualified3.IsEnclosing() || 
179          Qualified3.IsOutside() || Qualified3.IsUnqualified())) {
180      GccEnt_BadQualifier::Raise();
181      return;
182    }
183    gp_Circ2d C1 = Qualified1.Qualified();
184    TheCurve Cu2 = Qualified2.Qualified();
185    TheCurve Cu3 = Qualified3.Qualified();
186    GccIter_FuncTCuCuCu Func(C1,Cu2,Cu3);
187    math_Vector Umin(1,3);
188    math_Vector Umax(1,3);
189    math_Vector Ufirst(1,3);
190    math_Vector tol(1,3);
191    Umin(1) = 0.;
192    Umin(2) = TheCurveTool::FirstParameter(Cu2);
193    Umin(3) = TheCurveTool::FirstParameter(Cu3);
194    Umax(1) = 2*M_PI;
195    Umax(2) = TheCurveTool::LastParameter(Cu2);
196    Umax(3) = TheCurveTool::LastParameter(Cu3);
197    Ufirst(1) = Param1;
198    Ufirst(2) = Param2;
199    Ufirst(3) = Param3;
200    tol(1) = 2.e-15*M_PI;
201    tol(2) = TheCurveTool::EpsX(Cu2,Abs(Tolerance));
202    tol(3) = TheCurveTool::EpsX(Cu3,Abs(Tolerance));   
203    math_FunctionSetRoot Root(Func,Ufirst,tol,Umin,Umax);
204    if (Root.IsDone()) {
205      Root.Root(Ufirst);
206 #ifdef DEB
207      Standard_Boolean Ok = Func.Value(Ufirst,Umin);
208 #else
209      Func.Value(Ufirst,Umin);
210 #endif
211      gp_Pnt2d centre1(C1.Location());
212      Standard_Real R1 = C1.Radius();
213      gp_Pnt2d point1(centre1.XY()+R1*gp_XY(Cos(Ufirst(1)),Sin(Ufirst(1))));
214      gp_Vec2d Tan1(gp_XY(-Sin(Ufirst(1)),Cos(Ufirst(1))));
215      gp_Pnt2d point2,point3;
216 //     gp_Vec2d Tan2,Tan3,Nor2,Nor3;
217      gp_Vec2d Tan2,Tan3;
218      TheCurveTool::D1(Cu2,Ufirst(2),point2,Tan2);
219      TheCurveTool::D1(Cu3,Ufirst(3),point3,Tan3);
220      GccAna_Circ2d3Tan circ(point1,point2,point3,Tol);
221      if (circ.IsDone()) {
222        cirsol = circ.ThisSolution(1);
223        gp_Pnt2d centre(cirsol.Location());
224        Standard_Real dist = centre1.Distance(centre);
225        Standard_Real Rsol = cirsol.Radius();
226        Standard_Real normetan1 = Tan1.Magnitude();
227        Standard_Real normetan2 = Tan2.Magnitude();
228        Standard_Real normetan3 = Tan3.Magnitude();
229        gp_Vec2d Vec1(point1,centre);
230        gp_Vec2d Vec2(point2,centre);
231        gp_Vec2d Vec3(point3,centre);
232        Standard_Real normevec1 = Vec1.Magnitude();
233        Standard_Real normevec2 = Vec2.Magnitude();
234        Standard_Real normevec3 = Vec3.Magnitude();
235        Standard_Real dot1,dot2,dot3;
236        if (normevec1 >= gp::Resolution() && normetan1 >= gp::Resolution()) {
237          dot1 = Vec1.Dot(Tan1)/(normevec1*normetan1);
238        }
239        else { dot1 = 0.; }
240        if (normevec2 >= gp::Resolution() && normetan2 >= gp::Resolution()) {
241          dot2 = Vec2.Dot(Tan2)/(normevec2*normetan2);
242        }
243        else { dot2 = 0.; }
244        if (normevec3 >= gp::Resolution() && normetan3 >= gp::Resolution()) {
245          dot3 = Vec3.Dot(Tan3)/(normevec3*normetan3);
246        }
247        else { dot3 = 0.; }
248        Tol = 1.e-12;
249        if (dot1 <= Tol && dot2 <=Tol && dot3 <= Tol) {
250          if (Qualified1.IsUnqualified() || 
251              (Qualified1.IsEnclosing() && Rsol >= R1 && dist <= Rsol)||
252              (Qualified1.IsOutside() && dist >= Rsol) ||
253              (Qualified1.IsEnclosed() && Rsol <= R1 && dist <= Rsol)) {
254            Standard_Real Angle1 = Vec2.Angle(Tan2);
255            if (Qualified2.IsUnqualified() || 
256                (Qualified2.IsEnclosing()&&Angle1<=0.)||
257                (Qualified2.IsOutside() && Angle1 >= 0) ||
258                (Qualified2.IsEnclosed() && Angle1 <= 0.)) {
259              Angle1 = Vec3.Angle(Tan3);
260              if (Qualified3.IsUnqualified() || 
261                  (Qualified3.IsEnclosing()&&Angle1<=0.)||
262                  (Qualified3.IsOutside() && Angle1 >= 0) ||
263                  (Qualified3.IsEnclosed() && Angle1 <= 0.)) {
264                qualifier1 = Qualified1.Qualifier();
265                qualifier2 = Qualified2.Qualifier();
266                qualifier3 = Qualified3.Qualifier();
267                pararg1 = Ufirst(1);
268                par1sol = 0.;
269                pnttg1sol = point1;
270                pararg2 = Ufirst(2);
271                pnttg2sol = point2;
272                par2sol = 0.;
273                pararg3 = Ufirst(3);
274                pnttg3sol = point3;
275                par3sol = 0.;
276                WellDone = Standard_True;
277              }
278            }
279          }
280        }
281      }
282    }
283  }
284
285 GccIter_Circ2d3Tan::
286    GccIter_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1 , 
287                        const GccEnt_QualifiedCirc& Qualified2 , 
288                        const TheQualifiedCurve&    Qualified3 , 
289                        const Standard_Real         Param1     ,
290                        const Standard_Real         Param2     ,
291                        const Standard_Real         Param3     ,
292                        const Standard_Real         Tolerance     ) {
293
294    TheSame1 = Standard_False;
295    TheSame2 = Standard_False;
296    TheSame3 = Standard_False;
297    par1sol = 0.;
298    par2sol = 0.;
299    par3sol = 0.;
300    pararg1 = 0.;
301    pararg2 = 0.;
302    pararg3 = 0.;
303
304    Standard_Real Tol = Abs(Tolerance);
305    WellDone = Standard_False;
306    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
307          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
308        !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || 
309          Qualified2.IsOutside() || Qualified2.IsUnqualified()) ||
310        !(Qualified3.IsEnclosed() || Qualified3.IsEnclosing() || 
311          Qualified3.IsOutside() || Qualified3.IsUnqualified())) {
312      GccEnt_BadQualifier::Raise();
313      return;
314    }
315    gp_Circ2d C1 = Qualified1.Qualified();
316    gp_Circ2d C2 = Qualified2.Qualified();
317    TheCurve Cu3 = Qualified3.Qualified();
318    GccIter_FuncTCuCuCu Func(C1,C2,Cu3);
319    math_Vector Umin(1,3);
320    math_Vector Umax(1,3);
321    math_Vector Ufirst(1,3);
322    math_Vector tol(1,3);
323    Umin(1) = 0.;
324    Umin(2) = 0.;
325    Umin(3) = TheCurveTool::FirstParameter(Cu3);
326    Umax(1) = 2*M_PI;
327    Umax(2) = 2*M_PI;
328    Umax(3) = TheCurveTool::LastParameter(Cu3);
329    Ufirst(1) = Param1;
330    Ufirst(2) = Param2;
331    Ufirst(3) = Param3;
332    tol(1) = 2.e-15*M_PI;
333    tol(2) = 2.e-15*M_PI;
334    tol(3) = TheCurveTool::EpsX(Cu3,Abs(Tolerance));   
335    math_FunctionSetRoot Root(Func,Ufirst,tol,Umin,Umax);
336    if (Root.IsDone()) {
337      Root.Root(Ufirst);
338 #ifdef DEB
339      Standard_Boolean Ok = Func.Value(Ufirst,Umin);
340 #else
341      Func.Value(Ufirst,Umin);
342 #endif
343      gp_Pnt2d centre1(C1.Location());
344      Standard_Real R1 = C1.Radius();
345      gp_Pnt2d point1(centre1.XY()+R1*gp_XY(Cos(Ufirst(1)),Sin(Ufirst(1))));
346      gp_Vec2d Tan1(gp_XY(-Sin(Ufirst(1)),Cos(Ufirst(1))));
347      gp_Pnt2d centre2(C2.Location());
348      Standard_Real R2 = C2.Radius();
349      gp_Pnt2d point2(centre2.XY()+R2*gp_XY(Cos(Ufirst(2)),Sin(Ufirst(2))));
350      gp_Vec2d Tan2(gp_XY(-Sin(Ufirst(2)),Cos(Ufirst(2))));
351      gp_Pnt2d point3;
352      gp_Vec2d Tan3;
353      TheCurveTool::D1(Cu3,Ufirst(3),point3,Tan3);
354      GccAna_Circ2d3Tan circ(point1,point2,point3,Tol);
355      if (circ.IsDone()) {
356        cirsol = circ.ThisSolution(1);
357        gp_Pnt2d centre(cirsol.Location());
358        Standard_Real dist = centre1.Distance(centre);
359        Standard_Real Rsol = cirsol.Radius();
360        Standard_Real normetan1 = Tan1.Magnitude();
361        Standard_Real normetan2 = Tan2.Magnitude();
362        Standard_Real normetan3 = Tan3.Magnitude();
363        gp_Vec2d Vec1(point1,centre);
364        gp_Vec2d Vec2(point2,centre);
365        gp_Vec2d Vec3(point3,centre);
366        Standard_Real normevec1 = Vec1.Magnitude();
367        Standard_Real normevec2 = Vec2.Magnitude();
368        Standard_Real normevec3 = Vec3.Magnitude();
369        Standard_Real dot1,dot2,dot3;
370        if (normevec1 >= gp::Resolution() && normetan1 >= gp::Resolution()) {
371          dot1 = Vec1.Dot(Tan1)/(normevec1*normetan1);
372        }
373        else { dot1 = 0.; }
374        if (normevec2 >= gp::Resolution() && normetan2 >= gp::Resolution()) {
375          dot2 = Vec2.Dot(Tan2)/(normevec2*normetan2);
376        }
377        else { dot2 = 0.; }
378        if (normevec3 >= gp::Resolution() && normetan3 >= gp::Resolution()) {
379          dot3 = Vec3.Dot(Tan3)/(normevec3*normetan3);
380        }
381        else { dot3 = 0.; }
382        Tol = 1.e-12;
383        if (dot1 <= Tol && dot2 <=Tol && dot3 <= Tol) {
384          if (Qualified1.IsUnqualified() || 
385              (Qualified1.IsEnclosing() && Rsol >= R1 && dist <= Rsol)||
386              (Qualified1.IsOutside() && dist >= Rsol) ||
387              (Qualified1.IsEnclosed() && Rsol <= R1 && dist <= Rsol)) {
388            dist = centre2.Distance(centre);
389            if (Qualified1.IsUnqualified() || 
390                (Qualified1.IsEnclosing() && Rsol >= R2 && dist <= Rsol)||
391                (Qualified1.IsOutside() && dist >= Rsol) ||
392                (Qualified1.IsEnclosed() && Rsol <= R2 && dist <= Rsol)) {
393              gp_Vec2d Vec(point3,centre);
394              Standard_Real Angle1 = Vec.Angle(Tan3);
395              if (Qualified3.IsUnqualified() || 
396                  (Qualified3.IsEnclosing()&&Angle1<=0.)||
397                  (Qualified3.IsOutside() && Angle1 >= 0) ||
398                  (Qualified3.IsEnclosed() && Angle1 <= 0.)) {
399                qualifier1 = Qualified1.Qualifier();
400                qualifier2 = Qualified2.Qualifier();
401                qualifier3 = Qualified3.Qualifier();
402                pararg1 = Ufirst(1);
403                par1sol = 0.;
404                pnttg1sol = point1;
405                pararg2 = Ufirst(2);
406                pnttg2sol = point2;
407                par2sol = 0.;
408                pararg3 = Ufirst(3);
409                pnttg3sol = point3;
410                par3sol = 0.;
411                WellDone = Standard_True;
412              }
413            }
414          }
415        }
416      }
417    }
418  }
419
420 GccIter_Circ2d3Tan::
421    GccIter_Circ2d3Tan (const GccEnt_QualifiedLin& Qualified1 , 
422                        const TheQualifiedCurve&   Qualified2 ,
423                        const TheQualifiedCurve&   Qualified3 , 
424                        const Standard_Real        Param1     ,
425                        const Standard_Real        Param2     ,
426                        const Standard_Real        Param3     ,
427                        const Standard_Real        Tolerance  ) {
428
429    TheSame1 = Standard_False;
430    TheSame2 = Standard_False;
431    TheSame3 = Standard_False;
432    par1sol = 0.;
433    par2sol = 0.;
434    par3sol = 0.;
435    pararg1 = 0.;
436    pararg2 = 0.;
437    pararg3 = 0.;
438
439    Standard_Real Tol = Abs(Tolerance);
440    WellDone = Standard_False;
441    if (!(Qualified1.IsEnclosed() ||
442          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
443        !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || 
444          Qualified2.IsOutside() || Qualified2.IsUnqualified()) ||
445        !(Qualified3.IsEnclosed() || Qualified3.IsEnclosing() || 
446          Qualified3.IsOutside() || Qualified3.IsUnqualified())) {
447      GccEnt_BadQualifier::Raise();
448      return;
449    }
450    gp_Lin2d L1 = Qualified1.Qualified();
451    TheCurve Cu2 = Qualified2.Qualified();
452    TheCurve Cu3 = Qualified3.Qualified();
453    GccIter_FuncTCuCuCu Func(L1,Cu2,Cu3);
454    math_Vector Umin(1,3);
455    math_Vector Umax(1,3);
456    math_Vector Ufirst(1,3);
457    math_Vector tol(1,3);
458    Umin(1) = RealFirst();
459    Umin(2) = TheCurveTool::FirstParameter(Cu2);
460    Umin(3) = TheCurveTool::FirstParameter(Cu3);
461    Umax(1) = RealLast();
462    Umax(2) = TheCurveTool::LastParameter(Cu2);
463    Umax(3) = TheCurveTool::LastParameter(Cu3);
464    Ufirst(1) = Param1;
465    Ufirst(2) = Param2;
466    Ufirst(3) = Param3;
467    tol(1) = 1.e-15;
468    tol(2) = TheCurveTool::EpsX(Cu2,Abs(Tolerance));
469    tol(3) = TheCurveTool::EpsX(Cu3,Abs(Tolerance));   
470    math_FunctionSetRoot Root(Func,Ufirst,tol,Umin,Umax);
471    if (Root.IsDone()) {
472      Root.Root(Ufirst);
473 #ifdef DEB
474      Standard_Boolean Ok = Func.Value(Ufirst,Umin);
475 #else
476      Func.Value(Ufirst,Umin);
477 #endif
478      gp_Pnt2d centre1(L1.Location());
479      gp_Pnt2d point1(centre1.XY()+Ufirst(1)*L1.Direction().XY());
480      gp_Pnt2d point2,point3;
481      gp_Vec2d Tan2,Tan3;
482      TheCurveTool::D1(Cu2,Ufirst(2),point2,Tan2);
483      TheCurveTool::D1(Cu3,Ufirst(3),point3,Tan3);
484      GccAna_Circ2d3Tan circ(point1,point2,point3,Tol);
485      if (circ.IsDone()) {
486        cirsol = circ.ThisSolution(1);
487        gp_Pnt2d centre(cirsol.Location());
488
489        // creation vaariables intermediaires pour WNT
490        gp_XY dummy1 = centre.XY()-L1.Location().XY();
491        gp_XY dummy2 (-L1.Direction().Y(),L1.Direction().X());
492        Standard_Real pscal=dummy1.Dot(dummy2);
493
494        gp_Vec2d Tan1(L1.Direction().XY());
495        Standard_Real normetan1 = Tan1.Magnitude();
496        Standard_Real normetan2 = Tan2.Magnitude();
497        Standard_Real normetan3 = Tan3.Magnitude();
498        gp_Vec2d Vec1(point1,centre);
499        gp_Vec2d Vec2(point2,centre);
500        gp_Vec2d Vec3(point3,centre);
501        Standard_Real normevec1 = Vec1.Magnitude();
502        Standard_Real normevec2 = Vec2.Magnitude();
503        Standard_Real normevec3 = Vec3.Magnitude();
504        Standard_Real dot1,dot2,dot3;
505        if (normevec1 >= gp::Resolution() && normetan1 >= gp::Resolution()) {
506          dot1 = Vec1.Dot(Tan1)/(normevec1*normetan1);
507        }
508        else { dot1 = 0.; }
509        if (normevec2 >= gp::Resolution() && normetan2 >= gp::Resolution()) {
510          dot2 = Vec2.Dot(Tan2)/(normevec2*normetan2);
511        }
512        else { dot2 = 0.; }
513        if (normevec3 >= gp::Resolution() && normetan3 >= gp::Resolution()) {
514          dot3 = Vec3.Dot(Tan3)/(normevec3*normetan3);
515        }
516        else { dot3 = 0.; }
517        Tol = 1.e-12;
518        if (dot1 <= Tol && dot2 <=Tol && dot3 <= Tol) {
519          if (Qualified1.IsUnqualified() || 
520              (Qualified1.IsOutside() && pscal <= 0.) ||
521              (Qualified1.IsEnclosed() && pscal >= 0.)) {
522            gp_Vec2d Vec(point2,centre);
523            Standard_Real Angle1 = Vec.Angle(Tan2);
524            if (Qualified2.IsUnqualified() || 
525                (Qualified2.IsEnclosing()&&Angle1<=0.)||
526                (Qualified2.IsOutside() && Angle1 >= 0) ||
527                (Qualified2.IsEnclosed() && Angle1 <= 0.)) {
528              Vec = gp_Vec2d(point3,centre);
529              Angle1 = Vec.Angle(Tan3);
530              if (Qualified3.IsUnqualified() || 
531                  (Qualified3.IsEnclosing()&&Angle1<=0.)||
532                  (Qualified3.IsOutside() && Angle1 >= 0) ||
533                  (Qualified3.IsEnclosed() && Angle1 <= 0.)) {
534                qualifier1 = Qualified1.Qualifier();
535                qualifier2 = Qualified2.Qualifier();
536                qualifier3 = Qualified3.Qualifier();
537                pararg1 = Ufirst(1);
538                par1sol = 0.;
539                pnttg1sol = point1;
540                pararg2 = Ufirst(2);
541                pnttg2sol = point2;
542                par2sol = 0.;
543                pararg3 = Ufirst(3);
544                pnttg3sol = point3;
545                par3sol = 0.;
546                WellDone = Standard_True;
547              }
548            }
549          }
550        }
551      }
552    }
553  }
554
555 GccIter_Circ2d3Tan::
556    GccIter_Circ2d3Tan (const GccEnt_QualifiedLin&  Qualified1 , 
557                        const GccEnt_QualifiedLin&  Qualified2 , 
558                        const TheQualifiedCurve&    Qualified3 , 
559                        const Standard_Real         Param1     ,
560                        const Standard_Real         Param2     ,
561                        const Standard_Real         Param3     ,
562                        const Standard_Real         Tolerance  ){
563
564    TheSame1 = Standard_False;
565    TheSame2 = Standard_False;
566    TheSame3 = Standard_False;
567    par1sol = 0.;
568    par2sol = 0.;
569    par3sol = 0.;
570    pararg1 = 0.;
571    pararg2 = 0.;
572    pararg3 = 0.;
573
574    Standard_Real Tol = Abs(Tolerance);
575    WellDone = Standard_False;
576    if (!(Qualified1.IsEnclosed() || 
577          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
578        !(Qualified2.IsEnclosed() || 
579          Qualified2.IsOutside() || Qualified2.IsUnqualified()) ||
580        !(Qualified3.IsEnclosed() || Qualified3.IsEnclosing() || 
581          Qualified3.IsOutside() || Qualified3.IsUnqualified())) {
582      GccEnt_BadQualifier::Raise();
583      return;
584    }
585    gp_Lin2d L1 = Qualified1.Qualified();
586    gp_Lin2d L2 = Qualified2.Qualified();
587    TheCurve Cu3 = Qualified3.Qualified();
588    GccIter_FuncTCuCuCu Func(L1,L2,Cu3);
589    math_Vector Umin(1,3);
590    math_Vector Umax(1,3);
591    math_Vector Ufirst(1,3);
592    math_Vector tol(1,3);
593    Umin(1) = RealFirst();
594    Umin(2) = RealFirst();
595    Umin(3) = TheCurveTool::FirstParameter(Cu3);
596    Umax(1) = RealLast();
597    Umax(2) = RealLast();
598    Umax(3) = TheCurveTool::LastParameter(Cu3);
599    Ufirst(1) = Param1;
600    Ufirst(2) = Param2;
601    Ufirst(3) = Param3;
602    tol(1) = 1.e-15;
603    tol(2) = 1.e-15;
604    tol(3) = TheCurveTool::EpsX(Cu3,Abs(Tolerance));   
605    math_FunctionSetRoot Root(Func,Ufirst,tol,Umin,Umax);
606    if (Root.IsDone()) {
607      Root.Root(Ufirst);
608 #ifdef DEB
609      Standard_Boolean Ok = Func.Value(Ufirst,Umin);
610 #else
611      Func.Value(Ufirst,Umin);
612 #endif
613      gp_Pnt2d centre1(L1.Location());
614      gp_Pnt2d point1(centre1.XY()+Ufirst(1)*L1.Direction().XY());
615      gp_Pnt2d centre2(L2.Location());
616      gp_Pnt2d point2(centre2.XY()+Ufirst(2)*L2.Direction().XY());
617      gp_Pnt2d point3;
618      gp_Vec2d Tan3;
619      TheCurveTool::D1(Cu3,Ufirst(3),point3,Tan3);
620      GccAna_Circ2d3Tan circ(point1,point2,point3,Tol);
621      if (circ.IsDone()) {
622        cirsol = circ.ThisSolution(1);
623        gp_Pnt2d centre(cirsol.Location());
624        Standard_Real pscal=centre.XY().Dot(gp_XY(-L1.Direction().Y(),
625                                         L1.Direction().X()));
626        if (Qualified1.IsUnqualified() || 
627            (Qualified1.IsOutside() && pscal <= 0.) ||
628            (Qualified1.IsEnclosed() && pscal >= 0.)) {
629          Standard_Real pscal=centre.XY().Dot(gp_XY(-L1.Direction().Y(),
630                                           L1.Direction().X()));
631          gp_Vec2d Tan1(L1.Direction().XY());
632          gp_Vec2d Tan2(L2.Direction().XY());
633          Standard_Real normetan1 = Tan1.Magnitude();
634          Standard_Real normetan2 = Tan2.Magnitude();
635          Standard_Real normetan3 = Tan3.Magnitude();
636          gp_Vec2d Vec1(point1,centre);
637          gp_Vec2d Vec2(point2,centre);
638          gp_Vec2d Vec3(point3,centre);
639          Standard_Real normevec1 = Vec1.Magnitude();
640          Standard_Real normevec2 = Vec2.Magnitude();
641          Standard_Real normevec3 = Vec3.Magnitude();
642          Standard_Real dot1,dot2,dot3;
643          if (normevec1 >= gp::Resolution() && normetan1 >= gp::Resolution()) {
644            dot1 = Vec1.Dot(Tan1)/(normevec1*normetan1);
645          }
646          else { dot1 = 0.; }
647          if (normevec2 >= gp::Resolution() && normetan2 >= gp::Resolution()) {
648            dot2 = Vec2.Dot(Tan2)/(normevec2*normetan2);
649          }
650          else { dot2 = 0.; }
651          if (normevec3 >= gp::Resolution() && normetan3 >= gp::Resolution()) {
652            dot3 = Vec3.Dot(Tan3)/(normevec3*normetan3);
653          }
654          else { dot3 = 0.; }
655          Tol = 1.e-12;
656          if (dot1 <= Tol && dot2 <=Tol && dot3 <= Tol) {
657            if (Qualified2.IsUnqualified() || 
658                (Qualified2.IsOutside() && pscal <= 0.) ||
659                (Qualified2.IsEnclosed() && pscal >= 0.)) {
660              Standard_Real Angle1 = Vec3.Angle(Tan3);
661              if (Qualified3.IsUnqualified() || 
662                  (Qualified3.IsEnclosing()&&Angle1<=0.)||
663                  (Qualified3.IsOutside() && Angle1 >= 0) ||
664                  (Qualified3.IsEnclosed() && Angle1 <= 0.)) {
665                qualifier1 = Qualified1.Qualifier();
666                qualifier2 = Qualified2.Qualifier();
667                qualifier3 = Qualified3.Qualifier();
668                pararg1 = Ufirst(1);
669                par1sol = 0.;
670                pnttg1sol = point1;
671                pararg2 = Ufirst(2);
672                pnttg2sol = point2;
673                par2sol = 0.;
674                pararg3 = Ufirst(3);
675                pnttg3sol = point3;
676                par3sol = 0.;
677                WellDone = Standard_True;
678              }
679            }
680          }
681        }
682      }
683    }
684  }
685
686 GccIter_Circ2d3Tan::
687    GccIter_Circ2d3Tan (const TheQualifiedCurve& Qualified1 ,
688                        const TheQualifiedCurve& Qualified2 , 
689                        const gp_Pnt2d&          Point3     ,
690                        const Standard_Real      Param1     ,
691                        const Standard_Real      Param2     ,
692                        const Standard_Real      Tolerance  ) {
693
694    TheSame1 = Standard_False;
695    TheSame2 = Standard_False;
696    TheSame3 = Standard_False;
697    par1sol = 0.;
698    par2sol = 0.;
699    par3sol = 0.;
700    pararg1 = 0.;
701    pararg2 = 0.;
702    pararg3 = 0.;
703
704    Standard_Real Tol = Abs(Tolerance);
705    WellDone = Standard_False;
706    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
707          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
708        !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || 
709          Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
710      GccEnt_BadQualifier::Raise();
711      return;
712    }
713    gp_Circ2d C1(gp_Ax2d(Point3,gp_Dir2d(1.,0.)),0.);
714    TheCurve Cu1 = Qualified1.Qualified();
715    TheCurve Cu2 = Qualified2.Qualified();
716    GccIter_FuncTCuCuCu Func(C1,Cu1,Cu2);
717    math_Vector Umin(1,3);
718    math_Vector Umax(1,3);
719    math_Vector Ufirst(1,3);
720    math_Vector tol(1,3);
721    Umin(1) = 0.;
722    Umin(2) = TheCurveTool::FirstParameter(Cu1);
723    Umin(3) = TheCurveTool::FirstParameter(Cu2);
724    Umax(1) = 2*M_PI;
725    Umax(2) = TheCurveTool::LastParameter(Cu1);
726    Umax(3) = TheCurveTool::LastParameter(Cu2);
727    Ufirst(1) = M_PI;
728    Ufirst(2) = Param1;
729    Ufirst(3) = Param2;
730    tol(1) = 2.e-15*M_PI;
731    tol(2) = TheCurveTool::EpsX(Cu1,Abs(Tolerance));
732    tol(3) = TheCurveTool::EpsX(Cu2,Abs(Tolerance));
733    math_FunctionSetRoot Root(Func,Ufirst,tol,Umin,Umax);
734    if (Root.IsDone()) {
735      Root.Root(Ufirst);
736 #ifdef DEB
737      Standard_Boolean Ok = Func.Value(Ufirst,Umin);
738 #else
739      Func.Value(Ufirst,Umin);
740 #endif
741      gp_Pnt2d point1,point2;
742 //     gp_Vec2d Tan1,Tan2,Nor1,Nor2;
743      gp_Vec2d Tan1,Tan2;
744      TheCurveTool::D1(Cu1,Ufirst(2),point1,Tan1);
745      TheCurveTool::D1(Cu2,Ufirst(3),point2,Tan2);
746      GccAna_Circ2d3Tan circ(Point3,point1,point2,Tol);
747      if (circ.IsDone()) {
748        cirsol = circ.ThisSolution(1);
749        gp_Pnt2d centre(cirsol.Location());
750        gp_Vec2d Tan3(-Sin(Ufirst(1)),Cos(Ufirst(1)));
751        Standard_Real normetan1 = Tan1.Magnitude();
752        Standard_Real normetan2 = Tan2.Magnitude();
753        Standard_Real normetan3 = Tan3.Magnitude();
754        gp_Vec2d Vec1(point1,centre);
755        gp_Vec2d Vec2(point2,centre);
756        gp_Vec2d Vec3(Point3,centre);
757        Standard_Real normevec1 = Vec1.Magnitude();
758        Standard_Real normevec2 = Vec2.Magnitude();
759        Standard_Real normevec3 = Vec3.Magnitude();
760        Standard_Real dot1,dot2,dot3;
761        if (normevec1 >= gp::Resolution() && normetan1 >= gp::Resolution()) {
762          dot1 = Vec1.Dot(Tan1)/(normevec1*normetan1);
763        }
764        else { dot1 = 0.; }
765        if (normevec2 >= gp::Resolution() && normetan2 >= gp::Resolution()) {
766          dot2 = Vec2.Dot(Tan2)/(normevec2*normetan2);
767        }
768        else { dot2 = 0.; }
769        if (normevec3 >= gp::Resolution() && normetan3 >= gp::Resolution()) {
770          dot3 = Vec3.Dot(Tan3)/(normevec3*normetan3);
771        }
772        else { dot3 = 0.; }
773        Tol = 1.e-12;
774        if (dot1 <= Tol && dot2 <=Tol && dot3 <= Tol) {
775          Standard_Real Angle1 = Vec1.Angle(Tan1);
776          if (Qualified1.IsUnqualified()||
777              (Qualified1.IsEnclosing()&&Angle1<=0.)||
778              (Qualified1.IsOutside() && Angle1 >= 0) ||
779              (Qualified1.IsEnclosed() && Angle1 <= 0.)) {
780            Angle1 = Vec2.Angle(Tan2);
781            if (Qualified1.IsUnqualified() ||
782                (Qualified1.IsEnclosing()&&Angle1<=0.)||
783                (Qualified1.IsOutside() && Angle1 >= 0) ||
784                (Qualified1.IsEnclosed() && Angle1 <= 0.)) {
785              qualifier1 = Qualified1.Qualifier();
786              qualifier2 = Qualified2.Qualifier();
787              qualifier3 = GccEnt_noqualifier;
788              pararg1 = Ufirst(2);
789              par1sol = 0.;
790              pnttg1sol = point1;
791              pararg2 = Ufirst(3);
792              pnttg2sol = point2;
793              par2sol = 0.;
794              pararg3 = 0.;
795              pnttg3sol = Point3;
796              par3sol = 0.;
797              WellDone = Standard_True;
798            }
799          }
800        }
801      }
802    }
803  }
804
805 GccIter_Circ2d3Tan::
806    GccIter_Circ2d3Tan (const TheQualifiedCurve& Qualified1 ,
807                           const gp_Pnt2d&          Point2     ,
808                           const gp_Pnt2d&          Point3     ,
809                           const Standard_Real      Param1     ,
810                           const Standard_Real      Tolerance     ) {
811
812    TheSame1 = Standard_False;
813    TheSame2 = Standard_False;
814    TheSame3 = Standard_False;
815    par1sol = 0.;
816    par2sol = 0.;
817    par3sol = 0.;
818    pararg1 = 0.;
819    pararg2 = 0.;
820    pararg3 = 0.;
821
822    Standard_Real Tol = Abs(Tolerance);
823    WellDone = Standard_False;
824    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
825          Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
826      GccEnt_BadQualifier::Raise();
827      return;
828    }
829    gp_Dir2d dirx(1.,0.);
830    gp_Circ2d C1(gp_Ax2d(Point2,dirx),0.);
831    gp_Circ2d C2(gp_Ax2d(Point3,dirx),0.);
832    TheCurve Cu1 = Qualified1.Qualified();
833    GccIter_FuncTCuCuCu Func(C1,C2,Cu1);
834    math_Vector Umin(1,3);
835    math_Vector Umax(1,3);
836    math_Vector Ufirst(1,3);
837    math_Vector tol(1,3);
838    Umin(1) = 0.;
839    Umin(2) = 0.;
840    Umin(3) = TheCurveTool::FirstParameter(Cu1);
841    Umax(1) = 2*M_PI;
842    Umax(2) = 2*M_PI;
843    Umax(3) = TheCurveTool::LastParameter(Cu1);
844    Ufirst(1) = M_PI;
845    Ufirst(2) = M_PI;
846    Ufirst(3) = Param1;
847    tol(1) = 2.e-15*M_PI;
848    tol(2) = 2.e-15*M_PI;
849    tol(3) = TheCurveTool::EpsX(Cu1,Abs(Tolerance));
850    math_FunctionSetRoot Root(Func,Ufirst,tol,Umin,Umax);
851    if (Root.IsDone()) {
852      Root.Root(Ufirst);
853 #ifdef DEB
854      Standard_Boolean Ok = Func.Value(Ufirst,Umin);
855 #else
856      Func.Value(Ufirst,Umin);
857 #endif
858      gp_Pnt2d point3;
859 //     gp_Vec2d Tan3,Nor3;
860      gp_Vec2d Tan3;
861      TheCurveTool::D1(Cu1,Ufirst(3),point3,Tan3);
862      GccAna_Circ2d3Tan circ(Point2,Point3,point3,Tol);
863      if (circ.IsDone()) { 
864        cirsol = circ.ThisSolution(1);
865        gp_Pnt2d centre(cirsol.Location());
866        gp_Vec2d Tan2(-Sin(Ufirst(2)),Cos(Ufirst(2)));
867        gp_Vec2d Tan1(-Sin(Ufirst(1)),Cos(Ufirst(1)));
868        Standard_Real normetan1 = Tan1.Magnitude();
869        Standard_Real normetan2 = Tan2.Magnitude();
870        Standard_Real normetan3 = Tan3.Magnitude();
871        gp_Vec2d Vec1(Point2,centre);
872        gp_Vec2d Vec2(Point3,centre);
873        gp_Vec2d Vec3(point3,centre);
874        Standard_Real normevec1 = Vec1.Magnitude();
875        Standard_Real normevec2 = Vec2.Magnitude();
876        Standard_Real normevec3 = Vec3.Magnitude();
877        Standard_Real dot1,dot2,dot3;
878        if (normevec1 >= gp::Resolution() && normetan1 >= gp::Resolution()) {
879          dot1 = Vec1.Dot(Tan1)/(normevec1*normetan1);
880        }
881        else { dot1 = 0.; }
882        if (normevec2 >= gp::Resolution() && normetan2 >= gp::Resolution()) {
883          dot2 = Vec2.Dot(Tan2)/(normevec2*normetan2);
884        }
885        else { dot2 = 0.; }
886        if (normevec3 >= gp::Resolution() && normetan3 >= gp::Resolution()) {
887          dot3 = Vec3.Dot(Tan3)/(normevec3*normetan3);
888        }
889        else { dot3 = 0.; }
890        Tol = 1.e-12;
891        if (dot1 <= Tol && dot2 <=Tol && dot3 <= Tol) {
892          Standard_Real Angle1 = Vec1.Angle(Tan1);
893          if (Qualified1.IsUnqualified() ||
894              (Qualified1.IsEnclosing()&&Angle1<=0.)||
895              (Qualified1.IsOutside() && Angle1 >= 0) ||
896              (Qualified1.IsEnclosed() && Angle1 <= 0.)) {
897            qualifier1 = Qualified1.Qualifier();
898            qualifier2 = GccEnt_noqualifier;
899            qualifier3 = GccEnt_noqualifier;
900            pararg1 = Ufirst(3);
901            par1sol = 0.;
902            pnttg1sol = point3;
903            pararg2 = 0.;
904            pnttg2sol = Point2;
905            par2sol = 0.;
906            pararg3 = 0.;
907            pnttg3sol = Point3;
908            par3sol = 0.;
909            WellDone = Standard_True;
910          }
911        }
912      }
913    }
914  }
915
916 GccIter_Circ2d3Tan::
917    GccIter_Circ2d3Tan (const GccEnt_QualifiedLin&  Qualified1 , 
918                        const TheQualifiedCurve&    Qualified2 ,
919                        const gp_Pnt2d&             Point3     ,
920                        const Standard_Real         Param1     ,
921                        const Standard_Real         Param2     ,
922                        const Standard_Real         Tolerance  ) {
923
924    TheSame1 = Standard_False;
925    TheSame2 = Standard_False;
926    TheSame3 = Standard_False;
927    par1sol = 0.;
928    par2sol = 0.;
929    par3sol = 0.;
930    pararg1 = 0.;
931    pararg2 = 0.;
932    pararg3 = 0.;
933
934    Standard_Real Tol = Abs(Tolerance);
935    WellDone = Standard_False;
936    if (!(Qualified1.IsEnclosed() ||
937          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
938        !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || 
939          Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
940      GccEnt_BadQualifier::Raise();
941      return;
942    }
943    gp_Dir2d dirx(1.,0.);
944    gp_Lin2d L1 = Qualified1.Qualified();
945    TheCurve Cu2 = Qualified2.Qualified();
946    gp_Circ2d C3(gp_Ax2d(Point3,dirx),0.);
947    GccIter_FuncTCuCuCu Func(C3,L1,Cu2);
948    math_Vector Umin(1,3);
949    math_Vector Umax(1,3);
950    math_Vector Ufirst(1,3);
951    math_Vector tol(1,3);
952    Umin(2) = RealFirst();
953    Umin(3) = TheCurveTool::FirstParameter(Cu2);
954    Umin(1) = 0.;
955    Umax(2) = RealLast();
956    Umax(3) = TheCurveTool::LastParameter(Cu2);
957    Umax(1) = 2*M_PI;
958    Ufirst(2) = Param1;
959    Ufirst(3) = Param2;
960    Ufirst(1) = M_PI;
961    tol(1) = 2.e-15;
962    tol(2) = 1.e-15;
963    tol(3) = TheCurveTool::EpsX(Cu2,Abs(Tolerance));
964    math_FunctionSetRoot Root(Func,Ufirst,tol,Umin,Umax);
965    if (Root.IsDone()) {
966      Root.Root(Ufirst);
967 #ifdef DEB
968      Standard_Boolean Ok = Func.Value(Ufirst,Umin);
969 #else
970      Func.Value(Ufirst,Umin);
971 #endif
972      gp_Pnt2d centre1(L1.Location());
973      gp_Pnt2d point1(centre1.XY()+Ufirst(2)*L1.Direction().XY());
974      gp_Pnt2d point2;
975      gp_Vec2d Tan2;
976      TheCurveTool::D1(Cu2,Ufirst(2),point2,Tan2);
977      GccAna_Circ2d3Tan circ(point1,point2,Point3,Tol);
978      if (circ.IsDone()) {
979        cirsol = circ.ThisSolution(1);
980        gp_Pnt2d centre(cirsol.Location());
981        Standard_Real pscal=centre.XY().Dot(gp_XY(-L1.Direction().Y(),
982                                         L1.Direction().X()));
983        gp_Vec2d Tan1(L1.Direction().XY());
984        gp_Vec2d Tan3(-Sin(Ufirst(1)),Cos(Ufirst(1)));
985        Standard_Real normetan1 = Tan1.Magnitude();
986        Standard_Real normetan2 = Tan2.Magnitude();
987        Standard_Real normetan3 = Tan3.Magnitude();
988        gp_Vec2d Vec1(point1,centre);
989        gp_Vec2d Vec2(point2,centre);
990        gp_Vec2d Vec3(Point3,centre);
991        Standard_Real normevec1 = Vec1.Magnitude();
992        Standard_Real normevec2 = Vec2.Magnitude();
993        Standard_Real normevec3 = Vec3.Magnitude();
994        Standard_Real dot1,dot2,dot3;
995        if (normevec1 >= gp::Resolution() && normetan1 >= gp::Resolution()) {
996          dot1 = Vec1.Dot(Tan1)/(normevec1*normetan1);
997        }
998        else { dot1 = 0.; }
999        if (normevec2 >= gp::Resolution() && normetan2 >= gp::Resolution()) {
1000          dot2 = Vec2.Dot(Tan2)/(normevec2*normetan2);
1001        }
1002        else { dot2 = 0.; }
1003        if (normevec3 >= gp::Resolution() && normetan3 >= gp::Resolution()) {
1004          dot3 = Vec3.Dot(Tan3)/(normevec3*normetan3);
1005        }
1006        else { dot3 = 0.; }
1007        Tol = 1.e-12;
1008        if (dot1 <= Tol && dot2 <=Tol && dot3 <= Tol) {
1009          if (Qualified1.IsUnqualified() || 
1010              (Qualified1.IsOutside() && pscal <= 0.) ||
1011              (Qualified1.IsEnclosed() && pscal >= 0.)) {
1012            Standard_Real Angle1 = Vec2.Angle(Tan2);
1013            if (Qualified2.IsUnqualified() || 
1014                (Qualified2.IsEnclosing()&&Angle1<=0.)||
1015                (Qualified2.IsOutside() && Angle1 >= 0) ||
1016                (Qualified2.IsEnclosed() && Angle1 <= 0.)) {
1017              qualifier1 = Qualified1.Qualifier();
1018              qualifier2 = Qualified2.Qualifier();
1019              qualifier3 = GccEnt_noqualifier;
1020              pararg1 = Ufirst(2);
1021              par1sol = 0.;
1022              pnttg1sol = point1;
1023              pararg2 = Ufirst(3);
1024              pnttg2sol = point2;
1025              par2sol = 0.;
1026              pararg3 = 0.;
1027              pnttg3sol = Point3;
1028              par3sol = 0.;
1029              WellDone = Standard_True;
1030            }
1031          }
1032        }
1033      }
1034    }
1035  }
1036
1037 GccIter_Circ2d3Tan::
1038    GccIter_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1 , 
1039                        const GccEnt_QualifiedLin&  Qualified2 , 
1040                        const TheQualifiedCurve&    Qualified3 , 
1041                        const Standard_Real         Param1     ,
1042                        const Standard_Real         Param2     ,
1043                        const Standard_Real         Param3     ,
1044                        const Standard_Real         Tolerance  ) {
1045      
1046    TheSame1 = Standard_False;
1047    TheSame2 = Standard_False;
1048    TheSame3 = Standard_False;
1049    par1sol = 0.;
1050    par2sol = 0.;
1051    par3sol = 0.;
1052    pararg1 = 0.;
1053    pararg2 = 0.;
1054    pararg3 = 0.;
1055
1056    Standard_Real Tol = Abs(Tolerance);
1057    WellDone = Standard_False;
1058    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
1059          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
1060        !(Qualified2.IsEnclosed() ||
1061          Qualified2.IsOutside() || Qualified2.IsUnqualified()) ||
1062        !(Qualified3.IsEnclosed() || Qualified3.IsEnclosing() || 
1063          Qualified3.IsOutside() || Qualified3.IsUnqualified())) {
1064      GccEnt_BadQualifier::Raise();
1065      return;
1066    }
1067    gp_Circ2d C1 = Qualified1.Qualified();
1068    gp_Lin2d L2 = Qualified2.Qualified();
1069    TheCurve Cu3 = Qualified3.Qualified();
1070    GccIter_FuncTCuCuCu Func(C1,L2,Cu3);
1071    math_Vector Umin(1,3);
1072    math_Vector Umax(1,3);
1073    math_Vector Ufirst(1,3);
1074    math_Vector tol(1,3);
1075    Umin(1) = 0.;
1076    Umin(2) = RealFirst();
1077    Umin(3) = TheCurveTool::FirstParameter(Cu3);
1078    Umax(1) = 2*M_PI;
1079    Umax(2) = RealLast();
1080    Umax(3) = TheCurveTool::LastParameter(Cu3);
1081    Ufirst(1) = Param1;
1082    Ufirst(2) = Param2;
1083    Ufirst(3) = Param3;
1084    tol(1) = 2.e-15*M_PI;
1085    tol(2) = 1.e-15;
1086    tol(3) = TheCurveTool::EpsX(Cu3,Abs(Tolerance));
1087    math_FunctionSetRoot Root(Func,Ufirst,tol,Umin,Umax);
1088    if (Root.IsDone()) {
1089 #ifdef DEB
1090      Standard_Boolean Ok = Func.Value(Ufirst,Umin);
1091 #else
1092      Func.Value(Ufirst,Umin);
1093 #endif
1094      Root.Root(Ufirst);
1095      gp_Pnt2d centre1(C1.Location());
1096      Standard_Real R1 = C1.Radius();
1097      gp_Pnt2d point1(centre1.XY()+R1*gp_XY(Cos(Ufirst(1)),Sin(Ufirst(1))));
1098      gp_Pnt2d centre2(L2.Location());
1099      gp_Pnt2d point2(centre2.XY()+Ufirst(2)*L2.Direction().XY());
1100      gp_Pnt2d point3;
1101      gp_Vec2d Tan3;
1102      TheCurveTool::D1(Cu3,Ufirst(3),point3,Tan3);
1103      GccAna_Circ2d3Tan circ(point1,point2,point3,Tol);
1104      if (circ.IsDone()) {
1105        cirsol = circ.ThisSolution(1);
1106        gp_Pnt2d centre(cirsol.Location());
1107        gp_Vec2d Tan1(-Sin(Ufirst(1)),Cos(Ufirst(1)));
1108        gp_Vec2d Tan2(L2.Direction().XY());
1109        Standard_Real normetan1 = Tan1.Magnitude();
1110        Standard_Real normetan2 = Tan2.Magnitude();
1111        Standard_Real normetan3 = Tan3.Magnitude();
1112        gp_Vec2d Vec1(point1,centre);
1113        gp_Vec2d Vec2(point2,centre);
1114        gp_Vec2d Vec3(point3,centre);
1115        Standard_Real normevec1 = Vec1.Magnitude();
1116        Standard_Real normevec2 = Vec2.Magnitude();
1117        Standard_Real normevec3 = Vec3.Magnitude();
1118        Standard_Real dot1,dot2,dot3;
1119        if (normevec1 >= gp::Resolution() && normetan1 >= gp::Resolution()) {
1120          dot1 = Vec1.Dot(Tan1)/(normevec1*normetan1);
1121        }
1122        else { dot1 = 0.; }
1123        if (normevec2 >= gp::Resolution() && normetan2 >= gp::Resolution()) {
1124          dot2 = Vec2.Dot(Tan2)/(normevec2*normetan2);
1125        }
1126        else { dot2 = 0.; }
1127        if (normevec3 >= gp::Resolution() && normetan3 >= gp::Resolution()) {
1128          dot3 = Vec3.Dot(Tan3)/(normevec3*normetan3);
1129        }
1130        else { dot3 = 0.; }
1131        Tol = 1.e-12;
1132        if (dot1 <= Tol && dot2 <=Tol && dot3 <= Tol) {
1133          Standard_Real dist = centre1.Distance(centre);
1134          Standard_Real Rsol = cirsol.Radius();
1135          if (Qualified1.IsUnqualified() || 
1136              (Qualified1.IsEnclosing() && Rsol >= R1 && dist <= Rsol)||
1137              (Qualified1.IsOutside() && dist >= Rsol) ||
1138              (Qualified1.IsEnclosed() && Rsol <= R1 && dist <= Rsol)) {
1139            Standard_Real pscal=centre.XY().Dot(gp_XY(-L2.Direction().Y(),
1140                                             L2.Direction().X()));
1141            if (Qualified2.IsUnqualified() || 
1142                (Qualified2.IsOutside() && pscal <= 0.) ||
1143                (Qualified2.IsEnclosed() && pscal >= 0.)) {
1144              Standard_Real Angle1 = Vec3.Angle(Tan3);
1145              if (Qualified3.IsUnqualified() || 
1146                  (Qualified3.IsEnclosing()&&Angle1<=0.)||
1147                  (Qualified3.IsOutside() && Angle1 >= 0) ||
1148                  (Qualified3.IsEnclosed() && Angle1 <= 0.)) {
1149                qualifier1 = Qualified1.Qualifier();
1150                qualifier2 = Qualified2.Qualifier();
1151                qualifier3 = Qualified3.Qualifier();
1152                pararg1 = Ufirst(1);
1153                par1sol = 0.;
1154                pnttg1sol = point1;
1155                pararg2 = Ufirst(2);
1156                pnttg2sol = point2;
1157                par2sol = 0.;
1158                pararg3 = Ufirst(3);
1159                pnttg3sol = point3;
1160                par3sol = 0.;
1161                WellDone = Standard_True;
1162              }
1163            }
1164          }
1165        }
1166      }
1167    }
1168  }
1169
1170 GccIter_Circ2d3Tan::
1171    GccIter_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1 , 
1172                        const TheQualifiedCurve&    Qualified2 ,
1173                        const gp_Pnt2d&             Point3     ,
1174                        const Standard_Real         Param1     ,
1175                        const Standard_Real         Param2     ,
1176                        const Standard_Real         Tolerance  ) {
1177      
1178    TheSame1 = Standard_False;
1179    TheSame2 = Standard_False;
1180    TheSame3 = Standard_False;
1181    par1sol = 0.;
1182    par2sol = 0.;
1183    par3sol = 0.;
1184    pararg1 = 0.;
1185    pararg2 = 0.;
1186    pararg3 = 0.;
1187
1188    Standard_Real Tol = Abs(Tolerance);
1189    WellDone = Standard_False;
1190    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
1191          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
1192        !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || 
1193          Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
1194      GccEnt_BadQualifier::Raise();
1195      return;
1196    }
1197    gp_Circ2d C1 = Qualified1.Qualified();
1198    TheCurve Cu2 = Qualified2.Qualified();
1199    gp_Dir2d dirx(1.,0.);
1200    gp_Circ2d C3(gp_Ax2d(Point3,dirx),0.);
1201    GccIter_FuncTCuCuCu Func(C1,C3,Cu2);
1202    math_Vector Umin(1,3);
1203    math_Vector Umax(1,3);
1204    math_Vector Ufirst(1,3);
1205    math_Vector tol(1,3);
1206    Umin(1) = 0.;
1207    Umin(3) = TheCurveTool::FirstParameter(Cu2);
1208    Umin(2) = 0.;
1209    Umax(1) = 2*M_PI;
1210    Umax(3) = TheCurveTool::LastParameter(Cu2);
1211    Umax(2) = 2*M_PI;
1212    Ufirst(1) = Param1;
1213    Ufirst(2) = M_PI;
1214    Ufirst(3) = Param2;
1215    tol(1) = 2.e-15*M_PI;
1216    tol(2) = 2.e-15*M_PI;
1217    tol(3) = TheCurveTool::EpsX(Cu2,Abs(Tolerance));
1218    math_FunctionSetRoot Root(Func,Ufirst,tol,Umin,Umax);
1219    if (Root.IsDone()) {
1220      Root.Root(Ufirst);
1221 #ifdef DEB
1222      Standard_Boolean Ok = Func.Value(Ufirst,Umin);
1223 #else
1224      Func.Value(Ufirst,Umin);
1225 #endif
1226      gp_Pnt2d centre1(C1.Location());
1227      Standard_Real R1 = C1.Radius();
1228      gp_Pnt2d point1(centre1.XY()+R1*gp_XY(Cos(Ufirst(1)),Sin(Ufirst(1))));
1229      gp_Pnt2d point2;
1230 //     gp_Vec2d Tan2,Nor2;
1231      gp_Vec2d Tan2;
1232      TheCurveTool::D1(Cu2,Ufirst(2),point2,Tan2);
1233      GccAna_Circ2d3Tan circ(point1,point2,Point3,Tol);
1234      if (circ.IsDone()) {
1235        cirsol = circ.ThisSolution(1);
1236        gp_Pnt2d centre(cirsol.Location());
1237        gp_Vec2d Tan1(-Sin(Ufirst(1)),Cos(Ufirst(1)));
1238        gp_Vec2d Tan3(-Sin(Ufirst(3)),Cos(Ufirst(3)));
1239        Standard_Real normetan2 = Tan2.Magnitude();
1240        gp_Vec2d Vec1(point1,centre);
1241        gp_Vec2d Vec2(point2,centre);
1242        gp_Vec2d Vec3(Point3,centre);
1243        Standard_Real normevec1 = Vec1.Magnitude();
1244        Standard_Real normevec2 = Vec2.Magnitude();
1245        Standard_Real normevec3 = Vec3.Magnitude();
1246        Standard_Real dot1,dot2,dot3;
1247        if (normevec1 >= gp::Resolution()) {
1248          dot1 = Vec1.Dot(Tan1)/(normevec1);
1249        }
1250        else { dot1 = 0.; }
1251        if (normevec2 >= gp::Resolution() && normetan2 >= gp::Resolution()) {
1252          dot2 = Vec2.Dot(Tan2)/(normevec2*normetan2);
1253        }
1254        else { dot2 = 0.; }
1255        if (normevec3 >= gp::Resolution()) {
1256          dot3 = Vec3.Dot(Tan3)/(normevec3);
1257        }
1258        else { dot3 = 0.; }
1259        Tol = 1.e-12;
1260        if (dot1 <= Tol && dot2 <=Tol && dot3 <= Tol) {
1261          Standard_Real dist = centre1.Distance(centre);
1262          Standard_Real Rsol = cirsol.Radius();
1263          if (Qualified1.IsUnqualified() || 
1264              (Qualified1.IsEnclosing() && Rsol >= R1 && dist <= Rsol)||
1265              (Qualified1.IsOutside() && dist >= Rsol) ||
1266              (Qualified1.IsEnclosed() && Rsol <= R1 && dist <= Rsol)) {
1267            Standard_Real Angle1 = Vec2.Angle(Tan2);
1268            if (Qualified2.IsUnqualified() || 
1269                (Qualified2.IsEnclosing()&&Angle1<=0.)||
1270                (Qualified2.IsOutside() && Angle1 >= 0) ||
1271                (Qualified2.IsEnclosed() && Angle1 <= 0.)) {
1272              qualifier1 = Qualified1.Qualifier();
1273              qualifier2 = Qualified2.Qualifier();
1274              qualifier3 = GccEnt_noqualifier;
1275              pararg1 = Ufirst(1);
1276              par1sol = 0.;
1277              pnttg1sol = point1;
1278              pararg2 = Ufirst(2);
1279              pnttg2sol = point2;
1280              par2sol = 0.;
1281              pararg3 = 0.;
1282              pnttg3sol = Point3;
1283              par3sol = 0.;
1284              WellDone = Standard_True;
1285            }
1286          }
1287        }
1288      }
1289    }
1290  }
1291
1292 Standard_Boolean GccIter_Circ2d3Tan::
1293    IsDone () const{ return WellDone; }
1294
1295 gp_Circ2d GccIter_Circ2d3Tan::
1296    ThisSolution () const{ return cirsol; }
1297
1298 void GccIter_Circ2d3Tan:: 
1299   WhichQualifier (GccEnt_Position& Qualif1  ,
1300                   GccEnt_Position& Qualif2  ,
1301                   GccEnt_Position& Qualif3  ) const
1302 {
1303   if (!WellDone) { StdFail_NotDone::Raise(); }
1304   else {
1305     Qualif1 = qualifier1;
1306     Qualif2 = qualifier2;
1307     Qualif3 = qualifier3;
1308   }
1309 }
1310
1311 void GccIter_Circ2d3Tan:: 
1312    Tangency1 (Standard_Real&      ParSol ,
1313               Standard_Real&      ParArg ,
1314               gp_Pnt2d&           PntSol ) const{
1315    if (!WellDone) { StdFail_NotDone::Raise(); }
1316    else {
1317      if (TheSame1 == 0) {
1318        ParSol = par1sol;
1319        ParArg = pararg1;
1320        PntSol = pnttg1sol;
1321      }
1322      else { StdFail_NotDone::Raise(); }
1323    }
1324  }
1325
1326 void GccIter_Circ2d3Tan:: 
1327    Tangency2 (Standard_Real&      ParSol         ,
1328               Standard_Real&      ParArg         ,
1329               gp_Pnt2d&  PntSol         ) const{
1330    if (!WellDone) { StdFail_NotDone::Raise(); }
1331    else {
1332      ParSol = par2sol;
1333      ParArg = pararg2;
1334      PntSol = pnttg2sol;
1335    }
1336  }
1337
1338 void GccIter_Circ2d3Tan:: 
1339    Tangency3 (Standard_Real&      ParSol         ,
1340               Standard_Real&      ParArg         ,
1341               gp_Pnt2d&  PntSol         ) const{
1342    if (!WellDone) { StdFail_NotDone::Raise(); }
1343    else {
1344      ParSol = par3sol;
1345      ParArg = pararg3;
1346      PntSol = pnttg3sol;
1347    }
1348  }
1349
1350 Standard_Boolean GccIter_Circ2d3Tan::
1351    IsTheSame1 () const
1352 {
1353   if (!WellDone) StdFail_NotDone::Raise();
1354
1355   if (TheSame1 == 0) 
1356     return Standard_False;
1357     
1358   return Standard_True;
1359 }
1360
1361
1362 Standard_Boolean GccIter_Circ2d3Tan::
1363    IsTheSame2 () const
1364 {
1365   if (!WellDone) StdFail_NotDone::Raise();
1366   
1367   if (TheSame3 == 0) 
1368     return Standard_False;
1369   
1370   return Standard_True;
1371   
1372 }
1373
1374 Standard_Boolean GccIter_Circ2d3Tan::
1375    IsTheSame3 () const
1376 {
1377   if (!WellDone) StdFail_NotDone::Raise();
1378  
1379   return Standard_True;
1380 }