Free Electron
Vector4.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __math_Vector4_h__
8 #define __math_Vector4_h__
9 
10 namespace fe
11 {
12 
13 typedef Vector<4,F64> Vector4d;
14 typedef Vector<4,F32> Vector4f;
15 typedef Vector<4,FE_UWORD> Vector4u;
16 typedef Vector<4,int> Vector4i;
17 typedef Vector<4,Real> Vector4;
18 
19 /// @brief Partially specialized 4-component vector intended for spatial use
20 template<typename T>
21 class Vector<4,T>
22 {
23  public:
24 
25  class Raw
26  {
27  public:
28  Raw(const Vector<4,T>& vector)
29  { m_array[0]=vector[0];
30  m_array[1]=vector[1];
31  m_array[2]=vector[2];
32  m_array[3]=vector[3]; }
33 
34  operator const T*(void) const
35  { return m_array; }
36 
37  private:
38  T m_array[4];
39  };
40 
41  Vector(void)
42  {
43 // m_data[3] = T(0); /* make 3D assumption valid */
44  }
45  Vector(const Vector<4,T>& other)
46  { operator=(other); }
47  template<typename U>
48  Vector(const Vector<4,U>& other)
49  { operator=(other); }
50  Vector(const Vector<3,T>& other)
51  { operator=(other); }
52  template<typename U>
53  Vector(const Vector<3,U>& other)
54  { operator=(other); }
55  Vector(const Vector<2,T>& other)
56  { operator=(other); }
57  template<typename U>
58  Vector(const Vector<2,U>& other)
59  { operator=(other); }
60  Vector(const T* array)
61  { operator=(array); }
62  Vector(T x,T y,T z=T(0),T w=T(0))
63  { set4(x,y,z,w); }
64 
65  Vector<4,T>& operator=(const Vector<4,T>& other)
66 #if FE_EXPLOIT_MEMCPY
67  { memcpy(m_data,other.m_data,4*sizeof(T));
68  return *this; }
69 #else
70  { return set4(other[0],other[1],other[2],other[3]); }
71 #endif
72  template<typename U>
73  Vector<4,T>& operator=(const Vector<4,U>& other)
74  { return set4((T)other[0],(T)other[1],(T)other[2],
75  (T)other[3]); }
76 
77  Vector<4,T>& operator=(const Vector<3,T>& other)
78 #if FE_EXPLOIT_MEMCPY
79  { memcpy(m_data,other.m_data,3*sizeof(T));
80  m_data[3]=T(0);
81  return *this; }
82 #else
83  { return set4(other[0],other[1],other[2],T(0)); }
84 #endif
85  template<typename U>
86  Vector<4,T>& operator=(const Vector<3,U>& other)
87  { return set4((T)other[0],(T)other[1],
88  (T)other[2],T(0)); }
89 
90  Vector<4,T>& operator=(const Vector<2,T>& other)
91 #if FE_EXPLOIT_MEMCPY
92  { memcpy(m_data,other.m_data,2*sizeof(T));
93  m_data[2]=T(0);
94  m_data[3]=T(0);
95  return *this; }
96 #else
97  { return set4(other[0],other[1],T(0),T(0)); }
98 #endif
99  template<typename U>
100  Vector<4,T>& operator=(const Vector<2,U>& other)
101  { return set4((T)other[0],(T)other[1],
102  (T)other[2],T(0)); }
103 
104  Vector<4,T>& operator=(const T* array)
105 #if FE_EXPLOIT_MEMCPY
106  { memcpy(m_data,array,4*sizeof(T));
107  return *this; }
108 #else
109  { return set4(array[0],array[1],array[2],array[3]); }
110 #endif
111 
112 
113 const T& operator[](U32 index) const;
114  T& operator[](U32 index);
115 
116  Vector<4,T>& set4(T x=T(0),T y=T(0),T z=T(0),T w=T(0));
117 
118  void get4(T array[4]);
119 
120 const Raw temp(void) const
121  { return *this; }
122 
123  protected:
124  T m_data[4];
125 };
126 
127 template<class T>
128 inline const T& Vector<4,T>::operator[](U32 index) const
129 {
130  return m_data[index];
131 }
132 
133 /** @brief Access internal component
134 
135  Warning, this provides internal access and should
136  be limited to immediate use only. */
137 template<class T>
138 inline T &Vector<4,T>::operator[](U32 index)
139 {
140  return m_data[index];
141 }
142 
143 template<typename T>
144 inline Vector<4,T>& Vector<4,T>::set4(T x,T y,T z,T w)
145 {
146  m_data[0]=x;
147  m_data[1]=y;
148  m_data[2]=z;
149  m_data[3]=w;
150  return *this;
151 }
152 
153 template<typename T>
154 inline void Vector<4,T>::get4(T array[4])
155 {
156  array[0]=m_data[0];
157  array[1]=m_data[1];
158  array[2]=m_data[2];
159  array[3]=m_data[3];
160 }
161 
162 /** Set components
163  @relates Vector<4,T>
164  */
165 template<typename T>
166 inline Vector<4,T> &set(Vector<4,T> &r)
167 {
168  r.set4(T(0),T(0),T(0),T(0));
169  return r;
170 }
171 
172 /** Set components
173  @relates Vector<4,T>
174  */
175 template<typename T,typename U>
176 inline Vector<4,T> &set(Vector<4,T> &r,U x)
177 {
178  r.set4(x,T(0),T(0),T(0));
179  return r;
180 }
181 
182 /** Set components
183  @relates Vector<4,T>
184  */
185 template<typename T,typename U,typename V>
186 inline Vector<4,T> &set(Vector<4,T> &r,U x,V y)
187 {
188  r.set4(x,y,T(0),T(0));
189  return r;
190 }
191 
192 /** Set components
193  @relates Vector<4,T>
194  */
195 template<typename T,typename U,typename V,typename W>
196 inline Vector<4,T> &set(Vector<4,T> &r,U x,V y,W z)
197 {
198  r.set4(x,y,z,T(0));
199  return r;
200 }
201 
202 /** Set components
203  @relates Vector<4,T>
204  */
205 template<typename T,typename U,typename V,typename W,typename X>
206 inline Vector<4,T> &set(Vector<4,T> &r,U x,V y,W z,X w)
207 {
208  r.set4(x,y,z,w);
209  return r;
210 }
211 
212 /** Set indexed component
213  @relates Vector<4,T>
214  */
215 template<typename T,typename U>
216 inline Vector<4,T> &setAt(Vector<4,T> &lhs,U32 index,U value)
217 {
218  lhs[index]=value;
219  return lhs;
220 
221 // T array[4];
222 // lhs.get4(array);
223 // array[index]=value;
224 // return lhs=array;
225 }
226 
227 /** Return the number of elements
228  @relates Vector<4,T>
229  */
230 template<typename T>
231 inline U32 size(const Vector<4,T> &lhs)
232 {
233  return 4;
234 }
235 
236 /** Add to Vector in place
237  @relates Vector<4,T>
238  */
239 template<typename T>
241 {
242  return set(lhs,lhs[0]+rhs[0],lhs[1]+rhs[1],lhs[2]+rhs[2],lhs[3]+rhs[3]);
243 }
244 
245 /** Subtract from Vector in place
246  @relates Vector<4,T>
247  */
248 template<typename T>
250 {
251  return set(lhs,lhs[0]-rhs[0],lhs[1]-rhs[1],lhs[2]-rhs[2],lhs[3]-rhs[3]);
252 }
253 
254 /** Negate the Vector
255  @relates Vector<4,T>
256  */
257 template<typename T>
259 {
260  Vector<4,T> v;
261  return set(v,-rhs[0],-rhs[1],-rhs[2],-rhs[3]);
262 }
263 
264 /** Independently scale components in place
265  @relates Vector<4,T>
266  */
267 template<typename T>
269 {
270  return set(lhs,lhs[0]*rhs[0],lhs[1]*rhs[1],lhs[2]*rhs[2],lhs[3]*rhs[3]);
271 }
272 
273 /** Uniformly scale components in place
274  @relates Vector<4,T>
275  */
276 template<typename T,typename U>
277 inline Vector<4,T> &operator*=(Vector<4,T> &lhs,U scale)
278 {
279  return set(lhs,lhs[0]*scale,lhs[1]*scale,lhs[2]*scale,lhs[3]*scale);
280 }
281 
282 /** Return dot product
283  @relates Vector<4,T>
284  */
285 template<typename T>
286 inline T dot(const Vector<4,T> &lhs,const Vector<4,T> &rhs)
287 {
288  return lhs[0]*rhs[0]+lhs[1]*rhs[1]+lhs[2]*rhs[2]+lhs[3]*rhs[3];
289 }
290 
291 /** Return square of the Vector length
292  @relates Vector<4,T>
293  */
294 template<typename T>
295 inline T magnitudeSquared(const Vector<4,T> &rhs)
296 {
297  return rhs[0]*rhs[0]+rhs[1]*rhs[1]+rhs[2]*rhs[2]+rhs[3]*rhs[3];
298 }
299 
300 /** Return the Vector length
301  @relates Vector<4,T>
302  */
303 template<typename T>
304 inline T magnitude(const Vector<4,T> &rhs)
305 {
306  return sqrt(magnitudeSquared(rhs));
307 }
308 
309 /** Return the Vector direction scaled to unit length
310  @relates Vector<4,T>
311  */
312 template<typename T>
313 inline Vector<4,T> unit(const Vector<4,T> &vector)
314 {
315  T mag=magnitude(vector);
316  if(mag==T(0))
317  {
318  feX("unit(Vector<4,T>)","attempt to normalize zero magnitude vector");
319  }
320  return vector*T(1.0/mag);
321 }
322 
323 /** Return the Vector direction scaled to unit length with zero check
324  @relates Vector<4,T>
325  */
326 template<typename T>
327 inline Vector<4,T> unitSafe(const Vector<4,T> &vector)
328 {
329  T mag=magnitude(vector);
330  if(mag>T(0))
331  {
332  return vector*(T(1)/mag);
333  }
334  return vector;
335 }
336 
337 /** Scale Vector to unit length
338  @relates Vector<4,T>
339  */
340 template<typename T>
342 {
343  T mag=magnitude(vector);
344  if(mag==T(0))
345  feX("normal","attempt to normalize zero magnitude vector");
346  return vector*=T(1.0/mag);
347 }
348 
349 /** Scale Vector to unit length with zero check
350  @relates Vector<4,T>
351  */
352 template<typename T>
354 {
355  T mag=magnitude(vector);
356  if(mag>T(0))
357  {
358  vector*=T(1.0/mag);
359  }
360  return vector;
361 }
362 
363 /** Return text describing the Vector's state
364  @relates Vector<4,T>
365  */
366 template<typename T>
367 inline String print(const Vector<4,T> &vector)
368 {
369  String s;
370  s.sPrintf("%g %g %g %g",vector[0],vector[1],vector[2],vector[3]);
371  return s;
372 }
373 
374 /** Return sum of Vectors
375  @relates Vector<4,T>
376  */
377 template<typename T>
378 inline Vector<4,T> operator+(const Vector<4,T> &lhs,const Vector<4,T> &rhs)
379 {
380  Vector<4,T> v;
381  return set(v,lhs[0]+rhs[0],lhs[1]+rhs[1],lhs[2]+rhs[2],lhs[3]+rhs[3]);
382 }
383 
384 /** Return difference of Vectors
385  @relates Vector<4,T>
386  */
387 template<typename T>
388 inline Vector<4,T> operator-(const Vector<4,T> &lhs,const Vector<4,T> &rhs)
389 {
390  Vector<4,T> v;
391  return set(v,lhs[0]-rhs[0],lhs[1]-rhs[1],lhs[2]-rhs[2],lhs[3]-rhs[3]);
392 }
393 
394 /** Return a Vector of products of each component
395  @relates Vector<4,T>
396  */
397 template<typename T>
398 inline Vector<4,T> operator*(const Vector<4,T> &lhs,const Vector<4,T> &rhs)
399 {
400  Vector<4,T> v;
401  return set(v,lhs[0]*rhs[0],lhs[1]*rhs[1],lhs[2]*rhs[2],lhs[3]*rhs[3]);
402 }
403 
404 /** Return a uniformly scale Vector (pre)
405  @relates Vector<4,T>
406  */
407 template<typename T,typename U>
408 inline
409 typename boost::enable_if<boost::is_arithmetic<U>,Vector<4,T> >::type
410 operator*(const U lhs, const Vector<4,T> &rhs)
411 {
412  Vector<4,T> v;
413  return set(v,lhs*rhs[0],lhs*rhs[1],lhs*rhs[2],lhs*rhs[3]);
414 }
415 
416 /** Return a uniformly scale Vector (post)
417  @relates Vector<4,T>
418  */
419 template<typename T,typename U>
420 inline
421 typename boost::enable_if<boost::is_arithmetic<U>,Vector<4,T> >::type
422 operator*(const Vector<4,T> &lhs, const U rhs)
423 {
424  Vector<4,T> v;
425  return set(v,lhs[0]*rhs,lhs[1]*rhs,lhs[2]*rhs,lhs[3]*rhs);
426 }
427 
428 /** Return a cross product of Vectors
429  @relates Vector<4,T>
430  */
431 template<typename T>
432 inline Vector<4,T> &cross3(Vector<4,T> &r, const Vector<4,T> &lhs,
433  const Vector<4,T> &rhs)
434 {
435  set(r, lhs[1] * rhs[2] - lhs[2] * rhs[1],
436  lhs[2] * rhs[0] - lhs[0] * rhs[2],
437  lhs[0] * rhs[1] - lhs[1] * rhs[0]);
438  return r;
439 }
440 
441 /** Set the Vector as a cross product of Vectors
442  @relates Vector<4,T>
443  */
444 template<typename T>
445 inline Vector<4,T> cross3(const Vector<4,T> &lhs, const Vector<4,T> &rhs)
446 {
447  Vector<4,T> v;
448  return cross3(v, lhs, rhs);
449 }
450 
451 } /* namespace */
452 
453 #endif /* __math_Vector4_h__ */
454 
String print(const Vector< 4, T > &vector)
Return text describing the Vector&#39;s state.
Definition: Vector4.h:367
Vector< 4, T > unitSafe(const Vector< 4, T > &vector)
Return the Vector direction scaled to unit length with zero check.
Definition: Vector4.h:327
Vector< 4, T > operator*(const Vector< 4, T > &lhs, const Vector< 4, T > &rhs)
Return a Vector of products of each component.
Definition: Vector4.h:398
Vector< 4, T > & normalize(Vector< 4, T > &vector)
Scale Vector to unit length.
Definition: Vector4.h:341
Vector< 4, T > operator+(const Vector< 4, T > &lhs, const Vector< 4, T > &rhs)
Return sum of Vectors.
Definition: Vector4.h:378
T dot(const Vector< 4, T > &lhs, const Vector< 4, T > &rhs)
Return dot product.
Definition: Vector4.h:286
kernel
Definition: namespace.dox:3
Vector< 4, T > & operator-=(Vector< 4, T > &lhs, const Vector< 4, T > &rhs)
Subtract from Vector in place.
Definition: Vector4.h:249
Vector< 4, T > & operator*=(Vector< 4, T > &lhs, const Vector< 4, T > &rhs)
Independently scale components in place.
Definition: Vector4.h:268
Dense vector - size fixed by template.
Definition: Vector.h:19
boost::enable_if< boost::is_arithmetic< U >, Vector< 4, T > >::type operator*(const U lhs, const Vector< 4, T > &rhs)
Return a uniformly scale Vector (pre)
Definition: Vector4.h:410
T magnitude(const Vector< 4, T > &rhs)
Return the Vector length.
Definition: Vector4.h:304
Vector< 4, T > & setAt(Vector< 4, T > &lhs, U32 index, U value)
Set indexed component.
Definition: Vector4.h:216
Vector< 4, T > operator-(const Vector< 4, T > &rhs)
Negate the Vector.
Definition: Vector4.h:258
String & sPrintf(const char *fmt,...)
Populate the string in the manner of sprintf().
Definition: String.cc:529
T magnitudeSquared(const Vector< 4, T > &rhs)
Return square of the Vector length.
Definition: Vector4.h:295
Automatically reference-counted string container.
Definition: String.h:128
Vector< 4, T > & cross3(Vector< 4, T > &r, const Vector< 4, T > &lhs, const Vector< 4, T > &rhs)
Return a cross product of Vectors.
Definition: Vector4.h:432
boost::enable_if< boost::is_arithmetic< U >, Vector< 4, T > >::type operator*(const Vector< 4, T > &lhs, const U rhs)
Return a uniformly scale Vector (post)
Definition: Vector4.h:422
Vector< 4, T > unit(const Vector< 4, T > &vector)
Return the Vector direction scaled to unit length.
Definition: Vector4.h:313
Vector< 4, T > operator-(const Vector< 4, T > &lhs, const Vector< 4, T > &rhs)
Return difference of Vectors.
Definition: Vector4.h:388
Vector< 4, T > & normalizeSafe(Vector< 4, T > &vector)
Scale Vector to unit length with zero check.
Definition: Vector4.h:353
T magnitude(const Vector< N, T > &rhs)
Frobenius norm operation.
Definition: Vector.h:785
T magnitudeSquared(const Vector< N, T > &rhs)
Square of the length.
Definition: Vector.h:794
Vector< 4, T > cross3(const Vector< 4, T > &lhs, const Vector< 4, T > &rhs)
Set the Vector as a cross product of Vectors.
Definition: Vector4.h:445
U32 size(const Vector< 4, T > &lhs)
Return the number of elements.
Definition: Vector4.h:231
Partially specialized 4-component vector intended for spatial use.
Definition: Vector4.h:21
Vector< 4, T > & operator*=(Vector< 4, T > &lhs, U scale)
Uniformly scale components in place.
Definition: Vector4.h:277
Vector< 4, T > & operator+=(Vector< 4, T > &lhs, const Vector< 4, T > &rhs)
Add to Vector in place.
Definition: Vector4.h:240