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