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