diff --git a/include/Vector3.h b/include/Vector3.h index 7001f90..8d50cd0 100644 --- a/include/Vector3.h +++ b/include/Vector3.h @@ -5,27 +5,29 @@ #ifndef VECTOR3_H #define VECTOR3_H -extern "C" { - /// - /// 3-dimensional Vector representation - /// - /// This is a C-style implementation - /// This uses the right-handed coordinate system. - typedef struct Vec3 { - /// - /// The right axis of the vector - /// - float x; - /// - /// The upward axis of the vector - /// - float y; - /// - /// The forward axis of the vector - /// - float z; +#include "Vector2.h" - } Vec3; +extern "C" { +/// +/// 3-dimensional Vector representation +/// +/// This is a C-style implementation +/// This uses the right-handed coordinate system. +typedef struct Vec3 { + /// + /// The right axis of the vector + /// + float x; + /// + /// The upward axis of the vector + /// + float y; + /// + /// The forward axis of the vector + /// + float z; + +} Vec3; } /// @@ -34,220 +36,228 @@ extern "C" { /// This uses the right-handed coordinate system. struct Vector3 : Vec3 { public: - /// - /// Create a new 3-dimensinal zero vector - /// - Vector3(); - /// - /// Create a new 3-dimensional vector - /// - /// x axis value - /// y axis value - /// z axis value - Vector3(float x, float y, float z); - /// - /// Create a vector from C-style Vec3 - /// - /// The C-style Vec - Vector3(Vec3 v); - ~Vector3(); + /// + /// Create a new 3-dimensinal zero vector + /// + Vector3(); + /// + /// Create a new 3-dimensional vector + /// + /// x axis value + /// y axis value + /// z axis value + Vector3(float x, float y, float z); + /// + /// Create a vector from C-style Vec3 + /// + /// The C-style Vec + Vector3(Vec3 v); + ~Vector3(); - /// - /// A vector with zero for all axis - /// - const static Vector3 zero; - /// - /// A vector with one for all axis - /// - const static Vector3 one; - /// - /// A vector with values (1, 0, 0) - /// - const static Vector3 right; - /// - /// A vector3 with values (-1, 0, 0) - /// - const static Vector3 left; - /// - /// A vector with values (0, 1, 0) - /// - const static Vector3 up; - /// - /// A vector with values (0, -1, 0) - /// - const static Vector3 down; - /// - /// A vector with values (0, 0, 1) - /// - const static Vector3 forward; - /// - /// A vector with values (0, 0, -1) - /// - const static Vector3 back; + /// + /// A vector with zero for all axis + /// + const static Vector3 zero; + /// + /// A vector with one for all axis + /// + const static Vector3 one; + /// + /// A vector with values (1, 0, 0) + /// + const static Vector3 right; + /// + /// A vector3 with values (-1, 0, 0) + /// + const static Vector3 left; + /// + /// A vector with values (0, 1, 0) + /// + const static Vector3 up; + /// + /// A vector with values (0, -1, 0) + /// + const static Vector3 down; + /// + /// A vector with values (0, 0, 1) + /// + const static Vector3 forward; + /// + /// A vector with values (0, 0, -1) + /// + const static Vector3 back; - /// - /// The length of a vector - /// - /// The vector for which you need the length - /// The length of the given vector - static float Magnitude(const Vector3& vector); - /// - /// The length of this vector - /// - /// The length of this vector - float magnitude() const; - /// - /// The squared length of a vector - /// - /// The vector for which you need the squared length - /// The squatred length - /// The squared length is computationally simpler than the real length. - /// Think of Pythagoras A^2 + B^2 = C^2. - /// This leaves out the calculation of the squared root of C. - static float SqrMagnitude(const Vector3& vector); - /// - /// The squared length of this vector - /// - /// The squared length - /// The squared length is computationally simpler than the real length. - /// Think of Pythagoras A^2 + B^2 = C^2. - /// This leaves out the calculation of the squared root of C. - float sqrMagnitude() const; - /// - /// Connvert a vector to a length of 1 - /// - /// The vector to convert - /// The vector with length 1 - static Vector3 Normalize(Vector3 vector); - /// - /// Convert the vector to a length of a - /// - /// The vector with length 1 - Vector3 normalized() const; + /// + /// The length of a vector + /// + /// The vector for which you need the length + /// The length of the given vector + static float Magnitude(const Vector3 &vector); + /// + /// The length of this vector + /// + /// The length of this vector + float magnitude() const; + /// + /// The squared length of a vector + /// + /// The vector for which you need the squared + /// length The squatred length The squared length + /// is computationally simpler than the real length. Think of Pythagoras A^2 + + /// B^2 = C^2. This leaves out the calculation of the squared root of C. + static float SqrMagnitude(const Vector3 &vector); + /// + /// The squared length of this vector + /// + /// The squared length + /// The squared length is computationally simpler than the real length. + /// Think of Pythagoras A^2 + B^2 = C^2. + /// This leaves out the calculation of the squared root of C. + float sqrMagnitude() const; + /// + /// Connvert a vector to a length of 1 + /// + /// The vector to convert + /// The vector with length 1 + static Vector3 Normalize(Vector3 vector); + /// + /// Convert the vector to a length of a + /// + /// The vector with length 1 + Vector3 normalized() const; - /// - /// Negate the vector - /// - /// The negated vector - /// This will result in a vector pointing in the opposite direction - Vector3 operator -(); - /// - /// Subtract a vector from this vector - /// - /// The vector to subtract from this vector - /// The result of the subtraction - Vector3 operator -(const Vector3& vector) const; + /// + /// Negate the vector + /// + /// The negated vector + /// This will result in a vector pointing in the opposite direction + Vector3 operator-(); + /// + /// Subtract a vector from this vector + /// + /// The vector to subtract from this vector + /// The result of the subtraction + Vector3 operator-(const Vector3 &vector) const; - /// - /// Add another vector to this vector - /// - /// The vector to add - /// The result of adding the vector - Vector3 operator +(const Vector3& vector2) const; + /// + /// Add another vector to this vector + /// + /// The vector to add + /// The result of adding the vector + Vector3 operator+(const Vector3 &vector2) const; - /// - /// Scale a vector using another vector - /// - /// The vector to scale - /// A vector with scaling factors - /// The scaled vector - /// Each component of the vector v1 will be multiplied with the - /// component from the scaling vector v2. - static Vector3 Scale(const Vector3& vector1, const Vector3& vector2); - /// - /// Scale a vector uniformly up - /// - /// The scaling factor - /// The scaled vector - /// Each component of the vector will be multipled with the same factor. - Vector3 operator *(float factor) const; - /// - /// Scale a vector uniformy down - /// - /// The scaling factor - /// The scaled vector - /// Each componet of the vector will be divided by the same factor. - Vector3 operator /(const float& factor); + /// + /// Scale a vector using another vector + /// + /// The vector to scale + /// A vector with scaling factors + /// The scaled vector + /// Each component of the vector v1 will be multiplied with the + /// component from the scaling vector v2. + static Vector3 Scale(const Vector3 &vector1, const Vector3 &vector2); + /// + /// Scale a vector uniformly up + /// + /// The scaling factor + /// The scaled vector + /// Each component of the vector will be multipled with the same factor. + Vector3 operator*(float factor) const; + /// + /// Scale a vector uniformy down + /// + /// The scaling factor + /// The scaled vector + /// Each componet of the vector will be divided by the same factor. + Vector3 operator/(const float &factor); - /// - /// The dot product of two vectors - /// - /// The first vector - /// The second vector - /// The dot product of the two vectors - static float Dot(const Vector3& vector1, const Vector3& vector2); + /// + /// The dot product of two vectors + /// + /// The first vector + /// The second vector + /// The dot product of the two vectors + static float Dot(const Vector3 &vector1, const Vector3 &vector2); - /// - /// Check is this vector is equal to the given vector - /// - /// The vector to check against - /// True if it is identical to the given vector - /// Note this uses float comparison to check equality which - /// may have strange effects. Equality on float should be avoided. - bool operator ==(const Vector3& vector); + /// + /// Check is this vector is equal to the given vector + /// + /// The vector to check against + /// True if it is identical to the given vector + /// Note this uses float comparison to check equality which + /// may have strange effects. Equality on float should be avoided. + bool operator==(const Vector3 &vector); - /// - /// The distance between two vectors - /// - /// The first vector - /// The second vectors - /// The distance between the two vectors - static float Distance(const Vector3& vector1, const Vector3& vector2); + /// + /// The distance between two vectors + /// + /// The first vector + /// The second vectors + /// The distance between the two vectors + static float Distance(const Vector3 &vector1, const Vector3 &vector2); - /// - /// The cross product of two vectors - /// - /// The first vector - /// The second vector - /// The cross product of the two vectors - static Vector3 Cross(const Vector3& vector1, const Vector3& vector2); + /// + /// The cross product of two vectors + /// + /// The first vector + /// The second vector + /// The cross product of the two vectors + static Vector3 Cross(const Vector3 &vector1, const Vector3 &vector2); - /// - /// Project a vector on another vector - /// - /// The vector to project - /// The normal vector to project on - /// The projected vector - static Vector3 Project(Vector3 vector, Vector3 onNormal); - /// - /// Projects a vector onto a plane defined by a normal orthogonal to the plane. - /// - /// The vector to project - /// The normal of the plane to project on - /// - static Vector3 ProjectOnPlane(Vector3 vector, Vector3 planeNormal); + /// + /// Project a vector on another vector + /// + /// The vector to project + /// The normal vector to project on + /// The projected vector + static Vector3 Project(Vector3 vector, Vector3 onNormal); + /// + /// Projects a vector onto a plane defined by a normal orthogonal to the + /// plane. + /// + /// The vector to project + /// The normal of the plane to project on + /// + static Vector3 ProjectOnPlane(Vector3 vector, Vector3 planeNormal); - /// - /// Calculate the angle between two vectors - /// - /// The first vector - /// The second vector - /// - /// This reterns an unsigned angle which is the shortest distance - /// between the two vectors. Use Vector3::SignedAngle if a - /// signed angle is needed. - static float Angle(Vector3 vector1, Vector3 vector2); + /// + /// Projects a vector onto the horizontal plane. + /// + /// The vector to project + /// A 2D carthesian vector with the coordinates in the horizontal + /// plane. + static Vector2 ProjectHorizontalPlane(Vector3 vector); - /// - /// Calculate the angle between two vectors rotation around an axis. - /// - /// The starting vector - /// The ending vector - /// The axis to rotate around - /// The signed angle - static float SignedAngle(Vector3 from, Vector3 to, Vector3 axis); + /// + /// Calculate the angle between two vectors + /// + /// The first vector + /// The second vector + /// + /// This reterns an unsigned angle which is the shortest distance + /// between the two vectors. Use Vector3::SignedAngle if a + /// signed angle is needed. + static float Angle(Vector3 vector1, Vector3 vector2); + /// + /// Calculate the angle between two vectors rotation around an axis. + /// + /// The starting vector + /// The ending vector + /// The axis to rotate around + /// The signed angle + static float SignedAngle(Vector3 from, Vector3 to, Vector3 axis); - /// - /// Lerp between two vectors - /// - /// The from vector - /// The to vector - /// The interpolation distance (0..1) - /// The lerped vector - /// The factor f is unclamped. Value 0 matches the *from* vector, Value 1 matches the *to* vector - /// Value -1 is *from* vector minus the difference between *from* and *to* etc. - static Vector3 Lerp(Vector3 from, Vector3 to, float f); + /// + /// Lerp between two vectors + /// + /// The from vector + /// The to vector + /// The interpolation distance (0..1) + /// The lerped vector + /// The factor f is unclamped. Value 0 matches the *from* vector, Value 1 + /// matches the *to* vector Value -1 is *from* vector minus the difference + /// between *from* and *to* etc. + static Vector3 Lerp(Vector3 from, Vector3 to, float f); }; #endif \ No newline at end of file diff --git a/src/Vector3.cpp b/src/Vector3.cpp index 69e0414..5ba27ac 100644 --- a/src/Vector3.cpp +++ b/src/Vector3.cpp @@ -2,33 +2,32 @@ // License, v. 2.0.If a copy of the MPL was not distributed with this // file, You can obtain one at https ://mozilla.org/MPL/2.0/. -#include #include "Vector3.h" +#include const float Deg2Rad = 0.0174532924F; const float Rad2Deg = 57.29578F; const float epsilon = 1E-05f; Vector3::Vector3() { - x = 0; - y = 0; - z = 0; + x = 0; + y = 0; + z = 0; } Vector3::Vector3(float _x, float _y, float _z) { - x = _x; - y = _y; - z = _z; + x = _x; + y = _y; + z = _z; } Vector3::Vector3(Vec3 v) { - x = v.x; - y = v.y; - z = v.z; + x = v.x; + y = v.y; + z = v.z; } -Vector3::~Vector3() { -} +Vector3::~Vector3() {} const Vector3 Vector3::zero = Vector3(0, 0, 0); const Vector3 Vector3::one = Vector3(1, 1, 1); @@ -39,130 +38,129 @@ const Vector3 Vector3::down = Vector3(0, -1, 0); const Vector3 Vector3::forward = Vector3(0, 0, 1); const Vector3 Vector3::back = Vector3(0, 0, -1); -float Vector3::Magnitude(const Vector3& a) { - return sqrtf(a.x * a.x + a.y * a.y + a.z * a.z); -} -float Vector3::magnitude() const { - return (float)sqrtf(x * x + y * y + z * z); +float Vector3::Magnitude(const Vector3 &a) { + return sqrtf(a.x * a.x + a.y * a.y + a.z * a.z); } +float Vector3::magnitude() const { return (float)sqrtf(x * x + y * y + z * z); } -float Vector3::SqrMagnitude(const Vector3& a) { - return a.x * a.x + a.y * a.y + a.z * a.z; -} -float Vector3::sqrMagnitude() const { - return(x * x + y * y + z * z); +float Vector3::SqrMagnitude(const Vector3 &a) { + return a.x * a.x + a.y * a.y + a.z * a.z; } +float Vector3::sqrMagnitude() const { return (x * x + y * y + z * z); } Vector3 Vector3::Normalize(Vector3 v) { - float num = Vector3::Magnitude(v); - Vector3 result = Vector3::zero; - if (num > epsilon) { - result = v / num; - } - return result; + float num = Vector3::Magnitude(v); + Vector3 result = Vector3::zero; + if (num > epsilon) { + result = v / num; + } + return result; } Vector3 Vector3::normalized() const { - float num = this->magnitude(); - Vector3 result = Vector3::zero; - if (num > epsilon) { - result = ((Vector3)*this) / num; - } - return result; + float num = this->magnitude(); + Vector3 result = Vector3::zero; + if (num > epsilon) { + result = ((Vector3) * this) / num; + } + return result; } -Vector3 Vector3::operator -(const Vector3& v2) const { - return Vector3(this->x - v2.x, this->y - v2.y, this->z - v2.z); +Vector3 Vector3::operator-(const Vector3 &v2) const { + return Vector3(this->x - v2.x, this->y - v2.y, this->z - v2.z); } -Vector3 Vector3::operator -() { - return Vector3(-this->x, -this->y, -this->z); +Vector3 Vector3::operator-() { return Vector3(-this->x, -this->y, -this->z); } + +Vector3 Vector3::operator+(const Vector3 &v2) const { + return Vector3(this->x + v2.x, this->y + v2.y, this->z + v2.z); } -Vector3 Vector3::operator +(const Vector3& v2) const { - return Vector3(this->x + v2.x, this->y + v2.y, this->z + v2.z); +Vector3 Vector3::Scale(const Vector3 &p1, const Vector3 &p2) { + return Vector3(p1.x * p2.x, p1.y * p2.y, p1.z * p2.z); } -Vector3 Vector3::Scale(const Vector3& p1, const Vector3& p2) { - return Vector3(p1.x * p2.x, p1.y * p2.y, p1.z * p2.z); +Vector3 Vector3::operator*(float f) const { + return Vector3(this->x * f, this->y * f, this->z * f); } -Vector3 Vector3::operator *(float f) const { - return Vector3(this->x * f, this->y * f, this->z * f); +Vector3 Vector3::operator/(const float &d) { + return Vector3(this->x / d, this->y / d, this->z / d); } -Vector3 Vector3::operator/(const float& d) { - return Vector3(this->x / d, this->y / d, this->z / d); +float Vector3::Dot(const Vector3 &v1, const Vector3 &v2) { + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; } -float Vector3::Dot(const Vector3& v1, const Vector3& v2) { - return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; +bool Vector3::operator==(const Vector3 &v) { + return (this->x == v.x && this->y == v.y && this->z == v.z); } -bool Vector3::operator==(const Vector3& v) { - return (this->x == v.x && this->y == v.y && this->z == v.z); +float Vector3::Distance(const Vector3 &p1, const Vector3 &p2) { + return Magnitude(p1 - p2); } -float Vector3::Distance(const Vector3& p1, const Vector3& p2) { - return Magnitude(p1 - p2); -} - -Vector3 Vector3::Cross(const Vector3& v1, const Vector3& v2) { - return Vector3(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x); +Vector3 Vector3::Cross(const Vector3 &v1, const Vector3 &v2) { + return Vector3(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, + v1.x * v2.y - v1.y * v2.x); } Vector3 Vector3::Project(Vector3 vector, Vector3 onNormal) { - float sqrMagnitude = Dot(onNormal, onNormal); - if (sqrMagnitude < epsilon) - return Vector3::zero; - else { - float dot = Dot(vector, onNormal); - Vector3 r = onNormal * dot / sqrMagnitude; - return r; - } + float sqrMagnitude = Dot(onNormal, onNormal); + if (sqrMagnitude < epsilon) + return Vector3::zero; + else { + float dot = Dot(vector, onNormal); + Vector3 r = onNormal * dot / sqrMagnitude; + return r; + } } Vector3 Vector3::ProjectOnPlane(Vector3 vector, Vector3 planeNormal) { - Vector3 r = vector - Project(vector, planeNormal); - return r; + Vector3 r = vector - Project(vector, planeNormal); + return r; +} + +Vector2 Vector3::ProjectHorizontalPlane(Vector3 vector) { + Vector2 r = Vector2(vector.x, vector.z); + return r; } float clamp(float x, float lower, float upper) { - float lowerClamp = fmaxf(x, lower); - float upperClamp = fminf(upper, lowerClamp); - return upperClamp; + float lowerClamp = fmaxf(x, lower); + float upperClamp = fminf(upper, lowerClamp); + return upperClamp; } float Vector3::Angle(Vector3 from, Vector3 to) { - float denominator = sqrtf(from.sqrMagnitude() * to.sqrMagnitude()); - if (denominator < epsilon) - return 0; + float denominator = sqrtf(from.sqrMagnitude() * to.sqrMagnitude()); + if (denominator < epsilon) + return 0; - float dot = Vector3::Dot(from, to); - float fraction = dot / denominator; - if (isnan(fraction)) - return fraction; // short cut to returning NaN universally + float dot = Vector3::Dot(from, to); + float fraction = dot / denominator; + if (isnan(fraction)) + return fraction; // short cut to returning NaN universally - float cdot = clamp(fraction, -1.0, 1.0); - float r = ((float)acos(cdot)) * Rad2Deg; - return r; + float cdot = clamp(fraction, -1.0, 1.0); + float r = ((float)acos(cdot)) * Rad2Deg; + return r; } float Vector3::SignedAngle(Vector3 from, Vector3 to, Vector3 axis) { - // angle in [0,180] - float angle = Vector3::Angle(from, to); + // angle in [0,180] + float angle = Vector3::Angle(from, to); - Vector3 cross = Vector3::Cross(from, to); - float b = Vector3::Dot(axis, cross); - float signd = b < 0 ? -1.0F : (b > 0 ? 1.0F : 0.0F); + Vector3 cross = Vector3::Cross(from, to); + float b = Vector3::Dot(axis, cross); + float signd = b < 0 ? -1.0F : (b > 0 ? 1.0F : 0.0F); - // angle in [-179,180] - float signed_angle = angle * signd; - - return signed_angle; + // angle in [-179,180] + float signed_angle = angle * signd; + return signed_angle; } Vector3 Vector3::Lerp(Vector3 from, Vector3 to, float f) { - Vector3 v = from + (to - from) * f; - return v; + Vector3 v = from + (to - from) * f; + return v; } \ No newline at end of file