5e27df78 |
1 | // Created by: Kirill GAVRILOV |
d5f74e42 |
2 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
5e27df78 |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
5e27df78 |
5 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
5e27df78 |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
5e27df78 |
14 | |
15 | #ifndef _NCollection_Vec2_H__ |
16 | #define _NCollection_Vec2_H__ |
17 | |
bf75be98 |
18 | #include <cmath> // std::sqrt() |
19 | |
a5162275 |
20 | #include <Standard_Dump.hxx> |
21 | |
5e27df78 |
22 | //! Auxiliary macros to define couple of similar access components as vector methods. |
23 | //! @return 2 components by their names in specified order |
24 | #define NCOLLECTION_VEC_COMPONENTS_2D(theX, theY) \ |
bf75be98 |
25 | const NCollection_Vec2<Element_t> theX##theY() const { return NCollection_Vec2<Element_t>(theX(), theY()); } \ |
26 | const NCollection_Vec2<Element_t> theY##theX() const { return NCollection_Vec2<Element_t>(theY(), theX()); } |
5e27df78 |
27 | |
28 | //! Defines the 2D-vector template. |
29 | //! The main target for this class - to handle raw low-level arrays (from/to graphic driver etc.). |
30 | template<typename Element_t> |
31 | class NCollection_Vec2 |
32 | { |
33 | |
34 | public: |
35 | |
36 | //! Returns the number of components. |
37 | static int Length() |
38 | { |
39 | return 2; |
40 | } |
41 | |
42 | //! Empty constructor. Construct the zero vector. |
43 | NCollection_Vec2() |
44 | { |
45 | v[0] = v[1] = Element_t(0); |
46 | } |
47 | |
48 | //! Initialize ALL components of vector within specified value. |
49 | explicit NCollection_Vec2 (const Element_t theXY) |
50 | { |
51 | v[0] = v[1] = theXY; |
52 | } |
53 | |
54 | //! Per-component constructor. |
55 | explicit NCollection_Vec2 (const Element_t theX, |
56 | const Element_t theY) |
57 | { |
58 | v[0] = theX; |
59 | v[1] = theY; |
60 | } |
61 | |
f9b30c0d |
62 | //! Conversion constructor (explicitly converts some 2-component vector with other element type |
63 | //! to a new 2-component vector with the element type Element_t, |
64 | //! whose elements are static_cast'ed corresponding elements of theOtherVec2 vector) |
65 | //! @tparam OtherElement_t the element type of the other 2-component vector theOtherVec2 |
66 | //! @param theOtherVec2 the 2-component vector that needs to be converted |
67 | template <typename OtherElement_t> |
68 | explicit NCollection_Vec2 (const NCollection_Vec2<OtherElement_t>& theOtherVec2) |
69 | { |
70 | v[0] = static_cast<Element_t> (theOtherVec2[0]); |
71 | v[1] = static_cast<Element_t> (theOtherVec2[1]); |
72 | } |
73 | |
e958a649 |
74 | //! Assign new values to the vector. |
75 | void SetValues (const Element_t theX, |
76 | const Element_t theY) |
77 | { |
78 | v[0] = theX; |
79 | v[1] = theY; |
80 | } |
81 | |
5e27df78 |
82 | //! Alias to 1st component as X coordinate in XY. |
83 | Element_t x() const { return v[0]; } |
84 | |
85 | //! Alias to 2nd component as Y coordinate in XY. |
86 | Element_t y() const { return v[1]; } |
87 | |
88 | //! @return 2 components by their names in specified order (in GLSL-style) |
5640d653 |
89 | NCOLLECTION_VEC_COMPONENTS_2D(x, y) |
5e27df78 |
90 | |
91 | //! Alias to 1st component as X coordinate in XY. |
92 | Element_t& x() { return v[0]; } |
93 | |
94 | //! Alias to 2nd component as Y coordinate in XY. |
95 | Element_t& y() { return v[1]; } |
96 | |
8613985b |
97 | //! Check this vector with another vector for equality (without tolerance!). |
98 | bool IsEqual (const NCollection_Vec2& theOther) const |
99 | { |
100 | return v[0] == theOther.v[0] |
101 | && v[1] == theOther.v[1]; |
102 | } |
103 | |
104 | //! Check this vector with another vector for equality (without tolerance!). |
105 | bool operator== (const NCollection_Vec2& theOther) { return IsEqual (theOther); } |
106 | bool operator== (const NCollection_Vec2& theOther) const { return IsEqual (theOther); } |
107 | |
108 | //! Check this vector with another vector for non-equality (without tolerance!). |
109 | bool operator!= (const NCollection_Vec2& theOther) { return !IsEqual (theOther); } |
110 | bool operator!= (const NCollection_Vec2& theOther) const { return !IsEqual (theOther); } |
111 | |
938d4544 |
112 | //! Raw access to the data (for OpenGL exchange). |
113 | const Element_t* GetData() const { return v; } |
114 | Element_t* ChangeData() { return v; } |
115 | operator const Element_t*() const { return v; } |
116 | operator Element_t*() { return v; } |
5e27df78 |
117 | |
118 | //! Compute per-component summary. |
119 | NCollection_Vec2& operator+= (const NCollection_Vec2& theAdd) |
120 | { |
121 | v[0] += theAdd.v[0]; |
122 | v[1] += theAdd.v[1]; |
123 | return *this; |
124 | } |
125 | |
126 | //! Compute per-component summary. |
127 | friend NCollection_Vec2 operator+ (const NCollection_Vec2& theLeft, |
128 | const NCollection_Vec2& theRight) |
129 | { |
130 | return NCollection_Vec2 (theLeft.v[0] + theRight.v[0], |
131 | theLeft.v[1] + theRight.v[1]); |
132 | } |
133 | |
134 | //! Compute per-component subtraction. |
135 | NCollection_Vec2& operator-= (const NCollection_Vec2& theDec) |
136 | { |
137 | v[0] -= theDec.v[0]; |
138 | v[1] -= theDec.v[1]; |
139 | return *this; |
140 | } |
141 | |
142 | //! Compute per-component subtraction. |
143 | friend NCollection_Vec2 operator- (const NCollection_Vec2& theLeft, |
144 | const NCollection_Vec2& theRight) |
145 | { |
146 | return NCollection_Vec2 (theLeft.v[0] - theRight.v[0], |
147 | theLeft.v[1] - theRight.v[1]); |
148 | } |
149 | |
150 | //! Unary -. |
151 | NCollection_Vec2 operator-() const |
152 | { |
153 | return NCollection_Vec2 (-x(), -y()); |
154 | } |
155 | |
156 | //! Compute per-component multiplication. |
157 | NCollection_Vec2& operator*= (const NCollection_Vec2& theRight) |
158 | { |
159 | v[0] *= theRight.v[0]; |
160 | v[1] *= theRight.v[1]; |
161 | return *this; |
162 | } |
163 | |
164 | //! Compute per-component multiplication. |
165 | friend NCollection_Vec2 operator* (const NCollection_Vec2& theLeft, |
166 | const NCollection_Vec2& theRight) |
167 | { |
168 | return NCollection_Vec2 (theLeft.v[0] * theRight.v[0], |
169 | theLeft.v[1] * theRight.v[1]); |
170 | } |
171 | |
172 | //! Compute per-component multiplication by scale factor. |
173 | void Multiply (const Element_t theFactor) |
174 | { |
175 | v[0] *= theFactor; |
176 | v[1] *= theFactor; |
177 | } |
178 | |
179 | //! Compute per-component multiplication by scale factor. |
180 | NCollection_Vec2 Multiplied (const Element_t theFactor) const |
181 | { |
182 | return NCollection_Vec2 (v[0] * theFactor, |
183 | v[1] * theFactor); |
184 | } |
185 | |
3c4e78f2 |
186 | //! Compute component-wise minimum of two vectors. |
187 | NCollection_Vec2 cwiseMin (const NCollection_Vec2& theVec) const |
188 | { |
200ed755 |
189 | return NCollection_Vec2 (v[0] < theVec.v[0] ? v[0] : theVec.v[0], |
190 | v[1] < theVec.v[1] ? v[1] : theVec.v[1]); |
3c4e78f2 |
191 | } |
192 | |
193 | //! Compute component-wise maximum of two vectors. |
194 | NCollection_Vec2 cwiseMax (const NCollection_Vec2& theVec) const |
195 | { |
200ed755 |
196 | return NCollection_Vec2 (v[0] > theVec.v[0] ? v[0] : theVec.v[0], |
197 | v[1] > theVec.v[1] ? v[1] : theVec.v[1]); |
3c4e78f2 |
198 | } |
199 | |
91c60b57 |
200 | //! Compute component-wise modulus of the vector. |
201 | NCollection_Vec2 cwiseAbs() const |
202 | { |
203 | return NCollection_Vec2 (std::abs (v[0]), |
204 | std::abs (v[1])); |
205 | } |
206 | |
207 | //! Compute maximum component of the vector. |
208 | Element_t maxComp() const |
209 | { |
210 | return v[0] > v[1] ? v[0] : v[1]; |
211 | } |
212 | |
213 | //! Compute minimum component of the vector. |
214 | Element_t minComp() const |
215 | { |
216 | return v[0] < v[1] ? v[0] : v[1]; |
217 | } |
218 | |
5e27df78 |
219 | //! Compute per-component multiplication by scale factor. |
220 | NCollection_Vec2& operator*= (const Element_t theFactor) |
221 | { |
222 | Multiply (theFactor); |
223 | return *this; |
224 | } |
225 | |
226 | //! Compute per-component division by scale factor. |
227 | NCollection_Vec2& operator/= (const Element_t theInvFactor) |
228 | { |
229 | v[0] /= theInvFactor; |
230 | v[1] /= theInvFactor; |
231 | return *this; |
232 | } |
233 | |
d0bcf7aa |
234 | //! Compute per-component division. |
235 | NCollection_Vec2& operator/= (const NCollection_Vec2& theRight) |
236 | { |
237 | v[0] /= theRight.v[0]; |
238 | v[1] /= theRight.v[1]; |
239 | return *this; |
240 | } |
241 | |
5e27df78 |
242 | //! Compute per-component multiplication by scale factor. |
243 | NCollection_Vec2 operator* (const Element_t theFactor) const |
244 | { |
245 | return Multiplied (theFactor); |
246 | } |
247 | |
248 | //! Compute per-component division by scale factor. |
249 | NCollection_Vec2 operator/ (const Element_t theInvFactor) const |
250 | { |
251 | return NCollection_Vec2(v[0] / theInvFactor, |
252 | v[1] / theInvFactor); |
253 | } |
254 | |
d0bcf7aa |
255 | //! Compute per-component division. |
256 | friend NCollection_Vec2 operator/ (const NCollection_Vec2& theLeft, |
257 | const NCollection_Vec2& theRight) |
258 | { |
259 | return NCollection_Vec2 (theLeft.v[0] / theRight.v[0], |
260 | theLeft.v[1] / theRight.v[1]); |
261 | } |
262 | |
5e27df78 |
263 | //! Computes the dot product. |
264 | Element_t Dot (const NCollection_Vec2& theOther) const |
265 | { |
266 | return x() * theOther.x() + y() * theOther.y(); |
267 | } |
268 | |
269 | //! Computes the vector modulus (magnitude, length). |
270 | Element_t Modulus() const |
271 | { |
272 | return std::sqrt (x() * x() + y() * y()); |
273 | } |
274 | |
275 | //! Computes the square of vector modulus (magnitude, length). |
276 | //! This method may be used for performance tricks. |
277 | Element_t SquareModulus() const |
278 | { |
279 | return x() * x() + y() * y(); |
280 | } |
281 | |
282 | //! Constuct DX unit vector. |
283 | static NCollection_Vec2 DX() |
284 | { |
285 | return NCollection_Vec2 (Element_t(1), Element_t(0)); |
286 | } |
287 | |
288 | //! Constuct DY unit vector. |
289 | static NCollection_Vec2 DY() |
290 | { |
291 | return NCollection_Vec2 (Element_t(0), Element_t(1)); |
292 | } |
293 | |
a5162275 |
294 | //! Dumps the content of me into the stream |
295 | void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const |
296 | { |
297 | (void)theDepth; |
298 | OCCT_DUMP_FIELD_VALUES_NUMERICAL (theOStream, "Vec2", 2, v[0], v[1]) |
299 | } |
300 | |
5e27df78 |
301 | private: |
302 | |
303 | Element_t v[2]; |
304 | |
305 | }; |
306 | |
307 | #endif // _NCollection_Vec2_H__ |