0022312: Translation of french commentaries in OCCT files
[occt.git] / src / Bisector / Bisector_BisecCC.cxx
CommitLineData
7fd59977 1// File: Bisector_BisecCC.cxx
2// Created: Thu Mar 10 17:54:52 1994
3// Author: Yves FRICAUD
4// <yfr@phylox>
5
6#include <Bisector_BisecCC.ixx>
7#include <Bisector_BisecPC.hxx>
8#include <Bisector.hxx>
9#include <Bisector_Curve.hxx>
10#include <Bisector_FunctionH.hxx>
11#include <Bisector_PointOnBis.hxx>
12#include <Geom2dAdaptor_Curve.hxx>
13#include <Geom2d_Curve.hxx>
14#include <Geom2dLProp_CLProps2d.hxx>
15#include <Geom2dGcc.hxx>
16#include <Geom2dGcc_Circ2d2TanRad.hxx>
17#include <Geom2dGcc_QualifiedCurve.hxx>
18#include <Geom2d_TrimmedCurve.hxx>
19#include <Geom2d_Circle.hxx>
20#include <Geom2d_Line.hxx>
21#include <Geom2dInt_GInter.hxx>
22#include <Geom2dAPI_ProjectPointOnCurve.hxx>
23#include <gp_Pnt2d.hxx>
24#include <gp_Vec2d.hxx>
25#include <gp.hxx>
26#include <IntRes2d_IntersectionPoint.hxx>
27#include <Precision.hxx>
28#include <math_FunctionRoot.hxx>
29#include <math_FunctionRoots.hxx>
30#include <math_BissecNewton.hxx>
31
32#include <Standard_OutOfRange.hxx>
33#include <Standard_DivideByZero.hxx>
34#include <Standard_NotImplemented.hxx>
35
36
37static Standard_Real ProjOnCurve (const gp_Pnt2d& P,
38 const Handle(Geom2d_Curve)& C);
39
40static Standard_Real Curvature (const Handle(Geom2d_Curve)& C,
41 Standard_Real U,
42 Standard_Real Tol) ;
43
44static Standard_Boolean TestExtension (const Handle(Geom2d_Curve)& C1,
45 const Handle(Geom2d_Curve)& C2,
46 const Standard_Integer Start_End);
47
48static Standard_Boolean DiscretPar(const Standard_Real DU,
49 const Standard_Real EpsMin,
50 const Standard_Real EpsMax,
51 const Standard_Integer NbMin,
52 const Standard_Integer NbMax,
53 Standard_Real& Eps,
54 Standard_Integer& Nb);
55
56//=============================================================================
57//function :
58//purpose :
59//=============================================================================
60Bisector_BisecCC::Bisector_BisecCC()
61{
62 shiftParameter = 0;
63 isEmpty = Standard_False;
64}
65
66//=============================================================================
67//function :
68//purpose :
69//=============================================================================
70Bisector_BisecCC::Bisector_BisecCC(const Handle(Geom2d_Curve)& Cu1,
71 const Handle(Geom2d_Curve)& Cu2,
72 const Standard_Real Side1,
73 const Standard_Real Side2,
74 const gp_Pnt2d& Origin,
75 const Standard_Real DistMax)
76{
77 Perform (Cu1,Cu2,Side1,Side2,Origin,DistMax);
78}
79
80//=============================================================================
81//function : Perform
82//purpose :
83//=============================================================================
84void Bisector_BisecCC::Perform(const Handle(Geom2d_Curve)& Cu1,
85 const Handle(Geom2d_Curve)& Cu2,
86 const Standard_Real Side1,
87 const Standard_Real Side2,
88 const gp_Pnt2d& Origin,
89 const Standard_Real DistMax)
90{
91 isEmpty = Standard_False;
92 distMax = DistMax;
93
94 curve1 = Handle (Geom2d_Curve)::DownCast(Cu1->Copy());
95 curve2 = Handle (Geom2d_Curve)::DownCast(Cu2->Copy());
96
97 sign1 = Side1;
98 sign2 = Side2;
99
100 isConvex1 = Bisector::IsConvex(curve1,sign1);
101 isConvex2 = Bisector::IsConvex(curve2,sign2);
102
103 Standard_Real U,UC1,UC2,Dist,dU,USol;
104 gp_Pnt2d P;
105 Standard_Integer NbPnts = 21;
106 Standard_Real EpsMin = 10*Precision::Confusion();
107 Standard_Boolean YaPoly = Standard_True;
108 Standard_Boolean OriInPoly = Standard_False;
109 //---------------------------------------------
0d969553 110 // Calculate first point of the polygon.
7fd59977 111 //---------------------------------------------
112 U = ProjOnCurve (Origin,curve1);
113 P = ValueByInt (U,UC1,UC2,Dist);
114
115 if (Dist < Precision::Infinite()) {
116 //----------------------------------------------------
0d969553
Y
117 // the parameter of the origin point gives a point
118 // on the polygon.
7fd59977 119 //----------------------------------------------------
120 myPolygon.Append(Bisector_PointOnBis(UC1,UC2,U,Dist,P));
121 startIntervals.Append(U);
122 if (P.IsEqual(Origin,Precision::Confusion())) {
123 //----------------------------------------
0d969553 124 // test if the first point is the origin.
7fd59977 125 //----------------------------------------
126 OriInPoly = Standard_True;
127 }
128 }
129 else {
130 //-------------------------------------------------------
0d969553
Y
131 // The origin point is on the extension.
132 // Find the first point of the polygon by dichotomy.
7fd59977 133 //-------------------------------------------------------
134 dU = (curve1->LastParameter() - U)/(NbPnts - 1);
135 U += dU;
136 for (Standard_Integer i = 1; i <= NbPnts - 1; i++) {
137 P = ValueByInt(U,UC1,UC2,Dist);
138 if (Dist < Precision::Infinite()) {
139 USol = SearchBound(U - dU,U);
140 P = ValueByInt(USol,UC1,UC2,Dist);
141 startIntervals.Append(USol);
142 myPolygon.Append(Bisector_PointOnBis(UC1,UC2,USol,Dist,P));
143 break;
144 }
145 U += dU;
146 }
147 }
148
149 if ( !myPolygon.Length() == 0) {
150 SupLastParameter();
151 //----------------------------------------------
0d969553 152 // Construction of the polygon of the bissectrice.
7fd59977 153 //---------------------------------------------
154 U = FirstParameter();
155 Standard_Real DU = LastParameter() - U;
156
157 if (DU < EpsMin) {NbPnts = 3;}
158 dU = DU/(NbPnts - 1);
159
160 U += dU;
161// modified by NIZHNY-EAP Fri Jan 21 09:33:20 2000 ___BEGIN___
162// prevent addition of the same point
163 gp_Pnt2d prevPnt = P;
164 for (Standard_Integer i = 1; i <= NbPnts - 1; i++) {
165 P = ValueByInt(U,UC1,UC2,Dist);
166 if (Dist < Precision::Infinite()) {
167 if (P.Distance (prevPnt) > Precision::Confusion())
168 myPolygon.Append(Bisector_PointOnBis(UC1,UC2,U,Dist,P));
169 }
170 else {
171 USol = SearchBound(U - dU,U);
172 P = ValueByInt(USol,UC1,UC2,Dist);
173 endIntervals.SetValue(1,USol);
174 if (P.Distance (prevPnt) > Precision::Confusion())
175 myPolygon.Append(Bisector_PointOnBis(UC1,UC2,USol,Dist,P));
176 break;
177 }
178 U += dU;
179 prevPnt=P;
180// modified by NIZHNY-EAP Fri Jan 21 09:33:24 2000 ___END___
181 }
182 }
183 else {
184 //----------------
0d969553 185 // Empty Polygon.
7fd59977 186 //----------------
187 YaPoly = Standard_False;
188 }
189
190 extensionStart = Standard_False;
191 extensionEnd = Standard_False;
192 pointStart = Origin;
193
194 if (isConvex1 && isConvex2) {
195 if (YaPoly) pointEnd = myPolygon.Last().Point();
196 }
197 else {
198 //-----------------------------------------------------------------------------
0d969553
Y
199 // Extension : The curve is extended at the beginning and/or the end if
200 // - one of two curves is concave.
201 // - the curves have a common point at the beginning and/or the end
202 // - the angle of opening at the common point between two curves
203 // values PI.
204 // the extension at the beginning is taken into account if the origin is found above.
205 // ie : the origin is not the in the polygon.
7fd59977 206 //-----------------------------------------------------------------------------
207
208 //---------------------------------
0d969553 209 // Do the extensions exist ?
7fd59977 210 //---------------------------------
211 if (OriInPoly) {
212 extensionStart = Standard_False;
213 }
214 else {
215 extensionStart = TestExtension(curve1,curve2,1);
216 }
217 extensionEnd = TestExtension(curve1,curve2,2);
218
219 //-----------------
0d969553 220 // Calculate pointEnd.
7fd59977 221 //-----------------
222 if (extensionEnd) {
223 pointEnd = curve1->Value(curve1->LastParameter());
224 }
225 else if (YaPoly) {
226 pointEnd = myPolygon.Last().Point();
227 }
228 else {
229 ComputePointEnd();
230 }
231 //------------------------------------------------------
0d969553 232 // Update the Limits of intervals of definition.
7fd59977 233 //------------------------------------------------------
234 if (YaPoly) {
235 if (extensionStart) {
236 gp_Pnt2d P1 = myPolygon.First().Point();
237 Standard_Real UFirst = startIntervals.First() - pointStart.Distance(P1);
238 startIntervals.InsertBefore(1,UFirst);
239 endIntervals .InsertBefore(1,startIntervals.Value(2));
240 }
241 if (extensionEnd) {
242 gp_Pnt2d P1;
243 Standard_Real UFirst,ULast;
244 P1 = myPolygon.Last().Point();
245 UFirst = endIntervals.Last();
246 ULast = UFirst + pointEnd.Distance(P1);
247 startIntervals.Append(UFirst);
248 endIntervals .Append(ULast );
249 }
250 }
251 else {
252 //--------------------------------------------------
0d969553 253 // No polygon => the bissectrice is a segment.
7fd59977 254 //--------------------------------------------------
255 startIntervals.Append(0.);
256 endIntervals .Append(pointEnd.Distance(pointStart));
257 }
258 }
259 if (!YaPoly && !extensionStart && !extensionEnd)
260 isEmpty = Standard_True;
261// modified by NIZHNY-EAP Mon Jan 17 17:32:40 2000 ___BEGIN___
262 if (myPolygon.Length() <= 2)
263 isEmpty = Standard_True;
264// modified by NIZHNY-EAP Mon Jan 17 17:32:42 2000 ___END___
265}
266
267//=============================================================================
268//function : IsExtendAtStart
269//purpose :
270//=============================================================================
271Standard_Boolean Bisector_BisecCC::IsExtendAtStart() const
272{
273 return extensionStart;
274}
275
276//=============================================================================
277//function : IsExtendAtEnd
278//purpose :
279//=============================================================================
280Standard_Boolean Bisector_BisecCC::IsExtendAtEnd() const
281{
282 return extensionEnd;
283}
284
285//=============================================================================
286//function : IsEmpty
287//purpose :
288//=============================================================================
289Standard_Boolean Bisector_BisecCC::IsEmpty() const
290{
291 return isEmpty;
292}
293
294//=============================================================================
295//function : Reverse
296//purpose :
297//=============================================================================
298void Bisector_BisecCC::Reverse()
299{
300 Standard_NotImplemented::Raise();
301}
302
303//=============================================================================
304//function : ReversedParameter
305// purpose :
306//=============================================================================
307Standard_Real Bisector_BisecCC::ReversedParameter(const Standard_Real U) const
308{
309 return LastParameter() + FirstParameter() - U;
310}
311
312//=============================================================================
313//function : Copy
314//purpose :
315//=============================================================================
316Handle(Geom2d_Geometry) Bisector_BisecCC::Copy() const
317{
318 Handle(Geom2d_Curve) CopyCurve1
319 = Handle(Geom2d_Curve)::DownCast(curve1->Copy());
320 Handle(Geom2d_Curve) CopyCurve2
321 = Handle(Geom2d_Curve)::DownCast(curve2->Copy());
322
323 Handle(Bisector_BisecCC) C = new Bisector_BisecCC();
324
325 C -> Curve (1, CopyCurve1) ; C -> Curve (2, CopyCurve2);
326 C -> Sign (1, sign1 ) ; C -> Sign (2, sign2 );
327 C -> IsConvex (1, isConvex1) ; C -> IsConvex (2, isConvex2);
328 C -> Polygon (myPolygon);
329 C -> IsEmpty (isEmpty) ;
330 C -> DistMax (distMax) ;
331 C -> StartIntervals (startIntervals); C -> EndIntervals (endIntervals);
332 C -> ExtensionStart (extensionStart); C -> ExtensionEnd (extensionEnd);
333 C -> PointStart (pointStart) ; C -> PointEnd (pointEnd) ;
334
335 return C;
336}
337
338//=============================================================================
339//function : ChangeGuide
0d969553
Y
340//purpose : Changet of the guideline for the parameters of the bissectrice
341// ATTENTION : - This can invert the direction of parameterization.
342// - This concerns only the part of the curve
343// corresponding to the polygon.
7fd59977 344//=============================================================================
345Handle(Bisector_BisecCC) Bisector_BisecCC::ChangeGuide() const
346{
347 Handle(Bisector_BisecCC) C = new Bisector_BisecCC();
348
349 C -> Curve (1, curve2) ; C -> Curve (2, curve1);
350 C -> Sign (1, sign2 ) ; C -> Sign (2, sign1 );
351 C -> IsConvex (1, isConvex2); C -> IsConvex (2, isConvex1);
352
353 //-------------------------------------------------------------------------
0d969553
Y
354 // Construction of the new polygon from the initial one.
355 // inversion of PointOnBis and Calculation of new parameters on the bissectrice.
7fd59977 356 //-------------------------------------------------------------------------
357 Bisector_PolyBis Poly;
358 if (sign1 == sign2 ) {
359 //---------------------------------------------------------------
0d969553 360 // elements of the new polygon are ranked in the other direction.
7fd59977 361 //---------------------------------------------------------------
362 for (Standard_Integer i = myPolygon.Length(); i >=1; i--) {
363 Bisector_PointOnBis P = myPolygon.Value(i);
364 Bisector_PointOnBis NewP (P.ParamOnC2(), P.ParamOnC1(),
365 P.ParamOnC2(), P.Distance (),
366 P.Point());
367 Poly.Append (NewP);
368 }
369 }
370 else {
371 for (Standard_Integer i = 1; i <= myPolygon.Length(); i ++) {
372 Bisector_PointOnBis P = myPolygon.Value(i);
373 Bisector_PointOnBis NewP (P.ParamOnC2(), P.ParamOnC1(),
374 P.ParamOnC2(), P.Distance (),
375 P.Point());
376 Poly.Append (NewP);
377 }
378 }
379 C -> Polygon (Poly);
380 C -> FirstParameter (Poly.First().ParamOnBis());
381 C -> LastParameter (Poly.Last() .ParamOnBis());
382
383 return C;
384}
385
386//=============================================================================
387//function : Transform
388//purpose :
389//=============================================================================
390void Bisector_BisecCC::Transform (const gp_Trsf2d& T)
391{
392 curve1 ->Transform(T);
393 curve2 ->Transform(T);
394 myPolygon . Transform(T);
395 pointStart. Transform(T);
396 pointEnd . Transform(T);
397}
398
399//=============================================================================
400//function : IsCN
401//purpose :
402//=============================================================================
403Standard_Boolean Bisector_BisecCC::IsCN (const Standard_Integer N) const
404{
405 return (curve1->IsCN(N+1) && curve2->IsCN(N+1));
406}
407
408//=============================================================================
409//function : FirstParameter
410//purpose :
411//=============================================================================
412Standard_Real Bisector_BisecCC::FirstParameter() const
413{
414 return startIntervals.First();
415}
416
417//=============================================================================
418//function : LastParameter
419//purpose :
420//=============================================================================
421Standard_Real Bisector_BisecCC::LastParameter() const
422{
423 return endIntervals.Last();
424}
425
426//=============================================================================
427//function : Continuity
428//purpose :
429//=============================================================================
430GeomAbs_Shape Bisector_BisecCC::Continuity() const
431{
432 GeomAbs_Shape Cont = curve1->Continuity();
433 switch (Cont) {
434 case GeomAbs_C1 : return GeomAbs_C0;
435 case GeomAbs_C2 : return GeomAbs_C1;
436 case GeomAbs_C3 : return GeomAbs_C2;
437 case GeomAbs_CN : return GeomAbs_CN;
438#ifndef DEB
439 default: break;
440#endif
441 }
442 return GeomAbs_C0;
443}
444
445//=============================================================================
446//function : NbIntervals
447//purpose :
448//=============================================================================
449Standard_Integer Bisector_BisecCC::NbIntervals() const
450{
451 return startIntervals.Length();
452}
453
454//=============================================================================
455//function : IntervalFirst
456//purpose :
457//=============================================================================
458Standard_Real Bisector_BisecCC::IntervalFirst(const Standard_Integer Index) const
459{
460 return startIntervals.Value(Index);
461}
462
463//=============================================================================
464//function : IntervalLast
465//purpose :
466//=============================================================================
467Standard_Real Bisector_BisecCC::IntervalLast(const Standard_Integer Index) const
468{
469 return endIntervals.Value(Index);
470}
471
472//=============================================================================
473//function : IntervalContinuity
474//purpose :
475//=============================================================================
476GeomAbs_Shape Bisector_BisecCC::IntervalContinuity() const
477{
478 GeomAbs_Shape Cont = curve1->Continuity();
479 switch (Cont) {
480 case GeomAbs_C1 : return GeomAbs_C0;
481 case GeomAbs_C2 : return GeomAbs_C1;
482 case GeomAbs_C3 : return GeomAbs_C2;
483 case GeomAbs_CN : return GeomAbs_CN;
484#ifndef DEB
485 default: break;
486#endif
487 }
488 return GeomAbs_C0;
489}
490
491//=============================================================================
492//function : IsClosed
493//purpose :
494//=============================================================================
495Standard_Boolean Bisector_BisecCC::IsClosed() const
496{
497 if (curve1->IsClosed()) {
498 if (startIntervals.First() == curve1->FirstParameter() &&
499 endIntervals .Last () == curve1->LastParameter () )
500 return Standard_True;
501 }
502 return Standard_False;
503}
504
505//=============================================================================
506//function : IsPeriodic
507//purpose :
508//=============================================================================
509Standard_Boolean Bisector_BisecCC::IsPeriodic() const
510{
511 return Standard_False;
512}
513
514
515//=============================================================================
516//function : Curvature
517//purpose :
518//=============================================================================
519static Standard_Real Curvature (const Handle(Geom2d_Curve)& C,
520 Standard_Real U,
521 Standard_Real Tol)
522{
523 Standard_Real K1;
524 gp_Vec2d D1,D2;
525 gp_Pnt2d P;
526 C->D2(U,P,D1,D2);
527 Standard_Real Norm2 = D1.SquareMagnitude();;
528 if (Norm2 < Tol) {
529 K1 = 0.0;
530 }
531 else {
532 K1 = (D1^D2)/(Norm2*sqrt(Norm2));
533 }
534 return K1;
535}
536
537//=============================================================================
538//function : Value
0d969553 539//purpose : CALCULATE THE CURRENT POINT BY ITERATIVE METHOD.
7fd59977 540// ----------------------------------------------
0d969553
Y
541// Calculate the current point, the distance from the current point to
542// both curves, the parameters on each curve of the projection
543// of the current point.
7fd59977 544//
0d969553
Y
545//method : - Find start parameter by using <myPolygon>.
546// - Calculate parameter U2 on curve C2 solution of H(U,V)= 0
7fd59977 547// - P(U) = F(U,U2)
548//
0d969553 549// or :
7fd59977 550// ||P2(v0)P1(u)||**2
551// F(u,v) = P1(u) - 1/2 *----------------* N(u)
552// (N(u).P2(v0)P1(u))
553//
554// H(u,v) = (Tu.P1(u)P2(v))**2||Tv||**2 - (Tv.P1(u)P2(v))**2||Tu||**2
555//
556//=============================================================================
557gp_Pnt2d Bisector_BisecCC::ValueAndDist (const Standard_Real U,
558 Standard_Real& U1,
559 Standard_Real& U2,
560 Standard_Real& Dist) const
561{
562 gp_Vec2d T;
563
564 //-----------------------------------------------
0d969553 565 // is the polygon reduced to a point or empty?
7fd59977 566 //-----------------------------------------------
567 if (myPolygon.Length() <= 1) {
568 return Extension(U,U1,U2,Dist,T);
569 }
570
571 //-----------------------------------------------
0d969553 572 // test U out of the limits of the polygon.
7fd59977 573 //-----------------------------------------------
574 if (U < myPolygon.First().ParamOnBis()) {
575 return Extension(U,U1,U2,Dist,T);
576 }
577 if (U > myPolygon.Last().ParamOnBis()) {
578 return Extension(U,U1,U2,Dist,T);
579 }
580
581 //-------------------------------------------------------
0d969553 582 // Find start parameter by using <myPolygon>.
7fd59977 583 //-------------------------------------------------------
584 Standard_Integer IntervalIndex = myPolygon.Interval(U);
585 Standard_Real UMin = myPolygon.Value(IntervalIndex ).ParamOnBis();
586 Standard_Real UMax = myPolygon.Value(IntervalIndex + 1).ParamOnBis();
587 Standard_Real VMin = myPolygon.Value(IntervalIndex ).ParamOnC2();
588 Standard_Real VMax = myPolygon.Value(IntervalIndex + 1).ParamOnC2();
589 Standard_Real Alpha,VInit;
590
591 if (Abs(UMax - UMin) < gp::Resolution()) {
592 VInit = VMin;
593 }
594 else {
595 Alpha = (U - UMin)/(UMax - UMin);
596 VInit = VMin + Alpha*(VMax - VMin);
597 }
598
599 U1 = LinkBisCurve(U);
600 Standard_Real VTemp = Min(VMin,VMax);
601 VMax = Max(VMin,VMax); VMin = VTemp;
602 Standard_Boolean Valid = Standard_True;
603 //---------------------------------------------------------------
0d969553 604 // Calculate parameter U2 on curve C2 solution of H(u,v)=0
7fd59977 605 //---------------------------------------------------------------
606 gp_Pnt2d P1;
607 gp_Vec2d T1;
608 Standard_Real EpsH = 1.E-8;
609 Standard_Real EpsH100 = 1.E-6;
610 curve1->D1 (U1,P1,T1);
611 gp_Vec2d N1(T1.Y(), - T1.X());
612
613 if ((VMax - VMin) < Precision::PConfusion()) {
614 U2 = VInit;
615 }
616 else {
617 Bisector_FunctionH H (curve2,P1,sign1*sign2*T1);
618 Standard_Real FInit;
619 H.Value(VInit,FInit);
620 if (Abs(FInit) < EpsH) {
621 U2 = VInit;
622 }
623 else {
624 math_BissecNewton SolNew (H,VMin - EpsH100,VMax + EpsH100,EpsH,10);
625 if (SolNew.IsDone()) {
626 U2 = SolNew.Root();
627 }
628 else {
629 math_FunctionRoot SolRoot (H,VInit,EpsH,VMin - EpsH100,VMax + EpsH100);
630 if (SolRoot.IsDone()) {
631 U2 = SolRoot.Root();
632 }
633 else { Valid = Standard_False;}
634 }
635 }
636 }
637
638 gp_Pnt2d PBis = pointStart;
639 //----------------
640 // P(U) = F(U1,U2)
641 //----------------
642 if (Valid) {
643 gp_Pnt2d P2 = curve2->Value(U2);
644 gp_Vec2d P2P1(P1.X() - P2.X(),P1.Y() - P2.Y());
645 Standard_Real SquareP2P1 = P2P1.SquareMagnitude();
646 Standard_Real N1P2P1 = N1.Dot(P2P1);
647
648 if (P1.IsEqual(P2,Precision::Confusion())) {
649 PBis = P1 ;
650 Dist = 0.0;
651 }
652 else if (N1P2P1*sign1 < 0) {
653 Valid = Standard_False;
654 }
655 else {
656 PBis = P1.Translated(- (0.5*SquareP2P1/N1P2P1)*N1);
657 Dist = P1.SquareDistance(PBis);
658 }
659 }
660
661 //----------------------------------------------------------------
0d969553
Y
662 // If the point is not valid
663 // calculate by intersection.
7fd59977 664 //----------------------------------------------------------------
665 if (!Valid) {
666 //--------------------------------------------------------------------
0d969553
Y
667 // Construction of the bisectrice point curve and of the straight line passing
668 // by P1 and carried by the normal. curve2 is limited by VMin and VMax.
7fd59977 669 //--------------------------------------------------------------------
670 Standard_Real DMin = Precision::Infinite();
671 gp_Pnt2d P;
672 Handle(Bisector_BisecPC) BisPC
673 = new Bisector_BisecPC(curve2, P1, sign2, VMin, VMax);
674 Handle(Geom2d_Line) NorLi = new Geom2d_Line (P1,N1);
675
676 Geom2dAdaptor_Curve ABisPC(BisPC);
677 Geom2dAdaptor_Curve ANorLi(NorLi);
678 //-------------------------------------------------------------------------
679 Geom2dInt_GInter Intersect(ABisPC,ANorLi,
680 Precision::Confusion(),Precision::Confusion());
681 //-------------------------------------------------------------------------
682
683 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
684 for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) {
685 if (Intersect.Point(i).ParamOnSecond()*sign1 < Precision::PConfusion()) {
686 P = Intersect.Point(i).Value();
687 if (P.SquareDistance(P1) < DMin) {
688 DMin = P.SquareDistance(P1);
689 PBis = P;
690 U2 = BisPC->LinkBisCurve(Intersect.Point(i).ParamOnFirst());
691 Dist = DMin;
692 }
693 }
694 }
695 }
696 }
697 return PBis;
698}
699
700//=============================================================================
701//function : ValueByInt
0d969553
Y
702//purpose : CALCULATE THE CURRENT POINT BY INTERSECTION.
703// -------------------------------------------
704// Calculate the current point, the distance from the current point
705// to two curves, the parameters on each curve of the projection of the
706// current point.
707// the current point with parameter U is the intersection of the
708// bissectrice point curve (P1,curve2) and of the straight line
709// passing through P1 of director vector N1.
710// P1 is the current point of parameter U on curve1 and N1 the
711// normal at this point.
7fd59977 712//=============================================================================
713gp_Pnt2d Bisector_BisecCC::ValueByInt (const Standard_Real U,
714 Standard_Real& U1,
715 Standard_Real& U2,
716 Standard_Real& Dist) const
717{
718 //------------------------------------------------------------------
0d969553 719 // Return point, tangent, normal on C1 at parameter U.
7fd59977 720 //-------------------------------------------------------------------
721 U1 = LinkBisCurve(U);
722
723 gp_Pnt2d P1,P2,P,PSol;
724 gp_Vec2d Tan1,Tan2;
725 curve1->D1(U1,P1,Tan1);
726 gp_Vec2d N1( Tan1.Y(), - Tan1.X());
727
728 //--------------------------------------------------------------------------
0d969553 729 // test confusion of P1 with extremity of curve2.
7fd59977 730 //--------------------------------------------------------------------------
731 if (P1.Distance(curve2->Value(curve2->FirstParameter())) < Precision::Confusion()) {
732 U2 = curve2->FirstParameter();
733 curve2->D1(U2,P2,Tan2);
734 if ( isConvex1 && isConvex2 ) {
735 Dist = 0.;
736 return P1;
737 }
738 if (! Tan1.IsParallel(Tan2,Precision::Angular())) {
739 Dist = 0.;
740 return P1;
741 }
742 }
743 if (P1.Distance(curve2->Value(curve2->LastParameter())) < Precision::Confusion()) {
744 U2 = curve2->LastParameter();
745 curve2->D1(U2,P2,Tan2);
746 if ( isConvex1 && isConvex2 ) {
747 Dist = 0.;
748 return P1;
749 }
750 if (! Tan1.IsParallel(Tan2,Precision::Angular())) {
751 Dist = 0.;
752 return P1;
753 }
754 }
755
756 Standard_Boolean YaSol = Standard_False;
757 Standard_Real DMin = Precision::Infinite();
758 Standard_Real USol;
759 Standard_Real EpsMax = 1.E-6;
760 Standard_Real EpsX;
761 Standard_Real EpsH = 1.E-8;
762 Standard_Real DistPP1;
763 Standard_Integer NbSamples =20;
764 Standard_Real UFirstOnC2 = curve2->FirstParameter();
765 Standard_Real ULastOnC2 = curve2->LastParameter();
766
767 if (!myPolygon.IsEmpty()){
768 if (sign1 == sign2) { ULastOnC2 = myPolygon.Last().ParamOnC2();}
769 else { UFirstOnC2 = myPolygon.Last().ParamOnC2();}
770 }
771
772 if (Abs(ULastOnC2 - UFirstOnC2) < Precision::PConfusion()/100.) {
773 Dist = Precision::Infinite();
774 return P1;
775 }
776
777 DiscretPar(Abs(ULastOnC2 - UFirstOnC2),EpsH,EpsMax,2,20,EpsX,NbSamples);
778
779 Bisector_FunctionH H (curve2,P1,sign1*sign2*Tan1);
780 math_FunctionRoots SolRoot (H,
781 UFirstOnC2,
782 ULastOnC2 ,
783 NbSamples,
784 EpsX,EpsH,EpsH);
785 if (SolRoot.IsDone()) {
786 for (Standard_Integer j = 1; j <= SolRoot.NbSolutions(); j++) {
787 USol = SolRoot.Value(j);
788 gp_Pnt2d P2 = curve2->Value(USol);
789 gp_Vec2d P2P1(P1.X() - P2.X(),P1.Y() - P2.Y());
790 Standard_Real SquareP2P1 = P2P1.SquareMagnitude();
791 Standard_Real N1P2P1 = N1.Dot(P2P1);
792
0d969553 793 // Test if the solution is at the proper side of the curves.
7fd59977 794 if (N1P2P1*sign1 > 0 ) {
795 P = P1.Translated(- (0.5*SquareP2P1/N1P2P1)*N1);
796 DistPP1 = P1.SquareDistance(P);
797 if (DistPP1 < DMin) {
798 DMin = DistPP1;
799 PSol = P;
800 U2 = USol;
801 YaSol = Standard_True;
802 }
803 }
804 }
805 }
806
807/*
808 if (!YaSol) {
809 //--------------------------------------------------------------------
810 // Construction de la bisectrice point courbe et de la droite passant
811 // par P1 et portee par la normale.
812 //--------------------------------------------------------------------
813 Handle(Bisector_BisecPC) BisPC
814 = new Bisector_BisecPC(curve2,P1,sign2,2*distMax);
815 //-------------------------------
816 // Test si la bissectrice existe.
817 //-------------------------------
818 if (BisPC->IsEmpty()) {
819 Dist = Precision::Infinite();
820 PSol = P1;
821 return PSol;
822 }
823
824 Handle(Geom2d_Line) NorLi = new Geom2d_Line (P1,N1);
825 Geom2dAdaptor_Curve NorLiAd;
826 if (sign1 < 0.) {NorLiAd.Load(NorLi,0. ,distMax);}
827 else {NorLiAd.Load(NorLi,- distMax,0. );}
828
829 //-------------------------------------------------------------------------
830 Geom2dInt_GInter Intersect(BisPC,NorLiAd,
831 Precision::Confusion(),Precision::Confusion());
832 //-------------------------------------------------------------------------
833 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
834 for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) {
835 if (Intersect.Point(i).ParamOnSecond()*sign1< Precision::PConfusion()) {
836 P = Intersect.Point(i).Value();
837 DistPP1 = P.SquareDistance(P1);
838 if (DistPP1 < DMin) {
839 DMin = DistPP1;
840 PSol = P;
841 U2 = Intersect.Point(i).ParamOnFirst();
842 YaSol = Standard_True;
843 }
844 }
845 }
846 }
847 }
848*/
849
850 if (YaSol) {
851 Dist = DMin;
852 //--------------------------------------------------------------
0d969553 853 // Point found => Test curve distance + Angular Test
7fd59977 854 //---------------------------------------------------------------
855 P2 = curve2->Value(U2);
856 gp_Vec2d PP1(P1.X() - PSol.X(),P1.Y() - PSol.Y());
857 gp_Vec2d PP2(P2.X() - PSol.X(),P2.Y() - PSol.Y());
858
859 //-----------------------------------------------
0d969553 860 // Dist = product of norms = distance at the square.
7fd59977 861 //-----------------------------------------------
862 if (PP1.Dot(PP2) > (1. - Precision::Angular())*Dist) {
863 YaSol = Standard_False;
864 }
865 else {
866 if ( !isConvex1 ) {
867 Standard_Real K1 = Curvature(curve1,U1,Precision::Confusion());
868 if (K1 != 0.) {
869 if (Dist > 1/(K1*K1)) YaSol = Standard_False;
870 }
871 }
872 if (YaSol) {
873 if ( !isConvex2 ) {
874 Standard_Real K2 = Curvature(curve2,U2,Precision::Confusion());
875 if (K2 != 0.) {
876 if (Dist > 1/(K2*K2)) YaSol = Standard_False;
877 }
878 }
879 }
880 }
881 }
882 if (!YaSol) {
883 Dist = Precision::Infinite();
884 PSol = P1;
885 }
886 return PSol;
887}
888
889//=============================================================================
890//function : D0
891//purpose :
892//=============================================================================
893void Bisector_BisecCC::D0(const Standard_Real U,
894 gp_Pnt2d& P) const
895{
896 Standard_Real U1,U2,Dist;
897
898 P = ValueAndDist(U,U1,U2,Dist);
899}
900
901//=============================================================================
902//function : D1
903//purpose :
904//=============================================================================
905void Bisector_BisecCC::D1(const Standard_Real U,
906 gp_Pnt2d& P,
907 gp_Vec2d& V ) const
908{
909 V.SetCoord(0.,0.);
910 gp_Vec2d V2,V3;
911 Values(U,1,P,V,V2,V3);
912}
913
914//=============================================================================
915//function : D2
916//purpose :
917//=============================================================================
918void Bisector_BisecCC::D2(const Standard_Real U,
919 gp_Pnt2d& P,
920 gp_Vec2d& V1,
921 gp_Vec2d& V2) const
922{
923 V1.SetCoord(0.,0.);
924 V2.SetCoord(0.,0.);
925 gp_Vec2d V3;
926 Values(U,2,P,V1,V2,V3);
927}
928
929//=============================================================================
930//function : D3
931//purpose :
932//=============================================================================
933void Bisector_BisecCC::D3(const Standard_Real U,
934 gp_Pnt2d& P,
935 gp_Vec2d& V1,
936 gp_Vec2d& V2,
937 gp_Vec2d& V3) const
938{
939 V1.SetCoord(0.,0.);
940 V2.SetCoord(0.,0.);
941 V3.SetCoord(0.,0.);
942 Values(U,3,P,V1,V2,V3);
943}
944
945//=============================================================================
946//function : DN
947//purpose :
948//=============================================================================
949gp_Vec2d Bisector_BisecCC::DN(const Standard_Real U,
950 const Standard_Integer N) const
951{
952 gp_Pnt2d P;
953 gp_Vec2d V1(0.,0.);
954 gp_Vec2d V2(0.,0.);
955 gp_Vec2d V3(0.,0.);
956 Values (U,N,P,V1,V2,V3);
957 switch (N) {
958 case 1 : return V1;
959 case 2 : return V2;
960 case 3 : return V3;
961 default: {
962 Standard_NotImplemented::Raise();
963 }
964 }
965 return V1;
966}
967
968//=============================================================================
969//function : Values
0d969553 970// purpose : the curve can be described by the following equations:
7fd59977 971//
972// B(u) = F(u,v0)
0d969553 973// where v0 = Phi(u) is given by H (u,v) = 0.
7fd59977 974//
0d969553 975// with :
7fd59977 976// ||P2(v0)P1(u)||**2
977// F(u,v) = P1(u) - 1/2 *----------------* N(u)
978// (N(u).P2(v0)P1(u))
979//
980// H(u,v) = (Tu.P1(u)P2(v))**2||Tv||**2 - (Tv.P1(u)P2(v))**2||Tu||**2
981//
982// => dB(u)/du = dF/du + dF/dv(- dH/du:dH/dv)
983//
0d969553
Y
984// Note : tangent to the bisectrice is bissectrice at
985// tangents T1(u) and T2(v0)
7fd59977 986//
987//=============================================================================
988void Bisector_BisecCC::Values (const Standard_Real U,
989 const Standard_Integer N,
990 gp_Pnt2d& P,
991 gp_Vec2d& V1,
992 gp_Vec2d& V2,
993 gp_Vec2d& V3) const
994{
995 V1 = gp_Vec2d(0.,0.);
996 V2 = gp_Vec2d(0.,0.);
997 V3 = gp_Vec2d(0.,0.);
998 //-------------------------------------------------------------------------
0d969553
Y
999 // Calculate the current point on the bisectrice and the parameters on each
1000 // curve.
7fd59977 1001 //-------------------------------------------------------------------------
1002 Standard_Real U0,V0,Dist;
1003
1004 //-----------------------------------------------
0d969553 1005 // is the polygon reduced to a point or empty?
7fd59977 1006 //-----------------------------------------------
1007 if (myPolygon.Length() <= 1) {
1008 P = Extension(U,U0,V0,Dist,V1);
1009 }
1010 if (U < myPolygon.First().ParamOnBis()) {
1011 P = Extension(U,U0,V0,Dist,V1);
1012 return;
1013 }
1014 if (U > myPolygon.Last().ParamOnBis()) {
1015 P = Extension(U,U0,V0,Dist,V1);
1016 return;
1017 }
1018 P = ValueAndDist(U,U0,V0,Dist);
1019
1020 if (N == 0) return;
1021 //------------------------------------------------------------------
0d969553 1022 // Return point, tangent, normal to C1 by parameter U0.
7fd59977 1023 //-------------------------------------------------------------------
0d969553
Y
1024 gp_Pnt2d P1 ; // point on C1.
1025 gp_Vec2d Tu ; // tangent to C1 by U0.
1026 gp_Vec2d Tuu ; // second derivative to C1 by U0.
7fd59977 1027 curve1->D2(U0,P1,Tu,Tuu);
0d969553
Y
1028 gp_Vec2d Nor( - Tu .Y() , Tu .X()); // Normal by U0.
1029 gp_Vec2d Nu ( - Tuu.Y() , Tuu.X()); // derivative of the normal by U0.
7fd59977 1030
1031 //-------------------------------------------------------------------
0d969553 1032 // Return point, tangent, normale to C2 by parameter V0.
7fd59977 1033 //-------------------------------------------------------------------
0d969553
Y
1034 gp_Pnt2d P2 ; // point on C2.
1035 gp_Vec2d Tv ; // tangent to C2 by V.
1036 gp_Vec2d Tvv ; // second derivative to C2 by V.
7fd59977 1037 curve2->D2(V0,P2,Tv,Tvv);
1038
1039 gp_Vec2d PuPv(P2.X() - P1.X(), P2.Y() - P1.Y());
1040
1041 //-----------------------------
0d969553 1042 // Calculate dH/du and dH/dv.
7fd59977 1043 //-----------------------------
1044 Standard_Real TuTu,TvTv,TuTv;
1045 Standard_Real TuPuPv,TvPuPv ;
1046 Standard_Real TuuPuPv,TuTuu ;
1047 Standard_Real TvvPuPv,TvTvv ;
1048
1049 TuTu = Tu.Dot(Tu) ; TvTv = Tv.Dot(Tv) ; TuTv = Tu.Dot(Tv);
1050 TuPuPv = Tu.Dot(PuPv) ; TvPuPv = Tv.Dot(PuPv);
1051 TuuPuPv = Tuu.Dot(PuPv) ; TuTuu = Tu.Dot(Tuu) ;
1052 TvvPuPv = Tvv.Dot(PuPv) ; TvTvv = Tv.Dot(Tvv) ;
1053
1054 Standard_Real dHdu = 2*(TuPuPv*(TuuPuPv - TuTu)*TvTv +
1055 TvPuPv*TuTv*TuTu -TuTuu*TvPuPv*TvPuPv);
1056 Standard_Real dHdv = 2*(TuPuPv*TuTv*TvTv + TvTvv*TuPuPv*TuPuPv -
1057 TvPuPv*(TvvPuPv + TvTv)*TuTu);
1058
1059 //-----------------------------
0d969553 1060 // Calculate dF/du and dF/dv.
7fd59977 1061 //-----------------------------
1062 Standard_Real NorPuPv,NuPuPv,NorTv;
1063 Standard_Real A,B,dAdu,dAdv,dBdu,dBdv,BB;
1064
1065 NorPuPv = Nor.Dot(PuPv);
1066 NuPuPv = Nu .Dot(PuPv);
1067 NorTv = Nor.Dot(Tv) ;
1068
1069 A = 0.5*PuPv.SquareMagnitude();
1070 B = - NorPuPv;
1071 BB = B*B;
1072 dAdu = - TuPuPv;
1073 dBdu = - NuPuPv ;
1074 dAdv = TvPuPv;
1075 dBdv = - NorTv;
1076
1077 //---------------------------------------
1078 // F(u,v) = Pu - (A(u,v)/B(u,v))*Nor(u)
1079 //----------------------------------------
1080 if (BB < gp::Resolution()) {
1081 V1 = Tu.Normalized() + Tv.Normalized();
1082 V1 = 0.5*Tu.SquareMagnitude()*V1;
1083 }
1084 else {
1085 gp_Vec2d dFdu = Tu - (dAdu/B - dBdu*A/BB)*Nor - (A/B)*Nu;
1086 gp_Vec2d dFdv = ( - dAdv/B + dBdv*A/BB)*Nor ;
1087
1088 if (Abs(dHdv) > gp::Resolution()) {
1089 V1 = dFdu + dFdv*( - dHdu / dHdv );
1090 }
1091 else {
1092 V1 = Tu;
1093 }
1094 }
1095 if (N == 1) return;
1096}
1097
1098//=============================================================================
1099//function : Extension
0d969553
Y
1100// purpose : Calculate the current point on the extensions
1101// by tangence of the curve.
7fd59977 1102//============================================================================
1103gp_Pnt2d Bisector_BisecCC::Extension (const Standard_Real U,
1104 Standard_Real& U1,
1105 Standard_Real& U2,
1106 Standard_Real& Dist,
1107 gp_Vec2d& T ) const
1108{
1109 Bisector_PointOnBis PRef;
1110 gp_Pnt2d P,P1,P2,PBis;
1111 gp_Vec2d T1,Tang;
1112#ifndef DEB
1113 Standard_Real dU = 0.;
1114#else
1115 Standard_Real dU;
1116#endif
1117 Standard_Boolean ExtensionTangent = Standard_False;
1118
1119 if (myPolygon.Length() == 0) {
1120 //---------------------------------------------
0d969553 1121 // Empty Polygon => segment (pointStart,pointEnd)
7fd59977 1122 //---------------------------------------------
1123 dU = U - startIntervals.First();
1124 P = pointStart;
1125 P1 = pointEnd;
1126 U1 = curve1->LastParameter();
1127 if (sign1 == sign2) { U2 = curve2->FirstParameter();}
1128 else { U2 = curve2->LastParameter() ;}
1129 Tang.SetCoord(P1.X() - P.X(),P1.Y() - P.Y());
1130 }
1131 else if (U < myPolygon.First().ParamOnBis()) {
1132 PRef = myPolygon.First();
1133 P = PRef.Point();
1134 dU = U - PRef.ParamOnBis();
1135 if (extensionStart) {
1136 //------------------------------------------------------------
0d969553 1137 // extension = segment (pointstart, first point of the polygon.)
7fd59977 1138 //------------------------------------------------------------
1139 P1 = pointStart;
1140 U1 = curve1->FirstParameter();
1141 if (sign1 == sign2) { U2 = curve2->LastParameter();}
1142 else { U2 = curve2->FirstParameter();}
1143 Tang.SetCoord(P.X() - P1.X(),P.Y() - P1.Y());
1144 }
1145 else {
1146 ExtensionTangent = Standard_True;
1147 }
1148 }
1149 else if (U > myPolygon.Last().ParamOnBis()) {
1150 PRef = myPolygon.Last();
1151 P = PRef.Point();
1152 dU = U - PRef.ParamOnBis();
1153 if (extensionEnd) {
1154 //------------------------------------------------------------
0d969553 1155 // extension = segment (last point of the polygon.pointEnd)
7fd59977 1156 //------------------------------------------------------------
1157 P1 = pointEnd;
1158 U1 = curve1->LastParameter();
1159 if (sign1 == sign2) { U2 = curve2->LastParameter();}
1160 else { U2 = curve2->FirstParameter();}
1161 Tang.SetCoord(P1.X() - P.X(),P1.Y() - P.Y());
1162 }
1163 else {
1164 ExtensionTangent = Standard_True;
1165 }
1166 }
1167
1168 if (ExtensionTangent) {
1169 //-----------------------------------------------------------
0d969553 1170 // If the la curve has no a extension, it is extended by tangency
7fd59977 1171 //------------------------------------------------------------
1172 U1 = PRef.ParamOnC1();
1173 U2 = PRef.ParamOnC2();
1174 P2 = curve2->Value(U2);
1175 curve1->D1(U1,P1,T1);
1176 Tang.SetCoord(2*P.X() - P1.X() - P2.X(), 2*P.Y() - P1.Y() - P2.Y());
1177 if (Tang.Magnitude() < Precision::Confusion()) {
1178 Tang = T1;
1179 }
1180 if (T1.Dot(Tang) < 0.) Tang = - Tang;
1181 }
1182
1183 T = Tang.Normalized();
1184 PBis.SetCoord(P.X() + dU*T.X(),P.Y() + dU*T.Y());
1185 Dist = P1.Distance(PBis);
1186 return PBis;
1187}
1188
1189//=============================================================================
1190//function : PointByInt
1191// purpose :
1192//=============================================================================
1193static Standard_Boolean PointByInt(const Handle(Geom2d_Curve)& CA,
1194 const Handle(Geom2d_Curve)& CB,
1195 const Standard_Real SignA,
1196 const Standard_Real SignB,
1197 const Standard_Real UOnA,
1198 Standard_Real& UOnB,
1199 Standard_Real& Dist)
1200{
1201 //------------------------------------------------------------------
0d969553 1202 // Return point,tangent, normal on CA with parameter UOnA.
7fd59977 1203 //-------------------------------------------------------------------
1204 gp_Pnt2d P1,P2,P,PSol;
1205 gp_Vec2d Tan1,Tan2;
1206 Standard_Boolean IsConvexA = Bisector::IsConvex(CA,SignA);
1207 Standard_Boolean IsConvexB = Bisector::IsConvex(CB,SignB);
1208
1209 CA->D1(UOnA,P1,Tan1);
1210 gp_Vec2d N1(Tan1.Y(), - Tan1.X());
1211
1212 //--------------------------------------------------------------------------
0d969553 1213 // test of confusion of P1 with extremity of curve2.
7fd59977 1214 //--------------------------------------------------------------------------
1215 if (P1.Distance(CB->Value(CB->FirstParameter())) < Precision::Confusion()) {
1216 UOnB = CB->FirstParameter();
1217 CB->D1(UOnB,P2,Tan2);
1218 if ( IsConvexA && IsConvexB ) {
1219 Dist = 0.;
1220 return Standard_True;
1221 }
1222 if (! Tan1.IsParallel(Tan2,Precision::Angular())) {
1223 Dist = 0.;
1224 return Standard_False;
1225 }
1226 }
1227 if (P1.Distance(CB->Value(CB->LastParameter())) < Precision::Confusion()) {
1228 UOnB = CB->LastParameter();
1229 CB->D1(UOnB,P2,Tan2);
1230 if ( IsConvexA && IsConvexB ) {
1231 Dist = 0.;
1232 return Standard_True;
1233 }
1234 if (! Tan1.IsParallel(Tan2,Precision::Angular())) {
1235 Dist = 0.;
1236 return Standard_False;
1237 }
1238 }
1239
1240 Standard_Real DMin = Precision::Infinite();
1241 Standard_Real UPC;
1242 Standard_Boolean YaSol = Standard_False;
1243 //--------------------------------------------------------------------
0d969553
Y
1244 // Construction of the bisectrice point curve and of the straight line passing
1245 // through P1 and carried by the normal.
7fd59977 1246 //--------------------------------------------------------------------
1247 Handle(Bisector_BisecPC) BisPC
1248 = new Bisector_BisecPC(CB,P1,SignB );
1249 //-------------------------------
0d969553 1250 // Test if the bissectrice exists.
7fd59977 1251 //-------------------------------
1252 if (BisPC->IsEmpty()) {
1253 Dist = Precision::Infinite();
1254 PSol = P1;
1255 return Standard_False;
1256 }
1257
1258 Handle(Geom2d_Line) NorLi = new Geom2d_Line (P1,N1);
1259
1260 Geom2dAdaptor_Curve ABisPC(BisPC);
1261 Geom2dAdaptor_Curve ANorLi(NorLi);
1262 //-------------------------------------------------------------------------
1263 Geom2dInt_GInter Intersect(ABisPC,ANorLi,
1264 Precision::Confusion(),Precision::Confusion());
1265 //-------------------------------------------------------------------------
1266
1267 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1268 for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) {
1269 if (Intersect.Point(i).ParamOnSecond()*SignA < Precision::PConfusion()) {
1270 P = Intersect.Point(i).Value();
1271 if (P.SquareDistance(P1) < DMin) {
1272 DMin = P.SquareDistance(P1);
1273 PSol = P;
1274 UPC = Intersect.Point(i).ParamOnFirst();
1275 UOnB = BisPC->LinkBisCurve(UPC);
1276 Dist = DMin;
1277 YaSol = Standard_True;
1278 }
1279 }
1280 }
1281 }
1282 if (YaSol) {
1283 //--------------------------------------------------------------
0d969553 1284 // Point found => Test distance curvature + Angular test
7fd59977 1285 //---------------------------------------------------------------
1286 P2 = CB->Value(UOnB);
1287 gp_Dir2d PP1Unit(P1.X() - PSol.X(),P1.Y() - PSol.Y());
1288 gp_Dir2d PP2Unit(P2.X() - PSol.X(),P2.Y() - PSol.Y());
1289
1290 if (PP1Unit*PP2Unit > 1. - Precision::Angular()) {
1291 YaSol = Standard_False;
1292 }
1293 else {
1294 Dist = sqrt(Dist);
1295 if ( !IsConvexA ) {
1296 Standard_Real K1 = Curvature(CA,UOnA,Precision::Confusion());
1297 if (K1 != 0.) {
1298 if (Dist > Abs(1/K1)) YaSol = Standard_False;
1299 }
1300 }
1301 if (YaSol) {
1302 if ( !IsConvexB ) {
1303 Standard_Real K2 = Curvature(CB,UOnB,Precision::Confusion());
1304 if (K2 != 0.) {
1305 if (Dist > Abs(1/K2)) YaSol = Standard_False;
1306 }
1307 }
1308 }
1309 }
1310 }
1311 return YaSol;
1312}
1313
1314//=============================================================================
1315//function : SupLastParameter
1316// purpose :
1317//=============================================================================
1318void Bisector_BisecCC::SupLastParameter()
1319{
1320 endIntervals.Append(curve1->LastParameter());
1321 // ----------------------------------------------------------------------
0d969553
Y
1322 // Calculate parameter on curve1 associated to one or the other of the extremities
1323 // of curve2 following the values of sign1 and sign2.
1324 // the bissectrice is limited by the obtained parameters.
7fd59977 1325 //------------------------------------------------------------------------
1326 Standard_Real UOnC1,UOnC2,Dist;
1327 if (sign1 == sign2) {
1328 UOnC2 = curve2->FirstParameter();
1329 }
1330 else {
1331 UOnC2 = curve2->LastParameter();
1332 }
1333 Standard_Boolean YaSol = PointByInt(curve2,curve1,sign2,sign1,UOnC2,UOnC1,Dist);
1334 if (YaSol) {
1335 if (UOnC1 > startIntervals.First() && UOnC1 < endIntervals.Last()) {
1336 endIntervals.SetValue(1,UOnC1);
1337 }
1338 }
1339}
1340
1341//=============================================================================
1342//function : Curve
1343// purpose :
1344//=============================================================================
1345Handle(Geom2d_Curve) Bisector_BisecCC::Curve(const Standard_Integer I) const
1346{
1347 if (I == 1) return curve1;
1348 else if (I == 2) return curve2;
1349 else Standard_OutOfRange::Raise();
1350 return curve1;
1351}
1352
1353//=============================================================================
1354//function : LinkBisCurve
1355//purpose :
1356//=============================================================================
1357Standard_Real Bisector_BisecCC::LinkBisCurve(const Standard_Real U) const
1358{
1359 return (U - shiftParameter);
1360}
1361
1362//=============================================================================
1363//function : LinkCurveBis
1364//purpose :
1365//=============================================================================
1366Standard_Real Bisector_BisecCC::LinkCurveBis(const Standard_Real U) const
1367{
1368 return (U + shiftParameter);
1369}
1370
1371//=============================================================================
1372//function : Indent
1373//purpose :
1374//=============================================================================
1375static void Indent(const Standard_Integer Offset) {
1376 if (Offset > 0) {
1377 for (Standard_Integer i = 0; i < Offset; i++) {cout << " ";}
1378 }
1379}
1380
1381//=============================================================================
1382//function : Polygon
1383// purpose :
1384//=============================================================================
1385const Bisector_PolyBis& Bisector_BisecCC::Polygon() const
1386{
1387 return myPolygon;
1388}
1389
1390//==========================================================================
1391//function : Parameter
1392//purpose :
1393//==========================================================================
1394Standard_Real Bisector_BisecCC::Parameter(const gp_Pnt2d& P) const
1395{
1396 Standard_Real UOnCurve;
1397
1398 if (P.IsEqual(Value(FirstParameter()),Precision::Confusion())) {
1399 UOnCurve = FirstParameter();
1400 }
1401 else if (P.IsEqual(Value(LastParameter()),Precision::Confusion())) {
1402 UOnCurve = LastParameter();
1403 }
1404 else {
1405 UOnCurve = ProjOnCurve(P,curve1);
1406 }
1407 return UOnCurve;
1408}
1409
1410
1411//=============================================================================
1412//function : Dump
1413// purpose :
1414//=============================================================================
1415//void Bisector_BisecCC::Dump(const Standard_Integer Deep,
1416void Bisector_BisecCC::Dump(const Standard_Integer ,
1417 const Standard_Integer Offset) const
1418{
1419 Indent (Offset);
1420 cout <<"Bisector_BisecCC :"<<endl;
1421 Indent (Offset);
1422// cout <<"Curve1 :"<<curve1<<endl;
1423// cout <<"Curve2 :"<<curve2<<endl;
1424 cout <<"Sign1 :"<<sign1<<endl;
1425 cout <<"Sign2 :"<<sign2<<endl;
1426
1427 cout <<"Number Of Intervals :"<<startIntervals.Length()<<endl;
1428 for (Standard_Integer i = 1; i <= startIntervals.Length(); i++) {
1429 cout <<"Interval number :"<<i<<"Start :"<<startIntervals.Value(i)
1430 <<" end :"<< endIntervals.Value(i)<<endl ;
1431 }
1432 cout <<"Index Current Interval :"<<currentInterval<<endl;
1433}
1434
1435//=============================================================================
1436//function : Curve
1437// purpose :
1438//=============================================================================
1439void Bisector_BisecCC::Curve(const Standard_Integer I,
1440 const Handle(Geom2d_Curve)& C)
1441{
1442 if (I == 1) curve1 = C;
1443 else if (I == 2) curve2 = C;
1444 else Standard_OutOfRange::Raise();
1445}
1446
1447//=============================================================================
1448//function : Sign
1449// purpose :
1450//=============================================================================
1451void Bisector_BisecCC::Sign(const Standard_Integer I,
1452 const Standard_Real S)
1453{
1454 if (I == 1) sign1 = S;
1455 else if (I == 2) sign2 = S;
1456 else Standard_OutOfRange::Raise();
1457}
1458
1459//=============================================================================
1460//function : Polygon
1461// purpose :
1462//=============================================================================
1463void Bisector_BisecCC::Polygon(const Bisector_PolyBis& P)
1464{
1465 myPolygon = P;
1466}
1467
1468//=============================================================================
1469//function : DistMax
1470// purpose :
1471//=============================================================================
1472void Bisector_BisecCC::DistMax(const Standard_Real D)
1473{
1474 distMax = D;
1475}
1476
1477//=============================================================================
1478//function : IsConvex
1479// purpose :
1480//=============================================================================
1481void Bisector_BisecCC::IsConvex(const Standard_Integer I,
1482 const Standard_Boolean IsConvex)
1483{
1484 if (I == 1) isConvex1 = IsConvex;
1485 else if (I == 2) isConvex2 = IsConvex;
1486 else Standard_OutOfRange::Raise();
1487}
1488
1489//=============================================================================
1490//function : IsEmpty
1491// purpose :
1492//=============================================================================
1493void Bisector_BisecCC::IsEmpty ( const Standard_Boolean IsEmpty)
1494{
1495 isEmpty = IsEmpty;
1496}
1497
1498//=============================================================================
1499//function : ExtensionStart
1500// purpose :
1501//=============================================================================
1502void Bisector_BisecCC::ExtensionStart( const Standard_Boolean ExtensionStart)
1503{
1504 extensionStart = ExtensionStart;
1505}
1506
1507//=============================================================================
1508//function : ExtensionEnd
1509// purpose :
1510//=============================================================================
1511void Bisector_BisecCC::ExtensionEnd( const Standard_Boolean ExtensionEnd)
1512{
1513 extensionEnd = ExtensionEnd;
1514}
1515
1516//=============================================================================
1517//function : PointStart
1518// purpose :
1519//=============================================================================
1520void Bisector_BisecCC::PointStart( const gp_Pnt2d& Point)
1521{
1522 pointStart = Point;
1523}
1524
1525//=============================================================================
1526//function : PointEnd
1527// purpose :
1528//=============================================================================
1529void Bisector_BisecCC::PointEnd( const gp_Pnt2d& Point)
1530{
1531 pointEnd = Point;
1532}
1533
1534//=============================================================================
1535//function : StartIntervals
1536// purpose :
1537//=============================================================================
1538void Bisector_BisecCC::StartIntervals
1539 (const TColStd_SequenceOfReal& StartIntervals)
1540{
1541 startIntervals = StartIntervals;
1542}
1543
1544//=============================================================================
1545//function : EndIntervals
1546// purpose :
1547//=============================================================================
1548void Bisector_BisecCC::EndIntervals
1549 (const TColStd_SequenceOfReal& EndIntervals)
1550{
1551 endIntervals = EndIntervals;
1552}
1553
1554//=============================================================================
1555//function : FirstParameter
1556// purpose :
1557//=============================================================================
1558void Bisector_BisecCC::FirstParameter (const Standard_Real U)
1559{
1560 startIntervals.Append(U);
1561}
1562
1563//=============================================================================
1564//function : LastParameter
1565// purpose :
1566//=============================================================================
1567void Bisector_BisecCC::LastParameter (const Standard_Real U)
1568{
1569 endIntervals.Append(U);
1570}
1571
1572//=============================================================================
1573//function : SearchBound
1574// purpose :
1575//=============================================================================
1576Standard_Real Bisector_BisecCC::SearchBound (const Standard_Real U1,
1577 const Standard_Real U2) const
1578{
1579 Standard_Real UMid,Dist1,Dist2,DistMid,U11,U22;
1580 Standard_Real UC1,UC2;
1581 gp_Pnt2d PBis,PBisPrec;
1582 Standard_Real TolPnt = Precision::Confusion();
1583 Standard_Real TolPar = Precision::PConfusion();
1584 U11 = U1; U22 = U2;
1585 PBisPrec = ValueByInt(U11,UC1,UC2,Dist1);
1586 PBis = ValueByInt(U22,UC1,UC2,Dist2);
1587
1588 while ((U22 - U11) > TolPar ||
1589 ((Dist1 < Precision::Infinite() &&
1590 Dist2 < Precision::Infinite() &&
1591 !PBis.IsEqual(PBisPrec,TolPnt)))) {
1592 PBisPrec = PBis;
1593 UMid = 0.5*( U22 + U11);
1594 PBis = ValueByInt(UMid,UC1,UC2,DistMid);
1595 if ((Dist1 < Precision::Infinite()) == (DistMid < Precision::Infinite())) {
1596 U11 = UMid;
1597 Dist1 = DistMid;
1598 }
1599 else {
1600 U22 = UMid;
1601 Dist2 = DistMid;
1602 }
1603 }
1604 PBis = ValueByInt(U11,UC1,UC2,Dist1);
1605 if (Dist1 < Precision::Infinite()) {
1606 UMid = U11;
1607 }
1608 else {
1609 UMid = U22;
1610 }
1611 return UMid;
1612}
1613
1614//=============================================================================
1615//function : ProjOnCurve
1616// purpose :
1617//=============================================================================
1618static Standard_Real ProjOnCurve (const gp_Pnt2d& P,
1619 const Handle(Geom2d_Curve)& C)
1620{
1621#ifndef DEB
1622 Standard_Real UOnCurve =0.;
1623#else
1624 Standard_Real UOnCurve;
1625#endif
1626 gp_Pnt2d PF,PL;
1627 gp_Vec2d TF,TL;
1628
1629 C->D1(C->FirstParameter(),PF,TF);
1630 C->D1(C->LastParameter() ,PL,TL);
1631
1632 if (P.IsEqual(PF ,Precision::Confusion())) {
1633 return C->FirstParameter();
1634 }
1635 if (P.IsEqual(PL ,Precision::Confusion())) {
1636 return C->LastParameter();
1637 }
1638 gp_Vec2d PPF(PF.X() - P.X(), PF.Y() - P.Y());
1639 TF.Normalize();
1640 if ( Abs (PPF.Dot(TF)) < Precision::Confusion()) {
1641 return C->FirstParameter();
1642 }
1643 gp_Vec2d PPL (PL.X() - P.X(), PL.Y() - P.Y());
1644 TL.Normalize();
1645 if ( Abs (PPL.Dot(TL)) < Precision::Confusion()) {
1646 return C->LastParameter();
1647 }
1648 Geom2dAPI_ProjectPointOnCurve Proj(P,C,
1649 C->FirstParameter(),
1650 C->LastParameter());
1651 if (Proj.NbPoints() > 0) {
1652 UOnCurve = Proj.LowerDistanceParameter();
1653 }
1654 else {
1655 Standard_OutOfRange::Raise();
1656 }
1657 return UOnCurve;
1658}
1659
1660//=============================================================================
1661//function : TestExtension
1662// purpose :
1663//=============================================================================
1664static Standard_Boolean TestExtension (const Handle(Geom2d_Curve)& C1,
1665 const Handle(Geom2d_Curve)& C2,
1666 const Standard_Integer Start_End)
1667{
1668 gp_Pnt2d P1,P2;
1669 gp_Vec2d T1,T2;
1670 Standard_Boolean Test = Standard_False;
1671 if (Start_End == 1) {
1672 C1->D1(C1->FirstParameter(),P1,T1);
1673 }
1674 else {
1675 C1->D1(C1->LastParameter(),P1,T1);
1676 }
1677 C2->D1(C2->FirstParameter(),P2,T2);
1678 if (P1.IsEqual(P2,Precision::Confusion())) {
1679 T1.Normalize(); T2.Normalize();
1680 if (T1.Dot(T2) > 1.0 - Precision::Confusion()) {
1681 Test = Standard_True;
1682 }
1683 }
1684 else {
1685 C2->D1(C2->LastParameter(),P2,T2);
1686 if (P1.IsEqual(P2,Precision::Confusion())) {
1687 T2.Normalize();
1688 if (T1.Dot(T2) > 1.0 - Precision::Confusion()) {
1689 Test = Standard_True;
1690 }
1691 }
1692 }
1693 return Test;
1694}
1695
1696//=============================================================================
1697//function : ComputePointEnd
1698// purpose :
1699//=============================================================================
1700void Bisector_BisecCC::ComputePointEnd ()
1701{
1702 Standard_Real U1,U2;
1703 Standard_Real KC,RC;
1704 U1 = curve1->FirstParameter();
1705 if (sign1 == sign2) {
1706 U2 = curve2->LastParameter();
1707 }
1708 else {
1709 U2 = curve2->FirstParameter();
1710 }
1711 Standard_Real K1 = Curvature(curve1,U1,Precision::Confusion());
1712 Standard_Real K2 = Curvature(curve2,U2,Precision::Confusion());
1713 if (!isConvex1 && !isConvex2) {
1714 if (K1 < K2) {KC = K1;} else {KC = K2;}
1715 }
1716 else if (!isConvex1) {KC = K1;}
1717 else {KC = K2;}
1718
1719 gp_Pnt2d PF;
1720 gp_Vec2d TF;
1721 curve1->D1(U1,PF,TF);
1722 TF.Normalize();
1723 if (KC != 0.) { RC = Abs(1/KC);}
1724 else { RC = Precision::Infinite();}
1725 pointEnd.SetCoord(PF.X() - sign1*RC*TF.Y(), PF.Y() + sign1*RC*TF.X());
1726
1727}
1728
1729//=============================================================================
1730//function : DiscretPar
1731// purpose :
1732//=============================================================================
1733static Standard_Boolean DiscretPar(const Standard_Real DU,
1734 const Standard_Real EpsMin,
1735 const Standard_Real EpsMax,
1736 const Standard_Integer NbMin,
1737 const Standard_Integer NbMax,
1738 Standard_Real& Eps,
1739 Standard_Integer& Nb)
1740{
1741 if (DU <= NbMin*EpsMin) {
1742 Eps = DU/(NbMin + 1) ;
1743 Nb = NbMin;
1744 return Standard_False;
1745 }
1746
1747 Eps = Min (EpsMax,DU/NbMax);
1748
1749 if (Eps < EpsMin) {
1750 Eps = EpsMin;
1751 Nb = Standard_Integer(DU/EpsMin);
1752 }
1753 else { Nb = NbMax;}
1754
1755 return Standard_True;
1756}
1757
1758