1 | #ifndef MXVEC4_INCLUDED // -*- C++ -*-
|
---|
2 | #define MXVEC4_INCLUDED
|
---|
3 | #if !defined(__GNUC__)
|
---|
4 | # pragma once
|
---|
5 | #endif
|
---|
6 |
|
---|
7 | /************************************************************************
|
---|
8 |
|
---|
9 | 4D Vector class
|
---|
10 |
|
---|
11 | Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details.
|
---|
12 |
|
---|
13 | $Id: MxVec4.h,v 1.1 2002/09/24 16:53:54 wimmer Exp $
|
---|
14 |
|
---|
15 | ************************************************************************/
|
---|
16 |
|
---|
17 | #include "MxMath.h"
|
---|
18 | #include "MxVec3.h"
|
---|
19 |
|
---|
20 | #ifdef MIX_USE_TVEC
|
---|
21 | #include "MxVector.h"
|
---|
22 |
|
---|
23 | template<class T>
|
---|
24 | class MxTVec4 : public MxVBlock<T, 4>
|
---|
25 | {
|
---|
26 | public:
|
---|
27 | MxTVec4() { }
|
---|
28 | MxTVec4(T x, T y, T z, T w)
|
---|
29 | { (*this)[0]=x; (*this)[1]=y; (*this)[2]=z; (*this)[3]=w; }
|
---|
30 | MxTVec4(const MxVBlock<T, 3>& v, T w)
|
---|
31 | {(*this)[0]=v[0];(*this)[1]=v[1];(*this)[2]=v[2];(*this)[3]=w;}
|
---|
32 | MxTVec4(const MxVBlock<T, 4>& v) : MxVBlock<T, 4>(v) { }
|
---|
33 | MxTVec4(const float *v)
|
---|
34 | {(*this)[0]=v[0];(*this)[1]=v[1];(*this)[2]=v[2];(*this)[3]=v[3];}
|
---|
35 | MxTVec4(const double *v)
|
---|
36 | {(*this)[0]=v[0];(*this)[1]=v[1];(*this)[2]=v[2];(*this)[3]=v[3];}
|
---|
37 | };
|
---|
38 |
|
---|
39 | typedef MxTVec4<double> Vec4;
|
---|
40 |
|
---|
41 | #else
|
---|
42 |
|
---|
43 | class Vec4 {
|
---|
44 | private:
|
---|
45 | double elt[4];
|
---|
46 |
|
---|
47 | protected:
|
---|
48 | inline void copy(const Vec4& v);
|
---|
49 |
|
---|
50 | public:
|
---|
51 | //
|
---|
52 | // Standard constructors
|
---|
53 | //
|
---|
54 | Vec4(double x=0, double y=0, double z=0, double w=0) {
|
---|
55 | elt[0]=x; elt[1]=y; elt[2]=z; elt[3]=w;
|
---|
56 | }
|
---|
57 | Vec4(const Vec3& v,double w) {elt[0]=v[0];elt[1]=v[1];elt[2]=v[2];elt[3]=w;}
|
---|
58 | Vec4(const Vec4& v) { copy(v); }
|
---|
59 | Vec4(const float *v) {elt[0]=v[0]; elt[1]=v[1]; elt[2]=v[2]; elt[3]=v[3]; }
|
---|
60 | Vec4(const double *v) {elt[0]=v[0]; elt[1]=v[1]; elt[2]=v[2]; elt[3]=v[3];}
|
---|
61 |
|
---|
62 | //
|
---|
63 | // Access methods
|
---|
64 | //
|
---|
65 | double& operator()(uint i) { AssertBound(i<4); return elt[i]; }
|
---|
66 | double operator()(uint i) const { AssertBound(i<4); return elt[i]; }
|
---|
67 | #ifdef __GNUC__
|
---|
68 | double& operator[](uint i) { return elt[i]; }
|
---|
69 | double operator[](uint i) const { return elt[i]; }
|
---|
70 | #endif
|
---|
71 |
|
---|
72 | operator double*() { return elt; }
|
---|
73 | operator const double*() const { return elt; }
|
---|
74 | // operator Vec3&() { return *((Vec3 *)this); }
|
---|
75 |
|
---|
76 | //
|
---|
77 | // Comparison methods
|
---|
78 | //
|
---|
79 | inline bool operator==(const Vec4&) const;
|
---|
80 | inline bool operator!=(const Vec4&) const;
|
---|
81 |
|
---|
82 | //
|
---|
83 | // Assignment and in-place arithmetic methods
|
---|
84 | //
|
---|
85 | inline void set(double x, double y, double z, double w){
|
---|
86 | elt[0]=x; elt[1]=y; elt[2]=z; elt[3]=w;
|
---|
87 | }
|
---|
88 | inline Vec4& operator=(const Vec4& v);
|
---|
89 | inline Vec4& operator+=(const Vec4& v);
|
---|
90 | inline Vec4& operator-=(const Vec4& v);
|
---|
91 | inline Vec4& operator*=(double s);
|
---|
92 | inline Vec4& operator/=(double s);
|
---|
93 |
|
---|
94 | //
|
---|
95 | // Binary arithmetic methods
|
---|
96 | //
|
---|
97 | inline Vec4 operator+(const Vec4& v) const;
|
---|
98 | inline Vec4 operator-(const Vec4& v) const;
|
---|
99 | inline Vec4 operator-() const;
|
---|
100 |
|
---|
101 | inline Vec4 operator*(double s) const;
|
---|
102 | inline Vec4 operator/(double s) const;
|
---|
103 | inline double operator*(const Vec4& v) const;
|
---|
104 | };
|
---|
105 |
|
---|
106 |
|
---|
107 |
|
---|
108 | ////////////////////////////////////////////////////////////////////////
|
---|
109 | //
|
---|
110 | // Method definitions
|
---|
111 | //
|
---|
112 |
|
---|
113 | inline void Vec4::copy(const Vec4& v)
|
---|
114 | {
|
---|
115 | elt[0]=v.elt[0]; elt[1]=v.elt[1]; elt[2]=v.elt[2]; elt[3]=v.elt[3];
|
---|
116 | }
|
---|
117 |
|
---|
118 | inline bool Vec4::operator==(const Vec4& v) const
|
---|
119 | {
|
---|
120 | double dx=elt[X]-v[X], dy=elt[Y]-v[Y], dz=elt[Z]-v[Z], dw=elt[W]-v[W];
|
---|
121 | return (dx*dx + dy*dy + dz*dz + dw*dw) < FEQ_EPS2;
|
---|
122 | }
|
---|
123 |
|
---|
124 | inline bool Vec4::operator!=(const Vec4& v) const
|
---|
125 | {
|
---|
126 | double dx=elt[X]-v[X], dy=elt[Y]-v[Y], dz=elt[Z]-v[Z], dw=elt[W]-v[W];
|
---|
127 | return (dx*dx + dy*dy + dz*dz + dw*dw) > FEQ_EPS2;
|
---|
128 | }
|
---|
129 |
|
---|
130 | inline Vec4& Vec4::operator=(const Vec4& v)
|
---|
131 | {
|
---|
132 | copy(v);
|
---|
133 | return *this;
|
---|
134 | }
|
---|
135 |
|
---|
136 | inline Vec4& Vec4::operator+=(const Vec4& v)
|
---|
137 | {
|
---|
138 | elt[0] += v[0]; elt[1] += v[1]; elt[2] += v[2]; elt[3] += v[3];
|
---|
139 | return *this;
|
---|
140 | }
|
---|
141 |
|
---|
142 | inline Vec4& Vec4::operator-=(const Vec4& v)
|
---|
143 | {
|
---|
144 | elt[0] -= v[0]; elt[1] -= v[1]; elt[2] -= v[2]; elt[3] -= v[3];
|
---|
145 | return *this;
|
---|
146 | }
|
---|
147 |
|
---|
148 | inline Vec4& Vec4::operator*=(double s)
|
---|
149 | {
|
---|
150 | elt[0] *= s; elt[1] *= s; elt[2] *= s; elt[3] *= s;
|
---|
151 | return *this;
|
---|
152 | }
|
---|
153 |
|
---|
154 | inline Vec4& Vec4::operator/=(double s)
|
---|
155 | {
|
---|
156 | elt[0] /= s; elt[1] /= s; elt[2] /= s; elt[3] /= s;
|
---|
157 | return *this;
|
---|
158 | }
|
---|
159 |
|
---|
160 | inline Vec4 Vec4::operator+(const Vec4& v) const
|
---|
161 | {
|
---|
162 | return Vec4(elt[0]+v[0], elt[1]+v[1], elt[2]+v[2], elt[3]+v[3]);
|
---|
163 | }
|
---|
164 |
|
---|
165 | inline Vec4 Vec4::operator-(const Vec4& v) const
|
---|
166 | {
|
---|
167 | return Vec4(elt[0]-v[0], elt[1]-v[1], elt[2]-v[2], elt[3]-v[3]);
|
---|
168 | }
|
---|
169 |
|
---|
170 | inline Vec4 Vec4::operator-() const
|
---|
171 | {
|
---|
172 | return Vec4(-elt[0], -elt[1], -elt[2], -elt[3]);
|
---|
173 | }
|
---|
174 |
|
---|
175 | inline Vec4 Vec4::operator*(double s) const
|
---|
176 | {
|
---|
177 | return Vec4(elt[0]*s, elt[1]*s, elt[2]*s, elt[3]*s);
|
---|
178 | }
|
---|
179 |
|
---|
180 | inline Vec4 Vec4::operator/(double s) const
|
---|
181 | {
|
---|
182 | return Vec4(elt[0]/s, elt[1]/s, elt[2]/s, elt[3]/s);
|
---|
183 | }
|
---|
184 |
|
---|
185 | inline double Vec4::operator*(const Vec4& v) const
|
---|
186 | {
|
---|
187 | return elt[0]*v[0] + elt[1]*v[1] + elt[2]*v[2] + elt[3]*v[3];
|
---|
188 | }
|
---|
189 |
|
---|
190 | #endif
|
---|
191 |
|
---|
192 | // Make scalar multiplication commutative
|
---|
193 | inline Vec4 operator*(double s, const Vec4& v) { return v*s; }
|
---|
194 |
|
---|
195 |
|
---|
196 |
|
---|
197 | ////////////////////////////////////////////////////////////////////////
|
---|
198 | //
|
---|
199 | // Primitive function definitions
|
---|
200 | //
|
---|
201 |
|
---|
202 | //
|
---|
203 | // Code adapted from VecLib4d.c in Graphics Gems V
|
---|
204 | inline Vec4 cross(const Vec4& a, const Vec4& b, const Vec4& c)
|
---|
205 | {
|
---|
206 | Vec4 result;
|
---|
207 |
|
---|
208 | double d1 = (b[Z] * c[W]) - (b[W] * c[Z]);
|
---|
209 | double d2 = (b[Y] * c[W]) - (b[W] * c[Y]);
|
---|
210 | double d3 = (b[Y] * c[Z]) - (b[Z] * c[Y]);
|
---|
211 | double d4 = (b[X] * c[W]) - (b[W] * c[X]);
|
---|
212 | double d5 = (b[X] * c[Z]) - (b[Z] * c[X]);
|
---|
213 | double d6 = (b[X] * c[Y]) - (b[Y] * c[X]);
|
---|
214 |
|
---|
215 | result[X] = - a[Y] * d1 + a[Z] * d2 - a[W] * d3;
|
---|
216 | result[Y] = a[X] * d1 - a[Z] * d4 + a[W] * d5;
|
---|
217 | result[Z] = - a[X] * d2 + a[Y] * d4 - a[W] * d6;
|
---|
218 | result[W] = a[X] * d3 - a[Y] * d5 + a[Z] * d6;
|
---|
219 |
|
---|
220 | return result;
|
---|
221 | }
|
---|
222 |
|
---|
223 | inline double norm(const Vec4& v)
|
---|
224 | {
|
---|
225 | return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3]);
|
---|
226 | }
|
---|
227 |
|
---|
228 | inline double norm2(const Vec4& v)
|
---|
229 | {
|
---|
230 | return v[0]*v[0] + v[1]*v[1] + v[2]*v[2] + v[3]*v[3];
|
---|
231 | }
|
---|
232 |
|
---|
233 | inline double unitize(Vec4& v)
|
---|
234 | {
|
---|
235 | double l=norm2(v);
|
---|
236 | if( l!=1.0 && l!=0.0 )
|
---|
237 | {
|
---|
238 | l = sqrt(l);
|
---|
239 | v /= l;
|
---|
240 | }
|
---|
241 | return l;
|
---|
242 | }
|
---|
243 |
|
---|
244 | inline Vec3 proj(const Vec4& v)
|
---|
245 | {
|
---|
246 | Vec3 u(v[0], v[1], v[2]);
|
---|
247 | if( v[3]!=1.0 && v[3]!=0.0 )
|
---|
248 | u /= v[3];
|
---|
249 | return u;
|
---|
250 | }
|
---|
251 |
|
---|
252 |
|
---|
253 |
|
---|
254 | ////////////////////////////////////////////////////////////////////////
|
---|
255 | //
|
---|
256 | // Misc. function definitions
|
---|
257 | //
|
---|
258 |
|
---|
259 | inline ostream& operator<<(ostream& out, const Vec4& v)
|
---|
260 | {
|
---|
261 | return
|
---|
262 | out << v[0] << " " << v[1] << " " << v[2] << " " << v[3];
|
---|
263 | }
|
---|
264 |
|
---|
265 | inline istream& operator>>(istream& in, Vec4& v)
|
---|
266 | {
|
---|
267 | return in >> v[0] >> v[1] >> v[2] >> v[3];
|
---|
268 | }
|
---|
269 |
|
---|
270 | #ifdef MXGL_INCLUDED
|
---|
271 | inline void glV(const Vec4& v) { glVertex4d(v[X], v[Y], v[Z], v[W]); }
|
---|
272 | inline void glC(const Vec4& v) { glColor4d(v[X], v[Y], v[Z], v[W]); }
|
---|
273 | #endif
|
---|
274 |
|
---|
275 | // MXVEC4_INCLUDED
|
---|
276 | #endif
|
---|