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