File indexing completed on 2026-09-21 09:16:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef _Extrema_GFuncExtCC_HeaderFile
0016 #define _Extrema_GFuncExtCC_HeaderFile
0017
0018 #include <GeomAbs_CurveType.hxx>
0019 #include <math_FunctionSetWithDerivatives.hxx>
0020 #include <math_Matrix.hxx>
0021 #include <math_Vector.hxx>
0022 #include <Precision.hxx>
0023 #include <Standard.hxx>
0024 #include <Standard_DefineAlloc.hxx>
0025 #include <Standard_OutOfRange.hxx>
0026 #include <NCollection_Sequence.hxx>
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 template <typename TheCurve1,
0041 typename TheCurveTool1,
0042 typename TheCurve2,
0043 typename TheCurveTool2,
0044 typename ThePOnC,
0045 typename ThePoint,
0046 typename TheVector,
0047 typename TheSequenceOfPOnC>
0048 class Extrema_GFuncExtCC : public math_FunctionSetWithDerivatives
0049 {
0050 public:
0051 DEFINE_STANDARD_ALLOC
0052
0053
0054 Extrema_GFuncExtCC(const double theTol = 1.0e-10);
0055
0056
0057 Extrema_GFuncExtCC(const TheCurve1& theC1, const TheCurve2& theC2, const double theTol = 1.0e-10);
0058
0059
0060 void SetCurve(const int theRank, const TheCurve1& theC);
0061
0062
0063 void SetTolerance(const double theTol) { myTol = theTol; }
0064
0065
0066 int NbVariables() const override { return 2; }
0067
0068
0069 int NbEquations() const override { return 2; }
0070
0071
0072 bool Value(const math_Vector& theUV, math_Vector& theF) override;
0073
0074
0075 bool Derivatives(const math_Vector& theUV, math_Matrix& theDF) override;
0076
0077
0078 bool Values(const math_Vector& theUV, math_Vector& theF, math_Matrix& theDF) override;
0079
0080
0081 int GetStateNumber() override;
0082
0083
0084 int NbExt() const { return mySqDist.Length(); }
0085
0086
0087 double SquareDistance(const int theN) const { return mySqDist.Value(theN); }
0088
0089
0090 void Points(const int theN, ThePOnC& theP1, ThePOnC& theP2) const;
0091
0092
0093 void* CurvePtr(const int theRank) const
0094 {
0095 Standard_OutOfRange_Raise_if(theRank < 1 || theRank > 2, "Extrema_GFuncExtCC::CurvePtr()");
0096 return (theRank == 1 ? myC1 : myC2);
0097 }
0098
0099
0100 double Tolerance() const { return myTol; }
0101
0102
0103 void SubIntervalInitialize(const math_Vector& theUfirst, const math_Vector& theUlast);
0104
0105
0106 double SearchOfTolerance(void* const theC);
0107
0108 private:
0109 static constexpr double THE_MIN_TOL = 1.e-20;
0110 static constexpr double THE_TOL_FACTOR = 1.e-12;
0111 static constexpr double THE_MIN_STEP = 1e-7;
0112 static constexpr int THE_MAX_ORDER = 3;
0113
0114 void* myC1;
0115 void* myC2;
0116 double myTol;
0117 double myU;
0118 double myV;
0119 ThePoint myP1;
0120 ThePoint myP2;
0121 TheVector myDu;
0122 TheVector myDv;
0123 NCollection_Sequence<double> mySqDist;
0124 TheSequenceOfPOnC myPoints;
0125 double myTolC1;
0126 double myTolC2;
0127 int myMaxDerivOrderC1;
0128 int myMaxDerivOrderC2;
0129 double myUinfium;
0130 double myUsupremum;
0131 double myVinfium;
0132 double myVsupremum;
0133 };
0134
0135
0136
0137
0138
0139
0140
0141 template <typename TheCurve1,
0142 typename TheCurveTool1,
0143 typename TheCurve2,
0144 typename TheCurveTool2,
0145 typename ThePOnC,
0146 typename ThePoint,
0147 typename TheVector,
0148 typename TheSequenceOfPOnC>
0149 double Extrema_GFuncExtCC<TheCurve1,
0150 TheCurveTool1,
0151 TheCurve2,
0152 TheCurveTool2,
0153 ThePOnC,
0154 ThePoint,
0155 TheVector,
0156 TheSequenceOfPOnC>::SearchOfTolerance(void* const theC)
0157 {
0158 const int NPoint = 10;
0159 double aStartParam, anEndParam;
0160
0161 if (theC == myC1)
0162 {
0163 aStartParam = myUinfium;
0164 anEndParam = myUsupremum;
0165 }
0166 else if (theC == myC2)
0167 {
0168 aStartParam = myVinfium;
0169 anEndParam = myVsupremum;
0170 }
0171 else
0172 {
0173 return THE_MIN_TOL;
0174 }
0175
0176 const double aStep = (anEndParam - aStartParam) / (double)NPoint;
0177
0178 int aNum = 0;
0179 double aMax = -Precision::Infinite();
0180
0181 do
0182 {
0183 double u = aStartParam + aNum * aStep;
0184 if (u > anEndParam)
0185 u = anEndParam;
0186
0187 ThePoint Ptemp;
0188 TheVector VDer;
0189 TheCurveTool1::D1(*((TheCurve1*)theC), u, Ptemp, VDer);
0190 double vm = VDer.Magnitude();
0191 if (vm > aMax)
0192 aMax = vm;
0193 } while (++aNum < NPoint + 1);
0194
0195 return std::max(aMax * THE_TOL_FACTOR, THE_MIN_TOL);
0196 }
0197
0198
0199
0200 template <typename TheCurve1,
0201 typename TheCurveTool1,
0202 typename TheCurve2,
0203 typename TheCurveTool2,
0204 typename ThePOnC,
0205 typename ThePoint,
0206 typename TheVector,
0207 typename TheSequenceOfPOnC>
0208 Extrema_GFuncExtCC<TheCurve1,
0209 TheCurveTool1,
0210 TheCurve2,
0211 TheCurveTool2,
0212 ThePOnC,
0213 ThePoint,
0214 TheVector,
0215 TheSequenceOfPOnC>::Extrema_GFuncExtCC(const double theTol)
0216 : myC1(nullptr),
0217 myC2(nullptr),
0218 myTol(theTol)
0219 {
0220 math_Vector V1(1, 2), V2(1, 2);
0221 V1(1) = 0.0;
0222 V2(1) = 0.0;
0223 V1(2) = 0.0;
0224 V2(2) = 0.0;
0225 SubIntervalInitialize(V1, V2);
0226 myMaxDerivOrderC1 = 0;
0227 myTolC1 = THE_MIN_TOL;
0228 myMaxDerivOrderC2 = 0;
0229 myTolC2 = THE_MIN_TOL;
0230 }
0231
0232
0233
0234 template <typename TheCurve1,
0235 typename TheCurveTool1,
0236 typename TheCurve2,
0237 typename TheCurveTool2,
0238 typename ThePOnC,
0239 typename ThePoint,
0240 typename TheVector,
0241 typename TheSequenceOfPOnC>
0242 Extrema_GFuncExtCC<TheCurve1,
0243 TheCurveTool1,
0244 TheCurve2,
0245 TheCurveTool2,
0246 ThePOnC,
0247 ThePoint,
0248 TheVector,
0249 TheSequenceOfPOnC>::Extrema_GFuncExtCC(const TheCurve1& theC1,
0250 const TheCurve2& theC2,
0251 const double theTol)
0252 : myC1((void*)&theC1),
0253 myC2((void*)&theC2),
0254 myTol(theTol)
0255 {
0256 math_Vector V1(1, 2), V2(1, 2);
0257 V1(1) = TheCurveTool1::FirstParameter(*((TheCurve1*)myC1));
0258 V2(1) = TheCurveTool1::LastParameter(*((TheCurve1*)myC1));
0259 V1(2) = TheCurveTool2::FirstParameter(*((TheCurve2*)myC2));
0260 V2(2) = TheCurveTool2::LastParameter(*((TheCurve2*)myC2));
0261 SubIntervalInitialize(V1, V2);
0262
0263 switch (TheCurveTool1::GetType(*((TheCurve1*)myC1)))
0264 {
0265 case GeomAbs_BezierCurve:
0266 case GeomAbs_BSplineCurve:
0267 case GeomAbs_OffsetCurve:
0268 case GeomAbs_OtherCurve:
0269 myMaxDerivOrderC1 = THE_MAX_ORDER;
0270 myTolC1 = SearchOfTolerance((void*)&theC1);
0271 break;
0272 default:
0273 myMaxDerivOrderC1 = 0;
0274 myTolC1 = THE_MIN_TOL;
0275 break;
0276 }
0277
0278 switch (TheCurveTool2::GetType(*((TheCurve2*)myC2)))
0279 {
0280 case GeomAbs_BezierCurve:
0281 case GeomAbs_BSplineCurve:
0282 case GeomAbs_OffsetCurve:
0283 case GeomAbs_OtherCurve:
0284 myMaxDerivOrderC2 = THE_MAX_ORDER;
0285 myTolC2 = SearchOfTolerance((void*)&theC2);
0286 break;
0287 default:
0288 myMaxDerivOrderC2 = 0;
0289 myTolC2 = THE_MIN_TOL;
0290 break;
0291 }
0292 }
0293
0294
0295
0296 template <typename TheCurve1,
0297 typename TheCurveTool1,
0298 typename TheCurve2,
0299 typename TheCurveTool2,
0300 typename ThePOnC,
0301 typename ThePoint,
0302 typename TheVector,
0303 typename TheSequenceOfPOnC>
0304 void Extrema_GFuncExtCC<TheCurve1,
0305 TheCurveTool1,
0306 TheCurve2,
0307 TheCurveTool2,
0308 ThePOnC,
0309 ThePoint,
0310 TheVector,
0311 TheSequenceOfPOnC>::SetCurve(const int theRank, const TheCurve1& theC)
0312 {
0313 Standard_OutOfRange_Raise_if(theRank < 1 || theRank > 2, "Extrema_GFuncExtCC::SetCurve()")
0314
0315 if (theRank == 1)
0316 {
0317 myC1 = (void*)&theC;
0318 switch (theC.GetType())
0319 {
0320 case GeomAbs_BezierCurve:
0321 case GeomAbs_BSplineCurve:
0322 case GeomAbs_OffsetCurve:
0323 case GeomAbs_OtherCurve:
0324 myMaxDerivOrderC1 = THE_MAX_ORDER;
0325 myTolC1 = SearchOfTolerance((void*)&theC);
0326 break;
0327 default:
0328 myMaxDerivOrderC1 = 0;
0329 myTolC1 = THE_MIN_TOL;
0330 break;
0331 }
0332 }
0333 else if (theRank == 2)
0334 {
0335 myC2 = (void*)&theC;
0336 switch (theC.GetType())
0337 {
0338 case GeomAbs_BezierCurve:
0339 case GeomAbs_BSplineCurve:
0340 case GeomAbs_OffsetCurve:
0341 case GeomAbs_OtherCurve:
0342 myMaxDerivOrderC2 = THE_MAX_ORDER;
0343 myTolC2 = SearchOfTolerance((void*)&theC);
0344 break;
0345 default:
0346 myMaxDerivOrderC2 = 0;
0347 myTolC2 = THE_MIN_TOL;
0348 break;
0349 }
0350 }
0351 }
0352
0353
0354
0355 template <typename TheCurve1,
0356 typename TheCurveTool1,
0357 typename TheCurve2,
0358 typename TheCurveTool2,
0359 typename ThePOnC,
0360 typename ThePoint,
0361 typename TheVector,
0362 typename TheSequenceOfPOnC>
0363 bool Extrema_GFuncExtCC<TheCurve1,
0364 TheCurveTool1,
0365 TheCurve2,
0366 TheCurveTool2,
0367 ThePOnC,
0368 ThePoint,
0369 TheVector,
0370 TheSequenceOfPOnC>::Value(const math_Vector& theUV, math_Vector& theF)
0371 {
0372 myU = theUV(1);
0373 myV = theUV(2);
0374 TheCurveTool1::D1(*((TheCurve1*)myC1), myU, myP1, myDu);
0375 TheCurveTool2::D1(*((TheCurve2*)myC2), myV, myP2, myDv);
0376
0377 TheVector P1P2(myP1, myP2);
0378
0379 double Ndu = myDu.Magnitude();
0380
0381 if (myMaxDerivOrderC1 != 0)
0382 {
0383 if (Ndu <= myTolC1)
0384 {
0385 const double DivisionFactor = 1.e-3;
0386 double du;
0387 if ((myUsupremum >= RealLast()) || (myUinfium <= RealFirst()))
0388 du = 0.0;
0389 else
0390 du = myUsupremum - myUinfium;
0391
0392 const double aDelta = std::max(du * DivisionFactor, THE_MIN_STEP);
0393
0394 int n = 1;
0395 TheVector V;
0396 bool IsDeriveFound;
0397
0398 do
0399 {
0400 V = TheCurveTool1::DN(*((TheCurve1*)myC1), myU, ++n);
0401 Ndu = V.Magnitude();
0402 IsDeriveFound = (Ndu > myTolC1);
0403 } while (!IsDeriveFound && n < myMaxDerivOrderC1);
0404
0405 if (IsDeriveFound)
0406 {
0407 double u;
0408
0409 if (myU - myUinfium < aDelta)
0410 u = myU + aDelta;
0411 else
0412 u = myU - aDelta;
0413
0414 ThePoint P1, P2;
0415 TheCurveTool1::D0(*((TheCurve1*)myC1), std::min(myU, u), P1);
0416 TheCurveTool1::D0(*((TheCurve1*)myC1), std::max(myU, u), P2);
0417
0418 TheVector V1(P1, P2);
0419 double aDirFactor = V.Dot(V1);
0420
0421 if (aDirFactor < 0.0)
0422 myDu = -V;
0423 else
0424 myDu = V;
0425 }
0426 else
0427 {
0428 ThePoint Ptemp;
0429 ThePoint P1, P2, P3;
0430 bool IsParameterGrown;
0431
0432 if (myU - myUinfium < 2 * aDelta)
0433 {
0434 TheCurveTool1::D0(*((TheCurve1*)myC1), myU, P1);
0435 TheCurveTool1::D0(*((TheCurve1*)myC1), myU + aDelta, P2);
0436 TheCurveTool1::D0(*((TheCurve1*)myC1), myU + 2 * aDelta, P3);
0437 IsParameterGrown = true;
0438 }
0439 else
0440 {
0441 TheCurveTool1::D0(*((TheCurve1*)myC1), myU - 2 * aDelta, P1);
0442 TheCurveTool1::D0(*((TheCurve1*)myC1), myU - aDelta, P2);
0443 TheCurveTool1::D0(*((TheCurve1*)myC1), myU, P3);
0444 IsParameterGrown = false;
0445 }
0446
0447 TheVector V1(Ptemp, P1), V2(Ptemp, P2), V3(Ptemp, P3);
0448
0449 if (IsParameterGrown)
0450 myDu = -3 * V1 + 4 * V2 - V3;
0451 else
0452 myDu = V1 - 4 * V2 + 3 * V3;
0453 }
0454 Ndu = myDu.Magnitude();
0455 }
0456 }
0457
0458 if (Ndu <= THE_MIN_TOL)
0459 {
0460 return false;
0461 }
0462
0463 double Ndv = myDv.Magnitude();
0464
0465 if (myMaxDerivOrderC2 != 0)
0466 {
0467 if (Ndv <= myTolC2)
0468 {
0469 const double DivisionFactor = 1.e-3;
0470 double dv;
0471 if ((myVsupremum >= RealLast()) || (myVinfium <= RealFirst()))
0472 dv = 0.0;
0473 else
0474 dv = myVsupremum - myVinfium;
0475
0476 const double aDelta = std::max(dv * DivisionFactor, THE_MIN_STEP);
0477
0478 int n = 1;
0479 TheVector V;
0480 bool IsDeriveFound;
0481
0482 do
0483 {
0484 V = TheCurveTool2::DN(*((TheCurve2*)myC2), myV, ++n);
0485 Ndv = V.Magnitude();
0486 IsDeriveFound = (Ndv > myTolC2);
0487 } while (!IsDeriveFound && n < myMaxDerivOrderC2);
0488
0489 if (IsDeriveFound)
0490 {
0491 double v;
0492
0493 if (myV - myVinfium < aDelta)
0494 v = myV + aDelta;
0495 else
0496 v = myV - aDelta;
0497
0498 ThePoint P1, P2;
0499 TheCurveTool2::D0(*((TheCurve2*)myC2), std::min(myV, v), P1);
0500 TheCurveTool2::D0(*((TheCurve2*)myC2), std::max(myV, v), P2);
0501
0502 TheVector V1(P1, P2);
0503 double aDirFactor = V.Dot(V1);
0504
0505 if (aDirFactor < 0.0)
0506 myDv = -V;
0507 else
0508 myDv = V;
0509 }
0510 else
0511 {
0512 ThePoint Ptemp;
0513 ThePoint P1, P2, P3;
0514 bool IsParameterGrown;
0515
0516 if (myV - myVinfium < 2 * aDelta)
0517 {
0518 TheCurveTool2::D0(*((TheCurve2*)myC2), myV, P1);
0519 TheCurveTool2::D0(*((TheCurve2*)myC2), myV + aDelta, P2);
0520 TheCurveTool2::D0(*((TheCurve2*)myC2), myV + 2 * aDelta, P3);
0521 IsParameterGrown = true;
0522 }
0523 else
0524 {
0525 TheCurveTool2::D0(*((TheCurve2*)myC2), myV - 2 * aDelta, P1);
0526 TheCurveTool2::D0(*((TheCurve2*)myC2), myV - aDelta, P2);
0527 TheCurveTool2::D0(*((TheCurve2*)myC2), myV, P3);
0528 IsParameterGrown = false;
0529 }
0530
0531 TheVector V1(Ptemp, P1), V2(Ptemp, P2), V3(Ptemp, P3);
0532
0533 if (IsParameterGrown)
0534 myDv = -3 * V1 + 4 * V2 - V3;
0535 else
0536 myDv = V1 - 4 * V2 + 3 * V3;
0537 }
0538
0539 Ndv = myDv.Magnitude();
0540 }
0541 }
0542
0543 if (Ndv <= THE_MIN_TOL)
0544 {
0545 return false;
0546 }
0547
0548 theF(1) = P1P2.Dot(myDu) / Ndu;
0549 theF(2) = P1P2.Dot(myDv) / Ndv;
0550 return true;
0551 }
0552
0553
0554
0555 template <typename TheCurve1,
0556 typename TheCurveTool1,
0557 typename TheCurve2,
0558 typename TheCurveTool2,
0559 typename ThePOnC,
0560 typename ThePoint,
0561 typename TheVector,
0562 typename TheSequenceOfPOnC>
0563 bool Extrema_GFuncExtCC<TheCurve1,
0564 TheCurveTool1,
0565 TheCurve2,
0566 TheCurveTool2,
0567 ThePOnC,
0568 ThePoint,
0569 TheVector,
0570 TheSequenceOfPOnC>::Derivatives(const math_Vector& theUV,
0571 math_Matrix& theDF)
0572 {
0573 math_Vector F(1, 2);
0574 return Values(theUV, F, theDF);
0575 }
0576
0577
0578
0579 template <typename TheCurve1,
0580 typename TheCurveTool1,
0581 typename TheCurve2,
0582 typename TheCurveTool2,
0583 typename ThePOnC,
0584 typename ThePoint,
0585 typename TheVector,
0586 typename TheSequenceOfPOnC>
0587 bool Extrema_GFuncExtCC<TheCurve1,
0588 TheCurveTool1,
0589 TheCurve2,
0590 TheCurveTool2,
0591 ThePOnC,
0592 ThePoint,
0593 TheVector,
0594 TheSequenceOfPOnC>::Values(const math_Vector& theUV,
0595 math_Vector& theF,
0596 math_Matrix& theDF)
0597 {
0598 myU = theUV(1);
0599 myV = theUV(2);
0600
0601 if (Value(theUV, theF) == false)
0602 {
0603 return false;
0604 }
0605
0606 TheVector Du, Dv, Duu, Dvv;
0607 TheCurveTool1::D2(*((TheCurve1*)myC1), myU, myP1, Du, Duu);
0608 TheCurveTool2::D2(*((TheCurve2*)myC2), myV, myP2, Dv, Dvv);
0609
0610 const double myU_old = myU, myV_old = myV;
0611 const ThePoint myP1_old = myP1, myP2_old = myP2;
0612 const TheVector myDu_old = myDu, myDv_old = myDv;
0613
0614 const double DivisionFactor = 0.01;
0615
0616 double du;
0617 if ((myUsupremum >= RealLast()) || (myUinfium <= RealFirst()))
0618 du = 0.0;
0619 else
0620 du = myUsupremum - myUinfium;
0621
0622 const double aDeltaU = std::max(du * DivisionFactor, THE_MIN_STEP);
0623
0624 double dv;
0625 if ((myVsupremum >= RealLast()) || (myVinfium <= RealFirst()))
0626 dv = 0.0;
0627 else
0628 dv = myVsupremum - myVinfium;
0629
0630 const double aDeltaV = std::max(dv * DivisionFactor, THE_MIN_STEP);
0631
0632 TheVector P1P2(myP1, myP2);
0633
0634 if ((myMaxDerivOrderC1 != 0) && (Du.Magnitude() <= myTolC1))
0635 {
0636 math_Vector FF1(1, 2), FF2(1, 2), FF3(1, 2);
0637 double F1, F2, F3;
0638
0639 if (myU - myUinfium < 2 * aDeltaU)
0640 {
0641 F1 = theF(1);
0642 math_Vector UV2(1, 2), UV3(1, 2);
0643 UV2(1) = myU + aDeltaU;
0644 UV2(2) = myV;
0645 UV3(1) = myU + 2 * aDeltaU;
0646 UV3(2) = myV;
0647 if (!((Value(UV2, FF2)) && (Value(UV3, FF3))))
0648 {
0649 return false;
0650 }
0651
0652 F2 = FF2(1);
0653 F3 = FF3(1);
0654
0655 theDF(1, 1) = (-3 * F1 + 4 * F2 - F3) / (2.0 * aDeltaU);
0656 }
0657 else
0658 {
0659 F3 = theF(1);
0660 math_Vector UV2(1, 2), UV1(1, 2);
0661 UV2(1) = myU - aDeltaU;
0662 UV2(2) = myV;
0663 UV1(1) = myU - 2 * aDeltaU;
0664 UV1(2) = myV;
0665
0666 if (!((Value(UV2, FF2)) && (Value(UV1, FF1))))
0667 {
0668 return false;
0669 }
0670
0671 F1 = FF1(1);
0672 F2 = FF2(1);
0673
0674 theDF(1, 1) = (F1 - 4 * F2 + 3 * F3) / (2.0 * aDeltaU);
0675 }
0676
0677 myU = myU_old;
0678 myV = myV_old;
0679
0680 if (myV - myVinfium < 2 * aDeltaV)
0681 {
0682 F1 = theF(1);
0683 math_Vector UV2(1, 2), UV3(1, 2);
0684 UV2(1) = myU;
0685 UV2(2) = myV + aDeltaV;
0686 UV3(1) = myU;
0687 UV3(2) = myV + 2 * aDeltaV;
0688
0689 if (!((Value(UV2, FF2)) && (Value(UV3, FF3))))
0690 {
0691 return false;
0692 }
0693 F2 = FF2(1);
0694 F3 = FF3(1);
0695
0696 theDF(1, 2) = (-3 * F1 + 4 * F2 - F3) / (2.0 * aDeltaV);
0697 }
0698 else
0699 {
0700 F3 = theF(1);
0701 math_Vector UV2(1, 2), UV1(1, 2);
0702 UV2(1) = myU;
0703 UV2(2) = myV - aDeltaV;
0704 UV1(1) = myU;
0705 UV1(2) = myV - 2 * aDeltaV;
0706 if (!((Value(UV2, FF2)) && (Value(UV1, FF1))))
0707 {
0708 return false;
0709 }
0710
0711 F1 = FF1(1);
0712 F2 = FF2(1);
0713
0714 theDF(1, 2) = (F1 - 4 * F2 + 3 * F3) / (2.0 * aDeltaV);
0715 }
0716
0717 myU = myU_old;
0718 myV = myV_old;
0719 myP1 = myP1_old, myP2 = myP2_old;
0720 myDu = myDu_old, myDv = myDv_old;
0721 }
0722 else
0723 {
0724 const double Ndu = myDu.Magnitude();
0725 theDF(1, 1) = -Ndu + (P1P2.Dot(Duu) / Ndu) - theF(1) * (myDu.Dot(Duu) / (Ndu * Ndu));
0726 theDF(1, 2) = myDv.Dot(myDu) / Ndu;
0727 }
0728
0729 if ((myMaxDerivOrderC2 != 0) && (Dv.Magnitude() <= myTolC2))
0730 {
0731 math_Vector FF1(1, 2), FF2(1, 2), FF3(1, 2);
0732 double F1, F2, F3;
0733
0734 if (myV - myVinfium < 2 * aDeltaV)
0735 {
0736 F1 = theF(2);
0737 math_Vector UV2(1, 2), UV3(1, 2);
0738 UV2(1) = myU;
0739 UV2(2) = myV + aDeltaV;
0740 UV3(1) = myU;
0741 UV3(2) = myV + 2 * aDeltaV;
0742
0743 if (!((Value(UV2, FF2)) && (Value(UV3, FF3))))
0744 {
0745 return false;
0746 }
0747
0748 F2 = FF2(2);
0749 F3 = FF3(2);
0750
0751 theDF(2, 2) = (-3 * F1 + 4 * F2 - F3) / (2.0 * aDeltaV);
0752 }
0753 else
0754 {
0755 F3 = theF(2);
0756 math_Vector UV2(1, 2), UV1(1, 2);
0757 UV2(1) = myU;
0758 UV2(2) = myV - aDeltaV;
0759 UV1(1) = myU;
0760 UV1(2) = myV - 2 * aDeltaV;
0761
0762 if (!((Value(UV2, FF2)) && (Value(UV1, FF1))))
0763 {
0764 return false;
0765 }
0766
0767 F1 = FF1(2);
0768 F2 = FF2(2);
0769
0770 theDF(2, 2) = (F1 - 4 * F2 + 3 * F3) / (2.0 * aDeltaV);
0771 }
0772
0773 myU = myU_old;
0774 myV = myV_old;
0775
0776 if (myU - myUinfium < 2 * aDeltaU)
0777 {
0778 F1 = theF(2);
0779 math_Vector UV2(1, 2), UV3(1, 2);
0780 UV2(1) = myU + aDeltaU;
0781 UV2(2) = myV;
0782 UV3(1) = myU + 2 * aDeltaU;
0783 UV3(2) = myV;
0784 if (!((Value(UV2, FF2)) && (Value(UV3, FF3))))
0785 {
0786 return false;
0787 }
0788
0789 F2 = FF2(2);
0790 F3 = FF3(2);
0791
0792 theDF(2, 1) = (-3 * F1 + 4 * F2 - F3) / (2.0 * aDeltaU);
0793 }
0794 else
0795 {
0796 F3 = theF(2);
0797 math_Vector UV2(1, 2), UV1(1, 2);
0798 UV2(1) = myU - aDeltaU;
0799 UV2(2) = myV;
0800 UV1(1) = myU - 2 * aDeltaU;
0801 UV1(2) = myV;
0802
0803 if (!((Value(UV2, FF2)) && (Value(UV1, FF1))))
0804 {
0805 return false;
0806 }
0807
0808 F1 = FF1(2);
0809 F2 = FF2(2);
0810
0811 theDF(2, 1) = (F1 - 4 * F2 + 3 * F3) / (2.0 * aDeltaU);
0812 }
0813
0814 myU = myU_old;
0815 myV = myV_old;
0816 myP1 = myP1_old;
0817 myP2 = myP2_old;
0818 myDu = myDu_old;
0819 myDv = myDv_old;
0820 }
0821 else
0822 {
0823 double Ndv = myDv.Magnitude();
0824 theDF(2, 2) = Ndv + (P1P2.Dot(Dvv) / Ndv) - theF(2) * (myDv.Dot(Dvv) / (Ndv * Ndv));
0825 theDF(2, 1) = -myDu.Dot(myDv) / Ndv;
0826 }
0827
0828 return true;
0829 }
0830
0831
0832
0833 template <typename TheCurve1,
0834 typename TheCurveTool1,
0835 typename TheCurve2,
0836 typename TheCurveTool2,
0837 typename ThePOnC,
0838 typename ThePoint,
0839 typename TheVector,
0840 typename TheSequenceOfPOnC>
0841 int Extrema_GFuncExtCC<TheCurve1,
0842 TheCurveTool1,
0843 TheCurve2,
0844 TheCurveTool2,
0845 ThePOnC,
0846 ThePoint,
0847 TheVector,
0848 TheSequenceOfPOnC>::GetStateNumber()
0849 {
0850 TheVector Du(myDu), Dv(myDv);
0851 TheVector P1P2(myP1, myP2);
0852
0853 double mod = Du.Magnitude();
0854 if (mod > myTolC1)
0855 {
0856 Du /= mod;
0857 }
0858 mod = Dv.Magnitude();
0859 if (mod > myTolC2)
0860 {
0861 Dv /= mod;
0862 }
0863
0864 if (std::abs(P1P2.Dot(Du)) <= myTol && std::abs(P1P2.Dot(Dv)) <= myTol)
0865 {
0866 mySqDist.Append(myP1.SquareDistance(myP2));
0867 myPoints.Append(ThePOnC(myU, myP1));
0868 myPoints.Append(ThePOnC(myV, myP2));
0869 }
0870 return 0;
0871 }
0872
0873
0874
0875 template <typename TheCurve1,
0876 typename TheCurveTool1,
0877 typename TheCurve2,
0878 typename TheCurveTool2,
0879 typename ThePOnC,
0880 typename ThePoint,
0881 typename TheVector,
0882 typename TheSequenceOfPOnC>
0883 void Extrema_GFuncExtCC<TheCurve1,
0884 TheCurveTool1,
0885 TheCurve2,
0886 TheCurveTool2,
0887 ThePOnC,
0888 ThePoint,
0889 TheVector,
0890 TheSequenceOfPOnC>::Points(const int theN,
0891 ThePOnC& theP1,
0892 ThePOnC& theP2) const
0893 {
0894 theP1 = myPoints.Value(2 * theN - 1);
0895 theP2 = myPoints.Value(2 * theN);
0896 }
0897
0898
0899
0900 template <typename TheCurve1,
0901 typename TheCurveTool1,
0902 typename TheCurve2,
0903 typename TheCurveTool2,
0904 typename ThePOnC,
0905 typename ThePoint,
0906 typename TheVector,
0907 typename TheSequenceOfPOnC>
0908 void Extrema_GFuncExtCC<TheCurve1,
0909 TheCurveTool1,
0910 TheCurve2,
0911 TheCurveTool2,
0912 ThePOnC,
0913 ThePoint,
0914 TheVector,
0915 TheSequenceOfPOnC>::SubIntervalInitialize(const math_Vector& theInfBound,
0916 const math_Vector& theSupBound)
0917 {
0918 myUinfium = theInfBound(1);
0919 myUsupremum = theSupBound(1);
0920 myVinfium = theInfBound(2);
0921 myVsupremum = theSupBound(2);
0922 }
0923
0924 #endif