File indexing completed on 2026-09-17 09:20:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef _Extrema_GCurveLocator_HeaderFile
0016 #define _Extrema_GCurveLocator_HeaderFile
0017
0018 #include <Standard.hxx>
0019 #include <Standard_Real.hxx>
0020 #include <Standard_DefineAlloc.hxx>
0021 #include <Standard_OutOfRange.hxx>
0022
0023 #include <cmath>
0024
0025
0026
0027
0028
0029
0030
0031
0032 template <typename TheCurve, typename TheCurveTool, typename ThePOnC, typename ThePoint>
0033 class Extrema_GCurveLocator
0034 {
0035 public:
0036 DEFINE_STANDARD_ALLOC
0037
0038
0039
0040
0041
0042
0043
0044
0045 static void Locate(const ThePoint& theP, const TheCurve& theC, const int theNbU, ThePOnC& thePapp)
0046 {
0047 if (theNbU < 2)
0048 {
0049 throw Standard_OutOfRange();
0050 }
0051
0052 double aU = TheCurveTool::FirstParameter(theC);
0053 double aPasU = (TheCurveTool::LastParameter(theC) - aU) / (theNbU - 1);
0054 double aDist2Min = RealLast();
0055 double aUMin = 0;
0056 ThePoint aPntMin;
0057 double aDist2;
0058 ThePoint aPt;
0059
0060 for (int aNoSample = 1; aNoSample < theNbU; aNoSample++, aU += aPasU)
0061 {
0062 aPt = TheCurveTool::Value(theC, aU);
0063 aDist2 = aPt.SquareDistance(theP);
0064 if (aDist2 < aDist2Min)
0065 {
0066 aDist2Min = aDist2;
0067 aUMin = aU;
0068 aPntMin = aPt;
0069 }
0070 }
0071 thePapp.SetValues(aUMin, aPntMin);
0072 }
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 static void Locate(const ThePoint& theP,
0085 const TheCurve& theC,
0086 const int theNbU,
0087 const double theUmin,
0088 const double theUsup,
0089 ThePOnC& thePapp)
0090 {
0091 if (theNbU < 2)
0092 {
0093 throw Standard_OutOfRange();
0094 }
0095
0096 double aUinf = TheCurveTool::FirstParameter(theC);
0097 double aUlast = TheCurveTool::LastParameter(theC);
0098
0099 double aU1 = std::min(aUinf, aUlast);
0100 double aU2 = std::max(aUinf, aUlast);
0101 double aU11 = std::min(theUmin, theUsup);
0102 double aU12 = std::max(theUmin, theUsup);
0103
0104 if (aU11 < aU1 - RealEpsilon())
0105 aU11 = aU1;
0106 if (aU12 > aU2 + RealEpsilon())
0107 aU12 = aU2;
0108
0109 double aU = aU11;
0110 double aPasU = (aU12 - aU) / (theNbU - 1);
0111 double aDist2Min = RealLast();
0112 double aUMin = 0;
0113 ThePoint aPntMin;
0114 double aDist2;
0115 ThePoint aPt;
0116
0117 for (int aNoSample = 1; aNoSample < theNbU; aNoSample++, aU += aPasU)
0118 {
0119 aPt = TheCurveTool::Value(theC, aU);
0120 aDist2 = aPt.SquareDistance(theP);
0121 if (aDist2 < aDist2Min)
0122 {
0123 aDist2Min = aDist2;
0124 aUMin = aU;
0125 aPntMin = aPt;
0126 }
0127 }
0128 thePapp.SetValues(aUMin, aPntMin);
0129 }
0130 };
0131
0132 #endif