1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * Tecorrec is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * Tecorrec is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with Tecorrec. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
22 * @brief Vector of values, designed for spacial coordinate vectors.
23 * @author James Hogan <james@albanarts.com>
24 * @note Copyright (C) 2007
26 * @version 1 : From Computer Graphics and Visualisation Open Assessment.
29 #ifndef _maths_Vector_h
30 #define _maths_Vector_h
32 #include "TemplateMaths.h"
42 * @param N int Number of components in the vector.
43 * @param T typename Type of the components of the vector.
45 template <int N
, typename T
>
56 /// Default constructor (Does not initialise the values!)
61 inline explicit Vector(T value
)
63 for (int i
= 0; i
< N
; ++i
)
68 inline Vector(T x
, T y
)
74 for (int i
= 2; i
< N
; ++i
)
76 v
[i
] = maths::zero
<T
>();
80 inline Vector(T x
, T y
, T z
)
89 for (int i
= 3; i
< N
; ++i
)
91 v
[i
] = maths::zero
<T
>();
96 inline Vector(T x
, T y
, T z
, T w
)
108 for (int i
= 4; i
< N
; ++i
)
110 v
[i
] = maths::zero
<T
>();
116 inline explicit Vector(const T
* vec
)
118 for (int i
= 0; i
< N
; ++i
)
123 template <int M
, typename U
> inline explicit Vector(const Vector
<M
,U
> & copy
)
126 for (; i
< N
&& i
< M
; ++i
)
132 v
[i
] = maths::zero
<T
>();
136 inline const Vector
& set()
138 for (int i
= 0; i
< N
; ++i
)
140 v
[i
] = maths::zero
<T
>();
144 inline const Vector
& set(T all
)
146 for (int i
= 0; i
< N
; ++i
)
152 inline const Vector
& set(T x
, T y
)
158 for (int i
= 2; i
< N
; ++i
)
160 v
[i
] = maths::zero
<T
>();
165 inline const Vector
& set(T x
, T y
, T z
)
174 for (int i
= 3; i
< N
; ++i
)
176 v
[i
] = maths::zero
<T
>();
182 inline const Vector
& set(T x
, T y
, T z
, T w
)
194 for (int i
= 4; i
< N
; ++i
)
196 v
[i
] = maths::zero
<T
>();
203 inline const Vector
& set(const Vector
<3,T
> xyz
, T w
)
215 for (int i
= 4; i
< N
; ++i
)
217 v
[i
] = maths::zero
<T
>();
225 /// Setter for specific component.
227 inline void setComponent(const T newValue
)
232 /// Getter for specific component.
234 inline T
getComponent() const
239 /// Concatination operator, append a number.
240 inline Vector
<N
+1, T
> operator , (T f
) const
242 Vector
<N
+1,T
> result
;
243 for (int i
= 0; i
< N
; ++i
)
251 /// Concatination operator, prepend a number.
252 inline friend Vector
<N
+1, T
> operator , (T f
, const Vector
& vector
)
254 Vector
<N
+1,T
> result
;
256 for (int i
= 0; i
< N
; ++i
)
258 result
[i
+1] = vector
[i
];
263 /// Concatination operator, append a vector.
265 inline Vector
<N
+M
, T
> operator , (const Vector
<M
,T
> & vector
) const
267 Vector
<N
+M
,T
> result
;
268 for (int i
= 0; i
< N
; ++i
)
272 for (int i
= 0; i
< M
; ++i
)
274 result
[N
+i
] = vector
[i
];
279 /// Slice out of the vector a reference.
280 template <int S
, int L
>
281 inline Vector
<L
, T
> & slice()
283 return *(Vector
<L
,T
>*)(v
+S
);
286 /// Slice out of the vector a reference.
287 template <int S
, int L
>
288 inline const Vector
<L
, T
> & slice() const
290 return *(Vector
<L
,T
>*)(v
+S
);
293 inline T
& operator [] (int index
)
297 inline const T
& operator [] (int index
) const
302 inline operator T
* ()
306 inline operator const T
* () const
311 inline Vector
operator - () const
314 for (int i
= 0; i
< N
; ++i
)
321 template <typename U
>
322 inline Vector
& operator += (const Vector
<N
,U
> & rhs
)
324 for (int i
= 0; i
< N
; ++i
)
330 template <typename U
>
331 inline Vector
operator + (const Vector
<N
,U
> & rhs
) const
337 inline Vector
& operator -= (const Vector
& rhs
)
339 for (int i
= 0; i
< N
; ++i
)
345 inline Vector
operator - (const Vector
& rhs
) const
351 inline Vector
& operator *= (const T rhs
)
353 for (int i
= 0; i
< N
; ++i
)
359 inline Vector
operator * (const T rhs
) const
364 inline friend Vector
operator * (const T lhs
, const Vector
& rhs
)
370 inline T
operator * (const Vector
& rhs
) const
372 T fDot
= maths::zero
<T
>();
373 for (int i
= 0; i
< N
; ++i
)
375 fDot
+= v
[i
]*rhs
.v
[i
];
381 inline T
operator / (const Vector
& rhs
) const
383 // a = B/C = (B*C)/(C*C)
384 return operator * (rhs
) / rhs
.sqr();
387 inline Vector
& operator /= (const T rhs
)
389 for (int i
= 0; i
< N
; ++i
)
395 inline Vector
operator / (const T rhs
) const
400 inline friend Vector
operator / (const T lhs
, const Vector
& rhs
)
402 return rhs
* (lhs
/ rhs
.sqr());
409 template <typename U
>
410 inline U
tsqr() const
412 U ret
= maths::zero
<U
>();
413 for (int i
= 0; i
< N
; ++i
)
415 ret
+= maths::sqr
<U
>(v
[i
]);
420 inline Vector
inv() const
422 return *this / sqr();
429 template <typename U
>
430 inline U
tmag() const
432 return maths::sqrt
<U
>(tsqr
<U
>());
436 inline Vector
& normalize()
438 return operator /= (mag());
440 inline Vector
normalized() const
442 return operator / (mag());
444 inline Vector
& resize(T tLength
)
446 return operator *= (tLength
/ mag());
448 inline Vector
resized(T tLength
) const
450 return operator * (tLength
/ mag());
457 inline bool operator == (const Vector
& rhs
) const
459 for (int i
= 0; i
< N
; ++i
)
461 if (v
[i
] != rhs
.v
[i
])
469 inline bool operator != (const Vector
& rhs
) const
471 for (int i
= 0; i
< N
; ++i
)
473 if (v
[i
] != rhs
.v
[i
])
481 /// Compare the magnitude of vectors.
482 inline bool operator < (const Vector
& rhs
) const
484 return sqr() < rhs
.sqr();
486 /// Compare the magnitude of the vector with a scalar magnitude.
487 inline bool operator < (const T
& rhs
) const
489 return sqr() < rhs
*rhs
;
491 /// Compare the magnitude of the vector with a scalar magnitude.
492 inline friend bool operator < (const T
& lhs
, const Vector
& rhs
)
494 return lhs
*lhs
< rhs
.sqr();
496 /// Compare the magnitude of vectors.
497 inline bool operator <= (const Vector
& rhs
) const
499 return sqr() <= rhs
.sqr();
501 /// Compare the magnitude of the vector with a scalar magnitude.
502 inline bool operator <= (const T
& rhs
) const
504 return sqr() <= rhs
*rhs
;
506 /// Compare the magnitude of the vector with a scalar magnitude.
507 inline friend bool operator <= (const T
& lhs
, const Vector
& rhs
)
509 return lhs
*lhs
<= rhs
.sqr();
511 /// Compare the magnitude of vectors.
512 inline bool operator > (const Vector
& rhs
) const
514 return sqr() > rhs
.sqr();
516 /// Compare the magnitude of the vector with a scalar magnitude.
517 inline bool operator > (const T
& rhs
) const
519 return sqr() > rhs
*rhs
;
521 /// Compare the magnitude of the vector with a scalar magnitude.
522 inline friend bool operator > (const T
& lhs
, const Vector
& rhs
)
524 return lhs
*lhs
> rhs
.sqr();
526 /// Compare the magnitude of vectors.
527 inline bool operator >= (const Vector
& rhs
) const
529 return sqr() >= rhs
.sqr();
531 /// Compare the magnitude of the vector with a scalar magnitude.
532 inline bool operator >= (const T
& rhs
) const
534 return sqr() >= rhs
*rhs
;
536 /// Compare the magnitude of the vector with a scalar magnitude.
537 inline friend bool operator >= (const T
& lhs
, const Vector
& rhs
)
539 return lhs
*lhs
>= rhs
.sqr();
542 /// Find whether the vector zero.
543 inline bool zero() const
545 for (int i
= 0; i
< N
; ++i
)
556 inline operator std::string() const;
557 }; // ::maths::Vector
559 template <int N
, typename T
>
560 inline Vector
<N
,T
> & add (Vector
<N
,T
> & dest
, const Vector
<N
,T
> & lhs
, const Vector
<N
,T
> & rhs
)
562 for (int i
= 0; i
< N
; ++i
)
564 dest
.v
[i
] = lhs
.v
[i
] + rhs
.v
[i
];
569 template <int N
, typename T
>
570 inline Vector
<N
,T
> & sub (Vector
<N
,T
> & dest
, const Vector
<N
,T
> & lhs
, const Vector
<N
,T
> & rhs
)
572 for (int i
= 0; i
< N
; ++i
)
574 dest
.v
[i
] = lhs
.v
[i
] - rhs
.v
[i
];
579 template <typename T
>
580 inline Vector
<3,T
> & cross (Vector
<3,T
> & dest
, const Vector
<3,T
> & lhs
, const Vector
<3,T
> & rhs
)
582 dest
.v
[0] = lhs
.v
[1]*rhs
.v
[2] - lhs
.v
[2]*rhs
.v
[1];
583 dest
.v
[1] = lhs
.v
[2]*rhs
.v
[0] - lhs
.v
[0]*rhs
.v
[2];
584 dest
.v
[2] = lhs
.v
[0]*rhs
.v
[1] - lhs
.v
[1]*rhs
.v
[0];
588 template <typename T
>
589 inline Vector
<3,T
> cross (const Vector
<3,T
> & lhs
, const Vector
<3,T
> & rhs
)
592 dest
.v
[0] = lhs
.v
[1]*rhs
.v
[2] - lhs
.v
[2]*rhs
.v
[1];
593 dest
.v
[1] = lhs
.v
[2]*rhs
.v
[0] - lhs
.v
[0]*rhs
.v
[2];
594 dest
.v
[2] = lhs
.v
[0]*rhs
.v
[1] - lhs
.v
[1]*rhs
.v
[0];
598 template <typename T
>
599 inline Vector
<4,T
> homogenous(Vector
<3,T
> & vec
, T homogenousness
= (T
)1)
601 Vector
<4,T
> ret(vec
);
602 ret
[3] = homogenousness
;
606 /// Get the distance from a plane.
607 template <typename T
>
608 inline T
plane(const Vector
<4, T
> & plane
, const Vector
<3, T
> & point
)
610 return plane
[0]*point
[0] + plane
[1]*point
[1] + plane
[2]*point
[2] + plane
[3];
614 /// Write a vector to an output stream.
615 template <int N
, typename T
>
616 inline std::ostream
& operator << (std::ostream
& out
, const Vector
<N
,T
> & v
)
619 for (int i
= 1; i
< N
; ++i
)
625 /// Convert to a string using the above stream operator
626 template <int N
, typename T
>
627 inline Vector
<N
,T
>::operator std::string() const
629 std::stringstream ss
;
634 /// Basic function to create a one dimentional vector (scalar) which can then be expanded by concatination.
635 template <typename T
>
636 inline maths::Vector
<1,T
> Scalar(const T a
)
638 return maths::Vector
<1,T
>(a
);
643 #endif // _maths_vector_h