Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/opencascade/Extrema_GExtPC.gxx is written in an unsupported language. File is not indexed.

0001 // Created on: 1992-10-19
0002 // Created by: Laurent PAINNOT
0003 // Copyright (c) 1992-1999 Matra Datavision
0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0005 //
0006 // This file is part of Open CASCADE Technology software library.
0007 //
0008 // This library is free software; you can redistribute it and/or modify it under
0009 // the terms of the GNU Lesser General Public License version 2.1 as published
0010 // by the Free Software Foundation, with special exception defined in the file
0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0012 // distribution for complete text of the license and disclaimer of any warranty.
0013 //
0014 // Alternatively, this file may be used under the terms of Open CASCADE
0015 // commercial license or contractual agreement.
0016 
0017 // Modified by cma, Fri Dec 10 18:11:56 1993
0018 
0019 #include Extrema_EPC_hxx
0020 #include ThePOnC_hxx
0021 #include TheSequenceOfPOnC_hxx
0022 #include ThePoint_hxx
0023 #include TheVector_hxx
0024 #include TheExtPElC_hxx
0025 #include <StdFail_NotDone.hxx>
0026 #include <Standard_Failure.hxx>
0027 #include <GeomAbs_CurveType.hxx>
0028 #include <Precision.hxx>
0029 #include <ElCLib.hxx>
0030 #include <TColStd_Array1OfReal.hxx>
0031 #include <TColStd_HArray1OfReal.hxx>
0032 #include <NCollection_Array1.hxx>
0033 
0034 
0035 //=======================================================================
0036 //function : Perform
0037 //purpose  : 
0038 //=======================================================================
0039 void Extrema_GExtPC::Perform(const ThePoint& P)
0040 {
0041   mySqDist.Clear();
0042   mypoint.Clear();
0043   myismin.Clear();
0044   Standard_Integer i, NbExt, n;                     
0045   Standard_Real U;
0046   mysample = 17;
0047   Standard_Real t3d = Precision::Confusion();
0048   if (Precision::IsInfinite(myuinf)) mydist1 = RealLast();
0049   else {
0050     Pf = TheCurveTool::Value(*((TheCurve*)myC), myuinf);
0051     mydist1 = P.SquareDistance(Pf);
0052   }
0053   
0054   if (Precision::IsInfinite(myusup)) mydist2 = RealLast();
0055   else {
0056     Pl = TheCurveTool::Value(*((TheCurve*)myC), myusup);
0057     mydist2 = P.SquareDistance(Pl);
0058   }
0059 
0060   TheCurve & aCurve = *((TheCurve*)myC);
0061 
0062   switch(type) {
0063   case GeomAbs_Circle: 
0064     {
0065       myExtPElC.Perform(P, TheCurveTool::Circle(aCurve), t3d, myuinf, myusup);
0066     }
0067     break;
0068   case GeomAbs_Ellipse: 
0069     {
0070       myExtPElC.Perform(P, TheCurveTool::Ellipse(aCurve), t3d, myuinf, myusup);
0071     }
0072     break;
0073   case GeomAbs_Parabola: 
0074     {
0075       myExtPElC.Perform(P, TheCurveTool::Parabola(aCurve), t3d,myuinf,myusup);
0076     }
0077     break;
0078   case GeomAbs_Hyperbola: 
0079     {
0080       myExtPElC.Perform(P,TheCurveTool::Hyperbola(aCurve),t3d, myuinf, myusup);
0081     }
0082     break;
0083   case GeomAbs_Line: 
0084     {
0085       myExtPElC.Perform(P, TheCurveTool::Line(aCurve), t3d, myuinf, myusup);
0086     }
0087     break;
0088   case GeomAbs_BezierCurve:
0089     {
0090       myintuinf = myuinf;
0091       myintusup = myusup;
0092       mysample = (TheCurveTool::Bezier(aCurve))->NbPoles() * 2;
0093       myExtPC.Initialize(aCurve);
0094       IntervalPerform(P);
0095       return;
0096     }
0097   case GeomAbs_BSplineCurve: 
0098     {
0099       const Standard_Integer 
0100         aFirstIdx = TheCurveTool::BSpline(aCurve)->FirstUKnotIndex(),
0101         aLastIdx  = TheCurveTool::BSpline(aCurve)->LastUKnotIndex();
0102       // const reference can not be used due to implementation of BRep_Adaptor.
0103       TColStd_Array1OfReal aKnots(aFirstIdx, aLastIdx);
0104       TheCurveTool::BSpline(aCurve)->Knots(aKnots); 
0105 
0106       // Workaround to work with:
0107       // blend, where knots may be moved from parameter space.
0108       Standard_Real aPeriodJump = 0.0;
0109       // Avoid problem with too close knots.
0110       const Standard_Real aTolCoeff = (myusup - myuinf) * Precision::PConfusion();
0111       if (TheCurveTool::IsPeriodic(aCurve))
0112       {
0113         Standard_Integer aPeriodShift =
0114           Standard_Integer ((myuinf - aKnots(aFirstIdx)) / TheCurveTool::Period(aCurve));
0115         
0116         if (myuinf < aKnots(aFirstIdx) - aTolCoeff)
0117           aPeriodShift--;
0118 
0119         aPeriodJump = TheCurveTool::Period(aCurve) * aPeriodShift;
0120       }
0121 
0122       Standard_Integer anIdx;
0123 
0124       // Find first and last used knot.
0125       Standard_Integer aFirstUsedKnot = aFirstIdx,
0126                         aLastUsedKnot = aLastIdx;
0127       for(anIdx = aFirstIdx; anIdx <= aLastIdx; anIdx++)
0128       {
0129         Standard_Real aKnot = aKnots(anIdx) + aPeriodJump;
0130         if (myuinf >= aKnot - aTolCoeff)
0131           aFirstUsedKnot = anIdx;
0132         else
0133           break;
0134 
0135       }
0136       for(anIdx = aLastIdx; anIdx >= aFirstIdx; anIdx--)
0137       {
0138         Standard_Real aKnot = aKnots(anIdx) + aPeriodJump;
0139         if (myusup <= aKnot + aTolCoeff)
0140           aLastUsedKnot = anIdx;
0141         else
0142           break;
0143       }
0144 
0145       if (aFirstUsedKnot == aLastUsedKnot)
0146       {
0147         // Degenerated case:
0148         // Some bounds lies out of curve param space.
0149         // In this case build one interval with [myuinf, myusup].
0150         // Parameters of these indexes will be redefined.
0151         aFirstUsedKnot = aFirstIdx;
0152         aLastUsedKnot  = aFirstIdx + 1;
0153       }
0154 
0155       mysample = (TheCurveTool::BSpline(aCurve))->Degree() + 1;
0156 
0157       if (mysample == 2)
0158       {
0159         //BSpline of first degree, direct searching extrema for each knot interval
0160         ThePoint aPmin;
0161         Standard_Real tmin = 0., distmin = RealLast();
0162         Standard_Real aMin1 = 0., aMin2 = 0.;
0163         myExtPC.Initialize(aCurve);
0164         for (anIdx = aFirstUsedKnot; anIdx < aLastUsedKnot; anIdx++)
0165         {
0166           Standard_Real aF = aKnots(anIdx) + aPeriodJump,
0167             aL = aKnots(anIdx + 1) + aPeriodJump;
0168 
0169           if (anIdx == aFirstUsedKnot)
0170           {
0171             aF = myuinf;
0172           }
0173           else
0174           if (anIdx == aLastUsedKnot - 1)
0175           {
0176             aL = myusup;
0177           }
0178 
0179 
0180           ThePoint aP1, aP2;
0181           TheCurveTool::D0(aCurve, aF, aP1);
0182           TheCurveTool::D0(aCurve, aL, aP2);
0183           TheVector aBase1(P, aP1), aBase2(P, aP2);
0184           TheVector aV(aP2, aP1);
0185           Standard_Real aVal1 = aV.Dot(aBase1); // Derivative of (C(u) - P)^2
0186           Standard_Real aVal2 = aV.Dot(aBase2); // Derivative of (C(u) - P)^2
0187           if (anIdx == aFirstUsedKnot)
0188           {
0189             aMin1 = P.SquareDistance(aP1);
0190           }
0191           else
0192           {
0193             aMin1 = aMin2;          
0194             if (distmin > aMin1)
0195             {
0196               distmin = aMin1;
0197               tmin = aF;
0198               aPmin = aP1;
0199             }
0200           }
0201           aMin2 = P.SquareDistance(aP2);
0202           Standard_Real aMinSqDist = Min(aMin1, aMin2);
0203           Standard_Real aMinDer = Min(Abs(aVal1), Abs(aVal2));
0204           if (!(Precision::IsInfinite(aVal1) || Precision::IsInfinite(aVal2)))
0205           {
0206             // Derivatives have opposite signs - min or max inside of interval (sufficient condition).
0207             if (aVal1 * aVal2 <= 0.0 ||
0208                 aMinSqDist < 100. * Precision::SquareConfusion() ||
0209                 2.*aMinDer < Precision::Confusion())
0210             {
0211               myintuinf = aF;
0212               myintusup = aL;
0213               IntervalPerform(P);
0214             }
0215           }
0216         }
0217         if (!Precision::IsInfinite(distmin))
0218         {
0219           Standard_Boolean isToAdd = Standard_True;
0220           NbExt = mypoint.Length();
0221           for (i = 1; i <= NbExt && isToAdd; i++)
0222           {
0223             Standard_Real t = mypoint.Value(i).Parameter();
0224             isToAdd = (distmin < mySqDist(i)) && (Abs(t - tmin) > mytolu);
0225           }
0226           if (isToAdd)
0227           {
0228             ThePOnC PC(tmin, aPmin);
0229             mySqDist.Append(distmin);
0230             myismin.Append(Standard_True);
0231             mypoint.Append(PC);
0232           }
0233         }
0234       }
0235       else
0236       {
0237 
0238         // Fill sample points.
0239         Standard_Integer aValIdx = 1;
0240         NCollection_Array1<Standard_Real> aVal(1, (mysample)* (aLastUsedKnot - aFirstUsedKnot) + 1);
0241         NCollection_Array1<Standard_Real> aParam(1, (mysample)* (aLastUsedKnot - aFirstUsedKnot) + 1);
0242         for (anIdx = aFirstUsedKnot; anIdx < aLastUsedKnot; anIdx++)
0243         {
0244           Standard_Real aF = aKnots(anIdx) + aPeriodJump,
0245             aL = aKnots(anIdx + 1) + aPeriodJump;
0246 
0247           if (anIdx == aFirstUsedKnot)
0248             aF = myuinf;
0249           if (anIdx == aLastUsedKnot - 1)
0250             aL = myusup;
0251 
0252           Standard_Real aStep = (aL - aF) / mysample;
0253           for (Standard_Integer aPntIdx = 0; aPntIdx < mysample; aPntIdx++)
0254           {
0255             Standard_Real aCurrentParam = aF + aStep * aPntIdx;
0256             aVal(aValIdx) = TheCurveTool::Value(aCurve, aCurrentParam).SquareDistance(P);
0257             aParam(aValIdx) = aCurrentParam;
0258             aValIdx++;
0259           }
0260         }
0261         // Fill last point.
0262         aVal(aValIdx) = TheCurveTool::Value(aCurve, myusup).SquareDistance(P);
0263         aParam(aValIdx) = myusup;
0264 
0265         myExtPC.Initialize(aCurve);
0266 
0267         // Find extremas.
0268         for (anIdx = aVal.Lower() + 1; anIdx < aVal.Upper(); anIdx++)
0269         {
0270           if (aVal(anIdx) <= Precision::SquareConfusion())
0271           {
0272             mySqDist.Append(aVal(anIdx));
0273             myismin.Append(Standard_True);
0274             mypoint.Append(ThePOnC(aParam(anIdx), TheCurveTool::Value(aCurve, aParam(anIdx))));
0275           }
0276           if ((aVal(anIdx) >= aVal(anIdx + 1) &&
0277             aVal(anIdx) >= aVal(anIdx - 1)) ||
0278             (aVal(anIdx) <= aVal(anIdx + 1) &&
0279             aVal(anIdx) <= aVal(anIdx - 1)))
0280           {
0281             myintuinf = aParam(anIdx - 1);
0282             myintusup = aParam(anIdx + 1);
0283 
0284             IntervalPerform(P);
0285           }
0286         }
0287 
0288         // Solve on the first and last intervals.
0289         if (mydist1 > Precision::SquareConfusion() && !Precision::IsPositiveInfinite(mydist1))
0290         {
0291           ThePoint aP1, aP2;
0292           TheVector aV1, aV2;
0293           TheCurveTool::D1(aCurve, aParam.Value(aParam.Lower()), aP1, aV1);
0294           TheCurveTool::D1(aCurve, aParam.Value(aParam.Lower() + 1), aP2, aV2);
0295           TheVector aBase1(P, aP1), aBase2(P, aP2);
0296           Standard_Real aVal1 = aV1.Dot(aBase1); // Derivative of (C(u) - P)^2
0297           Standard_Real aVal2 = aV2.Dot(aBase2); // Derivative of (C(u) - P)^2
0298           if (!(Precision::IsInfinite(aVal1) || Precision::IsInfinite(aVal2)))
0299           {
0300             // Derivatives have opposite signs - min or max inside of interval (sufficient condition).
0301             // Necessary condition - when point lies on curve.
0302             // Necessary condition - when derivative of point is too small.
0303             if (aVal1 * aVal2 <= 0.0 ||
0304               aBase1.Dot(aBase2) <= 0.0 ||
0305               2.0 * Abs(aVal1) < Precision::Confusion())
0306             {
0307               myintuinf = aParam(aVal.Lower());
0308               myintusup = aParam(aVal.Lower() + 1);
0309               IntervalPerform(P);
0310             }
0311           }
0312         }
0313 
0314         if (mydist2 > Precision::SquareConfusion() && !Precision::IsPositiveInfinite(mydist2))
0315         {
0316           ThePoint aP1, aP2;
0317           TheVector aV1, aV2;
0318           TheCurveTool::D1(aCurve, aParam.Value(aParam.Upper() - 1), aP1, aV1);
0319           TheCurveTool::D1(aCurve, aParam.Value(aParam.Upper()), aP2, aV2);
0320           TheVector aBase1(P, aP1), aBase2(P, aP2);
0321           Standard_Real aVal1 = aV1.Dot(aBase1); // Derivative of (C(u) - P)^2
0322           Standard_Real aVal2 = aV2.Dot(aBase2); // Derivative of (C(u) - P)^2
0323 
0324           if (!(Precision::IsInfinite(aVal1) || Precision::IsInfinite(aVal2)))
0325           {
0326             // Derivatives have opposite signs - min or max inside of interval (sufficient condition).
0327             // Necessary condition - when point lies on curve.
0328             // Necessary condition - when derivative of point is too small.
0329             if (aVal1 * aVal2 <= 0.0 ||
0330               aBase1.Dot(aBase2) <= 0.0 ||
0331               2.0 * Abs(aVal2) < Precision::Confusion())
0332             {
0333               myintuinf = aParam(aVal.Upper() - 1);
0334               myintusup = aParam(aVal.Upper());
0335               IntervalPerform(P);
0336             }
0337           }
0338         }
0339       }
0340       mydone = Standard_True;
0341       break;
0342     }
0343   default:
0344     {
0345       const Standard_Integer aMaxSample = 17;
0346       Standard_Boolean IntExtIsDone = Standard_False;
0347       Standard_Boolean IntIsNotValid;
0348       Handle(TColStd_HArray1OfReal) theHInter;
0349       n = TheCurveTool::NbIntervals(aCurve, GeomAbs_C2);
0350       if (n > 1)
0351       {
0352         theHInter = new TColStd_HArray1OfReal(1, n + 1);
0353         TheCurveTool::Intervals(aCurve, theHInter->ChangeArray1(), GeomAbs_C2);
0354       }
0355       else
0356       {
0357         theHInter = TheCurveTool::DeflCurvIntervals(aCurve);
0358         n = theHInter->Length() - 1;
0359       }
0360       mysample = Max(mysample / n, aMaxSample);
0361       Standard_Real maxint = 0.;
0362       for (i = 1; i <= n; ++i)
0363       {
0364         Standard_Real dt = theHInter->Value(i + 1) - theHInter->Value(i);
0365         if (maxint < dt)
0366         {
0367           maxint = dt;
0368         }
0369       }
0370       Standard_Boolean isPeriodic = TheCurveTool::IsPeriodic(aCurve);
0371       TheVector V1;
0372       ThePoint PP;
0373       Standard_Real s1 = 0.0 ;
0374       Standard_Real s2 = 0.0;
0375       myExtPC.Initialize(aCurve);
0376       for (i = 1; i <= n; i++)
0377       {
0378         myintuinf = theHInter->Value(i);
0379         myintusup = theHInter->Value(i+1);
0380         mysample = Max(RealToInt(aMaxSample*(myintusup - myintuinf) / maxint), 3);
0381         
0382         Standard_Real anInfToCheck = myintuinf;
0383         Standard_Real aSupToCheck = myintusup;
0384         
0385         if (isPeriodic) {
0386           Standard_Real aPeriod = TheCurveTool::Period(aCurve);
0387           anInfToCheck = ElCLib::InPeriod(myintuinf, myuinf, myuinf+aPeriod);
0388           aSupToCheck = myintusup+(anInfToCheck-myintuinf);
0389         }    
0390         IntIsNotValid = (myuinf > aSupToCheck) || (myusup < anInfToCheck);
0391 
0392         if(IntIsNotValid) continue;
0393 
0394         if (myuinf >= anInfToCheck) anInfToCheck = myuinf;
0395         if (myusup <= aSupToCheck) aSupToCheck = myusup;
0396         if((aSupToCheck - anInfToCheck) <= mytolu) continue;
0397         
0398         if (i != 1)
0399           {
0400           TheCurveTool::D1(aCurve, myintuinf, PP, V1);
0401           s1 = (TheVector(P, PP))*V1;
0402           if (s1*s2 < 0.0) {
0403             mySqDist.Append(PP.SquareDistance(P));
0404             myismin.Append((s1 < 0.0));
0405             mypoint.Append(ThePOnC(myintuinf, PP));
0406           }
0407         }
0408         if (i != n) {
0409           TheCurveTool::D1(aCurve, myintusup, PP, V1);
0410           s2 = (TheVector(P, PP))*V1;
0411         }
0412 
0413         IntervalPerform(P);
0414         IntExtIsDone = IntExtIsDone || mydone;
0415       }
0416 
0417       mydone = IntExtIsDone;
0418       break;
0419     }
0420   }
0421 
0422   // Postprocessing.
0423   if (type == GeomAbs_BSplineCurve ||
0424       type == GeomAbs_OffsetCurve ||
0425       type == GeomAbs_OtherCurve)
0426   {
0427     // Additional checking if the point is on the first or last point of the curve
0428     // and does not added yet.
0429     if (mydist1 < Precision::SquareConfusion() || 
0430         mydist2 < Precision::SquareConfusion())
0431     {
0432       Standard_Boolean isFirstAdded = Standard_False;
0433       Standard_Boolean isLastAdded  = Standard_False;
0434       Standard_Integer aNbPoints = mypoint.Length();
0435       for (i = 1; i <= aNbPoints; i++)
0436       {
0437         U = mypoint.Value(i).Parameter();
0438         if (Abs(U - myuinf) < mytolu)
0439           isFirstAdded = Standard_True;
0440         else if (Abs(myusup - U) < mytolu)
0441           isLastAdded = Standard_True;
0442       }
0443       if (!isFirstAdded && mydist1 < Precision::SquareConfusion())
0444       {
0445         mySqDist.Prepend(mydist1);
0446         myismin.Prepend(Standard_True);
0447         mypoint.Prepend(ThePOnC(myuinf, Pf));
0448       }
0449       if (!isLastAdded && mydist2 < Precision::SquareConfusion())
0450       {
0451         mySqDist.Append(mydist2);
0452         myismin.Append(Standard_True);
0453         mypoint.Append(ThePOnC(myusup, Pl));
0454       }
0455       mydone = Standard_True;
0456     }
0457   }
0458   else
0459   {
0460     // In analytical case
0461     mydone = myExtPElC.IsDone();
0462     if (mydone)
0463     {
0464       NbExt = myExtPElC.NbExt();
0465       for (i = 1; i <= NbExt; i++)
0466       {
0467         // Verification de la validite des parametres:
0468         ThePOnC PC = myExtPElC.Point(i);
0469         U = PC.Parameter();
0470         if (TheCurveTool::IsPeriodic(aCurve))
0471         {
0472           U = ElCLib::InPeriod(U, myuinf, myuinf+TheCurveTool::Period(aCurve));
0473         }
0474         if ((U >= myuinf-mytolu) && (U <= myusup+mytolu))
0475         {
0476           PC.SetValues(U, myExtPElC.Point(i).Value());
0477           mySqDist.Append(myExtPElC.SquareDistance(i));
0478           myismin.Append(myExtPElC.IsMin(i));
0479           mypoint.Append(PC);
0480         }
0481       }
0482     }
0483   }
0484 }
0485 
0486 
0487 //=======================================================================
0488 //function : Initialize
0489 //purpose  : 
0490 //=======================================================================
0491 
0492 void Extrema_GExtPC::Initialize(const TheCurve&     C,
0493                                 const Standard_Real Uinf,
0494                                 const Standard_Real Usup,
0495                                 const Standard_Real TolF) 
0496 {
0497   myC = (Standard_Address)&C;
0498   myintuinf = myuinf = Uinf;
0499   myintusup = myusup = Usup;
0500   mytolf = TolF;
0501   mytolu = TheCurveTool::Resolution(*((TheCurve*)myC), Precision::Confusion());
0502   type = TheCurveTool::GetType(C);
0503   mydone = Standard_False;
0504   mydist1 = RealLast();
0505   mydist2 = RealLast();
0506   mysample = 17;
0507 }
0508 
0509 
0510 //=======================================================================
0511 //function : IntervalPerform
0512 //purpose  : 
0513 //=======================================================================
0514 
0515 void Extrema_GExtPC::IntervalPerform(const ThePoint& P)
0516 {
0517   Standard_Integer i;
0518   Standard_Real U;
0519   myExtPC.Initialize(mysample, myintuinf, myintusup, mytolu, mytolf);
0520   myExtPC.Perform(P);
0521   mydone = myExtPC.IsDone();
0522   if (mydone)
0523   {
0524     Standard_Integer NbExt = myExtPC.NbExt();
0525     for (i = 1; i <= NbExt; i++)
0526     {
0527       // Verification de la validite des parametres pour le cas trimme:
0528       ThePOnC PC = myExtPC.Point(i);
0529       U = PC.Parameter();
0530       if (TheCurveTool::IsPeriodic(*((TheCurve*)myC)))
0531       {
0532         U = ElCLib::InPeriod(U, myuinf, myuinf+TheCurveTool::Period(*((TheCurve*)myC)));
0533       }
0534       if ((U >= myuinf - mytolu) && (U <= myusup + mytolu))
0535       {
0536         AddSol(U, PC.Value(),
0537                myExtPC.SquareDistance(i),
0538                myExtPC.IsMin(i));
0539       }
0540     }
0541   }
0542 }
0543 
0544 
0545 //=======================================================================
0546 //function : AddSol
0547 //purpose  : 
0548 //=======================================================================
0549 
0550 void Extrema_GExtPC::AddSol(const Standard_Real theU, const ThePoint& theP,
0551                             const Standard_Real theSqDist, 
0552                             const Standard_Boolean isMin)
0553 {
0554   Standard_Integer i, NbExt = mypoint.Length();
0555   for (i = 1; i <= NbExt; i++)
0556   {
0557     Standard_Real t = mypoint.Value(i).Parameter();
0558     if (Abs(t - theU) <= mytolu)
0559     {
0560       return;
0561     }
0562   }
0563   ThePOnC PC(theU, theP);
0564   mySqDist.Append(theSqDist);
0565   myismin.Append(isMin);
0566   mypoint.Append(PC);
0567 
0568  }
0569 
0570 
0571 //=======================================================================
0572 //function : Extrema_GExtPC
0573 //purpose  : 
0574 //=======================================================================
0575 
0576 Extrema_GExtPC::Extrema_GExtPC()
0577 {
0578   myC = 0;
0579   mydone = Standard_False;
0580   mydist1 = RealLast();
0581   mydist2 = RealLast();
0582   mytolu = 0.0;
0583   mytolf = 0.0;
0584   mysample = 17;
0585   myintuinf = myintusup = myuinf = myusup = Precision::Infinite();
0586   type = GeomAbs_OtherCurve;
0587 }
0588 
0589 //=======================================================================
0590 //function : Extrema_GExtPC
0591 //purpose  : 
0592 //=======================================================================
0593 
0594 Extrema_GExtPC::Extrema_GExtPC(const ThePoint&           P, 
0595                                const TheCurve&           C,
0596                                const Standard_Real       Uinf,
0597                                const Standard_Real       Usup,
0598                                const Standard_Real       TolF) 
0599 {
0600   Initialize(C, Uinf, Usup, TolF);
0601   Perform(P);
0602 }
0603 
0604 //=======================================================================
0605 //function : Extrema_GExtPC
0606 //purpose  : 
0607 //=======================================================================
0608 
0609 Extrema_GExtPC::Extrema_GExtPC(const ThePoint&     P, 
0610                                const TheCurve&     C,
0611                                const Standard_Real TolF) 
0612 {
0613   Initialize(C, TheCurveTool::FirstParameter(C), 
0614              TheCurveTool::LastParameter(C), TolF);
0615   Perform(P);
0616 }
0617 
0618 
0619 //=======================================================================
0620 //function : IsDone
0621 //purpose  : 
0622 //=======================================================================
0623 
0624 Standard_Boolean Extrema_GExtPC::IsDone() const
0625 {
0626   return mydone;
0627 }
0628 
0629 
0630 //=======================================================================
0631 //function : Value
0632 //purpose  : 
0633 //=======================================================================
0634 
0635 Standard_Real Extrema_GExtPC::SquareDistance(const Standard_Integer N) const 
0636 {
0637   if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
0638   return mySqDist.Value(N);
0639 }
0640 
0641 
0642 //=======================================================================
0643 //function : NbExt
0644 //purpose  : 
0645 //=======================================================================
0646 
0647 Standard_Integer Extrema_GExtPC::NbExt() const
0648 {
0649   if (!IsDone()) throw StdFail_NotDone();
0650   return mySqDist.Length();
0651 }
0652 
0653 
0654 //=======================================================================
0655 //function : IsMin
0656 //purpose  : 
0657 //=======================================================================
0658 
0659 Standard_Boolean Extrema_GExtPC::IsMin(const Standard_Integer N) const
0660 {
0661   if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
0662   return myismin.Value(N);
0663 }
0664 
0665 
0666 
0667 //=======================================================================
0668 //function : Point
0669 //purpose  : 
0670 //=======================================================================
0671 
0672 const ThePOnC & Extrema_GExtPC::Point(const Standard_Integer N) const
0673 {
0674   if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
0675   return mypoint.Value(N);
0676 }
0677 
0678 
0679 //=======================================================================
0680 //function : TrimmedDistances
0681 //purpose  : 
0682 //=======================================================================
0683 
0684 void Extrema_GExtPC::TrimmedSquareDistances(Standard_Real& dist1, 
0685                                       Standard_Real& dist2,
0686                                       ThePoint& P1,
0687                                       ThePoint& P2) const
0688 {
0689   dist1 = mydist1;
0690   dist2 = mydist2;
0691   P1 = Pf;
0692   P2 = Pl;
0693 }