1 // Copyright (c) 1996-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #include <Adaptor2d_Curve2d.hxx>
17 #include <Bnd_Box2d.hxx>
18 #include <BndLib_Add2dCurve.hxx>
19 #include <Geom2d_BezierCurve.hxx>
20 #include <Geom2d_BSplineCurve.hxx>
21 #include <Geom2d_Circle.hxx>
22 #include <Geom2d_Conic.hxx>
23 #include <Geom2d_Curve.hxx>
24 #include <Geom2d_Ellipse.hxx>
25 #include <Geom2d_Geometry.hxx>
26 #include <Geom2d_Hyperbola.hxx>
27 #include <Geom2d_Line.hxx>
28 #include <Geom2d_OffsetCurve.hxx>
29 #include <Geom2d_Parabola.hxx>
30 #include <Geom2d_TrimmedCurve.hxx>
31 #include <Geom2dAdaptor_Curve.hxx>
33 #include <Precision.hxx>
34 #include <Standard_Type.hxx>
35 #include <math_MultipleVarFunction.hxx>
36 #include <math_Function.hxx>
37 #include <math_BrentMinimum.hxx>
38 #include <math_PSO.hxx>
40 //=======================================================================
41 //function : BndLib_Box2dCurve
43 //=======================================================================
44 class BndLib_Box2dCurve {
48 virtual ~BndLib_Box2dCurve();
50 void SetCurve(const Handle(Geom2d_Curve)& aC);
52 const Handle(Geom2d_Curve)& Curve() const;
54 void SetRange(const Standard_Real aT1,
55 const Standard_Real aT2);
57 void Range(Standard_Real& aT1,
58 Standard_Real& aT2) const;
60 const Bnd_Box2d& Box() const;
64 void PerformOptimal(const Standard_Real Tol);
68 Standard_Integer ErrorStatus() const;
70 //-----------------------------
74 void PerformLineConic();
76 void PerformBSpline();
78 void D0(const Standard_Real, gp_Pnt2d&);
80 void Compute(const Handle(Geom2d_Conic)&,
81 const GeomAbs_CurveType,
87 Standard_Integer Compute(const Handle(Geom2d_Conic)&,
88 const GeomAbs_CurveType,
91 Standard_Boolean IsTypeBase(const Handle(Geom2d_Curve)& ,
94 Standard_Real AdjustToPeriod(const Standard_Real ,
95 const Standard_Real );
97 void PerformOnePoint();
99 void PerformGenCurv(const Standard_Real Tol = Precision::PConfusion());
101 Standard_Integer NbSamples();
103 Standard_Real AdjustExtr(const Standard_Real UMin,
104 const Standard_Real UMax,
105 const Standard_Real Extr0,
106 const Standard_Integer CoordIndx,
107 const Standard_Real Tol,
108 const Standard_Boolean IsMin);
109 //-----------------------------
111 Handle(Geom2d_Curve) myCurve;
113 Standard_Integer myErrorStatus;
114 Handle(Geom2d_Curve) myCurveBase;
115 Standard_Real myOffsetBase;
116 Standard_Boolean myOffsetFlag;
119 GeomAbs_CurveType myTypeBase;
122 class Curv2dMaxMinCoordMVar : public math_MultipleVarFunction
125 Curv2dMaxMinCoordMVar(const Handle(Geom2d_Curve)& theCurve,
126 const Standard_Real UMin,
127 const Standard_Real UMax,
128 const Standard_Integer CoordIndx,
129 const Standard_Real Sign)
133 myCoordIndx(CoordIndx),
138 Standard_Boolean Value (const math_Vector& X,
141 if (!CheckInputData(X(1)))
143 return Standard_False;
145 gp_Pnt2d aP = myCurve->Value(X(1));
147 F = mySign * aP.Coord(myCoordIndx);
149 return Standard_True;
154 Standard_Integer NbVariables() const
160 Curv2dMaxMinCoordMVar & operator = (const Curv2dMaxMinCoordMVar & theOther);
162 Standard_Boolean CheckInputData(Standard_Real theParam)
164 if (theParam < myUMin ||
166 return Standard_False;
167 return Standard_True;
170 const Handle(Geom2d_Curve)& myCurve;
171 Standard_Real myUMin;
172 Standard_Real myUMax;
173 Standard_Integer myCoordIndx;
174 Standard_Real mySign;
177 class Curv2dMaxMinCoord : public math_Function
180 Curv2dMaxMinCoord(const Handle(Geom2d_Curve)& theCurve,
181 const Standard_Real UMin,
182 const Standard_Real UMax,
183 const Standard_Integer CoordIndx,
184 const Standard_Real Sign)
188 myCoordIndx(CoordIndx),
193 Standard_Boolean Value (const Standard_Real X,
196 if (!CheckInputData(X))
198 return Standard_False;
200 gp_Pnt2d aP = myCurve->Value(X);
202 F = mySign * aP.Coord(myCoordIndx);
204 return Standard_True;
208 Curv2dMaxMinCoord & operator = (const Curv2dMaxMinCoord & theOther);
210 Standard_Boolean CheckInputData(Standard_Real theParam)
212 if (theParam < myUMin ||
214 return Standard_False;
215 return Standard_True;
218 const Handle(Geom2d_Curve)& myCurve;
219 Standard_Real myUMin;
220 Standard_Real myUMax;
221 Standard_Integer myCoordIndx;
222 Standard_Real mySign;
225 //=======================================================================
228 //=======================================================================
229 BndLib_Box2dCurve::BndLib_Box2dCurve()
233 //=======================================================================
236 //=======================================================================
237 BndLib_Box2dCurve::~BndLib_Box2dCurve()
240 //=======================================================================
243 //=======================================================================
244 void BndLib_Box2dCurve::Clear()
249 myTypeBase=GeomAbs_OtherCurve;
251 myOffsetFlag=Standard_False;
253 //=======================================================================
254 //function : SetCurve
256 //=======================================================================
257 void BndLib_Box2dCurve::SetCurve(const Handle(Geom2d_Curve)& aC2D)
261 //=======================================================================
264 //=======================================================================
265 const Handle(Geom2d_Curve)& BndLib_Box2dCurve::Curve()const
269 //=======================================================================
270 //function : SetRange
272 //=======================================================================
273 void BndLib_Box2dCurve::SetRange(const Standard_Real aT1,
274 const Standard_Real aT2)
279 //=======================================================================
282 //=======================================================================
283 void BndLib_Box2dCurve::Range(Standard_Real& aT1,
284 Standard_Real& aT2) const
289 //=======================================================================
290 //function : ErrorStatus
292 //=======================================================================
293 Standard_Integer BndLib_Box2dCurve::ErrorStatus()const
295 return myErrorStatus;
297 //=======================================================================
300 //=======================================================================
301 const Bnd_Box2d& BndLib_Box2dCurve::Box()const
305 //=======================================================================
306 //function : CheckData
308 //=======================================================================
309 void BndLib_Box2dCurve::CheckData()
313 if(myCurve.IsNull()) {
319 myErrorStatus=12; // invalid range
323 //=======================================================================
326 //=======================================================================
327 void BndLib_Box2dCurve::Perform()
348 if (myTypeBase==GeomAbs_Line ||
349 myTypeBase==GeomAbs_Circle ||
350 myTypeBase==GeomAbs_Ellipse ||
351 myTypeBase==GeomAbs_Parabola ||
352 myTypeBase==GeomAbs_Hyperbola) { // LineConic
355 else if (myTypeBase==GeomAbs_BezierCurve) { // Bezier
358 else if (myTypeBase==GeomAbs_BSplineCurve) { //B-Spline
362 myErrorStatus=11; // unknown type base
365 //=======================================================================
366 //function : PerformOptimal
368 //=======================================================================
369 void BndLib_Box2dCurve::PerformOptimal(const Standard_Real Tol)
389 if (myTypeBase==GeomAbs_Line ||
390 myTypeBase==GeomAbs_Circle ||
391 myTypeBase==GeomAbs_Ellipse ||
392 myTypeBase==GeomAbs_Parabola ||
393 myTypeBase==GeomAbs_Hyperbola) { // LineConic
400 //=======================================================================
401 //function : PerformOnePoint
403 //=======================================================================
404 void BndLib_Box2dCurve::PerformOnePoint()
408 myCurve->D0(myT1, aP2D);
411 //=======================================================================
412 //function : PerformBezier
414 //=======================================================================
415 void BndLib_Box2dCurve::PerformBezier()
422 Standard_Integer i, aNbPoles;
423 Standard_Real aT1, aT2, aTb[2];
425 Handle(Geom2d_Geometry) aG;
426 Handle(Geom2d_BezierCurve) aCBz, aCBzSeg;
429 Bnd_Box2d& aBox2D=myBox;
431 aCBz=Handle(Geom2d_BezierCurve)::DownCast(myCurveBase);
432 aT1=aCBz->FirstParameter();
433 aT2=aCBz->LastParameter();
445 if (!(aT1==aTb[0] && aT2==aTb[1])) {
448 aCBzSeg=Handle(Geom2d_BezierCurve)::DownCast(aG);
449 aCBzSeg->Segment(aTb[0], aTb[1]);
453 aNbPoles=aCBz->NbPoles();
454 for (i=1; i<=aNbPoles; ++i) {
459 //=======================================================================
460 //function : PerformBSpline
462 //=======================================================================
463 void BndLib_Box2dCurve::PerformBSpline()
470 Standard_Integer i, aNbPoles;
471 Standard_Real aT1, aT2, aTb[2];
473 Handle(Geom2d_Geometry) aG;
474 Handle(Geom2d_BSplineCurve) aCBS, aCBSs;
477 Bnd_Box2d& aBox2D=myBox;
479 aCBS=Handle(Geom2d_BSplineCurve)::DownCast(myCurveBase);
480 aT1=aCBS->FirstParameter();
481 aT2=aCBS->LastParameter();
499 const Standard_Real eps = Precision::PConfusion();
500 if (fabs(aT1-aTb[0]) > eps || fabs(aT2-aTb[1]) > eps) {
503 aCBSs=Handle(Geom2d_BSplineCurve)::DownCast(aG);
504 aCBSs->Segment(aTb[0], aTb[1]);
508 aNbPoles=aCBS->NbPoles();
509 for (i=1; i<=aNbPoles; ++i) {
514 //=======================================================================
515 //function : PerformOther
517 //=======================================================================
518 void BndLib_Box2dCurve::PerformOther()
520 Standard_Integer j, aNb;
521 Standard_Real aT, dT;
525 dT=(myT2-myT1)/(aNb-1);
528 for (j=0; j<aNb; ++j) {
530 myCurve->D0(aT, aP2D);
533 myCurve->D0(myT2, aP2D);
536 //=======================================================================
537 //function : NbSamples
539 //=======================================================================
540 Standard_Integer BndLib_Box2dCurve::NbSamples()
543 switch (myTypeBase) {
544 case GeomAbs_BezierCurve:
546 Handle(Geom2d_BezierCurve) aCBz=Handle(Geom2d_BezierCurve)::DownCast(myCurveBase);
548 //By default parametric range of Bezier curv is [0, 1]
549 Standard_Real du = myT2 - myT1;
552 N = RealToInt(du*N) + 1;
557 case GeomAbs_BSplineCurve:
559 Handle(Geom2d_BSplineCurve) aCBS=Handle(Geom2d_BSplineCurve)::DownCast(myCurveBase);
560 N = (aCBS->Degree() + 1)*(aCBS->NbKnots() -1);
561 Standard_Real umin = aCBS->FirstParameter(),
562 umax = aCBS->LastParameter();
563 Standard_Real du = (myT2 - myT1) / (umax - umin);
566 N = RealToInt(du*N) + 1;
576 //=======================================================================
577 //function : AdjustExtr
579 //=======================================================================
580 Standard_Real BndLib_Box2dCurve::AdjustExtr(const Standard_Real UMin,
581 const Standard_Real UMax,
582 const Standard_Real Extr0,
583 const Standard_Integer CoordIndx,
584 const Standard_Real Tol,
585 const Standard_Boolean IsMin)
587 Standard_Real aSign = IsMin ? 1.:-1.;
588 Standard_Real extr = aSign * Extr0;
590 Standard_Real Du = (myCurve->LastParameter() - myCurve->FirstParameter());
592 Geom2dAdaptor_Curve aGAC(myCurve);
593 Standard_Real UTol = Max(aGAC.Resolution(Tol), Precision::PConfusion());
594 Standard_Real reltol = UTol / Max(Abs(UMin), Abs(UMax));
595 if(UMax - UMin < 0.01 * Du)
597 //It is suggested that function has one extremum on small interval
598 math_BrentMinimum anOptLoc(reltol, 100, UTol);
599 Curv2dMaxMinCoord aFunc(myCurve, UMin, UMax, CoordIndx, aSign);
600 anOptLoc.Perform(aFunc, UMin, (UMin+UMax)/2., UMax);
601 if(anOptLoc.IsDone())
603 extr = anOptLoc.Minimum();
608 Standard_Integer aNbParticles = Max(8, RealToInt(32 * (UMax - UMin) / Du));
609 Standard_Real maxstep = (UMax - UMin) / (aNbParticles + 1);
611 math_Vector aLowBorder(1,1);
612 math_Vector aUppBorder(1,1);
613 math_Vector aSteps(1,1);
614 aLowBorder(1) = UMin;
615 aUppBorder(1) = UMax;
616 aSteps(1) = Min(0.1 * Du, maxstep);
618 Curv2dMaxMinCoordMVar aFunc(myCurve, UMin, UMax, CoordIndx, aSign);
619 math_PSO aFinder(&aFunc, aLowBorder, aUppBorder, aSteps, aNbParticles);
620 aFinder.Perform(aSteps, extr, aT);
622 math_BrentMinimum anOptLoc(reltol, 100, UTol);
623 Curv2dMaxMinCoord aFunc1(myCurve, UMin, UMax, CoordIndx, aSign);
624 anOptLoc.Perform(aFunc1, Max(aT(1) - aSteps(1), UMin), aT(1), Min(aT(1) + aSteps(1), UMax));
626 if(anOptLoc.IsDone())
628 extr = anOptLoc.Minimum();
635 //=======================================================================
636 //function : PerformGenCurv
638 //=======================================================================
639 void BndLib_Box2dCurve::PerformGenCurv(const Standard_Real Tol)
642 Standard_Integer Nu = NbSamples();
644 Standard_Real CoordMin[2] = {RealLast(), RealLast()};
645 Standard_Real CoordMax[2] = {-RealLast(), -RealLast()};
646 Standard_Real DeflMax[2] = {-RealLast(), -RealLast()};
649 Standard_Integer i, k;
650 Standard_Real du = (myT2 - myT1)/(Nu-1), du2 = du / 2.;
651 NCollection_Array1<gp_XY> aPnts(1, Nu);
653 for (i = 1, u = myT1; i <= Nu; i++, u += du)
658 for(k = 0; k < 2; ++k)
660 if(CoordMin[k] > P.Coord(k+1))
662 CoordMin[k] = P.Coord(k+1);
664 if(CoordMax[k] < P.Coord(k+1))
666 CoordMax[k] = P.Coord(k+1);
672 gp_XY aPm = 0.5 * (aPnts(i-1) + aPnts(i));
674 gp_XY aD = (P.XY() - aPm);
675 for(k = 0; k < 2; ++k)
677 if(CoordMin[k] > P.Coord(k+1))
679 CoordMin[k] = P.Coord(k+1);
681 if(CoordMax[k] < P.Coord(k+1))
683 CoordMax[k] = P.Coord(k+1);
685 Standard_Real d = Abs(aD.Coord(k+1));
695 for(k = 0; k < 2; ++k)
697 Standard_Real d = DeflMax[k];
702 Standard_Real CMin = CoordMin[k];
703 Standard_Real CMax = CoordMax[k];
704 for(i = 1; i <= Nu; ++i)
706 if(aPnts(i).Coord(k+1) - CMin < d)
708 Standard_Real tmin, tmax;
709 tmin = myT1 + Max(0, i-2) * du;
710 tmax = myT1 + Min(Nu-1, i) * du;
711 Standard_Real cmin = AdjustExtr(tmin, tmax,
712 CMin, k + 1, Tol, Standard_True);
718 else if(CMax - aPnts(i).Coord(k+1) < d)
720 Standard_Real tmin, tmax;
721 tmin = myT1 + Max(0, i-2) * du;
722 tmax = myT1 + Min(Nu-1, i) * du;
723 Standard_Real cmax = AdjustExtr(tmin, tmax,
724 CMax, k + 1, Tol, Standard_False);
735 myBox.Add(gp_Pnt2d(CoordMin[0], CoordMin[1]));
736 myBox.Add(gp_Pnt2d(CoordMax[0], CoordMax[1]));
739 //=======================================================================
742 //=======================================================================
743 void BndLib_Box2dCurve::D0(const Standard_Real aU,
748 myCurveBase->D1(aU, aP2D, aV1);
751 Standard_Integer aIndex, aMaxDegree;
752 Standard_Real aA, aB, aR, aRes;
756 aRes=gp::Resolution();
758 while (aV1.Magnitude() <= aRes && aIndex <= aMaxDegree) {
759 aV1=myCurveBase->DN(aU, aIndex);
765 aR=sqrt(aA*aA+aB*aB);
774 aP2D.SetCoord(aP2D.X()+aA, aP2D.Y()+aB);
778 //=======================================================================
779 //function : GetInfoBase
781 //=======================================================================
782 void BndLib_Box2dCurve::GetInfoBase()
784 Standard_Boolean bIsTypeBase;
785 Standard_Integer iTrimmed, iOffset;
786 GeomAbs_CurveType aTypeB;
787 Handle(Geom2d_Curve) aC2DB;
788 Handle(Geom2d_TrimmedCurve) aCT2D;
789 Handle(Geom2d_OffsetCurve) aCF2D;
792 myTypeBase=GeomAbs_OtherCurve;
796 bIsTypeBase=IsTypeBase(aC2DB, aTypeB);
803 while(!bIsTypeBase) {
806 aCT2D=Handle(Geom2d_TrimmedCurve)::DownCast(aC2DB);
807 if (!aCT2D.IsNull()) {
808 aC2DB=aCT2D->BasisCurve();
812 aCF2D=Handle(Geom2d_OffsetCurve)::DownCast(aC2DB);
813 if (!aCF2D.IsNull()) {
814 Standard_Real aOffset;
816 aOffset=aCF2D->Offset();
817 myOffsetBase=myOffsetBase+aOffset;
818 myOffsetFlag=Standard_True;
820 aC2DB=aCF2D->BasisCurve();
824 if (!(iTrimmed || iOffset)) {
828 bIsTypeBase=IsTypeBase(aC2DB, aTypeB);
836 myErrorStatus=11; // unknown type base
838 //=======================================================================
839 //function : IsTypeBase
841 //=======================================================================
842 Standard_Boolean BndLib_Box2dCurve::IsTypeBase
843 (const Handle(Geom2d_Curve)& aC2D,
844 GeomAbs_CurveType& aTypeB)
846 Standard_Boolean bRet;
847 Handle(Standard_Type) aType;
851 aType=aC2D->DynamicType();
852 if (aType==STANDARD_TYPE(Geom2d_Line)) {
855 else if (aType==STANDARD_TYPE(Geom2d_Circle)) {
856 aTypeB=GeomAbs_Circle;
858 else if (aType==STANDARD_TYPE(Geom2d_Ellipse)) {
859 aTypeB=GeomAbs_Ellipse;
861 else if (aType==STANDARD_TYPE(Geom2d_Parabola)) {
862 aTypeB=GeomAbs_Parabola;
864 else if (aType==STANDARD_TYPE(Geom2d_Hyperbola)) {
865 aTypeB=GeomAbs_Hyperbola;
867 else if (aType==STANDARD_TYPE(Geom2d_BezierCurve)) {
868 aTypeB=GeomAbs_BezierCurve;
870 else if (aType==STANDARD_TYPE(Geom2d_BSplineCurve)) {
871 aTypeB=GeomAbs_BSplineCurve;
874 aTypeB=GeomAbs_OtherCurve;
879 //=======================================================================
880 //function : PerformLineConic
882 //=======================================================================
883 void BndLib_Box2dCurve::PerformLineConic()
885 Standard_Integer i, iInf[2];
886 Standard_Real aTb[2];
891 Bnd_Box2d& aBox2D=myBox;
898 for (i=0; i<2; ++i) {
899 if (Precision::IsNegativeInfinite(aTb[i])) {
904 else if (Precision::IsPositiveInfinite(aTb[i])) {
915 if (myTypeBase==GeomAbs_Line) {
919 if (iInf[0] && iInf[1]) {
923 Handle(Geom2d_Conic) aConic2D;
925 aConic2D=Handle(Geom2d_Conic)::DownCast(myCurveBase);
926 Compute(aConic2D, myTypeBase, aTb[0], aTb[1], aBox2D);
929 //=======================================================================
932 //=======================================================================
933 void BndLib_Box2dCurve::Compute(const Handle(Geom2d_Conic)& aConic2D,
934 const GeomAbs_CurveType aType,
935 const Standard_Real aT1,
936 const Standard_Real aT2,
939 Standard_Integer i, aNbT;
940 Standard_Real pT[10], aT, aTwoPI, dT, aEps;
943 aNbT=Compute(aConic2D, aType, pT);
945 if (aType==GeomAbs_Parabola || aType==GeomAbs_Hyperbola) {
946 for (i=0; i<aNbT; ++i) {
948 if (aT>aT1 && aT<aT2) {
956 //aType==GeomAbs_Circle || aType==GeomAbs_Ellipse
961 Standard_Real aT1z = AdjustToPeriod (aT1, aTwoPI);
962 if (fabs(aT1z)<aEps) {
966 Standard_Real aT2z = aT1z + dT;
967 if (fabs(aT2z-aTwoPI)<aEps) {
971 for (i=0; i<aNbT; ++i) {
973 // adjust aT to range [aT1z, aT1z + 2*PI]; note that pT[i] and aT1z
974 // are adjusted to range [0, 2*PI], but aT2z can be greater than 2*PI
975 aT = (aT < aT1z ? aT + aTwoPI : aT);
983 //=======================================================================
986 //=======================================================================
987 Standard_Integer BndLib_Box2dCurve::Compute
988 (const Handle(Geom2d_Conic)& aConic2D,
989 const GeomAbs_CurveType aType,
992 Standard_Integer iRet, i, j;
993 Standard_Real aCosBt, aSinBt, aCosGm, aSinGm;
994 Standard_Real aLx, aLy;
998 const gp_Ax22d& aPos=aConic2D->Position();
999 const gp_XY& aXDir=aPos.XDirection().XY();
1000 const gp_XY& aYDir=aPos.YDirection().XY();
1007 if (aType==GeomAbs_Circle || aType==GeomAbs_Ellipse) {
1008 Standard_Real aR1 = 0.0, aR2 = 0.0, aTwoPI = M_PI+M_PI;
1009 Standard_Real aA11 = 0.0, aA12 = 0.0, aA21 = 0.0, aA22 = 0.0;
1010 Standard_Real aBx = 0.0, aBy = 0.0, aB = 0.0, aCosFi = 0.0, aSinFi = 0.0, aFi = 0.0;
1012 if(aType==GeomAbs_Ellipse) {
1013 Handle(Geom2d_Ellipse) aEL2D;
1015 aEL2D=Handle(Geom2d_Ellipse)::DownCast(aConic2D);
1016 aR1=aEL2D->MajorRadius();
1017 aR2=aEL2D->MinorRadius();
1019 else if(aType==GeomAbs_Circle) {
1020 Handle(Geom2d_Circle) aCR2D;
1022 aCR2D=Handle(Geom2d_Circle)::DownCast(aConic2D);
1023 aR1=aCR2D->Radius();
1032 for (i=0; i<2; ++i) {
1035 aBx=aLx*aA21-aLy*aA11;
1036 aBy=aLx*aA22-aLy*aA12;
1037 aB=sqrt(aBx*aBx+aBy*aBy);
1049 pT[j]=AdjustToPeriod(pT[j], aTwoPI);
1052 pT[j+1]=AdjustToPeriod(pT[j+1], aTwoPI);
1055 }//if (aType==GeomAbs_Ellipse) {
1057 else if (aType==GeomAbs_Parabola) {
1058 Standard_Real aFc, aEps;
1059 Standard_Real aA1, aA2;
1060 Handle(Geom2d_Parabola) aPR2D;
1064 aPR2D=Handle(Geom2d_Parabola)::DownCast(aConic2D);
1068 for (i=0; i<2; i++) {
1072 aA2=aLx*aSinBt-aLy*aCosBt;
1073 if (fabs(aA2)<aEps) {
1077 aA1=aLy*aCosGm-aLx*aSinGm;
1079 pT[j]=2.*aFc*aA1/aA2;
1083 }// else if (aType==GeomAbs_Parabola) {
1085 else if (aType==GeomAbs_Hyperbola) {
1087 Standard_Real aR1, aR2;
1088 Standard_Real aEps, aB1, aB2, aB12, aB22, aZ, aD;
1089 Handle(Geom2d_Hyperbola) aHP2D;
1093 aHP2D=Handle(Geom2d_Hyperbola)::DownCast(aConic2D);
1094 aR1=aHP2D->MajorRadius();
1095 aR2=aHP2D->MinorRadius();
1098 for (i=0; i<2; i++) {
1102 aB1=aR1*(aLx*aSinBt-aLy*aCosBt);
1103 aB2=aR2*(aLx*aSinGm-aLy*aCosGm);
1105 if (fabs(aB1)<aEps) {
1109 if (fabs(aB2)<aEps) {
1122 for (k=-1; k<2; k+=2) {
1125 pT[j]=-log((1.+aZ)/(1.-aZ));
1132 }// else if (aType==GeomAbs_Hyperbola) {
1136 //=======================================================================
1137 //function : AdjustToPeriod
1139 //=======================================================================
1140 Standard_Real BndLib_Box2dCurve::AdjustToPeriod(const Standard_Real aT,
1141 const Standard_Real aPeriod)
1144 Standard_Real aTRet;
1148 k=1+(Standard_Integer)(-aT/aPeriod);
1151 else if (aT>aPeriod) {
1152 k=(Standard_Integer)(aT/aPeriod);
1155 if (aTRet==aPeriod) {
1163 // -1 - object is just initialized
1164 // 10 - myCurve is Null
1165 // 12 - invalid range myT1 > myT2l
1166 // 11 - unknown type of base curve
1167 // 13 - offset curve can not be computed
1170 //=======================================================================
1173 //=======================================================================
1174 void BndLib_Add2dCurve::Add(const Adaptor2d_Curve2d& aC,
1175 const Standard_Real aTol,
1178 BndLib_Add2dCurve::Add(aC,
1179 aC.FirstParameter(),
1180 aC.LastParameter (),
1184 //=======================================================================
1187 //=======================================================================
1188 void BndLib_Add2dCurve::Add(const Adaptor2d_Curve2d& aC,
1189 const Standard_Real aU1,
1190 const Standard_Real aU2,
1191 const Standard_Real aTol,
1194 Adaptor2d_Curve2d *pC=(Adaptor2d_Curve2d *)&aC;
1195 Geom2dAdaptor_Curve *pA=dynamic_cast<Geom2dAdaptor_Curve*>(pC);
1197 Standard_Real U, DU;
1198 Standard_Integer N, j;
1202 DU = (aU2-aU1)/(N-1);
1203 for (j=1; j<N; j++) {
1210 aBox2D.Enlarge(aTol);
1214 const Handle(Geom2d_Curve)& aC2D=pA->Curve();
1216 BndLib_Add2dCurve::Add(aC2D, aU1, aU2, aTol, aBox2D);
1218 //=======================================================================
1221 //=======================================================================
1222 void BndLib_Add2dCurve::Add(const Handle(Geom2d_Curve)& aC2D,
1223 const Standard_Real aTol,
1226 Standard_Real aT1, aT2;
1228 aT1=aC2D->FirstParameter();
1229 aT2=aC2D->LastParameter();
1231 BndLib_Add2dCurve::Add(aC2D, aT1, aT2, aTol, aBox2D);
1234 //=======================================================================
1237 //=======================================================================
1238 void BndLib_Add2dCurve::Add(const Handle(Geom2d_Curve)& aC2D,
1239 const Standard_Real aT1,
1240 const Standard_Real aT2,
1241 const Standard_Real aTol,
1244 BndLib_Box2dCurve aBC;
1247 aBC.SetRange(aT1, aT2);
1251 const Bnd_Box2d& aBoxC=aBC.Box();
1253 aBox2D.Enlarge(aTol);
1255 //=======================================================================
1256 //function : AddOptimal
1258 //=======================================================================
1259 void BndLib_Add2dCurve::AddOptimal(const Handle(Geom2d_Curve)& aC2D,
1260 const Standard_Real aT1,
1261 const Standard_Real aT2,
1262 const Standard_Real aTol,
1265 BndLib_Box2dCurve aBC;
1268 aBC.SetRange(aT1, aT2);
1270 aBC.PerformOptimal(aTol);
1272 const Bnd_Box2d& aBoxC=aBC.Box();
1274 aBox2D.Enlarge(aTol);