1 // Created on: 1994-03-10
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Bisector.hxx>
19 #include <Bisector_BisecCC.hxx>
20 #include <Bisector_BisecPC.hxx>
21 #include <Bisector_FunctionH.hxx>
22 #include <Bisector_PointOnBis.hxx>
23 #include <Bisector_PolyBis.hxx>
24 #include <Geom2d_Curve.hxx>
25 #include <Geom2d_Geometry.hxx>
26 #include <Geom2d_Line.hxx>
27 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
28 #include <Geom2dGcc_Circ2d2TanRad.hxx>
29 #include <Geom2dInt_GInter.hxx>
30 #include <Geom2dLProp_CLProps2d.hxx>
32 #include <gp_Pnt2d.hxx>
33 #include <gp_Trsf2d.hxx>
34 #include <gp_Vec2d.hxx>
35 #include <IntRes2d_IntersectionPoint.hxx>
36 #include <math_BissecNewton.hxx>
37 #include <math_FunctionRoot.hxx>
38 #include <math_FunctionRoots.hxx>
39 #include <Precision.hxx>
40 #include <Standard_NotImplemented.hxx>
41 #include <Standard_OutOfRange.hxx>
42 #include <Standard_Type.hxx>
44 IMPLEMENT_STANDARD_RTTIEXT(Bisector_BisecCC,Bisector_Curve)
46 static Standard_Boolean ProjOnCurve (const gp_Pnt2d& P,
47 const Handle(Geom2d_Curve)& C,
48 Standard_Real& theParam);
50 static Standard_Real Curvature (const Handle(Geom2d_Curve)& C,
54 static Standard_Boolean TestExtension (const Handle(Geom2d_Curve)& C1,
55 const Handle(Geom2d_Curve)& C2,
56 const Standard_Integer Start_End);
58 static Standard_Boolean DiscretPar(const Standard_Real DU,
59 const Standard_Real EpsMin,
60 const Standard_Real EpsMax,
61 const Standard_Integer NbMin,
62 const Standard_Integer NbMax,
64 Standard_Integer& Nb);
66 //=============================================================================
69 //=============================================================================
70 Bisector_BisecCC::Bisector_BisecCC()
76 isEmpty(Standard_True),
77 isConvex1(Standard_False),
78 isConvex2(Standard_False),
79 extensionStart(Standard_False),
80 extensionEnd(Standard_False)
84 //=============================================================================
87 //=============================================================================
88 Bisector_BisecCC::Bisector_BisecCC(const Handle(Geom2d_Curve)& Cu1,
89 const Handle(Geom2d_Curve)& Cu2,
90 const Standard_Real Side1,
91 const Standard_Real Side2,
92 const gp_Pnt2d& Origin,
93 const Standard_Real DistMax)
95 Perform (Cu1,Cu2,Side1,Side2,Origin,DistMax);
98 //=============================================================================
101 //=============================================================================
102 void Bisector_BisecCC::Perform(const Handle(Geom2d_Curve)& Cu1,
103 const Handle(Geom2d_Curve)& Cu2,
104 const Standard_Real Side1,
105 const Standard_Real Side2,
106 const gp_Pnt2d& Origin,
107 const Standard_Real DistMax)
109 isEmpty = Standard_False;
112 curve1 = Handle (Geom2d_Curve)::DownCast(Cu1->Copy());
113 curve2 = Handle (Geom2d_Curve)::DownCast(Cu2->Copy());
118 isConvex1 = Bisector::IsConvex(curve1,sign1);
119 isConvex2 = Bisector::IsConvex(curve2,sign2);
121 Standard_Real U,UC1,UC2,Dist,dU,USol;
123 Standard_Integer NbPnts = 21;
124 Standard_Real EpsMin = 10*Precision::Confusion();
125 Standard_Boolean YaPoly = Standard_True;
126 Standard_Boolean OriInPoly = Standard_False;
127 //---------------------------------------------
128 // Calculate first point of the polygon.
129 //---------------------------------------------
130 Standard_Boolean isProjDone = ProjOnCurve (Origin,curve1, U);
134 isEmpty = Standard_True;
138 P = ValueByInt (U,UC1,UC2,Dist);
139 if(Dist < Precision::Confusion())
141 gp_Pnt2d aP1 = curve1->Value(UC1);
142 gp_Pnt2d aP2 = curve2->Value(UC2);
143 Standard_Real dp = (aP1.Distance(P)+aP2.Distance(P));
144 Standard_Real dorig = (aP1.Distance(Origin)+aP2.Distance(Origin));
147 isEmpty = Standard_True;
152 if (Dist < Precision::Infinite()) {
153 //----------------------------------------------------
154 // the parameter of the origin point gives a point
156 //----------------------------------------------------
157 myPolygon.Append(Bisector_PointOnBis(UC1,UC2,U,Dist,P));
158 startIntervals.Append(U);
159 if (P.IsEqual(Origin,Precision::Confusion())) {
160 //----------------------------------------
161 // test if the first point is the origin.
162 //----------------------------------------
163 OriInPoly = Standard_True;
167 //-------------------------------------------------------
168 // The origin point is on the extension.
169 // Find the first point of the polygon by dichotomy.
170 //-------------------------------------------------------
171 dU = (curve1->LastParameter() - U)/(NbPnts - 1);
173 for (Standard_Integer i = 1; i <= NbPnts - 1; i++) {
174 P = ValueByInt(U,UC1,UC2,Dist);
175 if (Dist < Precision::Infinite()) {
176 USol = SearchBound(U - dU,U);
177 P = ValueByInt(USol,UC1,UC2,Dist);
178 startIntervals.Append(USol);
179 myPolygon.Append(Bisector_PointOnBis(UC1,UC2,USol,Dist,P));
186 if ( myPolygon.Length() != 0 ) {
188 //----------------------------------------------
189 // Construction of the polygon of the bissectrice.
190 //---------------------------------------------
191 U = FirstParameter();
192 Standard_Real DU = LastParameter() - U;
194 if (DU < EpsMin) {NbPnts = 3;}
195 dU = DU/(NbPnts - 1);
198 // modified by NIZHNY-EAP Fri Jan 21 09:33:20 2000 ___BEGIN___
199 // prevent addition of the same point
200 gp_Pnt2d prevPnt = P;
201 for (Standard_Integer i = 1; i <= NbPnts - 1; i++) {
202 P = ValueByInt(U,UC1,UC2,Dist);
203 if (Dist < Precision::Infinite()) {
204 if (P.Distance (prevPnt) > Precision::Confusion())
205 myPolygon.Append(Bisector_PointOnBis(UC1,UC2,U,Dist,P));
208 USol = SearchBound(U - dU,U);
209 P = ValueByInt(USol,UC1,UC2,Dist);
210 endIntervals.SetValue(1,USol);
211 if (P.Distance (prevPnt) > Precision::Confusion())
212 myPolygon.Append(Bisector_PointOnBis(UC1,UC2,USol,Dist,P));
217 // modified by NIZHNY-EAP Fri Jan 21 09:33:24 2000 ___END___
224 YaPoly = Standard_False;
227 extensionStart = Standard_False;
228 extensionEnd = Standard_False;
231 if (isConvex1 && isConvex2) {
232 if (YaPoly) pointEnd = myPolygon.Last().Point();
235 //-----------------------------------------------------------------------------
236 // Extension : The curve is extended at the beginning and/or the end if
237 // - one of two curves is concave.
238 // - the curves have a common point at the beginning and/or the end
239 // - the angle of opening at the common point between two curves
241 // the extension at the beginning is taken into account if the origin is found above.
242 // ie : the origin is not the in the polygon.
243 //-----------------------------------------------------------------------------
245 //---------------------------------
246 // Do the extensions exist ?
247 //---------------------------------
249 extensionStart = Standard_False;
252 extensionStart = TestExtension(curve1,curve2,1);
254 extensionEnd = TestExtension(curve1,curve2,2);
257 // Calculate pointEnd.
260 pointEnd = curve1->Value(curve1->LastParameter());
263 pointEnd = myPolygon.Last().Point();
268 //------------------------------------------------------
269 // Update the Limits of intervals of definition.
270 //------------------------------------------------------
272 if (extensionStart) {
273 gp_Pnt2d P1 = myPolygon.First().Point();
274 Standard_Real UFirst = startIntervals.First() - pointStart.Distance(P1);
275 startIntervals.InsertBefore(1,UFirst);
276 endIntervals .InsertBefore(1,startIntervals.Value(2));
280 Standard_Real UFirst,ULast;
281 P1 = myPolygon.Last().Point();
282 UFirst = endIntervals.Last();
283 ULast = UFirst + pointEnd.Distance(P1);
284 startIntervals.Append(UFirst);
285 endIntervals .Append(ULast );
289 //--------------------------------------------------
290 // No polygon => the bissectrice is a segment.
291 //--------------------------------------------------
292 startIntervals.Append(0.);
293 endIntervals .Append(pointEnd.Distance(pointStart));
296 if (!YaPoly && !extensionStart && !extensionEnd)
297 isEmpty = Standard_True;
298 // modified by NIZHNY-EAP Mon Jan 17 17:32:40 2000 ___BEGIN___
299 if (myPolygon.Length() <= 2)
300 isEmpty = Standard_True;
301 // modified by NIZHNY-EAP Mon Jan 17 17:32:42 2000 ___END___
304 //=============================================================================
305 //function : IsExtendAtStart
307 //=============================================================================
308 Standard_Boolean Bisector_BisecCC::IsExtendAtStart() const
310 return extensionStart;
313 //=============================================================================
314 //function : IsExtendAtEnd
316 //=============================================================================
317 Standard_Boolean Bisector_BisecCC::IsExtendAtEnd() const
322 //=============================================================================
325 //=============================================================================
326 Standard_Boolean Bisector_BisecCC::IsEmpty() const
331 //=============================================================================
334 //=============================================================================
335 void Bisector_BisecCC::Reverse()
337 throw Standard_NotImplemented();
340 //=============================================================================
341 //function : ReversedParameter
343 //=============================================================================
344 Standard_Real Bisector_BisecCC::ReversedParameter(const Standard_Real U) const
346 return LastParameter() + FirstParameter() - U;
349 //=============================================================================
352 //=============================================================================
353 Handle(Geom2d_Geometry) Bisector_BisecCC::Copy() const
355 Handle(Geom2d_Curve) CopyCurve1
356 = Handle(Geom2d_Curve)::DownCast(curve1->Copy());
357 Handle(Geom2d_Curve) CopyCurve2
358 = Handle(Geom2d_Curve)::DownCast(curve2->Copy());
360 Handle(Bisector_BisecCC) C = new Bisector_BisecCC();
362 C -> Curve (1, CopyCurve1) ; C -> Curve (2, CopyCurve2);
363 C -> Sign (1, sign1 ) ; C -> Sign (2, sign2 );
364 C -> IsConvex (1, isConvex1) ; C -> IsConvex (2, isConvex2);
365 C -> Polygon (myPolygon);
366 C -> IsEmpty (isEmpty) ;
367 C -> DistMax (distMax) ;
368 C -> StartIntervals (startIntervals); C -> EndIntervals (endIntervals);
369 C -> ExtensionStart (extensionStart); C -> ExtensionEnd (extensionEnd);
370 C -> PointStart (pointStart) ; C -> PointEnd (pointEnd) ;
375 //=============================================================================
376 //function : ChangeGuide
377 //purpose : Changet of the guideline for the parameters of the bissectrice
378 // ATTENTION : - This can invert the direction of parameterization.
379 // - This concerns only the part of the curve
380 // corresponding to the polygon.
381 //=============================================================================
382 Handle(Bisector_BisecCC) Bisector_BisecCC::ChangeGuide() const
384 Handle(Bisector_BisecCC) C = new Bisector_BisecCC();
386 C -> Curve (1, curve2) ; C -> Curve (2, curve1);
387 C -> Sign (1, sign2 ) ; C -> Sign (2, sign1 );
388 C -> IsConvex (1, isConvex2); C -> IsConvex (2, isConvex1);
390 //-------------------------------------------------------------------------
391 // Construction of the new polygon from the initial one.
392 // inversion of PointOnBis and Calculation of new parameters on the bissectrice.
393 //-------------------------------------------------------------------------
394 Bisector_PolyBis Poly;
395 if (sign1 == sign2 ) {
396 //---------------------------------------------------------------
397 // elements of the new polygon are ranked in the other direction.
398 //---------------------------------------------------------------
399 for (Standard_Integer i = myPolygon.Length(); i >=1; i--) {
400 Bisector_PointOnBis P = myPolygon.Value(i);
401 Bisector_PointOnBis NewP (P.ParamOnC2(), P.ParamOnC1(),
402 P.ParamOnC2(), P.Distance (),
408 for (Standard_Integer i = 1; i <= myPolygon.Length(); i ++) {
409 Bisector_PointOnBis P = myPolygon.Value(i);
410 Bisector_PointOnBis NewP (P.ParamOnC2(), P.ParamOnC1(),
411 P.ParamOnC2(), P.Distance (),
417 C -> FirstParameter (Poly.First().ParamOnBis());
418 C -> LastParameter (Poly.Last() .ParamOnBis());
423 //=============================================================================
424 //function : Transform
426 //=============================================================================
427 void Bisector_BisecCC::Transform (const gp_Trsf2d& T)
429 curve1 ->Transform(T);
430 curve2 ->Transform(T);
431 myPolygon . Transform(T);
432 pointStart. Transform(T);
433 pointEnd . Transform(T);
436 //=============================================================================
439 //=============================================================================
440 Standard_Boolean Bisector_BisecCC::IsCN (const Standard_Integer N) const
442 return (curve1->IsCN(N+1) && curve2->IsCN(N+1));
445 //=============================================================================
446 //function : FirstParameter
448 //=============================================================================
449 Standard_Real Bisector_BisecCC::FirstParameter() const
451 return startIntervals.First();
454 //=============================================================================
455 //function : LastParameter
457 //=============================================================================
458 Standard_Real Bisector_BisecCC::LastParameter() const
460 return endIntervals.Last();
463 //=============================================================================
464 //function : Continuity
466 //=============================================================================
467 GeomAbs_Shape Bisector_BisecCC::Continuity() const
469 GeomAbs_Shape Cont = curve1->Continuity();
471 case GeomAbs_C1 : return GeomAbs_C0;
472 case GeomAbs_C2 : return GeomAbs_C1;
473 case GeomAbs_C3 : return GeomAbs_C2;
474 case GeomAbs_CN : return GeomAbs_CN;
480 //=============================================================================
481 //function : NbIntervals
483 //=============================================================================
484 Standard_Integer Bisector_BisecCC::NbIntervals() const
486 return startIntervals.Length();
489 //=============================================================================
490 //function : IntervalFirst
492 //=============================================================================
493 Standard_Real Bisector_BisecCC::IntervalFirst(const Standard_Integer Index) const
495 return startIntervals.Value(Index);
498 //=============================================================================
499 //function : IntervalLast
501 //=============================================================================
502 Standard_Real Bisector_BisecCC::IntervalLast(const Standard_Integer Index) const
504 return endIntervals.Value(Index);
507 //=============================================================================
508 //function : IntervalContinuity
510 //=============================================================================
511 GeomAbs_Shape Bisector_BisecCC::IntervalContinuity() const
513 GeomAbs_Shape Cont = curve1->Continuity();
515 case GeomAbs_C1 : return GeomAbs_C0;
516 case GeomAbs_C2 : return GeomAbs_C1;
517 case GeomAbs_C3 : return GeomAbs_C2;
518 case GeomAbs_CN : return GeomAbs_CN;
524 //=============================================================================
525 //function : IsClosed
527 //=============================================================================
528 Standard_Boolean Bisector_BisecCC::IsClosed() const
530 if (curve1->IsClosed()) {
531 if (startIntervals.First() == curve1->FirstParameter() &&
532 endIntervals .Last () == curve1->LastParameter () )
533 return Standard_True;
535 return Standard_False;
538 //=============================================================================
539 //function : IsPeriodic
541 //=============================================================================
542 Standard_Boolean Bisector_BisecCC::IsPeriodic() const
544 return Standard_False;
548 //=============================================================================
549 //function : Curvature
551 //=============================================================================
552 static Standard_Real Curvature (const Handle(Geom2d_Curve)& C,
560 Standard_Real Norm2 = D1.SquareMagnitude();
565 K1 = (D1^D2)/(Norm2*sqrt(Norm2));
570 //=============================================================================
572 //purpose : CALCULATE THE CURRENT POINT BY ITERATIVE METHOD.
573 // ----------------------------------------------
574 // Calculate the current point, the distance from the current point to
575 // both curves, the parameters on each curve of the projection
576 // of the current point.
578 //method : - Find start parameter by using <myPolygon>.
579 // - Calculate parameter U2 on curve C2 solution of H(U,V)= 0
583 // ||P2(v0)P1(u)||**2
584 // F(u,v) = P1(u) - 1/2 *----------------* N(u)
585 // (N(u).P2(v0)P1(u))
587 // H(u,v) = (Tu.P1(u)P2(v))**2||Tv||**2 - (Tv.P1(u)P2(v))**2||Tu||**2
589 //=============================================================================
590 gp_Pnt2d Bisector_BisecCC::ValueAndDist (const Standard_Real U,
593 Standard_Real& Dist) const
597 //-----------------------------------------------
598 // is the polygon reduced to a point or empty?
599 //-----------------------------------------------
600 if (myPolygon.Length() <= 1) {
601 return Extension(U,U1,U2,Dist,T);
604 //-----------------------------------------------
605 // test U out of the limits of the polygon.
606 //-----------------------------------------------
607 if (U < myPolygon.First().ParamOnBis()) {
608 return Extension(U,U1,U2,Dist,T);
610 if (U > myPolygon.Last().ParamOnBis()) {
611 return Extension(U,U1,U2,Dist,T);
614 //-------------------------------------------------------
615 // Find start parameter by using <myPolygon>.
616 //-------------------------------------------------------
617 Standard_Integer IntervalIndex = myPolygon.Interval(U);
618 Standard_Real UMin = myPolygon.Value(IntervalIndex ).ParamOnBis();
619 Standard_Real UMax = myPolygon.Value(IntervalIndex + 1).ParamOnBis();
620 Standard_Real VMin = myPolygon.Value(IntervalIndex ).ParamOnC2();
621 Standard_Real VMax = myPolygon.Value(IntervalIndex + 1).ParamOnC2();
622 Standard_Real Alpha,VInit;
624 if (Abs(UMax - UMin) < gp::Resolution()) {
628 Alpha = (U - UMin)/(UMax - UMin);
629 VInit = VMin + Alpha*(VMax - VMin);
632 U1 = LinkBisCurve(U);
633 Standard_Real VTemp = Min(VMin,VMax);
634 VMax = Max(VMin,VMax); VMin = VTemp;
635 Standard_Boolean Valid = Standard_True;
636 //---------------------------------------------------------------
637 // Calculate parameter U2 on curve C2 solution of H(u,v)=0
638 //---------------------------------------------------------------
641 Standard_Real EpsH = 1.E-9;
642 Standard_Real EpsH100 = 1.E-7;
643 curve1->D1 (U1,P1,T1);
644 gp_Vec2d N1(T1.Y(), - T1.X());
646 if ((VMax - VMin) < Precision::PConfusion()) {
650 Bisector_FunctionH H (curve2,P1,sign1*sign2*T1);
652 H.Value(VInit,FInit);
653 if (Abs(FInit) < EpsH) {
658 math_BissecNewton aNewSolution(EpsH);
659 aNewSolution.Perform(H, VMin - EpsH100, VMax + EpsH100, 10);
661 if (aNewSolution.IsDone())
663 U2 = aNewSolution.Root();
667 math_FunctionRoot SolRoot (H,VInit,EpsH,VMin - EpsH100,VMax + EpsH100);
669 if (SolRoot.IsDone())
672 Valid = Standard_False;
677 gp_Pnt2d PBis = pointStart;
682 gp_Pnt2d P2 = curve2->Value(U2);
683 gp_Vec2d P2P1(P1.X() - P2.X(),P1.Y() - P2.Y());
684 Standard_Real SquareP2P1 = P2P1.SquareMagnitude();
685 Standard_Real N1P2P1 = N1.Dot(P2P1);
686 const Standard_Real anEps = Epsilon(1);
688 if (P1.IsEqual(P2,Precision::Confusion())) {
692 else if (N1P2P1*sign1 < anEps) {
693 Valid = Standard_False;
696 PBis = P1.Translated(- (0.5*SquareP2P1/N1P2P1)*N1);
697 Dist = P1.SquareDistance(PBis);
701 //----------------------------------------------------------------
702 // If the point is not valid
703 // calculate by intersection.
704 //----------------------------------------------------------------
706 //--------------------------------------------------------------------
707 // Construction of the bisectrice point curve and of the straight line passing
708 // by P1 and carried by the normal. curve2 is limited by VMin and VMax.
709 //--------------------------------------------------------------------
710 Standard_Real DMin = Precision::Infinite();
712 Handle(Bisector_BisecPC) BisPC
713 = new Bisector_BisecPC(curve2, P1, sign2, VMin, VMax);
714 Handle(Geom2d_Line) NorLi = new Geom2d_Line (P1,N1);
716 Geom2dAdaptor_Curve ABisPC(BisPC);
717 Geom2dAdaptor_Curve ANorLi(NorLi);
718 //-------------------------------------------------------------------------
719 Geom2dInt_GInter Intersect(ABisPC,ANorLi,
720 Precision::Confusion(),Precision::Confusion());
721 //-------------------------------------------------------------------------
723 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
724 for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) {
725 if (Intersect.Point(i).ParamOnSecond()*sign1 < Precision::PConfusion()) {
726 P = Intersect.Point(i).Value();
727 if (P.SquareDistance(P1) < DMin) {
728 DMin = P.SquareDistance(P1);
730 U2 = BisPC->LinkBisCurve(Intersect.Point(i).ParamOnFirst());
740 //=============================================================================
741 //function : ValueByInt
742 //purpose : CALCULATE THE CURRENT POINT BY INTERSECTION.
743 // -------------------------------------------
744 // Calculate the current point, the distance from the current point
745 // to two curves, the parameters on each curve of the projection of the
747 // the current point with parameter U is the intersection of the
748 // bissectrice point curve (P1,curve2) and of the straight line
749 // passing through P1 of director vector N1.
750 // P1 is the current point of parameter U on curve1 and N1 the
751 // normal at this point.
752 //=============================================================================
753 gp_Pnt2d Bisector_BisecCC::ValueByInt (const Standard_Real U,
756 Standard_Real& Dist) const
758 //------------------------------------------------------------------
759 // Return point, tangent, normal on C1 at parameter U.
760 //-------------------------------------------------------------------
761 U1 = LinkBisCurve(U);
763 gp_Pnt2d P1,P2,P,PSol;
765 curve1->D1(U1,P1,Tan1);
766 gp_Vec2d N1( Tan1.Y(), - Tan1.X());
768 //--------------------------------------------------------------------------
769 // test confusion of P1 with extremity of curve2.
770 //--------------------------------------------------------------------------
771 if (P1.Distance(curve2->Value(curve2->FirstParameter())) < Precision::Confusion()) {
772 U2 = curve2->FirstParameter();
773 curve2->D1(U2,P2,Tan2);
774 if ( isConvex1 && isConvex2 ) {
778 if (! Tan1.IsParallel(Tan2,Precision::Angular())) {
783 if (P1.Distance(curve2->Value(curve2->LastParameter())) < Precision::Confusion()) {
784 U2 = curve2->LastParameter();
785 curve2->D1(U2,P2,Tan2);
786 if ( isConvex1 && isConvex2 ) {
790 if (! Tan1.IsParallel(Tan2,Precision::Angular())) {
796 Standard_Boolean YaSol = Standard_False;
797 Standard_Real DMin = Precision::Infinite();
799 Standard_Real EpsMax = 1.E-6;
801 Standard_Real EpsH = 1.E-8;
802 Standard_Real DistPP1;
803 Standard_Integer NbSamples =20;
804 Standard_Real UFirstOnC2 = curve2->FirstParameter();
805 Standard_Real ULastOnC2 = curve2->LastParameter();
807 if (!myPolygon.IsEmpty()){
808 if (sign1 == sign2) { ULastOnC2 = myPolygon.Last().ParamOnC2();}
809 else { UFirstOnC2 = myPolygon.Last().ParamOnC2();}
812 if (Abs(ULastOnC2 - UFirstOnC2) < Precision::PConfusion()/100.) {
813 Dist = Precision::Infinite();
817 DiscretPar(Abs(ULastOnC2 - UFirstOnC2),EpsH,EpsMax,2,20,EpsX,NbSamples);
819 Bisector_FunctionH H (curve2,P1,sign1*sign2*Tan1);
820 math_FunctionRoots SolRoot (H,
825 if (SolRoot.IsDone()) {
826 for (Standard_Integer j = 1; j <= SolRoot.NbSolutions(); j++) {
827 USol = SolRoot.Value(j);
828 gp_Pnt2d P2Curve2 = curve2->Value(USol);
829 gp_Vec2d P2P1(P1.X() - P2Curve2.X(),P1.Y() - P2Curve2.Y());
830 Standard_Real SquareP2P1 = P2P1.SquareMagnitude();
831 Standard_Real N1P2P1 = N1.Dot(P2P1);
833 // Test if the solution is at the proper side of the curves.
834 if (N1P2P1*sign1 > 0 ) {
835 P = P1.Translated(- (0.5*SquareP2P1/N1P2P1)*N1);
836 DistPP1 = P1.SquareDistance(P);
837 if (DistPP1 < DMin) {
841 YaSol = Standard_True;
849 //--------------------------------------------------------------------
850 // Construction de la bisectrice point courbe et de la droite passant
851 // par P1 et portee par la normale.
852 //--------------------------------------------------------------------
853 Handle(Bisector_BisecPC) BisPC
854 = new Bisector_BisecPC(curve2,P1,sign2,2*distMax);
855 //-------------------------------
856 // Test si la bissectrice existe.
857 //-------------------------------
858 if (BisPC->IsEmpty()) {
859 Dist = Precision::Infinite();
864 Handle(Geom2d_Line) NorLi = new Geom2d_Line (P1,N1);
865 Geom2dAdaptor_Curve NorLiAd;
866 if (sign1 < 0.) {NorLiAd.Load(NorLi,0. ,distMax);}
867 else {NorLiAd.Load(NorLi,- distMax,0. );}
869 //-------------------------------------------------------------------------
870 Geom2dInt_GInter Intersect(BisPC,NorLiAd,
871 Precision::Confusion(),Precision::Confusion());
872 //-------------------------------------------------------------------------
873 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
874 for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) {
875 if (Intersect.Point(i).ParamOnSecond()*sign1< Precision::PConfusion()) {
876 P = Intersect.Point(i).Value();
877 DistPP1 = P.SquareDistance(P1);
878 if (DistPP1 < DMin) {
881 U2 = Intersect.Point(i).ParamOnFirst();
882 YaSol = Standard_True;
892 //--------------------------------------------------------------
893 // Point found => Test curve distance + Angular Test
894 //---------------------------------------------------------------
895 P2 = curve2->Value(U2);
896 gp_Vec2d PP1(P1.X() - PSol.X(),P1.Y() - PSol.Y());
897 gp_Vec2d PP2(P2.X() - PSol.X(),P2.Y() - PSol.Y());
899 //-----------------------------------------------
900 // Dist = product of norms = distance at the square.
901 //-----------------------------------------------
902 if (PP1.Dot(PP2) > (1. - Precision::Angular())*Dist) {
903 YaSol = Standard_False;
907 Standard_Real K1 = Curvature(curve1,U1,Precision::Confusion());
909 if (Dist > 1/(K1*K1)) YaSol = Standard_False;
914 Standard_Real K2 = Curvature(curve2,U2,Precision::Confusion());
916 if (Dist > 1/(K2*K2)) YaSol = Standard_False;
923 Dist = Precision::Infinite();
929 //=============================================================================
932 //=============================================================================
933 void Bisector_BisecCC::D0(const Standard_Real U,
936 Standard_Real U1,U2,Dist;
938 P = ValueAndDist(U,U1,U2,Dist);
941 //=============================================================================
944 //=============================================================================
945 void Bisector_BisecCC::D1(const Standard_Real U,
951 Values(U,1,P,V,V2,V3);
954 //=============================================================================
957 //=============================================================================
958 void Bisector_BisecCC::D2(const Standard_Real U,
966 Values(U,2,P,V1,V2,V3);
969 //=============================================================================
972 //=============================================================================
973 void Bisector_BisecCC::D3(const Standard_Real U,
982 Values(U,3,P,V1,V2,V3);
985 //=============================================================================
988 //=============================================================================
989 gp_Vec2d Bisector_BisecCC::DN(const Standard_Real U,
990 const Standard_Integer N) const
996 Values (U,N,P,V1,V2,V3);
1002 throw Standard_NotImplemented();
1007 //=============================================================================
1009 // purpose : the curve can be described by the following equations:
1012 // where v0 = Phi(u) is given by H (u,v) = 0.
1015 // ||P2(v0)P1(u)||**2
1016 // F(u,v) = P1(u) - 1/2 *----------------* N(u)
1017 // (N(u).P2(v0)P1(u))
1019 // H(u,v) = (Tu.P1(u)P2(v))**2||Tv||**2 - (Tv.P1(u)P2(v))**2||Tu||**2
1021 // => dB(u)/du = dF/du + dF/dv(- dH/du:dH/dv)
1023 // Note : tangent to the bisectrice is bissectrice at
1024 // tangents T1(u) and T2(v0)
1026 //=============================================================================
1027 void Bisector_BisecCC::Values (const Standard_Real U,
1028 const Standard_Integer N,
1034 V1 = gp_Vec2d(0.,0.);
1035 V2 = gp_Vec2d(0.,0.);
1036 V3 = gp_Vec2d(0.,0.);
1037 //-------------------------------------------------------------------------
1038 // Calculate the current point on the bisectrice and the parameters on each
1040 //-------------------------------------------------------------------------
1041 Standard_Real U0,V0,Dist;
1043 //-----------------------------------------------
1044 // is the polygon reduced to a point or empty?
1045 //-----------------------------------------------
1046 if (myPolygon.Length() <= 1) {
1047 P = Extension(U,U0,V0,Dist,V1);
1049 if (U < myPolygon.First().ParamOnBis()) {
1050 P = Extension(U,U0,V0,Dist,V1);
1053 if (U > myPolygon.Last().ParamOnBis()) {
1054 P = Extension(U,U0,V0,Dist,V1);
1057 P = ValueAndDist(U,U0,V0,Dist);
1060 //------------------------------------------------------------------
1061 // Return point, tangent, normal to C1 by parameter U0.
1062 //-------------------------------------------------------------------
1063 gp_Pnt2d P1 ; // point on C1.
1064 gp_Vec2d Tu ; // tangent to C1 by U0.
1065 gp_Vec2d Tuu ; // second derivative to C1 by U0.
1066 curve1->D2(U0,P1,Tu,Tuu);
1067 gp_Vec2d Nor( - Tu .Y() , Tu .X()); // Normal by U0.
1068 gp_Vec2d Nu ( - Tuu.Y() , Tuu.X()); // derivative of the normal by U0.
1070 //-------------------------------------------------------------------
1071 // Return point, tangent, normale to C2 by parameter V0.
1072 //-------------------------------------------------------------------
1073 gp_Pnt2d P2 ; // point on C2.
1074 gp_Vec2d Tv ; // tangent to C2 by V.
1075 gp_Vec2d Tvv ; // second derivative to C2 by V.
1076 curve2->D2(V0,P2,Tv,Tvv);
1078 gp_Vec2d PuPv(P2.X() - P1.X(), P2.Y() - P1.Y());
1080 //-----------------------------
1081 // Calculate dH/du and dH/dv.
1082 //-----------------------------
1083 Standard_Real TuTu,TvTv,TuTv;
1084 Standard_Real TuPuPv,TvPuPv ;
1085 Standard_Real TuuPuPv,TuTuu ;
1086 Standard_Real TvvPuPv,TvTvv ;
1088 TuTu = Tu.Dot(Tu) ; TvTv = Tv.Dot(Tv) ; TuTv = Tu.Dot(Tv);
1089 TuPuPv = Tu.Dot(PuPv) ; TvPuPv = Tv.Dot(PuPv);
1090 TuuPuPv = Tuu.Dot(PuPv) ; TuTuu = Tu.Dot(Tuu) ;
1091 TvvPuPv = Tvv.Dot(PuPv) ; TvTvv = Tv.Dot(Tvv) ;
1093 Standard_Real dHdu = 2*(TuPuPv*(TuuPuPv - TuTu)*TvTv +
1094 TvPuPv*TuTv*TuTu -TuTuu*TvPuPv*TvPuPv);
1095 Standard_Real dHdv = 2*(TuPuPv*TuTv*TvTv + TvTvv*TuPuPv*TuPuPv -
1096 TvPuPv*(TvvPuPv + TvTv)*TuTu);
1098 //-----------------------------
1099 // Calculate dF/du and dF/dv.
1100 //-----------------------------
1101 Standard_Real NorPuPv,NuPuPv,NorTv;
1102 Standard_Real A,B,dAdu,dAdv,dBdu,dBdv,BB;
1104 NorPuPv = Nor.Dot(PuPv);
1105 NuPuPv = Nu .Dot(PuPv);
1106 NorTv = Nor.Dot(Tv) ;
1108 A = 0.5*PuPv.SquareMagnitude();
1116 //---------------------------------------
1117 // F(u,v) = Pu - (A(u,v)/B(u,v))*Nor(u)
1118 //----------------------------------------
1119 if (BB < gp::Resolution()) {
1120 V1 = Tu.Normalized() + Tv.Normalized();
1121 V1 = 0.5*Tu.SquareMagnitude()*V1;
1124 gp_Vec2d dFdu = Tu - (dAdu/B - dBdu*A/BB)*Nor - (A/B)*Nu;
1125 gp_Vec2d dFdv = ( - dAdv/B + dBdv*A/BB)*Nor ;
1127 if (Abs(dHdv) > gp::Resolution()) {
1128 V1 = dFdu + dFdv*( - dHdu / dHdv );
1137 //=============================================================================
1138 //function : Extension
1139 // purpose : Calculate the current point on the extensions
1140 // by tangence of the curve.
1141 //============================================================================
1142 gp_Pnt2d Bisector_BisecCC::Extension (const Standard_Real U,
1145 Standard_Real& Dist,
1148 Bisector_PointOnBis PRef;
1149 gp_Pnt2d P,P1,P2,PBis;
1151 Standard_Real dU = 0.;
1152 Standard_Boolean ExtensionTangent = Standard_False;
1154 if (myPolygon.Length() == 0) {
1155 //---------------------------------------------
1156 // Empty Polygon => segment (pointStart,pointEnd)
1157 //---------------------------------------------
1158 dU = U - startIntervals.First();
1161 U1 = curve1->LastParameter();
1162 if (sign1 == sign2) { U2 = curve2->FirstParameter();}
1163 else { U2 = curve2->LastParameter() ;}
1164 Tang.SetCoord(P1.X() - P.X(),P1.Y() - P.Y());
1166 else if (U < myPolygon.First().ParamOnBis()) {
1167 PRef = myPolygon.First();
1169 dU = U - PRef.ParamOnBis();
1170 if (extensionStart) {
1171 //------------------------------------------------------------
1172 // extension = segment (pointstart, first point of the polygon.)
1173 //------------------------------------------------------------
1175 U1 = curve1->FirstParameter();
1176 if (sign1 == sign2) { U2 = curve2->LastParameter();}
1177 else { U2 = curve2->FirstParameter();}
1178 Tang.SetCoord(P.X() - P1.X(),P.Y() - P1.Y());
1181 ExtensionTangent = Standard_True;
1184 else if (U > myPolygon.Last().ParamOnBis()) {
1185 PRef = myPolygon.Last();
1187 dU = U - PRef.ParamOnBis();
1189 //------------------------------------------------------------
1190 // extension = segment (last point of the polygon.pointEnd)
1191 //------------------------------------------------------------
1193 U1 = curve1->LastParameter();
1194 if (sign1 == sign2) { U2 = curve2->LastParameter();}
1195 else { U2 = curve2->FirstParameter();}
1196 Tang.SetCoord(P1.X() - P.X(),P1.Y() - P.Y());
1199 ExtensionTangent = Standard_True;
1203 if (ExtensionTangent) {
1204 //-----------------------------------------------------------
1205 // If the la curve has no a extension, it is extended by tangency
1206 //------------------------------------------------------------
1207 U1 = PRef.ParamOnC1();
1208 U2 = PRef.ParamOnC2();
1209 P2 = curve2->Value(U2);
1210 curve1->D1(U1,P1,T1);
1211 Tang.SetCoord(2*P.X() - P1.X() - P2.X(), 2*P.Y() - P1.Y() - P2.Y());
1212 if (Tang.Magnitude() < Precision::Confusion()) {
1215 if (T1.Dot(Tang) < 0.) Tang = - Tang;
1218 T = Tang.Normalized();
1219 PBis.SetCoord(P.X() + dU*T.X(),P.Y() + dU*T.Y());
1220 Dist = P1.Distance(PBis);
1224 //=============================================================================
1225 //function : PointByInt
1227 //=============================================================================
1228 static Standard_Boolean PointByInt(const Handle(Geom2d_Curve)& CA,
1229 const Handle(Geom2d_Curve)& CB,
1230 const Standard_Real SignA,
1231 const Standard_Real SignB,
1232 const Standard_Real UOnA,
1233 Standard_Real& UOnB,
1234 Standard_Real& Dist)
1236 //------------------------------------------------------------------
1237 // Return point,tangent, normal on CA with parameter UOnA.
1238 //-------------------------------------------------------------------
1239 gp_Pnt2d P1,P2,P,PSol;
1241 Standard_Boolean IsConvexA = Bisector::IsConvex(CA,SignA);
1242 Standard_Boolean IsConvexB = Bisector::IsConvex(CB,SignB);
1244 CA->D1(UOnA,P1,Tan1);
1245 gp_Vec2d N1(Tan1.Y(), - Tan1.X());
1247 //--------------------------------------------------------------------------
1248 // test of confusion of P1 with extremity of curve2.
1249 //--------------------------------------------------------------------------
1250 if (P1.Distance(CB->Value(CB->FirstParameter())) < Precision::Confusion()) {
1251 UOnB = CB->FirstParameter();
1252 CB->D1(UOnB,P2,Tan2);
1253 if ( IsConvexA && IsConvexB ) {
1255 return Standard_True;
1257 if (! Tan1.IsParallel(Tan2,Precision::Angular())) {
1259 return Standard_False;
1262 if (P1.Distance(CB->Value(CB->LastParameter())) < Precision::Confusion()) {
1263 UOnB = CB->LastParameter();
1264 CB->D1(UOnB,P2,Tan2);
1265 if ( IsConvexA && IsConvexB ) {
1267 return Standard_True;
1269 if (! Tan1.IsParallel(Tan2,Precision::Angular())) {
1271 return Standard_False;
1275 Standard_Real DMin = Precision::Infinite();
1277 Standard_Boolean YaSol = Standard_False;
1278 //--------------------------------------------------------------------
1279 // Construction of the bisectrice point curve and of the straight line passing
1280 // through P1 and carried by the normal.
1281 //--------------------------------------------------------------------
1282 Handle(Bisector_BisecPC) BisPC
1283 = new Bisector_BisecPC(CB,P1,SignB );
1284 //-------------------------------
1285 // Test if the bissectrice exists.
1286 //-------------------------------
1287 if (BisPC->IsEmpty()) {
1288 Dist = Precision::Infinite();
1290 return Standard_False;
1293 Handle(Geom2d_Line) NorLi = new Geom2d_Line (P1,N1);
1295 Geom2dAdaptor_Curve ABisPC(BisPC);
1296 Geom2dAdaptor_Curve ANorLi(NorLi);
1297 //-------------------------------------------------------------------------
1298 Geom2dInt_GInter Intersect(ABisPC,ANorLi,
1299 Precision::Confusion(),Precision::Confusion());
1300 //-------------------------------------------------------------------------
1302 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1303 for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) {
1304 if (Intersect.Point(i).ParamOnSecond()*SignA < Precision::PConfusion()) {
1305 P = Intersect.Point(i).Value();
1306 if (P.SquareDistance(P1) < DMin) {
1307 DMin = P.SquareDistance(P1);
1309 UPC = Intersect.Point(i).ParamOnFirst();
1310 UOnB = BisPC->LinkBisCurve(UPC);
1312 YaSol = Standard_True;
1318 //--------------------------------------------------------------
1319 // Point found => Test distance curvature + Angular test
1320 //---------------------------------------------------------------
1321 P2 = CB->Value(UOnB);
1322 if(P1.SquareDistance(PSol) < 1.e-32)
1324 YaSol = Standard_False;
1327 if(P2.SquareDistance(PSol) < 1.e-32)
1329 YaSol = Standard_False;
1333 gp_Dir2d PP1Unit(P1.X() - PSol.X(),P1.Y() - PSol.Y());
1334 gp_Dir2d PP2Unit(P2.X() - PSol.X(),P2.Y() - PSol.Y());
1336 if (PP1Unit*PP2Unit > 1. - Precision::Angular()) {
1337 YaSol = Standard_False;
1342 Standard_Real K1 = Curvature(CA,UOnA,Precision::Confusion());
1344 if (Dist > Abs(1/K1)) YaSol = Standard_False;
1349 Standard_Real K2 = Curvature(CB,UOnB,Precision::Confusion());
1351 if (Dist > Abs(1/K2)) YaSol = Standard_False;
1360 //=============================================================================
1361 //function : SupLastParameter
1363 //=============================================================================
1364 void Bisector_BisecCC::SupLastParameter()
1366 endIntervals.Append(curve1->LastParameter());
1367 // ----------------------------------------------------------------------
1368 // Calculate parameter on curve1 associated to one or the other of the extremities
1369 // of curve2 following the values of sign1 and sign2.
1370 // the bissectrice is limited by the obtained parameters.
1371 //------------------------------------------------------------------------
1372 Standard_Real UOnC1,UOnC2,Dist;
1373 if (sign1 == sign2) {
1374 UOnC2 = curve2->FirstParameter();
1377 UOnC2 = curve2->LastParameter();
1379 Standard_Boolean YaSol = PointByInt(curve2,curve1,sign2,sign1,UOnC2,UOnC1,Dist);
1381 if (UOnC1 > startIntervals.First() && UOnC1 < endIntervals.Last()) {
1382 endIntervals.SetValue(1,UOnC1);
1387 //=============================================================================
1390 //=============================================================================
1391 Handle(Geom2d_Curve) Bisector_BisecCC::Curve(const Standard_Integer I) const
1393 if (I == 1) return curve1;
1394 else if (I == 2) return curve2;
1395 else throw Standard_OutOfRange();
1398 //=============================================================================
1399 //function : LinkBisCurve
1401 //=============================================================================
1402 Standard_Real Bisector_BisecCC::LinkBisCurve(const Standard_Real U) const
1404 return (U - shiftParameter);
1407 //=============================================================================
1408 //function : LinkCurveBis
1410 //=============================================================================
1411 Standard_Real Bisector_BisecCC::LinkCurveBis(const Standard_Real U) const
1413 return (U + shiftParameter);
1416 //=============================================================================
1419 //=============================================================================
1420 static void Indent(const Standard_Integer Offset) {
1422 for (Standard_Integer i = 0; i < Offset; i++) {std::cout << " ";}
1426 //=============================================================================
1427 //function : Polygon
1429 //=============================================================================
1430 const Bisector_PolyBis& Bisector_BisecCC::Polygon() const
1435 //==========================================================================
1436 //function : Parameter
1438 //==========================================================================
1439 Standard_Real Bisector_BisecCC::Parameter(const gp_Pnt2d& P) const
1441 Standard_Real UOnCurve;
1443 if (P.IsEqual(Value(FirstParameter()),Precision::Confusion())) {
1444 UOnCurve = FirstParameter();
1446 else if (P.IsEqual(Value(LastParameter()),Precision::Confusion())) {
1447 UOnCurve = LastParameter();
1451 ProjOnCurve(P, curve1, UOnCurve);
1458 //=============================================================================
1461 //=============================================================================
1462 //void Bisector_BisecCC::Dump(const Standard_Integer Deep,
1463 void Bisector_BisecCC::Dump(const Standard_Integer ,
1464 const Standard_Integer Offset) const
1467 std::cout <<"Bisector_BisecCC :"<<std::endl;
1469 // std::cout <<"Curve1 :"<<curve1<<std::endl;
1470 // std::cout <<"Curve2 :"<<curve2<<std::endl;
1471 std::cout <<"Sign1 :"<<sign1<<std::endl;
1472 std::cout <<"Sign2 :"<<sign2<<std::endl;
1474 std::cout <<"Number Of Intervals :"<<startIntervals.Length()<<std::endl;
1475 for (Standard_Integer i = 1; i <= startIntervals.Length(); i++) {
1476 std::cout <<"Interval number :"<<i<<"Start :"<<startIntervals.Value(i)
1477 <<" end :"<< endIntervals.Value(i)<<std::endl ;
1479 std::cout <<"Index Current Interval :"<<currentInterval<<std::endl;
1482 //=============================================================================
1485 //=============================================================================
1486 void Bisector_BisecCC::Curve(const Standard_Integer I,
1487 const Handle(Geom2d_Curve)& C)
1489 if (I == 1) curve1 = C;
1490 else if (I == 2) curve2 = C;
1491 else throw Standard_OutOfRange();
1494 //=============================================================================
1497 //=============================================================================
1498 void Bisector_BisecCC::Sign(const Standard_Integer I,
1499 const Standard_Real S)
1501 if (I == 1) sign1 = S;
1502 else if (I == 2) sign2 = S;
1503 else throw Standard_OutOfRange();
1506 //=============================================================================
1507 //function : Polygon
1509 //=============================================================================
1510 void Bisector_BisecCC::Polygon(const Bisector_PolyBis& P)
1515 //=============================================================================
1516 //function : DistMax
1518 //=============================================================================
1519 void Bisector_BisecCC::DistMax(const Standard_Real D)
1524 //=============================================================================
1525 //function : IsConvex
1527 //=============================================================================
1528 void Bisector_BisecCC::IsConvex(const Standard_Integer I,
1529 const Standard_Boolean IsConvex)
1531 if (I == 1) isConvex1 = IsConvex;
1532 else if (I == 2) isConvex2 = IsConvex;
1533 else throw Standard_OutOfRange();
1536 //=============================================================================
1537 //function : IsEmpty
1539 //=============================================================================
1540 void Bisector_BisecCC::IsEmpty ( const Standard_Boolean IsEmpty)
1545 //=============================================================================
1546 //function : ExtensionStart
1548 //=============================================================================
1549 void Bisector_BisecCC::ExtensionStart( const Standard_Boolean ExtensionStart)
1551 extensionStart = ExtensionStart;
1554 //=============================================================================
1555 //function : ExtensionEnd
1557 //=============================================================================
1558 void Bisector_BisecCC::ExtensionEnd( const Standard_Boolean ExtensionEnd)
1560 extensionEnd = ExtensionEnd;
1563 //=============================================================================
1564 //function : PointStart
1566 //=============================================================================
1567 void Bisector_BisecCC::PointStart( const gp_Pnt2d& Point)
1572 //=============================================================================
1573 //function : PointEnd
1575 //=============================================================================
1576 void Bisector_BisecCC::PointEnd( const gp_Pnt2d& Point)
1581 //=============================================================================
1582 //function : StartIntervals
1584 //=============================================================================
1585 void Bisector_BisecCC::StartIntervals
1586 (const TColStd_SequenceOfReal& StartIntervals)
1588 startIntervals = StartIntervals;
1591 //=============================================================================
1592 //function : EndIntervals
1594 //=============================================================================
1595 void Bisector_BisecCC::EndIntervals
1596 (const TColStd_SequenceOfReal& EndIntervals)
1598 endIntervals = EndIntervals;
1601 //=============================================================================
1602 //function : FirstParameter
1604 //=============================================================================
1605 void Bisector_BisecCC::FirstParameter (const Standard_Real U)
1607 startIntervals.Append(U);
1610 //=============================================================================
1611 //function : LastParameter
1613 //=============================================================================
1614 void Bisector_BisecCC::LastParameter (const Standard_Real U)
1616 endIntervals.Append(U);
1619 //=============================================================================
1620 //function : SearchBound
1622 //=============================================================================
1623 Standard_Real Bisector_BisecCC::SearchBound (const Standard_Real U1,
1624 const Standard_Real U2) const
1626 Standard_Real UMid,Dist1,Dist2,DistMid,U11,U22;
1627 Standard_Real UC1,UC2;
1628 gp_Pnt2d PBis,PBisPrec;
1629 Standard_Real TolPnt = Precision::Confusion();
1630 Standard_Real TolPar = Precision::PConfusion();
1632 PBisPrec = ValueByInt(U11,UC1,UC2,Dist1);
1633 PBis = ValueByInt(U22,UC1,UC2,Dist2);
1635 while ((U22 - U11) > TolPar ||
1636 ((Dist1 < Precision::Infinite() &&
1637 Dist2 < Precision::Infinite() &&
1638 !PBis.IsEqual(PBisPrec,TolPnt)))) {
1640 UMid = 0.5*( U22 + U11);
1641 PBis = ValueByInt(UMid,UC1,UC2,DistMid);
1642 if ((Dist1 < Precision::Infinite()) == (DistMid < Precision::Infinite())) {
1651 PBis = ValueByInt(U11,UC1,UC2,Dist1);
1652 if (Dist1 < Precision::Infinite()) {
1661 //=============================================================================
1662 //function : ProjOnCurve
1664 //=============================================================================
1665 static Standard_Boolean ProjOnCurve (const gp_Pnt2d& P,
1666 const Handle(Geom2d_Curve)& C,
1667 Standard_Real& theParam)
1669 //Standard_Real UOnCurve =0.;
1674 C->D1(C->FirstParameter(),PF,TF);
1675 C->D1(C->LastParameter() ,PL,TL);
1677 if (P.IsEqual(PF ,Precision::Confusion()))
1679 theParam = C->FirstParameter();
1680 return Standard_True;
1683 if (P.IsEqual(PL ,Precision::Confusion()))
1685 theParam = C->LastParameter();
1686 return Standard_True;
1689 gp_Vec2d PPF(PF.X() - P.X(), PF.Y() - P.Y());
1692 if ( Abs (PPF.Dot(TF)) < Precision::Confusion())
1694 theParam = C->FirstParameter();
1695 return Standard_True;
1697 gp_Vec2d PPL (PL.X() - P.X(), PL.Y() - P.Y());
1699 if ( Abs (PPL.Dot(TL)) < Precision::Confusion())
1701 theParam = C->LastParameter();
1702 return Standard_True;
1704 Geom2dAPI_ProjectPointOnCurve Proj(P,C,
1705 C->FirstParameter(),
1706 C->LastParameter());
1707 if (Proj.NbPoints() > 0) {
1708 theParam = Proj.LowerDistanceParameter();
1711 return Standard_False;
1714 return Standard_True;
1717 //=============================================================================
1718 //function : TestExtension
1720 //=============================================================================
1721 static Standard_Boolean TestExtension (const Handle(Geom2d_Curve)& C1,
1722 const Handle(Geom2d_Curve)& C2,
1723 const Standard_Integer Start_End)
1727 Standard_Boolean Test = Standard_False;
1728 if (Start_End == 1) {
1729 C1->D1(C1->FirstParameter(),P1,T1);
1732 C1->D1(C1->LastParameter(),P1,T1);
1734 C2->D1(C2->FirstParameter(),P2,T2);
1735 if (P1.IsEqual(P2,Precision::Confusion())) {
1736 T1.Normalize(); T2.Normalize();
1737 if (T1.Dot(T2) > 1.0 - Precision::Confusion()) {
1738 Test = Standard_True;
1742 C2->D1(C2->LastParameter(),P2,T2);
1743 if (P1.IsEqual(P2,Precision::Confusion())) {
1745 if (T1.Dot(T2) > 1.0 - Precision::Confusion()) {
1746 Test = Standard_True;
1753 //=============================================================================
1754 //function : ComputePointEnd
1756 //=============================================================================
1757 void Bisector_BisecCC::ComputePointEnd ()
1759 Standard_Real U1,U2;
1760 Standard_Real KC,RC;
1761 U1 = curve1->FirstParameter();
1762 if (sign1 == sign2) {
1763 U2 = curve2->LastParameter();
1766 U2 = curve2->FirstParameter();
1768 Standard_Real K1 = Curvature(curve1,U1,Precision::Confusion());
1769 Standard_Real K2 = Curvature(curve2,U2,Precision::Confusion());
1770 if (!isConvex1 && !isConvex2) {
1771 if (K1 < K2) {KC = K1;} else {KC = K2;}
1773 else if (!isConvex1) {KC = K1;}
1778 curve1->D1(U1,PF,TF);
1780 if (KC != 0.) { RC = Abs(1/KC);}
1781 else { RC = Precision::Infinite();}
1782 pointEnd.SetCoord(PF.X() - sign1*RC*TF.Y(), PF.Y() + sign1*RC*TF.X());
1786 //=============================================================================
1787 //function : DiscretPar
1789 //=============================================================================
1790 static Standard_Boolean DiscretPar(const Standard_Real DU,
1791 const Standard_Real EpsMin,
1792 const Standard_Real EpsMax,
1793 const Standard_Integer NbMin,
1794 const Standard_Integer NbMax,
1796 Standard_Integer& Nb)
1798 if (DU <= NbMin*EpsMin) {
1799 Eps = DU/(NbMin + 1) ;
1801 return Standard_False;
1804 Eps = Min (EpsMax,DU/NbMax);
1808 Nb = Standard_Integer(DU/EpsMin);
1812 return Standard_True;