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