]> Dogcows Code - chaz/yoink/blob - src/vector.hh
new interface class: drawable
[chaz/yoink] / src / vector.hh
1
2 /*******************************************************************************
3
4 Copyright (c) 2009, Charles McGarvey
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 *******************************************************************************/
28
29 #ifndef _VECTOR_HH_
30 #define _VECTOR_HH_
31
32 /**
33 * @file vector.hh
34 * Vector classes.
35 */
36
37 #include <iostream>
38 #include <cassert>
39
40 #include "math.hh"
41 #include "random.hh"
42
43
44 // TODO: project, reflect, random, normal (of plane), orthonormal
45
46 namespace dc {
47
48 /**
49 * 2-dimensional vector.
50 */
51
52 struct vector2
53 {
54 vector2() {}
55 vector2(scalar X, scalar Y) : x(X), y(Y) {}
56 vector2(scalar v[2]) : x(v[0]), y(v[1]) {}
57
58 const scalar& operator[](int i) const
59 {
60 assert(i >= 0 && i <= 1 && "Index into vector2 out of bounds.");
61 return array[i];
62 }
63 scalar& operator[](int i)
64 {
65 assert(i >= 0 && i <= 1 && "Index into vector2 out of bounds.");
66 return array[i];
67 }
68
69 vector2 operator+(const vector2& v) const
70 {
71 return vector2(x + v.x, y + v.y);
72 }
73 vector2 operator-(const vector2& v) const
74 {
75 return vector2(x - v.x, y - v.y);
76 }
77 vector2 operator*(scalar s) const
78 {
79 return vector2(x * s, y * s);
80 }
81 vector2 operator/(scalar s) const
82 {
83 return vector2(x / s, y / s);
84 }
85
86 vector2& operator+=(const vector2& v)
87 {
88 x += v.x; y += v.y;
89 return *this;
90 }
91 vector2& operator-=(const vector2& v)
92 {
93 x -= v.x; y -= v.y;
94 return *this;
95 }
96 vector2& operator*=(scalar s)
97 {
98 x *= s; y *= s;
99 return *this;
100 }
101 vector2& operator/=(scalar s)
102 {
103 x /= s; y /= s;
104 return *this;
105 }
106
107 vector2 operator-() const
108 {
109 return vector2(-x, -y);
110 }
111
112 scalar dot(const vector2& v) const /// dot product
113 {
114 return x * v.x + y * v.y;
115 }
116 scalar angleBetween(const vector2& v) const
117 {
118 scalar lens = length() * v.length();
119 if (lens == 0.0) { return HUGE_VAL; }
120 return std::acos(dot(v) / lens);
121 }
122
123 void normalize() /// scale such that length is one
124 {
125 scalar len = length();
126 if (len != 0.0) { *this /= len; }
127 }
128 vector2 normalized() const
129 {
130 scalar len = length();
131 if (len != 0.0) { return *this / len; }
132 return vector2(0.0, 0.0);
133 }
134
135 scalar length2() const /// magnitude squared
136 {
137 return dot(*this);
138 }
139 scalar length() const /// magnitude
140 {
141 return std::sqrt(length2());
142 }
143
144 bool operator==(const vector2& v) const
145 {
146 return equals(x, v.x) && equals(y, v.y);
147 }
148 bool operator!=(const vector2& v) const
149 {
150 return !(*this == v);
151 }
152
153
154 static vector2 random()
155 {
156 vector2 v = random(-1.0, 1.0);
157 v.normalize();
158 return v;
159 }
160
161 static vector2 random(scalar lower, scalar upper)
162 {
163 return vector2(rng::get<scalar>(lower, upper),
164 rng::get<scalar>(lower, upper));
165 }
166
167
168 union
169 {
170 struct
171 {
172 scalar x, y; ///< euler coordinates
173 };
174 scalar array[2]; ///< array
175 };
176
177 static vector2 zero; ///< zero vector
178 };
179
180 inline vector2 operator*(scalar s, const vector2& v)
181 {
182 return v * s;
183 }
184 inline vector2 operator/(scalar s, const vector2& v)
185 {
186 return vector2(s / v.x, s / v.y);
187 }
188
189 inline std::ostream& operator<<(std::ostream& output, const vector2& v)
190 {
191 output << "(" << v.x << "," << v.y << ")";
192 return output;
193 }
194
195
196 typedef vector2 point;
197
198
199 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
200
201 /**
202 * 3-dimensional vector.
203 */
204
205 struct vector3
206 {
207 vector3() {}
208 vector3(scalar X, scalar Y, scalar Z) : x(X), y(Y), z(Z) {}
209 vector3(scalar v[3]) : x(v[0]), y(v[1]), z(v[2]) {}
210
211 const scalar& operator[](int i) const
212 {
213 assert(i >= 0 && i <= 2 && "Index into vector3 out of bounds.");
214 return array[i];
215 }
216 scalar& operator[](int i)
217 {
218 assert(i >= 0 && i <= 2 && "Index into vector3 out of bounds.");
219 return array[i];
220 }
221
222 vector3 operator+(const vector3& v) const
223 {
224 return vector3(x + v.x, y + v.y, z + v.z);
225 }
226 vector3 operator-(const vector3& v) const
227 {
228 return vector3(x - v.x, y - v.y, z - v.z);
229 }
230 vector3 operator*(scalar s) const
231 {
232 return vector3(x * s, y * s, z * s);
233 }
234 vector3 operator/(scalar s) const
235 {
236 return vector3(x / s, y / s, z / s);
237 }
238
239 vector3& operator+=(const vector3& v)
240 {
241 x += v.x; y += v.y; z += v.z;
242 return *this;
243 }
244 vector3& operator-=(const vector3& v)
245 {
246 x -= v.x; y -= v.y; z -= v.z;
247 return *this;
248 }
249 vector3& operator*=(scalar s)
250 {
251 x *= s; y *= s; z *= s;
252 return *this;
253 }
254 vector3& operator/=(scalar s)
255 {
256 x /= s; y /= s; z /= s;
257 return *this;
258 }
259
260 vector3 operator-() const
261 {
262 return vector3(-x, -y, -z);
263 }
264
265 scalar dot(const vector3& v) const /// dot product
266 {
267 return x * v.x + y * v.y + z * v.z;
268 }
269 vector3 cross(const vector3& v) const /// cross product
270 {
271 return vector3(y * v.z - z * v.y,
272 z * v.x - x * v.z,
273 x * v.y - y * v.x);
274 }
275
276 scalar angleBetween(const vector3& v) const
277 {
278 scalar lens = length() * v.length();
279 if (lens == 0.0) { return HUGE_VAL; }
280 return std::acos(dot(v) / lens);
281 }
282
283 void normalize() /// scale such that length is one
284 {
285 scalar len = length();
286 if (len != 0.0) { *this /= len; }
287 }
288 vector3 normalized() const
289 {
290 scalar len = length();
291 if (len != 0.0) { return *this / len; }
292 return vector3(0.0, 0.0, 0.0);
293 }
294
295 scalar length2() const /// magnitude squared
296 {
297 return dot(*this);
298 }
299 scalar length() const /// magnitude
300 {
301 return std::sqrt(length2());
302 }
303
304 bool operator==(const vector3& v) const
305 {
306 return equals(x, v.x) && equals(y, v.y) && equals(z, v.z);
307 }
308 bool operator!=(const vector3& v) const
309 {
310 return !(*this == v);
311 }
312
313
314 static vector3 random()
315 {
316 vector3 v = random(-1.0, 1.0);
317 v.normalize();
318 return v;
319 }
320
321 static vector3 random(scalar lower, scalar upper)
322 {
323 return vector3(rng::get<scalar>(lower, upper),
324 rng::get<scalar>(lower, upper),
325 rng::get<scalar>(lower, upper));
326 }
327
328
329 union
330 {
331 struct
332 {
333 scalar x, y, z; ///< euler coordinates
334 };
335 struct
336 {
337 scalar u, v, w; ///< texture coordinates
338 };
339 struct
340 {
341 scalar r, g, b; ///< color intensities
342 };
343 scalar array[3]; ///< array
344 };
345
346 static vector3 zero; ///< zero vector
347 };
348
349 inline vector3 operator*(scalar s, const vector3& v)
350 {
351 return v * s;
352 }
353 inline vector3 operator/(scalar s, const vector3& v)
354 {
355 return vector3(s / v.x, s / v.y, s / v.z);
356 }
357
358 inline std::ostream& operator<<(std::ostream& output, const vector3& v)
359 {
360 output << "(" << v.x << "," << v.y << "," << v.z << ")";
361 return output;
362 }
363
364
365 typedef vector3 color;
366
367
368 } // namespace dc
369
370
371 #endif // _VECTOR_HH_
372
This page took 0.048696 seconds and 4 git commands to generate.