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