1 // Created on: 1993-08-02
2 // Created by: Laurent BOURESCHE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #ifndef _gp_Ax3_HeaderFile
18 #define _gp_Ax3_HeaderFile
28 //! Describes a coordinate system in 3D space. Unlike a
29 //! gp_Ax2 coordinate system, a gp_Ax3 can be
30 //! right-handed ("direct sense") or left-handed ("indirect sense").
31 //! A coordinate system is defined by:
32 //! - its origin (also referred to as its "Location point"), and
33 //! - three orthogonal unit vectors, termed the "X
34 //! Direction", the "Y Direction" and the "Direction" (also
35 //! referred to as the "main Direction").
36 //! The "Direction" of the coordinate system is called its
37 //! "main Direction" because whenever this unit vector is
38 //! modified, the "X Direction" and the "Y Direction" are
39 //! recomputed. However, when we modify either the "X
40 //! Direction" or the "Y Direction", "Direction" is not modified.
41 //! "Direction" is also the "Z Direction".
42 //! The "main Direction" is always parallel to the cross
43 //! product of its "X Direction" and "Y Direction".
44 //! If the coordinate system is right-handed, it satisfies the equation:
45 //! "main Direction" = "X Direction" ^ "Y Direction"
46 //! and if it is left-handed, it satisfies the equation:
47 //! "main Direction" = -"X Direction" ^ "Y Direction"
48 //! A coordinate system is used:
49 //! - to describe geometric entities, in particular to position
50 //! them. The local coordinate system of a geometric
51 //! entity serves the same purpose as the STEP function
52 //! "axis placement three axes", or
53 //! - to define geometric transformations.
55 //! - We refer to the "X Axis", "Y Axis" and "Z Axis",
56 //! respectively, as the axes having:
57 //! - the origin of the coordinate system as their origin, and
58 //! - the unit vectors "X Direction", "Y Direction" and
59 //! "main Direction", respectively, as their unit vectors.
60 //! - The "Z Axis" is also the "main Axis".
61 //! - gp_Ax2 is used to define a coordinate system that must be always right-handed.
68 //! Creates an object corresponding to the reference
69 //! coordinate system (OXYZ).
70 gp_Ax3() : vydir (0., 1., 0.)
71 // vxdir(1.,0.,0.) use default ctor of gp_Dir, as it creates the same dir(1,0,0)
74 //! Creates a coordinate system from a right-handed
75 //! coordinate system.
76 gp_Ax3 (const gp_Ax2& theA);
78 //! Creates a right handed axis placement with the
79 //! "Location" point theP and two directions, theN gives the
80 //! "Direction" and theVx gives the "XDirection".
81 //! Raises ConstructionError if theN and theVx are parallel (same or opposite orientation).
82 gp_Ax3 (const gp_Pnt& theP, const gp_Dir& theN, const gp_Dir& theVx)
87 vxdir.CrossCross (theVx, theN);
91 //! Creates an axis placement with the "Location" point <theP>
92 //! and the normal direction <theV>.
93 Standard_EXPORT gp_Ax3 (const gp_Pnt& theP, const gp_Dir& theV);
95 //! Reverses the X direction of <me>.
96 void XReverse() { vxdir.Reverse(); }
98 //! Reverses the Y direction of <me>.
99 void YReverse() { vydir.Reverse(); }
101 //! Reverses the Z direction of <me>.
102 void ZReverse() { axis.Reverse(); }
104 //! Assigns the origin and "main Direction" of the axis theA1 to
105 //! this coordinate system, then recomputes its "X Direction" and "Y Direction".
107 //! - The new "X Direction" is computed as follows:
108 //! new "X Direction" = V1 ^(previous "X Direction" ^ V)
109 //! where V is the "Direction" of theA1.
110 //! - The orientation of this coordinate system
111 //! (right-handed or left-handed) is not modified.
112 //! Raises ConstructionError if the "Direction" of <theA1> and the "XDirection" of <me>
113 //! are parallel (same or opposite orientation) because it is
114 //! impossible to calculate the new "XDirection" and the new
116 void SetAxis (const gp_Ax1& theA1);
118 //! Changes the main direction of this coordinate system,
119 //! then recomputes its "X Direction" and "Y Direction".
121 //! - The new "X Direction" is computed as follows:
122 //! new "X Direction" = theV ^ (previous "X Direction" ^ theV).
123 //! - The orientation of this coordinate system (left- or right-handed) is not modified.
124 //! Raises ConstructionError if <theV> and the previous "XDirection" are parallel
125 //! because it is impossible to calculate the new "XDirection"
126 //! and the new "YDirection".
127 void SetDirection (const gp_Dir& theV);
129 //! Changes the "Location" point (origin) of <me>.
130 void SetLocation (const gp_Pnt& theP) { axis.SetLocation (theP); }
132 //! Changes the "Xdirection" of <me>. The main direction
133 //! "Direction" is not modified, the "Ydirection" is modified.
134 //! If <theVx> is not normal to the main direction then <XDirection>
135 //! is computed as follows XDirection = Direction ^ (theVx ^ Direction).
136 //! Raises ConstructionError if <theVx> is parallel (same or opposite
137 //! orientation) to the main direction of <me>
138 void SetXDirection (const gp_Dir& theVx);
140 //! Changes the "Ydirection" of <me>. The main direction is not
141 //! modified but the "Xdirection" is changed.
142 //! If <theVy> is not normal to the main direction then "YDirection"
143 //! is computed as follows
144 //! YDirection = Direction ^ (<theVy> ^ Direction).
145 //! Raises ConstructionError if <theVy> is parallel to the main direction of <me>
146 void SetYDirection (const gp_Dir& theVy);
148 //! Computes the angular value between the main direction of
149 //! <me> and the main direction of <theOther>. Returns the angle
150 //! between 0 and PI in radians.
151 Standard_Real Angle (const gp_Ax3& theOther) const { return axis.Angle (theOther.axis); }
153 //! Returns the main axis of <me>. It is the "Location" point
154 //! and the main "Direction".
155 const gp_Ax1& Axis() const { return axis; }
157 //! Computes a right-handed coordinate system with the
158 //! same "X Direction" and "Y Direction" as those of this
159 //! coordinate system, then recomputes the "main Direction".
160 //! If this coordinate system is right-handed, the result
161 //! returned is the same coordinate system. If this
162 //! coordinate system is left-handed, the result is reversed.
165 //! Returns the main direction of <me>.
166 const gp_Dir& Direction() const { return axis.Direction(); }
168 //! Returns the "Location" point (origin) of <me>.
169 const gp_Pnt& Location() const { return axis.Location(); }
171 //! Returns the "XDirection" of <me>.
172 const gp_Dir& XDirection() const { return vxdir; }
174 //! Returns the "YDirection" of <me>.
175 const gp_Dir& YDirection() const { return vydir; }
177 //! Returns True if the coordinate system is right-handed. i.e.
178 //! XDirection().Crossed(YDirection()).Dot(Direction()) > 0
179 Standard_Boolean Direct() const { return (vxdir.Crossed (vydir).Dot (axis.Direction()) > 0.); }
182 //! . the distance between the "Location" point of <me> and
183 //! <theOther> is lower or equal to theLinearTolerance and
184 //! . the distance between the "Location" point of <theOther> and
185 //! <me> is lower or equal to theLinearTolerance and
186 //! . the main direction of <me> and the main direction of
187 //! <theOther> are parallel (same or opposite orientation).
188 Standard_Boolean IsCoplanar (const gp_Ax3& theOther, const Standard_Real theLinearTolerance, const Standard_Real theAngularTolerance) const;
191 //! . the distance between <me> and the "Location" point of theA1
192 //! is lower of equal to theLinearTolerance and
193 //! . the distance between theA1 and the "Location" point of <me>
194 //! is lower or equal to theLinearTolerance and
195 //! . the main direction of <me> and the direction of theA1 are normal.
196 Standard_Boolean IsCoplanar (const gp_Ax1& theA1, const Standard_Real theLinearTolerance, const Standard_Real theAngularTolerance) const;
198 Standard_EXPORT void Mirror (const gp_Pnt& theP);
200 //! Performs the symmetrical transformation of an axis
201 //! placement with respect to the point theP which is the
202 //! center of the symmetry.
204 //! The main direction of the axis placement is not changed.
205 //! The "XDirection" and the "YDirection" are reversed.
206 //! So the axis placement stay right handed.
207 Standard_NODISCARD Standard_EXPORT gp_Ax3 Mirrored (const gp_Pnt& theP) const;
209 Standard_EXPORT void Mirror (const gp_Ax1& theA1);
211 //! Performs the symmetrical transformation of an axis
212 //! placement with respect to an axis placement which
213 //! is the axis of the symmetry.
214 //! The transformation is performed on the "Location"
215 //! point, on the "XDirection" and "YDirection".
216 //! The resulting main "Direction" is the cross product between
217 //! the "XDirection" and the "YDirection" after transformation.
218 Standard_NODISCARD Standard_EXPORT gp_Ax3 Mirrored (const gp_Ax1& theA1) const;
220 Standard_EXPORT void Mirror (const gp_Ax2& theA2);
222 //! Performs the symmetrical transformation of an axis
223 //! placement with respect to a plane.
224 //! The axis placement <theA2> locates the plane of the symmetry :
225 //! (Location, XDirection, YDirection).
226 //! The transformation is performed on the "Location"
227 //! point, on the "XDirection" and "YDirection".
228 //! The resulting main "Direction" is the cross product between
229 //! the "XDirection" and the "YDirection" after transformation.
230 Standard_NODISCARD Standard_EXPORT gp_Ax3 Mirrored (const gp_Ax2& theA2) const;
232 void Rotate (const gp_Ax1& theA1, const Standard_Real theAng)
234 axis.Rotate (theA1, theAng);
235 vxdir.Rotate (theA1, theAng);
236 vydir.Rotate (theA1, theAng);
239 //! Rotates an axis placement. <theA1> is the axis of the
240 //! rotation . theAng is the angular value of the rotation
242 Standard_NODISCARD gp_Ax3 Rotated (const gp_Ax1& theA1, const Standard_Real theAng) const
244 gp_Ax3 aTemp = *this;
245 aTemp.Rotate (theA1, theAng);
249 void Scale (const gp_Pnt& theP, const Standard_Real theS)
251 axis.Scale (theP, theS);
259 //! Applies a scaling transformation on the axis placement.
260 //! The "Location" point of the axisplacement is modified.
262 //! If the scale <theS> is negative :
263 //! . the main direction of the axis placement is not changed.
264 //! . The "XDirection" and the "YDirection" are reversed.
265 //! So the axis placement stay right handed.
266 Standard_NODISCARD gp_Ax3 Scaled (const gp_Pnt& theP, const Standard_Real theS) const
268 gp_Ax3 aTemp = *this;
269 aTemp.Scale (theP, theS);
273 void Transform (const gp_Trsf& theT)
275 axis.Transform (theT);
276 vxdir.Transform (theT);
277 vydir.Transform (theT);
280 //! Transforms an axis placement with a Trsf.
281 //! The "Location" point, the "XDirection" and the
282 //! "YDirection" are transformed with theT. The resulting
283 //! main "Direction" of <me> is the cross product between
284 //! the "XDirection" and the "YDirection" after transformation.
285 Standard_NODISCARD gp_Ax3 Transformed (const gp_Trsf& theT) const
287 gp_Ax3 aTemp = *this;
288 aTemp.Transform (theT);
292 void Translate (const gp_Vec& theV) { axis.Translate (theV); }
294 //! Translates an axis plaxement in the direction of the vector
295 //! <theV>. The magnitude of the translation is the vector's magnitude.
296 Standard_NODISCARD gp_Ax3 Translated (const gp_Vec& theV) const
298 gp_Ax3 aTemp = *this;
299 aTemp.Translate (theV);
303 void Translate (const gp_Pnt& theP1, const gp_Pnt& theP2) { Translate (gp_Vec (theP1, theP2)); }
305 //! Translates an axis placement from the point <theP1> to the
307 Standard_NODISCARD gp_Ax3 Translated (const gp_Pnt& theP1, const gp_Pnt& theP2) const { return Translated (gp_Vec (theP1, theP2)); }
309 //! Dumps the content of me into the stream
310 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
312 //! Inits the content of me from the stream
313 Standard_EXPORT Standard_Boolean InitFromJson (const Standard_SStream& theSStream, Standard_Integer& theStreamPos);
323 // =======================================================================
326 // =======================================================================
327 inline gp_Ax3::gp_Ax3 (const gp_Ax2& theA)
328 : axis (theA.Axis()),
329 vydir (theA.YDirection()),
330 vxdir (theA.XDirection())
333 // =======================================================================
336 // =======================================================================
337 inline gp_Ax2 gp_Ax3::Ax2()const
339 gp_Dir aZz = axis.Direction();
344 return gp_Ax2 (axis.Location(), aZz, vxdir);
347 // =======================================================================
348 // function : SetAxis
350 // =======================================================================
351 inline void gp_Ax3::SetAxis (const gp_Ax1& theA1)
353 Standard_Boolean isDirect = Direct();
355 vxdir = axis.Direction().CrossCrossed (vxdir, axis.Direction());
358 vydir = axis.Direction().Crossed (vxdir);
362 vydir = vxdir.Crossed (axis.Direction());
366 // =======================================================================
367 // function : SetDirection
369 // =======================================================================
370 inline void gp_Ax3::SetDirection (const gp_Dir& theV)
372 Standard_Boolean isDirect = Direct();
373 axis.SetDirection (theV);
374 vxdir = theV.CrossCrossed (vxdir, theV);
377 vydir = theV.Crossed (vxdir);
381 vydir = vxdir.Crossed (theV);
385 // =======================================================================
386 // function : SetXDirection
388 // =======================================================================
389 inline void gp_Ax3::SetXDirection (const gp_Dir& theVx)
391 Standard_Boolean isDirect = Direct();
392 vxdir = axis.Direction().CrossCrossed (theVx, axis.Direction());
395 vydir = axis.Direction().Crossed (vxdir);
399 vydir = vxdir.Crossed (axis.Direction());
403 // =======================================================================
404 // function : SetYDirection
406 // =======================================================================
407 inline void gp_Ax3::SetYDirection (const gp_Dir& theVy)
409 Standard_Boolean isDirect = Direct();
410 vxdir = theVy.Crossed (axis.Direction());
411 vydir = (axis.Direction()).Crossed (vxdir);
418 // =======================================================================
419 // function : IsCoplanar
421 // =======================================================================
422 inline Standard_Boolean gp_Ax3::IsCoplanar (const gp_Ax3& theOther,
423 const Standard_Real theLinearTolerance,
424 const Standard_Real theAngularTolerance)const
426 gp_Vec aVec (axis.Location(), theOther.axis.Location());
427 Standard_Real aD1 = gp_Vec (axis.Direction()).Dot(aVec);
432 Standard_Real aD2 = gp_Vec (theOther.axis.Direction()).Dot(aVec);
437 return (aD1 <= theLinearTolerance && aD2 <= theLinearTolerance &&
438 axis.IsParallel (theOther.axis, theAngularTolerance));
441 // =======================================================================
442 // function : IsCoplanar
444 // =======================================================================
445 inline Standard_Boolean gp_Ax3::IsCoplanar (const gp_Ax1& theA1,
446 const Standard_Real theLinearTolerance,
447 const Standard_Real theAngularTolerance)const
449 gp_Vec aVec (axis.Location(), theA1.Location());
450 Standard_Real aD1 = gp_Vec (axis.Direction()).Dot (aVec);
455 Standard_Real aD2 = (gp_Vec (theA1.Direction()).Crossed (aVec)).Magnitude();
460 return (aD1 <= theLinearTolerance && aD2 <= theLinearTolerance &&
461 axis.IsNormal (theA1, theAngularTolerance));
464 #endif // _gp_Ax3_HeaderFile