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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #ifndef _gp_Ax3_HeaderFile
18 #define _gp_Ax3_HeaderFile
19
20 #include <gp_Ax1.hxx>
21 #include <gp_Ax2.hxx>
22 #include <gp_Dir.hxx>
23 #include <gp_Pnt.hxx>
24 #include <gp_Vec.hxx>
25
26 class gp_Trsf;
27
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.
54 //! Note:
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.
62 class gp_Ax3
63 {
64 public:
65
66 DEFINE_STANDARD_ALLOC
67
68 //! Creates an object corresponding to the reference
69 //! coordinate system (OXYZ).
gp_Ax3()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)
72 {}
73
74 //! Creates a coordinate system from a right-handed
75 //! coordinate system.
76 gp_Ax3 (const gp_Ax2& theA);
77
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).
gp_Ax3(const gp_Pnt & theP,const gp_Dir & theN,const gp_Dir & theVx)82 gp_Ax3 (const gp_Pnt& theP, const gp_Dir& theN, const gp_Dir& theVx)
83 : axis (theP, theN),
84 vydir(theN),
85 vxdir(theN)
86 {
87 vxdir.CrossCross (theVx, theN);
88 vydir.Cross (vxdir);
89 }
90
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);
94
95 //! Reverses the X direction of <me>.
XReverse()96 void XReverse() { vxdir.Reverse(); }
97
98 //! Reverses the Y direction of <me>.
YReverse()99 void YReverse() { vydir.Reverse(); }
100
101 //! Reverses the Z direction of <me>.
ZReverse()102 void ZReverse() { axis.Reverse(); }
103
104 //! Assigns the origin and "main Direction" of the axis theA1 to
105 //! this coordinate system, then recomputes its "X Direction" and "Y Direction".
106 //! Note:
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
115 //! "YDirection".
116 void SetAxis (const gp_Ax1& theA1);
117
118 //! Changes the main direction of this coordinate system,
119 //! then recomputes its "X Direction" and "Y Direction".
120 //! Note:
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);
128
129 //! Changes the "Location" point (origin) of <me>.
SetLocation(const gp_Pnt & theP)130 void SetLocation (const gp_Pnt& theP) { axis.SetLocation (theP); }
131
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);
139
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);
147
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.
Angle(const gp_Ax3 & theOther) const151 Standard_Real Angle (const gp_Ax3& theOther) const { return axis.Angle (theOther.axis); }
152
153 //! Returns the main axis of <me>. It is the "Location" point
154 //! and the main "Direction".
Axis() const155 const gp_Ax1& Axis() const { return axis; }
156
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.
163 gp_Ax2 Ax2() const;
164
165 //! Returns the main direction of <me>.
Direction() const166 const gp_Dir& Direction() const { return axis.Direction(); }
167
168 //! Returns the "Location" point (origin) of <me>.
Location() const169 const gp_Pnt& Location() const { return axis.Location(); }
170
171 //! Returns the "XDirection" of <me>.
XDirection() const172 const gp_Dir& XDirection() const { return vxdir; }
173
174 //! Returns the "YDirection" of <me>.
YDirection() const175 const gp_Dir& YDirection() const { return vydir; }
176
177 //! Returns True if the coordinate system is right-handed. i.e.
178 //! XDirection().Crossed(YDirection()).Dot(Direction()) > 0
Direct() const179 Standard_Boolean Direct() const { return (vxdir.Crossed (vydir).Dot (axis.Direction()) > 0.); }
180
181 //! Returns True if
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;
189
190 //! Returns True if
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;
197
198 Standard_EXPORT void Mirror (const gp_Pnt& theP);
199
200 //! Performs the symmetrical transformation of an axis
201 //! placement with respect to the point theP which is the
202 //! center of the symmetry.
203 //! Warnings :
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;
208
209 Standard_EXPORT void Mirror (const gp_Ax1& theA1);
210
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;
219
220 Standard_EXPORT void Mirror (const gp_Ax2& theA2);
221
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;
231
Rotate(const gp_Ax1 & theA1,const Standard_Real theAng)232 void Rotate (const gp_Ax1& theA1, const Standard_Real theAng)
233 {
234 axis.Rotate (theA1, theAng);
235 vxdir.Rotate (theA1, theAng);
236 vydir.Rotate (theA1, theAng);
237 }
238
239 //! Rotates an axis placement. <theA1> is the axis of the
240 //! rotation . theAng is the angular value of the rotation
241 //! in radians.
Rotated(const gp_Ax1 & theA1,const Standard_Real theAng) const242 Standard_NODISCARD gp_Ax3 Rotated (const gp_Ax1& theA1, const Standard_Real theAng) const
243 {
244 gp_Ax3 aTemp = *this;
245 aTemp.Rotate (theA1, theAng);
246 return aTemp;
247 }
248
Scale(const gp_Pnt & theP,const Standard_Real theS)249 void Scale (const gp_Pnt& theP, const Standard_Real theS)
250 {
251 axis.Scale (theP, theS);
252 if (theS < 0.)
253 {
254 vxdir.Reverse();
255 vydir.Reverse();
256 }
257 }
258
259 //! Applies a scaling transformation on the axis placement.
260 //! The "Location" point of the axisplacement is modified.
261 //! Warnings :
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.
Scaled(const gp_Pnt & theP,const Standard_Real theS) const266 Standard_NODISCARD gp_Ax3 Scaled (const gp_Pnt& theP, const Standard_Real theS) const
267 {
268 gp_Ax3 aTemp = *this;
269 aTemp.Scale (theP, theS);
270 return aTemp;
271 }
272
Transform(const gp_Trsf & theT)273 void Transform (const gp_Trsf& theT)
274 {
275 axis.Transform (theT);
276 vxdir.Transform (theT);
277 vydir.Transform (theT);
278 }
279
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.
Transformed(const gp_Trsf & theT) const285 Standard_NODISCARD gp_Ax3 Transformed (const gp_Trsf& theT) const
286 {
287 gp_Ax3 aTemp = *this;
288 aTemp.Transform (theT);
289 return aTemp;
290 }
291
Translate(const gp_Vec & theV)292 void Translate (const gp_Vec& theV) { axis.Translate (theV); }
293
294 //! Translates an axis plaxement in the direction of the vector
295 //! <theV>. The magnitude of the translation is the vector's magnitude.
Translated(const gp_Vec & theV) const296 Standard_NODISCARD gp_Ax3 Translated (const gp_Vec& theV) const
297 {
298 gp_Ax3 aTemp = *this;
299 aTemp.Translate (theV);
300 return aTemp;
301 }
302
Translate(const gp_Pnt & theP1,const gp_Pnt & theP2)303 void Translate (const gp_Pnt& theP1, const gp_Pnt& theP2) { Translate (gp_Vec (theP1, theP2)); }
304
305 //! Translates an axis placement from the point <theP1> to the
306 //! point <theP2>.
Translated(const gp_Pnt & theP1,const gp_Pnt & theP2) const307 Standard_NODISCARD gp_Ax3 Translated (const gp_Pnt& theP1, const gp_Pnt& theP2) const { return Translated (gp_Vec (theP1, theP2)); }
308
309 //! Dumps the content of me into the stream
310 Standard_EXPORT void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const;
311
312 //! Inits the content of me from the stream
313 Standard_EXPORT Standard_Boolean InitFromJson (const Standard_SStream& theSStream, Standard_Integer& theStreamPos);
314
315 private:
316
317 gp_Ax1 axis;
318 gp_Dir vydir;
319 gp_Dir vxdir;
320
321 };
322
323 // =======================================================================
324 // function : gp_Ax3
325 // purpose :
326 // =======================================================================
gp_Ax3(const gp_Ax2 & theA)327 inline gp_Ax3::gp_Ax3 (const gp_Ax2& theA)
328 : axis (theA.Axis()),
329 vydir (theA.YDirection()),
330 vxdir (theA.XDirection())
331 {}
332
333 // =======================================================================
334 // function : Ax2
335 // purpose :
336 // =======================================================================
Ax2() const337 inline gp_Ax2 gp_Ax3::Ax2()const
338 {
339 gp_Dir aZz = axis.Direction();
340 if (!Direct())
341 {
342 aZz.Reverse();
343 }
344 return gp_Ax2 (axis.Location(), aZz, vxdir);
345 }
346
347 // =======================================================================
348 // function : SetAxis
349 // purpose :
350 // =======================================================================
SetAxis(const gp_Ax1 & theA1)351 inline void gp_Ax3::SetAxis (const gp_Ax1& theA1)
352 {
353 Standard_Boolean isDirect = Direct();
354 axis = theA1;
355 vxdir = axis.Direction().CrossCrossed (vxdir, axis.Direction());
356 if (isDirect)
357 {
358 vydir = axis.Direction().Crossed (vxdir);
359 }
360 else
361 {
362 vydir = vxdir.Crossed (axis.Direction());
363 }
364 }
365
366 // =======================================================================
367 // function : SetDirection
368 // purpose :
369 // =======================================================================
SetDirection(const gp_Dir & theV)370 inline void gp_Ax3::SetDirection (const gp_Dir& theV)
371 {
372 Standard_Boolean isDirect = Direct();
373 axis.SetDirection (theV);
374 vxdir = theV.CrossCrossed (vxdir, theV);
375 if (isDirect)
376 {
377 vydir = theV.Crossed (vxdir);
378 }
379 else
380 {
381 vydir = vxdir.Crossed (theV);
382 }
383 }
384
385 // =======================================================================
386 // function : SetXDirection
387 // purpose :
388 // =======================================================================
SetXDirection(const gp_Dir & theVx)389 inline void gp_Ax3::SetXDirection (const gp_Dir& theVx)
390 {
391 Standard_Boolean isDirect = Direct();
392 vxdir = axis.Direction().CrossCrossed (theVx, axis.Direction());
393 if (isDirect)
394 {
395 vydir = axis.Direction().Crossed (vxdir);
396 }
397 else
398 {
399 vydir = vxdir.Crossed (axis.Direction());
400 }
401 }
402
403 // =======================================================================
404 // function : SetYDirection
405 // purpose :
406 // =======================================================================
SetYDirection(const gp_Dir & theVy)407 inline void gp_Ax3::SetYDirection (const gp_Dir& theVy)
408 {
409 Standard_Boolean isDirect = Direct();
410 vxdir = theVy.Crossed (axis.Direction());
411 vydir = (axis.Direction()).Crossed (vxdir);
412 if (!isDirect)
413 {
414 vxdir.Reverse();
415 }
416 }
417
418 // =======================================================================
419 // function : IsCoplanar
420 // purpose :
421 // =======================================================================
IsCoplanar(const gp_Ax3 & theOther,const Standard_Real theLinearTolerance,const Standard_Real theAngularTolerance) const422 inline Standard_Boolean gp_Ax3::IsCoplanar (const gp_Ax3& theOther,
423 const Standard_Real theLinearTolerance,
424 const Standard_Real theAngularTolerance)const
425 {
426 gp_Vec aVec (axis.Location(), theOther.axis.Location());
427 Standard_Real aD1 = gp_Vec (axis.Direction()).Dot(aVec);
428 if (aD1 < 0)
429 {
430 aD1 = -aD1;
431 }
432 Standard_Real aD2 = gp_Vec (theOther.axis.Direction()).Dot(aVec);
433 if (aD2 < 0)
434 {
435 aD2 = -aD2;
436 }
437 return (aD1 <= theLinearTolerance && aD2 <= theLinearTolerance &&
438 axis.IsParallel (theOther.axis, theAngularTolerance));
439 }
440
441 // =======================================================================
442 // function : IsCoplanar
443 // purpose :
444 // =======================================================================
IsCoplanar(const gp_Ax1 & theA1,const Standard_Real theLinearTolerance,const Standard_Real theAngularTolerance) const445 inline Standard_Boolean gp_Ax3::IsCoplanar (const gp_Ax1& theA1,
446 const Standard_Real theLinearTolerance,
447 const Standard_Real theAngularTolerance)const
448 {
449 gp_Vec aVec (axis.Location(), theA1.Location());
450 Standard_Real aD1 = gp_Vec (axis.Direction()).Dot (aVec);
451 if (aD1 < 0)
452 {
453 aD1 = -aD1;
454 }
455 Standard_Real aD2 = (gp_Vec (theA1.Direction()).Crossed (aVec)).Magnitude();
456 if (aD2 < 0)
457 {
458 aD2 = -aD2;
459 }
460 return (aD1 <= theLinearTolerance && aD2 <= theLinearTolerance &&
461 axis.IsNormal (theA1, theAngularTolerance));
462 }
463
464 #endif // _gp_Ax3_HeaderFile
465