DexterAndre

Vector Struct C++

Mar 18th, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 18.55 KB | None | 0 0
  1. #ifndef VEC3_H
  2. #define VEC3_H
  3.  
  4. #include "Math/constants.h"
  5. #include <QDebug>
  6. #include <QVector3D>
  7.  
  8. // Mostly finished, but missing some error-control and a few operations
  9. struct Vec3
  10. {
  11.     // Data
  12.     float x, y, z;
  13.  
  14.     // Constructors
  15.     Vec3() { x = y = z = 0.0f; }
  16.     Vec3(float a, float b, float c) { x = a; y = b; z = c; }
  17.     Vec3(const Vec3& v) { x = v.x; y = v.y; z = v.z; }
  18.  
  19.     // Premade vectors
  20.     static Vec3 right() { return Vec3(1, 0, 0); }
  21.     static Vec3 up() { return Vec3(0, 1, 0); }
  22.     static Vec3 left() { return Vec3(-1, 0, 0); }
  23.     static Vec3 down() { return Vec3(0, -1, 0); }
  24.     static Vec3 forth() { return Vec3(0, 0, -1); }
  25.     static Vec3 back() { return Vec3(0, 0, 1); }
  26.     static Vec3 one() { return Vec3(1, 1, 1); }
  27.     static Vec3 null() { return Vec3(0, 0, 0); }
  28.  
  29.     static Vec3 octantI() { return Vec3(SQRT3OVER2, SQRT3OVER2, SQRT3OVER2); }
  30.     static Vec3 octantII() { return Vec3(-SQRT3OVER2, SQRT3OVER2, SQRT3OVER2); }
  31.     static Vec3 octantIII() { return Vec3(-SQRT3OVER2, -SQRT3OVER2, SQRT3OVER2); }
  32.     static Vec3 octantIV() { return Vec3(SQRT3OVER2, -SQRT3OVER2, SQRT3OVER2); }
  33.     static Vec3 octantV() { return Vec3(SQRT3OVER2, SQRT3OVER2, -SQRT3OVER2); }
  34.     static Vec3 octantVI() { return Vec3(-SQRT3OVER2, SQRT3OVER2, -SQRT3OVER2); }
  35.     static Vec3 octantVII() { return Vec3(-SQRT3OVER2, -SQRT3OVER2, -SQRT3OVER2); }
  36.     static Vec3 octantVIII() { return Vec3(SQRT3OVER2, -SQRT3OVER2, -SQRT3OVER2); }
  37.  
  38.     // Utilities
  39.     void debugPrint()
  40.     {
  41.         qDebug() << "[" + QString::number(x) + ", " + QString::number(y) + ", " + QString::number(z) + "]";
  42.     }
  43.     static void debugPrint(const Vec3& v)
  44.     {
  45.         qDebug() << "[" + QString::number(v.x) + ", " + QString::number(v.y) + ", " + QString::number(v.z) + "]";
  46.     }
  47.     void debugPrint(QString preface)
  48.     {
  49.         qDebug() << preface + "[" + QString::number(x) + ", " + QString::number(y) + ", " + QString::number(z) + "]";
  50.     }
  51.     static void debugPrint(const Vec3& v, QString preface)
  52.     {
  53.         qDebug() << preface + "[" + QString::number(v.x) + ", " + QString::number(v.y) + ", " + QString::number(v.z) + "]";
  54.     }
  55.     static void debugTest()
  56.     {
  57.  
  58.     }
  59.  
  60.     // Access operators
  61.     float& operator [](int i) { return (&x)[i]; }
  62.     const float& operator [](int i) const { return (&x)[i]; }
  63.  
  64.     // Assignment operator
  65.     Vec3& operator =(const Vec3& v) { x = v.x; y = v.y; z = v.z; return *this; }
  66.  
  67.     // Conversion
  68.     QVector3D toQVector3D() { return QVector3D(x, y, z); }
  69.  
  70.     // Swizzling
  71.     Vec3 xxx() { return Vec3(x, x, x); }
  72.     Vec3 xxy() { return Vec3(x, x, y); }
  73.     Vec3 xxz() { return Vec3(x, x, z); }
  74.     Vec3 xyx() { return Vec3(x, y, x); }
  75.     Vec3 xyy() { return Vec3(x, y, y); }
  76.     Vec3 xyz() { return Vec3(x, y, z); }
  77.     Vec3 xzx() { return Vec3(x, z, x); }
  78.     Vec3 xzy() { return Vec3(x, z, y); }
  79.     Vec3 xzz() { return Vec3(x, z, z); }
  80.     Vec3 yxx() { return Vec3(y, x, x); }
  81.     Vec3 yxy() { return Vec3(y, x, y); }
  82.     Vec3 yxz() { return Vec3(y, x, z); }
  83.     Vec3 yyx() { return Vec3(y, y, x); }
  84.     Vec3 yyy() { return Vec3(y, y, y); }
  85.     Vec3 yyz() { return Vec3(y, y, z); }
  86.     Vec3 yzx() { return Vec3(y, z, x); }
  87.     Vec3 yzy() { return Vec3(y, z, y); }
  88.     Vec3 yzz() { return Vec3(y, z, z); }
  89.     Vec3 zxx() { return Vec3(z, x, x); }
  90.     Vec3 zxy() { return Vec3(z, x, y); }
  91.     Vec3 zxz() { return Vec3(z, x, z); }
  92.     Vec3 zyx() { return Vec3(z, y, x); }
  93.     Vec3 zyy() { return Vec3(z, y, y); }
  94.     Vec3 zyz() { return Vec3(z, y, z); }
  95.     Vec3 zzx() { return Vec3(z, z, x); }
  96.     Vec3 zzy() { return Vec3(z, z, y); }
  97.     Vec3 zzz() { return Vec3(z, z, z); }
  98.  
  99.     // Magnitude comparison operators
  100.     bool operator ==(const Vec3& v) { return (x == v.x && y == v.y && z == v.z) ? true : false; }
  101.     bool operator <(const Vec3& v) { return (*this).magnitudeSquared() < v.magnitudeSquared() ? true : false; }
  102.     bool operator <=(const Vec3& v) { return (*this).magnitudeSquared() <= v.magnitudeSquared() ? true : false; }
  103.     bool operator >(const Vec3& v) { return (*this).magnitudeSquared() > v.magnitudeSquared() ? true : false; }
  104.     bool operator >=(const Vec3& v) { return (*this).magnitudeSquared() >= v.magnitudeSquared() ? true : false; }
  105.  
  106.     // Vector operations
  107.     Vec3 operator +(const Vec3& v) const { return Vec3(x + v.x, y + v.y, z + v.z); }
  108.     Vec3& operator +=(const Vec3& v) { x += v.x; y += v.y; z += v.z; return *this; }
  109.     Vec3 operator -(const Vec3& v) const { return Vec3(x - v.x, y - v.y, z - v.z); }
  110.     Vec3& operator -=(const Vec3& v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
  111.     Vec3 operator *(const float& s) const { return Vec3(x * s, y * s, z * s); }
  112.     Vec3& operator *=(const float& s) { x *= s; y *= s; z *= s; return *this; }
  113.     Vec3 operator /(float s) const { s = 1.0f / s; return Vec3(x * s, y * s, z * s); }
  114.     Vec3& operator /=(float s) { s = 1.0f / s; x *= s; y *= s; z *= s; return *this; }
  115.     float operator *(const Vec3& v) const { return x * v.x + y * v.y; }
  116.     float dot(const Vec3& v) const { return x * v.x + y * v.y + z * v.z; }
  117.     static float dot(const Vec3& a, const Vec3& b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
  118.     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); }
  119.     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); }
  120.     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); }
  121.     // Quaternion multiplication
  122.     // Matrix multiplication
  123.     float magnitude() const { return sqrt(x * x + y * y + z * z); }
  124.     float magnitudeSquared() const { return x * x + y * y + z * z; }
  125.     float angle(const Vec3& v) const { return acos(((*this) * v) / ((*this).magnitude() * v.magnitude())); }
  126.     static float angle(const Vec3& a, const Vec3& b) { return acos((a * b) / (a.magnitude() * b.magnitude())); }
  127.     float angleUnit(const Vec3& v) const { return acos((*this) * v); }
  128.     static float angleUnit(const Vec3& a, const Vec3& b) { return acos(a * b); }
  129.     Vec3 normalization()
  130.     {
  131.         // Returns a normalized copy of this
  132.         if (x != 0.0f || y != 0.0f)
  133.         {
  134.             float s = 1.0f / (*this).magnitude();
  135.             return (*this) * s;
  136.         }
  137.         // Else throw error
  138.     }
  139.     static Vec3 normalization(Vec3 v)
  140.     {
  141.         // Returns a normalized copy of v
  142.         if (v.x != 0.0f || v.y != 0.0f)
  143.         {
  144.             float s = 1.0f / v.magnitude();
  145.             return v * s;
  146.         }
  147.         // Else throw error
  148.     }
  149.     Vec3& normalize()
  150.     {
  151.         // Normalizes this
  152.         if (x != 0.0f || y != 0.0f)
  153.         {
  154.             float s = 1.0f / (*this).magnitude();
  155.             (*this) * s;
  156.             return *this;
  157.         }
  158.         // Else throw error
  159.     }
  160.     static Vec3& normalize(Vec3& v)
  161.     {
  162.         // Normalizes v
  163.         if (v.x != 0.0f || v.y != 0.0f)
  164.         {
  165.             float s = 1.0f / v.magnitude();
  166.             v *= s;
  167.             return v;
  168.         }
  169.         // Else throw error
  170.     }
  171.     Vec3 projection(const Vec3& v)
  172.     {
  173.         return Vec3(v * (((*this) * v) / (v * v)));
  174.     }
  175.     Vec3 projectionUnit(const Vec3& v)
  176.     {
  177.         // If v is normalized...
  178.         return Vec3(v * ((*this) * v));
  179.     }
  180.     static Vec3 projection(const Vec3& a, const Vec3& b)
  181.     {
  182.         return Vec3(b * ((a * b) / (b * b)));
  183.     }
  184.     static Vec3 projectionUnit(const Vec3& a, const Vec3& b)
  185.     {
  186.         // If b is normalized...
  187.         return Vec3(b * (a * b));
  188.     }
  189.     Vec3& project(const Vec3& v)
  190.     {
  191.         // Catch if v is null vector
  192.         *this = v * ((*this) * v / (v * v));
  193.         return *this;
  194.     }
  195.     Vec3& projectUnit(const Vec3& v)
  196.     {
  197.         // If v is normalized...
  198.         *this = v * ((*this) * v);
  199.         return *this;
  200.     }
  201.     static Vec3& project(Vec3& a, const Vec3& b)
  202.     {
  203.         a = b * (a * b) / (b * b);
  204.         return a;
  205.     }
  206.     static Vec3& projectUnit(Vec3& a, const Vec3& b)
  207.     {
  208.         // If b is normalized...
  209.         a = b * (a * b);
  210.         return a;
  211.     }
  212.     Vec3 rejection(const Vec3& v)
  213.     {
  214.         return Vec3((*this) - v * (((*this) * v) / (v * v)));
  215.     }
  216.     Vec3 rejectionUnit(const Vec3& v)
  217.     {
  218.         // If v is normalized...
  219.         return Vec3((*this) - v * ((*this) * v));
  220.     }
  221.     static Vec3 rejection(const Vec3& a, const Vec3& b)
  222.     {
  223.         return Vec3(a - b * ((a * b) / (b * b)));
  224.     }
  225.     static Vec3 rejectionUnit(const Vec3& a, const Vec3& b)
  226.     {
  227.         // If b is normalized...
  228.         return Vec3(a - b * (a * b));
  229.     }
  230.     Vec3& reject(const Vec3& v)
  231.     {
  232.         *this = *this - v * ((*this) * v / (v * v));
  233.         return *this;
  234.     }
  235.     Vec3& rejectUnit(const Vec3& v)
  236.     {
  237.         // If v is normalized...
  238.         *this = *this - v * ((*this) * v);
  239.         return *this;
  240.     }
  241.     static Vec3& reject(Vec3& a, const Vec3& b)
  242.     {
  243.         a = a - b * (a * b) / (b * b);
  244.         return a;
  245.     }
  246.     static Vec3& rejectUnit(Vec3& a, const Vec3& b)
  247.     {
  248.         // If b is normalized...
  249.         a = a - b * (a * b);
  250.         return a;
  251.     }
  252.     Vec3 reflection(const Vec3& v)
  253.     {
  254.         return Vec3((*this) - v * (((*this) * v) / (v * v)) * 2);
  255.     }
  256.     Vec3 reflectionUnit(const Vec3& v)
  257.     {
  258.         // If v is normalized...
  259.         return Vec3((*this) - v * ((*this) * v) * 2);
  260.     }
  261.     static Vec3 reflection(const Vec3& a, const Vec3& b)
  262.     {
  263.         return Vec3(a - b * ((a * b)) / (b * b) * 2);
  264.     }
  265.     static Vec3 reflectionUnit(const Vec3& a, const Vec3& b)
  266.     {
  267.         // If b is normalized...
  268.         return Vec3(a - b * (a * b) * 2);
  269.     }
  270.     Vec3& reflect(const Vec3& v)
  271.     {
  272.         *this = *this - v * (((*this) * v) / (v * v) * 2);
  273.         return *this;
  274.     }
  275.     Vec3& reflectUnit(const Vec3& v)
  276.     {
  277.         *this = *this - v * ((*this) * v) * 2;
  278.         return *this;
  279.     }
  280.     static Vec3& reflect(Vec3& a, const Vec3& b)
  281.     {
  282.         a = a - b * ((a * b) / (b * b) * 2);
  283.         return a;
  284.     }
  285.     static Vec3& reflectUnit(Vec3& a, const Vec3& b)
  286.     {
  287.         a = a - b * (a * b) * 2;
  288.         return a;
  289.     }
  290.  
  291.     // Mixing vectors
  292.     static Vec3 lerp(const Vec3& a, const Vec3& b, const float& t) { return Vec3(a + (b - a) * t); }
  293.     static Vec3 lerpNormalized(const Vec3& a, const Vec3& b, const float& t) { return Vec3(a + (b - a) * t).normalization(); }
  294.     static Vec3 slerp(const Vec3& a, const Vec3& b, const float& t)
  295.     {
  296.  
  297.     }
  298.  
  299.     // Tests - epsilon lets you customize the tolerance
  300.     bool isNormalized()
  301.     {
  302.         // Maybe let epsilon dictate how many units in length, rather than an abstract number?
  303.         // 0.1      -> 0.05 length precision
  304.         // 0.01     -> 0.005 length precision
  305.         // 0.001    -> 0.0005 length precision
  306.         // 0.0001   -> 0.00005 length precision
  307.         // 0.00001  -> 0.000005 length precision
  308.  
  309.         return abs((*this) * (*this) - 1.0f) < 0.0000001f ? true : false;
  310.     }
  311.     bool isNormalized(const float& epsilon)
  312.     {
  313.         // Accuracy is < 1.0, preferably far below, but not negative.
  314.         return abs((*this) * (*this) - 1.0f) < epsilon ? true : false;
  315.     }
  316.     static bool isNormalized(const Vec3& v)
  317.     {
  318.         return abs(v * v - 1.0f) < 0.0000001f ? true : false;
  319.     }
  320.     static bool isNormalized(const Vec3& v, const float& epsilon)
  321.     {
  322.         return abs(v * v - 1.0f) < epsilon ? true : false;
  323.     }
  324.     bool isParallel(const Vec3& v)
  325.     {
  326.         // https://stackoverflow.com/questions/7572640/how-do-i-know-if-two-vectors-are-near-parallel
  327.         float s = 1.0f / ((*this).magnitude() * v.magnitude());
  328.         if (((*this) * v) * s > 1 - 0.0000001f)
  329.             return true;
  330.         else
  331.             return false;
  332.     }
  333.     bool isParallel(const Vec3& v, const float& epsilon)
  334.     {
  335.         float s = 1.0f / ((*this).magnitude() * v.magnitude());
  336.         if (((*this) * v) * s > 1 - epsilon)
  337.             return true;
  338.         else
  339.             return false;
  340.     }
  341.     bool isParallelUnit(const Vec3& v)
  342.     {
  343.         if (((*this) * v) > 1 - 0.0000001f)
  344.             return true;
  345.         else
  346.             return false;
  347.     }
  348.     bool isParallelUnit(const Vec3& v, const float& epsilon)
  349.     {
  350.         if (((*this) * v) > 1 - epsilon)
  351.             return true;
  352.         else
  353.             return false;
  354.     }
  355.     static bool isParallel(const Vec3& a, const Vec3& b)
  356.     {
  357.         float s = 1.0f / (a.magnitude() * b.magnitude());
  358.         if ((a * b) * s > 1 - 0.0000001f)
  359.             return true;
  360.         else
  361.             return false;
  362.     }
  363.     static bool isParallel(const Vec3& a, const Vec3& b, const float& epsilon)
  364.     {
  365.         float s = 1.0f / (a.magnitude() * b.magnitude());
  366.         if ((a * b) * s > 1 - epsilon)
  367.             return true;
  368.         else
  369.             return false;
  370.     }
  371.     static bool isParallelUnit(const Vec3& a, const Vec3& b)
  372.     {
  373.         if ((a * b) > 1 - 0.0000001f)
  374.             return true;
  375.         else
  376.             return false;
  377.     }
  378.     static bool isParallelUnit(const Vec3& a, const Vec3& b, const float& epsilon)
  379.     {
  380.         if ((a * b) > 1 - epsilon)
  381.             return true;
  382.         else
  383.             return false;
  384.     }
  385.     bool isAntiparallel(const Vec3& v)
  386.     {
  387.         float s = 1.0f / ((*this).magnitude() * v.magnitude());
  388.         if (((*this) * v) * s < 0.0000001f - 1)
  389.             return true;
  390.         else
  391.             return false;
  392.     }
  393.     bool isAntiparallel(const Vec3& v, const float& epsilon)
  394.     {
  395.         float s = 1.0f / ((*this).magnitude() * v.magnitude());
  396.         if (((*this) * v) * s < epsilon - 1)
  397.             return true;
  398.         else
  399.             return false;
  400.     }
  401.     bool isAntiparallelUnit(const Vec3& v)
  402.     {
  403.         if (((*this) * v) < 0.0000001f - 1)
  404.             return true;
  405.         else
  406.             return false;
  407.     }
  408.     bool isAntiparallelUnit(const Vec3& v, const float& epsilon)
  409.     {
  410.         if (((*this) * v) < epsilon - 1)
  411.             return true;
  412.         else
  413.             return false;
  414.     }
  415.     static bool isAntiparallel(const Vec3& a, const Vec3& b)
  416.     {
  417.         float s = 1.0f / (a.magnitude() * b.magnitude());
  418.         if ((a * b) * s < 0.0000001f - 1)
  419.             return true;
  420.         else
  421.             return false;
  422.     }
  423.     static bool isAntiparallel(const Vec3& a, const Vec3& b, const float& epsilon)
  424.     {
  425.         float s = 1.0f / (a.magnitude() * b.magnitude());
  426.         if ((a * b) * s < epsilon - 1)
  427.             return true;
  428.         else
  429.             return false;
  430.     }
  431.     static bool isAntiparallelUnit(const Vec3& a, const Vec3& b)
  432.     {
  433.         if (a * b < 0.0000001f - 1)
  434.             return true;
  435.         else
  436.             return false;
  437.     }
  438.     static bool isAntiparallelUnit(const Vec3& a, const Vec3& b, const float& epsilon)
  439.     {
  440.         if (a * b < epsilon - 1)
  441.             return true;
  442.         else
  443.             return false;
  444.     }
  445.     bool isColinear(const Vec3& v)
  446.     {
  447.         float dot = ((*this) * v) / ((*this).magnitude() * v.magnitude());
  448.         if (dot > 1 - 0.0000001f)
  449.             return true;
  450.         else if (dot < 0.0000001f - 1)
  451.             return true;
  452.         else
  453.             return false;
  454.     }
  455.     bool isColinear(const Vec3& v, const float& epsilon)
  456.     {
  457.         float dot = ((*this) * v) / ((*this).magnitude() * v.magnitude());
  458.         if (dot > 1 - epsilon)
  459.             return true;
  460.         else if (dot < epsilon - 1)
  461.             return true;
  462.         else
  463.             return false;
  464.     }
  465.     bool isColinearUnit(const Vec3& v)
  466.     {
  467.         float dot = ((*this) * v);
  468.         if (dot > 1 - 0.0000001f)
  469.             return true;
  470.         else if (dot < 0.0000001f - 1)
  471.             return true;
  472.         else
  473.             return false;
  474.     }
  475.     bool isColinearUnit(const Vec3& v, const float& epsilon)
  476.     {
  477.         float dot = ((*this) * v);
  478.         if (dot > 1 - epsilon)
  479.             return true;
  480.         else if (dot < epsilon - 1)
  481.             return true;
  482.         else
  483.             return false;
  484.     }
  485.     static bool isColinear(const Vec3& a, const Vec3& b)
  486.     {
  487.         float dot = (a * b) / (a.magnitude() * b.magnitude());
  488.         if (dot > 1 - 0.0000001f)
  489.             return true;
  490.         else if (dot < 0.0000001f - 1)
  491.             return true;
  492.         else
  493.             return false;
  494.     }
  495.     static bool isColinear(const Vec3& a, const Vec3& b, const float& epsilon)
  496.     {
  497.         float dot = (a * b) / (a.magnitude() * b.magnitude());
  498.         if (dot > 1 - epsilon)
  499.             return true;
  500.         else if (dot < epsilon - 1)
  501.             return true;
  502.         else
  503.             return false;
  504.     }
  505.     static bool isColinearUnit(const Vec3& a, const Vec3& b)
  506.     {
  507.         float dot = (a * b);
  508.         if (dot > 1 - 0.0000001f)
  509.             return true;
  510.         else if (dot < 0.0000001f - 1)
  511.             return true;
  512.         else
  513.             return false;
  514.     }
  515.     static bool isColinearUnit(const Vec3& a, const Vec3& b, const float& epsilon)
  516.     {
  517.         float dot = (a * b);
  518.         if (dot > 1 - epsilon)
  519.             return true;
  520.         else if (dot < epsilon - 1)
  521.             return true;
  522.         else
  523.             return false;
  524.     }
  525.     bool isOrthogonal(const Vec3& v)
  526.     {
  527.         float s = 1.0f / ((*this).magnitude() * v.magnitude());
  528.         return abs(((*this) * v) * s) < 0.0000001f ? true : false;
  529.     }
  530.     bool isOrthogonal(const Vec3& v, const float& epsilon)
  531.     {
  532.         float s = 1.0f / ((*this).magnitude() * v.magnitude());
  533.         return abs(((*this) * v) * s) < epsilon ? true : false;
  534.     }
  535.     bool isOrthogonalUnit(const Vec3& v)
  536.     {
  537.         return abs((*this) * v) < 0.0000001f ? true : false;
  538.     }
  539.     bool isOrthogonalUnit(const Vec3& v, const float& epsilon)
  540.     {
  541.         return abs((*this) * v) < epsilon ? true : false;
  542.     }
  543.     static bool isOrthogonal(const Vec3& a, const Vec3& b)
  544.     {
  545.         float s = 1.0f / (a.magnitude() * b.magnitude());
  546.         return abs((a * b) * s) < 0.0000001f ? true : false;
  547.     }
  548.     static bool isOrthogonal(const Vec3& a, const Vec3& b, const float& epsilon)
  549.     {
  550.         float s = 1.0f / (a.magnitude() * b.magnitude());
  551.         return abs((a * b) * s) < epsilon ? true : false;
  552.     }
  553.     static bool isOrthogonalUnit(const Vec3& a, const Vec3& b)
  554.     {
  555.         return abs(a * b) < 0.0000001f ? true : false;
  556.     }
  557.     static bool isOrthogonalUnit(const Vec3& a, const Vec3& b, const float& epsilon)
  558.     {
  559.         return abs(a * b) < epsilon ? true : false;
  560.     }
  561. };
  562.  
  563. #endif // VEC3_H
Advertisement
Add Comment
Please, Sign In to add comment