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