42cf5bc1 |
1 | // Copyright (c) 1991-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 | #ifndef _gp_XY_HeaderFile |
16 | #define _gp_XY_HeaderFile |
17 | |
d5477f8c |
18 | #include <gp.hxx> |
19 | #include <gp_Mat2d.hxx> |
20 | #include <Standard_ConstructionError.hxx> |
21 | #include <Standard_OutOfRange.hxx> |
42cf5bc1 |
22 | |
23 | //! This class describes a cartesian coordinate entity in 2D |
24 | //! space {X,Y}. This class is non persistent. This entity used |
25 | //! for algebraic calculation. An XY can be transformed with a |
26 | //! Trsf2d or a GTrsf2d from package gp. |
27 | //! It is used in vectorial computations or for holding this type |
28 | //! of information in data structures. |
29 | class gp_XY |
30 | { |
31 | public: |
32 | |
33 | DEFINE_STANDARD_ALLOC |
34 | |
42cf5bc1 |
35 | //! Creates XY object with zero coordinates (0,0). |
d5477f8c |
36 | gp_XY() |
37 | : x (0.), |
38 | y (0.) |
39 | {} |
40 | |
42cf5bc1 |
41 | //! a number pair defined by the XY coordinates |
d5477f8c |
42 | gp_XY (const Standard_Real theX, const Standard_Real theY) |
43 | : x (theX), |
44 | y (theY) |
45 | {} |
46 | |
47 | //! modifies the coordinate of range theIndex |
48 | //! theIndex = 1 => X is modified |
49 | //! theIndex = 2 => Y is modified |
50 | //! Raises OutOfRange if theIndex != {1, 2}. |
51 | inline void SetCoord (const Standard_Integer theIndex, const Standard_Real theXi) |
52 | { |
53 | Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > 2, NULL); |
54 | (&x)[theIndex - 1] = theXi; |
55 | } |
56 | |
42cf5bc1 |
57 | //! For this number pair, assigns |
d5477f8c |
58 | //! the values theX and theY to its coordinates |
59 | inline void SetCoord (const Standard_Real theX, const Standard_Real theY) |
60 | { |
61 | x = theX; |
62 | y = theY; |
63 | } |
64 | |
42cf5bc1 |
65 | //! Assigns the given value to the X coordinate of this number pair. |
d5477f8c |
66 | void SetX (const Standard_Real theX) { x = theX; } |
67 | |
42cf5bc1 |
68 | //! Assigns the given value to the Y coordinate of this number pair. |
d5477f8c |
69 | void SetY (const Standard_Real theY) { y = theY; } |
70 | |
71 | //! returns the coordinate of range theIndex : |
72 | //! theIndex = 1 => X is returned |
73 | //! theIndex = 2 => Y is returned |
74 | //! Raises OutOfRange if theIndex != {1, 2}. |
75 | inline Standard_Real Coord (const Standard_Integer theIndex) const |
76 | { |
77 | Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > 2, NULL); |
78 | return (&x)[theIndex - 1]; |
79 | } |
80 | |
81 | inline Standard_Real& ChangeCoord (const Standard_Integer theIndex) |
82 | { |
83 | Standard_OutOfRange_Raise_if (theIndex < 1 || theIndex > 2, NULL); |
84 | return (&x)[theIndex - 1]; |
85 | } |
86 | |
42cf5bc1 |
87 | //! For this number pair, returns its coordinates X and Y. |
d5477f8c |
88 | inline void Coord (Standard_Real& theX, Standard_Real& theY) const |
89 | { |
90 | theX = x; |
91 | theY = y; |
92 | } |
93 | |
42cf5bc1 |
94 | //! Returns the X coordinate of this number pair. |
d5477f8c |
95 | Standard_Real X() const { return x; } |
96 | |
42cf5bc1 |
97 | //! Returns the Y coordinate of this number pair. |
d5477f8c |
98 | Standard_Real Y() const { return y; } |
99 | |
42cf5bc1 |
100 | //! Computes Sqrt (X*X + Y*Y) where X and Y are the two coordinates of this number pair. |
d5477f8c |
101 | Standard_Real Modulus() const { return sqrt (x * x + y * y); } |
102 | |
42cf5bc1 |
103 | //! Computes X*X + Y*Y where X and Y are the two coordinates of this number pair. |
d5477f8c |
104 | Standard_Real SquareModulus() const { return x * x + y * y; } |
42cf5bc1 |
105 | |
106 | //! Returns true if the coordinates of this number pair are |
107 | //! equal to the respective coordinates of the number pair |
d5477f8c |
108 | //! theOther, within the specified tolerance theTolerance. I.e.: |
109 | //! abs(<me>.X() - theOther.X()) <= theTolerance and |
110 | //! abs(<me>.Y() - theOther.Y()) <= theTolerance and |
42cf5bc1 |
111 | //! computations |
d5477f8c |
112 | Standard_EXPORT Standard_Boolean IsEqual (const gp_XY& theOther, const Standard_Real theTolerance) const; |
113 | |
114 | //! Computes the sum of this number pair and number pair theOther |
08eda8e3 |
115 | //! @code |
d5477f8c |
116 | //! <me>.X() = <me>.X() + theOther.X() |
117 | //! <me>.Y() = <me>.Y() + theOther.Y() |
118 | inline void Add (const gp_XY& theOther) |
119 | { |
120 | x += theOther.x; |
121 | y += theOther.y; |
122 | } |
123 | |
124 | void operator+= (const gp_XY& theOther) { Add (theOther); } |
125 | |
126 | //! Computes the sum of this number pair and number pair theOther |
08eda8e3 |
127 | //! @code |
d5477f8c |
128 | //! new.X() = <me>.X() + theOther.X() |
129 | //! new.Y() = <me>.Y() + theOther.Y() |
08eda8e3 |
130 | //! @endcode |
d5477f8c |
131 | Standard_NODISCARD gp_XY Added (const gp_XY& theOther) const |
132 | { |
133 | return gp_XY (x + theOther.X(), y + theOther.Y()); |
134 | } |
135 | |
136 | Standard_NODISCARD gp_XY operator+ (const gp_XY& theOther) const { return Added (theOther); } |
42cf5bc1 |
137 | |
08eda8e3 |
138 | //! @code |
d5477f8c |
139 | //! double D = <me>.X() * theOther.Y() - <me>.Y() * theOther.X() |
08eda8e3 |
140 | //! @endcode |
d5477f8c |
141 | Standard_NODISCARD Standard_Real Crossed (const gp_XY& theOther) const { return x * theOther.y - y * theOther.x; } |
142 | |
143 | Standard_NODISCARD Standard_Real operator^ (const gp_XY& theOther) const { return Crossed (theOther); } |
42cf5bc1 |
144 | |
145 | //! computes the magnitude of the cross product between <me> and |
d5477f8c |
146 | //! theRight. Returns || <me> ^ theRight || |
147 | inline Standard_Real CrossMagnitude (const gp_XY& theRight) const |
148 | { |
149 | Standard_Real aVal = x * theRight.y - y * theRight.x; |
150 | return aVal < 0 ? -aVal : aVal; |
151 | } |
42cf5bc1 |
152 | |
153 | //! computes the square magnitude of the cross product between <me> and |
d5477f8c |
154 | //! theRight. Returns || <me> ^ theRight ||**2 |
155 | inline Standard_Real CrossSquareMagnitude (const gp_XY& theRight) const |
156 | { |
157 | Standard_Real aZresult = x * theRight.y - y * theRight.x; |
158 | return aZresult * aZresult; |
159 | } |
160 | |
42cf5bc1 |
161 | //! divides <me> by a real. |
d5477f8c |
162 | void Divide (const Standard_Real theScalar) |
163 | { |
164 | x /= theScalar; |
165 | y /= theScalar; |
166 | } |
167 | |
168 | void operator /= (const Standard_Real theScalar) { Divide (theScalar); } |
169 | |
42cf5bc1 |
170 | //! Divides <me> by a real. |
d5477f8c |
171 | Standard_NODISCARD gp_XY Divided (const Standard_Real theScalar) const |
172 | { |
173 | return gp_XY (x / theScalar, y / theScalar); |
174 | } |
42cf5bc1 |
175 | |
d5477f8c |
176 | Standard_NODISCARD gp_XY operator/ (const Standard_Real theScalar) const { return Divided (theScalar); } |
177 | |
178 | //! Computes the scalar product between <me> and theOther |
179 | Standard_Real Dot (const gp_XY& theOther) const { return x * theOther.x + y * theOther.y; } |
180 | |
181 | Standard_Real operator* (const gp_XY& theOther) const { return Dot (theOther); } |
08eda8e3 |
182 | |
183 | //! @code |
d5477f8c |
184 | //! <me>.X() = <me>.X() * theScalar; |
185 | //! <me>.Y() = <me>.Y() * theScalar; |
186 | void Multiply (const Standard_Real theScalar) |
187 | { |
188 | x *= theScalar; |
189 | y *= theScalar; |
190 | } |
191 | |
192 | void operator*= (const Standard_Real theScalar) { Multiply (theScalar); } |
193 | |
08eda8e3 |
194 | //! @code |
d5477f8c |
195 | //! <me>.X() = <me>.X() * theOther.X(); |
196 | //! <me>.Y() = <me>.Y() * theOther.Y(); |
197 | void Multiply (const gp_XY& theOther) |
198 | { |
199 | x *= theOther.x; |
200 | y *= theOther.y; |
201 | } |
202 | |
203 | void operator*= (const gp_XY& theOther) { Multiply (theOther); } |
204 | |
205 | //! <me> = theMatrix * <me> |
206 | void Multiply (const gp_Mat2d& theMatrix); |
207 | |
208 | void operator*= (const gp_Mat2d& theMatrix) { Multiply (theMatrix); } |
209 | |
08eda8e3 |
210 | //! @code |
d5477f8c |
211 | //! New.X() = <me>.X() * theScalar; |
212 | //! New.Y() = <me>.Y() * theScalar; |
213 | Standard_NODISCARD gp_XY Multiplied (const Standard_Real theScalar) const { return gp_XY (x * theScalar, y * theScalar); } |
08eda8e3 |
214 | |
d5477f8c |
215 | Standard_NODISCARD gp_XY operator* (const Standard_Real theScalar) const { return Multiplied (theScalar); } |
08eda8e3 |
216 | //! @code |
d5477f8c |
217 | //! new.X() = <me>.X() * theOther.X(); |
218 | //! new.Y() = <me>.Y() * theOther.Y(); |
219 | Standard_NODISCARD gp_XY Multiplied (const gp_XY& theOther) const { return gp_XY (x * theOther.X(), y * theOther.Y()); } |
220 | |
221 | //! New = theMatrix * <me> |
08eda8e3 |
222 | //! @endcode |
d5477f8c |
223 | Standard_NODISCARD gp_XY Multiplied (const gp_Mat2d& theMatrix) const |
224 | { |
225 | const Standard_Address aM = (Standard_Address) &(theMatrix.Value (1, 1)); |
226 | return gp_XY (Mat2d00 * x + Mat2d01 * y, Mat2d10 * x + Mat2d11 * y); |
227 | } |
228 | |
229 | Standard_NODISCARD gp_XY operator* (const gp_Mat2d& theMatrix) const { return Multiplied (theMatrix); } |
08eda8e3 |
230 | //! @code |
42cf5bc1 |
231 | //! <me>.X() = <me>.X()/ <me>.Modulus() |
232 | //! <me>.Y() = <me>.Y()/ <me>.Modulus() |
08eda8e3 |
233 | //! @endcode |
42cf5bc1 |
234 | //! Raises ConstructionError if <me>.Modulus() <= Resolution from gp |
d5477f8c |
235 | void Normalize(); |
236 | |
08eda8e3 |
237 | //! @code |
42cf5bc1 |
238 | //! New.X() = <me>.X()/ <me>.Modulus() |
239 | //! New.Y() = <me>.Y()/ <me>.Modulus() |
08eda8e3 |
240 | //! @endcode |
42cf5bc1 |
241 | //! Raises ConstructionError if <me>.Modulus() <= Resolution from gp |
d5477f8c |
242 | Standard_NODISCARD gp_XY Normalized() const |
243 | { |
244 | Standard_Real aD = Modulus(); |
245 | Standard_ConstructionError_Raise_if (aD <= gp::Resolution(), "gp_XY::Normalized() - vector has zero norm"); |
246 | return gp_XY (x / aD, y / aD); |
247 | } |
248 | |
08eda8e3 |
249 | //! @code |
42cf5bc1 |
250 | //! <me>.X() = -<me>.X() |
251 | //! <me>.Y() = -<me>.Y() |
d5477f8c |
252 | inline void Reverse() |
253 | { |
254 | x = -x; |
255 | y = -y; |
256 | } |
257 | |
08eda8e3 |
258 | //! @code |
42cf5bc1 |
259 | //! New.X() = -<me>.X() |
260 | //! New.Y() = -<me>.Y() |
d5477f8c |
261 | Standard_NODISCARD gp_XY Reversed() const |
262 | { |
263 | gp_XY aCoord2D = *this; |
264 | aCoord2D.Reverse(); |
265 | return aCoord2D; |
266 | } |
267 | |
268 | Standard_NODISCARD gp_XY operator-() const { return Reversed(); } |
42cf5bc1 |
269 | |
270 | //! Computes the following linear combination and |
271 | //! assigns the result to this number pair: |
08eda8e3 |
272 | //! @code |
d5477f8c |
273 | //! theA1 * theXY1 + theA2 * theXY2 |
274 | inline void SetLinearForm (const Standard_Real theA1, const gp_XY& theXY1, |
275 | const Standard_Real theA2, const gp_XY& theXY2) |
276 | { |
277 | x = theA1 * theXY1.x + theA2 * theXY2.x; |
278 | y = theA1 * theXY1.y + theA2 * theXY2.y; |
279 | } |
42cf5bc1 |
280 | |
281 | //! -- Computes the following linear combination and |
282 | //! assigns the result to this number pair: |
08eda8e3 |
283 | //! @code |
d5477f8c |
284 | //! theA1 * theXY1 + theA2 * theXY2 + theXY3 |
285 | inline void SetLinearForm (const Standard_Real theA1, const gp_XY& theXY1, |
286 | const Standard_Real theA2, const gp_XY& theXY2, |
287 | const gp_XY& theXY3) |
288 | { |
289 | x = theA1 * theXY1.x + theA2 * theXY2.x + theXY3.x; |
290 | y = theA1 * theXY1.y + theA2 * theXY2.y + theXY3.y; |
291 | } |
42cf5bc1 |
292 | |
293 | //! Computes the following linear combination and |
294 | //! assigns the result to this number pair: |
08eda8e3 |
295 | //! @code |
d5477f8c |
296 | //! theA1 * theXY1 + theXY2 |
297 | inline void SetLinearForm (const Standard_Real theA1, const gp_XY& theXY1, |
298 | const gp_XY& theXY2) |
299 | { |
300 | x = theA1 * theXY1.x + theXY2.x; |
301 | y = theA1 * theXY1.y + theXY2.y; |
302 | } |
42cf5bc1 |
303 | |
304 | //! Computes the following linear combination and |
305 | //! assigns the result to this number pair: |
08eda8e3 |
306 | //! @code |
d5477f8c |
307 | //! theXY1 + theXY2 |
308 | inline void SetLinearForm (const gp_XY& theXY1, |
309 | const gp_XY& theXY2) |
310 | { |
311 | x = theXY1.x + theXY2.x; |
312 | y = theXY1.y + theXY2.y; |
313 | } |
42cf5bc1 |
314 | |
08eda8e3 |
315 | //! @code |
d5477f8c |
316 | //! <me>.X() = <me>.X() - theOther.X() |
317 | //! <me>.Y() = <me>.Y() - theOther.Y() |
318 | inline void Subtract (const gp_XY& theOther) |
319 | { |
320 | x -= theOther.x; |
321 | y -= theOther.y; |
322 | } |
42cf5bc1 |
323 | |
d5477f8c |
324 | void operator-= (const gp_XY& theOther) { Subtract (theOther); } |
42cf5bc1 |
325 | |
d5477f8c |
326 | //! @code |
327 | //! new.X() = <me>.X() - theOther.X() |
328 | //! new.Y() = <me>.Y() - theOther.Y() |
329 | //! @endcode |
330 | Standard_NODISCARD gp_XY Subtracted (const gp_XY& theOther) const |
331 | { |
332 | gp_XY aCoord2D = *this; |
333 | aCoord2D.Subtract (theOther); |
334 | return aCoord2D; |
335 | } |
42cf5bc1 |
336 | |
d5477f8c |
337 | Standard_NODISCARD gp_XY operator- (const gp_XY& theOther) const { return Subtracted (theOther); } |
42cf5bc1 |
338 | |
339 | private: |
340 | |
42cf5bc1 |
341 | Standard_Real x; |
342 | Standard_Real y; |
343 | |
42cf5bc1 |
344 | }; |
345 | |
d5477f8c |
346 | //======================================================================= |
347 | //function : Multiply |
348 | // purpose : |
349 | //======================================================================= |
350 | inline void gp_XY::Multiply (const gp_Mat2d& theMatrix) |
351 | { |
352 | const Standard_Address aM = (Standard_Address) &(theMatrix.Value (1, 1)); |
353 | Standard_Real aXresult = Mat2d00 * x + Mat2d01 * y; |
354 | y = Mat2d10 * x + Mat2d11 * y; |
355 | x = aXresult; |
356 | } |
42cf5bc1 |
357 | |
d5477f8c |
358 | //======================================================================= |
359 | //function : Normalize |
360 | // purpose : |
361 | //======================================================================= |
362 | inline void gp_XY::Normalize() |
363 | { |
364 | Standard_Real aD = Modulus(); |
365 | Standard_ConstructionError_Raise_if (aD <= gp::Resolution(), "gp_XY::Normalize() - vector has zero norm"); |
366 | x = x / aD; |
367 | y = y / aD; |
368 | } |
42cf5bc1 |
369 | |
d5477f8c |
370 | //======================================================================= |
371 | //function : operator* |
372 | // purpose : |
373 | //======================================================================= |
374 | inline gp_XY operator* (const gp_Mat2d& theMatrix, |
375 | const gp_XY& theCoord1) |
376 | { |
377 | return theCoord1.Multiplied (theMatrix); |
378 | } |
42cf5bc1 |
379 | |
d5477f8c |
380 | //======================================================================= |
381 | //function : operator* |
382 | // purpose : |
383 | //======================================================================= |
384 | inline gp_XY operator* (const Standard_Real theScalar, |
385 | const gp_XY& theCoord1) |
386 | { |
387 | return theCoord1.Multiplied (theScalar); |
388 | } |
42cf5bc1 |
389 | |
390 | #endif // _gp_XY_HeaderFile |