0024255: Regressions in test cases on OCCT vc9 win64 Release
[occt.git] / src / Bisector / Bisector_Bisec.cxx
1 // Created on: 1994-07-04
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1994-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 #include <Bisector_Bisec.ixx>
18 #include <Bisector.hxx>
19 #include <Geom2d_Circle.hxx>
20 #include <Geom2d_Line.hxx>
21 #include <Geom2d_Point.hxx>
22 #include <Geom2d_CartesianPoint.hxx>
23 #include <Geom2d_TrimmedCurve.hxx>
24 #include <Geom2d_BSplineCurve.hxx>
25 #include <gp.hxx>
26 #include <gp_Pnt2d.hxx>
27 #include <gp_Vec2d.hxx>
28 #include <StdFail_NotDone.hxx>
29 #include <Standard_NotImplemented.hxx>
30 #include <Precision.hxx>
31 #include <Bisector_Curve.hxx>
32 #include <Bisector_BisecAna.hxx>
33 #include <Bisector_BisecPC.hxx>
34 #include <Bisector_BisecCC.hxx>
35 #include <GCE2d_MakeSegment.hxx>
36
37 #ifdef OCCT_DEBUG
38 //#define DRAW
39 #ifdef DRAW
40 #include <DrawTrSurf.hxx>
41 #pragma comment(lib, "TKDraw.lib")
42 static char name[100];
43 static Standard_Integer nbb  = 0;
44 static Standard_Boolean Affich = Standard_False;
45 #endif
46 #endif
47
48
49 static Standard_Boolean IsMaxRC (const Handle(Geom2d_Curve)& C,
50   Standard_Real         U,
51   Standard_Real&        R);
52
53 static void ReplaceByLineIfIsToSmall (Handle(Geom2d_Curve)& Bis,
54   Standard_Real&        UFirst,
55   Standard_Real&        ULast);                                 
56 //=============================================================================
57 //function : Empty Constructor                                                
58 //=============================================================================
59 Bisector_Bisec::Bisector_Bisec()
60 {
61 }
62
63 //===========================================================================
64 //    calculate the bissectrice between two curves coming from a point.         
65 //                                                                          
66 //   afirstcurve   : \ curves between which the          
67 //   asecondcurve  : / bissectrice is calculated.                                         
68 //   apoint        :   point through which the bissectrice should pass.         
69 //   afirstvector  : \ vectors to determine the sector where       
70 //   asecondvector : / the bissectrice should be located.                      
71 //   adirection    :   shows the the side of the bissectrice to be preserved.       
72 //   tolerance     :   threshold starting from which the bisectrices are degenerated
73 //===========================================================================
74
75 void Bisector_Bisec::Perform(const Handle(Geom2d_Curve)& afirstcurve   ,
76   const Handle(Geom2d_Curve)& asecondcurve  ,
77   const gp_Pnt2d&             apoint        ,
78   const gp_Vec2d&             afirstvector  ,
79   const gp_Vec2d&             asecondvector ,
80   const Standard_Real         adirection    ,
81   const Standard_Real         tolerance     ,
82   const Standard_Boolean      oncurve       )
83 {
84   Handle(Standard_Type)  Type1 = afirstcurve ->DynamicType();
85   Handle(Standard_Type)  Type2 = asecondcurve->DynamicType();
86   Handle(Bisector_Curve) Bis;
87   Standard_Real          UFirst,ULast;
88
89   if (Type1 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
90     Type1 = Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)
91       ->BasisCurve()->DynamicType();
92   }
93   if (Type2 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
94     Type2 = Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)
95       ->BasisCurve()->DynamicType();
96   }
97
98   Handle(Geom2d_Curve) afirstcurve1 = afirstcurve;
99   Handle(Geom2d_Curve) asecondcurve1 = asecondcurve;
100
101   if(Type1 == STANDARD_TYPE(Geom2d_BSplineCurve))
102   {
103     Handle(Geom2d_BSplineCurve) aBS;
104     if(afirstcurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
105     {
106       aBS = Handle(Geom2d_BSplineCurve)::DownCast(Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)
107                                                                                ->BasisCurve());
108     }
109     else
110     {
111       aBS = Handle(Geom2d_BSplineCurve)::DownCast(afirstcurve);
112     }
113     if(aBS->Degree() == 1 && aBS->NbPoles() == 2)
114     {
115       if(aBS->Pole(1).Distance(aBS->Pole(2)) < 1.e-4)
116       {
117         afirstcurve1 = GCE2d_MakeSegment(aBS->Pole(1), aBS->Pole(2));
118         Type1 = STANDARD_TYPE(Geom2d_Line);
119       }
120     }
121   }
122
123
124   if(Type2 == STANDARD_TYPE(Geom2d_BSplineCurve))
125   {
126     Handle(Geom2d_BSplineCurve) aBS;
127     if(asecondcurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
128     {
129       aBS = Handle(Geom2d_BSplineCurve)::DownCast(Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)
130                                                                                ->BasisCurve());
131     }
132     else
133     {
134       aBS = Handle(Geom2d_BSplineCurve)::DownCast(asecondcurve);
135     }
136     if(aBS->Degree() == 1 && aBS->NbPoles() == 2)
137     {
138       if(aBS->Pole(1).Distance(aBS->Pole(2)) < 1.e-4)
139       {
140         asecondcurve1 = GCE2d_MakeSegment(aBS->Pole(1), aBS->Pole(2));
141         Type2 = STANDARD_TYPE(Geom2d_Line);
142       }
143     }
144   }
145
146   if ( (Type1 == STANDARD_TYPE(Geom2d_Circle) || Type1 == STANDARD_TYPE(Geom2d_Line)) &&
147     (Type2 == STANDARD_TYPE(Geom2d_Circle) || Type2 == STANDARD_TYPE(Geom2d_Line))   )
148   {    
149     //------------------------------------------------------------------
150     // Analytic Bissectrice.
151     //------------------------------------------------------------------
152     Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
153     BisAna->Perform(afirstcurve1   ,
154       asecondcurve1  ,
155       apoint        ,
156       afirstvector  ,
157       asecondvector ,
158       adirection    ,
159       tolerance     ,
160       oncurve       );
161     UFirst = BisAna->ParameterOfStartPoint();
162     ULast  = BisAna->ParameterOfEndPoint(); 
163     Bis = BisAna;   
164   }
165   else {  
166     Standard_Boolean IsLine = Standard_False;
167
168     if (oncurve) {
169       gp_Dir2d Fd(afirstvector);
170       gp_Dir2d Sd(asecondvector);
171       //if (Fd.Dot(Sd) < Precision::Angular() - 1.) { 
172       //if (Fd.Dot(Sd) < 10*Precision::Angular() - 1.) //patch
173       if (Fd.Dot(Sd) < Sqrt(2.*Precision::Angular()) - 1.)
174         IsLine = Standard_True;
175     }
176     if (IsLine) {     
177       //------------------------------------------------------------------
178       // Half-Staight.
179       //------------------------------------------------------------------
180       gp_Dir2d N ( - adirection*afirstvector.Y(), adirection*afirstvector.X());
181       Handle (Geom2d_CartesianPoint) PG     = new Geom2d_CartesianPoint(apoint);
182       Handle (Geom2d_Line)           L      = new Geom2d_Line (apoint,N);
183       Handle (Geom2d_TrimmedCurve)   
184         BisL   = new Geom2d_TrimmedCurve (L,0,Precision::Infinite());
185       Handle(Bisector_BisecAna)      BisAna = new Bisector_BisecAna ();
186       BisAna->Init(BisL);
187       UFirst = BisAna->ParameterOfStartPoint();
188       ULast  = BisAna->ParameterOfEndPoint();
189       Bis    = BisAna;
190     }
191     else {
192       //-------------------------------------------------------------------
193       // Bissectrice algo
194       //-------------------------------------------------------------------
195       Handle(Bisector_BisecCC) BisCC = new Bisector_BisecCC();
196       BisCC -> Perform(asecondcurve1, 
197         afirstcurve1 ,
198         adirection  , 
199         adirection  , 
200         apoint);
201
202       if (BisCC -> IsEmpty()) {
203         // bissectrice is empty. a point is projected at the end of the guide curve. 
204         // Construction of a false bissectrice.
205         //  modified by NIZHNY-EAP Mon Feb 21 12:00:13 2000 ___BEGIN___
206         gp_Pnt2d aP1 = afirstcurve1->Value(afirstcurve1->LastParameter());
207         gp_Pnt2d aP2 = asecondcurve1->Value(asecondcurve1->FirstParameter());
208         gp_Pnt2d aPm(.5*(aP1.XY()+aP2.XY()));
209         Standard_Real Nx, Ny;
210         if(aPm.Distance(apoint) > 10.*Precision::Confusion())
211         {
212           Nx = apoint.X() - aPm.X();
213           Ny = apoint.Y() - aPm.Y();
214           if(adirection < 0)
215           {
216             Nx = -Nx;
217             Ny = -Ny;
218           }
219         }
220         else
221         {
222           gp_Dir2d dir1(afirstvector), dir2(asecondvector);
223           Nx = - dir1.X() - dir2.X(),
224           Ny = - dir1.Y() - dir2.Y();
225           if (Abs(Nx) <= gp::Resolution() && Abs(Ny) <= gp::Resolution()) {
226             Nx = -afirstvector.Y();
227             Ny = afirstvector.X();
228           }
229         }
230         gp_Dir2d N ( adirection*Nx, adirection*Ny);
231         //  modified by NIZHNY-EAP Mon Feb 21 12:00:19 2000 ___END___
232
233         Handle (Geom2d_CartesianPoint) PG     = new Geom2d_CartesianPoint(apoint);
234         Handle (Geom2d_Line)           L      = new Geom2d_Line (apoint,N);
235         Handle (Geom2d_TrimmedCurve)   
236           BisL   = new Geom2d_TrimmedCurve (L,0,Precision::Infinite());
237         Handle(Bisector_BisecAna)      BisAna = new Bisector_BisecAna ();
238         BisAna->Init(BisL);
239         UFirst = BisAna->ParameterOfStartPoint();
240         ULast  = BisAna->ParameterOfEndPoint();
241         Bis    = BisAna;
242       }
243       else {
244         UFirst = BisCC->FirstParameter();
245         ULast  = BisCC->LastParameter ();
246         Bis    = BisCC;
247         ReplaceByLineIfIsToSmall(Bis,UFirst,ULast);
248       }
249     }
250   }
251   UFirst = Max(UFirst, Bis->FirstParameter());
252   ULast = Min(ULast, Bis->LastParameter());
253   thebisector = new Geom2d_TrimmedCurve(Bis,UFirst,ULast);
254 #ifdef DRAW  
255   if(Affich) 
256   {
257     sprintf( name, "c1_%d", ++nbb );
258     DrawTrSurf::Set( name, afirstcurve );
259     sprintf( name, "c2_%d", nbb );
260     DrawTrSurf::Set( name, asecondcurve );
261     sprintf( name, "p%d", nbb );
262     DrawTrSurf::Set( name, apoint );
263     sprintf( name, "b%d", nbb );
264     DrawTrSurf::Set( name, thebisector );
265   }
266 #endif
267   
268 }
269
270 //===========================================================================
271 //  calculate the bissectrice between a curve and a point starting in a point. 
272 //                                                                          
273 //   afirstcurve   : \ curve and point the bissectrice between which is calculated.
274 //   asecondpoint  : /                                          
275 //   apoint        :   point through which the bissectrice should pass.         
276 //   afirstvector  : \ vectors to find the sector where       
277 //   asecondvector : / the bissectrice should be located.                      
278 //   adirection    :   shows the side of the bissectrice to be preserved.       
279 //   tolerance     :   threshold starting from which the bisectrices are degenerated
280 //===========================================================================
281
282 void Bisector_Bisec::Perform(const Handle(Geom2d_Curve)& afirstcurve  ,
283   const Handle(Geom2d_Point)& asecondpoint ,
284   const gp_Pnt2d&             apoint       ,
285   const gp_Vec2d&             afirstvector ,
286   const gp_Vec2d&             asecondvector,
287   const Standard_Real         adirection   ,
288   const Standard_Real         tolerance    ,
289   const Standard_Boolean      oncurve       )
290 {  
291   //gp_Pnt2d SecondPnt = asecondpoint->Pnt2d();
292
293   Handle(Bisector_Curve) Bis;
294   Handle(Standard_Type)  Type1 = afirstcurve ->DynamicType();
295   Standard_Real          UFirst,ULast;
296
297   if (Type1 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
298     Type1 = Handle(Geom2d_TrimmedCurve)::DownCast(afirstcurve)
299       ->BasisCurve()->DynamicType();
300   }
301
302   if ( Type1 == STANDARD_TYPE(Geom2d_Circle) || Type1 == STANDARD_TYPE(Geom2d_Line)) {
303     //------------------------------------------------------------------
304     // Analytic Bissectrice.
305     //------------------------------------------------------------------
306     Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
307     BisAna -> Perform (afirstcurve   ,
308       asecondpoint  ,
309       apoint        ,
310       afirstvector  ,
311       asecondvector ,
312       adirection    ,
313       tolerance     ,
314       oncurve       );
315     UFirst = BisAna->ParameterOfStartPoint();
316     ULast  = BisAna->ParameterOfEndPoint();
317     Bis    = BisAna;
318   }
319   else {  
320     Standard_Boolean IsLine    = Standard_False;
321     Standard_Real    RC        = Precision::Infinite();
322
323     if (oncurve) {
324       if (Bisector::IsConvex(afirstcurve,adirection) || 
325         IsMaxRC(afirstcurve,afirstcurve->LastParameter(),RC)) { 
326           IsLine = Standard_True; 
327       }
328     }
329     if (IsLine) {     
330       //------------------------------------------------------------------
331       // Half-Right.
332       //------------------------------------------------------------------
333       gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
334       Handle (Geom2d_Line)         L      = new Geom2d_Line (apoint,N);
335       Handle (Geom2d_TrimmedCurve) BisL   = new Geom2d_TrimmedCurve(L,0,RC);
336       Handle(Bisector_BisecAna)    BisAna = new Bisector_BisecAna ();
337       BisAna->Init(BisL);
338       UFirst = BisAna->ParameterOfStartPoint();
339       ULast  = BisAna->ParameterOfEndPoint();
340       Bis    = BisAna;
341     }
342     else {
343       //-------------------------------------------------------------------
344       // Bissectrice algo
345       //-------------------------------------------------------------------
346       Handle(Bisector_BisecPC) BisPC = new Bisector_BisecPC();
347       Handle(Geom2d_Curve) afirstcurvereverse = afirstcurve->Reversed();
348
349       BisPC -> Perform(afirstcurvereverse   ,
350         asecondpoint->Pnt2d(),
351         - adirection         );
352       //  Modified by Sergey KHROMOV - Thu Feb 21 16:49:54 2002 Begin
353       if (BisPC -> IsEmpty()) {
354         gp_Dir2d dir1(afirstvector), dir2(asecondvector);
355         Standard_Real
356           Nx = - dir1.X() - dir2.X(),
357           Ny = - dir1.Y() - dir2.Y();
358         if (Abs(Nx) <= gp::Resolution() && Abs(Ny) <= gp::Resolution()) {
359           Nx = - afirstvector.Y();
360           Ny = afirstvector.X();
361         }
362         //      gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
363         gp_Dir2d N ( adirection*Nx, adirection*Ny);
364         Handle (Geom2d_Line)         L      = new Geom2d_Line (apoint,N);
365         Handle (Geom2d_TrimmedCurve) BisL   = new Geom2d_TrimmedCurve(L,0,RC);
366         Handle(Bisector_BisecAna)    BisAna = new Bisector_BisecAna ();
367         BisAna->Init(BisL);
368         UFirst = BisAna->ParameterOfStartPoint();
369         ULast  = BisAna->ParameterOfEndPoint();
370         Bis    = BisAna;
371       } else {
372         //  Modified by Sergey KHROMOV - Wed Mar  6 17:01:08 2002 End
373         UFirst = BisPC->Parameter(apoint);
374         ULast  = BisPC->LastParameter();
375         if(UFirst >= ULast)
376         {
377           //Standard_Real t = .9;
378           //UFirst = (1. - t) * BisPC->FirstParameter() + t * ULast;
379           //Extrapolate by line
380           //gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
381           gp_Vec2d V( BisPC->Value(BisPC->FirstParameter()), BisPC->Value(ULast) );
382           gp_Dir2d N( V );
383           Handle (Geom2d_Line)         L      = new Geom2d_Line         (apoint,N);
384           Handle (Geom2d_TrimmedCurve) BisL   = new Geom2d_TrimmedCurve (L,0,RC);
385           Handle(Bisector_BisecAna)    BisAna = new Bisector_BisecAna   ();
386           BisAna->Init(BisL);
387           UFirst = BisAna->ParameterOfStartPoint();
388           ULast  = BisAna->ParameterOfEndPoint();
389           Bis    = BisAna;
390         }
391         else
392           Bis    = BisPC;
393       }
394     }
395   }
396   if(UFirst < Bis->FirstParameter())
397     UFirst = Bis->FirstParameter();
398   if(ULast > Bis->LastParameter())
399     ULast = Bis->LastParameter();
400   thebisector = new Geom2d_TrimmedCurve(Bis,UFirst,ULast);
401
402 #ifdef DRAW
403   if(Affich)
404   {
405   sprintf( name, "c1_%d", ++nbb );
406   DrawTrSurf::Set( name, afirstcurve );
407   sprintf( name, "c2_%d", nbb );
408   DrawTrSurf::Set( name, asecondpoint->Pnt2d() );
409   sprintf( name, "p%d", nbb );
410   DrawTrSurf::Set( name, apoint );
411   sprintf( name, "b%d", nbb );
412   DrawTrSurf::Set( name, thebisector );
413   }
414 #endif
415 }
416
417 //===========================================================================
418 //   calculate the bissectrice between a curve and a point starting in a point. 
419 //                                                                          
420 //   afirstpoint   : \ curve and point the bissectrice between which is calculated.         
421 //   asecondcurve  : /                                          
422 //   apoint        :   point through which the bissectrice should pass.         
423 //   afirstvector  : \ vectors to find the sector where       
424 //   asecondvector : / the bissectrice should be located.                      
425 //   adirection    :   shows the side of the bissectrice to be preserved.       
426 //   tolerance     :   threshold starting from which the bisectrices are degenerated
427 //===========================================================================
428
429 void Bisector_Bisec::Perform(const Handle(Geom2d_Point)& afirstpoint  ,
430   const Handle(Geom2d_Curve)& asecondcurve ,
431   const gp_Pnt2d&             apoint       ,
432   const gp_Vec2d&             afirstvector ,
433   const gp_Vec2d&             asecondvector,
434   const Standard_Real         adirection   ,
435   const Standard_Real         tolerance    ,
436   const Standard_Boolean      oncurve       )
437
438 {  
439   //gp_Pnt2d FirstPnt = afirstpoint->Pnt2d();
440
441   Handle(Bisector_Curve) Bis;
442   Handle(Standard_Type)  Type1 = asecondcurve ->DynamicType();
443   Standard_Real          UFirst,ULast;
444
445   if (Type1 == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
446     Type1 = Handle(Geom2d_TrimmedCurve)::DownCast(asecondcurve)
447       ->BasisCurve()->DynamicType();
448   }
449
450   if ( Type1 == STANDARD_TYPE(Geom2d_Circle) || Type1 == STANDARD_TYPE(Geom2d_Line)) {
451     //------------------------------------------------------------------
452     // Analytic Bissectrice.
453     //------------------------------------------------------------------
454     Handle(Bisector_BisecAna) BisAna = new Bisector_BisecAna();
455     BisAna -> Perform (afirstpoint   ,
456       asecondcurve  ,
457       apoint        ,
458       afirstvector  ,
459       asecondvector ,
460       adirection    ,
461       tolerance     ,
462       oncurve       );
463     UFirst = BisAna->ParameterOfStartPoint();
464     ULast  = BisAna->ParameterOfEndPoint();
465     Bis    = BisAna;
466   }
467   else {   
468     //  Standard_Real    UPoint    = 0.;
469     Standard_Boolean IsLine    = Standard_False;
470     Standard_Real    RC        = Precision::Infinite();
471
472     if (oncurve) {
473       if (Bisector::IsConvex(asecondcurve, adirection) || 
474         IsMaxRC(asecondcurve,asecondcurve->FirstParameter(),RC)) {
475           IsLine = Standard_True;
476       }
477     }    
478     if (IsLine) {     
479       //------------------------------------------------------------------
480       // Half-Staight.
481       //------------------------------------------------------------------
482       gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
483       Handle (Geom2d_Line)         L      = new Geom2d_Line         (apoint,N);
484       Handle (Geom2d_TrimmedCurve) BisL   = new Geom2d_TrimmedCurve (L,0,RC);
485       Handle(Bisector_BisecAna)    BisAna = new Bisector_BisecAna   ();
486       BisAna->Init(BisL);
487       UFirst = BisAna->ParameterOfStartPoint();
488       ULast  = BisAna->ParameterOfEndPoint();
489       Bis    = BisAna;
490     }
491     else {
492       //-------------------------------------------------------------------
493       // Bissectrice algo
494       //-------------------------------------------------------------------
495       Handle(Bisector_BisecPC) BisPC = new Bisector_BisecPC();
496       BisPC -> Perform(asecondcurve        ,
497         afirstpoint->Pnt2d(),
498         adirection          );
499       //  Modified by Sergey KHROMOV - Thu Feb 21 16:49:54 2002 Begin
500       if (BisPC -> IsEmpty()) {
501         gp_Dir2d dir1(afirstvector), dir2(asecondvector);
502         Standard_Real
503           Nx = - dir1.X() - dir2.X(),
504           Ny = - dir1.Y() - dir2.Y();
505         if (Abs(Nx) <= gp::Resolution() && Abs(Ny) <= gp::Resolution()) {
506           Nx = - afirstvector.Y();
507           Ny = afirstvector.X();
508         }
509         //      gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
510         gp_Dir2d N ( adirection*Nx, adirection*Ny);
511         Handle (Geom2d_Line)         L      = new Geom2d_Line (apoint,N);
512         Handle (Geom2d_TrimmedCurve) BisL   = new Geom2d_TrimmedCurve(L,0,RC);
513         Handle(Bisector_BisecAna)    BisAna = new Bisector_BisecAna ();
514         BisAna->Init(BisL);
515         UFirst = BisAna->ParameterOfStartPoint();
516         ULast  = BisAna->ParameterOfEndPoint();
517         Bis    = BisAna;
518       } else {
519         //  Modified by Sergey KHROMOV - Thu Feb 21 16:49:58 2002 End
520         UFirst = BisPC->Parameter(apoint);
521         ULast  = BisPC->LastParameter();
522         if(UFirst >= ULast)
523         {
524           //Extrapolate by line
525           //gp_Dir2d N ( -adirection*afirstvector.Y(), adirection*afirstvector.X());
526           gp_Vec2d V( BisPC->Value(BisPC->FirstParameter()), BisPC->Value(ULast) );
527           gp_Dir2d N( V );
528           Handle (Geom2d_Line)         L      = new Geom2d_Line         (apoint,N);
529           Handle (Geom2d_TrimmedCurve) BisL   = new Geom2d_TrimmedCurve (L,0,RC);
530           Handle(Bisector_BisecAna)    BisAna = new Bisector_BisecAna   ();
531           BisAna->Init(BisL);
532           UFirst = BisAna->ParameterOfStartPoint();
533           ULast  = BisAna->ParameterOfEndPoint();
534           Bis    = BisAna;
535         }
536         else
537           Bis    = BisPC;
538       }
539     }
540   }
541  
542   UFirst = Max(UFirst, Bis->FirstParameter());
543   ULast = Min(ULast, Bis->LastParameter());
544   thebisector = new Geom2d_TrimmedCurve(Bis,UFirst,ULast);
545
546 #ifdef DRAW
547   if(Affich)
548   {
549   sprintf( name, "c1_%d", ++nbb );
550   DrawTrSurf::Set( name, afirstpoint->Pnt2d() );
551   sprintf( name, "c2_%d", nbb );
552   DrawTrSurf::Set( name, asecondcurve );
553   sprintf( name, "p%d", nbb );
554   DrawTrSurf::Set( name, apoint );
555   sprintf( name, "b%d", nbb );
556   DrawTrSurf::Set( name, thebisector );
557   }
558 #endif
559
560 }
561
562 //===========================================================================
563 //        calculate the bissectrice between two points starting in a point.      
564 //                                                                          
565 //   afirstpoint   : \ curves the bissectrice between which should be          
566 //   asecondpoint  : / calculated.                                         
567 //   apoint        :   point through which the bissectrice should pass.         
568 //   afirstvector  : \ vectors to find the sector where       
569 //   asecondvector : / the bissectrice should be located.                      
570 //   adirection    :   shows the side of the bissectrice to be preserved.       
571 //===========================================================================
572
573 void Bisector_Bisec::Perform(const Handle(Geom2d_Point)& afirstpoint  ,
574   const Handle(Geom2d_Point)& asecondpoint ,
575   const gp_Pnt2d&             apoint       ,
576   const gp_Vec2d&             afirstvector ,
577   const gp_Vec2d&             asecondvector,
578   const Standard_Real         adirection   ,
579   const Standard_Real         tolerance    ,
580   const Standard_Boolean      oncurve      )
581 {
582   Handle(Bisector_BisecAna) Bis = new Bisector_BisecAna();
583
584   Bis -> Perform (afirstpoint   ,
585     asecondpoint  ,
586     apoint        ,
587     afirstvector  ,
588     asecondvector ,
589     adirection    ,
590     tolerance     ,
591     oncurve       ); 
592   thebisector = new Geom2d_TrimmedCurve(Bis,
593     Bis->ParameterOfStartPoint(),
594     Bis->ParameterOfEndPoint());
595
596 #ifdef DRAW
597   if(Affich)
598   {
599   sprintf( name, "c1_%d", ++nbb );
600   DrawTrSurf::Set( name, afirstpoint->Pnt2d() );
601   sprintf( name, "c2_%d", nbb );
602   DrawTrSurf::Set( name, asecondpoint->Pnt2d() );
603   sprintf( name, "p%d", nbb );
604   DrawTrSurf::Set( name, apoint );
605   sprintf( name, "b%d", nbb );
606   DrawTrSurf::Set( name, thebisector );
607   }
608 #endif
609 }
610
611 //=============================================================================
612 //function : Value
613 //purpose  :
614 //=============================================================================
615 const Handle(Geom2d_TrimmedCurve)&  Bisector_Bisec::Value() const
616 {
617   return thebisector;
618 }
619
620 //=============================================================================
621 //function : ChangeValue
622 //purpose  :
623 //=============================================================================
624 const Handle(Geom2d_TrimmedCurve)&  Bisector_Bisec::ChangeValue()
625 {
626   return thebisector;
627 }
628
629 //=============================================================================
630 //function : ReplaceByLineIfIsToSmall 
631 //purpose  : If the size of an algorithmic bissectrice is negligeable it is
632 //           replaced by a half-straight.
633 //=============================================================================
634 static void ReplaceByLineIfIsToSmall (Handle(Geom2d_Curve)& Bis,
635   Standard_Real&        UFirst,
636   Standard_Real&        ULast )
637
638 {
639   if (Abs(ULast - UFirst) > 2.*Precision::PConfusion()*10.) return; //patch
640
641   gp_Pnt2d PF = Bis->Value(UFirst);
642   gp_Pnt2d PL = Bis->Value(ULast);
643
644   if (PF.Distance(PL) > Precision::Confusion()*10.) return;
645
646   gp_Vec2d T1 = Bis->DN(UFirst,1);
647
648   Handle (Geom2d_CartesianPoint) PG     = new Geom2d_CartesianPoint(PF);
649   Handle (Geom2d_Line)           L      = new Geom2d_Line (PF,T1);
650   Handle (Geom2d_TrimmedCurve)   
651     BisL   = new Geom2d_TrimmedCurve (L,0,Precision::Infinite());
652   Handle(Bisector_BisecAna)      BisAna = new Bisector_BisecAna ();
653   BisAna->Init(BisL);
654   UFirst = BisAna->ParameterOfStartPoint();
655   ULast  = BisAna->ParameterOfEndPoint();
656   Bis    = BisAna;
657 }
658
659 //=============================================================================
660 //function : IsMaxRC
661 //purpose  :
662 //=============================================================================
663 static Standard_Boolean  IsMaxRC (const Handle(Geom2d_Curve)& C,
664   Standard_Real         U,
665   Standard_Real&        R)
666 {  
667   Standard_Real KF,KL;
668   Standard_Real US = C->FirstParameter();
669   Standard_Real UL = C->LastParameter();
670
671   gp_Vec2d      D1,D2;
672   gp_Pnt2d      P;
673   Standard_Real Norm2;
674
675   C->D2(US,P,D1,D2);
676   Norm2 = D1.SquareMagnitude();;
677   if (Norm2 < gp::Resolution()) { KF = 0.0;}
678   else                          { KF = Abs(D1^D2)/(Norm2*sqrt(Norm2));}
679
680   C->D2(UL,P,D1,D2);
681   Norm2 = D1.SquareMagnitude();;
682   if (Norm2 < gp::Resolution()) { KL = 0.0;}
683   else                          { KL = Abs(D1^D2)/(Norm2*sqrt(Norm2));}
684
685   Standard_Boolean IsMax = Standard_False;
686
687   if (U == UL) {
688     if (KL < KF) {
689       if (KL == 0.0) R = Precision::Infinite(); else R = 1/KL;
690       IsMax = Standard_True;
691     }
692   }
693   else {   
694     if (KF < KL) {
695       if (KF == 0.0) R = Precision::Infinite(); else R = 1/KF;
696       IsMax = Standard_True;
697     }
698   }
699   return IsMax;
700 }