Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1702 | - | 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 | |||
47 | template <typename T> |
||
48 | class Vector3 |
||
49 | { |
||
50 | public: |
||
51 | T x, y, z; |
||
52 | |||
53 | // trivial ctor |
||
54 | Vector3<T>() { x = y = z = 0; } |
||
55 | |||
56 | // setting ctor |
||
57 | Vector3<T>(const T x0, const T y0, const T z0): x(x0), y(y0), z(z0) {} |
||
58 | |||
59 | // function call operator |
||
60 | void operator ()(const T x0, const T y0, const T z0) |
||
61 | { x= x0; y= y0; z= z0; } |
||
62 | |||
63 | // test for equality |
||
64 | bool operator==(const Vector3<T> &v) |
||
65 | { return (x==v.x && y==v.y && z==v.z); } |
||
66 | |||
67 | // test for inequality |
||
68 | bool operator!=(const Vector3<T> &v) |
||
69 | { return (x!=v.x || y!=v.y || z!=v.z); } |
||
70 | |||
71 | // negation |
||
72 | Vector3<T> operator -(void) const |
||
73 | { return Vector3<T>(-x,-y,-z); } |
||
74 | |||
75 | // addition |
||
76 | Vector3<T> operator +(const Vector3<T> &v) const |
||
77 | { return Vector3<T>(x+v.x, y+v.y, z+v.z); } |
||
78 | |||
79 | // subtraction |
||
80 | Vector3<T> operator -(const Vector3<T> &v) const |
||
81 | { return Vector3<T>(x-v.x, y-v.y, z-v.z); } |
||
82 | |||
83 | // uniform scaling |
||
84 | Vector3<T> operator *(const T num) const |
||
85 | { |
||
86 | Vector3<T> temp(*this); |
||
87 | return temp*=num; |
||
88 | } |
||
89 | |||
90 | // uniform scaling |
||
91 | Vector3<T> operator /(const T num) const |
||
92 | { |
||
93 | Vector3<T> temp(*this); |
||
94 | return temp/=num; |
||
95 | } |
||
96 | |||
97 | // addition |
||
98 | Vector3<T> &operator +=(const Vector3<T> &v) |
||
99 | { |
||
100 | x+=v.x; y+=v.y; z+=v.z; |
||
101 | return *this; |
||
102 | } |
||
103 | |||
104 | // subtraction |
||
105 | Vector3<T> &operator -=(const Vector3<T> &v) |
||
106 | { |
||
107 | x-=v.x; y-=v.y; z-=v.z; |
||
108 | return *this; |
||
109 | } |
||
110 | |||
111 | // uniform scaling |
||
112 | Vector3<T> &operator *=(const T num) |
||
113 | { |
||
114 | x*=num; y*=num; z*=num; |
||
115 | return *this; |
||
116 | } |
||
117 | |||
118 | // uniform scaling |
||
119 | Vector3<T> &operator /=(const T num) |
||
120 | { |
||
121 | x/=num; y/=num; z/=num; |
||
122 | return *this; |
||
123 | } |
||
124 | |||
125 | // dot product |
||
126 | T operator *(const Vector3<T> &v) const |
||
127 | { return x*v.x + y*v.y + z*v.z; } |
||
128 | |||
129 | // cross product |
||
130 | Vector3<T> operator %(const Vector3<T> &v) const |
||
131 | { |
||
132 | Vector3<T> temp(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x); |
||
133 | return temp; |
||
134 | } |
||
135 | |||
136 | // gets the length of this vector squared |
||
137 | T length_squared() const |
||
138 | { return (T)(*this * *this); } |
||
139 | |||
140 | // gets the length of this vector |
||
141 | float length() const |
||
142 | { return (T)sqrt(*this * *this); } |
||
143 | |||
144 | // normalizes this vector |
||
145 | void normalize() |
||
146 | { *this/=length(); } |
||
147 | |||
148 | // zero the vector |
||
149 | void zero() |
||
150 | { x = y = z = 0.0; } |
||
151 | |||
152 | // returns the normalized version of this vector |
||
153 | Vector3<T> normalized() const |
||
154 | { return *this/length(); } |
||
155 | |||
156 | // reflects this vector about n |
||
157 | void reflect(const Vector3<T> &n) |
||
158 | { |
||
159 | Vector3<T> orig(*this); |
||
160 | project(n); |
||
161 | *this= *this*2 - orig; |
||
162 | } |
||
163 | |||
164 | // projects this vector onto v |
||
165 | void project(const Vector3<T> &v) |
||
166 | { *this= v * (*this * v)/(v*v); } |
||
167 | |||
168 | // returns this vector projected onto v |
||
169 | Vector3<T> projected(const Vector3<T> &v) |
||
170 | { return v * (*this * v)/(v*v); } |
||
171 | |||
172 | // computes the angle between 2 arbitrary vectors |
||
173 | T angle(const Vector3<T> &v1, const Vector3<T> &v2) |
||
174 | { return (T)acosf((v1*v2) / (v1.length()*v2.length())); } |
||
175 | |||
176 | // computes the angle between 2 arbitrary normalized vectors |
||
177 | T angle_normalized(const Vector3<T> &v1, const Vector3<T> &v2) |
||
178 | { return (T)acosf(v1*v2); } |
||
179 | |||
180 | // check if any elements are NAN |
||
181 | bool is_nan(void) |
||
182 | { return isnan(x) || isnan(y) || isnan(z); } |
||
183 | |||
184 | // check if any elements are infinity |
||
185 | bool is_inf(void) |
||
186 | { return isinf(x) || isinf(y) || isinf(z); } |
||
187 | |||
188 | // rotate by a standard rotation |
||
189 | void rotate(enum Rotation rotation); |
||
190 | |||
191 | }; |
||
192 | |||
193 | typedef Vector3<int16_t> Vector3i; |
||
194 | typedef Vector3<uint16_t> Vector3ui; |
||
195 | typedef Vector3<int32_t> Vector3l; |
||
196 | typedef Vector3<uint32_t> Vector3ul; |
||
197 | typedef Vector3<float> Vector3f; |
||
198 | |||
199 | #endif // VECTOR3_H |