c0e9d5ab1744d6d248131c37512feac0cc690f57
[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
9 // under the terms of the GNU Lesser General Public 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,theSense;
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         theSense = sense;
411         if (ok) {
412           sense = Standard_False;
413 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
414 //       distanceptsol = Distance(apoint,solution,
415 //                             afirstvector,asecondvector,
416 //                             adirection,parameter,sense,ok);
417           if (oncurve)
418             distanceptsol = Distance(apoint,solution,
419                                      tan2,tan1,
420                                      adirection,parameter,sense,ok);
421           else
422             distanceptsol = Distance(apoint,solution,
423                                      afirstvector,asecondvector,
424                                      adirection,parameter,sense,ok);
425 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
426           if (distanceptsol <= distancemini) {
427             TheSol         = solution;
428             firstparameter = parameter;
429             thesense       = sense;
430             distancemini   = distanceptsol;
431           }
432         }
433       }
434       if (!TheSol.IsNull()) {
435         Handle(Geom2d_Curve) bisectorcurve;
436         GccInt_IType type = TheSol->ArcType();
437         if (type == GccInt_Lin) {
438           gp_Lin2d gpline = TheSol->Line(); 
439           bisectorcurve  = new Geom2d_Line(gpline);
440           
441           Standard_Real  secondparameter =   Precision::Infinite();
442           if (!thesense) secondparameter = - Precision::Infinite();
443           
444           if (oncurve) {
445             // bisectrice right and oncurve 
446             // is cut between two circle of the same radius if circles are tangent.
447
448             // if tangent flat and the bissectrice at the side of the concavity
449             // of one of the circles. the bissectrice is a segment of the point common to 
450             // first of 2 centers of circle that it meets. 
451             // in this case it is important to set a segmnent for 
452             // intersection in Tool2d.
453             
454             if (CirclesTangent) {
455               //  Modified by skv - Tue Apr 13 17:23:31 2004 IDEM(Airbus) Begin
456               //  Trying to correct the line if the distance between it
457               //  and the reference point is too big.
458               if (distancemini > tolerance) {
459                 gp_Pnt2d      aPloc    = gpline.Location();
460                 gp_Dir2d      aNewDir(apoint.XY() - aPloc.XY());
461                 gp_Lin2d      aNewLin(aPloc, aNewDir);
462                 gp_Pnt2d      aCC2     = circle2.Location();
463                 Standard_Real aNewDMin = aNewLin.Distance(apoint);
464                 Standard_Real aTolConf = 1.e-3;
465                 // Hope, aNewDMin is equal to 0...
466
467                 if (aNewLin.Distance(aCC2) <= aTolConf) {
468                   distancemini   =     aNewDMin;
469                   firstparameter =     ElCLib::Parameter(aNewLin, apoint);
470                   bisectorcurve  = new Geom2d_Line(aNewLin);
471                 }
472               }
473               //  Modified by skv - Tue Apr 13 17:23:32 2004 IDEM(Airbus) End
474               if (tan1.Dot(tan2) < 0.) {
475                 // flat and not turn back.
476                 Standard_Real Par1 = ElCLib::Parameter(gpline, circle1.Location());
477                 Standard_Real Par2 = ElCLib::Parameter(gpline, circle2.Location());
478                 Standard_Real MinPar = Min(Par1,Par2);
479                 Standard_Real MaxPar = Max(Par1,Par2);
480                 
481                 if (!thesense) {
482                   if (MaxPar < firstparameter) 
483                     secondparameter = MaxPar - 1.E-8;
484                   else if (MinPar < firstparameter)
485                     secondparameter = MinPar - 1.E-8;
486                 }
487                 else {
488                   if (MinPar > firstparameter) 
489                     secondparameter = MinPar + 1.E-8;
490                   else if (MaxPar > firstparameter)
491                     secondparameter = MaxPar + 1.E-8;
492                 }
493               }
494             }
495           }
496           
497           thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
498                                                 firstparameter,
499                                                 secondparameter);
500         }
501         else if (type == GccInt_Cir) { 
502           bisectorcurve = new Geom2d_Circle(TheSol->Circle());
503           if (!thesense)
504             thebisector = new Geom2d_TrimmedCurve
505               (bisectorcurve,firstparameter-2.0*M_PI,firstparameter,thesense);
506           else
507             thebisector = new Geom2d_TrimmedCurve
508               (bisectorcurve,firstparameter,firstparameter+2.0*M_PI,thesense);
509         }
510         else if (type == GccInt_Hpr) {
511           bisectorcurve = new Geom2d_Hyperbola(TheSol->Hyperbola());
512           if (!thesense)
513             thebisector = new Geom2d_TrimmedCurve
514               (bisectorcurve,firstparameter, - Precision::Infinite());
515           else
516             thebisector = new Geom2d_TrimmedCurve
517               (bisectorcurve,firstparameter,Precision::Infinite());
518         }
519         else if (type == GccInt_Ell) {
520           bisectorcurve = new Geom2d_Ellipse(TheSol->Ellipse());
521           if (!thesense)
522             thebisector = new Geom2d_TrimmedCurve
523               (bisectorcurve,firstparameter-2.0*M_PI,firstparameter,thesense);
524           else
525             thebisector = new Geom2d_TrimmedCurve
526               (bisectorcurve,firstparameter,firstparameter+2.0*M_PI,thesense);
527         }
528       }
529     }
530   }
531   break;
532     
533 //=============================================================================
534 //                       Bissectrice circle - straight.                         +
535 //=============================================================================
536       
537   case 2 : {
538     // small reframing of circles. in case OnCurve.
539     // If the circle and the straight line are almost tangent they become tangent.
540     if (oncurve) {
541       Standard_Real radius1 = circle1.Radius();
542       Standard_Real D1 = (line2.Distance(circle1.Location()) - radius1);
543 //  Modified by Sergey KHROMOV - Wed Oct 30 14:48:43 2002 Begin
544 //       if (Abs(D1) < PreConf) {
545       if (Abs(D1) < PreConf && tan1.IsParallel(tan2, 1.e-8)) {
546 //  Modified by Sergey KHROMOV - Wed Oct 30 14:48:44 2002 End
547         circle1.SetRadius(radius1+D1);
548       }
549     }
550
551     GccAna_CircLin2dBisec Bisector(circle1,line2);
552     
553     distancemini = Precision::Infinite();
554
555     if (Bisector.IsDone()) {
556       nbsolution = Bisector.NbSolutions();
557       for (Standard_Integer i = 1; i <= nbsolution; i++) {
558         Handle(GccInt_Bisec) solution = Bisector.ThisSolution(i);
559         Degenerate(solution,tolerance);
560         sense = Standard_True;
561         distanceptsol = Distance(apoint,solution,tan1,tan2,
562                                  adirection,parameter,sense,ok);
563         theSense = sense;
564         if (ok || !oncurve) {
565           sense = Standard_False;
566 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
567 //       distanceptsol = Distance(apoint,solution,
568 //                             afirstvector,asecondvector,
569 //                             adirection,parameter,sense,ok);
570           if (oncurve)
571             distanceptsol = Distance(apoint,solution,
572                                      tan2,tan1,
573                                      adirection,parameter,sense,ok);
574           else
575             distanceptsol = Distance(apoint,solution,
576                                      afirstvector,asecondvector,
577                                      adirection,parameter,sense,ok);
578 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
579           if (distanceptsol <= distancemini) {
580             TheSol         = solution;
581             firstparameter = parameter;
582             thesense       = sense;
583             distancemini   = distanceptsol+1.e-8;
584           }
585         }
586       }
587       if (!TheSol.IsNull()) {
588         GccInt_IType type = TheSol->ArcType();
589         Handle(Geom2d_Curve) bisectorcurve;
590         if (type == GccInt_Lin) {
591           // -----------------------------------------------------------------
592           // If the bisectrice is a line 
593           //       => the straight line is tangent to the circle.
594           //       It the part of bisectrice concerned is at the side of the center.
595           //       => the bisectrice is limited by the point and the center of the circle.
596           // Note : In the latter case the bisectrice is a degenerated parabole.
597           // -----------------------------------------------------------------
598           gp_Pnt2d      circlecenter;
599           gp_Lin2d      gpline;
600           Standard_Real secondparameter;
601           
602           circlecenter    = circle1.Location();
603           gpline          = TheSol->Line(); 
604           secondparameter = ElCLib::Parameter(gpline, circlecenter);
605           bisectorcurve   = new Geom2d_Line(gpline);
606
607           if (!thesense) {
608             if (secondparameter > firstparameter) {
609               secondparameter = - Precision::Infinite();
610             }
611             else {
612               secondparameter = secondparameter - 1.E-8;
613             }
614           }
615           else {
616             if (secondparameter < firstparameter) {
617               secondparameter = Precision::Infinite();
618             }
619             else {
620               secondparameter = secondparameter + 1.E-8;
621             }
622           }
623           
624           thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
625                                                 firstparameter,
626                                                 secondparameter);
627         }
628         else if (type == GccInt_Par) {
629           bisectorcurve = new Geom2d_Parabola(TheSol->Parabola());
630           if (!thesense)
631             thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
632                                                   firstparameter,
633                                                   - Precision::Infinite());
634           else
635             thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
636                                                   firstparameter,
637                                                   Precision::Infinite());
638         }
639       }
640     }
641   }
642     break;
643     
644 //=============================================================================
645 //                       Bissectrice straight - straight.                     +
646 //=============================================================================
647   case 3 : {
648     gp_Dir2d Direc1(line1.Direction());
649     gp_Dir2d Direc2(line2.Direction());
650     gp_Lin2d line;
651     distancemini = Precision::Infinite();
652
653 //  Modified by Sergey KHROMOV - Tue Sep 10 15:58:43 2002 Begin
654 //  Change to the same criterion as in MAT2d_Circuit.cxx:
655 //         method MAT2d_Circuit::InitOpen(..)
656 //     if (Direc1.IsParallel(Direc2,RealEpsilon())) {
657     if (Direc1.IsParallel(Direc2,1.e-8)) {
658 //  Modified by Sergey KHROMOV - Tue Sep 10 15:58:45 2002 End
659       if (line1.Distance(line2.Location())/2. <= Precision::Confusion())
660         line = gp_Lin2d(apoint,gp_Dir2d(-line1.Direction().Y(),
661                                         line1.Direction().X()));
662       else
663         line = gp_Lin2d(apoint,line2.Direction());
664       
665       Handle(GccInt_Bisec) solution = new GccInt_BLine(line);
666 //  Modified by skv - Wed Jul  7 17:21:09 2004 IDEM(Airbus) Begin
667 //       sense = Standard_True;
668 //       distanceptsol = Distance(apoint,solution,
669 //                             tan1,tan2,
670 //                             adirection,parameter,sense,ok);
671 //       theSense = sense;
672 //       if (ok || !oncurve) {
673       sense = Standard_False;
674 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
675 //       distanceptsol = Distance(apoint,solution,
676 //                             afirstvector,asecondvector,
677 //                             adirection,parameter,sense,ok);
678       if (oncurve)
679         distanceptsol = Distance(apoint,solution,
680                                  tan2,tan1,
681                                  adirection,parameter,sense,ok);
682       else
683         distanceptsol = Distance(apoint,solution,
684                                  afirstvector,asecondvector,
685                                  adirection,parameter,sense,ok);
686 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
687 //      if (distanceptsol <= distancemini) {
688       firstparameter = parameter;
689       Handle(Geom2d_Curve) bisectorcurve;
690       bisectorcurve = new Geom2d_Line(line);
691       if (!sense)
692         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
693                                               firstparameter,
694                                               - Precision::Infinite());
695       else
696         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
697                                               firstparameter,
698                                               Precision::Infinite());
699 //      }
700 //       }
701 //  Modified by skv - Wed Jul  7 17:21:09 2004 IDEM(Airbus) End
702     }
703     else {
704       gp_Lin2d l(apoint,gp_Dir2d(Direc2.XY()-Direc1.XY()));
705       Handle(GccInt_Bisec) solution = new GccInt_BLine(l);
706       Standard_Boolean ok;
707       sense = Standard_False;
708 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
709 //       distanceptsol = Distance(apoint,solution,
710 //                             afirstvector,asecondvector,
711 //                             adirection,parameter,sense,ok);
712       if (oncurve)
713         distanceptsol = Distance(apoint,solution,
714                                  tan2,tan1,
715                                  adirection,parameter,sense,ok);
716       else
717         distanceptsol = Distance(apoint,solution,
718                                  afirstvector,asecondvector,
719                                  adirection,parameter,sense,ok);
720 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
721       if (ok || !oncurve) {
722         thesense = sense;
723         distancemini = distanceptsol;
724       }
725       TheSol = new GccInt_BLine(l);
726       Handle(Geom2d_Curve) bisectorcurve;
727       bisectorcurve = new Geom2d_Line(TheSol->Line());
728       if (!thesense)
729         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
730                                               0.,- Precision::Infinite());
731       else
732         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
733                                               0., Precision::Infinite());
734     }
735   }
736     break;
737
738     default :
739       StdFail_NotDone::Raise();
740     break;
741   }
742 }
743
744
745 //===========================================================================
746 //  calculate the bissectrice between a curve and a point and starting in a point. +
747 //                                                                          +
748 //   afirstcurve   : \ curve and point the bissectrice between which is calculated +
749 //   asecondpoint  : /                                          +
750 //   apoint        :   point through which the bissectrice should pass.         +
751 //   afirstvector  : \ vectors to determine the sector in which      +
752 //   asecondvector : / the bissectrice should be located.                      +
753 //   adirection    :   shows the side of the bissectrice to be preserved.       +
754 //   tolerance     :   threshold starting from which the bisectrices are degenerated+
755 //===========================================================================
756
757 void Bisector_BisecAna::Perform(const Handle(Geom2d_Curve)& afirstcurve  ,
758                                 const Handle(Geom2d_Point)& asecondpoint ,
759                                 const gp_Pnt2d&             apoint       ,
760                                 const gp_Vec2d&             afirstvector ,
761                                 const gp_Vec2d&             asecondvector,
762                                 const Standard_Real         adirection   ,
763                                 const Standard_Real         tolerance    ,
764                                 const Standard_Boolean      oncurve       )
765 {
766   Standard_Boolean ok;
767   Standard_Boolean thesense = Standard_False,sense,theSense;
768   Standard_Real    distanceptsol,parameter,firstparameter =0.,secondparameter;
769   Handle(Geom2d_Curve) curve;
770   Handle(GccInt_Bisec) TheSol;
771
772   gp_Circ2d circle;
773   gp_Lin2d  line;
774   gp_Pnt2d  circlecenter;
775
776   Standard_Integer cas = 0;
777
778   Handle(Standard_Type) type = afirstcurve->DynamicType();
779
780   if (type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
781     curve = (*(Handle_Geom2d_TrimmedCurve*)&afirstcurve)->BasisCurve();
782   }
783   else {
784     curve = afirstcurve;
785   }
786
787   type = curve->DynamicType();
788 #ifdef DEB
789   gp_Pnt2d Point(asecondpoint->Pnt2d());
790 #else
791   asecondpoint->Pnt2d();
792 #endif
793   if (type == STANDARD_TYPE(Geom2d_Circle)) {
794     cas = 1;
795     Handle(Geom2d_Circle) C1 = Handle(Geom2d_Circle)::DownCast(curve);
796     circle = C1->Circ2d();
797   }
798   else if (type == STANDARD_TYPE(Geom2d_Line)) {
799     cas = 2;
800     Handle(Geom2d_Line) L1 = Handle(Geom2d_Line)::DownCast(curve);
801     line   = L1->Lin2d();
802   }
803   else {
804     cout << "Not yet implemented" << endl;
805   }
806
807   switch(cas) {
808
809 //=============================================================================
810 //                       Bissectrice point - circle.                          +
811 //=============================================================================
812     case 1 : {
813       GccAna_CircPnt2dBisec Bisector(circle,asecondpoint->Pnt2d());
814       Standard_Real distancemini = Precision::Infinite();
815       if (Bisector.IsDone()) {
816         Standard_Integer nbsolution = Bisector.NbSolutions();
817         for (Standard_Integer i = 1; i <= nbsolution; i++) {
818           Handle(GccInt_Bisec) solution = Bisector.ThisSolution(i);
819           Degenerate(solution,tolerance);
820           sense = Standard_False;
821           distanceptsol = Distance(apoint,solution,
822                                    afirstvector,asecondvector,
823                                    adirection,parameter,sense,ok);
824
825           if (distanceptsol <= distancemini) {
826             TheSol = solution;
827             firstparameter = parameter;
828             thesense = sense;
829             distancemini = distanceptsol;
830           }
831         }
832         if (!TheSol.IsNull()) {
833           GccInt_IType type = TheSol->ArcType();
834           Handle(Geom2d_Curve) bisectorcurve;
835           if (type == GccInt_Lin) { 
836
837 // ----------------------------------------------------------------------------
838 // If the bisectrice is a line 
839 //       => the point is on the circle.
840 //       If the part of bisectrice concerned is at the side of the center.
841 //       => the bisectrice is limited by the point and the center of the circle.
842 // Note : In this latter case the bisectrice is actually an ellipse of small null axis.
843 // ----------------------------------------------------------------------------
844             
845             circlecenter    = circle.Location();
846             line            = TheSol->Line(); 
847             secondparameter = ElCLib::Parameter(line, circlecenter);
848             bisectorcurve   = new Geom2d_Line(line);
849
850             if (!thesense) {
851               if (secondparameter > firstparameter) {
852                 secondparameter = - Precision::Infinite();
853               }
854               else {
855                 secondparameter = secondparameter - 1.E-8;
856               }
857             }
858             else {
859               if (secondparameter < firstparameter) {
860                 secondparameter = Precision::Infinite();
861               }
862               else {
863                 secondparameter = secondparameter + 1.E-8;
864               }
865             }
866
867             thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
868                                                   firstparameter,
869                                                   secondparameter);
870
871           }
872           else if (type == GccInt_Cir) { 
873             bisectorcurve = new Geom2d_Circle(TheSol->Circle());
874             if (!thesense)
875               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
876                                                     firstparameter-2.0*M_PI,
877                                                     firstparameter,
878                                                     thesense);
879             else
880               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
881                                                     firstparameter,
882                                                     firstparameter+2.0*M_PI,
883                                                     thesense);
884           }
885           else if (type == GccInt_Hpr) {
886             bisectorcurve=new Geom2d_Hyperbola(TheSol->Hyperbola());
887             if (!thesense)
888               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
889                                                     firstparameter,
890                                                     - Precision::Infinite());
891             else
892               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
893                                                     firstparameter,
894                                                     Precision::Infinite());
895           }
896           else if (type == GccInt_Ell) {
897             bisectorcurve = new Geom2d_Ellipse(TheSol->Ellipse());
898             if (!thesense)
899               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
900                                                     firstparameter-2.0*M_PI,
901                                                     firstparameter,
902                                                     thesense);
903             else
904               thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
905                                                     firstparameter,
906                                                     firstparameter+2.0*M_PI,
907                                                     thesense);
908           }
909         }
910       }
911     }
912       break;
913
914 //=============================================================================
915 //                       Bissectrice point - straight.                          +
916 //=============================================================================
917     case 2 : {
918       GccAna_LinPnt2dBisec Bisector(line,asecondpoint->Pnt2d());
919       
920       theSense = Standard_True;
921 #ifdef DEB
922       gp_Vec2d V(line.Direction());
923 #else
924       line.Direction();
925 #endif
926       Handle(GccInt_Bisec) solution = Bisector.ThisSolution();
927       Degenerate(solution,tolerance);      
928       GccInt_IType type = solution->ArcType();
929       Handle(Geom2d_Curve) bisectorcurve;
930       
931       if (type == GccInt_Lin) {
932         bisectorcurve = new Geom2d_Line(solution->Line());
933       }
934       else if (type == GccInt_Par) {
935         bisectorcurve = new Geom2d_Parabola(solution->Parabola());
936       }
937       sense = Standard_False;
938       distanceptsol = Distance(apoint,solution,
939                                afirstvector,asecondvector,
940                                adirection,parameter,sense,ok);
941
942       if (ok || !oncurve) {
943         firstparameter = parameter;
944         thesense = sense;
945       }
946       
947       if (!thesense)
948         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
949                                               firstparameter, 
950                                               - Precision::Infinite());
951       else
952         thebisector = new Geom2d_TrimmedCurve(bisectorcurve,
953                                               firstparameter, 
954                                               Precision::Infinite());
955     }
956       break;
957
958     default:
959       {
960         cout << "Not yet implemented" << endl;
961         break;
962       }
963     }
964 }
965
966
967 //===========================================================================
968 //  calculate the bissectrice between a curve and a point starting at a point. +
969 //                                                                          +
970 //   afirstpoint   : \ curves between which the                             +
971 //   asecondcurve  : / bissectrice is calculated.                           +
972 //   apoint        :   point through which the bissectrice should pass.     +
973 //   afirstvector  : \ vectors to determine the secteur in which            +
974 //   asecondvector : / the bissectrice should be located.                   +
975 //   adirection    :   shows the side of the bissectrice to be preserved.   +
976 //   tolerance     :   threshold at which the bisectrices become degenerated+
977 //===========================================================================
978
979 void Bisector_BisecAna::Perform(const Handle(Geom2d_Point)& afirstpoint  ,
980                                 const Handle(Geom2d_Curve)& asecondcurve ,
981                                 const gp_Pnt2d&             apoint       ,
982                                 const gp_Vec2d&             afirstvector ,
983                                 const gp_Vec2d&             asecondvector,
984                                 const Standard_Real         adirection   ,
985 //                              const Standard_Real         tolerance    ,
986                                 const Standard_Real             ,
987                                 const Standard_Boolean      oncurve       )
988      
989 {
990   Standard_Real  adirectionreverse = - adirection;
991   Perform(asecondcurve        , 
992           afirstpoint         , 
993           apoint              , 
994           asecondvector       ,
995           afirstvector        ,
996           adirectionreverse   ,
997 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration Begin
998           0.,
999 //  Modified by skv - Tue Feb 15 17:51:29 2005 Integration End
1000           oncurve             );
1001 }
1002
1003 //===========================================================================
1004 //        calculate the bissectrice between two points starting at a point. +
1005 //                                                                          +
1006 //   afirstpoint   : \ curves between which the                             +
1007 //   asecondpoint  : / bissectrice is calculated.                           +
1008 //   apoint        :   point through which the bissectrice should pass.     +
1009 //   afirstvector  : \ vectors to determine the sector in which the         +
1010 //   asecondvector : / bissectrice should be located.                       +
1011 //   adirection    :   shows the side of the bissectrice to be preserved.   +
1012 //===========================================================================
1013
1014 void Bisector_BisecAna::Perform(const Handle(Geom2d_Point)& afirstpoint  ,
1015                                 const Handle(Geom2d_Point)& asecondpoint ,
1016                                 const gp_Pnt2d&             apoint       ,
1017                                 const gp_Vec2d&             afirstvector ,
1018                                 const gp_Vec2d&             asecondvector,
1019                                 const Standard_Real         adirection   ,
1020 //                              const Standard_Real         tolerance    ,
1021                                 const Standard_Real             ,
1022                                 const Standard_Boolean      oncurve       )
1023 {
1024   Standard_Boolean sense,ok;
1025   Standard_Real distanceptsol,parameter;
1026
1027   GccAna_Pnt2dBisec bisector(afirstpoint->Pnt2d(),asecondpoint->Pnt2d());
1028   gp_Lin2d line = bisector.ThisSolution();
1029   Handle(GccInt_Bisec) solution = new GccInt_BLine(line);
1030
1031   sense = Standard_False;
1032   distanceptsol = Distance(apoint,solution,
1033                            afirstvector,asecondvector,
1034                            adirection,parameter,sense,ok);
1035   if (ok || !oncurve) {
1036     Handle(Geom2d_Curve) bisectorcurve = new Geom2d_Line(line);
1037     if (!sense)
1038       thebisector=new Geom2d_TrimmedCurve(bisectorcurve,
1039                                           parameter,- Precision::Infinite());
1040     else
1041       thebisector =new Geom2d_TrimmedCurve(bisectorcurve,
1042                                            parameter,Precision::Infinite());
1043   }
1044 }
1045
1046 //=============================================================================
1047 //function : IsExtendAtStart
1048 //purpose  :
1049 //=============================================================================
1050 Standard_Boolean Bisector_BisecAna::IsExtendAtStart() const
1051 {
1052   return Standard_False;
1053 }
1054
1055 //=============================================================================
1056 //function : IsExtendAtEnd
1057 //purpose  :
1058 //=============================================================================
1059 Standard_Boolean Bisector_BisecAna::IsExtendAtEnd() const
1060 {
1061   return Standard_False;
1062 }
1063
1064 //=============================================================================
1065 //function : SetTrim
1066 //purpose  : Restriction of the bissectrice by the domain of the curve Cu.
1067 //           The domain of the curve is the set of points that are closer to the
1068 //           than to its extremities. 
1069 //           For the calculation the domain is extended. Extension of Epsilon1 of the 
1070 //           First and the Last parameter of the curve.
1071 //=============================================================================
1072 //void Bisector_BisecAna::SetTrim(const Handle(Geom2d_Curve)& Cu)
1073 void Bisector_BisecAna::SetTrim(const Handle(Geom2d_Curve)& )
1074 {
1075 /*
1076   Handle(Standard_Type)       Type;
1077   Handle(Geom2d_Curve)        TheCurve;
1078   Handle(Geom2d_Circle)       CircleCu;
1079   Handle(Geom2d_Line)         LineCu;
1080   Handle(Geom2d_Curve)        FirstLimit;
1081   Handle(Geom2d_Curve)        LastLimit;
1082
1083   gp_Lin2d                    gpLine;
1084   gp_Pnt2d                    P, PFirst, PLast, FirstPointBisector, Center;
1085   gp_Vec2d                    TanFirst, TanLast;
1086
1087   IntRes2d_Domain             FirstDomain;
1088   IntRes2d_Domain             LastDomain ;
1089   
1090   Standard_Real   UFirst, ULast, UB1, UB2;
1091   Standard_Real   UBisInt1, UBisInt2, Utrim;
1092   Standard_Real   Distance;
1093   Standard_Real   Radius;
1094
1095   Standard_Real Epsilon1  = 1.E-6; // Epsilon sur le parametre de la courbe.
1096   Standard_Real Tolerance = 1.E-8; // Tolerance pour les intersections.
1097
1098    Type = Cu->DynamicType();
1099
1100   if (Type == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
1101     TheCurve = Handle(Geom2d_TrimmedCurve)::DownCast(Cu)->BasisCurve();
1102     Type     = TheCurve->DynamicType();
1103   }
1104   else {
1105     TheCurve = Cu;
1106   }
1107
1108   if (Type == STANDARD_TYPE(Geom2d_Circle)) {
1109     CircleCu = Handle(Geom2d_Circle)::DownCast(TheCurve);
1110   }
1111   else {
1112     LineCu = Handle(Geom2d_Line)::DownCast(TheCurve);
1113   }
1114
1115   // Recuperation de UFirst, ULast.
1116   // -------------------------------
1117   UFirst   = Cu->FirstParameter();
1118   ULast    = Cu->LastParameter();
1119
1120   // Creation des lignes Limites du domaine si elles existent.
1121   // et Determination de leur domaine d intersection.
1122   // ---------------------------------------------------------
1123   if (Type == STANDARD_TYPE(Geom2d_Circle)) {
1124     CircleCu->D1(UFirst,PFirst,TanFirst);
1125     CircleCu->D1(ULast ,PLast ,TanLast);
1126     Radius = CircleCu->Radius();
1127
1128     if (PFirst.Distance(PLast) > 2.*Epsilon1 && Radius > Epsilon1) {
1129       Center     = CircleCu->Location();
1130       P          = PFirst.Translated( - (Epsilon1/Radius)*TanFirst );
1131
1132       FirstLimit = new Geom2d_Line(P,
1133                                    gp_Dir2d(PFirst.X() - Center.X(), 
1134                                             PFirst.Y() - Center.Y()));
1135       P          = PLast .Translated( (Epsilon1/Radius)*TanLast );
1136
1137       LastLimit  = new Geom2d_Line(P,
1138                                    gp_Dir2d(PLast.X() - Center.X(), 
1139                                             PLast.Y() - Center.Y()));
1140
1141       Geom2dAdaptor_Curve AFirstLimit(FirstLimit);
1142       Geom2dAdaptor_Curve ALastLimit (LastLimit);
1143       Geom2dInt_GInter Intersect(AFirstLimit , FirstDomain,   
1144                                  ALastLimit  , LastDomain ,
1145                                  Tolerance   , Tolerance     );
1146       
1147       if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1148         if (Intersect.NbPoints() >= 1) {
1149           FirstDomain.SetValues(Intersect.Point(1).Value(),
1150                                 Intersect.Point(1).ParamOnFirst(),
1151                                 Tolerance,Standard_True);
1152           LastDomain. SetValues(Intersect.Point(1).Value(),
1153                                 Intersect.Point(1).ParamOnSecond(),
1154                                 Tolerance,Standard_True);
1155         }
1156       }
1157     }  
1158   }
1159   else if (Type == STANDARD_TYPE(Geom2d_Line)) {
1160     gpLine = LineCu->Lin2d();
1161     if (UFirst > - Precision::Infinite()){
1162       P          = LineCu->Value(UFirst - Epsilon1);
1163       FirstLimit = new Geom2d_Line(gpLine.Normal(P)) ;
1164     }
1165     if (ULast < Precision::Infinite()) {
1166       P         = LineCu->Value(ULast + Epsilon1);
1167       LastLimit = new Geom2d_Line(gpLine.Normal(P));
1168     }
1169   }
1170   else {
1171     Standard_NotImplemented::Raise();
1172   }
1173     
1174   // Determination domaine d intersection de la Bissectrice.
1175   // -------------------------------------------------------
1176   UB1 = thebisector->FirstParameter();
1177   UB2 = thebisector->LastParameter();
1178   if (UB2 > 10000.) {
1179     UB2 = 10000.;
1180     Handle(Geom2d_Curve)  BasisCurve = thebisector->BasisCurve();
1181     Handle(Standard_Type) Type1 = BasisCurve->DynamicType();
1182     gp_Parab2d gpParabola;
1183     gp_Hypr2d  gpHyperbola;
1184     Standard_Real Focus;
1185     Standard_Real Limit = 50000.;
1186     if (Type1 == STANDARD_TYPE(Geom2d_Parabola)) {
1187       gpParabola = Handle(Geom2d_Parabola)::DownCast(BasisCurve)->Parab2d();
1188       Focus = gpParabola.Focal();
1189       Standard_Real Val1 = Sqrt(Limit*Focus);
1190       Standard_Real Val2 = Sqrt(Limit*Limit);
1191       UB2 = (Val1 <= Val2 ? Val1:Val2);
1192     }
1193     else if (Type1 == STANDARD_TYPE(Geom2d_Hyperbola)) {
1194       gpHyperbola = Handle(Geom2d_Hyperbola)::DownCast(BasisCurve)->Hypr2d();
1195       Standard_Real Majr  = gpHyperbola.MajorRadius();
1196       Standard_Real Minr  = gpHyperbola.MinorRadius();
1197       Standard_Real Valu1 = Limit/Majr;
1198       Standard_Real Valu2 = Limit/Minr;
1199       Standard_Real Val1  = Log(Valu1+Sqrt(Valu1*Valu1-1));
1200       Standard_Real Val2  = Log(Valu2+Sqrt(Valu2*Valu2+1));
1201       UB2 = (Val1 <= Val2 ? Val1:Val2);
1202     }
1203   }
1204
1205   IntRes2d_Domain DomainBisector(thebisector->Value(UB1), UB1, Tolerance,
1206                                  thebisector->Value(UB2), UB2, Tolerance);
1207
1208   if (thebisector->BasisCurve()->IsPeriodic()) {
1209     DomainBisector.SetEquivalentParameters(0.0,2.*M_PI);
1210   }
1211   FirstPointBisector = thebisector->Value(UB1);
1212
1213
1214   // Intersection Bisectrice avec FirstLimit => UBisInt1.
1215   // ----------------------------------------------------
1216   UBisInt1 = Precision::Infinite();
1217   if (!FirstLimit.IsNull()) {
1218     Geom2dAdaptor_Curve AdapBis    (thebisector);
1219     Geom2dAdaptor_Curve AFirstLimit(FirstLimit);
1220     Geom2dInt_GInter Intersect(AFirstLimit , FirstDomain,   
1221                                AdapBis     , DomainBisector,
1222                                Tolerance   , Tolerance     );
1223
1224     if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1225       for (Standard_Integer i=1; i<=Intersect.NbPoints(); i++) {
1226         Distance = FirstPointBisector.Distance(Intersect.Point(i).Value());
1227         if (Distance > 2.*Tolerance) {
1228           UBisInt1 = Intersect.Point(i).ParamOnSecond();
1229           break;
1230         }
1231       }
1232     } 
1233   } 
1234   // Intersection Bisectrice avec LastLimit => UBisInt2.
1235   // ---------------------------------------------------
1236   UBisInt2 = Precision::Infinite();
1237   if (!LastLimit.IsNull()) {
1238     Geom2dAdaptor_Curve AdapBis    (thebisector);
1239     Geom2dAdaptor_Curve ALastLimit (LastLimit);
1240     Geom2dInt_GInter Intersect(ALastLimit , LastDomain    ,
1241                                AdapBis    , DomainBisector, 
1242                                Tolerance  , Tolerance     );
1243
1244     if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1245       for (Standard_Integer i=1; i<=Intersect.NbPoints(); i++) {
1246         Distance = FirstPointBisector.Distance(Intersect.Point(i).Value());
1247         if (Distance > 2.*Tolerance) {
1248           UBisInt2 = Intersect.Point(i).ParamOnSecond();
1249           break;
1250         }
1251       }
1252     }
1253   }
1254   // Restriction de la Bissectrice par le point d intersection de plus petit
1255   // parametre.
1256   //------------------------------------------------------------------------
1257   Utrim = (UBisInt1 < UBisInt2) ? UBisInt1 : UBisInt2;
1258   
1259   if (Utrim < UB2 && Utrim > UB1) thebisector->SetTrim(UB1,Utrim);
1260 */
1261 }
1262
1263 void Bisector_BisecAna::SetTrim(const Standard_Real uf, const Standard_Real ul)
1264 {
1265   thebisector->SetTrim(uf, ul);
1266 }
1267 //=============================================================================
1268 //function : Reverse 
1269 //purpose  :
1270 //=============================================================================
1271 void Bisector_BisecAna::Reverse()
1272 {
1273   thebisector->Reverse();
1274 }
1275
1276 //=============================================================================
1277 //function : ReversedParameter 
1278 //purpose  :
1279 //=============================================================================
1280 Standard_Real Bisector_BisecAna::ReversedParameter(const Standard_Real U) const 
1281 {
1282   return thebisector->ReversedParameter(U);
1283 }
1284
1285 //=============================================================================
1286 //function : IsCN
1287 //purpose  :
1288 //=============================================================================
1289 Standard_Boolean Bisector_BisecAna::IsCN(const Standard_Integer N) const 
1290 {
1291   return thebisector->IsCN(N);
1292 }
1293
1294 //=============================================================================
1295 //function : Copy 
1296 //purpose  :
1297 //=============================================================================
1298 Handle(Geom2d_Geometry) Bisector_BisecAna::Copy() const 
1299 {
1300   Handle(Bisector_BisecAna) C = new  Bisector_BisecAna();
1301   C->Init (Handle(Geom2d_TrimmedCurve)::DownCast(thebisector->Copy()));
1302   return C;
1303 }
1304
1305 //=============================================================================
1306 //function : Transform
1307 //purpose  :
1308 //=============================================================================
1309 void Bisector_BisecAna::Transform(const gp_Trsf2d& T)
1310 {
1311   thebisector->Transform(T);
1312 }
1313
1314 //=============================================================================
1315 //function : FirstParameter
1316 //purpose  :
1317 //=============================================================================
1318 Standard_Real Bisector_BisecAna::FirstParameter() const 
1319 {
1320 //  modified by NIZHNY-EAP Thu Feb  3 17:23:42 2000 ___BEGIN___
1321 //  return thebisector->BasisCurve()->FirstParameter();
1322   return thebisector->FirstParameter();
1323 //  modified by NIZHNY-EAP Thu Feb  3 17:23:48 2000 ___END___
1324 }
1325
1326 //=============================================================================
1327 //function : LastParameter
1328 //purpose  :
1329 //=============================================================================
1330 Standard_Real Bisector_BisecAna::LastParameter() const 
1331 {
1332   return thebisector->LastParameter();
1333 }
1334
1335 //=============================================================================
1336 //function : IsClosed
1337 //purpose  :
1338 //=============================================================================
1339 Standard_Boolean Bisector_BisecAna::IsClosed() const 
1340 {
1341   return thebisector->BasisCurve()->IsClosed(); 
1342 }
1343
1344 //=============================================================================
1345 //function : IsPeriodic
1346 //purpose  :
1347 //=============================================================================
1348 Standard_Boolean Bisector_BisecAna::IsPeriodic() const 
1349 {
1350   return thebisector->BasisCurve()->IsPeriodic(); 
1351 }
1352
1353 //=============================================================================
1354 //function : Continuity
1355 //purpose  :
1356 //=============================================================================
1357 GeomAbs_Shape Bisector_BisecAna::Continuity() const 
1358 {
1359  return thebisector->Continuity(); 
1360 }
1361
1362 //=============================================================================
1363 //function : D0 
1364 //purpose  :
1365 //=============================================================================
1366 void Bisector_BisecAna::D0(const Standard_Real U, gp_Pnt2d& P) const 
1367 {
1368   thebisector->BasisCurve()->D0(U,P);
1369 }
1370
1371 //=============================================================================
1372 //function : D1
1373 //purpose  :
1374 //=============================================================================
1375 void Bisector_BisecAna::D1(const Standard_Real U, gp_Pnt2d& P, gp_Vec2d& V1) const 
1376 {
1377   thebisector->BasisCurve()->D1(U,P,V1);
1378 }
1379 //=============================================================================
1380 //function : D2
1381 //purpose  :
1382 //=============================================================================
1383 void Bisector_BisecAna::D2(const Standard_Real U, 
1384                            gp_Pnt2d&           P, 
1385                            gp_Vec2d&           V1, 
1386                            gp_Vec2d&           V2) const 
1387 {
1388   thebisector->BasisCurve()->D2(U,P,V1,V2);
1389 }
1390 //=============================================================================
1391 //function : D3
1392 //purpose  :
1393 //=============================================================================
1394 void Bisector_BisecAna::D3(const Standard_Real U,
1395                            gp_Pnt2d&           P, 
1396                            gp_Vec2d&           V1, 
1397                            gp_Vec2d&           V2, 
1398                            gp_Vec2d&           V3) const 
1399 {
1400   thebisector->BasisCurve()->D3(U,P,V1,V2,V3);
1401 }
1402 //=============================================================================
1403 //function : DN
1404 //purpose  :
1405 //=============================================================================
1406 gp_Vec2d Bisector_BisecAna::DN(const Standard_Real U, const Standard_Integer N) const 
1407 {
1408   return thebisector->BasisCurve()->DN (U, N);
1409 }
1410
1411 //=============================================================================
1412 //function : Geom2dCurve
1413 //purpose  :
1414 //=============================================================================
1415 Handle(Geom2d_Curve) Bisector_BisecAna::Geom2dCurve() const
1416 {
1417   return thebisector->BasisCurve();
1418 }
1419
1420 //==========================================================================
1421 //function : ParameterOfStartPoint
1422 //purpose  :
1423 //==========================================================================
1424 Standard_Real Bisector_BisecAna::ParameterOfStartPoint() const
1425 {
1426   return thebisector->FirstParameter();
1427 }
1428
1429 //==========================================================================
1430 //function : ParameterOfEndPoint
1431 //purpose  :
1432 //==========================================================================
1433 Standard_Real Bisector_BisecAna::ParameterOfEndPoint() const
1434 {
1435   return thebisector->LastParameter();
1436 }
1437
1438 //==========================================================================
1439 //function : Parameter
1440 //purpose  :
1441 //==========================================================================
1442 Standard_Real Bisector_BisecAna::Parameter(const gp_Pnt2d& P) const
1443 {
1444   gp_Hypr2d  gphyperbola;
1445   gp_Parab2d gpparabola ;
1446   gp_Elips2d gpellipse  ;
1447   gp_Circ2d  gpcircle   ;
1448   gp_Lin2d   gpline     ;
1449
1450   Handle(Geom2d_Curve)  BasisCurve = thebisector->BasisCurve();
1451   Handle(Standard_Type) Type       = BasisCurve ->DynamicType();
1452   
1453   if (Type == STANDARD_TYPE(Geom2d_Line)) {
1454     gpline     = Handle(Geom2d_Line)::DownCast(BasisCurve)->Lin2d();
1455     return ElCLib::Parameter(gpline,P);
1456   }
1457   else if (Type == STANDARD_TYPE(Geom2d_Circle)) {
1458     gpcircle   = Handle(Geom2d_Circle)::DownCast(BasisCurve)->Circ2d();
1459     return ElCLib::Parameter(gpcircle,P);
1460   } 
1461    else if (Type == STANDARD_TYPE(Geom2d_Hyperbola)) {
1462     gphyperbola   = Handle(Geom2d_Hyperbola)::DownCast(BasisCurve)->Hypr2d();
1463     return ElCLib::Parameter(gphyperbola,P);
1464   }
1465   else if (Type == STANDARD_TYPE(Geom2d_Parabola)) {
1466     gpparabola   = Handle(Geom2d_Parabola)::DownCast(BasisCurve)->Parab2d();
1467     return ElCLib::Parameter(gpparabola,P);
1468   }
1469   else if (Type == STANDARD_TYPE(Geom2d_Ellipse)) {
1470     gpellipse   = Handle(Geom2d_Ellipse)::DownCast(BasisCurve)->Elips2d();
1471     return ElCLib::Parameter(gpellipse,P);
1472   }
1473   return 0.;
1474 }
1475
1476 //=============================================================================
1477 //function : NbIntervals
1478 //purpose  :
1479 //=============================================================================
1480 Standard_Integer Bisector_BisecAna::NbIntervals() const
1481 {
1482   return 1;
1483 }
1484
1485 //=============================================================================
1486 //function : IntervalFirst
1487 //purpose  :
1488 //=============================================================================
1489 Standard_Real Bisector_BisecAna::IntervalFirst(const Standard_Integer I) const
1490 {
1491   if (I != 1) Standard_OutOfRange::Raise();
1492   return FirstParameter();
1493 }
1494
1495 //=============================================================================
1496 //function : IntervalLast
1497 //purpose  : 
1498 //=============================================================================
1499 Standard_Real Bisector_BisecAna::IntervalLast(const Standard_Integer I) const
1500 {  
1501   if (I != 1) Standard_OutOfRange::Raise();
1502   return LastParameter();
1503 }
1504
1505 //=============================================================================
1506 //function :           
1507 //=============================================================================
1508 void Bisector_BisecAna::Init(const Handle(Geom2d_TrimmedCurve)& Bis)
1509 {
1510   thebisector = Bis;
1511 }
1512
1513 //=============================================================================
1514 //function : Degenerate
1515 //purpose  : Replace the bisectrice by a straight line,
1516 //           if the bisectrice is an ellipse, a parabole or a degenerated ellipse.
1517 //=============================================================================
1518 Standard_Boolean Degenerate(Handle(GccInt_Bisec)& aBisector,
1519                             const Standard_Real   Tolerance)
1520 {
1521   Standard_Boolean Degeneree = Standard_False;
1522
1523   gp_Hypr2d  gphyperbola;
1524   gp_Parab2d gpparabola ;
1525   gp_Elips2d gpellipse  ;
1526   //gp_Circ2d  gpcircle   ;
1527
1528   Handle(GccInt_Bisec) NewBisector;
1529
1530   GccInt_IType type = aBisector->ArcType();
1531
1532   if (type == GccInt_Hpr) {
1533     gphyperbola   = aBisector->Hyperbola();
1534
1535     // If the Hyperbola is degenerated, it is replaced by the straight line
1536     // with direction to the axis if symmetry.
1537
1538     if (gphyperbola.MajorRadius() < Tolerance) {
1539       gp_Lin2d gpline(gphyperbola.YAxis());
1540       NewBisector = new GccInt_BLine(gpline);
1541       aBisector   = NewBisector;
1542       Degeneree   = Standard_True;
1543     }
1544     if (gphyperbola.MinorRadius() < Tolerance) {
1545       gp_Lin2d gpline(gphyperbola.XAxis());
1546       NewBisector = new GccInt_BLine(gpline);
1547       aBisector   = NewBisector;
1548       Degeneree   = Standard_True;
1549     }
1550   }
1551   else if (type == GccInt_Par) {
1552     gpparabola   = aBisector->Parabola();
1553     
1554     // If the parabole is degenerated, it is replaces by the straight 
1555     // line starting at the Top and with direction of the axis of symmetry.
1556     
1557     if (gpparabola.Focal() < Tolerance) {
1558       gp_Lin2d gpline(gpparabola.MirrorAxis());
1559       NewBisector = new GccInt_BLine(gpline);
1560       aBisector   = NewBisector;
1561       Degeneree   = Standard_True;
1562     }
1563   }
1564   else if (type == GccInt_Ell) {
1565     gpellipse   = aBisector->Ellipse();
1566     
1567     // If the ellipse is degenerated, it is replaced by the straight line 
1568     // defined by the great axis.
1569     
1570     if (gpellipse.MinorRadius() < Tolerance) {
1571       gp_Lin2d gpline(gpellipse.XAxis());
1572       NewBisector = new GccInt_BLine(gpline);
1573       aBisector   = NewBisector;
1574       Degeneree   = Standard_True;
1575     }
1576   }
1577   return Degeneree;
1578
1579
1580 static void Indent (const Standard_Integer Offset) {
1581   if (Offset > 0) {
1582     for (Standard_Integer i = 0; i < Offset; i++) { cout << " "; }
1583   }
1584 }
1585
1586 //=============================================================================
1587 //function : Dump
1588 // purpose : 
1589 //=============================================================================
1590 //void Bisector_BisecAna::Dump(const Standard_Integer Deep, 
1591 void Bisector_BisecAna::Dump(const Standard_Integer , 
1592                              const Standard_Integer Offset) const 
1593 {
1594   Indent (Offset);
1595   cout<<"Bisector_BisecAna"<<endl;
1596   Indent (Offset);
1597 //  thebisector->Dump();
1598 }