0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / Bisector / Bisector_BisecPC.cxx
1 // File:        Bisector_BisecPC.cxx
2 // Created:     Thu Mar 10 17:54:52 1994
3 // Author:      Yves FRICAUD
4 //              <yfr@phylox>
5
6 #include <Bisector_BisecPC.ixx>
7 #include <Bisector.hxx>
8 #include <Geom2dAdaptor_Curve.hxx>
9 #include <Geom2d_Curve.hxx>
10 #include <Geom2d_Line.hxx>
11 #include <Geom2d_CartesianPoint.hxx>
12 #include <Geom2dInt_GInter.hxx>
13 #include <Geom2dGcc.hxx>
14 #include <GccEnt_Position.hxx>
15 #include <Geom2dGcc_Circ2d2TanRad.hxx>
16 #include <Geom2dGcc_QualifiedCurve.hxx>
17 #include <Geom2d_TrimmedCurve.hxx>
18 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
19 #include <Geom2dLProp_CLProps2d.hxx>
20 #include <gp_Pnt2d.hxx>
21 #include <gp_Vec2d.hxx>
22 #include <gp_Ax2d.hxx>  
23 #include <gp.hxx>
24 #include <Precision.hxx>
25 #include <ElCLib.hxx>
26 #include <IntRes2d_IntersectionPoint.hxx>
27
28 #include <Standard_DivideByZero.hxx>
29 #include <Standard_NotImplemented.hxx>
30
31 //=============================================================================
32 //function :
33 // purpose :
34 //=============================================================================
35 Bisector_BisecPC::Bisector_BisecPC()
36 {
37 }
38
39 //=============================================================================
40 //function :
41 // purpose :
42 //=============================================================================
43 Bisector_BisecPC::Bisector_BisecPC(const Handle(Geom2d_Curve)& Cu, 
44                                    const gp_Pnt2d&             P,
45                                    const Standard_Real         Side,
46                                    const Standard_Real         DistMax)
47 {
48   Perform (Cu,P,Side,DistMax);
49 }
50
51 //=============================================================================
52 //function :
53 // purpose :
54 //=============================================================================
55 Bisector_BisecPC::Bisector_BisecPC(const Handle(Geom2d_Curve)& Cu, 
56                                    const gp_Pnt2d&             P,
57                                    const Standard_Real         Side,
58                                    const Standard_Real         UMin,
59                                    const Standard_Real         UMax)
60
61 {
62   curve    = Handle (Geom2d_Curve)::DownCast(Cu->Copy());
63   point    = P;
64   sign     = Side;
65   startIntervals.Append(UMin);
66   endIntervals  .Append(UMax);  
67   bisInterval    = 1;
68   extensionStart = Standard_False;
69   extensionEnd   = Standard_False; 
70   pointStartBis  = Value(UMin);
71   pointEndBis    = Value(UMax);
72   isConvex = Bisector::IsConvex(curve,sign);
73 }
74
75 //=============================================================================
76 //function : Perform
77 // purpose :
78 //=============================================================================
79 void  Bisector_BisecPC::Perform(const Handle(Geom2d_Curve)& Cu, 
80                                 const gp_Pnt2d&             P,
81                                 const Standard_Real         Side,
82                                 const Standard_Real         DistMax)
83 {
84   curve    = Handle (Geom2d_Curve)::DownCast(Cu->Copy());
85   point    = P;
86   distMax  = DistMax;
87   sign     = Side;
88   isConvex = Bisector::IsConvex(curve,sign);
89   //--------------------------------------------
90   // Calculate interval of definition.
91   //--------------------------------------------
92   ComputeIntervals();
93   if (isEmpty) return;
94
95   //-------------------------
96   // Construction extensions.
97   //-------------------------  
98   bisInterval    = 1;
99   extensionStart = Standard_False;
100   extensionEnd   = Standard_False;
101   pointStartBis  = Value(startIntervals.First());
102   pointEndBis    = Value(endIntervals  .Last());
103
104   if (!isConvex) {
105     if (point.IsEqual(curve->Value(curve->FirstParameter()),
106                       Precision::Confusion())               ) {
107       extensionStart = Standard_True;
108       Standard_Real UFirst = startIntervals.First() - P.Distance(pointStartBis);
109       startIntervals.InsertBefore(1,UFirst);
110       endIntervals  .InsertBefore(1,startIntervals.Value(2));
111       bisInterval = 2;
112     }
113     else if (point.IsEqual(curve->Value(curve->LastParameter()),
114                            Precision::Confusion())              ) {
115       extensionEnd = Standard_True;      
116       Standard_Real ULast = endIntervals.Last() + P.Distance(pointEndBis);
117       startIntervals.Append(endIntervals.Last());
118       endIntervals  .Append(ULast);
119       bisInterval = 1;
120     }
121   }
122 }
123
124 //=============================================================================
125 //function : IsExtendAtStart
126 //purpose  :
127 //=============================================================================
128 Standard_Boolean Bisector_BisecPC::IsExtendAtStart() const
129 {
130   return extensionStart;
131 }
132
133 //=============================================================================
134 //function : IsExtendAtEnd
135 //purpose  :
136 //=============================================================================
137 Standard_Boolean Bisector_BisecPC::IsExtendAtEnd() const
138 {
139   return extensionEnd;
140 }
141
142 //=============================================================================
143 //function : Reverse
144 //purpose  :
145 //=============================================================================
146 void Bisector_BisecPC::Reverse()
147 {
148   Standard_NotImplemented::Raise();
149 }
150
151 //=============================================================================
152 //function : ReversedParameter
153 //purpose  :
154 //=============================================================================
155 Standard_Real  Bisector_BisecPC::ReversedParameter(const Standard_Real U) const
156 {
157  return LastParameter() + FirstParameter() - U;
158 }
159
160 //=============================================================================
161 //function : Copy
162 //purpose  :
163 //=============================================================================
164 Handle(Geom2d_Geometry) Bisector_BisecPC::Copy() const
165 {
166   Handle(Geom2d_Curve) CopyC = Handle(Geom2d_Curve)::DownCast(curve->Copy());
167   Handle(Bisector_BisecPC) C = new Bisector_BisecPC();
168
169   C->Init (CopyC,point,sign,
170            startIntervals,endIntervals,bisInterval,currentInterval,
171            shiftParameter,distMax,isEmpty,isConvex,extensionStart,extensionEnd,
172            pointStartBis,pointEndBis);
173   return C;  
174 }
175
176 //=============================================================================
177 //function : Transform
178 //purpose  :
179 //=============================================================================
180 void Bisector_BisecPC::Transform(const gp_Trsf2d& T)
181 {
182   curve        ->Transform(T);
183   point        . Transform(T);
184   pointStartBis. Transform(T);
185   pointEndBis  . Transform(T);
186 }
187
188 //=============================================================================
189 //function : IsCN
190 //purpose  :
191 //=============================================================================
192 Standard_Boolean Bisector_BisecPC::IsCN(const Standard_Integer N) const 
193 {
194   return curve->IsCN(N+1);
195 }
196
197 //=============================================================================
198 //function : FirstParameter
199 //purpose  :
200 //=============================================================================
201 Standard_Real Bisector_BisecPC::FirstParameter() const
202 {
203  return startIntervals.First();
204 }
205
206 //=============================================================================
207 //function : LastParameter
208 //purpose  :
209 //=============================================================================
210 Standard_Real Bisector_BisecPC::LastParameter() const
211 {
212  return endIntervals.Last();
213 }
214
215 //=============================================================================
216 //function : Continuity
217 //purpose  :
218 //=============================================================================
219 GeomAbs_Shape Bisector_BisecPC::Continuity() const 
220 {
221   GeomAbs_Shape Cont = curve->Continuity();
222   switch (Cont) {
223   case GeomAbs_C1 : return GeomAbs_C0; 
224   case GeomAbs_C2 : return GeomAbs_C1;
225   case GeomAbs_C3 : return GeomAbs_C2;
226   case GeomAbs_CN : return GeomAbs_CN;  
227 #ifndef DEB
228   default: break;
229 #endif
230   }
231   return GeomAbs_C0;
232 }
233
234 //=============================================================================
235 //function : NbIntervals
236 //purpose  :
237 //=============================================================================
238 Standard_Integer Bisector_BisecPC::NbIntervals() const
239 {
240   return startIntervals.Length();
241 }
242
243 //=============================================================================
244 //function : IntervalFirst
245 //purpose  :
246 //=============================================================================
247 Standard_Real Bisector_BisecPC::IntervalFirst(const Standard_Integer I) const
248 {
249   return startIntervals.Value(I);
250 }
251     
252 //=============================================================================
253 //function : IntervalLast
254 //purpose  :
255 //=============================================================================
256 Standard_Real Bisector_BisecPC::IntervalLast(const Standard_Integer I) const
257 {
258   return endIntervals.Value(I);
259 }
260
261 //=============================================================================
262 //function : IntervalContinuity
263 //purpose  :
264 //=============================================================================
265 GeomAbs_Shape Bisector_BisecPC::IntervalContinuity() const
266 {
267   GeomAbs_Shape Cont = curve->Continuity();
268   switch (Cont) {
269   case GeomAbs_C1 : return GeomAbs_C0; 
270   case GeomAbs_C2 : return GeomAbs_C1;
271   case GeomAbs_C3 : return GeomAbs_C2;
272   case GeomAbs_CN : return GeomAbs_CN;  
273 #ifndef DEB
274   default: break;
275 #endif
276   }
277   return GeomAbs_C0; 
278 }
279
280 //=============================================================================
281 //function : IsClosed
282 //purpose  :
283 //=============================================================================
284 Standard_Boolean Bisector_BisecPC::IsClosed() const
285 {
286   if (curve->IsClosed()) {
287     //-----------------------------------------------------------------------
288     // The bisectrice is closed if the curve is closed and the bissectrice
289     // has only one domain of continuity equal to the one of the curve.
290     // -----------------------------------------------------------------------
291     if (startIntervals.First() == curve->FirstParameter() &&
292         endIntervals  .First() == curve->LastParameter ()    )
293       return Standard_True;
294   }
295   return Standard_False;
296 }
297
298 //=============================================================================
299 //function : IsPeriodic
300 //purpose  :
301 //=============================================================================
302 Standard_Boolean Bisector_BisecPC::IsPeriodic() const
303 {
304   return Standard_False;
305 }
306
307 //=============================================================================
308 //function : Extension
309 // purpose :
310 //=============================================================================
311 void Bisector_BisecPC::Extension(const Standard_Real    U,
312                                        gp_Pnt2d&        P,
313                                        gp_Vec2d&        V1,
314                                        gp_Vec2d&        V2,
315                                        gp_Vec2d&        V3 ) const
316 {
317   gp_Dir2d      DirExt;
318   Standard_Real dU;
319
320   if      ( U < startIntervals.Value(bisInterval)) {
321     dU = U - startIntervals.Value(bisInterval);
322     DirExt.SetCoord(pointStartBis.X() - point.X(),
323                     pointStartBis.Y() - point.Y());
324     P.SetCoord(pointStartBis.X() + dU*DirExt.X(),
325                pointStartBis.Y() + dU*DirExt.Y());
326   }
327   else if ( U > endIntervals.Value(bisInterval)) { 
328     dU =  U - endIntervals.Value(bisInterval);
329     DirExt.SetCoord(point.X() - pointEndBis.X(),
330                     point.Y() - pointEndBis.Y()); 
331     P.SetCoord(pointEndBis.X() + dU*DirExt.X(),
332                pointEndBis.Y() + dU*DirExt.Y());
333   }
334   V1.SetCoord(DirExt.X(),DirExt.Y());
335   V2.SetCoord(0.        ,0.        );
336   V3.SetCoord(0.        ,0.        );
337 }
338
339
340 //=============================================================================
341 //function : Values
342 // purpose : To each point of the curve is associated a point on the 
343 //           bissectrice. The equation of the bissectrice is:
344 //                              || PP(u)||**2
345 //           F(u) = P(u) - 1/2* -------------- * N(u)
346 //                              (N(u)|PP(u))
347 //
348 //           N(u) normal to the curve by u.
349 //           ( | ) designation of the scalar product.
350 //=============================================================================
351 void Bisector_BisecPC::Values(const Standard_Real    U,
352                               const Standard_Integer N,
353                                     gp_Pnt2d&        P,
354                                     gp_Vec2d&        V1,
355                                     gp_Vec2d&        V2,
356                                     gp_Vec2d&        V3 ) const
357 {
358   if ( U < startIntervals.Value(bisInterval)) {
359     Extension(U,P,V1,V2,V3);
360     return;
361   }
362   else if ( U > endIntervals.Value(bisInterval)) { 
363     Extension(U,P,V1,V2,V3);
364     return;
365   }
366   Standard_Real UOnCurve = LinkBisCurve(U);
367
368   gp_Vec2d      Tu,Tuu,T3u;
369   gp_Pnt2d      PC;
370
371   switch (N) {
372   case 0 :  {curve->D1(UOnCurve,PC,Tu)        ;break;}
373   case 1 :  {curve->D2(UOnCurve,PC,Tu,Tuu)    ;break;}
374   case 2 :  {curve->D3(UOnCurve,PC,Tu,Tuu,T3u);break;}
375   }
376   
377   gp_Vec2d PPC(PC.X() - point.X(), PC.Y() - point.Y());
378   gp_Vec2d Nor( - Tu.Y(), Tu.X());
379   
380   Standard_Real SquarePPC = PPC.SquareMagnitude();
381   Standard_Real NorPPC    = Nor.Dot(PPC);
382   Standard_Real A1;
383
384   if (Abs(NorPPC) > gp::Resolution() && (NorPPC*sign) < 0.) {
385     A1 = 0.5*SquarePPC/NorPPC;
386     P.SetCoord(PC.X() - Nor.X()*A1, PC.Y() - Nor.Y()*A1);
387   }
388   else {return; }
389   
390   if (N == 0) return;                                 // End Calculation Point;
391
392   gp_Vec2d      Nu ( - Tuu.Y() , Tuu.X());            // derivative of the normal by U.
393   Standard_Real NuPPC     = Nu .Dot(PPC);
394   Standard_Real TuPPC     = Tu .Dot(PPC);
395   Standard_Real NorPPCE2  = NorPPC*NorPPC;
396   Standard_Real A2        = TuPPC/NorPPC - 0.5*NuPPC*SquarePPC/NorPPCE2;
397
398 //--------------------------
399   V1 = Tu - A1*Nu - A2*Nor;
400 //--------------------------
401   if (N == 1) return;                                       // End calculation D1.
402
403   gp_Vec2d Nuu ( - T3u.Y() , T3u.X());
404   
405   Standard_Real NorPPCE4 = NorPPCE2*NorPPCE2;
406   Standard_Real NuuPPC   = Nuu.Dot(PPC);
407   Standard_Real TuuPPC   = Tuu.Dot(PPC);
408   
409   Standard_Real A21 = TuuPPC/NorPPC - TuPPC*NuPPC/NorPPCE2;
410   Standard_Real A22 = (0.5*NuuPPC*SquarePPC + NuPPC*TuPPC)/NorPPCE2 - 
411                       NuPPC*SquarePPC*NorPPC*NuPPC/NorPPCE4;
412   Standard_Real A2u = A21 - A22;      
413 //----------------------------------------
414   V2  = Tuu - 2*A2*Nu - A1*Nuu - A2u*Nor;
415 //----------------------------------------
416 }
417
418 //=============================================================================
419 //function : Curvature
420 //purpose  :
421 //=============================================================================
422 // Unused :
423 #ifdef DEB
424 static Standard_Real Curvature (const Handle(Geom2d_Curve)& C,
425                                       Standard_Real         U,
426                                       Standard_Real         Tol)
427 {
428   Standard_Real K1;
429   gp_Vec2d      D1,D2;
430   gp_Pnt2d      P;
431   C->D2(U,P,D1,D2);
432   Standard_Real Norm2 = D1.SquareMagnitude();;
433   if (Norm2 < Tol) {
434     K1 = 0.0;
435   }
436   else {
437     K1   = (D1^D2)/(Norm2*sqrt(Norm2));
438   }
439   return K1;
440 }
441 #endif
442
443 //=============================================================================
444 //function : Distance
445 //purpose  : distance at the square of the point of parameter U to the curve and at point:
446 //
447 //            2             ||PP(u)||**4           2
448 //           d =   1/4* ------------------- ||Nor||
449 //                         (Nor(u)/PP(u))**2 
450 //
451 //           where Nor is the normal to the curve by U. 
452 //=============================================================================
453 Standard_Real Bisector_BisecPC::Distance (const Standard_Real U) const
454 {
455   gp_Vec2d Tan;
456   gp_Pnt2d PC;
457
458   Standard_Real UOnCurve = LinkBisCurve(U);
459   
460   curve->D1(UOnCurve,PC,Tan);
461   gp_Vec2d PPC(PC.X() - point.X(), PC.Y() - point.Y());
462   gp_Vec2d Nor( - Tan.Y(), Tan.X());
463
464   Standard_Real NorNor       = Nor.SquareMagnitude();
465   Standard_Real SquareMagPPC = PPC.SquareMagnitude();
466   Standard_Real Prosca       = Nor.Dot(PPC);
467   
468   if (point.IsEqual(PC,Precision::Confusion())) {
469     if (isConvex) { return 0.;}
470     //----------------------------------------------------
471     // the point is on a concave curve. 
472     // The required point is not the common point.
473     // This can avoid the discontinuity of the bisectrice.
474     //----------------------------------------------------
475     else { return Precision::Infinite();} 
476   }
477
478   if (Abs(Prosca) < Precision::Confusion() || (Prosca*sign) > 0. ) {
479     return Precision::Infinite();
480   }
481   else {    
482     Standard_Real A  = 0.5*SquareMagPPC/Prosca;
483     Standard_Real Dist = A*A*NorNor;
484     //----------------------------------------
485     // Test Curvature if the curve is concave.
486     //----------------------------------------
487 //    if (!isConvex){
488 //      Standard_Real K  = Curvature(curve,UOnCurve,Precision::Confusion());
489 //      if (K  != 0.) {
490 //      if (Dist > 1/(K*K)) { Dist = Precision::Infinite();}
491 //      }
492 //    }
493     return Dist;
494   }
495 }
496
497
498
499 //=============================================================================
500 //function : D0
501 // purpose : 
502 //=============================================================================
503 void Bisector_BisecPC::D0(const Standard_Real     U,
504                                 gp_Pnt2d&         P) const
505 {
506   P = point;
507   gp_Vec2d V1,V2,V3;
508   Values(U,0,P,V1,V2,V3);
509 }
510
511
512 //=============================================================================
513 //function : D1
514 // purpose : 
515 //=============================================================================
516 void Bisector_BisecPC::D1(const Standard_Real     U,
517                                 gp_Pnt2d&         P,
518                                 gp_Vec2d&         V ) const
519 {
520   P = point;
521   V.SetCoord(0.,0.);
522   gp_Vec2d V2,V3;
523   Values(U,1,P,V,V2,V3);
524 }
525
526
527 //=============================================================================
528 //function : D2
529 // purpose : 
530 //=============================================================================
531 void Bisector_BisecPC::D2(const Standard_Real     U,
532                                 gp_Pnt2d&         P,
533                                 gp_Vec2d&         V1,
534                                 gp_Vec2d&         V2) const
535 {
536   P = point;
537   V1.SetCoord(0.,0.);
538   V2.SetCoord(0.,0.);
539   gp_Vec2d V3;
540   Values(U,2,P,V1,V2,V3);
541 }
542
543 //=============================================================================
544 //function : D3
545 // purpose : 
546 //=============================================================================
547 void Bisector_BisecPC::D3(const Standard_Real     U,
548                                 gp_Pnt2d&         P,
549                                 gp_Vec2d&         V1,
550                                 gp_Vec2d&         V2,
551                                 gp_Vec2d&         V3) const
552 {
553   P = point;
554   V1.SetCoord(0.,0.);
555   V2.SetCoord(0.,0.);
556   V3.SetCoord(0.,0.);
557   Values(U,3,P,V1,V2,V3);
558 }
559
560
561 //=============================================================================
562 //function : DN
563 // purpose : 
564 //=============================================================================
565 gp_Vec2d Bisector_BisecPC::DN (const Standard_Real     U,
566                                const Standard_Integer  N) const
567 {
568   gp_Pnt2d P = point;
569   gp_Vec2d V1(0.,0.);
570   gp_Vec2d V2(0.,0.);
571   gp_Vec2d V3(0.,0.);
572   Values (U,N,P,V1,V2,V3);
573   switch (N) {
574   case 1 : return V1;
575   case 2 : return V2;
576   case 3 : return V3;
577   default: {
578     Standard_NotImplemented::Raise();
579     }
580   }
581   return V1;
582 }
583
584 //=============================================================================
585 //function : SearchBound
586 // purpose : 
587 //=============================================================================
588 Standard_Real Bisector_BisecPC::SearchBound (const Standard_Real U1,
589                                              const Standard_Real U2) const
590 {
591   Standard_Real Dist1,Dist2,DistMid,U11,U22; 
592 #ifndef DEB
593   Standard_Real UMid = 0.;
594 #else
595   Standard_Real UMid;
596 #endif
597   Standard_Real Tol      = Precision::PConfusion();
598   Standard_Real DistMax2 = distMax*distMax;
599   U11 = U1; U22 = U2;
600   Dist1 = Distance(U11);
601   Dist2 = Distance(U22);
602   
603   while ((U22 - U11) > Tol) {
604     UMid    = 0.5*( U22 + U11);
605     DistMid = Distance(UMid);
606     if ((Dist1 > DistMax2) == (DistMid > DistMax2)) {
607       U11    = UMid;
608       Dist1 = DistMid;
609     }
610     else {
611       U22    = UMid;
612       Dist2 = DistMid;
613     }
614   }
615   return UMid;
616 }
617
618 //=============================================================================
619 //function : CuspFilter
620 // purpose : 
621 //=============================================================================
622 void Bisector_BisecPC::CuspFilter()
623 {
624   Standard_NotImplemented::Raise();
625 }
626
627 //=============================================================================
628 //function : ComputeIntervals
629 // purpose : 
630 //=============================================================================
631 void Bisector_BisecPC::ComputeIntervals ()
632 {
633 #ifndef DEB
634   Standard_Real U1 =0.,U2 =0.,UProj =0.;
635 #else
636   Standard_Real U1,U2,UProj;
637 #endif
638   Standard_Real UStart,UEnd;
639   Standard_Real Dist1,Dist2,DistProj;
640   isEmpty        = Standard_False;     
641   shiftParameter = 0.;
642   Standard_Boolean YaProj   = Standard_False;
643   Standard_Real    DistMax2 = distMax*distMax;
644
645   U1 = curve->FirstParameter();
646   U2 = curve->LastParameter();
647   Dist1    = Distance(U1);
648   Dist2    = Distance(U2);
649   DistProj = Precision::Infinite();
650
651   Geom2dAPI_ProjectPointOnCurve Proj(point,curve,U1,U2);
652   if (Proj.NbPoints() > 0) {
653     UProj    = Proj.LowerDistanceParameter();
654     DistProj = Distance(UProj);
655     YaProj   = Standard_True;
656   } 
657
658   if (Dist1 < DistMax2 && Dist2 < DistMax2) {
659     if (DistProj > DistMax2 && YaProj) {
660       isEmpty = Standard_True;
661     }
662     else {
663       startIntervals.Append(U1);
664       endIntervals  .Append(U2);
665     }
666     return;
667   }
668   else if (Dist1 > DistMax2 && Dist2 > DistMax2) {
669     if (DistProj < DistMax2) {
670       UStart = SearchBound(U1,UProj);
671       UEnd   = SearchBound(UProj,U2);
672     }
673      else {
674       isEmpty = Standard_True;
675       return;
676     }
677   }
678   else if (Dist1 < DistMax2) {
679     UStart = U1;
680     UEnd = SearchBound(U1,U2);
681   }
682   else if (Dist2 < DistMax2) {
683     UEnd = U2;
684     UStart = SearchBound(U1,U2);
685   }
686   startIntervals.Append(UStart);
687   endIntervals  .Append(UEnd);
688
689   //------------------------------------------------------------------------
690   // Eventual offset of the parameter on the curve correspondingly to the one 
691   // on the curve. The offset can be done if the curve is periodical and the 
692   // point of initial parameter is less then the interval of continuity.
693   //------------------------------------------------------------------------
694   if (curve->IsPeriodic()) {
695     if (startIntervals.Length() > 1) {               // Plusieurs intervals.
696       if (endIntervals  .Last()  == curve->LastParameter() &&
697           startIntervals.First() == curve->FirstParameter()   ) {
698         //---------------------------------------------------------------
699         // the bissectrice is defined at the origin.
700         // => Fusion of the first and the last interval.
701         // => 0 on the bisectrice becomes the start of the first interval
702         // => offset of parameter on all limits of intervals.
703         //---------------------------------------------------------------
704         startIntervals.Remove(1);
705         endIntervals  .Remove(endIntervals.Length());
706         
707         shiftParameter = Period() - startIntervals.First() ;
708         for (Standard_Integer k = 1; k <= startIntervals.Length(); k++) {
709           endIntervals  .ChangeValue(k) += shiftParameter;
710           startIntervals.ChangeValue(k) += shiftParameter;
711         }
712         startIntervals.ChangeValue(1) = 0.;
713       }
714     }
715   }
716 }
717
718 //=============================================================================
719 //function : LinkBisCurve
720 //purpose  : 
721 //=============================================================================
722 Standard_Real Bisector_BisecPC::LinkBisCurve(const Standard_Real U) const 
723 {
724   return (U - shiftParameter);
725
726
727 //=============================================================================
728 //function : LinkCurveBis
729 //purpose  : 
730 //=============================================================================
731 Standard_Real Bisector_BisecPC::LinkCurveBis(const Standard_Real U) const 
732 {
733   return (U + shiftParameter);
734
735
736 //=============================================================================
737 //function : IsEmpty
738 //purpose  : 
739 //=============================================================================
740 Standard_Boolean Bisector_BisecPC::IsEmpty() const
741 {
742   return isEmpty;
743 }
744
745 //==========================================================================
746 //function : Parameter
747 //purpose  :
748 //==========================================================================
749 Standard_Real Bisector_BisecPC::Parameter(const gp_Pnt2d& P) const
750 {
751   Standard_Real    Tol     = Precision::Confusion();
752
753   if (P.IsEqual(pointStartBis,Tol)) {return startIntervals.Value(bisInterval);}
754   if (P.IsEqual(pointEndBis  ,Tol)) {return endIntervals  .Value(bisInterval);}
755
756   if (extensionStart) {
757     gp_Ax2d Axe(pointStartBis,gp_Dir2d(pointStartBis.X() - P.X(),
758                                        pointStartBis.Y() - P.Y()));
759     Standard_Real U    = ElCLib::LineParameter(Axe,P);
760     gp_Pnt2d      Proj = ElCLib::LineValue(U,Axe);
761     if (Proj.IsEqual(P,Tol) && U < 0.) {
762       return U + startIntervals.Value(bisInterval);
763     }
764   }
765   if (extensionEnd)   {    
766     gp_Ax2d Axe(pointEndBis,gp_Dir2d(P.X() - pointEndBis.X(),
767                                      P.Y() - pointEndBis.Y()));
768     Standard_Real U    = ElCLib::LineParameter(Axe,P);
769     gp_Pnt2d      Proj = ElCLib::LineValue(U,Axe);
770     if (Proj.IsEqual(P,Tol) && U > 0.) {
771       return U + endIntervals.Value(bisInterval);
772     }
773   }
774 #ifndef DEB
775   Standard_Real                 UOnCurve = 0.;
776 #else
777   Standard_Real                 UOnCurve;
778 #endif
779   Geom2dAPI_ProjectPointOnCurve Proj(P,curve,
780                                      curve->FirstParameter(),curve->LastParameter());
781   if (Proj.NbPoints() > 0) {
782     UOnCurve = Proj.LowerDistanceParameter();
783   }
784   return LinkCurveBis(UOnCurve);
785 }
786
787
788 //=============================================================================
789 //function : Indent
790 // purpose : 
791 //=============================================================================
792 static void Indent(const Standard_Integer Offset) {
793   if (Offset > 0) {
794     for (Standard_Integer i = 0; i < Offset; i++) {cout << " ";}
795   }
796 }
797
798 //=============================================================================
799 //function : Init
800 // purpose : 
801 //=============================================================================
802 void Bisector_BisecPC::Init (const Handle_Geom2d_Curve&    Curve, 
803                              const gp_Pnt2d&               Point, 
804                              const Standard_Real           Sign, 
805                              const TColStd_SequenceOfReal& StartIntervals, 
806                              const TColStd_SequenceOfReal& EndIntervals, 
807                              const Standard_Integer        BisInterval, 
808                              const Standard_Integer        CurrentInterval, 
809                              const Standard_Real           ShiftParameter, 
810                              const Standard_Real           DistMax, 
811                              const Standard_Boolean        IsEmpty, 
812                              const Standard_Boolean        IsConvex, 
813                              const Standard_Boolean        ExtensionStart, 
814                              const Standard_Boolean        ExtensionEnd, 
815                              const gp_Pnt2d&               PointStartBis, 
816                              const gp_Pnt2d&               PointEndBis)
817 {
818   curve           = Curve;
819   point           = Point; 
820   sign            = Sign ;
821   startIntervals  = StartIntervals; 
822   endIntervals    = EndIntervals;
823   bisInterval     = BisInterval;
824   currentInterval = CurrentInterval;
825   shiftParameter  = ShiftParameter;
826   distMax         = DistMax;
827   isEmpty         = IsEmpty;
828   isConvex        = IsConvex;
829   extensionStart  = ExtensionStart;
830   extensionEnd    = ExtensionEnd;
831   pointStartBis   = PointStartBis;
832   pointEndBis     = PointEndBis;   
833 }
834
835 //=============================================================================
836 //function : Dump
837 // purpose : 
838 //=============================================================================
839 //void Bisector_BisecPC::Dump(const Standard_Integer Deep, 
840 void Bisector_BisecPC::Dump(const Standard_Integer , 
841                             const Standard_Integer Offset) const 
842 {
843   Indent (Offset);
844   cout <<"Bisector_BisecPC :"<<endl;
845   Indent (Offset);
846   cout <<"Point :"<<endl;
847   cout <<" X = "<<point.X()<<endl;
848   cout <<" Y = "<<point.Y()<<endl;
849   cout <<"Sign  :"<<sign<<endl;
850   cout <<"Number Of Intervals :"<<startIntervals.Length()<<endl;
851   for (Standard_Integer i = 1; i <= startIntervals.Length(); i++) {
852     cout <<"Interval number :"<<i<<"Start :"<<startIntervals.Value(i)
853                                  <<"  end :"<<  endIntervals.Value(i)<<endl ;
854   }
855   cout <<"Index Current Interval :"<<currentInterval<<endl;
856 }
857
858
859
860
861
862