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