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