00001
00002
00003
00004
00005
00006
00007
00008 #ifndef QAF_UTIL_VECTOR3D_H
00009 #define QAF_UTIL_VECTOR3D_H
00010
00011 #include <math.h>
00012 #include "../qafDef.h"
00013
00014
00015 namespace qaf {
00016
00029 class Vector3D {
00030 public:
00031 float x, y, z;
00032
00033 Vector3D () : x(0), y(0), z(0) {}
00034 Vector3D ( float _x, float _y, float _z ) : x(_x), y(_y), z(_z) {}
00035 Vector3D ( int _x, int _y, int _z ) : x((float) _x), y((float) _y), z((float) _z) {}
00036
00037 inline Vector3D & operator = ( const Vector3D & v );
00038
00040 inline float length () const;
00041
00043 inline Vector3D unit () const;
00044
00046 inline float dist ( const Vector3D & that ) const;
00047
00049 inline void normalize ();
00050
00052 inline Vector3D project ( const Vector3D & onto ) const;
00053
00055 inline Vector3D reflect ( const Vector3D & around ) const;
00056
00058 inline Vector3D rotate ( const Vector3D & axis, float angle ) const;
00059
00060 inline Vector3D & operator += ( const Vector3D & v );
00061 inline Vector3D & operator -= ( const Vector3D & v );
00062 inline Vector3D operator + ( const Vector3D & v ) const;
00063 inline Vector3D operator - ( const Vector3D & v ) const;
00064 inline Vector3D operator - () const;
00065
00066 inline Vector3D & operator *= ( float s );
00067 inline Vector3D operator * ( float s ) const;
00068 inline Vector3D & operator /= ( float s );
00069 inline Vector3D operator / ( float s ) const;
00070
00072 inline float operator * ( const Vector3D & v ) const;
00073
00075
00076 inline Vector3D & operator %= ( const Vector3D & v );
00077 inline Vector3D operator % ( const Vector3D & v ) const;
00079
00080 };
00081
00082 inline Vector3D operator * ( float s, const Vector3D & t );
00083
00084
00085
00086 Vector3D & Vector3D::operator = ( const Vector3D & v ) {
00087 x = v.x;
00088 y = v.y;
00089 z = v.z;
00090
00091 return *this;
00092 }
00093
00094
00095 float Vector3D::length () const {
00096 return sqrtf( x * x + y * y + z * z );
00097 }
00098
00099
00100 float Vector3D::dist ( const Vector3D & that ) const {
00101 return sqrtf( ((x - that.x) * (x - that.x)) +
00102 ((y - that.y) * (y - that.y)) +
00103 ((z - that.z) * (z - that.z)) );
00104 }
00105
00106
00107 Vector3D Vector3D::unit () const {
00108 float abs = length();
00109 if ( abs <= QAF_EPSILON )
00110 return (*this);
00111 else
00112 return Vector3D(
00113 x / abs,
00114 y / abs,
00115 z / abs );
00116 }
00117
00118 void Vector3D::normalize () {
00119 float abs = length();
00120 if ( abs <= QAF_EPSILON )
00121 return;
00122 else {
00123 x /= abs;
00124 y /= abs;
00125 z /= abs;
00126 }
00127 }
00128
00129
00130 Vector3D Vector3D::project ( const Vector3D & onto ) const {
00131
00132 if ( fabs(onto * onto) < QAF_EPSILON )
00133 return Vector3D( 0, 0, 0 );
00134
00135
00136
00137 float newScale = ((*this) * onto)/(onto * onto);
00138
00139
00140 return Vector3D (
00141 onto.x * newScale,
00142 onto.y * newScale,
00143 onto.z * newScale );
00144 }
00145
00146
00147 Vector3D Vector3D::reflect ( const Vector3D & around ) const {
00148
00149 Vector3D vProj = this->project( around );
00150
00151
00152 Vector3D vIncrH ( vProj.x - x, vProj.y - y, vProj.z - z );
00153
00154
00155 return Vector3D (
00156 vProj.x + vIncrH.x,
00157 vProj.y + vIncrH.y,
00158 vProj.z + vIncrH.z );
00159 }
00160
00161
00162 Vector3D Vector3D::rotate ( const Vector3D & axis, float angle ) const {
00163 float axisLength = axis.length();
00164
00165 if ( axisLength >= QAF_EPSILON ) {
00166 float cos_a = cosf( angle );
00167 float sin_a = sinf( angle );
00168
00169 Vector3D e = axis / axisLength;
00170
00171 return Vector3D (
00172 (cos_a + (1 - cos_a)*e.x*e.x) * x + (e.x*e.y*(1 - cos_a) - e.z*sin_a) * y + (e.z*e.x*(1 - cos_a) + e.y*sin_a) * z,
00173 (e.x*e.y*(1 - cos_a) + e.z*sin_a) * x + (cos_a + (1 - cos_a)*e.y*e.y) * y + (e.y*e.z*(1 - cos_a) - e.x*sin_a) * z,
00174 (e.x*e.z*(1 - cos_a) - e.y*sin_a) * x + (e.y*e.z*(1 - cos_a) + e.x*sin_a) * y + (cos_a + (1 - cos_a)*e.z*e.z) * z );
00175 }
00176 else {
00177
00178 return (*this);
00179 }
00180 }
00181
00182
00183 Vector3D & Vector3D::operator += ( const Vector3D & v ) {
00184 x += v.x;
00185 y += v.y;
00186 z += v.z;
00187
00188 return *this;
00189 }
00190
00191 Vector3D & Vector3D::operator -= ( const Vector3D & v ) {
00192 x -= v.x;
00193 y -= v.y;
00194 z -= v.z;
00195
00196 return *this;
00197 }
00198
00199 Vector3D Vector3D::operator + ( const Vector3D & v ) const {
00200 return Vector3D (
00201 x + v.x,
00202 y + v.y,
00203 z + v.z );
00204 }
00205
00206 Vector3D Vector3D::operator - ( const Vector3D & v ) const {
00207 return Vector3D (
00208 x - v.x,
00209 y - v.y,
00210 z - v.z );
00211 }
00212
00213 Vector3D Vector3D::operator - () const {
00214 return Vector3D (
00215 -x,
00216 -y,
00217 -z);
00218 }
00219
00220
00221 Vector3D & Vector3D::operator *= ( float s ) {
00222 x *= s;
00223 y *= s;
00224 z *= s;
00225
00226 return *this;
00227 }
00228
00229 Vector3D Vector3D::operator * ( float s ) const {
00230 return Vector3D (
00231 x * s,
00232 y * s,
00233 z * s );
00234 }
00235
00236 Vector3D operator * ( float s, const Vector3D & t ) {
00237 return Vector3D (
00238 t.x * s,
00239 t.y * s,
00240 t.z * s );
00241 }
00242
00243 Vector3D & Vector3D::operator /= ( float s ) {
00244 x /= s;
00245 y /= s;
00246 z /= s;
00247
00248 return *this;
00249 }
00250
00251 Vector3D Vector3D::operator / ( float s ) const {
00252 return Vector3D (
00253 x / s,
00254 y / s,
00255 z / s );
00256 }
00257
00258
00259 float Vector3D::operator * ( const Vector3D & v ) const {
00260 return x * v.x + y * v.y + z * v.z;
00261 }
00262
00263
00264 Vector3D & Vector3D::operator %= ( const Vector3D & v ) {
00265 x = y * v.z - z * v.y;
00266 y = z * v.x - x * v.z;
00267 z = x * v.y - y * v.x;
00268
00269 return *this;
00270 }
00271
00272 Vector3D Vector3D::operator % ( const Vector3D & v ) const {
00273 return Vector3D (
00274 y * v.z - z * v.y,
00275 z * v.x - x * v.z,
00276 x * v.y - y * v.x );
00277 }
00278
00279
00280 }
00281
00282
00283 #endif