|
|
|||
File indexing completed on 2026-09-15 09:15:45
0001 // Copyright (c) 1991-1999 Matra Datavision 0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS 0003 // 0004 // This file is part of Open CASCADE Technology software library. 0005 // 0006 // This library is free software; you can redistribute it and/or modify it under 0007 // the terms of the GNU Lesser General Public License version 2.1 as published 0008 // by the Free Software Foundation, with special exception defined in the file 0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT 0010 // distribution for complete text of the license and disclaimer of any warranty. 0011 // 0012 // Alternatively, this file may be used under the terms of Open CASCADE 0013 // commercial license or contractual agreement. 0014 0015 #ifndef _gp_Dir_HeaderFile 0016 #define _gp_Dir_HeaderFile 0017 0018 #include <gp_XYZ.hxx> 0019 #include <Standard_ConstructionError.hxx> 0020 #include <Standard_DomainError.hxx> 0021 #include <Standard_OutOfRange.hxx> 0022 0023 class gp_Vec; 0024 class gp_Ax1; 0025 class gp_Ax2; 0026 class gp_Trsf; 0027 0028 //! Describes a unit vector in 3D space. This unit vector is also called "Direction". 0029 //! See Also 0030 //! gce_MakeDir which provides functions for more complex 0031 //! unit vector constructions 0032 //! Geom_Direction which provides additional functions for 0033 //! constructing unit vectors and works, in particular, with the 0034 //! parametric equations of unit vectors. 0035 class gp_Dir 0036 { 0037 public: 0038 //! Standard directions in 3D space for optimized constexpr construction 0039 enum class D 0040 { 0041 X, //!< Direction along positive X axis (1, 0, 0) 0042 Y, //!< Direction along positive Y axis (0, 1, 0) 0043 Z, //!< Direction along positive Z axis (0, 0, 1) 0044 NX, //!< Direction along negative X axis (-1, 0, 0) 0045 NY, //!< Direction along negative Y axis (0, -1, 0) 0046 NZ //!< Direction along negative Z axis (0, 0, -1) 0047 }; 0048 0049 DEFINE_STANDARD_ALLOC 0050 0051 //! Creates a direction corresponding to X axis. 0052 constexpr gp_Dir() noexcept 0053 : coord(1., 0., 0.) 0054 { 0055 } 0056 0057 //! Creates a direction from a standard direction enumeration. 0058 constexpr explicit gp_Dir(const D theDir) noexcept 0059 : coord(theDir == D::X ? 1.0 0060 : theDir == D::NX ? -1.0 0061 : 0.0, 0062 theDir == D::Y ? 1.0 0063 : theDir == D::NY ? -1.0 0064 : 0.0, 0065 theDir == D::Z ? 1.0 0066 : theDir == D::NZ ? -1.0 0067 : 0.0) 0068 { 0069 } 0070 0071 //! Normalizes the vector theV and creates a direction. Raises ConstructionError if 0072 //! theV.Magnitude() <= Resolution. 0073 //! @note Constexpr-compatible when input is already normalized. 0074 constexpr gp_Dir(const gp_Vec& theV); 0075 0076 //! Creates a direction from a triplet of coordinates. Raises ConstructionError if 0077 //! theCoord.Modulus() <= Resolution from gp. 0078 //! @note Constexpr-compatible when input is already normalized. 0079 constexpr gp_Dir(const gp_XYZ& theCoord); 0080 0081 //! Creates a direction with its 3 cartesian coordinates. Raises ConstructionError if 0082 //! std::sqrt(theXv*theXv + theYv*theYv + theZv*theZv) <= Resolution Modification of the 0083 //! direction's coordinates If std::sqrt (theXv*theXv + theYv*theYv + theZv*theZv) <= Resolution 0084 //! from gp where theXv, theYv ,theZv are the new coordinates it is not possible to construct the 0085 //! direction and the method raises the exception ConstructionError. 0086 //! @note Constexpr-compatible when input is already normalized. 0087 constexpr gp_Dir(const double theXv, const double theYv, const double theZv); 0088 0089 constexpr gp_Dir(const gp_Dir&) noexcept = default; 0090 constexpr gp_Dir(gp_Dir&&) noexcept = default; 0091 0092 constexpr gp_Dir& operator=(const gp_Dir&) noexcept = default; 0093 constexpr gp_Dir& operator=(gp_Dir&&) noexcept = default; 0094 0095 //! For this unit vector, assigns the value Xi to: 0096 //! - the X coordinate if theIndex is 1, or 0097 //! - the Y coordinate if theIndex is 2, or 0098 //! - the Z coordinate if theIndex is 3, 0099 //! and then normalizes it. 0100 //! Warning: 0101 //! Remember that all the coordinates of a unit vector are 0102 //! implicitly modified when any single one is changed directly. 0103 //! Exceptions 0104 //! Standard_OutOfRange if theIndex is not 1, 2, or 3. 0105 //! Standard_ConstructionError if either of the following 0106 //! is less than or equal to gp::Resolution(): 0107 //! - std::sqrt(Xv*Xv + Yv*Yv + Zv*Zv), or 0108 //! - the modulus of the number triple formed by the new 0109 //! value theXi and the two other coordinates of this vector 0110 //! that were not directly modified. 0111 //! @note Constexpr-compatible when result is already normalized. 0112 constexpr void SetCoord(const int theIndex, const double theXi); 0113 0114 //! For this unit vector, assigns the values theXv, theYv and theZv to its three coordinates. 0115 //! Remember that all the coordinates of a unit vector are 0116 //! implicitly modified when any single one is changed directly. 0117 //! @note Constexpr-compatible when input is already normalized. 0118 constexpr void SetCoord(const double theXv, const double theYv, const double theZv); 0119 0120 //! Assigns the given value to the X coordinate of this unit vector. 0121 //! @note Constexpr-compatible when result is already normalized. 0122 constexpr void SetX(const double theX); 0123 0124 //! Assigns the given value to the Y coordinate of this unit vector. 0125 //! @note Constexpr-compatible when result is already normalized. 0126 constexpr void SetY(const double theY); 0127 0128 //! Assigns the given value to the Z coordinate of this unit vector. 0129 //! @note Constexpr-compatible when result is already normalized. 0130 constexpr void SetZ(const double theZ); 0131 0132 //! Assigns the three coordinates of theCoord to this unit vector. 0133 //! @note Constexpr-compatible when input is already normalized. 0134 constexpr void SetXYZ(const gp_XYZ& theCoord); 0135 0136 //! Returns the coordinate of range theIndex : 0137 //! theIndex = 1 => X is returned 0138 //! theIndex = 2 => Y is returned 0139 //! theIndex = 3 => Z is returned 0140 //! Exceptions 0141 //! Standard_OutOfRange if theIndex is not 1, 2, or 3. 0142 constexpr double Coord(const int theIndex) const { return coord.Coord(theIndex); } 0143 0144 //! Returns for the unit vector its three coordinates theXv, theYv, and theZv. 0145 constexpr void Coord(double& theXv, double& theYv, double& theZv) const noexcept 0146 { 0147 coord.Coord(theXv, theYv, theZv); 0148 } 0149 0150 //! Returns the X coordinate for a unit vector. 0151 constexpr double X() const noexcept { return coord.X(); } 0152 0153 //! Returns the Y coordinate for a unit vector. 0154 constexpr double Y() const noexcept { return coord.Y(); } 0155 0156 //! Returns the Z coordinate for a unit vector. 0157 constexpr double Z() const noexcept { return coord.Z(); } 0158 0159 //! for this unit vector, returns its three coordinates as a number triple. 0160 constexpr const gp_XYZ& XYZ() const noexcept { return coord; } 0161 0162 //! Returns True if the angle between the two directions is 0163 //! lower or equal to theAngularTolerance. 0164 bool IsEqual(const gp_Dir& theOther, const double theAngularTolerance) const 0165 { 0166 return Angle(theOther) <= theAngularTolerance; 0167 } 0168 0169 //! Returns True if the angle between this unit vector and the unit vector theOther is equal to 0170 //! Pi/2 (normal). 0171 bool IsNormal(const gp_Dir& theOther, const double theAngularTolerance) const 0172 { 0173 double anAng = M_PI / 2.0 - Angle(theOther); 0174 if (anAng < 0) 0175 { 0176 anAng = -anAng; 0177 } 0178 return anAng <= theAngularTolerance; 0179 } 0180 0181 //! Returns True if the angle between this unit vector and the unit vector theOther is equal to 0182 //! Pi (opposite). 0183 bool IsOpposite(const gp_Dir& theOther, const double theAngularTolerance) const 0184 { 0185 return M_PI - Angle(theOther) <= theAngularTolerance; 0186 } 0187 0188 //! Returns true if the angle between this unit vector and the 0189 //! unit vector theOther is equal to 0 or to Pi. 0190 //! Note: the tolerance criterion is given by theAngularTolerance. 0191 bool IsParallel(const gp_Dir& theOther, const double theAngularTolerance) const 0192 { 0193 double anAng = Angle(theOther); 0194 return anAng <= theAngularTolerance || M_PI - anAng <= theAngularTolerance; 0195 } 0196 0197 //! Computes the angular value in radians between <me> and 0198 //! <theOther>. This value is always positive in 3D space. 0199 //! Returns the angle in the range [0, PI] 0200 Standard_EXPORT double Angle(const gp_Dir& theOther) const; 0201 0202 //! Computes the angular value between <me> and <theOther>. 0203 //! <theVRef> is the direction of reference normal to <me> and <theOther> 0204 //! and its orientation gives the positive sense of rotation. 0205 //! If the cross product <me> ^ <theOther> has the same orientation 0206 //! as <theVRef> the angular value is positive else negative. 0207 //! Returns the angular value in the range -PI and PI (in radians). Raises DomainError if <me> 0208 //! and <theOther> are not parallel this exception is raised when <theVRef> is in the same plane 0209 //! as <me> and <theOther> The tolerance criterion is Resolution from package gp. 0210 Standard_EXPORT double AngleWithRef(const gp_Dir& theOther, const gp_Dir& theVRef) const; 0211 0212 //! Computes the cross product between two directions 0213 //! Raises the exception ConstructionError if the two directions 0214 //! are parallel because the computed vector cannot be normalized 0215 //! to create a direction. 0216 //! @note Constexpr-compatible when result is already normalized. 0217 constexpr void Cross(const gp_Dir& theRight); 0218 0219 constexpr void operator^=(const gp_Dir& theRight) { Cross(theRight); } 0220 0221 //! Computes the triple vector product. 0222 //! <me> ^ (V1 ^ V2) 0223 //! Raises the exception ConstructionError if V1 and V2 are parallel 0224 //! or <me> and (V1^V2) are parallel because the computed vector 0225 //! can't be normalized to create a direction. 0226 //! @note Constexpr-compatible when result is already normalized. 0227 [[nodiscard]] constexpr gp_Dir Crossed(const gp_Dir& theRight) const; 0228 0229 [[nodiscard]] constexpr gp_Dir operator^(const gp_Dir& theRight) const 0230 { 0231 return Crossed(theRight); 0232 } 0233 0234 //! @note Constexpr-compatible when result is already normalized. 0235 constexpr void CrossCross(const gp_Dir& theV1, const gp_Dir& theV2); 0236 0237 //! Computes the double vector product this ^ (theV1 ^ theV2). 0238 //! - CrossCrossed creates a new unit vector. 0239 //! Exceptions 0240 //! Standard_ConstructionError if: 0241 //! - theV1 and theV2 are parallel, or 0242 //! - this unit vector and (theV1 ^ theV2) are parallel. 0243 //! This is because, in these conditions, the computed vector 0244 //! is null and cannot be normalized. 0245 //! @note Constexpr-compatible when result is already normalized. 0246 [[nodiscard]] constexpr gp_Dir CrossCrossed(const gp_Dir& theV1, const gp_Dir& theV2) const; 0247 0248 //! Computes the scalar product 0249 constexpr double Dot(const gp_Dir& theOther) const noexcept { return coord.Dot(theOther.coord); } 0250 0251 constexpr double operator*(const gp_Dir& theOther) const noexcept { return Dot(theOther); } 0252 0253 //! Computes the triple scalar product <me> * (theV1 ^ theV2). 0254 //! Warnings : 0255 //! The computed vector theV1' = theV1 ^ theV2 is not normalized 0256 //! to create a unitary vector. So this method never 0257 //! raises an exception even if theV1 and theV2 are parallel. 0258 constexpr double DotCross(const gp_Dir& theV1, const gp_Dir& theV2) const noexcept 0259 { 0260 return coord.Dot(theV1.coord.Crossed(theV2.coord)); 0261 } 0262 0263 constexpr void Reverse() noexcept { coord.Reverse(); } 0264 0265 //! Reverses the orientation of a direction 0266 //! geometric transformations 0267 //! Performs the symmetrical transformation of a direction 0268 //! with respect to the direction V which is the center of 0269 //! the symmetry. 0270 [[nodiscard]] constexpr gp_Dir Reversed() const noexcept 0271 { 0272 gp_Dir aV = *this; 0273 aV.coord.Reverse(); 0274 return aV; 0275 } 0276 0277 [[nodiscard]] constexpr gp_Dir operator-() const noexcept { return Reversed(); } 0278 0279 Standard_EXPORT void Mirror(const gp_Dir& theV) noexcept; 0280 0281 //! Performs the symmetrical transformation of a direction 0282 //! with respect to the direction theV which is the center 0283 //! of the symmetry. 0284 [[nodiscard]] Standard_EXPORT gp_Dir Mirrored(const gp_Dir& theV) const noexcept; 0285 0286 Standard_EXPORT void Mirror(const gp_Ax1& theA1) noexcept; 0287 0288 //! Performs the symmetrical transformation of a direction 0289 //! with respect to an axis placement which is the axis 0290 //! of the symmetry. 0291 [[nodiscard]] Standard_EXPORT gp_Dir Mirrored(const gp_Ax1& theA1) const noexcept; 0292 0293 Standard_EXPORT void Mirror(const gp_Ax2& theA2) noexcept; 0294 0295 //! Performs the symmetrical transformation of a direction 0296 //! with respect to a plane. The axis placement theA2 locates 0297 //! the plane of the symmetry : (Location, XDirection, YDirection). 0298 [[nodiscard]] Standard_EXPORT gp_Dir Mirrored(const gp_Ax2& theA2) const noexcept; 0299 0300 void Rotate(const gp_Ax1& theA1, const double theAng); 0301 0302 //! Rotates a direction. theA1 is the axis of the rotation. 0303 //! theAng is the angular value of the rotation in radians. 0304 [[nodiscard]] gp_Dir Rotated(const gp_Ax1& theA1, const double theAng) const 0305 { 0306 gp_Dir aV = *this; 0307 aV.Rotate(theA1, theAng); 0308 return aV; 0309 } 0310 0311 Standard_EXPORT void Transform(const gp_Trsf& theT); 0312 0313 //! Transforms a direction with a "Trsf" from gp. 0314 //! Warnings : 0315 //! If the scale factor of the "Trsf" theT is negative then the 0316 //! direction <me> is reversed. 0317 [[nodiscard]] gp_Dir Transformed(const gp_Trsf& theT) const 0318 { 0319 gp_Dir aV = *this; 0320 aV.Transform(theT); 0321 return aV; 0322 } 0323 0324 //! Dumps the content of me into the stream 0325 Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const; 0326 0327 //! Inits the content of me from the stream 0328 Standard_EXPORT bool InitFromJson(const Standard_SStream& theSStream, int& theStreamPos); 0329 0330 private: 0331 gp_XYZ coord; 0332 }; 0333 0334 #include <gp_Trsf.hxx> 0335 0336 //================================================================================================= 0337 0338 inline constexpr gp_Dir::gp_Dir(const gp_Vec& theV) 0339 : gp_Dir(theV.XYZ()) 0340 { 0341 } 0342 0343 //================================================================================================= 0344 0345 inline constexpr gp_Dir::gp_Dir(const gp_XYZ& theXYZ) 0346 : gp_Dir(theXYZ.X(), theXYZ.Y(), theXYZ.Z()) 0347 { 0348 } 0349 0350 //================================================================================================= 0351 0352 inline constexpr gp_Dir::gp_Dir(const double theXv, const double theYv, const double theZv) 0353 { 0354 const double aSqMod = theXv * theXv + theYv * theYv + theZv * theZv; 0355 0356 // Fast path: already normalized - fully constexpr 0357 if (aSqMod >= (1.0 - gp::Resolution()) && aSqMod <= (1.0 + gp::Resolution())) 0358 { 0359 coord.SetCoord(theXv, theYv, theZv); 0360 return; 0361 } 0362 0363 // Slow path: runtime only (sqrt not constexpr - compile error if reached in constexpr context) 0364 Standard_ConstructionError_Raise_if(aSqMod <= gp::Resolution() * gp::Resolution(), 0365 "gp_Dir() - input vector has zero norm"); 0366 const double aD = sqrt(aSqMod); 0367 coord.SetCoord(theXv / aD, theYv / aD, theZv / aD); 0368 } 0369 0370 //================================================================================================= 0371 0372 inline constexpr void gp_Dir::SetCoord(const int theIndex, const double theXi) 0373 { 0374 Standard_OutOfRange_Raise_if(theIndex < 1 || theIndex > 3, 0375 "gp_Dir::SetCoord() - index is out of range [1, 3]"); 0376 if (theIndex == 1) 0377 { 0378 SetX(theXi); 0379 } 0380 else if (theIndex == 2) 0381 { 0382 SetY(theXi); 0383 } 0384 else 0385 { 0386 SetZ(theXi); 0387 } 0388 } 0389 0390 //================================================================================================= 0391 0392 inline constexpr void gp_Dir::SetCoord(const double theXv, const double theYv, const double theZv) 0393 { 0394 const double aSqMod = theXv * theXv + theYv * theYv + theZv * theZv; 0395 0396 // Fast path: already normalized - fully constexpr 0397 if (aSqMod >= (1.0 - gp::Resolution()) && aSqMod <= (1.0 + gp::Resolution())) 0398 { 0399 coord.SetCoord(theXv, theYv, theZv); 0400 return; 0401 } 0402 0403 // Slow path: runtime only (sqrt not constexpr - compile error if reached in constexpr context) 0404 Standard_ConstructionError_Raise_if(aSqMod <= gp::Resolution() * gp::Resolution(), 0405 "gp_Dir::SetCoord() - input vector has zero norm"); 0406 const double aD = sqrt(aSqMod); 0407 coord.SetCoord(theXv / aD, theYv / aD, theZv / aD); 0408 } 0409 0410 //================================================================================================= 0411 0412 inline constexpr void gp_Dir::SetX(const double theX) 0413 { 0414 SetCoord(theX, coord.Y(), coord.Z()); 0415 } 0416 0417 //================================================================================================= 0418 0419 inline constexpr void gp_Dir::SetY(const double theY) 0420 { 0421 SetCoord(coord.X(), theY, coord.Z()); 0422 } 0423 0424 //================================================================================================= 0425 0426 inline constexpr void gp_Dir::SetZ(const double theZ) 0427 { 0428 SetCoord(coord.X(), coord.Y(), theZ); 0429 } 0430 0431 //================================================================================================= 0432 0433 inline constexpr void gp_Dir::SetXYZ(const gp_XYZ& theXYZ) 0434 { 0435 SetCoord(theXYZ.X(), theXYZ.Y(), theXYZ.Z()); 0436 } 0437 0438 //================================================================================================= 0439 0440 inline constexpr void gp_Dir::Cross(const gp_Dir& theRight) 0441 { 0442 coord.Cross(theRight.coord); 0443 const double aSqMod = coord.SquareModulus(); 0444 0445 // Fast path: already normalized - fully constexpr 0446 if (aSqMod >= (1.0 - gp::Resolution()) && aSqMod <= (1.0 + gp::Resolution())) 0447 { 0448 return; 0449 } 0450 0451 // Slow path: runtime only (sqrt not constexpr - compile error if reached in constexpr context) 0452 Standard_ConstructionError_Raise_if(aSqMod <= gp::Resolution() * gp::Resolution(), 0453 "gp_Dir::Cross() - result vector has zero norm"); 0454 coord.Divide(sqrt(aSqMod)); 0455 } 0456 0457 //================================================================================================= 0458 0459 inline constexpr gp_Dir gp_Dir::Crossed(const gp_Dir& theRight) const 0460 { 0461 gp_Dir aV = *this; 0462 aV.Cross(theRight); 0463 return aV; 0464 } 0465 0466 //================================================================================================= 0467 0468 inline constexpr void gp_Dir::CrossCross(const gp_Dir& theV1, const gp_Dir& theV2) 0469 { 0470 coord.CrossCross(theV1.coord, theV2.coord); 0471 const double aSqMod = coord.SquareModulus(); 0472 0473 // Fast path: already normalized - fully constexpr 0474 if (aSqMod >= (1.0 - gp::Resolution()) && aSqMod <= (1.0 + gp::Resolution())) 0475 { 0476 return; 0477 } 0478 0479 // Slow path: runtime only (sqrt not constexpr - compile error if reached in constexpr context) 0480 Standard_ConstructionError_Raise_if(aSqMod <= gp::Resolution() * gp::Resolution(), 0481 "gp_Dir::CrossCross() - result vector has zero norm"); 0482 coord.Divide(sqrt(aSqMod)); 0483 } 0484 0485 //================================================================================================= 0486 0487 inline constexpr gp_Dir gp_Dir::CrossCrossed(const gp_Dir& theV1, const gp_Dir& theV2) const 0488 { 0489 gp_Dir aV = *this; 0490 aV.CrossCross(theV1, theV2); 0491 return aV; 0492 } 0493 0494 //================================================================================================= 0495 0496 inline void gp_Dir::Rotate(const gp_Ax1& theA1, const double theAng) 0497 { 0498 gp_Trsf aT; 0499 aT.SetRotation(theA1, theAng); 0500 coord.Multiply(aT.HVectorialPart()); 0501 } 0502 0503 #endif // _gp_Dir_HeaderFile
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|