File indexing completed on 2026-09-28 09:19:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef _ExtremaPC_Line_HeaderFile
0015 #define _ExtremaPC_Line_HeaderFile
0016
0017 #include <ExtremaPC.hxx>
0018 #include <gp_Lin.hxx>
0019 #include <gp_Pnt.hxx>
0020 #include <gp_Vec.hxx>
0021 #include <Standard_DefineAlloc.hxx>
0022
0023 #include <algorithm>
0024 #include <optional>
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 class ExtremaPC_Line
0039 {
0040 public:
0041 DEFINE_STANDARD_ALLOC
0042
0043
0044
0045 explicit ExtremaPC_Line(const gp_Lin& theLine)
0046 : myLine(theLine),
0047 myDomain(std::nullopt)
0048 {
0049 }
0050
0051
0052
0053
0054 ExtremaPC_Line(const gp_Lin& theLine, const ExtremaPC::Domain1D& theDomain)
0055 : myLine(theLine),
0056 myDomain(theDomain.IsFinite() ? std::optional<ExtremaPC::Domain1D>(theDomain)
0057 : std::nullopt)
0058 {
0059 }
0060
0061
0062 ExtremaPC_Line(const ExtremaPC_Line&) = delete;
0063
0064
0065 ExtremaPC_Line& operator=(const ExtremaPC_Line&) = delete;
0066
0067
0068 ExtremaPC_Line(ExtremaPC_Line&&) = default;
0069
0070
0071 ExtremaPC_Line& operator=(ExtremaPC_Line&&) = default;
0072
0073
0074
0075
0076 gp_Pnt Value(double theU) const
0077 {
0078 return myLine.Location().Translated(theU * gp_Vec(myLine.Direction()));
0079 }
0080
0081
0082 bool IsBounded() const { return myDomain.has_value(); }
0083
0084
0085 const ExtremaPC::Domain1D& Domain() const { return *myDomain; }
0086
0087
0088
0089
0090
0091
0092
0093 [[nodiscard]] const ExtremaPC::Result& Perform(
0094 const gp_Pnt& theP,
0095 double theTol,
0096 ExtremaPC::SearchMode theMode = ExtremaPC::SearchMode::MinMax) const
0097 {
0098 (void)theMode;
0099
0100 myResult.Clear();
0101
0102
0103 const gp_Dir& aDir = myLine.Direction();
0104 const gp_Pnt& aOrigin = myLine.Location();
0105 gp_Vec aVec(aOrigin, theP);
0106 double aU = aVec.Dot(gp_Vec(aDir));
0107
0108
0109 if (myDomain.has_value())
0110 {
0111 if (aU < myDomain->Min - theTol || aU > myDomain->Max + theTol)
0112 {
0113
0114 myResult.Status = ExtremaPC::Status::OK;
0115 return myResult;
0116 }
0117
0118 aU = std::clamp(aU, myDomain->Min, myDomain->Max);
0119 }
0120
0121
0122 gp_Pnt aPtOnLine = aOrigin.Translated(aU * gp_Vec(aDir));
0123
0124
0125 ExtremaPC::ExtremumResult anExt;
0126 anExt.Parameter = aU;
0127 anExt.Point = aPtOnLine;
0128 anExt.SquareDistance = theP.SquareDistance(aPtOnLine);
0129 anExt.IsMinimum = true;
0130
0131 myResult.Extrema.Append(anExt);
0132 myResult.Status = ExtremaPC::Status::OK;
0133 return myResult;
0134 }
0135
0136
0137
0138
0139
0140
0141
0142 [[nodiscard]] const ExtremaPC::Result& PerformWithEndpoints(
0143 const gp_Pnt& theP,
0144 double theTol,
0145 ExtremaPC::SearchMode theMode = ExtremaPC::SearchMode::MinMax) const
0146 {
0147 (void)Perform(theP, theTol, theMode);
0148
0149 if (myResult.Status == ExtremaPC::Status::OK && myDomain.has_value())
0150 {
0151 ExtremaPC::AddEndpointExtrema(myResult, theP, *myDomain, *this, theTol, theMode);
0152 }
0153
0154 return myResult;
0155 }
0156
0157
0158 const gp_Lin& Line() const { return myLine; }
0159
0160 private:
0161 gp_Lin myLine;
0162 std::optional<ExtremaPC::Domain1D> myDomain;
0163 mutable ExtremaPC::Result myResult;
0164 };
0165
0166 #endif