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