0030686: Visualization, SelectMgr_ViewerSelector - sorting issues of transformation...
[occt.git] / src / Extrema / Extrema_GExtPC.gxx
CommitLineData
b311480e 1// Created on: 1992-10-19
2// Created by: Laurent PAINNOT
3// Copyright (c) 1992-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 17// Modified by cma, Fri Dec 10 18:11:56 1993
7fd59977 18
19#include Extrema_EPC_hxx
20#include ThePOnC_hxx
21#include TheSequenceOfPOnC_hxx
22#include ThePoint_hxx
23#include TheVector_hxx
24#include TheExtPElC_hxx
25#include <StdFail_NotDone.hxx>
26#include <Standard_Failure.hxx>
27#include <GeomAbs_CurveType.hxx>
28#include <Precision.hxx>
29#include <ElCLib.hxx>
30#include <TColStd_Array1OfReal.hxx>
f6b08ecf 31#include <TColStd_HArray1OfReal.hxx>
c8bf1eb7 32#include <NCollection_Array1.hxx>
7fd59977 33
34
35//=======================================================================
36//function : Perform
37//purpose :
38//=======================================================================
7fd59977 39void Extrema_GExtPC::Perform(const ThePoint& P)
40{
41 mySqDist.Clear();
42 mypoint.Clear();
43 myismin.Clear();
44 Standard_Integer i, NbExt, n;
45 Standard_Real U;
46 mysample = 17;
47 Standard_Real t3d = Precision::Confusion();
48 if (Precision::IsInfinite(myuinf)) mydist1 = RealLast();
49 else {
50 Pf = TheCurveTool::Value(*((TheCurve*)myC), myuinf);
51 mydist1 = P.SquareDistance(Pf);
52 }
53
54 if (Precision::IsInfinite(myusup)) mydist2 = RealLast();
55 else {
56 Pl = TheCurveTool::Value(*((TheCurve*)myC), myusup);
57 mydist2 = P.SquareDistance(Pl);
58 }
59
c8bf1eb7 60 TheCurve & aCurve = *((TheCurve*)myC);
61
7fd59977 62 switch(type) {
63 case GeomAbs_Circle:
64 {
c8bf1eb7 65 myExtPElC.Perform(P, TheCurveTool::Circle(aCurve), t3d, myuinf, myusup);
7fd59977 66 }
67 break;
68 case GeomAbs_Ellipse:
69 {
c8bf1eb7 70 myExtPElC.Perform(P, TheCurveTool::Ellipse(aCurve), t3d, myuinf, myusup);
7fd59977 71 }
72 break;
73 case GeomAbs_Parabola:
74 {
c8bf1eb7 75 myExtPElC.Perform(P, TheCurveTool::Parabola(aCurve), t3d,myuinf,myusup);
7fd59977 76 }
77 break;
78 case GeomAbs_Hyperbola:
79 {
c8bf1eb7 80 myExtPElC.Perform(P,TheCurveTool::Hyperbola(aCurve),t3d, myuinf, myusup);
7fd59977 81 }
82 break;
83 case GeomAbs_Line:
84 {
c8bf1eb7 85 myExtPElC.Perform(P, TheCurveTool::Line(aCurve), t3d, myuinf, myusup);
7fd59977 86 }
87 break;
88 case GeomAbs_BezierCurve:
89 {
90 myintuinf = myuinf;
91 myintusup = myusup;
c8bf1eb7 92 mysample = (TheCurveTool::Bezier(aCurve))->NbPoles() * 2;
93 myExtPC.Initialize(aCurve);
7fd59977 94 IntervalPerform(P);
95 return;
96 }
97 case GeomAbs_BSplineCurve:
98 {
c8bf1eb7 99 const Standard_Integer
100 aFirstIdx = TheCurveTool::BSpline(aCurve)->FirstUKnotIndex(),
101 aLastIdx = TheCurveTool::BSpline(aCurve)->LastUKnotIndex();
102 // const reference can not be used due to implementation of BRep_Adaptor.
103 TColStd_Array1OfReal aKnots(aFirstIdx, aLastIdx);
104 TheCurveTool::BSpline(aCurve)->Knots(aKnots);
105
106 // Workaround to work with:
c5a10cf7 107 // blend, where knots may be moved from parameter space.
c8bf1eb7 108 Standard_Real aPeriodJump = 0.0;
c5a10cf7 109 // Avoid problem with too close knots.
0cbfb9f1 110 const Standard_Real aTolCoeff = (myusup - myuinf) * Precision::PConfusion();
c8bf1eb7 111 if (TheCurveTool::IsPeriodic(aCurve))
112 {
113 Standard_Integer aPeriodShift =
114 Standard_Integer ((myuinf - aKnots(aFirstIdx)) / TheCurveTool::Period(aCurve));
115
0cbfb9f1 116 if (myuinf < aKnots(aFirstIdx) - aTolCoeff)
c8bf1eb7 117 aPeriodShift--;
118
119 aPeriodJump = TheCurveTool::Period(aCurve) * aPeriodShift;
120 }
121
122 Standard_Integer anIdx;
123
1581d651 124 // Find first and last used knot.
c8bf1eb7 125 Standard_Integer aFirstUsedKnot = aFirstIdx,
126 aLastUsedKnot = aLastIdx;
127 for(anIdx = aFirstIdx; anIdx <= aLastIdx; anIdx++)
128 {
129 Standard_Real aKnot = aKnots(anIdx) + aPeriodJump;
0cbfb9f1 130 if (myuinf >= aKnot - aTolCoeff)
c8bf1eb7 131 aFirstUsedKnot = anIdx;
132 else
133 break;
134
135 }
136 for(anIdx = aLastIdx; anIdx >= aFirstIdx; anIdx--)
137 {
138 Standard_Real aKnot = aKnots(anIdx) + aPeriodJump;
0cbfb9f1 139 if (myusup <= aKnot + aTolCoeff)
c8bf1eb7 140 aLastUsedKnot = anIdx;
141 else
142 break;
143 }
144
1581d651 145 if (aFirstUsedKnot == aLastUsedKnot)
146 {
147 // Degenerated case:
148 // Some bounds lies out of curve param space.
149 // In this case build one interval with [myuinf, myusup].
150 // Parameters of these indexes will be redefined.
151 aFirstUsedKnot = aFirstIdx;
152 aLastUsedKnot = aFirstIdx + 1;
153 }
154
c8bf1eb7 155 mysample = (TheCurveTool::BSpline(aCurve))->Degree() + 1;
156
d8406b2f 157 if (mysample == 2)
c8bf1eb7 158 {
d8406b2f 159 //BSpline of first degree, direct seaching extrema for each knot interval
160 ThePoint aPmin;
161 Standard_Real tmin = 0., distmin = RealLast();
162 Standard_Real aMin1 = 0., aMin2 = 0.;
163 myExtPC.Initialize(aCurve);
164 for (anIdx = aFirstUsedKnot; anIdx < aLastUsedKnot; anIdx++)
165 {
166 Standard_Real aF = aKnots(anIdx) + aPeriodJump,
167 aL = aKnots(anIdx + 1) + aPeriodJump;
168
169 if (anIdx == aFirstUsedKnot)
170 {
171 aF = myuinf;
172 }
173 else
174 if (anIdx == aLastUsedKnot - 1)
175 {
176 aL = myusup;
177 }
c8bf1eb7 178
c8bf1eb7 179
d8406b2f 180 ThePoint aP1, aP2;
181 TheCurveTool::D0(aCurve, aF, aP1);
182 TheCurveTool::D0(aCurve, aL, aP2);
183 TheVector aBase1(P, aP1), aBase2(P, aP2);
184 TheVector aV(aP2, aP1);
185 Standard_Real aVal1 = aV.Dot(aBase1); // Derivative of (C(u) - P)^2
186 Standard_Real aVal2 = aV.Dot(aBase2); // Derivative of (C(u) - P)^2
187 if (anIdx == aFirstUsedKnot)
188 {
189 aMin1 = P.SquareDistance(aP1);
190 }
191 else
192 {
193 aMin1 = aMin2;
194 if (distmin > aMin1)
195 {
196 distmin = aMin1;
197 tmin = aF;
198 aPmin = aP1;
199 }
200 }
201 aMin2 = P.SquareDistance(aP2);
202 Standard_Real aMinSqDist = Min(aMin1, aMin2);
203 Standard_Real aMinDer = Min(Abs(aVal1), Abs(aVal2));
204 if (!(Precision::IsInfinite(aVal1) || Precision::IsInfinite(aVal2)))
205 {
206 // Derivatives have opposite signs - min or max inside of interval (sufficient condition).
207 if (aVal1 * aVal2 <= 0.0 ||
208 aMinSqDist < 100. * Precision::SquareConfusion() ||
209 2.*aMinDer < Precision::Confusion())
210 {
211 myintuinf = aF;
212 myintusup = aL;
213 IntervalPerform(P);
214 }
215 }
216 }
217 if (!Precision::IsInfinite(distmin))
c8bf1eb7 218 {
d8406b2f 219 Standard_Boolean isToAdd = Standard_True;
220 NbExt = mypoint.Length();
221 for (i = 1; i <= NbExt && isToAdd; i++)
222 {
223 Standard_Real t = mypoint.Value(i).Parameter();
224 isToAdd = (distmin < mySqDist(i)) && (Abs(t - tmin) > mytolu);
225 }
226 if (isToAdd)
227 {
228 ThePOnC PC(tmin, aPmin);
229 mySqDist.Append(distmin);
230 myismin.Append(Standard_True);
231 mypoint.Append(PC);
232 }
c8bf1eb7 233 }
234 }
d8406b2f 235 else
c8bf1eb7 236 {
d8406b2f 237
238 // Fill sample points.
239 Standard_Integer aValIdx = 1;
240 NCollection_Array1<Standard_Real> aVal(1, (mysample)* (aLastUsedKnot - aFirstUsedKnot) + 1);
241 NCollection_Array1<Standard_Real> aParam(1, (mysample)* (aLastUsedKnot - aFirstUsedKnot) + 1);
242 for (anIdx = aFirstUsedKnot; anIdx < aLastUsedKnot; anIdx++)
c8bf1eb7 243 {
d8406b2f 244 Standard_Real aF = aKnots(anIdx) + aPeriodJump,
245 aL = aKnots(anIdx + 1) + aPeriodJump;
246
247 if (anIdx == aFirstUsedKnot)
248 aF = myuinf;
249 if (anIdx == aLastUsedKnot - 1)
250 aL = myusup;
c8bf1eb7 251
d8406b2f 252 Standard_Real aStep = (aL - aF) / mysample;
253 for (Standard_Integer aPntIdx = 0; aPntIdx < mysample; aPntIdx++)
254 {
255 Standard_Real aCurrentParam = aF + aStep * aPntIdx;
256 aVal(aValIdx) = TheCurveTool::Value(aCurve, aCurrentParam).SquareDistance(P);
257 aParam(aValIdx) = aCurrentParam;
258 aValIdx++;
259 }
c8bf1eb7 260 }
d8406b2f 261 // Fill last point.
262 aVal(aValIdx) = TheCurveTool::Value(aCurve, myusup).SquareDistance(P);
263 aParam(aValIdx) = myusup;
c8bf1eb7 264
d8406b2f 265 myExtPC.Initialize(aCurve);
266
267 // Find extremas.
268 for (anIdx = aVal.Lower() + 1; anIdx < aVal.Upper(); anIdx++)
c8bf1eb7 269 {
d8406b2f 270 if (aVal(anIdx) <= Precision::SquareConfusion())
271 {
272 mySqDist.Append(aVal(anIdx));
273 myismin.Append(Standard_True);
274 mypoint.Append(ThePOnC(aParam(anIdx), TheCurveTool::Value(aCurve, aParam(anIdx))));
275 }
276 if ((aVal(anIdx) >= aVal(anIdx + 1) &&
277 aVal(anIdx) >= aVal(anIdx - 1)) ||
278 (aVal(anIdx) <= aVal(anIdx + 1) &&
279 aVal(anIdx) <= aVal(anIdx - 1)))
f4dee9bb 280 {
d8406b2f 281 myintuinf = aParam(anIdx - 1);
282 myintusup = aParam(anIdx + 1);
283
f4dee9bb 284 IntervalPerform(P);
285 }
c8bf1eb7 286 }
c8bf1eb7 287
d8406b2f 288 // Solve on the first and last intervals.
289 if (mydist1 > Precision::SquareConfusion() && !Precision::IsPositiveInfinite(mydist1))
290 {
291 ThePoint aP1, aP2;
292 TheVector aV1, aV2;
293 TheCurveTool::D1(aCurve, aParam.Value(aParam.Lower()), aP1, aV1);
294 TheCurveTool::D1(aCurve, aParam.Value(aParam.Lower() + 1), aP2, aV2);
295 TheVector aBase1(P, aP1), aBase2(P, aP2);
296 Standard_Real aVal1 = aV1.Dot(aBase1); // Derivative of (C(u) - P)^2
297 Standard_Real aVal2 = aV2.Dot(aBase2); // Derivative of (C(u) - P)^2
298 if (!(Precision::IsInfinite(aVal1) || Precision::IsInfinite(aVal2)))
299 {
300 // Derivatives have opposite signs - min or max inside of interval (sufficient condition).
301 // Necessary condition - when point lies on curve.
302 // Necessary condition - when derivative of point is too small.
303 if (aVal1 * aVal2 <= 0.0 ||
304 aBase1.Dot(aBase2) <= 0.0 ||
305 2.0 * Abs(aVal1) < Precision::Confusion())
306 {
307 myintuinf = aParam(aVal.Lower());
308 myintusup = aParam(aVal.Lower() + 1);
309 IntervalPerform(P);
310 }
311 }
312 }
c8bf1eb7 313
d8406b2f 314 if (mydist2 > Precision::SquareConfusion() && !Precision::IsPositiveInfinite(mydist2))
c8bf1eb7 315 {
d8406b2f 316 ThePoint aP1, aP2;
317 TheVector aV1, aV2;
318 TheCurveTool::D1(aCurve, aParam.Value(aParam.Upper() - 1), aP1, aV1);
319 TheCurveTool::D1(aCurve, aParam.Value(aParam.Upper()), aP2, aV2);
320 TheVector aBase1(P, aP1), aBase2(P, aP2);
321 Standard_Real aVal1 = aV1.Dot(aBase1); // Derivative of (C(u) - P)^2
322 Standard_Real aVal2 = aV2.Dot(aBase2); // Derivative of (C(u) - P)^2
323
324 if (!(Precision::IsInfinite(aVal1) || Precision::IsInfinite(aVal2)))
f4dee9bb 325 {
d8406b2f 326 // Derivatives have opposite signs - min or max inside of interval (sufficient condition).
327 // Necessary condition - when point lies on curve.
328 // Necessary condition - when derivative of point is too small.
329 if (aVal1 * aVal2 <= 0.0 ||
330 aBase1.Dot(aBase2) <= 0.0 ||
331 2.0 * Abs(aVal2) < Precision::Confusion())
332 {
333 myintuinf = aParam(aVal.Upper() - 1);
334 myintusup = aParam(aVal.Upper());
335 IntervalPerform(P);
336 }
f4dee9bb 337 }
c8bf1eb7 338 }
339 }
c8bf1eb7 340 mydone = Standard_True;
341 break;
7fd59977 342 }
1aec3320 343 default:
7fd59977 344 {
f6b08ecf 345 const Standard_Integer aMaxSample = 17;
7fd59977 346 Standard_Boolean IntExtIsDone = Standard_False;
347 Standard_Boolean IntIsNotValid;
f6b08ecf 348 Handle(TColStd_HArray1OfReal) theHInter;
c8bf1eb7 349 n = TheCurveTool::NbIntervals(aCurve, GeomAbs_C2);
f6b08ecf 350 if (n > 1)
351 {
352 theHInter = new TColStd_HArray1OfReal(1, n + 1);
353 TheCurveTool::Intervals(aCurve, theHInter->ChangeArray1(), GeomAbs_C2);
354 }
355 else
356 {
357 theHInter = TheCurveTool::DeflCurvIntervals(aCurve);
358 n = theHInter->Length() - 1;
359 }
360 mysample = Max(mysample / n, aMaxSample);
361 Standard_Real maxint = 0.;
362 for (i = 1; i <= n; ++i)
363 {
364 Standard_Real dt = theHInter->Value(i + 1) - theHInter->Value(i);
365 if (maxint < dt)
366 {
367 maxint = dt;
368 }
369 }
c8bf1eb7 370 Standard_Boolean isPeriodic = TheCurveTool::IsPeriodic(aCurve);
7fd59977 371 TheVector V1;
372 ThePoint PP;
373 Standard_Real s1 = 0.0 ;
c8bf1eb7 374 Standard_Real s2 = 0.0;
375 myExtPC.Initialize(aCurve);
376 for (i = 1; i <= n; i++)
377 {
f6b08ecf 378 myintuinf = theHInter->Value(i);
379 myintusup = theHInter->Value(i+1);
380 mysample = Max(RealToInt(aMaxSample*(myintusup - myintuinf) / maxint), 3);
253881cf 381
382 Standard_Real anInfToCheck = myintuinf;
383 Standard_Real aSupToCheck = myintusup;
384
385 if (isPeriodic) {
c8bf1eb7 386 Standard_Real aPeriod = TheCurveTool::Period(aCurve);
253881cf 387 anInfToCheck = ElCLib::InPeriod(myintuinf, myuinf, myuinf+aPeriod);
388 aSupToCheck = myintusup+(anInfToCheck-myintuinf);
389 }
390 IntIsNotValid = (myuinf > aSupToCheck) || (myusup < anInfToCheck);
391
392 if(IntIsNotValid) continue;
393
394 if (myuinf >= anInfToCheck) anInfToCheck = myuinf;
395 if (myusup <= aSupToCheck) aSupToCheck = myusup;
396 if((aSupToCheck - anInfToCheck) <= mytolu) continue;
32ca7a51 397
398 if (i != 1)
399 {
c8bf1eb7 400 TheCurveTool::D1(aCurve, myintuinf, PP, V1);
253881cf 401 s1 = (TheVector(P, PP))*V1;
402 if (s1*s2 < 0.0) {
403 mySqDist.Append(PP.SquareDistance(P));
404 myismin.Append((s1 < 0.0));
405 mypoint.Append(ThePOnC(myintuinf, PP));
406 }
407 }
408 if (i != n) {
c8bf1eb7 409 TheCurveTool::D1(aCurve, myintusup, PP, V1);
253881cf 410 s2 = (TheVector(P, PP))*V1;
411 }
32ca7a51 412
253881cf 413 IntervalPerform(P);
414 IntExtIsDone = IntExtIsDone || mydone;
7fd59977 415 }
c8bf1eb7 416
7fd59977 417 mydone = IntExtIsDone;
c8bf1eb7 418 break;
419 }
420 }
94f71cad 421
c8bf1eb7 422 // Postprocessing.
423 if (type == GeomAbs_BSplineCurve ||
1aec3320 424 type == GeomAbs_OffsetCurve ||
c8bf1eb7 425 type == GeomAbs_OtherCurve)
426 {
427 // Additional checking if the point is on the first or last point of the curve
428 // and does not added yet.
429 if (mydist1 < Precision::SquareConfusion() ||
430 mydist2 < Precision::SquareConfusion())
431 {
432 Standard_Boolean isFirstAdded = Standard_False;
433 Standard_Boolean isLastAdded = Standard_False;
434 Standard_Integer aNbPoints = mypoint.Length();
435 for (i = 1; i <= aNbPoints; i++)
94f71cad 436 {
c8bf1eb7 437 U = mypoint.Value(i).Parameter();
438 if (Abs(U - myuinf) < mytolu)
439 isFirstAdded = Standard_True;
440 else if (Abs(myusup - U) < mytolu)
441 isLastAdded = Standard_True;
442 }
443 if (!isFirstAdded && mydist1 < Precision::SquareConfusion())
444 {
445 mySqDist.Prepend(mydist1);
446 myismin.Prepend(Standard_True);
447 mypoint.Prepend(ThePOnC(myuinf, Pf));
448 }
449 if (!isLastAdded && mydist2 < Precision::SquareConfusion())
450 {
451 mySqDist.Append(mydist2);
452 myismin.Append(Standard_True);
453 mypoint.Append(ThePOnC(myusup, Pl));
454 }
455 mydone = Standard_True;
456 }
457 }
458 else
459 {
460 // In analytical case
461 mydone = myExtPElC.IsDone();
462 if (mydone)
463 {
464 NbExt = myExtPElC.NbExt();
465 for (i = 1; i <= NbExt; i++)
466 {
467 // Verification de la validite des parametres:
468 ThePOnC PC = myExtPElC.Point(i);
469 U = PC.Parameter();
470 if (TheCurveTool::IsPeriodic(aCurve))
94f71cad 471 {
c8bf1eb7 472 U = ElCLib::InPeriod(U, myuinf, myuinf+TheCurveTool::Period(aCurve));
94f71cad 473 }
c8bf1eb7 474 if ((U >= myuinf-mytolu) && (U <= myusup+mytolu))
94f71cad 475 {
c8bf1eb7 476 PC.SetValues(U, myExtPElC.Point(i).Value());
477 mySqDist.Append(myExtPElC.SquareDistance(i));
478 myismin.Append(myExtPElC.IsMin(i));
479 mypoint.Append(PC);
94f71cad 480 }
481 }
7fd59977 482 }
483 }
7fd59977 484}
485
486
487//=======================================================================
488//function : Initialize
489//purpose :
490//=======================================================================
491
492void Extrema_GExtPC::Initialize(const TheCurve& C,
493 const Standard_Real Uinf,
494 const Standard_Real Usup,
495 const Standard_Real TolF)
496{
497 myC = (Standard_Address)&C;
498 myintuinf = myuinf = Uinf;
499 myintusup = myusup = Usup;
500 mytolf = TolF;
501 mytolu = TheCurveTool::Resolution(*((TheCurve*)myC), Precision::Confusion());
502 type = TheCurveTool::GetType(C);
503 mydone = Standard_False;
504 mydist1 = RealLast();
505 mydist2 = RealLast();
506 mysample = 17;
507}
508
509
510//=======================================================================
511//function : IntervalPerform
512//purpose :
513//=======================================================================
514
515void Extrema_GExtPC::IntervalPerform(const ThePoint& P)
516{
517 Standard_Integer i;
518 Standard_Real U;
c8bf1eb7 519 myExtPC.Initialize(mysample, myintuinf, myintusup, mytolu, mytolf);
7fd59977 520 myExtPC.Perform(P);
521 mydone = myExtPC.IsDone();
c8bf1eb7 522 if (mydone)
523 {
7fd59977 524 Standard_Integer NbExt = myExtPC.NbExt();
c8bf1eb7 525 for (i = 1; i <= NbExt; i++)
526 {
7fd59977 527 // Verification de la validite des parametres pour le cas trimme:
528 ThePOnC PC = myExtPC.Point(i);
529 U = PC.Parameter();
c8bf1eb7 530 if (TheCurveTool::IsPeriodic(*((TheCurve*)myC)))
531 {
253881cf 532 U = ElCLib::InPeriod(U, myuinf, myuinf+TheCurveTool::Period(*((TheCurve*)myC)));
7fd59977 533 }
c8bf1eb7 534 if ((U >= myuinf - mytolu) && (U <= myusup + mytolu))
535 {
1dbdf099 536 AddSol(U, PC.Value(),
537 myExtPC.SquareDistance(i),
538 myExtPC.IsMin(i));
7fd59977 539 }
540 }
541 }
542}
543
544
1dbdf099 545//=======================================================================
546//function : AddSol
547//purpose :
548//=======================================================================
549
550void Extrema_GExtPC::AddSol(const Standard_Real theU, const ThePoint& theP,
551 const Standard_Real theSqDist,
552 const Standard_Boolean isMin)
553{
554 Standard_Integer i, NbExt = mypoint.Length();
555 for (i = 1; i <= NbExt; i++)
556 {
557 Standard_Real t = mypoint.Value(i).Parameter();
558 if (Abs(t - theU) <= mytolu)
559 {
560 return;
561 }
562 }
563 ThePOnC PC(theU, theP);
564 mySqDist.Append(theSqDist);
565 myismin.Append(isMin);
566 mypoint.Append(PC);
567
568 }
7fd59977 569
570
571//=======================================================================
572//function : Extrema_GExtPC
573//purpose :
574//=======================================================================
575
576Extrema_GExtPC::Extrema_GExtPC()
577{
578 myC = 0;
579 mydone = Standard_False;
580 mydist1 = RealLast();
581 mydist2 = RealLast();
582 mytolu = 0.0;
583 mytolf = 0.0;
584 mysample = 17;
585 myintuinf = myintusup = myuinf = myusup = Precision::Infinite();
586 type = GeomAbs_OtherCurve;
587}
588
589//=======================================================================
590//function : Extrema_GExtPC
591//purpose :
592//=======================================================================
593
594Extrema_GExtPC::Extrema_GExtPC(const ThePoint& P,
595 const TheCurve& C,
596 const Standard_Real Uinf,
597 const Standard_Real Usup,
598 const Standard_Real TolF)
599{
600 Initialize(C, Uinf, Usup, TolF);
601 Perform(P);
602}
603
604//=======================================================================
605//function : Extrema_GExtPC
606//purpose :
607//=======================================================================
608
609Extrema_GExtPC::Extrema_GExtPC(const ThePoint& P,
610 const TheCurve& C,
611 const Standard_Real TolF)
612{
613 Initialize(C, TheCurveTool::FirstParameter(C),
614 TheCurveTool::LastParameter(C), TolF);
615 Perform(P);
616}
617
618
619//=======================================================================
620//function : IsDone
621//purpose :
622//=======================================================================
623
624Standard_Boolean Extrema_GExtPC::IsDone() const
625{
626 return mydone;
627}
628
629
630//=======================================================================
631//function : Value
632//purpose :
633//=======================================================================
634
635Standard_Real Extrema_GExtPC::SquareDistance(const Standard_Integer N) const
636{
638ad7f3 637 if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
7fd59977 638 return mySqDist.Value(N);
639}
640
641
642//=======================================================================
643//function : NbExt
644//purpose :
645//=======================================================================
646
647Standard_Integer Extrema_GExtPC::NbExt() const
648{
638ad7f3 649 if (!IsDone()) throw StdFail_NotDone();
7fd59977 650 return mySqDist.Length();
651}
652
653
654//=======================================================================
655//function : IsMin
656//purpose :
657//=======================================================================
658
659Standard_Boolean Extrema_GExtPC::IsMin(const Standard_Integer N) const
660{
638ad7f3 661 if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
7fd59977 662 return myismin.Value(N);
663}
664
665
666
667//=======================================================================
668//function : Point
669//purpose :
670//=======================================================================
671
5d99f2c8 672const ThePOnC & Extrema_GExtPC::Point(const Standard_Integer N) const
7fd59977 673{
638ad7f3 674 if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
7fd59977 675 return mypoint.Value(N);
676}
677
678
679//=======================================================================
680//function : TrimmedDistances
681//purpose :
682//=======================================================================
683
684void Extrema_GExtPC::TrimmedSquareDistances(Standard_Real& dist1,
685 Standard_Real& dist2,
686 ThePoint& P1,
687 ThePoint& P2) const
688{
689 dist1 = mydist1;
690 dist2 = mydist2;
691 P1 = Pf;
692 P2 = Pl;
693}