FaceGen 3 SDKs Reference
Loading...
Searching...
No Matches
vect3.hpp
1//
2// Copyright (c) Singular Inversions Inc. 1998.
3//
4
5#ifndef FR2_VECT3_HPP
6#define FR2_VECT3_HPP
7
8#include "FgSerial.hpp"
9
10namespace Fg {
11
12template<class T> class FR2Vect3TC
13{
14public:
15 T x1,x2,x3;
16
17 // Constructors.
18 FR2Vect3TC() : x1(0), x2(0), x3(0) {}; // default
19 FR2Vect3TC(T a) : x1(a), x2(a), x3(a) {}; // init single val.
20 FR2Vect3TC(T y1,T y2,T y3) : x1(y1), x2(y2), x3(y3) {}; // init each val.
21 template<class U>
22 explicit FR2Vect3TC(const U &y) : x1(T(y.x1)), x2(T(y.x2)), x3(T(y.x3)) {}
23
24 T& operator[](uint n)
25 {FGASSERT_FAST(n < 3);return (&x1)[n];}
26 T const& operator[](uint n) const
27 {FGASSERT_FAST(n < 3);return (&x1)[n];}
28
29 void set(T a) {x1 = a;x2 = a;x3 = a;}
30 const FR2Vect3TC operator-() const; // unary operator
31 void operator-=(FR2Vect3TC);
32 void operator+=(FR2Vect3TC);
33 const FR2Vect3TC operator+(const FR2Vect3TC&) const;
34 const FR2Vect3TC operator-(const FR2Vect3TC&) const;
35 const FR2Vect3TC operator*(T) const;
36 const FR2Vect3TC operator/(T) const;
37 void operator*=(T);
38 void operator/=(T);
39 bool operator==(const FR2Vect3TC &v) const
40 {return (x1==v.x1 && x2==v.x2 && x3==v.x3);}
41 bool operator!=(const FR2Vect3TC &v) const
42 {return (x1!=v.x1 || x2!=v.x2 || x3!=v.x3);}
43 T const len() const {return (T)(sqrt(x1*x1+x2*x2+x3*x3));}
44 T const mag() const {return(x1*x1+x2*x2+x3*x3);}
45 const FR2Vect3TC rotateX(T) const;
46 const FR2Vect3TC rotateY(T) const;
47 const FR2Vect3TC rotateZ(T) const;
48 const FR2Vect3TC rotateK(FR2Vect3TC,T) const;
49 const FR2Vect3TC cross(FR2Vect3TC) const;
50 T const dot(FR2Vect3TC vec) const {return(x1*vec.x1+x2*vec.x2+x3*vec.x3);}
51};
52
53// **********************************************************************
54// **********************************************************************
55
61
62template <class T>
64{
65 bool operator()(const FR2Vect3TC<T> &x, const FR2Vect3TC<T> &y) const
66 { return ((x.x3 < y.x3) ||
67 (x.x3 == y.x3 && x.x2 < y.x2) ||
68 (x.x3 == y.x3 && x.x2 == y.x2 && x.x1 < y.x1)); }
69};
70
71
72// Definitions are the in the 'cpp' file since they are written separately
73// for each template type.
74template<class T> std::ostream& operator<<(std::ostream&,FR2Vect3TC<T>);
75
76template<class T>
77std::istream& operator>>(std::istream& s,FR2Vect3TC<T> &v)
78{
79 s >> v.x1;
80 s >> v.x2;
81 s >> v.x3;
82 return s;
83}
84
85template<class T>
86const inline FR2Vect3TC<T> FR2Vect3TC<T>::operator-() const
87{
88 return FR2Vect3TC<T>(-x1,-x2,-x3);
89}
90
91template<class T>
92const inline FR2Vect3TC<T> FR2Vect3TC<T>::operator+(
93 const FR2Vect3TC<T> &v1)
94 const
95{
96 return FR2Vect3TC<T>(x1 + v1.x1,
97 x2 + v1.x2,
98 x3 + v1.x3);
99}
100
101template<class T>
102const inline FR2Vect3TC<T> FR2Vect3TC<T>::operator-(
103 const FR2Vect3TC<T> &v1)
104 const
105{
106 return FR2Vect3TC<T>(x1 - v1.x1,
107 x2 - v1.x2,
108 x3 - v1.x3);
109}
110
111template<class T>
112inline void FR2Vect3TC<T>::operator-=(
113 FR2Vect3TC<T> v)
114{
115 x1 -= v.x1;
116 x2 -= v.x2;
117 x3 -= v.x3;
118}
119
120template<class T>
121inline void FR2Vect3TC<T>::operator+=(
122 FR2Vect3TC<T> v)
123{
124 x1 += v.x1;
125 x2 += v.x2;
126 x3 += v.x3;
127}
128
129template<class T>
130const inline FR2Vect3TC<T> FR2Vect3TC<T>::operator*(
131 T val)
132 const
133{
134 return FR2Vect3TC<T>(x1*val, x2*val, x3*val);
135}
136
137template<class T>
138const inline FR2Vect3TC<T> FR2Vect3TC<T>::operator/(
139 T val) // Good form to create inverse operator, even if not used.
140 const
141{
142 FGASSERT_FAST(val != T(0));
143
144 return FR2Vect3TC<T>(x1/val, x2/val, x3/val);
145}
146
147template<class T>
148inline void FR2Vect3TC<T>::operator*=(
149 T val)
150{
151 x1 *= val;
152 x2 *= val;
153 x3 *= val;
154}
155
156template<class T>
157inline void FR2Vect3TC<T>::operator/=(
158 T val)
159{
160 FGASSERT_FAST(val != T(0));
161
162 x1 /= val;
163 x2 /= val;
164 x3 /= val;
165}
166
167//***********************************************************************
168// Rotations
169//***********************************************************************
170// All rotations act according to the right hand rule around the axis
171// about which they are named. Angles are given in radians.
172
173template<class T>
174const inline FR2Vect3TC<T> FR2Vect3TC<T>::rotateX(
175
176 T theta)
177 const
178{
179 T cosine = (T)cos(theta), // Casting is safe here to float since
180 sine = (T)sin(theta); // range of sin/cos is [-1,1].
181
182 return FR2Vect3TC<T>(x1,
183 x2 * cosine - x3 * sine,
184 x3 * cosine + x2 * sine);
185}
186
187template<class T>
188const inline FR2Vect3TC<T> FR2Vect3TC<T>::rotateY(
189
190 T theta)
191 const
192{
193 T cosine = (T)cos(theta),
194 sine = (T)sin(theta);
195
196 return FR2Vect3TC<T>(x1 * cosine + x3 * sine,
197 x2,
198 x3 * cosine - x1 * sine);
199}
200
201template<class T>
202const inline FR2Vect3TC<T> FR2Vect3TC<T>::rotateZ(
203
204 T theta)
205 const
206{
207 T cosine = (T)cos(theta),
208 sine = (T)sin(theta);
209
210 return FR2Vect3TC<T>(x1 * cosine - x2 * sine,
211 x2 * cosine + x1 * sine,
212 x3);
213}
214
215template<class T>
216const FR2Vect3TC<T> FR2Vect3TC<T>::rotateK(
217 FR2Vect3TC<T> K, // arbitrary axis of rotation
218 T theta) // angle of rotation
219 const
220{
221 T cosine=cos(theta),
222 sine=sin(theta);
223 T vtheta = 1.0-cosine;
224 FR2Vect3TC<T> retval, k;
225
226 // Make sure that the given vector is a unit vector
227 T ln = K.len();
228 FGASSERT_FAST(ln != T(0));
229 k = K / ln;
230
231 retval.x1 =
232 (k.x1*k.x1*vtheta+cosine) * x1 +
233 (k.x1*k.x2*vtheta-k.x3*sine) * x2 +
234 (k.x1*k.x3*vtheta+k.x2*sine) * x3;
235 retval.x2 =
236 (k.x1*k.x2*vtheta+k.x3*sine) * x1 +
237 (k.x2*k.x2*vtheta+cosine) * x2 +
238 (k.x2*k.x3*vtheta-k.x1*sine) * x3;
239 retval.x3 =
240 (k.x1*k.x3*vtheta-k.x2*sine) * x1 +
241 (k.x2*k.x3*vtheta+k.x1*sine) * x2 +
242 (k.x3*k.x3*vtheta+cosine) * x3;
243
244 return(retval);
245}
246
247template<class T>
248const inline FR2Vect3TC<T> FR2Vect3TC<T>::cross(
249
250 FR2Vect3TC<T> vec)
251 const
252{
253 return FR2Vect3TC<T>(x2 * vec.x3 - x3 * vec.x2,
254 x3 * vec.x1 - x1 * vec.x3,
255 x1 * vec.x2 - x2 * vec.x1);
256}
257
258
259// Given a list of vector sorted by z coord, then y cood, then x coord,
260// returns the index position of where the new vector should be inserted.
261// If there are exact matches between the new vector and elements in the
262// list, the function will return the index position of one of the exact
263// matches. This function uses binary search to find the insertion position.
264//
265// NOTE: The algorithm for this function is exactly the same as the one in
266// algs.hpp's fr2FindSortedListInsertPos. If there are any efficiency
267// issues, I should change fr2FindSortedListInsertPos to accept a predicate
268// as template argument and then define a special predicate for vector3 class.
269//
270template <class T>
271int fr2FindSortedVect3InsertPos(
272 const std::vector< FR2Vect3TC<T> > &list, const FR2Vect3TC<T> &pt)
273{
274 int numPts = list.size();
275 if (numPts == 0) return 0;
276
277 int lo = 0;
278 int hi = numPts-1;
279
280 if ((list[0].x3 > pt.x3) ||
281 (list[0].x3 == pt.x3 && list[0].x2 > pt.x2) ||
282 (list[0].x3 == pt.x3 && list[0].x2 == pt.x2 && list[0].x1 >= pt.x1))
283 return 0;
284
285 if ((list[hi].x3 < pt.x3) ||
286 (list[hi].x3 == pt.x3 && list[hi].x2 < pt.x2) ||
287 (list[hi].x3 == pt.x3 && list[hi].x2 == pt.x2 && list[hi].x1 < pt.x1))
288 return numPts;
289
290 int idx = (hi+lo+1)/2;
291
292 while (idx != hi)
293 {
294 if ((list[idx].x3 > pt.x3) ||
295 (list[idx].x3 == pt.x3 && list[idx].x2 > pt.x2) ||
296 (list[idx].x3 == pt.x3 && list[idx].x2 == pt.x2 &&
297 list[idx].x1 > pt.x1))
298 hi = idx;
299 else if ((list[idx].x3 < pt.x3) ||
300 (list[idx].x3 == pt.x3 && list[idx].x2 < pt.x2) ||
301 (list[idx].x3 == pt.x3 && list[idx].x2 == pt.x2 &&
302 list[idx].x1 < pt.x1))
303 lo = idx;
304 else // all three coordinates are equal
305 hi = lo = idx;
306
307 idx = (hi+lo+1)/2;
308 }
309
310 return idx;
311}
312
313}
314
315#endif