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