1 // Copyright (c) 1991-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #ifndef _gp_Ax2_HeaderFile
16 #define _gp_Ax2_HeaderFile
20 #include <Precision.hxx>
22 class Standard_ConstructionError;
27 //! Describes a right-handed coordinate system in 3D space.
28 //! A coordinate system is defined by:
29 //! - its origin (also referred to as its "Location point"), and
30 //! - three orthogonal unit vectors, termed respectively the
31 //! "X Direction", the "Y Direction" and the "Direction" (also
32 //! referred to as the "main Direction").
33 //! The "Direction" of the coordinate system is called its
34 //! "main Direction" because whenever this unit vector is
35 //! modified, the "X Direction" and the "Y Direction" are
36 //! recomputed. However, when we modify either the "X
37 //! Direction" or the "Y Direction", "Direction" is not modified.
38 //! The "main Direction" is also the "Z Direction".
39 //! Since an Ax2 coordinate system is right-handed, its
40 //! "main Direction" is always equal to the cross product of
41 //! its "X Direction" and "Y Direction". (To define a
42 //! left-handed coordinate system, use gp_Ax3.)
43 //! A coordinate system is used:
44 //! - to describe geometric entities, in particular to position
45 //! them. The local coordinate system of a geometric
46 //! entity serves the same purpose as the STEP function
47 //! "axis placement two axes", or
48 //! - to define geometric transformations.
49 //! Note: we refer to the "X Axis", "Y Axis" and "Z Axis",
50 //! respectively, as to axes having:
51 //! - the origin of the coordinate system as their origin, and
52 //! - the unit vectors "X Direction", "Y Direction" and "main
53 //! Direction", respectively, as their unit vectors.
54 //! The "Z Axis" is also the "main Axis".
61 //! Creates an object corresponding to the reference
62 //! coordinate system (OXYZ).
63 gp_Ax2() : vydir(0.,1.,0.)
64 // vxdir(1.,0.,0.) use default ctor of gp_Dir, as it creates the same dir(1,0,0)
67 //! Creates an axis placement with an origin P such that:
68 //! - N is the Direction, and
69 //! - the "X Direction" is normal to N, in the plane
70 //! defined by the vectors (N, Vx): "X
71 //! Direction" = (N ^ Vx) ^ N,
72 //! Exception: raises ConstructionError if N and Vx are parallel (same or opposite orientation).
73 gp_Ax2 (const gp_Pnt& P, const gp_Dir& N, const gp_Dir& Vx)
78 vxdir.CrossCross(Vx, N);
82 //! Creates - a coordinate system with an origin P, where V
83 //! gives the "main Direction" (here, "X Direction" and "Y
84 //! Direction" are defined automatically).
85 Standard_EXPORT gp_Ax2(const gp_Pnt& P, const gp_Dir& V);
87 //! Assigns the origin and "main Direction" of the axis A1 to
88 //! this coordinate system, then recomputes its "X Direction" and "Y Direction".
89 //! Note: The new "X Direction" is computed as follows:
90 //! new "X Direction" = V1 ^(previous "X Direction" ^ V)
91 //! where V is the "Direction" of A1.
93 //! Standard_ConstructionError if A1 is parallel to the "X
94 //! Direction" of this coordinate system.
95 void SetAxis (const gp_Ax1& A1);
97 //! Changes the "main Direction" of this coordinate system,
98 //! then recomputes its "X Direction" and "Y Direction".
99 //! Note: the new "X Direction" is computed as follows:
100 //! new "X Direction" = V ^ (previous "X Direction" ^ V)
102 //! Standard_ConstructionError if V is parallel to the "X
103 //! Direction" of this coordinate system.
104 void SetDirection (const gp_Dir& V);
106 //! Changes the "Location" point (origin) of <me>.
107 void SetLocation (const gp_Pnt& theP) { axis.SetLocation (theP); }
109 //! Changes the "Xdirection" of <me>. The main direction
110 //! "Direction" is not modified, the "Ydirection" is modified.
111 //! If <Vx> is not normal to the main direction then <XDirection>
112 //! is computed as follows XDirection = Direction ^ (Vx ^ Direction).
114 //! Standard_ConstructionError if Vx or Vy is parallel to
115 //! the "main Direction" of this coordinate system.
116 void SetXDirection (const gp_Dir& theVx)
118 vxdir = axis.Direction().CrossCrossed (theVx, axis.Direction());
119 vydir = axis.Direction().Crossed (vxdir);
122 //! Changes the "Ydirection" of <me>. The main direction is not
123 //! modified but the "Xdirection" is changed.
124 //! If <Vy> is not normal to the main direction then "YDirection"
125 //! is computed as follows
126 //! YDirection = Direction ^ (<Vy> ^ Direction).
128 //! Standard_ConstructionError if Vx or Vy is parallel to
129 //! the "main Direction" of this coordinate system.
130 void SetYDirection (const gp_Dir& theVy)
132 vxdir = theVy.Crossed (axis.Direction());
133 vydir = (axis.Direction()).Crossed (vxdir);
136 //! Computes the angular value, in radians, between the main direction of
137 //! <me> and the main direction of <theOther>. Returns the angle
138 //! between 0 and PI in radians.
139 Standard_Real Angle (const gp_Ax2& theOther) const { return axis.Angle (theOther.axis); }
141 //! Returns the main axis of <me>. It is the "Location" point
142 //! and the main "Direction".
143 const gp_Ax1& Axis() const { return axis; }
145 //! Returns the main direction of <me>.
146 const gp_Dir& Direction() const { return axis.Direction(); }
148 //! Returns the "Location" point (origin) of <me>.
149 const gp_Pnt& Location() const { return axis.Location(); }
151 //! Returns the "XDirection" of <me>.
152 const gp_Dir& XDirection() const { return vxdir; }
154 //! Returns the "YDirection" of <me>.
155 const gp_Dir& YDirection() const { return vydir; }
157 Standard_Boolean IsCoplanar (const gp_Ax2& Other, const Standard_Real LinearTolerance, const Standard_Real AngularTolerance) const;
160 //! . the distance between <me> and the "Location" point of A1
161 //! is lower of equal to LinearTolerance and
162 //! . the main direction of <me> and the direction of A1 are normal.
163 //! Note: the tolerance criterion for angular equality is given by AngularTolerance.
164 Standard_Boolean IsCoplanar (const gp_Ax1& A1, const Standard_Real LinearTolerance, const Standard_Real AngularTolerance) const;
166 //! Performs a symmetrical transformation of this coordinate
167 //! system with respect to:
168 //! - the point P, and assigns the result to this coordinate system.
170 //! This transformation is always performed on the origin.
171 //! In case of a reflection with respect to a point:
172 //! - the main direction of the coordinate system is not changed, and
173 //! - the "X Direction" and the "Y Direction" are simply reversed
174 //! In case of a reflection with respect to an axis or a plane:
175 //! - the transformation is applied to the "X Direction"
176 //! and the "Y Direction", then
177 //! - the "main Direction" is recomputed as the cross
178 //! product "X Direction" ^ "Y Direction".
179 //! This maintains the right-handed property of the
180 //! coordinate system.
181 Standard_EXPORT void Mirror (const gp_Pnt& P);
183 //! Performs a symmetrical transformation of this coordinate
184 //! system with respect to:
185 //! - the point P, and creates a new one.
187 //! This transformation is always performed on the origin.
188 //! In case of a reflection with respect to a point:
189 //! - the main direction of the coordinate system is not changed, and
190 //! - the "X Direction" and the "Y Direction" are simply reversed
191 //! In case of a reflection with respect to an axis or a plane:
192 //! - the transformation is applied to the "X Direction"
193 //! and the "Y Direction", then
194 //! - the "main Direction" is recomputed as the cross
195 //! product "X Direction" ^ "Y Direction".
196 //! This maintains the right-handed property of the
197 //! coordinate system.
198 Standard_NODISCARD Standard_EXPORT gp_Ax2 Mirrored (const gp_Pnt& P) const;
200 //! Performs a symmetrical transformation of this coordinate
201 //! system with respect to:
202 //! - the axis A1, and assigns the result to this coordinate systeme.
204 //! This transformation is always performed on the origin.
205 //! In case of a reflection with respect to a point:
206 //! - the main direction of the coordinate system is not changed, and
207 //! - the "X Direction" and the "Y Direction" are simply reversed
208 //! In case of a reflection with respect to an axis or a plane:
209 //! - the transformation is applied to the "X Direction"
210 //! and the "Y Direction", then
211 //! - the "main Direction" is recomputed as the cross
212 //! product "X Direction" ^ "Y Direction".
213 //! This maintains the right-handed property of the
214 //! coordinate system.
215 Standard_EXPORT void Mirror (const gp_Ax1& A1);
217 //! Performs a symmetrical transformation of this coordinate
218 //! system with respect to:
219 //! - the axis A1, and creates a new one.
221 //! This transformation is always performed on the origin.
222 //! In case of a reflection with respect to a point:
223 //! - the main direction of the coordinate system is not changed, and
224 //! - the "X Direction" and the "Y Direction" are simply reversed
225 //! In case of a reflection with respect to an axis or a plane:
226 //! - the transformation is applied to the "X Direction"
227 //! and the "Y Direction", then
228 //! - the "main Direction" is recomputed as the cross
229 //! product "X Direction" ^ "Y Direction".
230 //! This maintains the right-handed property of the
231 //! coordinate system.
232 Standard_NODISCARD Standard_EXPORT gp_Ax2 Mirrored (const gp_Ax1& A1) const;
234 //! Performs a symmetrical transformation of this coordinate
235 //! system with respect to:
236 //! - the plane defined by the origin, "X Direction" and "Y
237 //! Direction" of coordinate system A2 and assigns the result to this coordinate systeme.
239 //! This transformation is always performed on the origin.
240 //! In case of a reflection with respect to a point:
241 //! - the main direction of the coordinate system is not changed, and
242 //! - the "X Direction" and the "Y Direction" are simply reversed
243 //! In case of a reflection with respect to an axis or a plane:
244 //! - the transformation is applied to the "X Direction"
245 //! and the "Y Direction", then
246 //! - the "main Direction" is recomputed as the cross
247 //! product "X Direction" ^ "Y Direction".
248 //! This maintains the right-handed property of the
249 //! coordinate system.
250 Standard_EXPORT void Mirror (const gp_Ax2& A2);
252 //! Performs a symmetrical transformation of this coordinate
253 //! system with respect to:
254 //! - the plane defined by the origin, "X Direction" and "Y
255 //! Direction" of coordinate system A2 and creates a new one.
257 //! This transformation is always performed on the origin.
258 //! In case of a reflection with respect to a point:
259 //! - the main direction of the coordinate system is not changed, and
260 //! - the "X Direction" and the "Y Direction" are simply reversed
261 //! In case of a reflection with respect to an axis or a plane:
262 //! - the transformation is applied to the "X Direction"
263 //! and the "Y Direction", then
264 //! - the "main Direction" is recomputed as the cross
265 //! product "X Direction" ^ "Y Direction".
266 //! This maintains the right-handed property of the
267 //! coordinate system.
268 Standard_NODISCARD Standard_EXPORT gp_Ax2 Mirrored (const gp_Ax2& A2) const;
270 void Rotate (const gp_Ax1& theA1, const Standard_Real theAng)
272 gp_Pnt aTemp = axis.Location();
273 aTemp.Rotate (theA1, theAng);
274 axis.SetLocation (aTemp);
275 vxdir.Rotate (theA1, theAng);
276 vydir.Rotate (theA1, theAng);
277 axis.SetDirection (vxdir.Crossed (vydir));
280 //! Rotates an axis placement. <theA1> is the axis of the rotation.
281 //! theAng is the angular value of the rotation in radians.
282 Standard_NODISCARD gp_Ax2 Rotated (const gp_Ax1& theA1, const Standard_Real theAng) const
284 gp_Ax2 aTemp = *this;
285 aTemp.Rotate (theA1, theAng);
289 void Scale (const gp_Pnt& theP, const Standard_Real theS)
291 gp_Pnt aTemp = axis.Location();
292 aTemp.Scale (theP, theS);
293 axis.SetLocation (aTemp);
301 //! Applies a scaling transformation on the axis placement.
302 //! The "Location" point of the axisplacement is modified.
304 //! If the scale <S> is negative :
305 //! . the main direction of the axis placement is not changed.
306 //! . The "XDirection" and the "YDirection" are reversed.
307 //! So the axis placement stay right handed.
308 Standard_NODISCARD gp_Ax2 Scaled (const gp_Pnt& theP, const Standard_Real theS) const
310 gp_Ax2 aTemp = *this;
311 aTemp.Scale (theP, theS);
315 void Transform (const gp_Trsf& theT)
317 gp_Pnt aTemp = axis.Location();
318 aTemp.Transform (theT);
319 axis.SetLocation (aTemp);
320 vxdir.Transform (theT);
321 vydir.Transform (theT);
322 axis.SetDirection (vxdir.Crossed (vydir));
325 //! Transforms an axis placement with a Trsf.
326 //! The "Location" point, the "XDirection" and the "YDirection" are transformed with theT.
327 //! The resulting main "Direction" of <me> is the cross product between
328 //! the "XDirection" and the "YDirection" after transformation.
329 Standard_NODISCARD gp_Ax2 Transformed (const gp_Trsf& theT) const
331 gp_Ax2 aTemp = *this;
332 aTemp.Transform (theT);
336 void Translate (const gp_Vec& theV) { axis.Translate (theV); }
338 //! Translates an axis plaxement in the direction of the vector <theV>.
339 //! The magnitude of the translation is the vector's magnitude.
340 Standard_NODISCARD gp_Ax2 Translated (const gp_Vec& theV) const
342 gp_Ax2 aTemp = *this;
343 aTemp.Translate (theV);
347 void Translate (const gp_Pnt& theP1, const gp_Pnt& theP2) { axis.Translate (theP1, theP2); }
349 //! Translates an axis placement from the point <theP1> to the point <theP2>.
350 Standard_NODISCARD gp_Ax2 Translated (const gp_Pnt& theP1, const gp_Pnt& theP2) const
352 gp_Ax2 aTemp = *this;
353 aTemp.Translate (theP1, theP2);
357 //! Dumps the content of me into the stream
358 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
360 //! Inits the content of me from the stream
361 Standard_EXPORT Standard_Boolean InitFromJson (const Standard_SStream& theSStream, Standard_Integer& theStreamPos);
371 // =======================================================================
372 // function : SetAxis
374 // =======================================================================
375 inline void gp_Ax2::SetAxis (const gp_Ax1& theA1)
377 Standard_Real a = theA1.Direction() * vxdir;
378 if (Abs(Abs(a) - 1.) <= Precision::Angular())
383 vydir = axis.Direction();
388 vxdir = axis.Direction();
395 vxdir = axis.Direction().CrossCrossed (vxdir, axis.Direction());
396 vydir = axis.Direction().Crossed (vxdir);
400 // =======================================================================
401 // function : SetDirection
403 // =======================================================================
404 inline void gp_Ax2::SetDirection (const gp_Dir& theV)
406 Standard_Real a = theV * vxdir;
407 if (Abs(Abs(a) - 1.) <= Precision::Angular())
412 vydir = axis.Direction();
413 axis.SetDirection (theV);
417 vxdir = axis.Direction();
418 axis.SetDirection (theV);
423 axis.SetDirection (theV);
424 vxdir = theV.CrossCrossed (vxdir, theV);
425 vydir = theV.Crossed (vxdir);
429 // =======================================================================
430 // function : IsCoplanar
432 // =======================================================================
433 inline Standard_Boolean gp_Ax2::IsCoplanar (const gp_Ax2& theOther,
434 const Standard_Real theLinearTolerance,
435 const Standard_Real theAngularTolerance) const
437 const gp_Dir& DD = axis.Direction();
438 const gp_Pnt& PP = axis.Location();
439 const gp_Pnt& OP = theOther.axis.Location();
440 Standard_Real D1 = (DD.X() * (OP.X() - PP.X())
441 + DD.Y() * (OP.Y() - PP.Y())
442 + DD.Z() * (OP.Z() - PP.Z()));
447 return D1 <= theLinearTolerance
448 && axis.IsParallel (theOther.axis, theAngularTolerance);
451 // =======================================================================
452 // function : IsCoplanar
454 // =======================================================================
455 inline Standard_Boolean gp_Ax2::IsCoplanar (const gp_Ax1& theA,
456 const Standard_Real theLinearTolerance,
457 const Standard_Real theAngularTolerance) const
459 const gp_Dir& DD = axis.Direction();
460 const gp_Pnt& PP = axis.Location();
461 const gp_Pnt& AP = theA.Location();
462 Standard_Real D1 = (DD.X() * (AP.X() - PP.X()) +
463 DD.Y() * (AP.Y() - PP.Y()) +
464 DD.Z() * (AP.Z() - PP.Z()));
469 return D1 <= theLinearTolerance
470 && axis.IsNormal (theA, theAngularTolerance);
473 #endif // _gp_Ax2_HeaderFile