Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2189 | - | 1 | // -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: t -*- |
2 | |||
3 | // Copyright 2010 Michael Smith, all rights reserved. |
||
4 | |||
5 | // This library is free software; you can redistribute it and / or |
||
6 | // modify it under the terms of the GNU Lesser General Public |
||
7 | // License as published by the Free Software Foundation; either |
||
8 | // version 2.1 of the License, or (at your option) any later version. |
||
9 | |||
10 | // Derived closely from: |
||
11 | /**************************************** |
||
12 | * 3D Vector Classes |
||
13 | * By Bill Perone (billperone@yahoo.com) |
||
14 | * Original: 9-16-2002 |
||
15 | * Revised: 19-11-2003 |
||
16 | * 11-12-2003 |
||
17 | * 18-12-2003 |
||
18 | * 06-06-2004 |
||
19 | * |
||
20 | * � 2003, This code is provided "as is" and you can use it freely as long as |
||
21 | * credit is given to Bill Perone in the application it is used in |
||
22 | * |
||
23 | * Notes: |
||
24 | * if a*b = 0 then a & b are orthogonal |
||
25 | * a%b = -b%a |
||
26 | * a*(b%c) = (a%b)*c |
||
27 | * a%b = a(cast to matrix)*b |
||
28 | * (a%b).length() = area of parallelogram formed by a & b |
||
29 | * (a%b).length() = a.length()*b.length() * sin(angle between a & b) |
||
30 | * (a%b).length() = 0 if angle between a & b = 0 or a.length() = 0 or b.length() = 0 |
||
31 | * a * (b%c) = volume of parallelpiped formed by a, b, c |
||
32 | * vector triple product: a%(b%c) = b*(a*c) - c*(a*b) |
||
33 | * scalar triple product: a*(b%c) = c*(a%b) = b*(c%a) |
||
34 | * vector quadruple product: (a%b)*(c%d) = (a*c)*(b*d) - (a*d)*(b*c) |
||
35 | * if a is unit vector along b then a%b = -b%a = -b(cast to matrix)*a = 0 |
||
36 | * vectors a1...an are linearly dependant if there exists a vector of scalars (b) where a1*b1 + ... + an*bn = 0 |
||
37 | * or if the matrix (A) * b = 0 |
||
38 | * |
||
39 | ****************************************/ |
||
40 | |||
41 | #ifndef VECTOR3_H |
||
42 | #define VECTOR3_H |
||
43 | |||
44 | #include <math.h> |
||
45 | #include <string.h> |
||
46 | #include "Constants.h" |
||
47 | #include "Vector3.h" |
||
48 | |||
49 | template <typename T> |
||
50 | class Vector3 |
||
51 | { |
||
52 | public: |
||
53 | T x, y, z; |
||
54 | |||
55 | // trivial ctor |
||
56 | Vector3<T>() { x = y = z = 0; } |
||
57 | |||
58 | // setting ctor |
||
59 | Vector3<T>(const T x0, const T y0, const T z0): x(x0), y(y0), z(z0) {} |
||
60 | |||
61 | // function call operator |
||
62 | void operator ()(const T x0, const T y0, const T z0) |
||
63 | { x= x0; y= y0; z= z0; } |
||
64 | |||
65 | // indexing operator |
||
66 | T operator [](uint8_t i) |
||
67 | { switch(i) { |
||
68 | case 0: return x; |
||
69 | case 1: return y; |
||
70 | case 2: return z; |
||
71 | default: return 0; |
||
72 | } |
||
73 | } |
||
74 | |||
75 | // test for equality |
||
76 | bool operator==(const Vector3<T> &v) |
||
77 | { return (x==v.x && y==v.y && z==v.z); } |
||
78 | |||
79 | // test for inequality |
||
80 | bool operator!=(const Vector3<T> &v) |
||
81 | { return (x!=v.x || y!=v.y || z!=v.z); } |
||
82 | |||
83 | // negation |
||
84 | Vector3<T> operator -(void) const |
||
85 | { return Vector3<T>(-x,-y,-z); } |
||
86 | |||
87 | // addition |
||
88 | Vector3<T> operator +(const Vector3<T> &v) const |
||
89 | { return Vector3<T>(x+v.x, y+v.y, z+v.z); } |
||
90 | |||
91 | // subtraction |
||
92 | Vector3<T> operator -(const Vector3<T> &v) const |
||
93 | { return Vector3<T>(x-v.x, y-v.y, z-v.z); } |
||
94 | |||
95 | // uniform scaling |
||
96 | Vector3<T> operator *(const T num) const |
||
97 | { |
||
98 | Vector3<T> temp(*this); |
||
99 | return temp*=num; |
||
100 | } |
||
101 | |||
102 | // uniform scaling |
||
103 | Vector3<T> operator /(const T num) const |
||
104 | { |
||
105 | Vector3<T> temp(*this); |
||
106 | return temp/=num; |
||
107 | } |
||
108 | |||
109 | // addition |
||
110 | Vector3<T> &operator +=(const Vector3<T> &v) |
||
111 | { |
||
112 | x+=v.x; y+=v.y; z+=v.z; |
||
113 | return *this; |
||
114 | } |
||
115 | |||
116 | // subtraction |
||
117 | Vector3<T> &operator -=(const Vector3<T> &v) |
||
118 | { |
||
119 | x-=v.x; y-=v.y; z-=v.z; |
||
120 | return *this; |
||
121 | } |
||
122 | |||
123 | // uniform scaling |
||
124 | Vector3<T> &operator *=(const T num) |
||
125 | { |
||
126 | x*=num; y*=num; z*=num; |
||
127 | return *this; |
||
128 | } |
||
129 | |||
130 | // uniform scaling |
||
131 | Vector3<T> &operator /=(const T num) |
||
132 | { |
||
133 | x/=num; y/=num; z/=num; |
||
134 | return *this; |
||
135 | } |
||
136 | |||
137 | // dot product |
||
138 | T operator *(const Vector3<T> &v) const |
||
139 | { return x*v.x + y*v.y + z*v.z; } |
||
140 | |||
141 | // cross product |
||
142 | Vector3<T> operator %(const Vector3<T> &v) const |
||
143 | { |
||
144 | Vector3<T> temp(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x); |
||
145 | return temp; |
||
146 | } |
||
147 | |||
148 | // gets the length of this vector squared |
||
149 | T length_squared() const |
||
150 | { return (T)(*this * *this); } |
||
151 | |||
152 | // gets the length of this vector |
||
153 | float length() const |
||
154 | { return (T)sqrt(*this * *this); } |
||
155 | |||
156 | // normalizes this vector |
||
157 | void normalize() |
||
158 | { *this/=length(); } |
||
159 | |||
160 | // zero the vector |
||
161 | void zero() |
||
162 | { x = y = z = 0.0; } |
||
163 | |||
164 | // returns the normalized version of this vector |
||
165 | Vector3<T> normalized() const |
||
166 | { return *this/length(); } |
||
167 | |||
168 | // reflects this vector about n |
||
169 | void reflect(const Vector3<T> &n) |
||
170 | { |
||
171 | Vector3<T> orig(*this); |
||
172 | project(n); |
||
173 | *this= *this*2 - orig; |
||
174 | } |
||
175 | |||
176 | // projects this vector onto v |
||
177 | void project(const Vector3<T> &v) |
||
178 | { *this= v * (*this * v)/(v*v); } |
||
179 | |||
180 | // returns this vector projected onto v |
||
181 | Vector3<T> projected(const Vector3<T> &v) |
||
182 | { return v * (*this * v)/(v*v); } |
||
183 | |||
184 | // computes the angle between 2 arbitrary vectors |
||
185 | T angle(const Vector3<T> &v1, const Vector3<T> &v2) |
||
186 | { return (T)acosf((v1*v2) / (v1.length()*v2.length())); } |
||
187 | |||
188 | // computes the angle between 2 arbitrary normalized vectors |
||
189 | T angle_normalized(const Vector3<T> &v1, const Vector3<T> &v2) |
||
190 | { return (T)acosf(v1*v2); } |
||
191 | |||
192 | // check if any elements are NAN |
||
193 | bool is_nan(void) |
||
194 | { return isnan(x) || isnan(y) || isnan(z); } |
||
195 | |||
196 | // check if any elements are infinity |
||
197 | bool is_inf(void) |
||
198 | { return isinf(x) || isinf(y) || isinf(z); } |
||
199 | |||
200 | // rotate by a standard rotation |
||
201 | void rotate(enum Rotation rotation); |
||
202 | |||
203 | }; |
||
204 | |||
205 | typedef Vector3<int16_t> Vector3i; |
||
206 | typedef Vector3<uint16_t> Vector3ui; |
||
207 | typedef Vector3<int32_t> Vector3l; |
||
208 | typedef Vector3<uint32_t> Vector3ul; |
||
209 | typedef Vector3<float> Vector3f; |
||
210 | |||
211 | #endif // VECTOR3_H |