0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / gp / gp_Dir.lxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <gp_Vec.hxx>
16 #include <gp_Trsf.hxx>
17 #include <Standard_ConstructionError.hxx>
18 #include <Standard_OutOfRange.hxx>
19
20 inline gp_Dir::gp_Dir () : coord(1.,0.,0.)
21
22 }
23
24 inline gp_Dir::gp_Dir (const gp_Vec& V)
25 {
26   const gp_XYZ& XYZ = V.XYZ();
27   Standard_Real X = XYZ.X();
28   Standard_Real Y = XYZ.Y();
29   Standard_Real Z = XYZ.Z();
30   Standard_Real D = sqrt(X * X + Y * Y + Z * Z);
31   Standard_ConstructionError_Raise_if (D <= gp::Resolution(), "gp_Dir() - input vector has zero norm");
32   coord.SetX(X / D);
33   coord.SetY(Y / D);
34   coord.SetZ(Z / D);
35 }
36
37 inline gp_Dir::gp_Dir (const gp_XYZ& XYZ)
38 {
39   Standard_Real X = XYZ.X();
40   Standard_Real Y = XYZ.Y();
41   Standard_Real Z = XYZ.Z();
42   Standard_Real D = sqrt(X * X + Y * Y + Z * Z);
43   Standard_ConstructionError_Raise_if (D <= gp::Resolution(), "gp_Dir() - input vector has zero norm");
44   coord.SetX(X / D);
45   coord.SetY(Y / D);
46   coord.SetZ(Z / D);
47 }
48
49 inline gp_Dir::gp_Dir (const Standard_Real Xv,
50                        const Standard_Real Yv,
51                        const Standard_Real Zv)
52 {
53   Standard_Real D = sqrt (Xv * Xv + Yv * Yv + Zv * Zv);
54   Standard_ConstructionError_Raise_if (D <= gp::Resolution(), "gp_Dir() - input vector has zero norm");
55   coord.SetX(Xv / D);
56   coord.SetY(Yv / D);
57   coord.SetZ(Zv / D);
58 }
59
60 inline void gp_Dir::SetCoord (const Standard_Integer Index,
61                               const Standard_Real Xi)
62 {
63   Standard_Real X = coord.X();
64   Standard_Real Y = coord.Y();
65   Standard_Real Z = coord.Z();
66   Standard_OutOfRange_Raise_if (Index < 1 || Index > 3, "gp_Dir::SetCoord() - index is out of range [1, 3]");
67   if      (Index == 1)  X = Xi;
68   else if (Index == 2)  Y = Xi;
69   else                  Z = Xi;
70   Standard_Real D = sqrt (X * X + Y * Y + Z * Z);
71   Standard_ConstructionError_Raise_if (D <= gp::Resolution(), "gp_Dir::SetCoord() - result vector has zero norm");
72   coord.SetX(X / D);
73   coord.SetY(Y / D);
74   coord.SetZ(Z / D);
75 }
76
77 inline void gp_Dir::SetCoord (const Standard_Real Xv,
78                               const Standard_Real Yv,
79                               const Standard_Real Zv) {
80   Standard_Real D = sqrt(Xv * Xv + Yv * Yv + Zv * Zv);
81   Standard_ConstructionError_Raise_if(D <= gp::Resolution(), "gp_Dir::SetCoord() - input vector has zero norm");
82   coord.SetX(Xv / D);
83   coord.SetY(Yv / D);
84   coord.SetZ(Zv / D);
85 }
86
87 inline void gp_Dir::SetX (const Standard_Real X)
88 {
89   Standard_Real Y = coord.Y();
90   Standard_Real Z = coord.Z();
91   Standard_Real D = sqrt (X * X + Y * Y + Z * Z);
92   Standard_ConstructionError_Raise_if (D <= gp::Resolution(), "gp_Dir::SetX() - result vector has zero norm");
93   coord.SetX(X / D);
94   coord.SetY(Y / D);
95   coord.SetZ(Z / D);
96 }
97
98 inline void gp_Dir::SetY (const Standard_Real Y)
99 {
100   Standard_Real Z = coord.Z();
101   Standard_Real X = coord.X();
102   Standard_Real D = sqrt (X * X + Y * Y + Z * Z);
103   Standard_ConstructionError_Raise_if (D <= gp::Resolution(), "gp_Dir::SetY() - result vector has zero norm");
104   coord.SetX(X / D);
105   coord.SetY(Y / D);
106   coord.SetZ(Z / D);
107 }
108
109 inline void gp_Dir::SetZ (const Standard_Real Z)
110 {
111   Standard_Real X = coord.X();
112   Standard_Real Y = coord.Y();
113   Standard_Real D = sqrt (X * X + Y * Y + Z * Z);
114   Standard_ConstructionError_Raise_if (D <= gp::Resolution(), "gp_Dir::SetZ() - result vector has zero norm");
115   coord.SetX(X / D);
116   coord.SetY(Y / D);
117   coord.SetZ(Z / D);
118 }
119
120 inline void gp_Dir::SetXYZ (const gp_XYZ& XYZ)
121 {
122   Standard_Real X = XYZ.X();
123   Standard_Real Y = XYZ.Y();
124   Standard_Real Z = XYZ.Z();
125   Standard_Real D = sqrt(X * X + Y * Y + Z * Z);
126   Standard_ConstructionError_Raise_if (D <= gp::Resolution(), "gp_Dir::SetX() - input vector has zero norm");
127   coord.SetX(X / D);
128   coord.SetY(Y / D);
129   coord.SetZ(Z / D);
130 }
131
132 inline Standard_Real gp_Dir::Coord (const Standard_Integer Index) const
133 { return coord.Coord (Index);}
134
135 inline  void gp_Dir::Coord (Standard_Real& Xv,
136                             Standard_Real& Yv,
137                             Standard_Real& Zv) const
138 { coord.Coord (Xv, Yv, Zv); }
139
140 inline  Standard_Real gp_Dir::X() const
141 { return coord.X() ; }
142
143 inline  Standard_Real gp_Dir::Y() const
144 { return coord.Y() ; }
145
146 inline  Standard_Real gp_Dir::Z() const
147 { return coord.Z() ; }
148
149 inline  const gp_XYZ& gp_Dir::XYZ () const
150 { return coord; }
151
152 inline Standard_Boolean gp_Dir::IsEqual
153 (const gp_Dir& Other, 
154  const Standard_Real AngularTolerance) const
155 { return   Angle (Other) <= AngularTolerance; }    
156
157 inline Standard_Boolean gp_Dir::IsNormal
158 (const gp_Dir& Other,
159  const Standard_Real AngularTolerance) const
160 {
161   Standard_Real Ang = M_PI / 2.0 - Angle (Other);
162   if (Ang < 0) Ang = - Ang;
163   return   Ang <= AngularTolerance;
164 }    
165
166 inline Standard_Boolean gp_Dir::IsOpposite
167 (const gp_Dir& Other,
168  const Standard_Real AngularTolerance) const
169 { return M_PI - Angle (Other) <= AngularTolerance; }    
170
171 inline Standard_Boolean gp_Dir::IsParallel
172 (const gp_Dir& Other, 
173  const Standard_Real AngularTolerance) const
174 {
175   Standard_Real Ang = Angle (Other);
176   return Ang <= AngularTolerance || M_PI - Ang <= AngularTolerance;
177 }    
178
179 inline void gp_Dir::Cross (const gp_Dir& Right)
180
181   coord.Cross (Right.coord); 
182   Standard_Real D = coord.Modulus ();
183   Standard_ConstructionError_Raise_if (D <= gp::Resolution(), "gp_Dir::Cross() - result vector has zero norm");
184   coord.Divide (D);
185 }
186
187 inline gp_Dir gp_Dir::Crossed (const gp_Dir& Right) const
188 {
189   gp_Dir V = *this;
190   V.coord.Cross (Right.coord);
191   Standard_Real D = V.coord.Modulus();
192   Standard_ConstructionError_Raise_if (D <= gp::Resolution(), "gp_Dir::Crossed() - result vector has zero norm");
193   V.coord.Divide (D);
194   return V;
195 }
196
197 inline void gp_Dir::CrossCross (const gp_Dir& V1,
198                                 const gp_Dir& V2)
199
200   coord.CrossCross (V1.coord, V2.coord);
201   Standard_Real D = coord.Modulus();
202   Standard_ConstructionError_Raise_if (D <= gp::Resolution(), "gp_Dir::CrossCross() - result vector has zero norm");
203   coord.Divide(D);
204 }
205
206 inline gp_Dir gp_Dir::CrossCrossed (const gp_Dir& V1,
207                                     const gp_Dir& V2) const
208 {
209   gp_Dir V = *this;
210   (V.coord).CrossCross (V1.coord, V2.coord);
211   Standard_Real D = V.coord.Modulus();
212   Standard_ConstructionError_Raise_if (D <= gp::Resolution(), "gp_Dir::CrossCrossed() - result vector has zero norm");
213   V.coord.Divide(D);
214   return V;
215 }
216
217 inline Standard_Real gp_Dir::Dot (const gp_Dir& Other) const
218 { return coord.Dot (Other.coord); }
219
220 inline Standard_Real gp_Dir::DotCross (const gp_Dir& V1,
221                                        const gp_Dir& V2)  const
222 { return coord.Dot (V1.coord.Crossed (V2.coord)); } 
223
224 inline void gp_Dir::Reverse ()
225 { coord.Reverse(); }
226
227 inline gp_Dir gp_Dir::Reversed () const { 
228   gp_Dir V = *this;
229   V.coord.Reverse ();
230   return V;
231 }
232
233 inline void gp_Dir::Rotate (const gp_Ax1& A1, const Standard_Real Ang)
234 {
235   gp_Trsf T;
236   T.SetRotation (A1, Ang);
237   coord.Multiply (T.HVectorialPart ());
238 }
239
240 inline gp_Dir gp_Dir::Rotated (const gp_Ax1& A1,
241                                const Standard_Real Ang) const
242 {
243   gp_Dir V = *this;
244   V.Rotate (A1, Ang);
245   return V;
246 }
247
248 inline gp_Dir gp_Dir::Transformed (const gp_Trsf& T) const
249 {
250   gp_Dir V = *this;
251   V.Transform (T);
252   return V;
253
254