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_Curve.hxx>
22 #include <Bisector_FunctionH.hxx>
23 #include <Bisector_PointOnBis.hxx>
24 #include <Bisector_PolyBis.hxx>
25 #include <Geom2d_Circle.hxx>
26 #include <Geom2d_Curve.hxx>
27 #include <Geom2d_Geometry.hxx>
28 #include <Geom2d_Line.hxx>
29 #include <Geom2d_TrimmedCurve.hxx>
30 #include <Geom2dAdaptor_Curve.hxx>
31 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
32 #include <Geom2dGcc.hxx>
33 #include <Geom2dGcc_Circ2d2TanRad.hxx>
34 #include <Geom2dGcc_QualifiedCurve.hxx>
35 #include <Geom2dInt_GInter.hxx>
36 #include <Geom2dLProp_CLProps2d.hxx>
38 #include <gp_Pnt2d.hxx>
39 #include <gp_Trsf2d.hxx>
40 #include <gp_Vec2d.hxx>
41 #include <IntRes2d_IntersectionPoint.hxx>
42 #include <math_BissecNewton.hxx>
43 #include <math_FunctionRoot.hxx>
44 #include <math_FunctionRoots.hxx>
45 #include <Precision.hxx>
46 #include <Standard_DivideByZero.hxx>
47 #include <Standard_DomainError.hxx>
48 #include <Standard_NotImplemented.hxx>
49 #include <Standard_OutOfRange.hxx>
50 #include <Standard_RangeError.hxx>
51 #include <Standard_Type.hxx>
53 IMPLEMENT_STANDARD_RTTIEXT(Bisector_BisecCC,Bisector_Curve)
55 static Standard_Boolean ProjOnCurve (const gp_Pnt2d& P,
56 const Handle(Geom2d_Curve)& C,
57 Standard_Real& theParam);
59 static Standard_Real Curvature (const Handle(Geom2d_Curve)& C,
63 static Standard_Boolean TestExtension (const Handle(Geom2d_Curve)& C1,
64 const Handle(Geom2d_Curve)& C2,
65 const Standard_Integer Start_End);
67 static Standard_Boolean DiscretPar(const Standard_Real DU,
68 const Standard_Real EpsMin,
69 const Standard_Real EpsMax,
70 const Standard_Integer NbMin,
71 const Standard_Integer NbMax,
73 Standard_Integer& Nb);
75 //=============================================================================
78 //=============================================================================
79 Bisector_BisecCC::Bisector_BisecCC()
82 isEmpty = Standard_False;
85 //=============================================================================
88 //=============================================================================
89 Bisector_BisecCC::Bisector_BisecCC(const Handle(Geom2d_Curve)& Cu1,
90 const Handle(Geom2d_Curve)& Cu2,
91 const Standard_Real Side1,
92 const Standard_Real Side2,
93 const gp_Pnt2d& Origin,
94 const Standard_Real DistMax)
96 Perform (Cu1,Cu2,Side1,Side2,Origin,DistMax);
99 //=============================================================================
102 //=============================================================================
103 void Bisector_BisecCC::Perform(const Handle(Geom2d_Curve)& Cu1,
104 const Handle(Geom2d_Curve)& Cu2,
105 const Standard_Real Side1,
106 const Standard_Real Side2,
107 const gp_Pnt2d& Origin,
108 const Standard_Real DistMax)
110 isEmpty = Standard_False;
113 curve1 = Handle (Geom2d_Curve)::DownCast(Cu1->Copy());
114 curve2 = Handle (Geom2d_Curve)::DownCast(Cu2->Copy());
119 isConvex1 = Bisector::IsConvex(curve1,sign1);
120 isConvex2 = Bisector::IsConvex(curve2,sign2);
122 Standard_Real U,UC1,UC2,Dist,dU,USol;
124 Standard_Integer NbPnts = 21;
125 Standard_Real EpsMin = 10*Precision::Confusion();
126 Standard_Boolean YaPoly = Standard_True;
127 Standard_Boolean OriInPoly = Standard_False;
128 //---------------------------------------------
129 // Calculate first point of the polygon.
130 //---------------------------------------------
131 Standard_Boolean isProjDone = ProjOnCurve (Origin,curve1, U);
135 isEmpty = Standard_True;
139 P = ValueByInt (U,UC1,UC2,Dist);
140 if(Dist < Precision::Confusion())
142 gp_Pnt2d aP1 = curve1->Value(UC1);
143 gp_Pnt2d aP2 = curve2->Value(UC2);
144 Standard_Real dp = (aP1.Distance(P)+aP2.Distance(P));
145 Standard_Real dorig = (aP1.Distance(Origin)+aP2.Distance(Origin));
148 isEmpty = Standard_True;
153 if (Dist < Precision::Infinite()) {
154 //----------------------------------------------------
155 // the parameter of the origin point gives a point
157 //----------------------------------------------------
158 myPolygon.Append(Bisector_PointOnBis(UC1,UC2,U,Dist,P));
159 startIntervals.Append(U);
160 if (P.IsEqual(Origin,Precision::Confusion())) {
161 //----------------------------------------
162 // test if the first point is the origin.
163 //----------------------------------------
164 OriInPoly = Standard_True;
168 //-------------------------------------------------------
169 // The origin point is on the extension.
170 // Find the first point of the polygon by dichotomy.
171 //-------------------------------------------------------
172 dU = (curve1->LastParameter() - U)/(NbPnts - 1);
174 for (Standard_Integer i = 1; i <= NbPnts - 1; i++) {
175 P = ValueByInt(U,UC1,UC2,Dist);
176 if (Dist < Precision::Infinite()) {
177 USol = SearchBound(U - dU,U);
178 P = ValueByInt(USol,UC1,UC2,Dist);
179 startIntervals.Append(USol);
180 myPolygon.Append(Bisector_PointOnBis(UC1,UC2,USol,Dist,P));
187 if ( myPolygon.Length() != 0 ) {
189 //----------------------------------------------
190 // Construction of the polygon of the bissectrice.
191 //---------------------------------------------
192 U = FirstParameter();
193 Standard_Real DU = LastParameter() - U;
195 if (DU < EpsMin) {NbPnts = 3;}
196 dU = DU/(NbPnts - 1);
199 // modified by NIZHNY-EAP Fri Jan 21 09:33:20 2000 ___BEGIN___
200 // prevent addition of the same point
201 gp_Pnt2d prevPnt = P;
202 for (Standard_Integer i = 1; i <= NbPnts - 1; i++) {
203 P = ValueByInt(U,UC1,UC2,Dist);
204 if (Dist < Precision::Infinite()) {
205 if (P.Distance (prevPnt) > Precision::Confusion())
206 myPolygon.Append(Bisector_PointOnBis(UC1,UC2,U,Dist,P));
209 USol = SearchBound(U - dU,U);
210 P = ValueByInt(USol,UC1,UC2,Dist);
211 endIntervals.SetValue(1,USol);
212 if (P.Distance (prevPnt) > Precision::Confusion())
213 myPolygon.Append(Bisector_PointOnBis(UC1,UC2,USol,Dist,P));
218 // modified by NIZHNY-EAP Fri Jan 21 09:33:24 2000 ___END___
225 YaPoly = Standard_False;
228 extensionStart = Standard_False;
229 extensionEnd = Standard_False;
232 if (isConvex1 && isConvex2) {
233 if (YaPoly) pointEnd = myPolygon.Last().Point();
236 //-----------------------------------------------------------------------------
237 // Extension : The curve is extended at the beginning and/or the end if
238 // - one of two curves is concave.
239 // - the curves have a common point at the beginning and/or the end
240 // - the angle of opening at the common point between two curves
242 // the extension at the beginning is taken into account if the origin is found above.
243 // ie : the origin is not the in the polygon.
244 //-----------------------------------------------------------------------------
246 //---------------------------------
247 // Do the extensions exist ?
248 //---------------------------------
250 extensionStart = Standard_False;
253 extensionStart = TestExtension(curve1,curve2,1);
255 extensionEnd = TestExtension(curve1,curve2,2);
258 // Calculate pointEnd.
261 pointEnd = curve1->Value(curve1->LastParameter());
264 pointEnd = myPolygon.Last().Point();
269 //------------------------------------------------------
270 // Update the Limits of intervals of definition.
271 //------------------------------------------------------
273 if (extensionStart) {
274 gp_Pnt2d P1 = myPolygon.First().Point();
275 Standard_Real UFirst = startIntervals.First() - pointStart.Distance(P1);
276 startIntervals.InsertBefore(1,UFirst);
277 endIntervals .InsertBefore(1,startIntervals.Value(2));
281 Standard_Real UFirst,ULast;
282 P1 = myPolygon.Last().Point();
283 UFirst = endIntervals.Last();
284 ULast = UFirst + pointEnd.Distance(P1);
285 startIntervals.Append(UFirst);
286 endIntervals .Append(ULast );
290 //--------------------------------------------------
291 // No polygon => the bissectrice is a segment.
292 //--------------------------------------------------
293 startIntervals.Append(0.);
294 endIntervals .Append(pointEnd.Distance(pointStart));
297 if (!YaPoly && !extensionStart && !extensionEnd)
298 isEmpty = Standard_True;
299 // modified by NIZHNY-EAP Mon Jan 17 17:32:40 2000 ___BEGIN___
300 if (myPolygon.Length() <= 2)
301 isEmpty = Standard_True;
302 // modified by NIZHNY-EAP Mon Jan 17 17:32:42 2000 ___END___
305 //=============================================================================
306 //function : IsExtendAtStart
308 //=============================================================================
309 Standard_Boolean Bisector_BisecCC::IsExtendAtStart() const
311 return extensionStart;
314 //=============================================================================
315 //function : IsExtendAtEnd
317 //=============================================================================
318 Standard_Boolean Bisector_BisecCC::IsExtendAtEnd() const
323 //=============================================================================
326 //=============================================================================
327 Standard_Boolean Bisector_BisecCC::IsEmpty() const
332 //=============================================================================
335 //=============================================================================
336 void Bisector_BisecCC::Reverse()
338 throw Standard_NotImplemented();
341 //=============================================================================
342 //function : ReversedParameter
344 //=============================================================================
345 Standard_Real Bisector_BisecCC::ReversedParameter(const Standard_Real U) const
347 return LastParameter() + FirstParameter() - U;
350 //=============================================================================
353 //=============================================================================
354 Handle(Geom2d_Geometry) Bisector_BisecCC::Copy() const
356 Handle(Geom2d_Curve) CopyCurve1
357 = Handle(Geom2d_Curve)::DownCast(curve1->Copy());
358 Handle(Geom2d_Curve) CopyCurve2
359 = Handle(Geom2d_Curve)::DownCast(curve2->Copy());
361 Handle(Bisector_BisecCC) C = new Bisector_BisecCC();
363 C -> Curve (1, CopyCurve1) ; C -> Curve (2, CopyCurve2);
364 C -> Sign (1, sign1 ) ; C -> Sign (2, sign2 );
365 C -> IsConvex (1, isConvex1) ; C -> IsConvex (2, isConvex2);
366 C -> Polygon (myPolygon);
367 C -> IsEmpty (isEmpty) ;
368 C -> DistMax (distMax) ;
369 C -> StartIntervals (startIntervals); C -> EndIntervals (endIntervals);
370 C -> ExtensionStart (extensionStart); C -> ExtensionEnd (extensionEnd);
371 C -> PointStart (pointStart) ; C -> PointEnd (pointEnd) ;
376 //=============================================================================
377 //function : ChangeGuide
378 //purpose : Changet of the guideline for the parameters of the bissectrice
379 // ATTENTION : - This can invert the direction of parameterization.
380 // - This concerns only the part of the curve
381 // corresponding to the polygon.
382 //=============================================================================
383 Handle(Bisector_BisecCC) Bisector_BisecCC::ChangeGuide() const
385 Handle(Bisector_BisecCC) C = new Bisector_BisecCC();
387 C -> Curve (1, curve2) ; C -> Curve (2, curve1);
388 C -> Sign (1, sign2 ) ; C -> Sign (2, sign1 );
389 C -> IsConvex (1, isConvex2); C -> IsConvex (2, isConvex1);
391 //-------------------------------------------------------------------------
392 // Construction of the new polygon from the initial one.
393 // inversion of PointOnBis and Calculation of new parameters on the bissectrice.
394 //-------------------------------------------------------------------------
395 Bisector_PolyBis Poly;
396 if (sign1 == sign2 ) {
397 //---------------------------------------------------------------
398 // elements of the new polygon are ranked in the other direction.
399 //---------------------------------------------------------------
400 for (Standard_Integer i = myPolygon.Length(); i >=1; i--) {
401 Bisector_PointOnBis P = myPolygon.Value(i);
402 Bisector_PointOnBis NewP (P.ParamOnC2(), P.ParamOnC1(),
403 P.ParamOnC2(), P.Distance (),
409 for (Standard_Integer i = 1; i <= myPolygon.Length(); i ++) {
410 Bisector_PointOnBis P = myPolygon.Value(i);
411 Bisector_PointOnBis NewP (P.ParamOnC2(), P.ParamOnC1(),
412 P.ParamOnC2(), P.Distance (),
418 C -> FirstParameter (Poly.First().ParamOnBis());
419 C -> LastParameter (Poly.Last() .ParamOnBis());
424 //=============================================================================
425 //function : Transform
427 //=============================================================================
428 void Bisector_BisecCC::Transform (const gp_Trsf2d& T)
430 curve1 ->Transform(T);
431 curve2 ->Transform(T);
432 myPolygon . Transform(T);
433 pointStart. Transform(T);
434 pointEnd . Transform(T);
437 //=============================================================================
440 //=============================================================================
441 Standard_Boolean Bisector_BisecCC::IsCN (const Standard_Integer N) const
443 return (curve1->IsCN(N+1) && curve2->IsCN(N+1));
446 //=============================================================================
447 //function : FirstParameter
449 //=============================================================================
450 Standard_Real Bisector_BisecCC::FirstParameter() const
452 return startIntervals.First();
455 //=============================================================================
456 //function : LastParameter
458 //=============================================================================
459 Standard_Real Bisector_BisecCC::LastParameter() const
461 return endIntervals.Last();
464 //=============================================================================
465 //function : Continuity
467 //=============================================================================
468 GeomAbs_Shape Bisector_BisecCC::Continuity() const
470 GeomAbs_Shape Cont = curve1->Continuity();
472 case GeomAbs_C1 : return GeomAbs_C0;
473 case GeomAbs_C2 : return GeomAbs_C1;
474 case GeomAbs_C3 : return GeomAbs_C2;
475 case GeomAbs_CN : return GeomAbs_CN;
481 //=============================================================================
482 //function : NbIntervals
484 //=============================================================================
485 Standard_Integer Bisector_BisecCC::NbIntervals() const
487 return startIntervals.Length();
490 //=============================================================================
491 //function : IntervalFirst
493 //=============================================================================
494 Standard_Real Bisector_BisecCC::IntervalFirst(const Standard_Integer Index) const
496 return startIntervals.Value(Index);
499 //=============================================================================
500 //function : IntervalLast
502 //=============================================================================
503 Standard_Real Bisector_BisecCC::IntervalLast(const Standard_Integer Index) const
505 return endIntervals.Value(Index);
508 //=============================================================================
509 //function : IntervalContinuity
511 //=============================================================================
512 GeomAbs_Shape Bisector_BisecCC::IntervalContinuity() const
514 GeomAbs_Shape Cont = curve1->Continuity();
516 case GeomAbs_C1 : return GeomAbs_C0;
517 case GeomAbs_C2 : return GeomAbs_C1;
518 case GeomAbs_C3 : return GeomAbs_C2;
519 case GeomAbs_CN : return GeomAbs_CN;
525 //=============================================================================
526 //function : IsClosed
528 //=============================================================================
529 Standard_Boolean Bisector_BisecCC::IsClosed() const
531 if (curve1->IsClosed()) {
532 if (startIntervals.First() == curve1->FirstParameter() &&
533 endIntervals .Last () == curve1->LastParameter () )
534 return Standard_True;
536 return Standard_False;
539 //=============================================================================
540 //function : IsPeriodic
542 //=============================================================================
543 Standard_Boolean Bisector_BisecCC::IsPeriodic() const
545 return Standard_False;
549 //=============================================================================
550 //function : Curvature
552 //=============================================================================
553 static Standard_Real Curvature (const Handle(Geom2d_Curve)& C,
561 Standard_Real Norm2 = D1.SquareMagnitude();;
566 K1 = (D1^D2)/(Norm2*sqrt(Norm2));
571 //=============================================================================
573 //purpose : CALCULATE THE CURRENT POINT BY ITERATIVE METHOD.
574 // ----------------------------------------------
575 // Calculate the current point, the distance from the current point to
576 // both curves, the parameters on each curve of the projection
577 // of the current point.
579 //method : - Find start parameter by using <myPolygon>.
580 // - Calculate parameter U2 on curve C2 solution of H(U,V)= 0
584 // ||P2(v0)P1(u)||**2
585 // F(u,v) = P1(u) - 1/2 *----------------* N(u)
586 // (N(u).P2(v0)P1(u))
588 // H(u,v) = (Tu.P1(u)P2(v))**2||Tv||**2 - (Tv.P1(u)P2(v))**2||Tu||**2
590 //=============================================================================
591 gp_Pnt2d Bisector_BisecCC::ValueAndDist (const Standard_Real U,
594 Standard_Real& Dist) const
598 //-----------------------------------------------
599 // is the polygon reduced to a point or empty?
600 //-----------------------------------------------
601 if (myPolygon.Length() <= 1) {
602 return Extension(U,U1,U2,Dist,T);
605 //-----------------------------------------------
606 // test U out of the limits of the polygon.
607 //-----------------------------------------------
608 if (U < myPolygon.First().ParamOnBis()) {
609 return Extension(U,U1,U2,Dist,T);
611 if (U > myPolygon.Last().ParamOnBis()) {
612 return Extension(U,U1,U2,Dist,T);
615 //-------------------------------------------------------
616 // Find start parameter by using <myPolygon>.
617 //-------------------------------------------------------
618 Standard_Integer IntervalIndex = myPolygon.Interval(U);
619 Standard_Real UMin = myPolygon.Value(IntervalIndex ).ParamOnBis();
620 Standard_Real UMax = myPolygon.Value(IntervalIndex + 1).ParamOnBis();
621 Standard_Real VMin = myPolygon.Value(IntervalIndex ).ParamOnC2();
622 Standard_Real VMax = myPolygon.Value(IntervalIndex + 1).ParamOnC2();
623 Standard_Real Alpha,VInit;
625 if (Abs(UMax - UMin) < gp::Resolution()) {
629 Alpha = (U - UMin)/(UMax - UMin);
630 VInit = VMin + Alpha*(VMax - VMin);
633 U1 = LinkBisCurve(U);
634 Standard_Real VTemp = Min(VMin,VMax);
635 VMax = Max(VMin,VMax); VMin = VTemp;
636 Standard_Boolean Valid = Standard_True;
637 //---------------------------------------------------------------
638 // Calculate parameter U2 on curve C2 solution of H(u,v)=0
639 //---------------------------------------------------------------
642 Standard_Real EpsH = 1.E-9;
643 Standard_Real EpsH100 = 1.E-7;
644 curve1->D1 (U1,P1,T1);
645 gp_Vec2d N1(T1.Y(), - T1.X());
647 if ((VMax - VMin) < Precision::PConfusion()) {
651 Bisector_FunctionH H (curve2,P1,sign1*sign2*T1);
653 H.Value(VInit,FInit);
654 if (Abs(FInit) < EpsH) {
659 math_BissecNewton aNewSolution(EpsH);
660 aNewSolution.Perform(H, VMin - EpsH100, VMax + EpsH100, 10);
662 if (aNewSolution.IsDone())
664 U2 = aNewSolution.Root();
668 math_FunctionRoot SolRoot (H,VInit,EpsH,VMin - EpsH100,VMax + EpsH100);
670 if (SolRoot.IsDone())
673 Valid = Standard_False;
678 gp_Pnt2d PBis = pointStart;
683 gp_Pnt2d P2 = curve2->Value(U2);
684 gp_Vec2d P2P1(P1.X() - P2.X(),P1.Y() - P2.Y());
685 Standard_Real SquareP2P1 = P2P1.SquareMagnitude();
686 Standard_Real N1P2P1 = N1.Dot(P2P1);
687 const Standard_Real anEps = Epsilon(1);
689 if (P1.IsEqual(P2,Precision::Confusion())) {
693 else if (N1P2P1*sign1 < anEps) {
694 Valid = Standard_False;
697 PBis = P1.Translated(- (0.5*SquareP2P1/N1P2P1)*N1);
698 Dist = P1.SquareDistance(PBis);
702 //----------------------------------------------------------------
703 // If the point is not valid
704 // calculate by intersection.
705 //----------------------------------------------------------------
707 //--------------------------------------------------------------------
708 // Construction of the bisectrice point curve and of the straight line passing
709 // by P1 and carried by the normal. curve2 is limited by VMin and VMax.
710 //--------------------------------------------------------------------
711 Standard_Real DMin = Precision::Infinite();
713 Handle(Bisector_BisecPC) BisPC
714 = new Bisector_BisecPC(curve2, P1, sign2, VMin, VMax);
715 Handle(Geom2d_Line) NorLi = new Geom2d_Line (P1,N1);
717 Geom2dAdaptor_Curve ABisPC(BisPC);
718 Geom2dAdaptor_Curve ANorLi(NorLi);
719 //-------------------------------------------------------------------------
720 Geom2dInt_GInter Intersect(ABisPC,ANorLi,
721 Precision::Confusion(),Precision::Confusion());
722 //-------------------------------------------------------------------------
724 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
725 for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) {
726 if (Intersect.Point(i).ParamOnSecond()*sign1 < Precision::PConfusion()) {
727 P = Intersect.Point(i).Value();
728 if (P.SquareDistance(P1) < DMin) {
729 DMin = P.SquareDistance(P1);
731 U2 = BisPC->LinkBisCurve(Intersect.Point(i).ParamOnFirst());
741 //=============================================================================
742 //function : ValueByInt
743 //purpose : CALCULATE THE CURRENT POINT BY INTERSECTION.
744 // -------------------------------------------
745 // Calculate the current point, the distance from the current point
746 // to two curves, the parameters on each curve of the projection of the
748 // the current point with parameter U is the intersection of the
749 // bissectrice point curve (P1,curve2) and of the straight line
750 // passing through P1 of director vector N1.
751 // P1 is the current point of parameter U on curve1 and N1 the
752 // normal at this point.
753 //=============================================================================
754 gp_Pnt2d Bisector_BisecCC::ValueByInt (const Standard_Real U,
757 Standard_Real& Dist) const
759 //------------------------------------------------------------------
760 // Return point, tangent, normal on C1 at parameter U.
761 //-------------------------------------------------------------------
762 U1 = LinkBisCurve(U);
764 gp_Pnt2d P1,P2,P,PSol;
766 curve1->D1(U1,P1,Tan1);
767 gp_Vec2d N1( Tan1.Y(), - Tan1.X());
769 //--------------------------------------------------------------------------
770 // test confusion of P1 with extremity of curve2.
771 //--------------------------------------------------------------------------
772 if (P1.Distance(curve2->Value(curve2->FirstParameter())) < Precision::Confusion()) {
773 U2 = curve2->FirstParameter();
774 curve2->D1(U2,P2,Tan2);
775 if ( isConvex1 && isConvex2 ) {
779 if (! Tan1.IsParallel(Tan2,Precision::Angular())) {
784 if (P1.Distance(curve2->Value(curve2->LastParameter())) < Precision::Confusion()) {
785 U2 = curve2->LastParameter();
786 curve2->D1(U2,P2,Tan2);
787 if ( isConvex1 && isConvex2 ) {
791 if (! Tan1.IsParallel(Tan2,Precision::Angular())) {
797 Standard_Boolean YaSol = Standard_False;
798 Standard_Real DMin = Precision::Infinite();
800 Standard_Real EpsMax = 1.E-6;
802 Standard_Real EpsH = 1.E-8;
803 Standard_Real DistPP1;
804 Standard_Integer NbSamples =20;
805 Standard_Real UFirstOnC2 = curve2->FirstParameter();
806 Standard_Real ULastOnC2 = curve2->LastParameter();
808 if (!myPolygon.IsEmpty()){
809 if (sign1 == sign2) { ULastOnC2 = myPolygon.Last().ParamOnC2();}
810 else { UFirstOnC2 = myPolygon.Last().ParamOnC2();}
813 if (Abs(ULastOnC2 - UFirstOnC2) < Precision::PConfusion()/100.) {
814 Dist = Precision::Infinite();
818 DiscretPar(Abs(ULastOnC2 - UFirstOnC2),EpsH,EpsMax,2,20,EpsX,NbSamples);
820 Bisector_FunctionH H (curve2,P1,sign1*sign2*Tan1);
821 math_FunctionRoots SolRoot (H,
826 if (SolRoot.IsDone()) {
827 for (Standard_Integer j = 1; j <= SolRoot.NbSolutions(); j++) {
828 USol = SolRoot.Value(j);
829 gp_Pnt2d P2Curve2 = curve2->Value(USol);
830 gp_Vec2d P2P1(P1.X() - P2Curve2.X(),P1.Y() - P2Curve2.Y());
831 Standard_Real SquareP2P1 = P2P1.SquareMagnitude();
832 Standard_Real N1P2P1 = N1.Dot(P2P1);
834 // Test if the solution is at the proper side of the curves.
835 if (N1P2P1*sign1 > 0 ) {
836 P = P1.Translated(- (0.5*SquareP2P1/N1P2P1)*N1);
837 DistPP1 = P1.SquareDistance(P);
838 if (DistPP1 < DMin) {
842 YaSol = Standard_True;
850 //--------------------------------------------------------------------
851 // Construction de la bisectrice point courbe et de la droite passant
852 // par P1 et portee par la normale.
853 //--------------------------------------------------------------------
854 Handle(Bisector_BisecPC) BisPC
855 = new Bisector_BisecPC(curve2,P1,sign2,2*distMax);
856 //-------------------------------
857 // Test si la bissectrice existe.
858 //-------------------------------
859 if (BisPC->IsEmpty()) {
860 Dist = Precision::Infinite();
865 Handle(Geom2d_Line) NorLi = new Geom2d_Line (P1,N1);
866 Geom2dAdaptor_Curve NorLiAd;
867 if (sign1 < 0.) {NorLiAd.Load(NorLi,0. ,distMax);}
868 else {NorLiAd.Load(NorLi,- distMax,0. );}
870 //-------------------------------------------------------------------------
871 Geom2dInt_GInter Intersect(BisPC,NorLiAd,
872 Precision::Confusion(),Precision::Confusion());
873 //-------------------------------------------------------------------------
874 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
875 for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) {
876 if (Intersect.Point(i).ParamOnSecond()*sign1< Precision::PConfusion()) {
877 P = Intersect.Point(i).Value();
878 DistPP1 = P.SquareDistance(P1);
879 if (DistPP1 < DMin) {
882 U2 = Intersect.Point(i).ParamOnFirst();
883 YaSol = Standard_True;
893 //--------------------------------------------------------------
894 // Point found => Test curve distance + Angular Test
895 //---------------------------------------------------------------
896 P2 = curve2->Value(U2);
897 gp_Vec2d PP1(P1.X() - PSol.X(),P1.Y() - PSol.Y());
898 gp_Vec2d PP2(P2.X() - PSol.X(),P2.Y() - PSol.Y());
900 //-----------------------------------------------
901 // Dist = product of norms = distance at the square.
902 //-----------------------------------------------
903 if (PP1.Dot(PP2) > (1. - Precision::Angular())*Dist) {
904 YaSol = Standard_False;
908 Standard_Real K1 = Curvature(curve1,U1,Precision::Confusion());
910 if (Dist > 1/(K1*K1)) YaSol = Standard_False;
915 Standard_Real K2 = Curvature(curve2,U2,Precision::Confusion());
917 if (Dist > 1/(K2*K2)) YaSol = Standard_False;
924 Dist = Precision::Infinite();
930 //=============================================================================
933 //=============================================================================
934 void Bisector_BisecCC::D0(const Standard_Real U,
937 Standard_Real U1,U2,Dist;
939 P = ValueAndDist(U,U1,U2,Dist);
942 //=============================================================================
945 //=============================================================================
946 void Bisector_BisecCC::D1(const Standard_Real U,
952 Values(U,1,P,V,V2,V3);
955 //=============================================================================
958 //=============================================================================
959 void Bisector_BisecCC::D2(const Standard_Real U,
967 Values(U,2,P,V1,V2,V3);
970 //=============================================================================
973 //=============================================================================
974 void Bisector_BisecCC::D3(const Standard_Real U,
983 Values(U,3,P,V1,V2,V3);
986 //=============================================================================
989 //=============================================================================
990 gp_Vec2d Bisector_BisecCC::DN(const Standard_Real U,
991 const Standard_Integer N) const
997 Values (U,N,P,V1,V2,V3);
1003 throw Standard_NotImplemented();
1008 //=============================================================================
1010 // purpose : the curve can be described by the following equations:
1013 // where v0 = Phi(u) is given by H (u,v) = 0.
1016 // ||P2(v0)P1(u)||**2
1017 // F(u,v) = P1(u) - 1/2 *----------------* N(u)
1018 // (N(u).P2(v0)P1(u))
1020 // H(u,v) = (Tu.P1(u)P2(v))**2||Tv||**2 - (Tv.P1(u)P2(v))**2||Tu||**2
1022 // => dB(u)/du = dF/du + dF/dv(- dH/du:dH/dv)
1024 // Note : tangent to the bisectrice is bissectrice at
1025 // tangents T1(u) and T2(v0)
1027 //=============================================================================
1028 void Bisector_BisecCC::Values (const Standard_Real U,
1029 const Standard_Integer N,
1035 V1 = gp_Vec2d(0.,0.);
1036 V2 = gp_Vec2d(0.,0.);
1037 V3 = gp_Vec2d(0.,0.);
1038 //-------------------------------------------------------------------------
1039 // Calculate the current point on the bisectrice and the parameters on each
1041 //-------------------------------------------------------------------------
1042 Standard_Real U0,V0,Dist;
1044 //-----------------------------------------------
1045 // is the polygon reduced to a point or empty?
1046 //-----------------------------------------------
1047 if (myPolygon.Length() <= 1) {
1048 P = Extension(U,U0,V0,Dist,V1);
1050 if (U < myPolygon.First().ParamOnBis()) {
1051 P = Extension(U,U0,V0,Dist,V1);
1054 if (U > myPolygon.Last().ParamOnBis()) {
1055 P = Extension(U,U0,V0,Dist,V1);
1058 P = ValueAndDist(U,U0,V0,Dist);
1061 //------------------------------------------------------------------
1062 // Return point, tangent, normal to C1 by parameter U0.
1063 //-------------------------------------------------------------------
1064 gp_Pnt2d P1 ; // point on C1.
1065 gp_Vec2d Tu ; // tangent to C1 by U0.
1066 gp_Vec2d Tuu ; // second derivative to C1 by U0.
1067 curve1->D2(U0,P1,Tu,Tuu);
1068 gp_Vec2d Nor( - Tu .Y() , Tu .X()); // Normal by U0.
1069 gp_Vec2d Nu ( - Tuu.Y() , Tuu.X()); // derivative of the normal by U0.
1071 //-------------------------------------------------------------------
1072 // Return point, tangent, normale to C2 by parameter V0.
1073 //-------------------------------------------------------------------
1074 gp_Pnt2d P2 ; // point on C2.
1075 gp_Vec2d Tv ; // tangent to C2 by V.
1076 gp_Vec2d Tvv ; // second derivative to C2 by V.
1077 curve2->D2(V0,P2,Tv,Tvv);
1079 gp_Vec2d PuPv(P2.X() - P1.X(), P2.Y() - P1.Y());
1081 //-----------------------------
1082 // Calculate dH/du and dH/dv.
1083 //-----------------------------
1084 Standard_Real TuTu,TvTv,TuTv;
1085 Standard_Real TuPuPv,TvPuPv ;
1086 Standard_Real TuuPuPv,TuTuu ;
1087 Standard_Real TvvPuPv,TvTvv ;
1089 TuTu = Tu.Dot(Tu) ; TvTv = Tv.Dot(Tv) ; TuTv = Tu.Dot(Tv);
1090 TuPuPv = Tu.Dot(PuPv) ; TvPuPv = Tv.Dot(PuPv);
1091 TuuPuPv = Tuu.Dot(PuPv) ; TuTuu = Tu.Dot(Tuu) ;
1092 TvvPuPv = Tvv.Dot(PuPv) ; TvTvv = Tv.Dot(Tvv) ;
1094 Standard_Real dHdu = 2*(TuPuPv*(TuuPuPv - TuTu)*TvTv +
1095 TvPuPv*TuTv*TuTu -TuTuu*TvPuPv*TvPuPv);
1096 Standard_Real dHdv = 2*(TuPuPv*TuTv*TvTv + TvTvv*TuPuPv*TuPuPv -
1097 TvPuPv*(TvvPuPv + TvTv)*TuTu);
1099 //-----------------------------
1100 // Calculate dF/du and dF/dv.
1101 //-----------------------------
1102 Standard_Real NorPuPv,NuPuPv,NorTv;
1103 Standard_Real A,B,dAdu,dAdv,dBdu,dBdv,BB;
1105 NorPuPv = Nor.Dot(PuPv);
1106 NuPuPv = Nu .Dot(PuPv);
1107 NorTv = Nor.Dot(Tv) ;
1109 A = 0.5*PuPv.SquareMagnitude();
1117 //---------------------------------------
1118 // F(u,v) = Pu - (A(u,v)/B(u,v))*Nor(u)
1119 //----------------------------------------
1120 if (BB < gp::Resolution()) {
1121 V1 = Tu.Normalized() + Tv.Normalized();
1122 V1 = 0.5*Tu.SquareMagnitude()*V1;
1125 gp_Vec2d dFdu = Tu - (dAdu/B - dBdu*A/BB)*Nor - (A/B)*Nu;
1126 gp_Vec2d dFdv = ( - dAdv/B + dBdv*A/BB)*Nor ;
1128 if (Abs(dHdv) > gp::Resolution()) {
1129 V1 = dFdu + dFdv*( - dHdu / dHdv );
1138 //=============================================================================
1139 //function : Extension
1140 // purpose : Calculate the current point on the extensions
1141 // by tangence of the curve.
1142 //============================================================================
1143 gp_Pnt2d Bisector_BisecCC::Extension (const Standard_Real U,
1146 Standard_Real& Dist,
1149 Bisector_PointOnBis PRef;
1150 gp_Pnt2d P,P1,P2,PBis;
1152 Standard_Real dU = 0.;
1153 Standard_Boolean ExtensionTangent = Standard_False;
1155 if (myPolygon.Length() == 0) {
1156 //---------------------------------------------
1157 // Empty Polygon => segment (pointStart,pointEnd)
1158 //---------------------------------------------
1159 dU = U - startIntervals.First();
1162 U1 = curve1->LastParameter();
1163 if (sign1 == sign2) { U2 = curve2->FirstParameter();}
1164 else { U2 = curve2->LastParameter() ;}
1165 Tang.SetCoord(P1.X() - P.X(),P1.Y() - P.Y());
1167 else if (U < myPolygon.First().ParamOnBis()) {
1168 PRef = myPolygon.First();
1170 dU = U - PRef.ParamOnBis();
1171 if (extensionStart) {
1172 //------------------------------------------------------------
1173 // extension = segment (pointstart, first point of the polygon.)
1174 //------------------------------------------------------------
1176 U1 = curve1->FirstParameter();
1177 if (sign1 == sign2) { U2 = curve2->LastParameter();}
1178 else { U2 = curve2->FirstParameter();}
1179 Tang.SetCoord(P.X() - P1.X(),P.Y() - P1.Y());
1182 ExtensionTangent = Standard_True;
1185 else if (U > myPolygon.Last().ParamOnBis()) {
1186 PRef = myPolygon.Last();
1188 dU = U - PRef.ParamOnBis();
1190 //------------------------------------------------------------
1191 // extension = segment (last point of the polygon.pointEnd)
1192 //------------------------------------------------------------
1194 U1 = curve1->LastParameter();
1195 if (sign1 == sign2) { U2 = curve2->LastParameter();}
1196 else { U2 = curve2->FirstParameter();}
1197 Tang.SetCoord(P1.X() - P.X(),P1.Y() - P.Y());
1200 ExtensionTangent = Standard_True;
1204 if (ExtensionTangent) {
1205 //-----------------------------------------------------------
1206 // If the la curve has no a extension, it is extended by tangency
1207 //------------------------------------------------------------
1208 U1 = PRef.ParamOnC1();
1209 U2 = PRef.ParamOnC2();
1210 P2 = curve2->Value(U2);
1211 curve1->D1(U1,P1,T1);
1212 Tang.SetCoord(2*P.X() - P1.X() - P2.X(), 2*P.Y() - P1.Y() - P2.Y());
1213 if (Tang.Magnitude() < Precision::Confusion()) {
1216 if (T1.Dot(Tang) < 0.) Tang = - Tang;
1219 T = Tang.Normalized();
1220 PBis.SetCoord(P.X() + dU*T.X(),P.Y() + dU*T.Y());
1221 Dist = P1.Distance(PBis);
1225 //=============================================================================
1226 //function : PointByInt
1228 //=============================================================================
1229 static Standard_Boolean PointByInt(const Handle(Geom2d_Curve)& CA,
1230 const Handle(Geom2d_Curve)& CB,
1231 const Standard_Real SignA,
1232 const Standard_Real SignB,
1233 const Standard_Real UOnA,
1234 Standard_Real& UOnB,
1235 Standard_Real& Dist)
1237 //------------------------------------------------------------------
1238 // Return point,tangent, normal on CA with parameter UOnA.
1239 //-------------------------------------------------------------------
1240 gp_Pnt2d P1,P2,P,PSol;
1242 Standard_Boolean IsConvexA = Bisector::IsConvex(CA,SignA);
1243 Standard_Boolean IsConvexB = Bisector::IsConvex(CB,SignB);
1245 CA->D1(UOnA,P1,Tan1);
1246 gp_Vec2d N1(Tan1.Y(), - Tan1.X());
1248 //--------------------------------------------------------------------------
1249 // test of confusion of P1 with extremity of curve2.
1250 //--------------------------------------------------------------------------
1251 if (P1.Distance(CB->Value(CB->FirstParameter())) < Precision::Confusion()) {
1252 UOnB = CB->FirstParameter();
1253 CB->D1(UOnB,P2,Tan2);
1254 if ( IsConvexA && IsConvexB ) {
1256 return Standard_True;
1258 if (! Tan1.IsParallel(Tan2,Precision::Angular())) {
1260 return Standard_False;
1263 if (P1.Distance(CB->Value(CB->LastParameter())) < Precision::Confusion()) {
1264 UOnB = CB->LastParameter();
1265 CB->D1(UOnB,P2,Tan2);
1266 if ( IsConvexA && IsConvexB ) {
1268 return Standard_True;
1270 if (! Tan1.IsParallel(Tan2,Precision::Angular())) {
1272 return Standard_False;
1276 Standard_Real DMin = Precision::Infinite();
1278 Standard_Boolean YaSol = Standard_False;
1279 //--------------------------------------------------------------------
1280 // Construction of the bisectrice point curve and of the straight line passing
1281 // through P1 and carried by the normal.
1282 //--------------------------------------------------------------------
1283 Handle(Bisector_BisecPC) BisPC
1284 = new Bisector_BisecPC(CB,P1,SignB );
1285 //-------------------------------
1286 // Test if the bissectrice exists.
1287 //-------------------------------
1288 if (BisPC->IsEmpty()) {
1289 Dist = Precision::Infinite();
1291 return Standard_False;
1294 Handle(Geom2d_Line) NorLi = new Geom2d_Line (P1,N1);
1296 Geom2dAdaptor_Curve ABisPC(BisPC);
1297 Geom2dAdaptor_Curve ANorLi(NorLi);
1298 //-------------------------------------------------------------------------
1299 Geom2dInt_GInter Intersect(ABisPC,ANorLi,
1300 Precision::Confusion(),Precision::Confusion());
1301 //-------------------------------------------------------------------------
1303 if (Intersect.IsDone() && !Intersect.IsEmpty()) {
1304 for (Standard_Integer i = 1; i <= Intersect.NbPoints(); i++) {
1305 if (Intersect.Point(i).ParamOnSecond()*SignA < Precision::PConfusion()) {
1306 P = Intersect.Point(i).Value();
1307 if (P.SquareDistance(P1) < DMin) {
1308 DMin = P.SquareDistance(P1);
1310 UPC = Intersect.Point(i).ParamOnFirst();
1311 UOnB = BisPC->LinkBisCurve(UPC);
1313 YaSol = Standard_True;
1319 //--------------------------------------------------------------
1320 // Point found => Test distance curvature + Angular test
1321 //---------------------------------------------------------------
1322 P2 = CB->Value(UOnB);
1323 if(P1.SquareDistance(PSol) < 1.e-32)
1325 YaSol = Standard_False;
1328 if(P2.SquareDistance(PSol) < 1.e-32)
1330 YaSol = Standard_False;
1334 gp_Dir2d PP1Unit(P1.X() - PSol.X(),P1.Y() - PSol.Y());
1335 gp_Dir2d PP2Unit(P2.X() - PSol.X(),P2.Y() - PSol.Y());
1337 if (PP1Unit*PP2Unit > 1. - Precision::Angular()) {
1338 YaSol = Standard_False;
1343 Standard_Real K1 = Curvature(CA,UOnA,Precision::Confusion());
1345 if (Dist > Abs(1/K1)) YaSol = Standard_False;
1350 Standard_Real K2 = Curvature(CB,UOnB,Precision::Confusion());
1352 if (Dist > Abs(1/K2)) YaSol = Standard_False;
1361 //=============================================================================
1362 //function : SupLastParameter
1364 //=============================================================================
1365 void Bisector_BisecCC::SupLastParameter()
1367 endIntervals.Append(curve1->LastParameter());
1368 // ----------------------------------------------------------------------
1369 // Calculate parameter on curve1 associated to one or the other of the extremities
1370 // of curve2 following the values of sign1 and sign2.
1371 // the bissectrice is limited by the obtained parameters.
1372 //------------------------------------------------------------------------
1373 Standard_Real UOnC1,UOnC2,Dist;
1374 if (sign1 == sign2) {
1375 UOnC2 = curve2->FirstParameter();
1378 UOnC2 = curve2->LastParameter();
1380 Standard_Boolean YaSol = PointByInt(curve2,curve1,sign2,sign1,UOnC2,UOnC1,Dist);
1382 if (UOnC1 > startIntervals.First() && UOnC1 < endIntervals.Last()) {
1383 endIntervals.SetValue(1,UOnC1);
1388 //=============================================================================
1391 //=============================================================================
1392 Handle(Geom2d_Curve) Bisector_BisecCC::Curve(const Standard_Integer I) const
1394 if (I == 1) return curve1;
1395 else if (I == 2) return curve2;
1396 else throw Standard_OutOfRange();
1399 //=============================================================================
1400 //function : LinkBisCurve
1402 //=============================================================================
1403 Standard_Real Bisector_BisecCC::LinkBisCurve(const Standard_Real U) const
1405 return (U - shiftParameter);
1408 //=============================================================================
1409 //function : LinkCurveBis
1411 //=============================================================================
1412 Standard_Real Bisector_BisecCC::LinkCurveBis(const Standard_Real U) const
1414 return (U + shiftParameter);
1417 //=============================================================================
1420 //=============================================================================
1421 static void Indent(const Standard_Integer Offset) {
1423 for (Standard_Integer i = 0; i < Offset; i++) {cout << " ";}
1427 //=============================================================================
1428 //function : Polygon
1430 //=============================================================================
1431 const Bisector_PolyBis& Bisector_BisecCC::Polygon() const
1436 //==========================================================================
1437 //function : Parameter
1439 //==========================================================================
1440 Standard_Real Bisector_BisecCC::Parameter(const gp_Pnt2d& P) const
1442 Standard_Real UOnCurve;
1444 if (P.IsEqual(Value(FirstParameter()),Precision::Confusion())) {
1445 UOnCurve = FirstParameter();
1447 else if (P.IsEqual(Value(LastParameter()),Precision::Confusion())) {
1448 UOnCurve = LastParameter();
1452 ProjOnCurve(P, curve1, UOnCurve);
1459 //=============================================================================
1462 //=============================================================================
1463 //void Bisector_BisecCC::Dump(const Standard_Integer Deep,
1464 void Bisector_BisecCC::Dump(const Standard_Integer ,
1465 const Standard_Integer Offset) const
1468 cout <<"Bisector_BisecCC :"<<endl;
1470 // cout <<"Curve1 :"<<curve1<<endl;
1471 // cout <<"Curve2 :"<<curve2<<endl;
1472 cout <<"Sign1 :"<<sign1<<endl;
1473 cout <<"Sign2 :"<<sign2<<endl;
1475 cout <<"Number Of Intervals :"<<startIntervals.Length()<<endl;
1476 for (Standard_Integer i = 1; i <= startIntervals.Length(); i++) {
1477 cout <<"Interval number :"<<i<<"Start :"<<startIntervals.Value(i)
1478 <<" end :"<< endIntervals.Value(i)<<endl ;
1480 cout <<"Index Current Interval :"<<currentInterval<<endl;
1483 //=============================================================================
1486 //=============================================================================
1487 void Bisector_BisecCC::Curve(const Standard_Integer I,
1488 const Handle(Geom2d_Curve)& C)
1490 if (I == 1) curve1 = C;
1491 else if (I == 2) curve2 = C;
1492 else throw Standard_OutOfRange();
1495 //=============================================================================
1498 //=============================================================================
1499 void Bisector_BisecCC::Sign(const Standard_Integer I,
1500 const Standard_Real S)
1502 if (I == 1) sign1 = S;
1503 else if (I == 2) sign2 = S;
1504 else throw Standard_OutOfRange();
1507 //=============================================================================
1508 //function : Polygon
1510 //=============================================================================
1511 void Bisector_BisecCC::Polygon(const Bisector_PolyBis& P)
1516 //=============================================================================
1517 //function : DistMax
1519 //=============================================================================
1520 void Bisector_BisecCC::DistMax(const Standard_Real D)
1525 //=============================================================================
1526 //function : IsConvex
1528 //=============================================================================
1529 void Bisector_BisecCC::IsConvex(const Standard_Integer I,
1530 const Standard_Boolean IsConvex)
1532 if (I == 1) isConvex1 = IsConvex;
1533 else if (I == 2) isConvex2 = IsConvex;
1534 else throw Standard_OutOfRange();
1537 //=============================================================================
1538 //function : IsEmpty
1540 //=============================================================================
1541 void Bisector_BisecCC::IsEmpty ( const Standard_Boolean IsEmpty)
1546 //=============================================================================
1547 //function : ExtensionStart
1549 //=============================================================================
1550 void Bisector_BisecCC::ExtensionStart( const Standard_Boolean ExtensionStart)
1552 extensionStart = ExtensionStart;
1555 //=============================================================================
1556 //function : ExtensionEnd
1558 //=============================================================================
1559 void Bisector_BisecCC::ExtensionEnd( const Standard_Boolean ExtensionEnd)
1561 extensionEnd = ExtensionEnd;
1564 //=============================================================================
1565 //function : PointStart
1567 //=============================================================================
1568 void Bisector_BisecCC::PointStart( const gp_Pnt2d& Point)
1573 //=============================================================================
1574 //function : PointEnd
1576 //=============================================================================
1577 void Bisector_BisecCC::PointEnd( const gp_Pnt2d& Point)
1582 //=============================================================================
1583 //function : StartIntervals
1585 //=============================================================================
1586 void Bisector_BisecCC::StartIntervals
1587 (const TColStd_SequenceOfReal& StartIntervals)
1589 startIntervals = StartIntervals;
1592 //=============================================================================
1593 //function : EndIntervals
1595 //=============================================================================
1596 void Bisector_BisecCC::EndIntervals
1597 (const TColStd_SequenceOfReal& EndIntervals)
1599 endIntervals = EndIntervals;
1602 //=============================================================================
1603 //function : FirstParameter
1605 //=============================================================================
1606 void Bisector_BisecCC::FirstParameter (const Standard_Real U)
1608 startIntervals.Append(U);
1611 //=============================================================================
1612 //function : LastParameter
1614 //=============================================================================
1615 void Bisector_BisecCC::LastParameter (const Standard_Real U)
1617 endIntervals.Append(U);
1620 //=============================================================================
1621 //function : SearchBound
1623 //=============================================================================
1624 Standard_Real Bisector_BisecCC::SearchBound (const Standard_Real U1,
1625 const Standard_Real U2) const
1627 Standard_Real UMid,Dist1,Dist2,DistMid,U11,U22;
1628 Standard_Real UC1,UC2;
1629 gp_Pnt2d PBis,PBisPrec;
1630 Standard_Real TolPnt = Precision::Confusion();
1631 Standard_Real TolPar = Precision::PConfusion();
1633 PBisPrec = ValueByInt(U11,UC1,UC2,Dist1);
1634 PBis = ValueByInt(U22,UC1,UC2,Dist2);
1636 while ((U22 - U11) > TolPar ||
1637 ((Dist1 < Precision::Infinite() &&
1638 Dist2 < Precision::Infinite() &&
1639 !PBis.IsEqual(PBisPrec,TolPnt)))) {
1641 UMid = 0.5*( U22 + U11);
1642 PBis = ValueByInt(UMid,UC1,UC2,DistMid);
1643 if ((Dist1 < Precision::Infinite()) == (DistMid < Precision::Infinite())) {
1652 PBis = ValueByInt(U11,UC1,UC2,Dist1);
1653 if (Dist1 < Precision::Infinite()) {
1662 //=============================================================================
1663 //function : ProjOnCurve
1665 //=============================================================================
1666 static Standard_Boolean ProjOnCurve (const gp_Pnt2d& P,
1667 const Handle(Geom2d_Curve)& C,
1668 Standard_Real& theParam)
1670 //Standard_Real UOnCurve =0.;
1675 C->D1(C->FirstParameter(),PF,TF);
1676 C->D1(C->LastParameter() ,PL,TL);
1678 if (P.IsEqual(PF ,Precision::Confusion()))
1680 theParam = C->FirstParameter();
1681 return Standard_True;
1684 if (P.IsEqual(PL ,Precision::Confusion()))
1686 theParam = C->LastParameter();
1687 return Standard_True;
1690 gp_Vec2d PPF(PF.X() - P.X(), PF.Y() - P.Y());
1693 if ( Abs (PPF.Dot(TF)) < Precision::Confusion())
1695 theParam = C->FirstParameter();
1696 return Standard_True;
1698 gp_Vec2d PPL (PL.X() - P.X(), PL.Y() - P.Y());
1700 if ( Abs (PPL.Dot(TL)) < Precision::Confusion())
1702 theParam = C->LastParameter();
1703 return Standard_True;
1705 Geom2dAPI_ProjectPointOnCurve Proj(P,C,
1706 C->FirstParameter(),
1707 C->LastParameter());
1708 if (Proj.NbPoints() > 0) {
1709 theParam = Proj.LowerDistanceParameter();
1712 return Standard_False;
1715 return Standard_True;
1718 //=============================================================================
1719 //function : TestExtension
1721 //=============================================================================
1722 static Standard_Boolean TestExtension (const Handle(Geom2d_Curve)& C1,
1723 const Handle(Geom2d_Curve)& C2,
1724 const Standard_Integer Start_End)
1728 Standard_Boolean Test = Standard_False;
1729 if (Start_End == 1) {
1730 C1->D1(C1->FirstParameter(),P1,T1);
1733 C1->D1(C1->LastParameter(),P1,T1);
1735 C2->D1(C2->FirstParameter(),P2,T2);
1736 if (P1.IsEqual(P2,Precision::Confusion())) {
1737 T1.Normalize(); T2.Normalize();
1738 if (T1.Dot(T2) > 1.0 - Precision::Confusion()) {
1739 Test = Standard_True;
1743 C2->D1(C2->LastParameter(),P2,T2);
1744 if (P1.IsEqual(P2,Precision::Confusion())) {
1746 if (T1.Dot(T2) > 1.0 - Precision::Confusion()) {
1747 Test = Standard_True;
1754 //=============================================================================
1755 //function : ComputePointEnd
1757 //=============================================================================
1758 void Bisector_BisecCC::ComputePointEnd ()
1760 Standard_Real U1,U2;
1761 Standard_Real KC,RC;
1762 U1 = curve1->FirstParameter();
1763 if (sign1 == sign2) {
1764 U2 = curve2->LastParameter();
1767 U2 = curve2->FirstParameter();
1769 Standard_Real K1 = Curvature(curve1,U1,Precision::Confusion());
1770 Standard_Real K2 = Curvature(curve2,U2,Precision::Confusion());
1771 if (!isConvex1 && !isConvex2) {
1772 if (K1 < K2) {KC = K1;} else {KC = K2;}
1774 else if (!isConvex1) {KC = K1;}
1779 curve1->D1(U1,PF,TF);
1781 if (KC != 0.) { RC = Abs(1/KC);}
1782 else { RC = Precision::Infinite();}
1783 pointEnd.SetCoord(PF.X() - sign1*RC*TF.Y(), PF.Y() + sign1*RC*TF.X());
1787 //=============================================================================
1788 //function : DiscretPar
1790 //=============================================================================
1791 static Standard_Boolean DiscretPar(const Standard_Real DU,
1792 const Standard_Real EpsMin,
1793 const Standard_Real EpsMax,
1794 const Standard_Integer NbMin,
1795 const Standard_Integer NbMax,
1797 Standard_Integer& Nb)
1799 if (DU <= NbMin*EpsMin) {
1800 Eps = DU/(NbMin + 1) ;
1802 return Standard_False;
1805 Eps = Min (EpsMax,DU/NbMax);
1809 Nb = Standard_Integer(DU/EpsMin);
1813 return Standard_True;