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