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