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