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