Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-29 09:19:13

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_Ax2_HeaderFile
0016 #define _gp_Ax2_HeaderFile
0017 
0018 #include <gp_Ax1.hxx>
0019 #include <gp_Dir.hxx>
0020 #include <Precision.hxx>
0021 
0022 class gp_Trsf;
0023 class gp_Vec;
0024 
0025 //! Describes a right-handed coordinate system in 3D space.
0026 //! A coordinate system is defined by:
0027 //! -   its origin (also referred to as its "Location point"), and
0028 //! -   three orthogonal unit vectors, termed respectively the
0029 //! "X Direction", the "Y Direction" and the "Direction" (also
0030 //! referred to as the "main Direction").
0031 //! The "Direction" of the coordinate system is called its
0032 //! "main Direction" because whenever this unit vector is
0033 //! modified, the "X Direction" and the "Y Direction" are
0034 //! recomputed. However, when we modify either the "X
0035 //! Direction" or the "Y Direction", "Direction" is not modified.
0036 //! The "main Direction" is also the "Z Direction".
0037 //! Since an Ax2 coordinate system is right-handed, its
0038 //! "main Direction" is always equal to the cross product of
0039 //! its "X Direction" and "Y Direction". (To define a
0040 //! left-handed coordinate system, use gp_Ax3.)
0041 //! A coordinate system is used:
0042 //! -   to describe geometric entities, in particular to position
0043 //! them. The local coordinate system of a geometric
0044 //! entity serves the same purpose as the STEP function
0045 //! "axis placement two axes", or
0046 //! -   to define geometric transformations.
0047 //! Note: we refer to the "X Axis", "Y Axis" and "Z Axis",
0048 //! respectively, as to axes having:
0049 //! - the origin of the coordinate system as their origin, and
0050 //! -   the unit vectors "X Direction", "Y Direction" and "main
0051 //! Direction", respectively, as their unit vectors.
0052 //! The "Z Axis" is also the "main Axis".
0053 class gp_Ax2
0054 {
0055 public:
0056   DEFINE_STANDARD_ALLOC
0057 
0058   //! Creates an object corresponding to the reference
0059   //! coordinate system (OXYZ).
0060   constexpr gp_Ax2() noexcept
0061       : vydir(gp_Dir::D::Y),
0062         vxdir(gp_Dir::D::X)
0063   // axis uses default ctor which creates Z axis at origin
0064   {
0065   }
0066 
0067   //! Creates an axis placement with an origin P such that:
0068   //! -   N is the Direction, and
0069   //! -   the "X Direction" is normal to N, in the plane
0070   //! defined by the vectors (N, Vx): "X
0071   //! Direction" = (N ^ Vx) ^ N,
0072   //! Exception: raises ConstructionError if N and Vx are parallel (same or opposite orientation).
0073   gp_Ax2(const gp_Pnt& P, const gp_Dir& N, const gp_Dir& Vx)
0074       : axis(P, N),
0075         vydir(N),
0076         vxdir(N)
0077   {
0078     vxdir.CrossCross(Vx, N);
0079     vydir.Cross(vxdir);
0080   }
0081 
0082   //! Creates an axis placement with standard directions.
0083   constexpr gp_Ax2(const gp_Pnt& theP, const gp_Dir::D theN, const gp_Dir::D theVx) noexcept
0084       : axis(theP, theN),
0085         vydir(crossStandardDir(theN, theVx)), // Y = Z x X (right-handed)
0086         vxdir(theVx)
0087   {
0088     // Note: For standard directions, cross product is computed at compile time
0089     // This constructor assumes theN and theVx are orthogonal standard directions
0090   }
0091 
0092   //! Creates a coordinate system with an origin P, where V
0093   //! gives the "main Direction" (here, "X Direction" and "Y
0094   //! Direction" are defined automatically).
0095   Standard_EXPORT gp_Ax2(const gp_Pnt& P, const gp_Dir& V);
0096 
0097   //! Creates a coordinate system with an origin P and standard main direction.
0098   constexpr gp_Ax2(const gp_Pnt& theP, const gp_Dir::D theV) noexcept
0099       : axis(theP, theV),
0100         vydir(getPerpendicularYDir(theV)),
0101         vxdir(getPerpendicularXDir(theV))
0102   {
0103   }
0104 
0105   //! Creates a coordinate system at the origin with the given standard main direction.
0106   //! Replaces gp::XOY(), gp::YOZ(), gp::ZOX() static functions.
0107   constexpr explicit gp_Ax2(const gp_Dir::D theV) noexcept
0108       : axis(gp_Pnt(0., 0., 0.), theV),
0109         vydir(getPerpendicularYDir(theV)),
0110         vxdir(getPerpendicularXDir(theV))
0111   {
0112   }
0113 
0114   //! Assigns the origin and "main Direction" of the axis A1 to
0115   //! this coordinate system, then recomputes its "X Direction" and "Y Direction".
0116   //! Note: The new "X Direction" is computed as follows:
0117   //! new "X Direction" = V1 ^(previous "X Direction" ^ V)
0118   //! where V is the "Direction" of A1.
0119   //! Exceptions
0120   //! Standard_ConstructionError if A1 is parallel to the "X
0121   //! Direction" of this coordinate system.
0122   void SetAxis(const gp_Ax1& A1);
0123 
0124   //! Changes the "main Direction" of this coordinate system,
0125   //! then recomputes its "X Direction" and "Y Direction".
0126   //! Note: the new "X Direction" is computed as follows:
0127   //! new "X Direction" = V ^ (previous "X Direction" ^ V)
0128   //! Exceptions
0129   //! Standard_ConstructionError if V is parallel to the "X
0130   //! Direction" of this coordinate system.
0131   void SetDirection(const gp_Dir& V);
0132 
0133   //! Changes the "Location" point (origin) of <me>.
0134   constexpr void SetLocation(const gp_Pnt& theP) noexcept { axis.SetLocation(theP); }
0135 
0136   //! Changes the "Xdirection" of <me>. The main direction
0137   //! "Direction" is not modified, the "Ydirection" is modified.
0138   //! If <Vx> is not normal to the main direction then <XDirection>
0139   //! is computed as follows XDirection = Direction ^ (Vx ^ Direction).
0140   //! Exceptions
0141   //! Standard_ConstructionError if Vx or Vy is parallel to
0142   //! the "main Direction" of this coordinate system.
0143   void SetXDirection(const gp_Dir& theVx)
0144   {
0145     vxdir = axis.Direction().CrossCrossed(theVx, axis.Direction());
0146     vydir = axis.Direction().Crossed(vxdir);
0147   }
0148 
0149   //! Changes the "Ydirection" of <me>. The main direction is not
0150   //! modified but the "Xdirection" is changed.
0151   //! If <Vy> is not normal to the main direction then "YDirection"
0152   //! is computed as follows
0153   //! YDirection = Direction ^ (<Vy> ^ Direction).
0154   //! Exceptions
0155   //! Standard_ConstructionError if Vx or Vy is parallel to
0156   //! the "main Direction" of this coordinate system.
0157   void SetYDirection(const gp_Dir& theVy)
0158   {
0159     vxdir = theVy.Crossed(axis.Direction());
0160     vydir = (axis.Direction()).Crossed(vxdir);
0161   }
0162 
0163   //! Computes the angular value, in radians, between the main direction of
0164   //! <me> and the main direction of <theOther>. Returns the angle
0165   //! between 0 and PI in radians.
0166   double Angle(const gp_Ax2& theOther) const { return axis.Angle(theOther.axis); }
0167 
0168   //! Returns the main axis of <me>. It is the "Location" point
0169   //! and the main "Direction".
0170   constexpr const gp_Ax1& Axis() const noexcept { return axis; }
0171 
0172   //! Returns the main direction of <me>.
0173   constexpr const gp_Dir& Direction() const noexcept { return axis.Direction(); }
0174 
0175   //! Returns the "Location" point (origin) of <me>.
0176   constexpr const gp_Pnt& Location() const noexcept { return axis.Location(); }
0177 
0178   //! Returns the "XDirection" of <me>.
0179   constexpr const gp_Dir& XDirection() const noexcept { return vxdir; }
0180 
0181   //! Returns the "YDirection" of <me>.
0182   constexpr const gp_Dir& YDirection() const noexcept { return vydir; }
0183 
0184   bool IsCoplanar(const gp_Ax2& Other,
0185                   const double  LinearTolerance,
0186                   const double  AngularTolerance) const;
0187 
0188   //! Returns True if:
0189   //! . the distance between <me> and the "Location" point of A1
0190   //! is lower of equal to LinearTolerance and
0191   //! . the main direction of <me> and the direction of A1 are normal.
0192   //! Note: the tolerance criterion for angular equality is given by AngularTolerance.
0193   bool IsCoplanar(const gp_Ax1& A1,
0194                   const double  LinearTolerance,
0195                   const double  AngularTolerance) const;
0196 
0197   //! Performs a symmetrical transformation of this coordinate
0198   //! system with respect to:
0199   //! -   the point P, and assigns the result to this coordinate system.
0200   //! Warning
0201   //! This transformation is always performed on the origin.
0202   //! In case of a reflection with respect to a point:
0203   //! - the main direction of the coordinate system is not changed, and
0204   //! - the "X Direction" and the "Y Direction" are simply reversed
0205   //! In case of a reflection with respect to an axis or a plane:
0206   //! -   the transformation is applied to the "X Direction"
0207   //! and the "Y Direction", then
0208   //! -   the "main Direction" is recomputed as the cross
0209   //! product "X Direction" ^ "Y Direction".
0210   //! This maintains the right-handed property of the
0211   //! coordinate system.
0212   Standard_EXPORT void Mirror(const gp_Pnt& P) noexcept;
0213 
0214   //! Performs a symmetrical transformation of this coordinate
0215   //! system with respect to:
0216   //! -   the point P, and creates a new one.
0217   //! Warning
0218   //! This transformation is always performed on the origin.
0219   //! In case of a reflection with respect to a point:
0220   //! - the main direction of the coordinate system is not changed, and
0221   //! - the "X Direction" and the "Y Direction" are simply reversed
0222   //! In case of a reflection with respect to an axis or a plane:
0223   //! -   the transformation is applied to the "X Direction"
0224   //! and the "Y Direction", then
0225   //! -   the "main Direction" is recomputed as the cross
0226   //! product "X Direction" ^ "Y Direction".
0227   //! This maintains the right-handed property of the
0228   //! coordinate system.
0229   [[nodiscard]] Standard_EXPORT gp_Ax2 Mirrored(const gp_Pnt& P) const noexcept;
0230 
0231   //! Performs a symmetrical transformation of this coordinate
0232   //! system with respect to:
0233   //! -   the axis A1, and assigns the result to this coordinate system.
0234   //! Warning
0235   //! This transformation is always performed on the origin.
0236   //! In case of a reflection with respect to a point:
0237   //! - the main direction of the coordinate system is not changed, and
0238   //! - the "X Direction" and the "Y Direction" are simply reversed
0239   //! In case of a reflection with respect to an axis or a plane:
0240   //! -   the transformation is applied to the "X Direction"
0241   //! and the "Y Direction", then
0242   //! -   the "main Direction" is recomputed as the cross
0243   //! product "X Direction" ^ "Y Direction".
0244   //! This maintains the right-handed property of the
0245   //! coordinate system.
0246   Standard_EXPORT void Mirror(const gp_Ax1& A1);
0247 
0248   //! Performs a symmetrical transformation of this coordinate
0249   //! system with respect to:
0250   //! -   the axis A1, and creates a new one.
0251   //! Warning
0252   //! This transformation is always performed on the origin.
0253   //! In case of a reflection with respect to a point:
0254   //! - the main direction of the coordinate system is not changed, and
0255   //! - the "X Direction" and the "Y Direction" are simply reversed
0256   //! In case of a reflection with respect to an axis or a plane:
0257   //! -   the transformation is applied to the "X Direction"
0258   //! and the "Y Direction", then
0259   //! -   the "main Direction" is recomputed as the cross
0260   //! product "X Direction" ^ "Y Direction".
0261   //! This maintains the right-handed property of the
0262   //! coordinate system.
0263   [[nodiscard]] Standard_EXPORT gp_Ax2 Mirrored(const gp_Ax1& A1) const;
0264 
0265   //! Performs a symmetrical transformation of this coordinate
0266   //! system with respect to:
0267   //! -   the plane defined by the origin, "X Direction" and "Y
0268   //! Direction" of coordinate system A2 and assigns the result to this coordinate system.
0269   //! Warning
0270   //! This transformation is always performed on the origin.
0271   //! In case of a reflection with respect to a point:
0272   //! - the main direction of the coordinate system is not changed, and
0273   //! - the "X Direction" and the "Y Direction" are simply reversed
0274   //! In case of a reflection with respect to an axis or a plane:
0275   //! -   the transformation is applied to the "X Direction"
0276   //! and the "Y Direction", then
0277   //! -   the "main Direction" is recomputed as the cross
0278   //! product "X Direction" ^ "Y Direction".
0279   //! This maintains the right-handed property of the
0280   //! coordinate system.
0281   Standard_EXPORT void Mirror(const gp_Ax2& A2);
0282 
0283   //! Performs a symmetrical transformation of this coordinate
0284   //! system with respect to:
0285   //! -   the plane defined by the origin, "X Direction" and "Y
0286   //! Direction" of coordinate system A2 and creates a new one.
0287   //! Warning
0288   //! This transformation is always performed on the origin.
0289   //! In case of a reflection with respect to a point:
0290   //! - the main direction of the coordinate system is not changed, and
0291   //! - the "X Direction" and the "Y Direction" are simply reversed
0292   //! In case of a reflection with respect to an axis or a plane:
0293   //! -   the transformation is applied to the "X Direction"
0294   //! and the "Y Direction", then
0295   //! -   the "main Direction" is recomputed as the cross
0296   //! product "X Direction" ^ "Y Direction".
0297   //! This maintains the right-handed property of the
0298   //! coordinate system.
0299   [[nodiscard]] Standard_EXPORT gp_Ax2 Mirrored(const gp_Ax2& A2) const;
0300 
0301   void Rotate(const gp_Ax1& theA1, const double theAng)
0302   {
0303     gp_Pnt aTemp = axis.Location();
0304     aTemp.Rotate(theA1, theAng);
0305     axis.SetLocation(aTemp);
0306     vxdir.Rotate(theA1, theAng);
0307     vydir.Rotate(theA1, theAng);
0308     axis.SetDirection(vxdir.Crossed(vydir));
0309   }
0310 
0311   //! Rotates an axis placement. <theA1> is the axis of the rotation.
0312   //! theAng is the angular value of the rotation in radians.
0313   [[nodiscard]] gp_Ax2 Rotated(const gp_Ax1& theA1, const double theAng) const
0314   {
0315     gp_Ax2 aTemp = *this;
0316     aTemp.Rotate(theA1, theAng);
0317     return aTemp;
0318   }
0319 
0320   constexpr void Scale(const gp_Pnt& theP, const double theS) noexcept
0321   {
0322     gp_Pnt aTemp = axis.Location();
0323     aTemp.Scale(theP, theS);
0324     axis.SetLocation(aTemp);
0325     if (theS < 0.0)
0326     {
0327       vxdir.Reverse();
0328       vydir.Reverse();
0329     }
0330   }
0331 
0332   //! Applies a scaling transformation on the axis placement.
0333   //! The "Location" point of the axisplacement is modified.
0334   //! Warnings:
0335   //! If the scale <S> is negative:
0336   //! . the main direction of the axis placement is not changed.
0337   //! . The "XDirection" and the "YDirection" are reversed.
0338   //! So the axis placement stay right handed.
0339   [[nodiscard]] constexpr gp_Ax2 Scaled(const gp_Pnt& theP, const double theS) const noexcept
0340   {
0341     gp_Ax2 aTemp = *this;
0342     aTemp.Scale(theP, theS);
0343     return aTemp;
0344   }
0345 
0346   void Transform(const gp_Trsf& theT)
0347   {
0348     gp_Pnt aTemp = axis.Location();
0349     aTemp.Transform(theT);
0350     axis.SetLocation(aTemp);
0351     vxdir.Transform(theT);
0352     vydir.Transform(theT);
0353     axis.SetDirection(vxdir.Crossed(vydir));
0354   }
0355 
0356   //! Transforms an axis placement with a Trsf.
0357   //! The "Location" point, the "XDirection" and the "YDirection" are transformed with theT.
0358   //! The resulting main "Direction" of <me> is the cross product between
0359   //! the "XDirection" and the "YDirection" after transformation.
0360   [[nodiscard]] gp_Ax2 Transformed(const gp_Trsf& theT) const
0361   {
0362     gp_Ax2 aTemp = *this;
0363     aTemp.Transform(theT);
0364     return aTemp;
0365   }
0366 
0367   constexpr void Translate(const gp_Vec& theV) noexcept { axis.Translate(theV); }
0368 
0369   //! Translates an axis plaxement in the direction of the vector <theV>.
0370   //! The magnitude of the translation is the vector's magnitude.
0371   [[nodiscard]] constexpr gp_Ax2 Translated(const gp_Vec& theV) const noexcept
0372   {
0373     gp_Ax2 aTemp = *this;
0374     aTemp.Translate(theV);
0375     return aTemp;
0376   }
0377 
0378   constexpr void Translate(const gp_Pnt& theP1, const gp_Pnt& theP2) noexcept
0379   {
0380     axis.Translate(theP1, theP2);
0381   }
0382 
0383   //! Translates an axis placement from the point <theP1> to the point <theP2>.
0384   [[nodiscard]] constexpr gp_Ax2 Translated(const gp_Pnt& theP1, const gp_Pnt& theP2) const noexcept
0385   {
0386     gp_Ax2 aTemp = *this;
0387     aTemp.Translate(theP1, theP2);
0388     return aTemp;
0389   }
0390 
0391   //! Dumps the content of me into the stream
0392   Standard_EXPORT void DumpJson(Standard_OStream& theOStream, int theDepth = -1) const;
0393 
0394   //! Inits the content of me from the stream
0395   Standard_EXPORT bool InitFromJson(const Standard_SStream& theSStream, int& theStreamPos);
0396 
0397 protected:
0398   //! Helper to compute perpendicular X direction for standard main directions
0399   static constexpr gp_Dir::D getPerpendicularXDir(const gp_Dir::D theMainDir) noexcept;
0400 
0401   //! Helper to compute Y direction (main x X) for standard directions
0402   static constexpr gp_Dir::D getPerpendicularYDir(const gp_Dir::D theMainDir) noexcept;
0403 
0404   //! Helper to compute cross product of two standard directions (right-handed: A x B)
0405   static constexpr gp_Dir::D crossStandardDir(const gp_Dir::D theA, const gp_Dir::D theB) noexcept;
0406 
0407 private:
0408   gp_Ax1 axis;
0409   gp_Dir vydir;
0410   gp_Dir vxdir;
0411 };
0412 
0413 //=================================================================================================
0414 
0415 inline constexpr gp_Dir::D gp_Ax2::getPerpendicularXDir(const gp_Dir::D theMainDir) noexcept
0416 {
0417   return (theMainDir == gp_Dir::D::X || theMainDir == gp_Dir::D::NX)   ? gp_Dir::D::Y
0418          : (theMainDir == gp_Dir::D::Y || theMainDir == gp_Dir::D::NY) ? gp_Dir::D::Z
0419                                                                        : gp_Dir::D::X;
0420 }
0421 
0422 //=================================================================================================
0423 
0424 inline constexpr gp_Dir::D gp_Ax2::getPerpendicularYDir(const gp_Dir::D theMainDir) noexcept
0425 {
0426   return (theMainDir == gp_Dir::D::Z)    ? gp_Dir::D::Y
0427          : (theMainDir == gp_Dir::D::NZ) ? gp_Dir::D::NY
0428          : (theMainDir == gp_Dir::D::X)  ? gp_Dir::D::Z
0429          : (theMainDir == gp_Dir::D::NX) ? gp_Dir::D::NZ
0430          : (theMainDir == gp_Dir::D::Y)  ? gp_Dir::D::X
0431                                          : gp_Dir::D::NX; // NY case
0432 }
0433 
0434 //=================================================================================================
0435 
0436 inline constexpr gp_Dir::D gp_Ax2::crossStandardDir(const gp_Dir::D theA,
0437                                                     const gp_Dir::D theB) noexcept
0438 {
0439   // Handle positive directions first
0440   if (theA == gp_Dir::D::X)
0441   {
0442     if (theB == gp_Dir::D::Y)
0443       return gp_Dir::D::Z;
0444     if (theB == gp_Dir::D::Z)
0445       return gp_Dir::D::NY;
0446     if (theB == gp_Dir::D::NY)
0447       return gp_Dir::D::NZ;
0448     if (theB == gp_Dir::D::NZ)
0449       return gp_Dir::D::Y;
0450     // X x X = 0, X x NX = 0 (parallel, should not happen)
0451     return gp_Dir::D::Z; // fallback
0452   }
0453   if (theA == gp_Dir::D::Y)
0454   {
0455     if (theB == gp_Dir::D::Z)
0456       return gp_Dir::D::X;
0457     if (theB == gp_Dir::D::X)
0458       return gp_Dir::D::NZ;
0459     if (theB == gp_Dir::D::NX)
0460       return gp_Dir::D::Z;
0461     if (theB == gp_Dir::D::NZ)
0462       return gp_Dir::D::NX;
0463     // Y x Y = 0, Y x NY = 0 (parallel, should not happen)
0464     return gp_Dir::D::X; // fallback
0465   }
0466   if (theA == gp_Dir::D::Z)
0467   {
0468     if (theB == gp_Dir::D::X)
0469       return gp_Dir::D::Y;
0470     if (theB == gp_Dir::D::Y)
0471       return gp_Dir::D::NX;
0472     if (theB == gp_Dir::D::NX)
0473       return gp_Dir::D::NY;
0474     if (theB == gp_Dir::D::NY)
0475       return gp_Dir::D::X;
0476     // Z x Z = 0, Z x NZ = 0 (parallel, should not happen)
0477     return gp_Dir::D::Y; // fallback
0478   }
0479   // Handle negative directions: -A x B = -(A x B)
0480   if (theA == gp_Dir::D::NX)
0481   {
0482     if (theB == gp_Dir::D::Y)
0483       return gp_Dir::D::NZ;
0484     if (theB == gp_Dir::D::Z)
0485       return gp_Dir::D::Y;
0486     if (theB == gp_Dir::D::NY)
0487       return gp_Dir::D::Z;
0488     if (theB == gp_Dir::D::NZ)
0489       return gp_Dir::D::NY;
0490     return gp_Dir::D::NZ; // fallback
0491   }
0492   if (theA == gp_Dir::D::NY)
0493   {
0494     if (theB == gp_Dir::D::Z)
0495       return gp_Dir::D::NX;
0496     if (theB == gp_Dir::D::X)
0497       return gp_Dir::D::Z;
0498     if (theB == gp_Dir::D::NX)
0499       return gp_Dir::D::NZ;
0500     if (theB == gp_Dir::D::NZ)
0501       return gp_Dir::D::X;
0502     return gp_Dir::D::NX; // fallback
0503   }
0504   if (theA == gp_Dir::D::NZ)
0505   {
0506     if (theB == gp_Dir::D::X)
0507       return gp_Dir::D::NY;
0508     if (theB == gp_Dir::D::Y)
0509       return gp_Dir::D::X;
0510     if (theB == gp_Dir::D::NX)
0511       return gp_Dir::D::Y;
0512     if (theB == gp_Dir::D::NY)
0513       return gp_Dir::D::NX;
0514     return gp_Dir::D::NY; // fallback
0515   }
0516   return gp_Dir::D::Z; // fallback
0517 }
0518 
0519 //=================================================================================================
0520 
0521 inline void gp_Ax2::SetAxis(const gp_Ax1& theA1)
0522 {
0523   double a = theA1.Direction() * vxdir;
0524   if (std::abs(std::abs(a) - 1.) <= Precision::Angular())
0525   {
0526     if (a > 0.)
0527     {
0528       vxdir = vydir;
0529       vydir = axis.Direction();
0530       axis  = theA1;
0531     }
0532     else
0533     {
0534       vxdir = axis.Direction();
0535       axis  = theA1;
0536     }
0537   }
0538   else
0539   {
0540     axis  = theA1;
0541     vxdir = axis.Direction().CrossCrossed(vxdir, axis.Direction());
0542     vydir = axis.Direction().Crossed(vxdir);
0543   }
0544 }
0545 
0546 //=================================================================================================
0547 
0548 inline void gp_Ax2::SetDirection(const gp_Dir& theV)
0549 {
0550   double a = theV * vxdir;
0551   if (std::abs(std::abs(a) - 1.) <= Precision::Angular())
0552   {
0553     if (a > 0.)
0554     {
0555       vxdir = vydir;
0556       vydir = axis.Direction();
0557       axis.SetDirection(theV);
0558     }
0559     else
0560     {
0561       vxdir = axis.Direction();
0562       axis.SetDirection(theV);
0563     }
0564   }
0565   else
0566   {
0567     axis.SetDirection(theV);
0568     vxdir = theV.CrossCrossed(vxdir, theV);
0569     vydir = theV.Crossed(vxdir);
0570   }
0571 }
0572 
0573 //=================================================================================================
0574 
0575 inline bool gp_Ax2::IsCoplanar(const gp_Ax2& theOther,
0576                                const double  theLinearTolerance,
0577                                const double  theAngularTolerance) const
0578 {
0579   const gp_Dir& DD = axis.Direction();
0580   const gp_Pnt& PP = axis.Location();
0581   const gp_Pnt& OP = theOther.axis.Location();
0582   double        D1 =
0583     (DD.X() * (OP.X() - PP.X()) + DD.Y() * (OP.Y() - PP.Y()) + DD.Z() * (OP.Z() - PP.Z()));
0584   if (D1 < 0)
0585   {
0586     D1 = -D1;
0587   }
0588   return D1 <= theLinearTolerance && axis.IsParallel(theOther.axis, theAngularTolerance);
0589 }
0590 
0591 //=================================================================================================
0592 
0593 inline bool gp_Ax2::IsCoplanar(const gp_Ax1& theA,
0594                                const double  theLinearTolerance,
0595                                const double  theAngularTolerance) const
0596 {
0597   const gp_Dir& DD = axis.Direction();
0598   const gp_Pnt& PP = axis.Location();
0599   const gp_Pnt& AP = theA.Location();
0600   double        D1 =
0601     (DD.X() * (AP.X() - PP.X()) + DD.Y() * (AP.Y() - PP.Y()) + DD.Z() * (AP.Z() - PP.Z()));
0602   if (D1 < 0)
0603   {
0604     D1 = -D1;
0605   }
0606   return D1 <= theLinearTolerance && axis.IsNormal(theA, theAngularTolerance);
0607 }
0608 
0609 #endif // _gp_Ax2_HeaderFile