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