1 #ifndef INCLUDE_AL_VEC_HPP
2 #define INCLUDE_AL_VEC_HPP
49 #include "al/math/al_Constants.hpp"
53 template <
int N,
class T>
67 #define IT(n) for (int i = 0; i < (n); ++i)
69 template <
int N,
class T>
97 return Vec<3, T>(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x);
105 return Vec<3, T>(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x);
116 template <
int N,
class T>
121 typedef T value_type;
128 Vec(
const T& v1,
const T& v2) {
set(v1, v2); }
133 Vec(
const T& v1,
const T& v2,
const T& v3) {
set(v1, v2, v3); }
139 Vec(
const T& v1,
const T& v2,
const T& v3,
const T& v4) {
144 template <
int N2,
class T2>
151 template <
class Tv,
class Ts>
159 Vec(
const T2* v,
int stride = 1) {
167 static int size() {
return N; }
171 static const Vec&
pun(
const T* src) {
return *(
const Vec*)(src); }
176 return *(V*)(
elems());
180 const V&
as()
const {
181 return *(
const V*)(
elems());
185 const T*
elems()
const {
return &x; }
190 T* begin() {
return elems(); }
191 const T* begin()
const {
return elems(); }
192 T* end() {
return elems() + N; }
193 const T* end()
const {
return elems() + N; }
204 if ((*
this)[i] != v[i])
return false;
212 if ((*
this)[i] != v)
return false;
225 return Vec<2, T>((*
this)[i0], (*
this)[i1]);
230 return Vec<3, T>((*
this)[i0], (*
this)[i1], (*
this)[i2]);
235 return Vec<4, T>((*
this)[i0], (*
this)[i1], (*
this)[i2], (*
this)[i3]);
252 Vec& operator=(
const Vec& v) {
return set(v); }
253 Vec& operator=(
const T& v) {
return set(v); }
254 Vec& operator+=(
const Vec& v) {
255 IT(N)(*this)[i] += v[i];
258 Vec& operator+=(
const T& v) {
259 IT(N)(*this)[i] += v;
262 Vec& operator-=(
const Vec& v) {
263 IT(N)(*this)[i] -= v[i];
266 Vec& operator-=(
const T& v) {
267 IT(N)(*this)[i] -= v;
270 Vec& operator*=(
const Vec& v) {
271 IT(N)(*this)[i] *= v[i];
274 Vec& operator*=(
const T& v) {
275 IT(N)(*this)[i] *= v;
278 Vec& operator/=(
const Vec& v) {
279 IT(N)(*this)[i] /= v[i];
282 Vec& operator/=(
const T& v) {
283 IT(N)(*this)[i] /= v;
287 Vec operator+(
const Vec& v)
const {
return Vec(*
this) += v; }
288 Vec operator+(
const T& v)
const {
return Vec(*
this) += v; }
289 Vec operator-(
const Vec& v)
const {
return Vec(*
this) -= v; }
290 Vec operator-(
const T& v)
const {
return Vec(*
this) -= v; }
291 Vec operator*(
const Vec& v)
const {
return Vec(*
this) *= v; }
292 Vec operator*(
const T& v)
const {
return Vec(*
this) *= v; }
293 Vec operator/(
const Vec& v)
const {
return Vec(*
this) /= v; }
294 Vec operator/(
const T& v)
const {
return Vec(*
this) /= v; }
295 Vec operator-()
const {
return Vec(*this).negate(); }
296 bool operator>(
const Vec& v)
const {
return magSqr() > v.magSqr(); }
297 bool operator<(
const Vec& v)
const {
return magSqr() < v.magSqr(); }
302 IT(N) { (*this)[i] = T(v[i]); }
307 template <
int N2,
class T2>
309 IT(N < N2 ? N : N2) { (*this)[i] = T(v[i]); }
314 template <
class Tv,
class Ts>
322 IT(N) { (*this)[i] = v; }
329 IT(N) { (*this)[i] = T(v[i]); }
336 IT(N) { (*this)[i] = T(v[i * stride]); }
341 Vec&
set(
const T& v1,
const T& v2) {
return set(v1, v2, v1, v1, v1, v1); }
344 Vec&
set(
const T& v1,
const T& v2,
const T& v3) {
345 return set(v1, v2, v3, v1, v1, v1);
349 Vec&
set(
const T& v1,
const T& v2,
const T& v3,
const T& v4) {
350 return set(v1, v2, v3, v4, v1, v1);
354 Vec&
set(
const T& v1,
const T& v2,
const T& v3,
const T& v4,
const T& v5) {
355 return set(v1, v2, v3, v4, v5, v1);
359 Vec&
set(
const T& v1,
const T& v2,
const T& v3,
const T& v4,
const T& v5,
388 template <
int Dimension>
391 res[Dimension] += shift;
396 Vec byx(T shift)
const {
return by<0>(shift); }
399 Vec byy(T shift)
const {
return by<1>(shift); }
402 Vec byz(T shift)
const {
return by<2>(shift); }
407 T r = (*this)[0] * v[0];
408 for (
int i = 1; i < N; ++i) {
409 r += (*this)[i] * v[i];
425 T r = std::pow(std::abs((*
this)[0]), p);
426 for (
int i = 1; i < N; ++i) {
427 r += std::pow(std::abs((*
this)[i]), p);
429 return std::pow(r, T(1) / p);
441 for (
int i = 1; i < N; ++i) {
450 for (
int i = 1; i < N; ++i) {
458 T r = std::abs((*
this)[0]);
459 for (
int i = 1; i < N; ++i) {
460 r += std::abs((*
this)[i]);
467 return (*
this) += (target - (*this)) * amt;
475 IT(N) { (*this)[i] = -(*this)[i]; }
509 double a = cos(
angle);
510 double b = sin(
angle);
513 (*this)[dim1] = t * a - u * b;
514 (*this)[dim2] = t * b + u * a;
519 void print(FILE* out = stdout)
const;
527 template <
int N,
class T>
532 template <
int N,
class T>
533 inline Vec<N, T> operator-(
const T& s,
const Vec<N, T>& v) {
537 template <
int N,
class T>
538 inline Vec<N, T> operator*(
const T& s,
const Vec<N, T>& v) {
542 template <
int N,
class T>
543 inline Vec<N, T> operator/(
const T& s,
const Vec<N, T>& v) {
545 IT(N) { r[i] = s / v[i]; }
552 template <
int N,
class T>
558 template <
int N1,
class T1,
int N2,
class T2>
562 for (
int i = 0; i < N2; ++i) r[i + N1] = T1(b[i]);
567 template <
int M,
int N,
class T>
569 return v.template sub<M>(begin);
590 inline void cross(Vec<3, T>& r,
const Vec<4, T>& a,
const Vec<4, T>& b) {
633 template <
int N,
class T>
636 if (cosAng >= T(1)) {
638 }
else if (cosAng <= T(-1)) {
641 return std::acos(cosAng);
650 template <
int N,
class T>
653 static const T _1_3 = T(1) / T(3);
654 c = (p1 + p2 + p3) * _1_3;
658 template <
int N,
class T>
662 auto dot = (p - a).dot(ab);
668 if (frac < 0.)
return a;
669 if (frac > 1.)
return b;
671 return a + ab * frac;
675 template <
int N,
class T,
class U>
677 return (a - b).mag();
680 template <
int N,
class T>
681 inline Vec<N, T> lerp(
const Vec<N, T>& input,
const Vec<N, T>& target, T amt) {
682 return Vec<N, T>(input).lerp(target, amt);
694 cross(n, p2 - p1, p3 - p1);
699 template <
int N,
class T>
702 IT(N) { r[i] = a[i] > b[i] ? b[i] : a[i]; }
707 template <
int N,
class T>
710 IT(N) { r[i] = a[i] < b[i] ? b[i] : a[i]; }
716 template <
int N,
class T>
728 template <
int N,
class T>
733 template <
typename T>
734 const char* typeString();
735 #define TypeString(A) \
737 inline const char* typeString<A>() { \
740 TypeString(
char) TypeString(
unsigned char) TypeString(
int)
741 TypeString(
unsigned int) TypeString(
float) TypeString(
double)
742 TypeString(
long double)
745 template <
int N,
class T>
749 fprintf(out,
"%g", (
double)((*
this)[0]));
750 for (
int i = 1; i < N; ++i) fprintf(out,
", %g", (
double)((*
this)[i]));
757 template <
int N,
class T>
758 std::ostream& operator<<(std::ostream& out,
const Vec<N, T>& v) {
769 for (
int i = 1; i < N; ++i) out <<
", " << v[i];
T sumAbs() const
Returns sum of absolute value of elements.
Vec & set(const T &v1, const T &v2, const T &v3)
Set first 3 elements.
Vec & lerp(const Vec &target, T amt)
Linearly interpolate towards some target.
bool operator!=(const T &v) const
Return true if all elements are not equal to value, false otherwise.
T & operator[](size_t i)
Set element at index with no bounds checking.
T norm2() const
Return 2-norm of elements.
Vec & set(const T &v1, const T &v2, const T &v3, const T &v4, const T &v5, const T &v6)
Set first 6 elements.
Vec< 4, T > get(int i0, int i1, int i2, int i3) const
Get a vector comprised of indexed elements.
Vec & normalize(T scale=T(1))
Set magnitude to one without changing direction.
const T * elems() const
Get read-only pointer to elements.
Vec & set(const T &v1, const T &v2)
Set first 2 elements.
T norm(const T &p) const
Returns p-norm of elements.
T magSqr() const
Returns magnitude squared.
Vec byz(T shift) const
Returns a nearby vector along z.
Vec & set(const Vec< N, T2 > &v)
Set elements from another vector.
Vec(const Vec< N - 1, Tv > &v, const Ts &s)
Vec & set(const T2 *v, int stride)
Set elements from strided raw C-pointer.
Vec & set(const Vec< N2, T2 > &v)
Set elements from another vector.
Vec & zero()
Set all elements to zero.
Vec(const T &v1, const T &v2, const T &v3, const T &v4)
Vec byy(T shift) const
Returns a nearby vector along y.
Vec & set(const T2 *v)
Set elements from raw C-pointer.
Vec & set(const T &v)
Set all elements to the same value.
Vec & reflect(const Vec &u)
Relect vector around a unit vector.
const T & operator[](size_t i) const
Get element at index with no bounds checking.
Vec normalized(T scale=T(1)) const
Return closest vector lying on unit sphere.
Vec & set(const T &v1, const T &v2, const T &v3, const T &v4)
Set first 4 elements.
bool operator==(const T &v) const
Return true if all elements are equal to value, false otherwise.
T norm1() const
Return 1-norm of elements.
static int size()
Returns number of elements.
Vec & set(const Vec< N - 1, Tv > &v, const Ts &s)
Set elements from another vector and scalar.
void print(FILE *out=stdout) const
debug printing
T sum() const
Returns sum of elements.
static Vec & pun(T *src)
Returns C array type punned into a vector.
Vec by(T shift) const
Returns a nearby vector along some dimension.
Vec< 2, T > get(int i0, int i1) const
Get a vector comprised of indexed elements.
Vec & negate()
Negates all elements.
Vec & mag(T v)
Set magnitude (preserving direction)
T dot(const Vec< N, U > &v) const
Returns dot (inner) product between vectors.
Vec rejection(const Vec &u) const
Get rejection of vector from a unit vector.
Vec(const Vec< N2, T2 > &v)
Vec(const T2 *v, int stride=1)
bool operator!=(const Vec &v) const
Return true if objects are not element-wise equal, false otherwise.
Vec< 3, T > get(int i0, int i1, int i2) const
Get a vector comprised of indexed elements.
T * elems()
Get read-write pointer to elements.
Vec & set(const T &v1, const T &v2, const T &v3, const T &v4, const T &v5)
Set first 5 elements.
T mag() const
Returns magnitude.
Vec byx(T shift) const
Returns a nearby vector along x.
Vec< M, T > sub(int begin=0) const
Get a subvector.
bool operator==(const Vec &v) const
Return true if objects are element-wise equal, false otherwise.
Vec projection(const Vec &u) const
Get projection of vector onto a unit vector.
T product() const
Returns product of elements.
Vec & rotate(double angle, int dim1=0, int dim2=1)
Rotate vector on a global plane.
V & as()
Get reference to self as another type.
Vec(const T &v1, const T &v2, const T &v3)
Vec(const T &v1, const T &v2)
T min(const T &v1, const T &v2, const T &v3)
T max(const T &v1, const T &v2, const T &v3)
Vec< N, T > closestPointOnLineSegment(const Vec< N, T > &a, const Vec< N, T > &b, const Vec< N, T > &p)
Get closest point on line segment ab to point p.
Vec< N1+N2, T1 > concat(const Vec< N1, T1 > &a, const Vec< N2, T2 > &b)
Returns concatenation of two vectors.
Vec< M, T > sub(const Vec< N, T > &v, int begin=0)
Get a subvector.
Vec< 3, double > Vec3d
double 3-vector
Vec< 2, double > Vec2d
double 2-vector
void normal(Vec< 3, T > &n, const Vec< 3, T > &p1, const Vec< 3, T > &p2, const Vec< 3, T > &p3)
Vec< 4, float > Vec4f
float 4-vector
Vec< 4, double > Vec4d
double 4-vector
Vec< 4, int > Vec4i
integer 4-vector
T angle(const Vec< N, T > &a, const Vec< N, T > &b)
Returns angle, in interval [0, pi], between two vectors.
void centroid3(Vec< N, T > &c, const Vec< N, T > &p1, const Vec< N, T > &p2, const Vec< N, T > &p3)
Vec< 3, float > Vec3f
float 3-vector
Vec< 2, int > Vec2i
integer 2-vector
T dist(const Vec< N, T > &a, const Vec< N, U > &b)
Returns distance between two vectors.
Vec< 2, float > Vec2f
float 2-vector
void cross(Vec< 3, T > &r, const Vec< 3, T > &a, const Vec< 3, T > &b)
Sets r to cross product, a x b.
Vec< 3, int > Vec3i
integer 3-vector
Vec< 3, T > cross(const Vec< 3, T > &b) const
Returns cross product of this x b.