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