Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-28 09:20:53

0001 // Copyright (c) 2025 OPEN CASCADE SAS
0002 //
0003 // This file is part of Open CASCADE Technology software library.
0004 //
0005 // This library is free software; you can redistribute it and/or modify it under
0006 // the terms of the GNU Lesser General Public License version 2.1 as published
0007 // by the Free Software Foundation, with special exception defined in the file
0008 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0009 // distribution for complete text of the license and disclaimer of any warranty.
0010 //
0011 // Alternatively, this file may be used under the terms of Open CASCADE
0012 // commercial license or contractual agreement.
0013 
0014 #ifndef _MathUtils_Domain_HeaderFile
0015 #define _MathUtils_Domain_HeaderFile
0016 
0017 #include <cmath>
0018 
0019 //! @file MathUtils_Domain.hxx
0020 //! @brief Parameter domain types for curves and surfaces.
0021 //!
0022 //! Provides lightweight value types for representing 1D and 2D parameter domains
0023 //! with utility methods for bounds checking, clamping, and domain analysis.
0024 
0025 namespace MathUtils
0026 {
0027 
0028 //! @brief 1D parameter domain for curves.
0029 //!
0030 //! Represents a parameter range [Min, Max] with utility methods for:
0031 //! - Bounds checking (Contains)
0032 //! - Parameter clamping (Clamp)
0033 //! - Domain analysis (IsLarge, IsFullPeriod)
0034 //!
0035 //! @note This is a lightweight value type designed for efficiency.
0036 //!       All methods are inline and constexpr where possible.
0037 struct Domain1D
0038 {
0039   double Min = 0.0; //!< Lower bound of the domain
0040   double Max = 0.0; //!< Upper bound of the domain
0041 
0042   //! Default constructor - creates empty domain [0, 0].
0043   constexpr Domain1D() = default;
0044 
0045   //! Construct from bounds.
0046   //! @param theMin lower bound
0047   //! @param theMax upper bound
0048   constexpr Domain1D(double theMin, double theMax)
0049       : Min(theMin),
0050         Max(theMax)
0051   {
0052   }
0053 
0054   //! Returns the length of the domain.
0055   constexpr double Length() const { return Max - Min; }
0056 
0057   //! Returns the midpoint of the domain.
0058   constexpr double Mid() const { return (Min + Max) * 0.5; }
0059 
0060   //! Check if value is within domain.
0061   //! @param theU parameter value to check
0062   //! @param theTol tolerance for boundary check
0063   //! @return true if theU is in [Min - theTol, Max + theTol]
0064   bool Contains(double theU, double theTol = 0.0) const
0065   {
0066     return theU >= Min - theTol && theU <= Max + theTol;
0067   }
0068 
0069   //! Clamp value to domain bounds.
0070   //! @param theU parameter value to clamp
0071   //! @return clamped value in [Min, Max]
0072   double Clamp(double theU) const { return theU < Min ? Min : (theU > Max ? Max : theU); }
0073 
0074   //! Check if domain is "large" (effectively unbounded for optimization).
0075   //! Large domains allow skipping bounds checking for performance.
0076   //! @param theThreshold size threshold (default 1000)
0077   //! @return true if Length() > theThreshold
0078   bool IsLarge(double theThreshold = 1000.0) const { return Length() > theThreshold; }
0079 
0080   //! Check if domain covers a full periodic range.
0081   //! @param thePeriod period of the parameter (e.g., 2*PI for angles)
0082   //! @param theTol tolerance
0083   //! @return true if domain covers at least one full period
0084   bool IsFullPeriod(double thePeriod, double theTol = 1.0e-10) const
0085   {
0086     return Length() >= thePeriod - theTol;
0087   }
0088 
0089   //! Interpolate within domain.
0090   //! @param theT interpolation parameter in [0, 1]
0091   //! @return Min + theT * Length()
0092   constexpr double Lerp(double theT) const { return Min + theT * (Max - Min); }
0093 
0094   //! Normalize parameter to [0, 1] range.
0095   //! @param theU parameter value
0096   //! @return (theU - Min) / Length(), or 0.5 if Length() == 0
0097   double Normalize(double theU) const
0098   {
0099     double aLen = Length();
0100     return aLen > 0.0 ? (theU - Min) / aLen : 0.5;
0101   }
0102 
0103   //! Check if domain has finite bounds (not effectively infinite).
0104   //! @param theInfLimit threshold for "infinity" (default 1e100)
0105   //! @return true if both Min and Max are within finite range
0106   bool IsFinite(double theInfLimit = 1.0e100) const
0107   {
0108     return Min > -theInfLimit && Max < theInfLimit;
0109   }
0110 
0111   //! Check if this domain equals another within tolerance.
0112   //! @param theOther domain to compare with
0113   //! @param theTol tolerance for comparison
0114   //! @return true if domains are equal within tolerance
0115   bool IsEqual(const Domain1D& theOther, double theTol = 1.0e-10) const
0116   {
0117     return std::abs(Min - theOther.Min) <= theTol && std::abs(Max - theOther.Max) <= theTol;
0118   }
0119 };
0120 
0121 //! @brief 2D parameter domain for surfaces.
0122 //!
0123 //! Represents a rectangular parameter domain [UMin, UMax] x [VMin, VMax]
0124 //! with utility methods for:
0125 //! - Bounds checking (Contains)
0126 //! - Parameter clamping (Clamp)
0127 //! - Domain analysis (IsLarge, IsFullPeriod)
0128 //! - Access to U and V subdomains
0129 //!
0130 //! @note This is a lightweight value type designed for efficiency.
0131 struct Domain2D
0132 {
0133   double UMin = 0.0; //!< Lower U bound
0134   double UMax = 0.0; //!< Upper U bound
0135   double VMin = 0.0; //!< Lower V bound
0136   double VMax = 0.0; //!< Upper V bound
0137 
0138   //! Default constructor - creates empty domain.
0139   constexpr Domain2D() = default;
0140 
0141   //! Construct from bounds.
0142   //! @param theUMin lower U bound
0143   //! @param theUMax upper U bound
0144   //! @param theVMin lower V bound
0145   //! @param theVMax upper V bound
0146   constexpr Domain2D(double theUMin, double theUMax, double theVMin, double theVMax)
0147       : UMin(theUMin),
0148         UMax(theUMax),
0149         VMin(theVMin),
0150         VMax(theVMax)
0151   {
0152   }
0153 
0154   //! Construct from two 1D domains.
0155   //! @param theUDomain U parameter domain
0156   //! @param theVDomain V parameter domain
0157   constexpr Domain2D(const Domain1D& theUDomain, const Domain1D& theVDomain)
0158       : UMin(theUDomain.Min),
0159         UMax(theUDomain.Max),
0160         VMin(theVDomain.Min),
0161         VMax(theVDomain.Max)
0162   {
0163   }
0164 
0165   //! Returns the U subdomain.
0166   constexpr Domain1D U() const { return {UMin, UMax}; }
0167 
0168   //! Returns the V subdomain.
0169   constexpr Domain1D V() const { return {VMin, VMax}; }
0170 
0171   //! Returns U length.
0172   constexpr double ULength() const { return UMax - UMin; }
0173 
0174   //! Returns V length.
0175   constexpr double VLength() const { return VMax - VMin; }
0176 
0177   //! Returns U midpoint.
0178   constexpr double UMid() const { return (UMin + UMax) * 0.5; }
0179 
0180   //! Returns V midpoint.
0181   constexpr double VMid() const { return (VMin + VMax) * 0.5; }
0182 
0183   //! Check if UV point is within domain.
0184   //! @param theU U parameter
0185   //! @param theV V parameter
0186   //! @param theTol tolerance for boundary check
0187   //! @return true if (theU, theV) is in domain
0188   bool Contains(double theU, double theV, double theTol = 0.0) const
0189   {
0190     return theU >= UMin - theTol && theU <= UMax + theTol && theV >= VMin - theTol
0191            && theV <= VMax + theTol;
0192   }
0193 
0194   //! Clamp UV to domain bounds.
0195   //! @param theU U parameter (modified in place)
0196   //! @param theV V parameter (modified in place)
0197   void Clamp(double& theU, double& theV) const
0198   {
0199     theU = theU < UMin ? UMin : (theU > UMax ? UMax : theU);
0200     theV = theV < VMin ? VMin : (theV > VMax ? VMax : theV);
0201   }
0202 
0203   //! Check if both U and V domains are "large".
0204   //! @param theThreshold size threshold (default 1000)
0205   //! @return true if both U and V lengths exceed threshold
0206   bool IsLarge(double theThreshold = 1000.0) const
0207   {
0208     return ULength() > theThreshold && VLength() > theThreshold;
0209   }
0210 
0211   //! Check if U domain covers a full period.
0212   //! @param thePeriod period of U parameter
0213   //! @param theTol tolerance
0214   bool IsUFullPeriod(double thePeriod, double theTol = 1.0e-10) const
0215   {
0216     return ULength() >= thePeriod - theTol;
0217   }
0218 
0219   //! Check if V domain covers a full period.
0220   //! @param thePeriod period of V parameter
0221   //! @param theTol tolerance
0222   bool IsVFullPeriod(double thePeriod, double theTol = 1.0e-10) const
0223   {
0224     return VLength() >= thePeriod - theTol;
0225   }
0226 
0227   //! Check if domain has finite bounds (not effectively infinite).
0228   //! @param theInfLimit threshold for "infinity" (default 1e100)
0229   bool IsFinite(double theInfLimit = 1.0e100) const
0230   {
0231     return UMin > -theInfLimit && UMax < theInfLimit && VMin > -theInfLimit && VMax < theInfLimit;
0232   }
0233 };
0234 
0235 } // namespace MathUtils
0236 
0237 #endif // _MathUtils_Domain_HeaderFile