Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef VEC3_H
- #define VEC3_H
- #include "Math/constants.h"
- #include <QDebug>
- #include <QVector3D>
- // Mostly finished, but missing some error-control and a few operations
- struct Vec3
- {
- // Data
- float x, y, z;
- // Constructors
- Vec3() { x = y = z = 0.0f; }
- Vec3(float a, float b, float c) { x = a; y = b; z = c; }
- Vec3(const Vec3& v) { x = v.x; y = v.y; z = v.z; }
- // Premade vectors
- static Vec3 right() { return Vec3(1, 0, 0); }
- static Vec3 up() { return Vec3(0, 1, 0); }
- static Vec3 left() { return Vec3(-1, 0, 0); }
- static Vec3 down() { return Vec3(0, -1, 0); }
- static Vec3 forth() { return Vec3(0, 0, -1); }
- static Vec3 back() { return Vec3(0, 0, 1); }
- static Vec3 one() { return Vec3(1, 1, 1); }
- static Vec3 null() { return Vec3(0, 0, 0); }
- static Vec3 octantI() { return Vec3(SQRT3OVER2, SQRT3OVER2, SQRT3OVER2); }
- static Vec3 octantII() { return Vec3(-SQRT3OVER2, SQRT3OVER2, SQRT3OVER2); }
- static Vec3 octantIII() { return Vec3(-SQRT3OVER2, -SQRT3OVER2, SQRT3OVER2); }
- static Vec3 octantIV() { return Vec3(SQRT3OVER2, -SQRT3OVER2, SQRT3OVER2); }
- static Vec3 octantV() { return Vec3(SQRT3OVER2, SQRT3OVER2, -SQRT3OVER2); }
- static Vec3 octantVI() { return Vec3(-SQRT3OVER2, SQRT3OVER2, -SQRT3OVER2); }
- static Vec3 octantVII() { return Vec3(-SQRT3OVER2, -SQRT3OVER2, -SQRT3OVER2); }
- static Vec3 octantVIII() { return Vec3(SQRT3OVER2, -SQRT3OVER2, -SQRT3OVER2); }
- // Utilities
- void debugPrint()
- {
- qDebug() << "[" + QString::number(x) + ", " + QString::number(y) + ", " + QString::number(z) + "]";
- }
- static void debugPrint(const Vec3& v)
- {
- qDebug() << "[" + QString::number(v.x) + ", " + QString::number(v.y) + ", " + QString::number(v.z) + "]";
- }
- void debugPrint(QString preface)
- {
- qDebug() << preface + "[" + QString::number(x) + ", " + QString::number(y) + ", " + QString::number(z) + "]";
- }
- static void debugPrint(const Vec3& v, QString preface)
- {
- qDebug() << preface + "[" + QString::number(v.x) + ", " + QString::number(v.y) + ", " + QString::number(v.z) + "]";
- }
- static void debugTest()
- {
- }
- // Access operators
- float& operator [](int i) { return (&x)[i]; }
- const float& operator [](int i) const { return (&x)[i]; }
- // Assignment operator
- Vec3& operator =(const Vec3& v) { x = v.x; y = v.y; z = v.z; return *this; }
- // Conversion
- QVector3D toQVector3D() { return QVector3D(x, y, z); }
- // Swizzling
- Vec3 xxx() { return Vec3(x, x, x); }
- Vec3 xxy() { return Vec3(x, x, y); }
- Vec3 xxz() { return Vec3(x, x, z); }
- Vec3 xyx() { return Vec3(x, y, x); }
- Vec3 xyy() { return Vec3(x, y, y); }
- Vec3 xyz() { return Vec3(x, y, z); }
- Vec3 xzx() { return Vec3(x, z, x); }
- Vec3 xzy() { return Vec3(x, z, y); }
- Vec3 xzz() { return Vec3(x, z, z); }
- Vec3 yxx() { return Vec3(y, x, x); }
- Vec3 yxy() { return Vec3(y, x, y); }
- Vec3 yxz() { return Vec3(y, x, z); }
- Vec3 yyx() { return Vec3(y, y, x); }
- Vec3 yyy() { return Vec3(y, y, y); }
- Vec3 yyz() { return Vec3(y, y, z); }
- Vec3 yzx() { return Vec3(y, z, x); }
- Vec3 yzy() { return Vec3(y, z, y); }
- Vec3 yzz() { return Vec3(y, z, z); }
- Vec3 zxx() { return Vec3(z, x, x); }
- Vec3 zxy() { return Vec3(z, x, y); }
- Vec3 zxz() { return Vec3(z, x, z); }
- Vec3 zyx() { return Vec3(z, y, x); }
- Vec3 zyy() { return Vec3(z, y, y); }
- Vec3 zyz() { return Vec3(z, y, z); }
- Vec3 zzx() { return Vec3(z, z, x); }
- Vec3 zzy() { return Vec3(z, z, y); }
- Vec3 zzz() { return Vec3(z, z, z); }
- // Magnitude comparison operators
- bool operator ==(const Vec3& v) { return (x == v.x && y == v.y && z == v.z) ? true : false; }
- bool operator <(const Vec3& v) { return (*this).magnitudeSquared() < v.magnitudeSquared() ? true : false; }
- bool operator <=(const Vec3& v) { return (*this).magnitudeSquared() <= v.magnitudeSquared() ? true : false; }
- bool operator >(const Vec3& v) { return (*this).magnitudeSquared() > v.magnitudeSquared() ? true : false; }
- bool operator >=(const Vec3& v) { return (*this).magnitudeSquared() >= v.magnitudeSquared() ? true : false; }
- // Vector operations
- Vec3 operator +(const Vec3& v) const { return Vec3(x + v.x, y + v.y, z + v.z); }
- Vec3& operator +=(const Vec3& v) { x += v.x; y += v.y; z += v.z; return *this; }
- Vec3 operator -(const Vec3& v) const { return Vec3(x - v.x, y - v.y, z - v.z); }
- Vec3& operator -=(const Vec3& v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
- Vec3 operator *(const float& s) const { return Vec3(x * s, y * s, z * s); }
- Vec3& operator *=(const float& s) { x *= s; y *= s; z *= s; return *this; }
- Vec3 operator /(float s) const { s = 1.0f / s; return Vec3(x * s, y * s, z * s); }
- Vec3& operator /=(float s) { s = 1.0f / s; x *= s; y *= s; z *= s; return *this; }
- float operator *(const Vec3& v) const { return x * v.x + y * v.y; }
- float dot(const Vec3& v) const { return x * v.x + y * v.y + z * v.z; }
- static float dot(const Vec3& a, const Vec3& b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
- Vec3 operator %(const Vec3& v) { return Vec3(y * v.z - v.y * z, v.x * z - x * v.z, x * v.y - v.x * y); }
- Vec3 cross(const Vec3& v) { return Vec3(y * v.z - v.y * z, v.x * z - x * v.z, x * v.y - v.x * y); }
- static Vec3 cross(const Vec3 &a, const Vec3& b) { return Vec3(a.y * b.z - b.y * a.z, b.x * a.z - a.x * b.z, a.x * b.y - b.x * a.y); }
- // Quaternion multiplication
- // Matrix multiplication
- float magnitude() const { return sqrt(x * x + y * y + z * z); }
- float magnitudeSquared() const { return x * x + y * y + z * z; }
- float angle(const Vec3& v) const { return acos(((*this) * v) / ((*this).magnitude() * v.magnitude())); }
- static float angle(const Vec3& a, const Vec3& b) { return acos((a * b) / (a.magnitude() * b.magnitude())); }
- float angleUnit(const Vec3& v) const { return acos((*this) * v); }
- static float angleUnit(const Vec3& a, const Vec3& b) { return acos(a * b); }
- Vec3 normalization()
- {
- // Returns a normalized copy of this
- if (x != 0.0f || y != 0.0f)
- {
- float s = 1.0f / (*this).magnitude();
- return (*this) * s;
- }
- // Else throw error
- }
- static Vec3 normalization(Vec3 v)
- {
- // Returns a normalized copy of v
- if (v.x != 0.0f || v.y != 0.0f)
- {
- float s = 1.0f / v.magnitude();
- return v * s;
- }
- // Else throw error
- }
- Vec3& normalize()
- {
- // Normalizes this
- if (x != 0.0f || y != 0.0f)
- {
- float s = 1.0f / (*this).magnitude();
- (*this) * s;
- return *this;
- }
- // Else throw error
- }
- static Vec3& normalize(Vec3& v)
- {
- // Normalizes v
- if (v.x != 0.0f || v.y != 0.0f)
- {
- float s = 1.0f / v.magnitude();
- v *= s;
- return v;
- }
- // Else throw error
- }
- Vec3 projection(const Vec3& v)
- {
- return Vec3(v * (((*this) * v) / (v * v)));
- }
- Vec3 projectionUnit(const Vec3& v)
- {
- // If v is normalized...
- return Vec3(v * ((*this) * v));
- }
- static Vec3 projection(const Vec3& a, const Vec3& b)
- {
- return Vec3(b * ((a * b) / (b * b)));
- }
- static Vec3 projectionUnit(const Vec3& a, const Vec3& b)
- {
- // If b is normalized...
- return Vec3(b * (a * b));
- }
- Vec3& project(const Vec3& v)
- {
- // Catch if v is null vector
- *this = v * ((*this) * v / (v * v));
- return *this;
- }
- Vec3& projectUnit(const Vec3& v)
- {
- // If v is normalized...
- *this = v * ((*this) * v);
- return *this;
- }
- static Vec3& project(Vec3& a, const Vec3& b)
- {
- a = b * (a * b) / (b * b);
- return a;
- }
- static Vec3& projectUnit(Vec3& a, const Vec3& b)
- {
- // If b is normalized...
- a = b * (a * b);
- return a;
- }
- Vec3 rejection(const Vec3& v)
- {
- return Vec3((*this) - v * (((*this) * v) / (v * v)));
- }
- Vec3 rejectionUnit(const Vec3& v)
- {
- // If v is normalized...
- return Vec3((*this) - v * ((*this) * v));
- }
- static Vec3 rejection(const Vec3& a, const Vec3& b)
- {
- return Vec3(a - b * ((a * b) / (b * b)));
- }
- static Vec3 rejectionUnit(const Vec3& a, const Vec3& b)
- {
- // If b is normalized...
- return Vec3(a - b * (a * b));
- }
- Vec3& reject(const Vec3& v)
- {
- *this = *this - v * ((*this) * v / (v * v));
- return *this;
- }
- Vec3& rejectUnit(const Vec3& v)
- {
- // If v is normalized...
- *this = *this - v * ((*this) * v);
- return *this;
- }
- static Vec3& reject(Vec3& a, const Vec3& b)
- {
- a = a - b * (a * b) / (b * b);
- return a;
- }
- static Vec3& rejectUnit(Vec3& a, const Vec3& b)
- {
- // If b is normalized...
- a = a - b * (a * b);
- return a;
- }
- Vec3 reflection(const Vec3& v)
- {
- return Vec3((*this) - v * (((*this) * v) / (v * v)) * 2);
- }
- Vec3 reflectionUnit(const Vec3& v)
- {
- // If v is normalized...
- return Vec3((*this) - v * ((*this) * v) * 2);
- }
- static Vec3 reflection(const Vec3& a, const Vec3& b)
- {
- return Vec3(a - b * ((a * b)) / (b * b) * 2);
- }
- static Vec3 reflectionUnit(const Vec3& a, const Vec3& b)
- {
- // If b is normalized...
- return Vec3(a - b * (a * b) * 2);
- }
- Vec3& reflect(const Vec3& v)
- {
- *this = *this - v * (((*this) * v) / (v * v) * 2);
- return *this;
- }
- Vec3& reflectUnit(const Vec3& v)
- {
- *this = *this - v * ((*this) * v) * 2;
- return *this;
- }
- static Vec3& reflect(Vec3& a, const Vec3& b)
- {
- a = a - b * ((a * b) / (b * b) * 2);
- return a;
- }
- static Vec3& reflectUnit(Vec3& a, const Vec3& b)
- {
- a = a - b * (a * b) * 2;
- return a;
- }
- // Mixing vectors
- static Vec3 lerp(const Vec3& a, const Vec3& b, const float& t) { return Vec3(a + (b - a) * t); }
- static Vec3 lerpNormalized(const Vec3& a, const Vec3& b, const float& t) { return Vec3(a + (b - a) * t).normalization(); }
- static Vec3 slerp(const Vec3& a, const Vec3& b, const float& t)
- {
- }
- // Tests - epsilon lets you customize the tolerance
- bool isNormalized()
- {
- // Maybe let epsilon dictate how many units in length, rather than an abstract number?
- // 0.1 -> 0.05 length precision
- // 0.01 -> 0.005 length precision
- // 0.001 -> 0.0005 length precision
- // 0.0001 -> 0.00005 length precision
- // 0.00001 -> 0.000005 length precision
- return abs((*this) * (*this) - 1.0f) < 0.0000001f ? true : false;
- }
- bool isNormalized(const float& epsilon)
- {
- // Accuracy is < 1.0, preferably far below, but not negative.
- return abs((*this) * (*this) - 1.0f) < epsilon ? true : false;
- }
- static bool isNormalized(const Vec3& v)
- {
- return abs(v * v - 1.0f) < 0.0000001f ? true : false;
- }
- static bool isNormalized(const Vec3& v, const float& epsilon)
- {
- return abs(v * v - 1.0f) < epsilon ? true : false;
- }
- bool isParallel(const Vec3& v)
- {
- // https://stackoverflow.com/questions/7572640/how-do-i-know-if-two-vectors-are-near-parallel
- float s = 1.0f / ((*this).magnitude() * v.magnitude());
- if (((*this) * v) * s > 1 - 0.0000001f)
- return true;
- else
- return false;
- }
- bool isParallel(const Vec3& v, const float& epsilon)
- {
- float s = 1.0f / ((*this).magnitude() * v.magnitude());
- if (((*this) * v) * s > 1 - epsilon)
- return true;
- else
- return false;
- }
- bool isParallelUnit(const Vec3& v)
- {
- if (((*this) * v) > 1 - 0.0000001f)
- return true;
- else
- return false;
- }
- bool isParallelUnit(const Vec3& v, const float& epsilon)
- {
- if (((*this) * v) > 1 - epsilon)
- return true;
- else
- return false;
- }
- static bool isParallel(const Vec3& a, const Vec3& b)
- {
- float s = 1.0f / (a.magnitude() * b.magnitude());
- if ((a * b) * s > 1 - 0.0000001f)
- return true;
- else
- return false;
- }
- static bool isParallel(const Vec3& a, const Vec3& b, const float& epsilon)
- {
- float s = 1.0f / (a.magnitude() * b.magnitude());
- if ((a * b) * s > 1 - epsilon)
- return true;
- else
- return false;
- }
- static bool isParallelUnit(const Vec3& a, const Vec3& b)
- {
- if ((a * b) > 1 - 0.0000001f)
- return true;
- else
- return false;
- }
- static bool isParallelUnit(const Vec3& a, const Vec3& b, const float& epsilon)
- {
- if ((a * b) > 1 - epsilon)
- return true;
- else
- return false;
- }
- bool isAntiparallel(const Vec3& v)
- {
- float s = 1.0f / ((*this).magnitude() * v.magnitude());
- if (((*this) * v) * s < 0.0000001f - 1)
- return true;
- else
- return false;
- }
- bool isAntiparallel(const Vec3& v, const float& epsilon)
- {
- float s = 1.0f / ((*this).magnitude() * v.magnitude());
- if (((*this) * v) * s < epsilon - 1)
- return true;
- else
- return false;
- }
- bool isAntiparallelUnit(const Vec3& v)
- {
- if (((*this) * v) < 0.0000001f - 1)
- return true;
- else
- return false;
- }
- bool isAntiparallelUnit(const Vec3& v, const float& epsilon)
- {
- if (((*this) * v) < epsilon - 1)
- return true;
- else
- return false;
- }
- static bool isAntiparallel(const Vec3& a, const Vec3& b)
- {
- float s = 1.0f / (a.magnitude() * b.magnitude());
- if ((a * b) * s < 0.0000001f - 1)
- return true;
- else
- return false;
- }
- static bool isAntiparallel(const Vec3& a, const Vec3& b, const float& epsilon)
- {
- float s = 1.0f / (a.magnitude() * b.magnitude());
- if ((a * b) * s < epsilon - 1)
- return true;
- else
- return false;
- }
- static bool isAntiparallelUnit(const Vec3& a, const Vec3& b)
- {
- if (a * b < 0.0000001f - 1)
- return true;
- else
- return false;
- }
- static bool isAntiparallelUnit(const Vec3& a, const Vec3& b, const float& epsilon)
- {
- if (a * b < epsilon - 1)
- return true;
- else
- return false;
- }
- bool isColinear(const Vec3& v)
- {
- float dot = ((*this) * v) / ((*this).magnitude() * v.magnitude());
- if (dot > 1 - 0.0000001f)
- return true;
- else if (dot < 0.0000001f - 1)
- return true;
- else
- return false;
- }
- bool isColinear(const Vec3& v, const float& epsilon)
- {
- float dot = ((*this) * v) / ((*this).magnitude() * v.magnitude());
- if (dot > 1 - epsilon)
- return true;
- else if (dot < epsilon - 1)
- return true;
- else
- return false;
- }
- bool isColinearUnit(const Vec3& v)
- {
- float dot = ((*this) * v);
- if (dot > 1 - 0.0000001f)
- return true;
- else if (dot < 0.0000001f - 1)
- return true;
- else
- return false;
- }
- bool isColinearUnit(const Vec3& v, const float& epsilon)
- {
- float dot = ((*this) * v);
- if (dot > 1 - epsilon)
- return true;
- else if (dot < epsilon - 1)
- return true;
- else
- return false;
- }
- static bool isColinear(const Vec3& a, const Vec3& b)
- {
- float dot = (a * b) / (a.magnitude() * b.magnitude());
- if (dot > 1 - 0.0000001f)
- return true;
- else if (dot < 0.0000001f - 1)
- return true;
- else
- return false;
- }
- static bool isColinear(const Vec3& a, const Vec3& b, const float& epsilon)
- {
- float dot = (a * b) / (a.magnitude() * b.magnitude());
- if (dot > 1 - epsilon)
- return true;
- else if (dot < epsilon - 1)
- return true;
- else
- return false;
- }
- static bool isColinearUnit(const Vec3& a, const Vec3& b)
- {
- float dot = (a * b);
- if (dot > 1 - 0.0000001f)
- return true;
- else if (dot < 0.0000001f - 1)
- return true;
- else
- return false;
- }
- static bool isColinearUnit(const Vec3& a, const Vec3& b, const float& epsilon)
- {
- float dot = (a * b);
- if (dot > 1 - epsilon)
- return true;
- else if (dot < epsilon - 1)
- return true;
- else
- return false;
- }
- bool isOrthogonal(const Vec3& v)
- {
- float s = 1.0f / ((*this).magnitude() * v.magnitude());
- return abs(((*this) * v) * s) < 0.0000001f ? true : false;
- }
- bool isOrthogonal(const Vec3& v, const float& epsilon)
- {
- float s = 1.0f / ((*this).magnitude() * v.magnitude());
- return abs(((*this) * v) * s) < epsilon ? true : false;
- }
- bool isOrthogonalUnit(const Vec3& v)
- {
- return abs((*this) * v) < 0.0000001f ? true : false;
- }
- bool isOrthogonalUnit(const Vec3& v, const float& epsilon)
- {
- return abs((*this) * v) < epsilon ? true : false;
- }
- static bool isOrthogonal(const Vec3& a, const Vec3& b)
- {
- float s = 1.0f / (a.magnitude() * b.magnitude());
- return abs((a * b) * s) < 0.0000001f ? true : false;
- }
- static bool isOrthogonal(const Vec3& a, const Vec3& b, const float& epsilon)
- {
- float s = 1.0f / (a.magnitude() * b.magnitude());
- return abs((a * b) * s) < epsilon ? true : false;
- }
- static bool isOrthogonalUnit(const Vec3& a, const Vec3& b)
- {
- return abs(a * b) < 0.0000001f ? true : false;
- }
- static bool isOrthogonalUnit(const Vec3& a, const Vec3& b, const float& epsilon)
- {
- return abs(a * b) < epsilon ? true : false;
- }
- };
- #endif // VEC3_H
Advertisement
Add Comment
Please, Sign In to add comment