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