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 }