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