0025720: Incorrect code of math classes can lead to unpredicted behavior of algorithms
[occt.git] / src / Bisector / Bisector_BisecAna.cxx
1 // Created on: 1992-10-19
2 // Created by: Remi GILET
3 // Copyright (c) 1992-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 //  Modified by skv - Fri Jul  1 16:23:17 2005 IDEM(Airbus)
18 //  Modified by skv - Wed Jul  7 17:21:09 2004 IDEM(Airbus)
19
20 #include <Bisector_BisecAna.ixx>
21 #include <Geom2d_Line.hxx>
22 #include <Geom2d_Circle.hxx>
23 #include <Geom2d_Parabola.hxx>
24 #include <Geom2d_Hyperbola.hxx>
25 #include <Geom2d_Ellipse.hxx>
26 #include <Geom2dAdaptor_Curve.hxx>
27 #include <Geom2d_TrimmedCurve.hxx>
28 #include <GccInt_IType.hxx>
29 #include <GccInt_BLine.hxx>
30 #include <GccAna_Circ2dBisec.hxx>
31 #include <GccAna_Pnt2dBisec.hxx>
32 #include <GccAna_CircLin2dBisec.hxx>
33 #include <GccAna_Lin2dBisec.hxx>
34 #include <GccAna_CircPnt2dBisec.hxx>
35 #include <GccAna_LinPnt2dBisec.hxx>
36 #include <gp.hxx>
37 #include <gp_Pnt2d.hxx>
38 #include <ElCLib.hxx>
39 #include <StdFail_NotDone.hxx>
40 #include <IntAna2d_AnaIntersection.hxx>
41 #include <IntAna2d_IntPoint.hxx>
42 #include <IntRes2d_Domain.hxx>
43 #include <IntRes2d_Domain.hxx>
44 #include <IntRes2d_IntersectionSegment.hxx>
45 #include <Geom2dInt_GInter.hxx>
46 #include <Standard_NotImplemented.hxx>
47 #include <Precision.hxx>
48
49 static Standard_Boolean Degenerate(Handle(GccInt_Bisec)& aBisector,
50                                    const Standard_Real   Tolerance);
51
52 //=============================================================================
53 //function :           
54 //=============================================================================
55 Bisector_BisecAna::Bisector_BisecAna()
56 {
57 }
58
59 //=============================================================================
60 //              calcul the distance betweem the point and the bissectrice.              +
61 //              and orientation of the bissectrice.                             +
62 //    apoint        :       point of passage.                                 +
63 //    abisector     :       calculated bissectrice.                          +
64 //    afirstvector  :       first vector. \                                +
65 //    asecondvector :       second vector./ to choose the proper sector.    +
66 //    adirection    :       shows if the bissectrice is interior or exterior.  +
67 //    aparameter    : out : the start parameter of the bissectrice.         +
68 //    asense        : out : the direction of the bissectrice.                        +
69 //    astatus       : out : shows if the bissectrice is preserved.               +
70 //=============================================================================
71 Standard_Real Bisector_BisecAna::Distance (
72    const gp_Pnt2d&             apoint,
73    const Handle(GccInt_Bisec)& abisector,
74    const gp_Vec2d&             afirstvector ,
75    const gp_Vec2d&             asecondvector,
76    const Standard_Real         adirection,
77    Standard_Real&              aparameter,
78    Standard_Boolean&           asense,
79    Standard_Boolean&           astatus)
80 {
81   astatus = Standard_True;
82
83   gp_Hypr2d  gphyperbola;
84   gp_Parab2d gpparabola ;
85   gp_Elips2d gpellipse  ;
86   gp_Circ2d  gpcircle   ;
87   gp_Lin2d   gpline     ;
88
89   Standard_Real distance = 0.;
90   gp_Vec2d tangent;
91   gp_Pnt2d point;
92
93   GccInt_IType type = abisector->ArcType();
94   
95   if (type == GccInt_Lin) {
96     gpline     = abisector->Line();
97     aparameter = ElCLib::Parameter(gpline,apoint);
98     ElCLib::D1(aparameter,gpline,point,tangent);
99   }
100   else if (type == GccInt_Cir) {
101     gpcircle   = abisector->Circle();
102     aparameter = ElCLib::Parameter(gpcircle,apoint);
103     ElCLib::D1(aparameter,gpcircle,point,tangent);
104   }
105   else if (type == GccInt_Hpr) {
106     gphyperbola   = abisector->Hyperbola();
107     aparameter    = ElCLib::Parameter(gphyperbola,apoint);
108     ElCLib::D1(aparameter,gphyperbola,point,tangent);
109   }
110   else if (type == GccInt_Par) {
111     gpparabola   = abisector->Parabola();
112     aparameter   = ElCLib::Parameter(gpparabola,apoint);
113     ElCLib::D1(aparameter,gpparabola,point,tangent);
114   }
115   else if (type == GccInt_Ell) {
116     gpellipse   = abisector->Ellipse();
117     aparameter  = ElCLib::Parameter(gpellipse,apoint);
118     ElCLib::D1(aparameter,gpellipse,point,tangent);
119   }
120
121   distance = apoint.Distance(point);
122
123   gp_Dir2d afirstdir (afirstvector);
124   gp_Dir2d aseconddir(asecondvector);
125   gp_Dir2d tangdir   (tangent);
126   gp_Dir2d secdirrev = aseconddir.Reversed();
127  
128
129 // 1st passage to learn if the curve is in the proper sector
130     
131   if(asense) {
132     // the status is determined only in case on curve ie:
133     // tangent to the bissectrice is bisectrice of two vectors.
134     Standard_Real SinPlat = 1.e-3;
135     if (Abs(afirstdir^aseconddir) < SinPlat) {   //flat
136       if (afirstdir*aseconddir >= 0.0) {       //tangent mixed
137         // correct if the scalar product is close to 1.
138         if (Abs(tangdir*afirstdir) < 0.5) {
139           astatus = Standard_False;            
140         }
141       }
142       else {  // opposed tangents.
143         // correct if the scalar product is close to 0.
144         if (Abs(tangdir*afirstdir) > 0.5 ) { 
145           astatus = Standard_False;
146         }
147       }
148     }
149     else if ((afirstdir^tangdir)*(tangdir^aseconddir) < -1.E-8) {
150       astatus = Standard_False;
151     }
152   }
153   else {
154     asense = Standard_True;
155
156 //  Modified by Sergey KHROMOV - Tue Oct 22 16:35:51 2002 Begin
157 // Replacement of -1.E-8 for a tolerance 1.e-4
158     Standard_Real aTol = 1.e-4;
159
160     if ((afirstdir^secdirrev)*adirection < -0.1) {   // input
161       if((afirstdir^tangdir)*adirection < aTol &&
162          (secdirrev^tangdir)*adirection < aTol) asense = Standard_False;
163     }
164     else if((afirstdir^secdirrev)*adirection > 0.1) { // output
165       if((afirstdir^tangdir)*adirection < aTol ||
166          (secdirrev^tangdir)*adirection < aTol) asense = Standard_False;
167     }
168     else  {                                                // flat
169       if (afirstdir.Dot(secdirrev) > 0.) {                // tangent 
170         if ((afirstdir^tangdir)*adirection < 0.) asense = Standard_False;
171       }
172       else{                                                // turn back
173 //  Modified by Sergey KHROMOV - Thu Oct 31 14:16:53 2002
174 //      if ((afirstdir.Dot(tangdir))*adirection > 0.) asense = Standard_False;
175         if (afirstdir.Dot(tangdir) < 0.) asense = Standard_False;
176 //  Modified by Sergey KHROMOV - Thu Oct 31 14:16:54 2002
177       }
178     }
179 //  Modified by Sergey KHROMOV - Tue Oct 22 16:35:51 2002 End
180   }
181   return distance;
182 }
183
184 //===========================================================================
185 //    calculate the bissectrice between two curves coming from a point.         +
186 //                                                                          +
187 //   afirstcurve   : \ curves the bissectrice between which will be calculated.      +
188 //   asecondcurve  : /                                          +
189 //   apoint        :   point through which the bissectrice should pass.         +
190 //   afirstvector  : \ vectors to find the sector where       +
191 //   asecondvector : / the bissectrice should be located.                      +
192 //   adirection    :   shows the side of the bissectrice to be preserved.       +
193 //   tolerance     :   threshold starting from which the bisectrices are degenerated +
194 //===========================================================================
195 void Bisector_BisecAna::Perform(const Handle(Geom2d_Curve)& afirstcurve   ,
196                                 const Handle(Geom2d_Curve)& asecondcurve  ,
197                                 const gp_Pnt2d&             apoint        ,
198                                 const gp_Vec2d&             afirstvector  ,
199                                 const gp_Vec2d&             asecondvector ,
200                                 const Standard_Real         adirection    ,
201                                 const Standard_Real         tolerance     ,
202                                 const Standard_Boolean      oncurve       )
203 {
204
205   Standard_Boolean ok;
206   Standard_Real    distanceptsol,parameter,firstparameter =0.;
207   Standard_Boolean thesense = Standard_False,sense;
208   Standard_Real    distancemini;
209   Standard_Integer nbsolution;
210   Standard_Real    PreConf = Precision::Confusion();
211
212   Handle(Standard_Type) type1 = afirstcurve->DynamicType();
213   Handle(Standard_Type) type2 = asecondcurve->DynamicType();
214   Handle(Geom2d_Curve)  CurveF;
215   Handle(Geom2d_Curve)  CurveE;
216   Handle(GccInt_Bisec)  TheSol;
217
218   gp_Vec2d tan1 = afirstcurve->DN(afirstcurve->LastParameter (),1);
219   gp_Vec2d tan2 = asecondcurve->DN(asecondcurve->FirstParameter(),1);
220   tan1.Reverse();
221
222   if (type1 == STANDARD_TYPE(Geom2d_TrimmedCurve))
223     CurveF = Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)->BasisCurve();
224   else 
225     CurveF = afirstcurve;
226
227   if (type2 == STANDARD_TYPE(Geom2d_TrimmedCurve))
228     CurveE  = Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)->BasisCurve();
229   else
230     CurveE = asecondcurve;
231
232   type1 = CurveF->DynamicType();
233   type2 = CurveE->DynamicType();
234   Standard_Integer cas =0;
235   gp_Circ2d circle1,circle2;
236   gp_Lin2d line1,line2;
237
238 //=============================================================================
239 //                Determination of the nature of arguments.                   +
240 //=============================================================================
241
242   if (type1 == STANDARD_TYPE(Geom2d_Circle)) {
243     if (type2 == STANDARD_TYPE(Geom2d_Circle)) {
244       cas = 1;
245       Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(CurveF);
246       circle1 = C1->Circ2d();
247       Handle(Geom2d_Circle) C2 = Handle(Geom2d_Circle)::DownCast(CurveE);
248       circle2 = C2->Circ2d();
249     }
250     else if (type2 == STANDARD_TYPE(Geom2d_Line)) {
251       cas = 2;
252       Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(CurveF);
253       circle1 = C1->Circ2d();
254       Handle(Geom2d_Line) L2 = Handle(Geom2d_Line)::DownCast(CurveE);
255       line2   = L2->Lin2d();
256     }
257     else {
258       cout << "Not yet implemented" << endl;
259     }
260   }
261   else if (type1 == STANDARD_TYPE(Geom2d_Line)) {
262     if (type2 == STANDARD_TYPE(Geom2d_Circle)) {
263       cas = 2;
264       Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(CurveE);
265       circle1 = C1->Circ2d();
266       Handle(Geom2d_Line) L2 = Handle(Geom2d_Line)::DownCast(CurveF);
267       line2   = L2->Lin2d();
268     }
269     else if (type2 == STANDARD_TYPE(Geom2d_Line)) {
270       cas = 3;
271       Handle(Geom2d_Line) L1 = Handle(Geom2d_Line)::DownCast(CurveF);
272       line1   = L1->Lin2d();
273       Handle(Geom2d_Line) L2 = Handle(Geom2d_Line)::DownCast(CurveE);
274       line2   = L2->Lin2d();
275     }
276     else {
277       cout << "Not yet implemented" << endl;
278     }
279   }
280   else {
281     cout << "Not yet implemented" << endl;
282   }
283
284   switch(cas) {
285
286 //=============================================================================
287 //                       Bissectrice circle - circle.                         +
288 //=============================================================================
289
290   case 1 : {
291     Standard_Real radius1 = circle1.Radius();
292     Standard_Real radius2 = circle2.Radius();
293
294     //-----------------------------------------------------
295     // Particular case when two circles are mixed.
296     //-----------------------------------------------------
297     if (circle1.Location().IsEqual(circle2.Location(),PreConf)&&
298         (Abs(radius1 - radius2) <= PreConf)){
299       gp_Pnt2d P1   = afirstcurve ->Value(afirstcurve ->LastParameter());
300       gp_Pnt2d P2   = asecondcurve->Value(asecondcurve->FirstParameter());
301       gp_Pnt2d PMil;
302       gp_Lin2d line;
303       PMil = gp_Pnt2d((P1.X() + P2.X())/2.,
304                       (P1.Y() + P2.Y())/2.);
305 //  Modified by skv - Fri Jul  1 16:23:32 2005 IDEM(Airbus) Begin
306 //       line = gp_Lin2d(PMil,
307 //                    gp_Dir2d(circle1.Location().X() - PMil.X(), 
308 //                             circle1.Location().Y() - PMil.Y()));
309       if (!circle1.Location().IsEqual(PMil,PreConf)) {
310         // PMil doesn't coinside with the circle location.
311         line = gp_Lin2d(PMil,
312                         gp_Dir2d(circle1.Location().X() - PMil.X(), 
313                                  circle1.Location().Y() - PMil.Y()));
314       } else if (radius1 >= PreConf) {
315         // PMil coinsides with the circle location and radius is greater then 0.
316         line = gp_Lin2d(circle1.Location(),
317                         gp_Dir2d(P1.Y() - circle1.Location().Y(), 
318                                  circle1.Location().X() - P1.X()));
319       } else {
320         // radius is equal to 0. No matter what direction to chose.
321         line = gp_Lin2d(circle1.Location(), gp_Dir2d(1., 0.));
322       }
323 //  Modified by skv - Fri Jul  1 16:23:32 2005 IDEM(Airbus) End
324       Handle(GccInt_Bisec) solution = new GccInt_BLine(line);
325       sense = Standard_False;
326 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
327 //       distanceptsol = Distance(apoint,solution,
328 //                             afirstvector,asecondvector,
329 //                             adirection,parameter,sense,ok);
330       if (oncurve)
331         distanceptsol = Distance(apoint,solution,
332                                  tan2,tan1,
333                                  adirection,parameter,sense,ok);
334       else
335         distanceptsol = Distance(apoint,solution,
336                                  afirstvector,asecondvector,
337                                  adirection,parameter,sense,ok);
338 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
339       Handle(Geom2d_Curve) bisectorcurve = new Geom2d_Line(line);
340       if (!sense)
341         thebisector =new Geom2d_TrimmedCurve(bisectorcurve,
342                                              parameter,
343                                              - Precision::Infinite());
344       else {
345         Standard_Real parameter2;
346         parameter2  = ElCLib::Parameter(line,circle1.Location());
347         parameter2  += 1.e-8;
348         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
349                                               parameter,
350                                               parameter2);
351       }
352       break;
353     } //end of case mixed circles. 
354     
355     if (radius1 < radius2) {
356       gp_Circ2d circle = circle1;
357       circle1 = circle2;
358       circle2 = circle;
359       
360       Standard_Real radius = radius1;
361       radius1 = radius2;
362       radius2 = radius;
363     }
364     
365     // small reframing of circles. in the case when the circles
366     // are OnCurve , if they are almost tangent they become tangent.
367     Standard_Real    EntreAxe = circle1.Location().Distance(circle2.Location());
368     Standard_Real    D1       = 0.5*(radius1 - EntreAxe - radius2);
369     Standard_Boolean CirclesTangent = Standard_False;
370
371 //  Modified by Sergey KHROMOV - Thu Oct 31 12:42:21 2002 End
372 //     if ( oncurve && Abs(D1) <  PreConf) {
373     if ( oncurve && Abs(D1) <  PreConf && tan1.IsParallel(tan2, 1.e-8)) {
374 //  Modified by Sergey KHROMOV - Thu Oct 31 12:42:22 2002 Begin
375       // C2 included in C1 and tangent.
376       circle1.SetRadius(radius1 - D1);
377       circle2.SetRadius(radius2 + D1);
378       CirclesTangent = Standard_True;
379     }
380     else {
381       D1 = 0.5*(radius1 - EntreAxe + radius2);
382 //  Modified by Sergey KHROMOV - Thu Oct 31 12:44:24 2002 Begin
383 //       if (oncurve && Abs(D1) < PreConf) {
384       if (oncurve && Abs(D1) < PreConf && tan1.IsParallel(tan2, 1.e-8)) {
385 //  Modified by Sergey KHROMOV - Thu Oct 31 12:44:25 2002 End
386         // C2 and C1 tangent and disconnected.
387         circle1.SetRadius(radius1 - D1);
388         circle2.SetRadius(radius2 - D1);
389         CirclesTangent = Standard_True;
390       }
391     }   // end of reframing.
392
393     GccAna_Circ2dBisec Bisector(circle1,circle2);
394     
395     distancemini = Precision::Infinite();
396         
397     if (Bisector.IsDone()) {
398       nbsolution = Bisector.NbSolutions();
399       for (Standard_Integer i = 1; i <= nbsolution; i++) {
400         Handle(GccInt_Bisec) solution = Bisector.ThisSolution(i);
401         Degenerate(solution,tolerance);
402         sense = Standard_True;
403         if (oncurve) {
404           distanceptsol = Distance(apoint,solution,
405                                    tan1,tan2,
406                                    adirection,parameter,sense,ok);
407         }
408         else {ok = Standard_True;}
409
410         if (ok) {
411           sense = Standard_False;
412 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
413 //       distanceptsol = Distance(apoint,solution,
414 //                             afirstvector,asecondvector,
415 //                             adirection,parameter,sense,ok);
416           if (oncurve)
417             distanceptsol = Distance(apoint,solution,
418                                      tan2,tan1,
419                                      adirection,parameter,sense,ok);
420           else
421             distanceptsol = Distance(apoint,solution,
422                                      afirstvector,asecondvector,
423                                      adirection,parameter,sense,ok);
424 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
425           if (distanceptsol <= distancemini) {
426             TheSol         = solution;
427             firstparameter = parameter;
428             thesense       = sense;
429             distancemini   = distanceptsol;
430           }
431         }
432       }
433       if (!TheSol.IsNull()) {
434         Handle(Geom2d_Curve) bisectorcurve;
435         GccInt_IType type = TheSol->ArcType();
436         if (type == GccInt_Lin) {
437           gp_Lin2d gpline = TheSol->Line(); 
438           bisectorcurve  = new Geom2d_Line(gpline);
439           
440           Standard_Real  secondparameter =   Precision::Infinite();
441           if (!thesense) secondparameter = - Precision::Infinite();
442           
443           if (oncurve) {
444             // bisectrice right and oncurve 
445             // is cut between two circle of the same radius if circles are tangent.
446
447             // if tangent flat and the bissectrice at the side of the concavity
448             // of one of the circles. the bissectrice is a segment of the point common to 
449             // first of 2 centers of circle that it meets. 
450             // in this case it is important to set a segmnent for 
451             // intersection in Tool2d.
452             
453             if (CirclesTangent) {
454               //  Modified by skv - Tue Apr 13 17:23:31 2004 IDEM(Airbus) Begin
455               //  Trying to correct the line if the distance between it
456               //  and the reference point is too big.
457               if (distancemini > tolerance) {
458                 gp_Pnt2d      aPloc    = gpline.Location();
459                 gp_Dir2d      aNewDir(apoint.XY() - aPloc.XY());
460                 gp_Lin2d      aNewLin(aPloc, aNewDir);
461                 gp_Pnt2d      aCC2     = circle2.Location();
462                 Standard_Real aNewDMin = aNewLin.Distance(apoint);
463                 Standard_Real aTolConf = 1.e-3;
464                 // Hope, aNewDMin is equal to 0...
465
466                 if (aNewLin.Distance(aCC2) <= aTolConf) {
467                   distancemini   =     aNewDMin;
468                   firstparameter =     ElCLib::Parameter(aNewLin, apoint);
469                   bisectorcurve  = new Geom2d_Line(aNewLin);
470                 }
471               }
472               //  Modified by skv - Tue Apr 13 17:23:32 2004 IDEM(Airbus) End
473               if (tan1.Dot(tan2) < 0.) {
474                 // flat and not turn back.
475                 Standard_Real Par1 = ElCLib::Parameter(gpline, circle1.Location());
476                 Standard_Real Par2 = ElCLib::Parameter(gpline, circle2.Location());
477                 Standard_Real MinPar = Min(Par1,Par2);
478                 Standard_Real MaxPar = Max(Par1,Par2);
479                 
480                 if (!thesense) {
481                   if (MaxPar < firstparameter) 
482                     secondparameter = MaxPar - 1.E-8;
483                   else if (MinPar < firstparameter)
484                     secondparameter = MinPar - 1.E-8;
485                 }
486                 else {
487                   if (MinPar > firstparameter) 
488                     secondparameter = MinPar + 1.E-8;
489                   else if (MaxPar > firstparameter)
490                     secondparameter = MaxPar + 1.E-8;
491                 }
492               }
493             }
494           }
495           
496           thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
497                                                 firstparameter,
498                                                 secondparameter);
499         }
500         else if (type == GccInt_Cir) { 
501           bisectorcurve = new Geom2d_Circle(TheSol->Circle());
502           if (!thesense)
503             thebisector = new Geom2d_TrimmedCurve
504               (bisectorcurve,firstparameter-2.0*M_PI,firstparameter,thesense);
505           else
506             thebisector = new Geom2d_TrimmedCurve
507               (bisectorcurve,firstparameter,firstparameter+2.0*M_PI,thesense);
508         }
509         else if (type == GccInt_Hpr) {
510           bisectorcurve = new Geom2d_Hyperbola(TheSol->Hyperbola());
511           if (!thesense)
512             thebisector = new Geom2d_TrimmedCurve
513               (bisectorcurve,firstparameter, - Precision::Infinite());
514           else
515             thebisector = new Geom2d_TrimmedCurve
516               (bisectorcurve,firstparameter,Precision::Infinite());
517         }
518         else if (type == GccInt_Ell) {
519           bisectorcurve = new Geom2d_Ellipse(TheSol->Ellipse());
520           if (!thesense)
521             thebisector = new Geom2d_TrimmedCurve
522               (bisectorcurve,firstparameter-2.0*M_PI,firstparameter,thesense);
523           else
524             thebisector = new Geom2d_TrimmedCurve
525               (bisectorcurve,firstparameter,firstparameter+2.0*M_PI,thesense);
526         }
527       }
528     }
529   }
530   break;
531     
532 //=============================================================================
533 //                       Bissectrice circle - straight.                         +
534 //=============================================================================
535       
536   case 2 : {
537     // small reframing of circles. in case OnCurve.
538     // If the circle and the straight line are almost tangent they become tangent.
539     if (oncurve) {
540       Standard_Real radius1 = circle1.Radius();
541       Standard_Real D1 = (line2.Distance(circle1.Location()) - radius1);
542 //  Modified by Sergey KHROMOV - Wed Oct 30 14:48:43 2002 Begin
543 //       if (Abs(D1) < PreConf) {
544       if (Abs(D1) < PreConf && tan1.IsParallel(tan2, 1.e-8)) {
545 //  Modified by Sergey KHROMOV - Wed Oct 30 14:48:44 2002 End
546         circle1.SetRadius(radius1+D1);
547       }
548     }
549
550     GccAna_CircLin2dBisec Bisector(circle1,line2);
551     
552     distancemini = Precision::Infinite();
553
554     if (Bisector.IsDone()) {
555       nbsolution = Bisector.NbSolutions();
556       for (Standard_Integer i = 1; i <= nbsolution; i++) {
557         Handle(GccInt_Bisec) solution = Bisector.ThisSolution(i);
558         Degenerate(solution,tolerance);
559         sense = Standard_True;
560         distanceptsol = Distance(apoint,solution,tan1,tan2,
561                                  adirection,parameter,sense,ok);
562         if (ok || !oncurve) {
563           sense = Standard_False;
564 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
565 //       distanceptsol = Distance(apoint,solution,
566 //                             afirstvector,asecondvector,
567 //                             adirection,parameter,sense,ok);
568           if (oncurve)
569             distanceptsol = Distance(apoint,solution,
570                                      tan2,tan1,
571                                      adirection,parameter,sense,ok);
572           else
573             distanceptsol = Distance(apoint,solution,
574                                      afirstvector,asecondvector,
575                                      adirection,parameter,sense,ok);
576 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
577           if (distanceptsol <= distancemini) {
578             TheSol         = solution;
579             firstparameter = parameter;
580             thesense       = sense;
581             distancemini   = distanceptsol+1.e-8;
582           }
583         }
584       }
585       if (!TheSol.IsNull()) {
586         GccInt_IType type = TheSol->ArcType();
587         Handle(Geom2d_Curve) bisectorcurve;
588         if (type == GccInt_Lin) {
589           // -----------------------------------------------------------------
590           // If the bisectrice is a line 
591           //       => the straight line is tangent to the circle.
592           //       It the part of bisectrice concerned is at the side of the center.
593           //       => the bisectrice is limited by the point and the center of the circle.
594           // Note : In the latter case the bisectrice is a degenerated parabole.
595           // -----------------------------------------------------------------
596           gp_Pnt2d      circlecenter;
597           gp_Lin2d      gpline;
598           Standard_Real secondparameter;
599           
600           circlecenter    = circle1.Location();
601           gpline          = TheSol->Line(); 
602           secondparameter = ElCLib::Parameter(gpline, circlecenter);
603           bisectorcurve   = new Geom2d_Line(gpline);
604
605           if (!thesense) {
606             if (secondparameter > firstparameter) {
607               secondparameter = - Precision::Infinite();
608             }
609             else {
610               secondparameter = secondparameter - 1.E-8;
611             }
612           }
613           else {
614             if (secondparameter < firstparameter) {
615               secondparameter = Precision::Infinite();
616             }
617             else {
618               secondparameter = secondparameter + 1.E-8;
619             }
620           }
621           
622           thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
623                                                 firstparameter,
624                                                 secondparameter);
625         }
626         else if (type == GccInt_Par) {
627           bisectorcurve = new Geom2d_Parabola(TheSol->Parabola());
628           if (!thesense)
629             thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
630                                                   firstparameter,
631                                                   - Precision::Infinite());
632           else
633             thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
634                                                   firstparameter,
635                                                   Precision::Infinite());
636         }
637       }
638     }
639   }
640     break;
641     
642 //=============================================================================
643 //                       Bissectrice straight - straight.                     +
644 //=============================================================================
645   case 3 : {
646     gp_Dir2d Direc1(line1.Direction());
647     gp_Dir2d Direc2(line2.Direction());
648     gp_Lin2d line;
649     distancemini = Precision::Infinite();
650
651 //  Modified by Sergey KHROMOV - Tue Sep 10 15:58:43 2002 Begin
652 //  Change to the same criterion as in MAT2d_Circuit.cxx:
653 //         method MAT2d_Circuit::InitOpen(..)
654 //     if (Direc1.IsParallel(Direc2,RealEpsilon())) {
655     if (Direc1.IsParallel(Direc2,1.e-8)) {
656 //  Modified by Sergey KHROMOV - Tue Sep 10 15:58:45 2002 End
657       if (line1.Distance(line2.Location())/2. <= Precision::Confusion())
658         line = gp_Lin2d(apoint,gp_Dir2d(-line1.Direction().Y(),
659                                         line1.Direction().X()));
660       else
661         line = gp_Lin2d(apoint,line2.Direction());
662       
663       Handle(GccInt_Bisec) solution = new GccInt_BLine(line);
664 //  Modified by skv - Wed Jul  7 17:21:09 2004 IDEM(Airbus) Begin
665 //       sense = Standard_True;
666 //       distanceptsol = Distance(apoint,solution,
667 //                             tan1,tan2,
668 //                             adirection,parameter,sense,ok);
669 //       theSense = sense;
670 //       if (ok || !oncurve) {
671       sense = Standard_False;
672 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
673 //       distanceptsol = Distance(apoint,solution,
674 //                             afirstvector,asecondvector,
675 //                             adirection,parameter,sense,ok);
676       if (oncurve)
677         distanceptsol = Distance(apoint,solution,
678                                  tan2,tan1,
679                                  adirection,parameter,sense,ok);
680       else
681         distanceptsol = Distance(apoint,solution,
682                                  afirstvector,asecondvector,
683                                  adirection,parameter,sense,ok);
684 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
685 //      if (distanceptsol <= distancemini) {
686       firstparameter = parameter;
687       Handle(Geom2d_Curve) bisectorcurve;
688       bisectorcurve = new Geom2d_Line(line);
689       if (!sense)
690         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
691                                               firstparameter,
692                                               - Precision::Infinite());
693       else
694         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
695                                               firstparameter,
696                                               Precision::Infinite());
697 //      }
698 //       }
699 //  Modified by skv - Wed Jul  7 17:21:09 2004 IDEM(Airbus) End
700     }
701     else {
702       gp_Lin2d l(apoint,gp_Dir2d(Direc2.XY()-Direc1.XY()));
703       Handle(GccInt_Bisec) solution = new GccInt_BLine(l);
704       Standard_Boolean ok;
705       sense = Standard_False;
706 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
707 //       distanceptsol = Distance(apoint,solution,
708 //                             afirstvector,asecondvector,
709 //                             adirection,parameter,sense,ok);
710       if (oncurve)
711         distanceptsol = Distance(apoint,solution,
712                                  tan2,tan1,
713                                  adirection,parameter,sense,ok);
714       else
715         distanceptsol = Distance(apoint,solution,
716                                  afirstvector,asecondvector,
717                                  adirection,parameter,sense,ok);
718 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
719       if (ok || !oncurve) {
720         thesense = sense;
721         distancemini = distanceptsol;
722       }
723       TheSol = new GccInt_BLine(l);
724       Handle(Geom2d_Curve) bisectorcurve;
725       bisectorcurve = new Geom2d_Line(TheSol->Line());
726       if (!thesense)
727         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
728                                               0.,- Precision::Infinite());
729       else
730         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
731                                               0., Precision::Infinite());
732     }
733   }
734     break;
735
736     default :
737       StdFail_NotDone::Raise();
738     break;
739   }
740 }
741
742
743 //===========================================================================
744 //  calculate the bissectrice between a curve and a point and starting in a point. +
745 //                                                                          +
746 //   afirstcurve   : \ curve and point the bissectrice between which is calculated +
747 //   asecondpoint  : /                                          +
748 //   apoint        :   point through which the bissectrice should pass.         +
749 //   afirstvector  : \ vectors to determine the sector in which      +
750 //   asecondvector : / the bissectrice should be located.                      +
751 //   adirection    :   shows the side of the bissectrice to be preserved.       +
752 //   tolerance     :   threshold starting from which the bisectrices are degenerated+
753 //===========================================================================
754
755 void Bisector_BisecAna::Perform(const Handle(Geom2d_Curve)& afirstcurve  ,
756                                 const Handle(Geom2d_Point)& asecondpoint ,
757                                 const gp_Pnt2d&             apoint       ,
758                                 const gp_Vec2d&             afirstvector ,
759                                 const gp_Vec2d&             asecondvector,
760                                 const Standard_Real         adirection   ,
761                                 const Standard_Real         tolerance    ,
762                                 const Standard_Boolean      oncurve       )
763 {
764   Standard_Boolean ok;
765   Standard_Boolean thesense = Standard_False,sense;
766   Standard_Real    distanceptsol,parameter,firstparameter =0.,secondparameter;
767   Handle(Geom2d_Curve) curve;
768   Handle(GccInt_Bisec) TheSol;
769
770   gp_Circ2d circle;
771   gp_Lin2d  line;
772   gp_Pnt2d  circlecenter;
773
774   Standard_Integer cas = 0;
775
776   Handle(Standard_Type) type = afirstcurve->DynamicType();
777
778   if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
779     curve = (*(Handle(Geom2d_TrimmedCurve)*)&afirstcurve)->BasisCurve();
780   }
781   else {
782     curve = afirstcurve;
783   }
784
785   type = curve->DynamicType();
786 #ifdef OCCT_DEBUG
787   gp_Pnt2d Point(asecondpoint->Pnt2d());
788 #else
789   asecondpoint->Pnt2d();
790 #endif
791   if (type == STANDARD_TYPE(Geom2d_Circle)) {
792     cas = 1;
793     Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(curve);
794     circle = C1->Circ2d();
795   }
796   else if (type == STANDARD_TYPE(Geom2d_Line)) {
797     cas = 2;
798     Handle(Geom2d_Line) L1 = Handle(Geom2d_Line)::DownCast(curve);
799     line   = L1->Lin2d();
800   }
801   else {
802     cout << "Not yet implemented" << endl;
803   }
804
805   switch(cas) {
806
807 //=============================================================================
808 //                       Bissectrice point - circle.                          +
809 //=============================================================================
810     case 1 : {
811       GccAna_CircPnt2dBisec Bisector(circle, asecondpoint->Pnt2d(), tolerance);
812       Standard_Real distancemini = Precision::Infinite();
813       if (Bisector.IsDone()) {
814         Standard_Integer nbsolution = Bisector.NbSolutions();
815         for (Standard_Integer i = 1; i <= nbsolution; i++) {
816           Handle(GccInt_Bisec) solution = Bisector.ThisSolution(i);
817           Degenerate(solution,tolerance);
818           sense = Standard_False;
819           distanceptsol = Distance(apoint,solution,
820                                    afirstvector,asecondvector,
821                                    adirection,parameter,sense,ok);
822
823           if (distanceptsol <= distancemini) {
824             TheSol = solution;
825             firstparameter = parameter;
826             thesense = sense;
827             distancemini = distanceptsol;
828           }
829         }
830         if (!TheSol.IsNull()) {
831           GccInt_IType type = TheSol->ArcType();
832           Handle(Geom2d_Curve) bisectorcurve;
833           if (type == GccInt_Lin) { 
834
835 // ----------------------------------------------------------------------------
836 // If the bisectrice is a line 
837 //       => the point is on the circle.
838 //       If the part of bisectrice concerned is at the side of the center.
839 //       => the bisectrice is limited by the point and the center of the circle.
840 // Note : In this latter case the bisectrice is actually an ellipse of small null axis.
841 // ----------------------------------------------------------------------------
842             
843             circlecenter    = circle.Location();
844             line            = TheSol->Line(); 
845             secondparameter = ElCLib::Parameter(line, circlecenter);
846             bisectorcurve   = new Geom2d_Line(line);
847
848             if (!thesense) {
849               if (secondparameter > firstparameter) {
850                 secondparameter = - Precision::Infinite();
851               }
852               else {
853                 secondparameter = secondparameter - 1.E-8;
854               }
855             }
856             else {
857               if (secondparameter < firstparameter) {
858                 secondparameter = Precision::Infinite();
859               }
860               else {
861                 secondparameter = secondparameter + 1.E-8;
862               }
863             }
864
865             thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
866                                                   firstparameter,
867                                                   secondparameter);
868
869           }
870           else if (type == GccInt_Cir) { 
871             bisectorcurve = new Geom2d_Circle(TheSol->Circle());
872             if (!thesense)
873               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
874                                                     firstparameter-2.0*M_PI,
875                                                     firstparameter,
876                                                     thesense);
877             else
878               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
879                                                     firstparameter,
880                                                     firstparameter+2.0*M_PI,
881                                                     thesense);
882           }
883           else if (type == GccInt_Hpr) {
884             bisectorcurve=new Geom2d_Hyperbola(TheSol->Hyperbola());
885             if (!thesense)
886               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
887                                                     firstparameter,
888                                                     - Precision::Infinite());
889             else
890               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
891                                                     firstparameter,
892                                                     Precision::Infinite());
893           }
894           else if (type == GccInt_Ell) {
895             bisectorcurve = new Geom2d_Ellipse(TheSol->Ellipse());
896             if (!thesense)
897               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
898                                                     firstparameter-2.0*M_PI,
899                                                     firstparameter,
900                                                     thesense);
901             else
902               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
903                                                     firstparameter,
904                                                     firstparameter+2.0*M_PI,
905                                                     thesense);
906           }
907         }
908       }
909     }
910       break;
911
912 //=============================================================================
913 //                       Bissectrice point - straight.                          +
914 //=============================================================================
915     case 2 : {
916       GccAna_LinPnt2dBisec Bisector(line,asecondpoint->Pnt2d());
917       
918 #ifdef OCCT_DEBUG
919       gp_Vec2d V(line.Direction());
920 #else
921       line.Direction();
922 #endif
923       Handle(GccInt_Bisec) solution = Bisector.ThisSolution();
924       Degenerate(solution,tolerance);      
925       GccInt_IType type = solution->ArcType();
926       Handle(Geom2d_Curve) bisectorcurve;
927       
928       if (type == GccInt_Lin) {
929         bisectorcurve = new Geom2d_Line(solution->Line());
930       }
931       else if (type == GccInt_Par) {
932         bisectorcurve = new Geom2d_Parabola(solution->Parabola());
933       }
934       sense = Standard_False;
935       distanceptsol = Distance(apoint,solution,
936                                afirstvector,asecondvector,
937                                adirection,parameter,sense,ok);
938
939       if (ok || !oncurve) {
940         firstparameter = parameter;
941         thesense = sense;
942       }
943       
944       if (!thesense)
945         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
946                                               firstparameter, 
947                                               - Precision::Infinite());
948       else
949         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
950                                               firstparameter, 
951                                               Precision::Infinite());
952     }
953       break;
954
955     default:
956       {
957         cout << "Not yet implemented" << endl;
958         break;
959       }
960     }
961 }
962
963
964 //===========================================================================
965 //  calculate the bissectrice between a curve and a point starting at a point. +
966 //                                                                          +
967 //   afirstpoint   : \ curves between which the                             +
968 //   asecondcurve  : / bissectrice is calculated.                           +
969 //   apoint        :   point through which the bissectrice should pass.     +
970 //   afirstvector  : \ vectors to determine the secteur in which            +
971 //   asecondvector : / the bissectrice should be located.                   +
972 //   adirection    :   shows the side of the bissectrice to be preserved.   +
973 //   tolerance     :   threshold at which the bisectrices become degenerated+
974 //===========================================================================
975
976 void Bisector_BisecAna::Perform(const Handle(Geom2d_Point)& afirstpoint  ,
977                                 const Handle(Geom2d_Curve)& asecondcurve ,
978                                 const gp_Pnt2d&             apoint       ,
979                                 const gp_Vec2d&             afirstvector ,
980                                 const gp_Vec2d&             asecondvector,
981                                 const Standard_Real         adirection   ,
982 //                              const Standard_Real         tolerance    ,
983                                 const Standard_Real             ,
984                                 const Standard_Boolean      oncurve       )
985      
986 {
987   Standard_Real  adirectionreverse = - adirection;
988   Perform(asecondcurve        , 
989           afirstpoint         , 
990           apoint              , 
991           asecondvector       ,
992           afirstvector        ,
993           adirectionreverse   ,
994 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
995           0.,
996 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
997           oncurve             );
998 }
999
1000 //===========================================================================
1001 //        calculate the bissectrice between two points starting at a point. +
1002 //                                                                          +
1003 //   afirstpoint   : \ curves between which the                             +
1004 //   asecondpoint  : / bissectrice is calculated.                           +
1005 //   apoint        :   point through which the bissectrice should pass.     +
1006 //   afirstvector  : \ vectors to determine the sector in which the         +
1007 //   asecondvector : / bissectrice should be located.                       +
1008 //   adirection    :   shows the side of the bissectrice to be preserved.   +
1009 //===========================================================================
1010
1011 void Bisector_BisecAna::Perform(const Handle(Geom2d_Point)& afirstpoint  ,
1012                                 const Handle(Geom2d_Point)& asecondpoint ,
1013                                 const gp_Pnt2d&             apoint       ,
1014                                 const gp_Vec2d&             afirstvector ,
1015                                 const gp_Vec2d&             asecondvector,
1016                                 const Standard_Real         adirection   ,
1017 //                              const Standard_Real         tolerance    ,
1018                                 const Standard_Real             ,
1019                                 const Standard_Boolean      oncurve       )
1020 {
1021   Standard_Boolean sense,ok;
1022   Standard_Real parameter;
1023
1024   GccAna_Pnt2dBisec bisector(afirstpoint->Pnt2d(),asecondpoint->Pnt2d());
1025   gp_Lin2d line = bisector.ThisSolution();
1026   Handle(GccInt_Bisec) solution = new GccInt_BLine(line);
1027
1028   sense = Standard_False;
1029   Distance(apoint,solution,
1030                            afirstvector,asecondvector,
1031                            adirection,parameter,sense,ok);
1032   if (ok || !oncurve) {
1033     Handle(Geom2d_Curve) bisectorcurve = new Geom2d_Line(line);
1034     if (!sense)
1035       thebisector=new Geom2d_TrimmedCurve(bisectorcurve,
1036                                           parameter,- Precision::Infinite());
1037     else
1038       thebisector =new Geom2d_TrimmedCurve(bisectorcurve,
1039                                            parameter,Precision::Infinite());
1040   }
1041 }
1042
1043 //=============================================================================
1044 //function : IsExtendAtStart
1045 //purpose  :
1046 //=============================================================================
1047 Standard_Boolean Bisector_BisecAna::IsExtendAtStart() const
1048 {
1049   return Standard_False;
1050 }
1051
1052 //=============================================================================
1053 //function : IsExtendAtEnd
1054 //purpose  :
1055 //=============================================================================
1056 Standard_Boolean Bisector_BisecAna::IsExtendAtEnd() const
1057 {
1058   return Standard_False;
1059 }
1060
1061 //=============================================================================
1062 //function : SetTrim
1063 //purpose  : Restriction of the bissectrice by the domain of the curve Cu.
1064 //           The domain of the curve is the set of points that are closer to the
1065 //           than to its extremities. 
1066 //           For the calculation the domain is extended. Extension of Epsilon1 of the 
1067 //           First and the Last parameter of the curve.
1068 //=============================================================================
1069 //void Bisector_BisecAna::SetTrim(const Handle(Geom2d_Curve)& Cu)
1070 void Bisector_BisecAna::SetTrim(const Handle(Geom2d_Curve)& )
1071 {
1072 /*
1073   Handle(Standard_Type)       Type;
1074   Handle(Geom2d_Curve)        TheCurve;
1075   Handle(Geom2d_Circle)       CircleCu;
1076   Handle(Geom2d_Line)         LineCu;
1077   Handle(Geom2d_Curve)        FirstLimit;
1078   Handle(Geom2d_Curve)        LastLimit;
1079
1080   gp_Lin2d                    gpLine;
1081   gp_Pnt2d                    P, PFirst, PLast, FirstPointBisector, Center;
1082   gp_Vec2d                    TanFirst, TanLast;
1083
1084   IntRes2d_Domain             FirstDomain;
1085   IntRes2d_Domain             LastDomain ;
1086   
1087   Standard_Real   UFirst, ULast, UB1, UB2;
1088   Standard_Real   UBisInt1, UBisInt2, Utrim;
1089   Standard_Real   Distance;
1090   Standard_Real   Radius;
1091
1092   Standard_Real Epsilon1  = 1.E-6; // Epsilon sur le parametre de la courbe.
1093   Standard_Real Tolerance = 1.E-8; // Tolerance pour les intersections.
1094
1095    Type = Cu->DynamicType();
1096
1097   if (Type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
1098     TheCurve = Handle(Geom2d_TrimmedCurve)::DownCast(Cu)->BasisCurve();
1099     Type     = TheCurve->DynamicType();
1100   }
1101   else {
1102     TheCurve = Cu;
1103   }
1104
1105   if (Type == STANDARD_TYPE(Geom2d_Circle)) {
1106     CircleCu = Handle(Geom2d_Circle)::DownCast(TheCurve);
1107   }
1108   else {
1109     LineCu = Handle(Geom2d_Line)::DownCast(TheCurve);
1110   }
1111
1112   // Recuperation de UFirst, ULast.
1113   // -------------------------------
1114   UFirst   = Cu->FirstParameter();
1115   ULast    = Cu->LastParameter();
1116
1117   // Creation des lignes Limites du domaine si elles existent.
1118   // et Determination de leur domaine d intersection.
1119   // ---------------------------------------------------------
1120   if (Type == STANDARD_TYPE(Geom2d_Circle)) {
1121     CircleCu->D1(UFirst,PFirst,TanFirst);
1122     CircleCu->D1(ULast ,PLast ,TanLast);
1123     Radius = CircleCu->Radius();
1124
1125     if (PFirst.Distance(PLast) > 2.*Epsilon1 && Radius > Epsilon1) {
1126       Center     = CircleCu->Location();
1127       P          = PFirst.Translated( - (Epsilon1/Radius)*TanFirst );
1128
1129       FirstLimit = new Geom2d_Line(P,
1130                                    gp_Dir2d(PFirst.X() - Center.X(), 
1131                                             PFirst.Y() - Center.Y()));
1132       P          = PLast .Translated( (Epsilon1/Radius)*TanLast );
1133
1134       LastLimit  = new Geom2d_Line(P,
1135                                    gp_Dir2d(PLast.X() - Center.X(), 
1136                                             PLast.Y() - Center.Y()));
1137
1138       Geom2dAdaptor_Curve AFirstLimit(FirstLimit);
1139       Geom2dAdaptor_Curve ALastLimit (LastLimit);
1140       Geom2dInt_GInter Intersect(AFirstLimit , FirstDomain,   
1141                                  ALastLimit  , LastDomain ,
1142                                  Tolerance   , Tolerance     );
1143       
1144       if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1145         if (Intersect.NbPoints() >= 1) {
1146           FirstDomain.SetValues(Intersect.Point(1).Value(),
1147                                 Intersect.Point(1).ParamOnFirst(),
1148                                 Tolerance,Standard_True);
1149           LastDomain. SetValues(Intersect.Point(1).Value(),
1150                                 Intersect.Point(1).ParamOnSecond(),
1151                                 Tolerance,Standard_True);
1152         }
1153       }
1154     }  
1155   }
1156   else if (Type == STANDARD_TYPE(Geom2d_Line)) {
1157     gpLine = LineCu->Lin2d();
1158     if (UFirst > - Precision::Infinite()){
1159       P          = LineCu->Value(UFirst - Epsilon1);
1160       FirstLimit = new Geom2d_Line(gpLine.Normal(P)) ;
1161     }
1162     if (ULast < Precision::Infinite()) {
1163       P         = LineCu->Value(ULast + Epsilon1);
1164       LastLimit = new Geom2d_Line(gpLine.Normal(P));
1165     }
1166   }
1167   else {
1168     Standard_NotImplemented::Raise();
1169   }
1170     
1171   // Determination domaine d intersection de la Bissectrice.
1172   // -------------------------------------------------------
1173   UB1 = thebisector->FirstParameter();
1174   UB2 = thebisector->LastParameter();
1175   if (UB2 > 10000.) {
1176     UB2 = 10000.;
1177     Handle(Geom2d_Curve)  BasisCurve = thebisector->BasisCurve();
1178     Handle(Standard_Type) Type1 = BasisCurve->DynamicType();
1179     gp_Parab2d gpParabola;
1180     gp_Hypr2d  gpHyperbola;
1181     Standard_Real Focus;
1182     Standard_Real Limit = 50000.;
1183     if (Type1 == STANDARD_TYPE(Geom2d_Parabola)) {
1184       gpParabola = Handle(Geom2d_Parabola)::DownCast(BasisCurve)->Parab2d();
1185       Focus = gpParabola.Focal();
1186       Standard_Real Val1 = Sqrt(Limit*Focus);
1187       Standard_Real Val2 = Sqrt(Limit*Limit);
1188       UB2 = (Val1 <= Val2 ? Val1:Val2);
1189     }
1190     else if (Type1 == STANDARD_TYPE(Geom2d_Hyperbola)) {
1191       gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(BasisCurve)->Hypr2d();
1192       Standard_Real Majr  = gpHyperbola.MajorRadius();
1193       Standard_Real Minr  = gpHyperbola.MinorRadius();
1194       Standard_Real Valu1 = Limit/Majr;
1195       Standard_Real Valu2 = Limit/Minr;
1196       Standard_Real Val1  = Log(Valu1+Sqrt(Valu1*Valu1-1));
1197       Standard_Real Val2  = Log(Valu2+Sqrt(Valu2*Valu2+1));
1198       UB2 = (Val1 <= Val2 ? Val1:Val2);
1199     }
1200   }
1201
1202   IntRes2d_Domain DomainBisector(thebisector->Value(UB1), UB1, Tolerance,
1203                                  thebisector->Value(UB2), UB2, Tolerance);
1204
1205   if (thebisector->BasisCurve()->IsPeriodic()) {
1206     DomainBisector.SetEquivalentParameters(0.0,2.*M_PI);
1207   }
1208   FirstPointBisector = thebisector->Value(UB1);
1209
1210
1211   // Intersection Bisectrice avec FirstLimit => UBisInt1.
1212   // ----------------------------------------------------
1213   UBisInt1 = Precision::Infinite();
1214   if (!FirstLimit.IsNull()) {
1215     Geom2dAdaptor_Curve AdapBis    (thebisector);
1216     Geom2dAdaptor_Curve AFirstLimit(FirstLimit);
1217     Geom2dInt_GInter Intersect(AFirstLimit , FirstDomain,   
1218                                AdapBis     , DomainBisector,
1219                                Tolerance   , Tolerance     );
1220
1221     if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1222       for (Standard_Integer i=1; i<=Intersect.NbPoints(); i++) {
1223         Distance = FirstPointBisector.Distance(Intersect.Point(i).Value());
1224         if (Distance > 2.*Tolerance) {
1225           UBisInt1 = Intersect.Point(i).ParamOnSecond();
1226           break;
1227         }
1228       }
1229     } 
1230   } 
1231   // Intersection Bisectrice avec LastLimit => UBisInt2.
1232   // ---------------------------------------------------
1233   UBisInt2 = Precision::Infinite();
1234   if (!LastLimit.IsNull()) {
1235     Geom2dAdaptor_Curve AdapBis    (thebisector);
1236     Geom2dAdaptor_Curve ALastLimit (LastLimit);
1237     Geom2dInt_GInter Intersect(ALastLimit , LastDomain    ,
1238                                AdapBis    , DomainBisector, 
1239                                Tolerance  , Tolerance     );
1240
1241     if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1242       for (Standard_Integer i=1; i<=Intersect.NbPoints(); i++) {
1243         Distance = FirstPointBisector.Distance(Intersect.Point(i).Value());
1244         if (Distance > 2.*Tolerance) {
1245           UBisInt2 = Intersect.Point(i).ParamOnSecond();
1246           break;
1247         }
1248       }
1249     }
1250   }
1251   // Restriction de la Bissectrice par le point d intersection de plus petit
1252   // parametre.
1253   //------------------------------------------------------------------------
1254   Utrim = (UBisInt1 < UBisInt2) ? UBisInt1 : UBisInt2;
1255   
1256   if (Utrim < UB2 && Utrim > UB1) thebisector->SetTrim(UB1,Utrim);
1257 */
1258 }
1259
1260 void Bisector_BisecAna::SetTrim(const Standard_Real uf, const Standard_Real ul)
1261 {
1262   thebisector->SetTrim(uf, ul);
1263 }
1264 //=============================================================================
1265 //function : Reverse 
1266 //purpose  :
1267 //=============================================================================
1268 void Bisector_BisecAna::Reverse()
1269 {
1270   thebisector->Reverse();
1271 }
1272
1273 //=============================================================================
1274 //function : ReversedParameter 
1275 //purpose  :
1276 //=============================================================================
1277 Standard_Real Bisector_BisecAna::ReversedParameter(const Standard_Real U) const 
1278 {
1279   return thebisector->ReversedParameter(U);
1280 }
1281
1282 //=============================================================================
1283 //function : IsCN
1284 //purpose  :
1285 //=============================================================================
1286 Standard_Boolean Bisector_BisecAna::IsCN(const Standard_Integer N) const 
1287 {
1288   return thebisector->IsCN(N);
1289 }
1290
1291 //=============================================================================
1292 //function : Copy 
1293 //purpose  :
1294 //=============================================================================
1295 Handle(Geom2d_Geometry) Bisector_BisecAna::Copy() const 
1296 {
1297   Handle(Bisector_BisecAna) C = new  Bisector_BisecAna();
1298   C->Init (Handle(Geom2d_TrimmedCurve)::DownCast(thebisector->Copy()));
1299   return C;
1300 }
1301
1302 //=============================================================================
1303 //function : Transform
1304 //purpose  :
1305 //=============================================================================
1306 void Bisector_BisecAna::Transform(const gp_Trsf2d& T)
1307 {
1308   thebisector->Transform(T);
1309 }
1310
1311 //=============================================================================
1312 //function : FirstParameter
1313 //purpose  :
1314 //=============================================================================
1315 Standard_Real Bisector_BisecAna::FirstParameter() const 
1316 {
1317 //  modified by NIZHNY-EAP Thu Feb  3 17:23:42 2000 ___BEGIN___
1318 //  return thebisector->BasisCurve()->FirstParameter();
1319   return thebisector->FirstParameter();
1320 //  modified by NIZHNY-EAP Thu Feb  3 17:23:48 2000 ___END___
1321 }
1322
1323 //=============================================================================
1324 //function : LastParameter
1325 //purpose  :
1326 //=============================================================================
1327 Standard_Real Bisector_BisecAna::LastParameter() const 
1328 {
1329   return thebisector->LastParameter();
1330 }
1331
1332 //=============================================================================
1333 //function : IsClosed
1334 //purpose  :
1335 //=============================================================================
1336 Standard_Boolean Bisector_BisecAna::IsClosed() const 
1337 {
1338   return thebisector->BasisCurve()->IsClosed(); 
1339 }
1340
1341 //=============================================================================
1342 //function : IsPeriodic
1343 //purpose  :
1344 //=============================================================================
1345 Standard_Boolean Bisector_BisecAna::IsPeriodic() const 
1346 {
1347   return thebisector->BasisCurve()->IsPeriodic(); 
1348 }
1349
1350 //=============================================================================
1351 //function : Continuity
1352 //purpose  :
1353 //=============================================================================
1354 GeomAbs_Shape Bisector_BisecAna::Continuity() const 
1355 {
1356  return thebisector->Continuity(); 
1357 }
1358
1359 //=============================================================================
1360 //function : D0 
1361 //purpose  :
1362 //=============================================================================
1363 void Bisector_BisecAna::D0(const Standard_Real U, gp_Pnt2d& P) const 
1364 {
1365   thebisector->BasisCurve()->D0(U,P);
1366 }
1367
1368 //=============================================================================
1369 //function : D1
1370 //purpose  :
1371 //=============================================================================
1372 void Bisector_BisecAna::D1(const Standard_Real U, gp_Pnt2d& P, gp_Vec2d& V1) const 
1373 {
1374   thebisector->BasisCurve()->D1(U,P,V1);
1375 }
1376 //=============================================================================
1377 //function : D2
1378 //purpose  :
1379 //=============================================================================
1380 void Bisector_BisecAna::D2(const Standard_Real U, 
1381                            gp_Pnt2d&           P, 
1382                            gp_Vec2d&           V1, 
1383                            gp_Vec2d&           V2) const 
1384 {
1385   thebisector->BasisCurve()->D2(U,P,V1,V2);
1386 }
1387 //=============================================================================
1388 //function : D3
1389 //purpose  :
1390 //=============================================================================
1391 void Bisector_BisecAna::D3(const Standard_Real U,
1392                            gp_Pnt2d&           P, 
1393                            gp_Vec2d&           V1, 
1394                            gp_Vec2d&           V2, 
1395                            gp_Vec2d&           V3) const 
1396 {
1397   thebisector->BasisCurve()->D3(U,P,V1,V2,V3);
1398 }
1399 //=============================================================================
1400 //function : DN
1401 //purpose  :
1402 //=============================================================================
1403 gp_Vec2d Bisector_BisecAna::DN(const Standard_Real U, const Standard_Integer N) const 
1404 {
1405   return thebisector->BasisCurve()->DN (U, N);
1406 }
1407
1408 //=============================================================================
1409 //function : Geom2dCurve
1410 //purpose  :
1411 //=============================================================================
1412 Handle(Geom2d_Curve) Bisector_BisecAna::Geom2dCurve() const
1413 {
1414   return thebisector->BasisCurve();
1415 }
1416
1417 //==========================================================================
1418 //function : ParameterOfStartPoint
1419 //purpose  :
1420 //==========================================================================
1421 Standard_Real Bisector_BisecAna::ParameterOfStartPoint() const
1422 {
1423   return thebisector->FirstParameter();
1424 }
1425
1426 //==========================================================================
1427 //function : ParameterOfEndPoint
1428 //purpose  :
1429 //==========================================================================
1430 Standard_Real Bisector_BisecAna::ParameterOfEndPoint() const
1431 {
1432   return thebisector->LastParameter();
1433 }
1434
1435 //==========================================================================
1436 //function : Parameter
1437 //purpose  :
1438 //==========================================================================
1439 Standard_Real Bisector_BisecAna::Parameter(const gp_Pnt2d& P) const
1440 {
1441   gp_Hypr2d  gphyperbola;
1442   gp_Parab2d gpparabola ;
1443   gp_Elips2d gpellipse  ;
1444   gp_Circ2d  gpcircle   ;
1445   gp_Lin2d   gpline     ;
1446
1447   Handle(Geom2d_Curve)  BasisCurve = thebisector->BasisCurve();
1448   Handle(Standard_Type) Type       = BasisCurve ->DynamicType();
1449   
1450   if (Type == STANDARD_TYPE(Geom2d_Line)) {
1451     gpline     = Handle(Geom2d_Line)::DownCast(BasisCurve)->Lin2d();
1452     return ElCLib::Parameter(gpline,P);
1453   }
1454   else if (Type == STANDARD_TYPE(Geom2d_Circle)) {
1455     gpcircle   = Handle(Geom2d_Circle)::DownCast(BasisCurve)->Circ2d();
1456     return ElCLib::Parameter(gpcircle,P);
1457   } 
1458    else if (Type == STANDARD_TYPE(Geom2d_Hyperbola)) {
1459     gphyperbola   = Handle(Geom2d_Hyperbola)::DownCast(BasisCurve)->Hypr2d();
1460     return ElCLib::Parameter(gphyperbola,P);
1461   }
1462   else if (Type == STANDARD_TYPE(Geom2d_Parabola)) {
1463     gpparabola   = Handle(Geom2d_Parabola)::DownCast(BasisCurve)->Parab2d();
1464     return ElCLib::Parameter(gpparabola,P);
1465   }
1466   else if (Type == STANDARD_TYPE(Geom2d_Ellipse)) {
1467     gpellipse   = Handle(Geom2d_Ellipse)::DownCast(BasisCurve)->Elips2d();
1468     return ElCLib::Parameter(gpellipse,P);
1469   }
1470   return 0.;
1471 }
1472
1473 //=============================================================================
1474 //function : NbIntervals
1475 //purpose  :
1476 //=============================================================================
1477 Standard_Integer Bisector_BisecAna::NbIntervals() const
1478 {
1479   return 1;
1480 }
1481
1482 //=============================================================================
1483 //function : IntervalFirst
1484 //purpose  :
1485 //=============================================================================
1486 Standard_Real Bisector_BisecAna::IntervalFirst(const Standard_Integer I) const
1487 {
1488   if (I != 1) Standard_OutOfRange::Raise();
1489   return FirstParameter();
1490 }
1491
1492 //=============================================================================
1493 //function : IntervalLast
1494 //purpose  : 
1495 //=============================================================================
1496 Standard_Real Bisector_BisecAna::IntervalLast(const Standard_Integer I) const
1497 {  
1498   if (I != 1) Standard_OutOfRange::Raise();
1499   return LastParameter();
1500 }
1501
1502 //=============================================================================
1503 //function :           
1504 //=============================================================================
1505 void Bisector_BisecAna::Init(const Handle(Geom2d_TrimmedCurve)& Bis)
1506 {
1507   thebisector = Bis;
1508 }
1509
1510 //=============================================================================
1511 //function : Degenerate
1512 //purpose  : Replace the bisectrice by a straight line,
1513 //           if the bisectrice is an ellipse, a parabole or a degenerated ellipse.
1514 //=============================================================================
1515 Standard_Boolean Degenerate(Handle(GccInt_Bisec)& aBisector,
1516                             const Standard_Real   Tolerance)
1517 {
1518   Standard_Boolean Degeneree = Standard_False;
1519
1520   gp_Hypr2d  gphyperbola;
1521   gp_Parab2d gpparabola ;
1522   gp_Elips2d gpellipse  ;
1523   //gp_Circ2d  gpcircle   ;
1524
1525   Handle(GccInt_Bisec) NewBisector;
1526
1527   GccInt_IType type = aBisector->ArcType();
1528
1529   if (type == GccInt_Hpr) {
1530     gphyperbola   = aBisector->Hyperbola();
1531
1532     // If the Hyperbola is degenerated, it is replaced by the straight line
1533     // with direction to the axis if symmetry.
1534
1535     if (gphyperbola.MajorRadius() < Tolerance) {
1536       gp_Lin2d gpline(gphyperbola.YAxis());
1537       NewBisector = new GccInt_BLine(gpline);
1538       aBisector   = NewBisector;
1539       Degeneree   = Standard_True;
1540     }
1541     if (gphyperbola.MinorRadius() < Tolerance) {
1542       gp_Lin2d gpline(gphyperbola.XAxis());
1543       NewBisector = new GccInt_BLine(gpline);
1544       aBisector   = NewBisector;
1545       Degeneree   = Standard_True;
1546     }
1547   }
1548   else if (type == GccInt_Par) {
1549     gpparabola   = aBisector->Parabola();
1550     
1551     // If the parabole is degenerated, it is replaces by the straight 
1552     // line starting at the Top and with direction of the axis of symmetry.
1553     
1554     if (gpparabola.Focal() < Tolerance) {
1555       gp_Lin2d gpline(gpparabola.MirrorAxis());
1556       NewBisector = new GccInt_BLine(gpline);
1557       aBisector   = NewBisector;
1558       Degeneree   = Standard_True;
1559     }
1560   }
1561   else if (type == GccInt_Ell) {
1562     gpellipse   = aBisector->Ellipse();
1563     
1564     // If the ellipse is degenerated, it is replaced by the straight line 
1565     // defined by the great axis.
1566     
1567     if (gpellipse.MinorRadius() < Tolerance) {
1568       gp_Lin2d gpline(gpellipse.XAxis());
1569       NewBisector = new GccInt_BLine(gpline);
1570       aBisector   = NewBisector;
1571       Degeneree   = Standard_True;
1572     }
1573   }
1574   return Degeneree;
1575
1576
1577 static void Indent (const Standard_Integer Offset) {
1578   if (Offset > 0) {
1579     for (Standard_Integer i = 0; i < Offset; i++) { cout << " "; }
1580   }
1581 }
1582
1583 //=============================================================================
1584 //function : Dump
1585 // purpose : 
1586 //=============================================================================
1587 //void Bisector_BisecAna::Dump(const Standard_Integer Deep, 
1588 void Bisector_BisecAna::Dump(const Standard_Integer , 
1589                              const Standard_Integer Offset) const 
1590 {
1591   Indent (Offset);
1592   cout<<"Bisector_BisecAna"<<endl;
1593   Indent (Offset);
1594 //  thebisector->Dump();
1595 }