Extend AngleOf support

This commit is contained in:
Pascal Serrarens 2024-07-31 11:44:23 +02:00
parent c70c079efc
commit b81b77b1c9
16 changed files with 441 additions and 268 deletions

View File

@ -3,8 +3,8 @@
// file, You can obtain one at https ://mozilla.org/MPL/2.0/. // file, You can obtain one at https ://mozilla.org/MPL/2.0/.
#include "Angle.h" #include "Angle.h"
#include "FloatSingle.h"
#include <math.h> #include <math.h>
#include "FloatSingle.h"
/* /*
const float Angle::Rad2Deg = 57.29578F; const float Angle::Rad2Deg = 57.29578F;
@ -73,17 +73,29 @@ float Angle::SineRuleAngle(float a, float beta, float b) {
*/ */
//---------------------- //----------------------
template <> AngleOf<float> AngleOf<float>::pi = 3.1415927410125732421875F; template <>
AngleOf<float>::AngleOf(float angle) : value(angle) {}
template <> AngleOf<float> AngleOf<float>::Rad2Deg = 360.0f / (pi * 2); template <>
template <> AngleOf<float> AngleOf<float>::Deg2Rad = (pi * 2) / 360.0f; AngleOf<float>::operator float() const {
return value;
}
template <>
AngleOf<float> AngleOf<float>::pi = 3.1415927410125732421875F;
template <>
AngleOf<float> AngleOf<float>::Rad2Deg = 360.0f / (pi * 2);
template <>
AngleOf<float> AngleOf<float>::Deg2Rad = (pi * 2) / 360.0f;
template <> template <>
bool Passer::LinearAlgebra::AngleOf<float>::operator==(AngleOf<float> a) { bool Passer::LinearAlgebra::AngleOf<float>::operator==(AngleOf<float> a) {
return (float)*this == (float)a; return (float)*this == (float)a;
} }
template <> AngleOf<float> AngleOf<float>::Normalize(AngleOf<float> angle) { template <>
AngleOf<float> AngleOf<float>::Normalize(AngleOf<float> angle) {
float angleValue = angle; float angleValue = angle;
if (!isfinite(angleValue)) if (!isfinite(angleValue))
return angleValue; return angleValue;
@ -96,7 +108,8 @@ template <> AngleOf<float> AngleOf<float>::Normalize(AngleOf<float> angle) {
} }
template <> template <>
AngleOf<float> AngleOf<float>::Clamp(AngleOf<float> angle, AngleOf<float> min, AngleOf<float> AngleOf<float>::Clamp(AngleOf<float> angle,
AngleOf<float> min,
AngleOf<float> max) { AngleOf<float> max) {
float normalizedAngle = Normalize(angle); float normalizedAngle = Normalize(angle);
float r = Float::Clamp(normalizedAngle, min, max); float r = Float::Clamp(normalizedAngle, min, max);
@ -120,7 +133,8 @@ AngleOf<float> AngleOf<float>::MoveTowards(AngleOf<float> fromAngle,
} }
template <> template <>
AngleOf<float> AngleOf<float>::CosineRuleSide(float a, float b, AngleOf<float> AngleOf<float>::CosineRuleSide(float a,
float b,
AngleOf<float> gamma) { AngleOf<float> gamma) {
float a2 = a * a; float a2 = a * a;
float b2 = b * b; float b2 = b * b;
@ -150,7 +164,8 @@ AngleOf<float> AngleOf<float>::CosineRuleAngle(float a, float b, float c) {
} }
template <> template <>
AngleOf<float> AngleOf<float>::SineRuleAngle(float a, AngleOf<float> beta, AngleOf<float> AngleOf<float>::SineRuleAngle(float a,
AngleOf<float> beta,
float b) { float b) {
float alpha = asin(a * sin(beta * Angle::Deg2Rad) / b); float alpha = asin(a * sin(beta * Angle::Deg2Rad) / b);
return alpha; return alpha;

24
Angle.h
View File

@ -8,11 +8,15 @@
namespace Passer { namespace Passer {
namespace LinearAlgebra { namespace LinearAlgebra {
template <typename T> class AngleOf { template <typename T>
public: class AngleOf {
AngleOf(){}; public:
AngleOf(T v) : value(v) {} AngleOf() {};
operator T() const { return value; } AngleOf(float f);
// AngleOf(T v) : value(v) {}
// operator T() const; // { return value; }
operator float() const;
inline T GetBinary() const { return this->value; }
static AngleOf<T> Rad2Deg; static AngleOf<T> Rad2Deg;
static AngleOf<T> Deg2Rad; static AngleOf<T> Deg2Rad;
@ -27,7 +31,8 @@ public:
AngleOf<T> r = Normalize(b - a); AngleOf<T> r = Normalize(b - a);
return r; return r;
}; };
static AngleOf<T> MoveTowards(AngleOf<T> fromAngle, AngleOf<T> toAngle, static AngleOf<T> MoveTowards(AngleOf<T> fromAngle,
AngleOf<T> toAngle,
AngleOf<T> maxAngle); AngleOf<T> maxAngle);
static AngleOf<T> CosineRuleSide(float a, float b, AngleOf<T> gamma); static AngleOf<T> CosineRuleSide(float a, float b, AngleOf<T> gamma);
@ -35,14 +40,15 @@ public:
static AngleOf<T> SineRuleAngle(float a, AngleOf<T> beta, float c); static AngleOf<T> SineRuleAngle(float a, AngleOf<T> beta, float c);
private: private:
T value; T value;
}; };
using Angle = AngleOf<float>; using Angle = AngleOf<float>;
// using Angle = AngleOf<signed short>;
} // namespace LinearAlgebra } // namespace LinearAlgebra
} // namespace Passer } // namespace Passer
using namespace Passer::LinearAlgebra; using namespace Passer::LinearAlgebra;
#endif #endif

74
Angle16.cpp Normal file
View File

@ -0,0 +1,74 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// 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 <math.h>
#include "Angle.h"
template <>
AngleOf<signed short>::AngleOf(float angle) {
if (!isfinite(angle)) {
value = 0;
return;
}
// map float [-180..180) to integer [-32768..32767]
this->value = (signed short)((angle / 360.0F) * 65536.0F);
}
template <>
AngleOf<signed short>::operator float() const {
float f = ((this->value * 180) / 32768.0F);
return f;
}
// This should not exist...
// template <>
// AngleOf<signed short> AngleOf<signed short>::pi = 3.1415927410125732421875F;
// template <>
// AngleOf<signed short> AngleOf<signed short>::Rad2Deg = 360.0f / (pi * 2);
// template <>
// AngleOf<signed short> AngleOf<signed short>::Deg2Rad = (pi * 2) / 360.0f;
// template <>
// AngleOf<signed short> AngleOf<signed short>::Normalize(
// AngleOf<signed short> angle) {
// return angle;
// }
// Not correct!!! just for syntactical compilation ATM
template <>
AngleOf<signed short> AngleOf<signed short>::CosineRuleSide(
float a,
float b,
AngleOf<signed short> gamma) {
float a2 = a * a;
float b2 = b * b;
float d = a2 + b2 - 2 * a * b * cos(gamma * AngleOf<float>::Deg2Rad);
// Catch edge cases where float inacuracies lead tot nans
if (d < 0)
return 0;
float c = sqrtf(d);
return c;
}
// Not correct!!! just for syntactical compilation ATM
template <>
AngleOf<signed short> AngleOf<signed short>::CosineRuleAngle(float a,
float b,
float c) {
float a2 = a * a;
float b2 = b * b;
float c2 = c * c;
float d = (a2 + b2 - c2) / (2 * a * b);
// Catch edge cases where float inacuracies lead tot nans
if (d >= 1)
return 0;
if (d <= -1)
return 180;
float gamma = acos(d) * Angle::Rad2Deg;
return gamma;
}

View File

@ -1,28 +1,28 @@
#include "AngleUsing.h" // #include "AngleUsing.h"
#include "Angle.h"
#include <math.h> #include <math.h>
#include "Angle.h"
namespace Passer { namespace Passer {
namespace LinearAlgebra { namespace LinearAlgebra {
typedef AngleUsing<signed short> Angle16; typedef AngleOf<signed short> Angle16;
template <> Angle16::AngleUsing(float angle) { // template <> Angle16::AngleOf(float angle) {
if (!isfinite(angle)) { // if (!isfinite(angle)) {
value = 0; // value = 0;
return; // return;
} // }
// map float [-180..180) to integer [-32768..32767] // // map float [-180..180) to integer [-32768..32767]
this->value = (signed short)((angle / 360.0F) * 65536.0F); // this->value = (signed short)((angle / 360.0F) * 65536.0F);
} // }
template <> float Angle16::ToFloat() const { // template <> float Angle16::ToFloat() const {
float f = ((this->value * 180) / 32768.0F); // float f = ((this->value * 180) / 32768.0F);
return f; // return f;
} // }
} // namespace LinearAlgebra } // namespace LinearAlgebra
} // namespace Passer } // namespace Passer
using namespace Passer::LinearAlgebra; using namespace Passer::LinearAlgebra;

View File

@ -1,28 +1,30 @@
#include "AngleUsing.h" // #include "AngleUsing.h"
#include "Angle.h"
#include <math.h> #include <math.h>
#include "Angle.h"
namespace Passer { namespace Passer {
namespace LinearAlgebra { namespace LinearAlgebra {
typedef AngleUsing<signed long> Angle32; typedef AngleOf<signed long> Angle32;
template <> Angle32::AngleUsing(float angle) { // template <>
if (!isfinite(angle)) { // Angle32::AngleOf(float angle) {
value = 0; // if (!isfinite(angle)) {
return; // value = 0;
} // return;
// }
// map float [-180..180) to integer [-2147483648..2147483647] // // map float [-180..180) to integer [-2147483648..2147483647]
this->value = (signed long)((angle / 360.0F) * 4294967295.0F); // this->value = (signed long)((angle / 360.0F) * 4294967295.0F);
} // }
template <> float Angle32::ToFloat() const { // template <>
float f = ((this->value * 180) / 2147483648.0F); // float Angle32::ToFloat() const {
return f; // float f = ((this->value * 180) / 2147483648.0F);
} // return f;
// }
} // namespace LinearAlgebra } // namespace LinearAlgebra
} // namespace Passer } // namespace Passer
using namespace Passer::LinearAlgebra; using namespace Passer::LinearAlgebra;

24
Angle8.cpp Normal file
View File

@ -0,0 +1,24 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// 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 <math.h>
#include "Angle.h"
template <>
AngleOf<signed char>::AngleOf(float angle) {
if (!isfinite(angle)) {
value = 0;
return;
}
// map float [-180..180) to integer [-128..127]
float f = angle / 360.0F;
this->value = (signed char)(f * 256.0F);
}
template <>
AngleOf<signed char>::operator float() const {
float f = (this->value * 180) / 128.0F;
return f;
}

View File

@ -1,29 +1,29 @@
#include "AngleUsing.h" // #include "AngleUsing.h"
#include "Angle.h"
#include <math.h> #include <math.h>
#include "Angle.h"
namespace Passer { namespace Passer {
namespace LinearAlgebra { namespace LinearAlgebra {
typedef AngleUsing<signed char> Angle8; typedef AngleOf<signed char> Angle8;
template <> Angle8::AngleUsing(float angle) { // template <> Angle8::AngleOf(float angle) {
if (!isfinite(angle)) { // if (!isfinite(angle)) {
value = 0; // value = 0;
return; // return;
} // }
// map float [-180..180) to integer [-128..127] // // map float [-180..180) to integer [-128..127]
float f = angle / 360.0F; // float f = angle / 360.0F;
this->value = (signed char)(f * 256.0F); // this->value = (signed char)(f * 256.0F);
} // }
template <> float Angle8::ToFloat() const { // template <> float Angle8::ToFloat() const {
float f = (this->value * 180) / 128.0F; // float f = (this->value * 180) / 128.0F;
return f; // return f;
} // }
} // namespace LinearAlgebra } // namespace LinearAlgebra
} // namespace Passer } // namespace Passer
using namespace Passer::LinearAlgebra; using namespace Passer::LinearAlgebra;

View File

@ -1,3 +1,4 @@
/*
#ifndef DISCRETEANGLE_H #ifndef DISCRETEANGLE_H
#define DISCRETEANGLE_H #define DISCRETEANGLE_H
@ -9,8 +10,9 @@ namespace LinearAlgebra {
// A fixed angle between (-180..180] // A fixed angle between (-180..180]
template <typename T> class AngleUsing { template <typename T>
public: class AngleUsing {
public:
AngleUsing(T sourceValue) { this->value = sourceValue; } AngleUsing(T sourceValue) { this->value = sourceValue; }
AngleUsing(float f); AngleUsing(float f);
float ToFloat() const; float ToFloat() const;
@ -42,8 +44,9 @@ public:
T value; T value;
}; };
} // namespace LinearAlgebra } // namespace LinearAlgebra
} // namespace Passer } // namespace Passer
using namespace Passer::LinearAlgebra; using namespace Passer::LinearAlgebra;
#endif #endif
*/

View File

@ -37,11 +37,11 @@ const Polar Polar::back = Polar(1.0, 180.0f);
const Polar Polar::right = Polar(1.0, 90.0f); const Polar Polar::right = Polar(1.0, 90.0f);
const Polar Polar::left = Polar(1.0, -90.0f); const Polar Polar::left = Polar(1.0, -90.0f);
bool Polar::operator==(const Polar &v) const { bool Polar::operator==(const Polar& v) const {
return (this->distance == v.distance && this->angle == v.angle); return (this->distance == v.distance && this->angle == v.angle);
} }
Polar Polar::Normalize(const Polar &v) { Polar Polar::Normalize(const Polar& v) {
Polar r = Polar(1, v.angle); Polar r = Polar(1, v.angle);
return r; return r;
} }
@ -55,15 +55,15 @@ Polar Polar::operator-() const {
return v; return v;
} }
Polar Polar::operator-(const Polar &v) const { Polar Polar::operator-(const Polar& v) const {
Polar r = -v; Polar r = -v;
return *this + r; return *this + r;
} }
Polar Polar::operator-=(const Polar &v) { Polar Polar::operator-=(const Polar& v) {
*this = *this - v; *this = *this - v;
return *this; return *this;
} }
Polar Polar::operator+(const Polar &v) const { Polar Polar::operator+(const Polar& v) const {
if (v.distance == 0) if (v.distance == 0)
return Polar(this->distance, this->angle); return Polar(this->distance, this->angle);
if (this->distance == 0.0f) if (this->distance == 0.0f)
@ -89,39 +89,39 @@ Polar Polar::operator+(const Polar &v) const {
Polar vector = Polar(newDistance, newAngle); Polar vector = Polar(newDistance, newAngle);
return vector; return vector;
} }
Polar Polar::operator+=(const Polar &v) { Polar Polar::operator+=(const Polar& v) {
*this = *this + v; *this = *this + v;
return *this; return *this;
} }
Polar Passer::LinearAlgebra::operator*(const Polar &v, float f) { // Polar Passer::LinearAlgebra::operator*(const Polar &v, float f) {
return Polar(v.distance * f, v.angle); // return Polar(v.distance * f, v.angle);
} // }
Polar Passer::LinearAlgebra::operator*(float f, const Polar &v) { // Polar Passer::LinearAlgebra::operator*(float f, const Polar &v) {
return Polar(v.distance * f, v.angle); // return Polar(v.distance * f, v.angle);
} // }
Polar Polar::operator*=(float f) { Polar Polar::operator*=(float f) {
this->distance *= f; this->distance *= f;
return *this; return *this;
} }
Polar Passer::LinearAlgebra::operator/(const Polar &v, float f) { // Polar Passer::LinearAlgebra::operator/(const Polar& v, float f) {
return Polar(v.distance / f, v.angle); // return Polar(v.distance / f, v.angle);
} // }
Polar Passer::LinearAlgebra::operator/(float f, const Polar &v) { // Polar Passer::LinearAlgebra::operator/(float f, const Polar& v) {
return Polar(v.distance / f, v.angle); // return Polar(v.distance / f, v.angle);
} // }
Polar Polar::operator/=(float f) { Polar Polar::operator/=(float f) {
this->distance /= f; this->distance /= f;
return *this; return *this;
} }
float Polar::Distance(const Polar &v1, const Polar &v2) { float Polar::Distance(const Polar& v1, const Polar& v2) {
float d = Angle::CosineRuleSide(v1.distance, v2.distance, float d = Angle::CosineRuleSide(v1.distance, v2.distance,
(float)v2.angle - (float)v1.angle); (float)v2.angle - (float)v1.angle);
return d; return d;
} }
Polar Polar::Rotate(const Polar &v, Angle angle) { Polar Polar::Rotate(const Polar& v, Angle angle) {
Angle a = Angle::Normalize(v.angle + angle); Angle a = Angle::Normalize(v.angle + angle);
Polar r = Polar(v.distance, a); Polar r = Polar(v.distance, a);
return r; return r;

40
Polar.h
View File

@ -17,7 +17,7 @@ struct Spherical;
/// @details This will use the polar coordinate system consisting of a angle /// @details This will use the polar coordinate system consisting of a angle
/// from a reference direction and a distance. /// from a reference direction and a distance.
struct Polar { struct Polar {
public: public:
/// @brief The distance in meters /// @brief The distance in meters
/// @remark The distance shall never be negative /// @remark The distance shall never be negative
float distance; float distance;
@ -59,12 +59,12 @@ public:
/// @return true: if it is identical to the given vector /// @return true: if it is identical to the given vector
/// @note This uses float comparison to check equality which may have /// @note This uses float comparison to check equality which may have
/// strange effects. Equality on floats should be avoided. /// strange effects. Equality on floats should be avoided.
bool operator==(const Polar &v) const; bool operator==(const Polar& v) const;
/// @brief The vector length /// @brief The vector length
/// @param v The vector for which you need the length /// @param v The vector for which you need the length
/// @return The vector length; /// @return The vector length;
inline static float Magnitude(const Polar &v) { return v.distance; } inline static float Magnitude(const Polar& v) { return v.distance; }
/// @brief The vector length /// @brief The vector length
/// @return The vector length /// @return The vector length
inline float magnitude() const { return this->distance; } inline float magnitude() const { return this->distance; }
@ -72,7 +72,7 @@ public:
/// @brief Convert the vector to a length of 1 /// @brief Convert the vector to a length of 1
/// @param v The vector to convert /// @param v The vector to convert
/// @return The vector normalized to a length of 1 /// @return The vector normalized to a length of 1
static Polar Normalize(const Polar &v); static Polar Normalize(const Polar& v);
/// @brief Convert the vector to a length of a /// @brief Convert the vector to a length of a
/// @return The vector normalized to a length of 1 /// @return The vector normalized to a length of 1
Polar normalized() const; Polar normalized() const;
@ -85,45 +85,53 @@ public:
/// @brief Subtract a polar vector from this vector /// @brief Subtract a polar vector from this vector
/// @param v The vector to subtract /// @param v The vector to subtract
/// @return The result of the subtraction /// @return The result of the subtraction
Polar operator-(const Polar &v) const; Polar operator-(const Polar& v) const;
Polar operator-=(const Polar &v); Polar operator-=(const Polar& v);
/// @brief Add a polar vector to this vector /// @brief Add a polar vector to this vector
/// @param v The vector to add /// @param v The vector to add
/// @return The result of the addition /// @return The result of the addition
Polar operator+(const Polar &v) const; Polar operator+(const Polar& v) const;
Polar operator+=(const Polar &v); Polar operator+=(const Polar& v);
/// @brief Scale the vector uniformly up /// @brief Scale the vector uniformly up
/// @param f The scaling factor /// @param f The scaling factor
/// @return The scaled vector /// @return The scaled vector
/// @remark This operation will scale the distance of the vector. The angle /// @remark This operation will scale the distance of the vector. The angle
/// will be unaffected. /// will be unaffected.
friend Polar operator*(const Polar &v, float f); friend Polar operator*(const Polar& v, float f) {
friend Polar operator*(float f, const Polar &v); return Polar(v.distance * f, v.angle);
}
friend Polar operator*(float f, const Polar& v) {
return Polar(f * v.distance, v.angle);
}
Polar operator*=(float f); Polar operator*=(float f);
/// @brief Scale the vector uniformly down /// @brief Scale the vector uniformly down
/// @param f The scaling factor /// @param f The scaling factor
/// @return The scaled factor /// @return The scaled factor
/// @remark This operation will scale the distance of the vector. The angle /// @remark This operation will scale the distance of the vector. The angle
/// will be unaffected. /// will be unaffected.
friend Polar operator/(const Polar &v, float f); friend Polar operator/(const Polar& v, float f) {
friend Polar operator/(float f, const Polar &v); return Polar(v.distance / f, v.angle);
}
friend Polar operator/(float f, const Polar& v) {
return Polar(f / v.distance, v.angle);
}
Polar operator/=(float f); Polar operator/=(float f);
/// @brief The distance between two vectors /// @brief The distance between two vectors
/// @param v1 The first vector /// @param v1 The first vector
/// @param v2 The second vector /// @param v2 The second vector
/// @return The distance between the two vectors /// @return The distance between the two vectors
static float Distance(const Polar &v1, const Polar &v2); static float Distance(const Polar& v1, const Polar& v2);
/// @brief Rotate a vector /// @brief Rotate a vector
/// @param v The vector to rotate /// @param v The vector to rotate
/// @param a The angle in degreesto rotate /// @param a The angle in degreesto rotate
/// @return The rotated vector /// @return The rotated vector
static Polar Rotate(const Polar &v, Angle a); static Polar Rotate(const Polar& v, Angle a);
}; };
} // namespace LinearAlgebra } // namespace LinearAlgebra
} // namespace Passer } // namespace Passer
using namespace Passer::LinearAlgebra; using namespace Passer::LinearAlgebra;
#include "Spherical.h" #include "Spherical.h"

View File

@ -17,7 +17,8 @@ Spherical::Spherical(Polar polar) {
this->verticalAngle = 0.0f; this->verticalAngle = 0.0f;
} }
Spherical::Spherical(float distance, Angle horizontalAngle, Spherical::Spherical(float distance,
Angle horizontalAngle,
Angle verticalAngle) { Angle verticalAngle) {
if (distance < 0) { if (distance < 0) {
this->distance = -distance; this->distance = -distance;
@ -50,13 +51,13 @@ const Spherical Spherical::left = Spherical(1.0f, -90.0f, 0.0f);
const Spherical Spherical::up = Spherical(1.0f, 0.0f, 90.0f); const Spherical Spherical::up = Spherical(1.0f, 0.0f, 90.0f);
const Spherical Spherical::down = Spherical(1.0f, 0.0f, -90.0f); const Spherical Spherical::down = Spherical(1.0f, 0.0f, -90.0f);
bool Spherical::operator==(const Spherical &v) const { bool Spherical::operator==(const Spherical& v) const {
return (this->distance == v.distance && return (this->distance == v.distance &&
this->horizontalAngle == v.horizontalAngle && this->horizontalAngle == v.horizontalAngle &&
this->verticalAngle == v.verticalAngle); this->verticalAngle == v.verticalAngle);
} }
Spherical Spherical::Normalize(const Spherical &v) { Spherical Spherical::Normalize(const Spherical& v) {
Spherical r = Spherical(1, v.horizontalAngle, v.verticalAngle); Spherical r = Spherical(1, v.horizontalAngle, v.verticalAngle);
return r; return r;
} }
@ -71,7 +72,7 @@ Spherical Spherical::operator-() const {
return v; return v;
} }
Spherical Spherical::operator-(const Spherical &s2) const { Spherical Spherical::operator-(const Spherical& s2) const {
// let's do it the easy way... // let's do it the easy way...
Vector3 v1 = Vector3(*this); Vector3 v1 = Vector3(*this);
Vector3 v2 = Vector3(s2); Vector3 v2 = Vector3(s2);
@ -79,12 +80,12 @@ Spherical Spherical::operator-(const Spherical &s2) const {
Spherical r = Spherical(v); Spherical r = Spherical(v);
return r; return r;
} }
Spherical Spherical::operator-=(const Spherical &v) { Spherical Spherical::operator-=(const Spherical& v) {
*this = *this - v; *this = *this - v;
return *this; return *this;
} }
Spherical Spherical::operator+(const Spherical &s2) const { Spherical Spherical::operator+(const Spherical& s2) const {
// let's do it the easy way... // let's do it the easy way...
Vector3 v1 = Vector3(*this); Vector3 v1 = Vector3(*this);
Vector3 v2 = Vector3(s2); Vector3 v2 = Vector3(s2);
@ -138,28 +139,28 @@ Spherical Spherical::operator+(const Spherical &s2) const {
Spherical v = Spherical(newDistance, newHorizontalAngle, newVerticalAngle); Spherical v = Spherical(newDistance, newHorizontalAngle, newVerticalAngle);
*/ */
} }
Spherical Spherical::operator+=(const Spherical &v) { Spherical Spherical::operator+=(const Spherical& v) {
*this = *this + v; *this = *this + v;
return *this; return *this;
} }
Spherical Passer::LinearAlgebra::operator*(const Spherical &v, float f) { // Spherical Passer::LinearAlgebra::operator*(const Spherical &v, float f) {
return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle); // return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle);
} // }
Spherical Passer::LinearAlgebra::operator*(float f, const Spherical &v) { // Spherical Passer::LinearAlgebra::operator*(float f, const Spherical &v) {
return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle); // return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle);
} // }
Spherical Spherical::operator*=(float f) { Spherical Spherical::operator*=(float f) {
this->distance *= f; this->distance *= f;
return *this; return *this;
} }
Spherical Passer::LinearAlgebra::operator/(const Spherical &v, float f) { // Spherical Passer::LinearAlgebra::operator/(const Spherical &v, float f) {
return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle); // return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle);
} // }
Spherical Passer::LinearAlgebra::operator/(float f, const Spherical &v) { // Spherical Passer::LinearAlgebra::operator/(float f, const Spherical &v) {
return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle); // return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle);
} // }
Spherical Spherical::operator/=(float f) { Spherical Spherical::operator/=(float f) {
this->distance /= f; this->distance /= f;
return *this; return *this;
@ -183,12 +184,11 @@ Spherical Spherical::operator/=(float f) {
const float epsilon = 1E-05f; const float epsilon = 1E-05f;
const float Rad2Deg = 57.29578F; const float Rad2Deg = 57.29578F;
Angle Spherical::AngleBetween(const Spherical &v1, const Spherical &v2) { Angle Spherical::AngleBetween(const Spherical& v1, const Spherical& v2) {
// float denominator = sqrtf(v1_3.sqrMagnitude() * v2_3.sqrMagnitude()); // float denominator = sqrtf(v1_3.sqrMagnitude() * v2_3.sqrMagnitude());
float denominator = float denominator =
v1.distance * v2.distance; // sqrtf(v1.distance * v1.distance * v1.distance * v2.distance; // sqrtf(v1.distance * v1.distance *
// v2.distance * v2.distance); // v2.distance * v2.distance);
if (denominator < epsilon) if (denominator < epsilon)
return 0; return 0;
@ -197,24 +197,25 @@ Angle Spherical::AngleBetween(const Spherical &v1, const Spherical &v2) {
float dot = Vector3::Dot(v1_3, v2_3); float dot = Vector3::Dot(v1_3, v2_3);
float fraction = dot / denominator; float fraction = dot / denominator;
if (isnan(fraction)) if (isnan(fraction))
return fraction; // short cut to returning NaN universally return fraction; // short cut to returning NaN universally
float cdot = Float::Clamp(fraction, -1.0, 1.0); float cdot = Float::Clamp(fraction, -1.0, 1.0);
float r = ((float)acos(cdot)) * Rad2Deg; float r = ((float)acos(cdot)) * Rad2Deg;
return r; return r;
} }
Spherical Spherical::Rotate(const Spherical &v, Angle horizontalAngle, Spherical Spherical::Rotate(const Spherical& v,
Angle horizontalAngle,
Angle verticalAngle) { Angle verticalAngle) {
Spherical r = Spherical(v.distance, v.horizontalAngle + horizontalAngle, Spherical r = Spherical(v.distance, v.horizontalAngle + horizontalAngle,
v.verticalAngle + verticalAngle); v.verticalAngle + verticalAngle);
return r; return r;
} }
Spherical Spherical::RotateHorizontal(const Spherical &v, Angle a) { Spherical Spherical::RotateHorizontal(const Spherical& v, Angle a) {
Spherical r = Spherical(v.distance, v.horizontalAngle + a, v.verticalAngle); Spherical r = Spherical(v.distance, v.horizontalAngle + a, v.verticalAngle);
return r; return r;
} }
Spherical Spherical::RotateVertical(const Spherical &v, Angle a) { Spherical Spherical::RotateVertical(const Spherical& v, Angle a) {
Spherical r = Spherical(v.distance, v.horizontalAngle, v.verticalAngle + a); Spherical r = Spherical(v.distance, v.horizontalAngle, v.verticalAngle + a);
return r; return r;
} }

View File

@ -19,7 +19,7 @@ struct Vector3;
/// reference direction. The reference direction is typically thought of /// reference direction. The reference direction is typically thought of
/// as a forward direction. /// as a forward direction.
struct Spherical { struct Spherical {
public: public:
/// @brief The distance in meters /// @brief The distance in meters
/// @remark The distance should never be negative /// @remark The distance should never be negative
float distance; float distance;
@ -66,12 +66,12 @@ public:
/// @return true: if it is identical to the given vector /// @return true: if it is identical to the given vector
/// @note This uses float comparison to check equality which may have strange /// @note This uses float comparison to check equality which may have strange
/// effects. Equality on floats should be avoided. /// effects. Equality on floats should be avoided.
bool operator==(const Spherical &v) const; bool operator==(const Spherical& v) const;
/// @brief The vector length /// @brief The vector length
/// @param v The vector for which you need the length /// @param v The vector for which you need the length
/// @return The vector length; /// @return The vector length;
inline static float Magnitude(const Spherical &v) { return v.distance; } inline static float Magnitude(const Spherical& v) { return v.distance; }
/// @brief The vector length /// @brief The vector length
/// @return The vector length /// @return The vector length
inline float magnitude() const { return this->distance; } inline float magnitude() const { return this->distance; }
@ -79,7 +79,7 @@ public:
/// @brief Convert the vector to a length of 1 /// @brief Convert the vector to a length of 1
/// @param v The vector to convert /// @param v The vector to convert
/// @return The vector normalized to a length of 1 /// @return The vector normalized to a length of 1
static Spherical Normalize(const Spherical &v); static Spherical Normalize(const Spherical& v);
/// @brief Convert the vector to a length of a /// @brief Convert the vector to a length of a
/// @return The vector normalized to a length of 1 /// @return The vector normalized to a length of 1
Spherical normalized() const; Spherical normalized() const;
@ -93,29 +93,39 @@ public:
/// @brief Subtract a spherical vector from this vector /// @brief Subtract a spherical vector from this vector
/// @param v The vector to subtract /// @param v The vector to subtract
/// @return The result of the subtraction /// @return The result of the subtraction
Spherical operator-(const Spherical &v) const; Spherical operator-(const Spherical& v) const;
Spherical operator-=(const Spherical &v); Spherical operator-=(const Spherical& v);
/// @brief Add a spherical vector to this vector /// @brief Add a spherical vector to this vector
/// @param v The vector to add /// @param v The vector to add
/// @return The result of the addition /// @return The result of the addition
Spherical operator+(const Spherical &v) const; Spherical operator+(const Spherical& v) const;
Spherical operator+=(const Spherical &v); Spherical operator+=(const Spherical& v);
/// @brief Scale the vector uniformly up /// @brief Scale the vector uniformly up
/// @param f The scaling factor /// @param f The scaling factor
/// @return The scaled vector /// @return The scaled vector
/// @remark This operation will scale the distance of the vector. The angle /// @remark This operation will scale the distance of the vector. The angle
/// will be unaffected. /// will be unaffected.
friend Spherical operator*(const Spherical &v, float f); friend Spherical operator*(const Spherical& v, float f) {
friend Spherical operator*(float f, const Spherical &v); return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle);
}
friend Spherical operator*(float f, const Spherical& v) {
return Spherical(v.distance * f, v.horizontalAngle,
v.verticalAngle); // not correct, should be f * v.distance
}
Spherical operator*=(float f); Spherical operator*=(float f);
/// @brief Scale the vector uniformly down /// @brief Scale the vector uniformly down
/// @param f The scaling factor /// @param f The scaling factor
/// @return The scaled factor /// @return The scaled factor
/// @remark This operation will scale the distance of the vector. The angle /// @remark This operation will scale the distance of the vector. The angle
/// will be unaffected. /// will be unaffected.
friend Spherical operator/(const Spherical &v, float f); friend Spherical operator/(const Spherical& v, float f) {
friend Spherical operator/(float f, const Spherical &v); return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle);
}
friend Spherical operator/(float f, const Spherical& v) {
return Spherical(v.distance / f, v.horizontalAngle,
v.verticalAngle); // not correct, should be f / v.distance
}
Spherical operator/=(float f); Spherical operator/=(float f);
/// <summary> /// <summary>
@ -126,16 +136,17 @@ public:
/// <returns>The distance between the two vectors</returns> /// <returns>The distance between the two vectors</returns>
// static float Distance(const Spherical &s1, const Spherical &s2); // static float Distance(const Spherical &s1, const Spherical &s2);
static Angle AngleBetween(const Spherical &v1, const Spherical &v2); static Angle AngleBetween(const Spherical& v1, const Spherical& v2);
static Spherical Rotate(const Spherical &v, Angle horizontalAngle, static Spherical Rotate(const Spherical& v,
Angle horizontalAngle,
Angle verticalAngle); Angle verticalAngle);
static Spherical RotateHorizontal(const Spherical &v, Angle angle); static Spherical RotateHorizontal(const Spherical& v, Angle angle);
static Spherical RotateVertical(const Spherical &v, Angle angle); static Spherical RotateVertical(const Spherical& v, Angle angle);
}; };
} // namespace LinearAlgebra } // namespace LinearAlgebra
} // namespace Passer } // namespace Passer
using namespace Passer::LinearAlgebra; using namespace Passer::LinearAlgebra;
#include "Vector3.h" #include "Vector3.h"

View File

@ -26,8 +26,8 @@ Vector2::Vector2(float _x, float _y) {
// y = v.y; // y = v.y;
// } // }
Vector2::Vector2(Vector3 v) { Vector2::Vector2(Vector3 v) {
x = v.Right(); // x; x = v.Right(); // x;
y = v.Forward(); // z; y = v.Forward(); // z;
} }
Vector2::Vector2(Polar p) { Vector2::Vector2(Polar p) {
float horizontalRad = p.angle * Angle::Deg2Rad; float horizontalRad = p.angle * Angle::Deg2Rad;
@ -49,18 +49,24 @@ const Vector2 Vector2::down = Vector2(0, -1);
const Vector2 Vector2::forward = Vector2(0, 1); const Vector2 Vector2::forward = Vector2(0, 1);
const Vector2 Vector2::back = Vector2(0, -1); const Vector2 Vector2::back = Vector2(0, -1);
bool Vector2::operator==(const Vector2 &v) { bool Vector2::operator==(const Vector2& v) {
return (this->x == v.x && this->y == v.y); return (this->x == v.x && this->y == v.y);
} }
float Vector2::Magnitude(const Vector2 &v) { float Vector2::Magnitude(const Vector2& v) {
return sqrtf(v.x * v.x + v.y * v.y); return sqrtf(v.x * v.x + v.y * v.y);
} }
float Vector2::magnitude() const { return (float)sqrtf(x * x + y * y); } float Vector2::magnitude() const {
float Vector2::SqrMagnitude(const Vector2 &v) { return v.x * v.x + v.y * v.y; } return (float)sqrtf(x * x + y * y);
float Vector2::sqrMagnitude() const { return (x * x + y * y); } }
float Vector2::SqrMagnitude(const Vector2& v) {
return v.x * v.x + v.y * v.y;
}
float Vector2::sqrMagnitude() const {
return (x * x + y * y);
}
Vector2 Vector2::Normalize(const Vector2 &v) { Vector2 Vector2::Normalize(const Vector2& v) {
float num = Vector2::Magnitude(v); float num = Vector2::Magnitude(v);
Vector2 result = Vector2::zero; Vector2 result = Vector2::zero;
if (num > Float::epsilon) { if (num > Float::epsilon) {
@ -77,63 +83,65 @@ Vector2 Vector2::normalized() const {
return result; return result;
} }
Vector2 Vector2::operator-() { return Vector2(-this->x, -this->y); } Vector2 Vector2::operator-() {
return Vector2(-this->x, -this->y);
}
Vector2 Vector2::operator-(const Vector2 &v) const { Vector2 Vector2::operator-(const Vector2& v) const {
return Vector2(this->x - v.x, this->y - v.y); return Vector2(this->x - v.x, this->y - v.y);
} }
Vector2 Vector2::operator-=(const Vector2 &v) { Vector2 Vector2::operator-=(const Vector2& v) {
this->x -= v.x; this->x -= v.x;
this->y -= v.y; this->y -= v.y;
return *this; return *this;
} }
Vector2 Vector2::operator+(const Vector2 &v) const { Vector2 Vector2::operator+(const Vector2& v) const {
return Vector2(this->x + v.x, this->y + v.y); return Vector2(this->x + v.x, this->y + v.y);
} }
Vector2 Vector2::operator+=(const Vector2 &v) { Vector2 Vector2::operator+=(const Vector2& v) {
this->x += v.x; this->x += v.x;
this->y += v.y; this->y += v.y;
return *this; return *this;
} }
Vector2 Vector2::Scale(const Vector2 &v1, const Vector2 &v2) { Vector2 Vector2::Scale(const Vector2& v1, const Vector2& v2) {
return Vector2(v1.x * v2.x, v1.y * v2.y); return Vector2(v1.x * v2.x, v1.y * v2.y);
} }
Vector2 Passer::LinearAlgebra::operator*(const Vector2 &v, float f) { // Vector2 Passer::LinearAlgebra::operator*(const Vector2 &v, float f) {
return Vector2(v.x * f, v.y * f); // return Vector2(v.x * f, v.y * f);
} // }
Vector2 Passer::LinearAlgebra::operator*(float f, const Vector2 &v) { // Vector2 Passer::LinearAlgebra::operator*(float f, const Vector2 &v) {
return Vector2(v.x * f, v.y * f); // return Vector2(v.x * f, v.y * f);
} // }
Vector2 Vector2::operator*=(float f) { Vector2 Vector2::operator*=(float f) {
this->x *= f; this->x *= f;
this->y *= f; this->y *= f;
return *this; return *this;
} }
Vector2 Passer::LinearAlgebra::operator/(const Vector2 &v, float f) { // Vector2 Passer::LinearAlgebra::operator/(const Vector2 &v, float f) {
return Vector2(v.x / f, v.y / f); // return Vector2(v.x / f, v.y / f);
} // }
Vector2 Passer::LinearAlgebra::operator/(float f, const Vector2 &v) { // Vector2 Passer::LinearAlgebra::operator/(float f, const Vector2 &v) {
return Vector2(v.x / f, v.y / f); // return Vector2(v.x / f, v.y / f);
} // }
Vector2 Vector2::operator/=(float f) { Vector2 Vector2::operator/=(float f) {
this->x /= f; this->x /= f;
this->y /= f; this->y /= f;
return *this; return *this;
} }
float Vector2::Dot(const Vector2 &v1, const Vector2 &v2) { float Vector2::Dot(const Vector2& v1, const Vector2& v2) {
return v1.x * v2.x + v1.y * v2.y; return v1.x * v2.x + v1.y * v2.y;
} }
float Vector2::Distance(const Vector2 &v1, const Vector2 &v2) { float Vector2::Distance(const Vector2& v1, const Vector2& v2) {
return Magnitude(v1 - v2); return Magnitude(v1 - v2);
} }
float Vector2::Angle(const Vector2 &v1, const Vector2 &v2) { float Vector2::Angle(const Vector2& v1, const Vector2& v2) {
return (float)fabs(SignedAngle(v1, v2)); return (float)fabs(SignedAngle(v1, v2));
} }
float Vector2::SignedAngle(const Vector2 &v1, const Vector2 &v2) { float Vector2::SignedAngle(const Vector2& v1, const Vector2& v2) {
float sqrMagFrom = v1.sqrMagnitude(); float sqrMagFrom = v1.sqrMagnitude();
float sqrMagTo = v2.sqrMagnitude(); float sqrMagTo = v2.sqrMagnitude();
@ -151,11 +159,11 @@ float Vector2::SignedAngle(const Vector2 &v1, const Vector2 &v2) {
return -(angleTo - angleFrom) * Angle::Rad2Deg; return -(angleTo - angleFrom) * Angle::Rad2Deg;
} }
Vector2 Vector2::Rotate(const Vector2 &v, Passer::LinearAlgebra::Angle a) { Vector2 Vector2::Rotate(const Vector2& v, Passer::LinearAlgebra::Angle a) {
float angleRad = a * Angle::Deg2Rad; float angleRad = a * Angle::Deg2Rad;
#if defined(AVR) #if defined(AVR)
float sinValue = sin(angleRad); float sinValue = sin(angleRad);
float cosValue = cos(angleRad); // * Angle::Deg2Rad); float cosValue = cos(angleRad); // * Angle::Deg2Rad);
#else #else
float sinValue = (float)sinf(angleRad); float sinValue = (float)sinf(angleRad);
float cosValue = (float)cosf(angleRad); float cosValue = (float)cosf(angleRad);
@ -168,7 +176,7 @@ Vector2 Vector2::Rotate(const Vector2 &v, Passer::LinearAlgebra::Angle a) {
return r; return r;
} }
Vector2 Vector2::Lerp(const Vector2 &v1, const Vector2 &v2, float f) { Vector2 Vector2::Lerp(const Vector2& v1, const Vector2& v2, float f) {
Vector2 v = v1 + (v2 - v1) * f; Vector2 v = v1 + (v2 - v1) * f;
return v; return v;
} }

View File

@ -38,7 +38,7 @@ struct Polar;
struct Vector2 : Vec2 { struct Vector2 : Vec2 {
friend struct Vec2; friend struct Vec2;
public: public:
/// @brief A new 2-dimensional zero vector /// @brief A new 2-dimensional zero vector
Vector2(); Vector2();
/// @brief A new 2-dimensional vector /// @brief A new 2-dimensional vector
@ -80,12 +80,12 @@ public:
/// @return true if it is identical to the given vector /// @return true if it is identical to the given vector
/// @note This uses float comparison to check equality which may have strange /// @note This uses float comparison to check equality which may have strange
/// effects. Equality on floats should be avoided. /// effects. Equality on floats should be avoided.
bool operator==(const Vector2 &v); bool operator==(const Vector2& v);
/// @brief The vector length /// @brief The vector length
/// @param v The vector for which you need the length /// @param v The vector for which you need the length
/// @return The vector length /// @return The vector length
static float Magnitude(const Vector2 &v); static float Magnitude(const Vector2& v);
/// @brief The vector length /// @brief The vector length
/// @return The vector length /// @return The vector length
float magnitude() const; float magnitude() const;
@ -95,7 +95,7 @@ public:
/// @remark The squared length is computationally simpler than the real /// @remark The squared length is computationally simpler than the real
/// length. Think of Pythagoras A^2 + B^2 = C^2. This prevents the calculation /// length. Think of Pythagoras A^2 + B^2 = C^2. This prevents the calculation
/// of the squared root of C. /// of the squared root of C.
static float SqrMagnitude(const Vector2 &v); static float SqrMagnitude(const Vector2& v);
/// @brief The squared vector length /// @brief The squared vector length
/// @return The squared vector length /// @return The squared vector length
/// @remark The squared length is computationally simpler than the real /// @remark The squared length is computationally simpler than the real
@ -106,7 +106,7 @@ public:
/// @brief Convert the vector to a length of 1 /// @brief Convert the vector to a length of 1
/// @param v The vector to convert /// @param v The vector to convert
/// @return The vector normalized to a length of 1 /// @return The vector normalized to a length of 1
static Vector2 Normalize(const Vector2 &v); static Vector2 Normalize(const Vector2& v);
/// @brief Convert the vector to a length 1 /// @brief Convert the vector to a length 1
/// @return The vector normalized to a length of 1 /// @return The vector normalized to a length of 1
Vector2 normalized() const; Vector2 normalized() const;
@ -118,13 +118,13 @@ public:
/// @brief Subtract a vector from this vector /// @brief Subtract a vector from this vector
/// @param v The vector to subtract from this vector /// @param v The vector to subtract from this vector
/// @return The result of the subtraction /// @return The result of the subtraction
Vector2 operator-(const Vector2 &v) const; Vector2 operator-(const Vector2& v) const;
Vector2 operator-=(const Vector2 &v); Vector2 operator-=(const Vector2& v);
/// @brief Add a vector to this vector /// @brief Add a vector to this vector
/// @param v The vector to add to this vector /// @param v The vector to add to this vector
/// @return The result of the addition /// @return The result of the addition
Vector2 operator+(const Vector2 &v) const; Vector2 operator+(const Vector2& v) const;
Vector2 operator+=(const Vector2 &v); Vector2 operator+=(const Vector2& v);
/// @brief Scale the vector using another vector /// @brief Scale the vector using another vector
/// @param v1 The vector to scale /// @param v1 The vector to scale
@ -132,34 +132,39 @@ public:
/// @return The scaled vector /// @return The scaled vector
/// @remark Each component of the vector v1 will be multiplied with the /// @remark Each component of the vector v1 will be multiplied with the
/// matching component from the scaling vector v2. /// matching component from the scaling vector v2.
static Vector2 Scale(const Vector2 &v1, const Vector2 &v2); static Vector2 Scale(const Vector2& v1, const Vector2& v2);
/// @brief Scale the vector uniformly up /// @brief Scale the vector uniformly up
/// @param f The scaling factor /// @param f The scaling factor
/// @return The scaled vector /// @return The scaled vector
/// @remark Each component of the vector will be multipled with the same /// @remark Each component of the vector will be multipled with the same
/// factor f. /// factor f.
friend Vector2 operator*(const Vector2 &v, float f); friend Vector2 operator*(const Vector2& v, float f) {
friend Vector2 operator*(float f, const Vector2 &v); return Vector2(v.x * f, v.y * f);
}
friend Vector2 operator*(float f, const Vector2& v) {
return Vector2(v.x * f, v.y * f);
// return Vector2(f * v.x, f * v.y);
}
Vector2 operator*=(float f); Vector2 operator*=(float f);
/// @brief Scale the vector uniformly down /// @brief Scale the vector uniformly down
/// @param f The scaling factor /// @param f The scaling factor
/// @return The scaled vector /// @return The scaled vector
/// @remark Each componet of the vector will be divided by the same factor. /// @remark Each componet of the vector will be divided by the same factor.
friend Vector2 operator/(const Vector2 &v, float f); friend Vector2 operator/(const Vector2& v, float f);
friend Vector2 operator/(float f, const Vector2 &v); friend Vector2 operator/(float f, const Vector2& v);
Vector2 operator/=(float f); Vector2 operator/=(float f);
/// @brief The dot product of two vectors /// @brief The dot product of two vectors
/// @param v1 The first vector /// @param v1 The first vector
/// @param v2 The second vector /// @param v2 The second vector
/// @return The dot product of the two vectors /// @return The dot product of the two vectors
static float Dot(const Vector2 &v1, const Vector2 &v2); static float Dot(const Vector2& v1, const Vector2& v2);
/// @brief The distance between two vectors /// @brief The distance between two vectors
/// @param v1 The first vector /// @param v1 The first vector
/// @param v2 The second vector /// @param v2 The second vector
/// @return The distance between the two vectors /// @return The distance between the two vectors
static float Distance(const Vector2 &v1, const Vector2 &v2); static float Distance(const Vector2& v1, const Vector2& v2);
/// @brief The angle between two vectors /// @brief The angle between two vectors
/// @param v1 The first vector /// @param v1 The first vector
@ -168,18 +173,18 @@ public:
/// @remark This reterns an unsigned angle which is the shortest distance /// @remark This reterns an unsigned angle which is the shortest distance
/// between the two vectors. Use Vector2::SignedAngle if a signed angle is /// between the two vectors. Use Vector2::SignedAngle if a signed angle is
/// needed. /// needed.
static float Angle(const Vector2 &v1, const Vector2 &v2); static float Angle(const Vector2& v1, const Vector2& v2);
/// @brief The signed angle between two vectors /// @brief The signed angle between two vectors
/// @param v1 The starting vector /// @param v1 The starting vector
/// @param v2 The ending vector /// @param v2 The ending vector
/// @return The signed angle between the two vectors /// @return The signed angle between the two vectors
static float SignedAngle(const Vector2 &v1, const Vector2 &v2); static float SignedAngle(const Vector2& v1, const Vector2& v2);
/// @brief Rotate the vector /// @brief Rotate the vector
/// @param v The vector to rotate /// @param v The vector to rotate
/// @param a The angle in degrees to rotate /// @param a The angle in degrees to rotate
/// @return The rotated vector /// @return The rotated vector
static Vector2 Rotate(const Vector2 &v, Passer::LinearAlgebra::Angle a); static Vector2 Rotate(const Vector2& v, Passer::LinearAlgebra::Angle a);
/// @brief Lerp (linear interpolation) between two vectors /// @brief Lerp (linear interpolation) between two vectors
/// @param v1 The starting vector /// @param v1 The starting vector
@ -189,11 +194,11 @@ public:
/// @remark The factor f is unclamped. Value 0 matches the vector *v1*, Value /// @remark The factor f is unclamped. Value 0 matches the vector *v1*, Value
/// 1 matches vector *v2*. Value -1 is vector *v1* minus the difference /// 1 matches vector *v2*. Value -1 is vector *v1* minus the difference
/// between *v1* and *v2* etc. /// between *v1* and *v2* etc.
static Vector2 Lerp(const Vector2 &v1, const Vector2 &v2, float f); static Vector2 Lerp(const Vector2& v1, const Vector2& v2, float f);
}; };
} // namespace LinearAlgebra } // namespace LinearAlgebra
} // namespace Passer } // namespace Passer
using namespace Passer::LinearAlgebra; using namespace Passer::LinearAlgebra;
#include "Polar.h" #include "Polar.h"

View File

@ -65,17 +65,21 @@ const Vector3 Vector3::back = Vector3(0, 0, -1);
// return Vector3(v.x, 0, v.y); // return Vector3(v.x, 0, v.y);
// } // }
float Vector3::Magnitude(const Vector3 &v) { float Vector3::Magnitude(const Vector3& v) {
return sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); return sqrtf(v.x * v.x + v.y * v.y + v.z * v.z);
} }
float Vector3::magnitude() const { return (float)sqrtf(x * x + y * y + z * z); } float Vector3::magnitude() const {
return (float)sqrtf(x * x + y * y + z * z);
}
float Vector3::SqrMagnitude(const Vector3 &v) { float Vector3::SqrMagnitude(const Vector3& v) {
return v.x * v.x + v.y * v.y + v.z * v.z; return v.x * v.x + v.y * v.y + v.z * v.z;
} }
float Vector3::sqrMagnitude() const { return (x * x + y * y + z * z); } float Vector3::sqrMagnitude() const {
return (x * x + y * y + z * z);
}
Vector3 Vector3::Normalize(const Vector3 &v) { Vector3 Vector3::Normalize(const Vector3& v) {
float num = Vector3::Magnitude(v); float num = Vector3::Magnitude(v);
Vector3 result = Vector3::zero; Vector3 result = Vector3::zero;
if (num > epsilon) { if (num > epsilon) {
@ -96,46 +100,46 @@ Vector3 Vector3::operator-() const {
return Vector3(-this->x, -this->y, -this->z); return Vector3(-this->x, -this->y, -this->z);
} }
Vector3 Vector3::operator-(const Vector3 &v) const { Vector3 Vector3::operator-(const Vector3& v) const {
return Vector3(this->x - v.x, this->y - v.y, this->z - v.z); return Vector3(this->x - v.x, this->y - v.y, this->z - v.z);
} }
Vector3 Vector3::operator-=(const Vector3 &v) { Vector3 Vector3::operator-=(const Vector3& v) {
this->x -= v.x; this->x -= v.x;
this->y -= v.y; this->y -= v.y;
this->z -= v.z; this->z -= v.z;
return *this; return *this;
} }
Vector3 Vector3::operator+(const Vector3 &v) const { Vector3 Vector3::operator+(const Vector3& v) const {
return Vector3(this->x + v.x, this->y + v.y, this->z + v.z); return Vector3(this->x + v.x, this->y + v.y, this->z + v.z);
} }
Vector3 Vector3::operator+=(const Vector3 &v) { Vector3 Vector3::operator+=(const Vector3& v) {
this->x += v.x; this->x += v.x;
this->y += v.y; this->y += v.y;
this->z += v.z; this->z += v.z;
return *this; return *this;
} }
Vector3 Vector3::Scale(const Vector3 &v1, const Vector3 &v2) { Vector3 Vector3::Scale(const Vector3& v1, const Vector3& v2) {
return Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); return Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
} }
Vector3 Passer::LinearAlgebra::operator*(const Vector3 &v, float f) { // Vector3 Passer::LinearAlgebra::operator*(const Vector3 &v, float f) {
return Vector3(v.x * f, v.y * f, v.z * f); // return Vector3(v.x * f, v.y * f, v.z * f);
} // }
Vector3 Passer::LinearAlgebra::operator*(float f, const Vector3 &v) { // Vector3 Passer::LinearAlgebra::operator*(float f, const Vector3 &v) {
return Vector3(v.x * f, v.y * f, v.z * f); // return Vector3(v.x * f, v.y * f, v.z * f);
} // }
Vector3 Vector3::operator*=(float f) { Vector3 Vector3::operator*=(float f) {
this->x *= f; this->x *= f;
this->y *= f; this->y *= f;
this->z *= f; this->z *= f;
return *this; return *this;
} }
Vector3 Passer::LinearAlgebra::operator/(const Vector3 &v, float f) { // Vector3 Passer::LinearAlgebra::operator/(const Vector3 &v, float f) {
return Vector3(v.x / f, v.y / f, v.z / f); // return Vector3(v.x / f, v.y / f, v.z / f);
} // }
Vector3 Passer::LinearAlgebra::operator/(float f, const Vector3 &v) { // Vector3 Passer::LinearAlgebra::operator/(float f, const Vector3 &v) {
return Vector3(v.x / f, v.y / f, v.z / f); // return Vector3(v.x / f, v.y / f, v.z / f);
} // }
Vector3 Vector3::operator/=(float f) { Vector3 Vector3::operator/=(float f) {
this->x /= f; this->x /= f;
this->y /= f; this->y /= f;
@ -143,24 +147,24 @@ Vector3 Vector3::operator/=(float f) {
return *this; return *this;
} }
float Vector3::Dot(const Vector3 &v1, const Vector3 &v2) { float Vector3::Dot(const Vector3& v1, const Vector3& v2) {
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
} }
bool Vector3::operator==(const Vector3 &v) { bool Vector3::operator==(const Vector3& v) {
return (this->x == v.x && this->y == v.y && this->z == v.z); return (this->x == v.x && this->y == v.y && this->z == v.z);
} }
float Vector3::Distance(const Vector3 &v1, const Vector3 &v2) { float Vector3::Distance(const Vector3& v1, const Vector3& v2) {
return Magnitude(v1 - v2); return Magnitude(v1 - v2);
} }
Vector3 Vector3::Cross(const Vector3 &v1, const Vector3 &v2) { 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, 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); v1.x * v2.y - v1.y * v2.x);
} }
Vector3 Vector3::Project(const Vector3 &v, const Vector3 &n) { Vector3 Vector3::Project(const Vector3& v, const Vector3& n) {
float sqrMagnitude = Dot(n, n); float sqrMagnitude = Dot(n, n);
if (sqrMagnitude < epsilon) if (sqrMagnitude < epsilon)
return Vector3::zero; return Vector3::zero;
@ -171,7 +175,7 @@ Vector3 Vector3::Project(const Vector3 &v, const Vector3 &n) {
} }
} }
Vector3 Vector3::ProjectOnPlane(const Vector3 &v, const Vector3 &n) { Vector3 Vector3::ProjectOnPlane(const Vector3& v, const Vector3& n) {
Vector3 r = v - Project(v, n); Vector3 r = v - Project(v, n);
return r; return r;
} }
@ -182,7 +186,7 @@ float clamp(float x, float lower, float upper) {
return upperClamp; return upperClamp;
} }
float Vector3::Angle(const Vector3 &v1, const Vector3 &v2) { float Vector3::Angle(const Vector3& v1, const Vector3& v2) {
float denominator = sqrtf(v1.sqrMagnitude() * v2.sqrMagnitude()); float denominator = sqrtf(v1.sqrMagnitude() * v2.sqrMagnitude());
if (denominator < epsilon) if (denominator < epsilon)
return 0; return 0;
@ -190,15 +194,16 @@ float Vector3::Angle(const Vector3 &v1, const Vector3 &v2) {
float dot = Vector3::Dot(v1, v2); float dot = Vector3::Dot(v1, v2);
float fraction = dot / denominator; float fraction = dot / denominator;
if (isnan(fraction)) if (isnan(fraction))
return fraction; // short cut to returning NaN universally return fraction; // short cut to returning NaN universally
float cdot = clamp(fraction, -1.0, 1.0); float cdot = clamp(fraction, -1.0, 1.0);
float r = ((float)acos(cdot)) * Rad2Deg; float r = ((float)acos(cdot)) * Rad2Deg;
return r; return r;
} }
float Vector3::SignedAngle(const Vector3 &v1, const Vector3 &v2, float Vector3::SignedAngle(const Vector3& v1,
const Vector3 &axis) { const Vector3& v2,
const Vector3& axis) {
// angle in [0,180] // angle in [0,180]
float angle = Vector3::Angle(v1, v2); float angle = Vector3::Angle(v1, v2);
@ -212,7 +217,7 @@ float Vector3::SignedAngle(const Vector3 &v1, const Vector3 &v2,
return signed_angle; return signed_angle;
} }
Vector3 Vector3::Lerp(const Vector3 &v1, const Vector3 &v2, float f) { Vector3 Vector3::Lerp(const Vector3& v1, const Vector3& v2, float f) {
Vector3 v = v1 + (v2 - v1) * f; Vector3 v = v1 + (v2 - v1) * f;
return v; return v;
} }

View File

@ -19,7 +19,7 @@ extern "C" {
/// This is a C-style implementation /// This is a C-style implementation
/// This uses the right-handed coordinate system. /// This uses the right-handed coordinate system.
typedef struct Vec3 { typedef struct Vec3 {
protected: protected:
/// <summary> /// <summary>
/// The right axis of the vector /// The right axis of the vector
/// </summary> /// </summary>
@ -42,7 +42,7 @@ protected:
struct Vector3 : Vec3 { struct Vector3 : Vec3 {
friend struct Vec3; friend struct Vec3;
public: public:
/// @brief A new 3-dimensional zero vector /// @brief A new 3-dimensional zero vector
Vector3(); Vector3();
/// @brief A new 3-dimensional vector /// @brief A new 3-dimensional vector
@ -88,12 +88,12 @@ public:
/// @return true if it is identical to the given vector /// @return true if it is identical to the given vector
/// @note This uses float comparison to check equality which may have strange /// @note This uses float comparison to check equality which may have strange
/// effects. Equality on floats should be avoided. /// effects. Equality on floats should be avoided.
bool operator==(const Vector3 &v); bool operator==(const Vector3& v);
/// @brief The vector length /// @brief The vector length
/// @param v The vector for which you need the length /// @param v The vector for which you need the length
/// @return The vector length /// @return The vector length
static float Magnitude(const Vector3 &v); static float Magnitude(const Vector3& v);
/// @brief The vector length /// @brief The vector length
/// @return The vector length /// @return The vector length
float magnitude() const; float magnitude() const;
@ -103,7 +103,7 @@ public:
/// @remark The squared length is computationally simpler than the real /// @remark The squared length is computationally simpler than the real
/// length. Think of Pythagoras A^2 + B^2 = C^2. This leaves out the /// length. Think of Pythagoras A^2 + B^2 = C^2. This leaves out the
/// calculation of the squared root of C. /// calculation of the squared root of C.
static float SqrMagnitude(const Vector3 &v); static float SqrMagnitude(const Vector3& v);
/// @brief The squared vector length /// @brief The squared vector length
/// @return The squared vector length /// @return The squared vector length
/// @remark The squared length is computationally simpler than the real /// @remark The squared length is computationally simpler than the real
@ -114,7 +114,7 @@ public:
/// @brief Convert the vector to a length of 1 /// @brief Convert the vector to a length of 1
/// @param v The vector to convert /// @param v The vector to convert
/// @return The vector normalized to a length of 1 /// @return The vector normalized to a length of 1
static Vector3 Normalize(const Vector3 &v); static Vector3 Normalize(const Vector3& v);
/// @brief Convert the vector to a length of 1 /// @brief Convert the vector to a length of 1
/// @return The vector normalized to a length of 1 /// @return The vector normalized to a length of 1
Vector3 normalized() const; Vector3 normalized() const;
@ -126,13 +126,13 @@ public:
/// @brief Subtract a vector from this vector /// @brief Subtract a vector from this vector
/// @param v The vector to subtract from this vector /// @param v The vector to subtract from this vector
/// @return The result of this subtraction /// @return The result of this subtraction
Vector3 operator-(const Vector3 &v) const; Vector3 operator-(const Vector3& v) const;
Vector3 operator-=(const Vector3 &v); Vector3 operator-=(const Vector3& v);
/// @brief Add a vector to this vector /// @brief Add a vector to this vector
/// @param v The vector to add to this vector /// @param v The vector to add to this vector
/// @return The result of the addition /// @return The result of the addition
Vector3 operator+(const Vector3 &v) const; Vector3 operator+(const Vector3& v) const;
Vector3 operator+=(const Vector3 &v); Vector3 operator+=(const Vector3& v);
/// @brief Scale the vector using another vector /// @brief Scale the vector using another vector
/// @param v1 The vector to scale /// @param v1 The vector to scale
@ -140,52 +140,62 @@ public:
/// @return The scaled vector /// @return The scaled vector
/// @remark Each component of the vector v1 will be multiplied with the /// @remark Each component of the vector v1 will be multiplied with the
/// matching component from the scaling vector v2. /// matching component from the scaling vector v2.
static Vector3 Scale(const Vector3 &v1, const Vector3 &v2); static Vector3 Scale(const Vector3& v1, const Vector3& v2);
/// @brief Scale the vector uniformly up /// @brief Scale the vector uniformly up
/// @param f The scaling factor /// @param f The scaling factor
/// @return The scaled vector /// @return The scaled vector
/// @remark Each component of the vector will be multipled with the same /// @remark Each component of the vector will be multipled with the same
/// factor f. /// factor f.
friend Vector3 operator*(const Vector3 &v, float f); friend Vector3 operator*(const Vector3& v, float f) {
friend Vector3 operator*(float f, const Vector3 &v); return Vector3(v.x * f, v.y * f, v.z * f);
}
friend Vector3 operator*(float f, const Vector3& v) {
// return Vector3(f * v.x, f * v.y, f * v.z);
return Vector3(v.x * f, v.y * f, v.z * f);
}
Vector3 operator*=(float f); Vector3 operator*=(float f);
/// @brief Scale the vector uniformly down /// @brief Scale the vector uniformly down
/// @param f The scaling factor /// @param f The scaling factor
/// @return The scaled vector /// @return The scaled vector
/// @remark Each componet of the vector will be divided by the same factor. /// @remark Each componet of the vector will be divided by the same factor.
friend Vector3 operator/(const Vector3 &v, float f); friend Vector3 operator/(const Vector3& v, float f) {
friend Vector3 operator/(float f, const Vector3 &v); return Vector3(v.x / f, v.y / f, v.z / f);
}
friend Vector3 operator/(float f, const Vector3& v) {
// return Vector3(f / v.x, f / v.y, f / v.z);
return Vector3(v.x / f, v.y / f, v.z / f);
}
Vector3 operator/=(float f); Vector3 operator/=(float f);
/// @brief The distance between two vectors /// @brief The distance between two vectors
/// @param v1 The first vector /// @param v1 The first vector
/// @param v2 The second vector /// @param v2 The second vector
/// @return The distance between the two vectors /// @return The distance between the two vectors
static float Distance(const Vector3 &v1, const Vector3 &v2); static float Distance(const Vector3& v1, const Vector3& v2);
/// @brief The dot product of two vectors /// @brief The dot product of two vectors
/// @param v1 The first vector /// @param v1 The first vector
/// @param v2 The second vector /// @param v2 The second vector
/// @return The dot product of the two vectors /// @return The dot product of the two vectors
static float Dot(const Vector3 &v1, const Vector3 &v2); static float Dot(const Vector3& v1, const Vector3& v2);
/// @brief The cross product of two vectors /// @brief The cross product of two vectors
/// @param v1 The first vector /// @param v1 The first vector
/// @param v2 The second vector /// @param v2 The second vector
/// @return The cross product of the two vectors /// @return The cross product of the two vectors
static Vector3 Cross(const Vector3 &v1, const Vector3 &v2); static Vector3 Cross(const Vector3& v1, const Vector3& v2);
/// @brief Project the vector on another vector /// @brief Project the vector on another vector
/// @param v The vector to project /// @param v The vector to project
/// @param n The normal vecto to project on /// @param n The normal vecto to project on
/// @return The projected vector /// @return The projected vector
static Vector3 Project(const Vector3 &v, const Vector3 &n); static Vector3 Project(const Vector3& v, const Vector3& n);
/// @brief Project the vector on a plane defined by a normal orthogonal to the /// @brief Project the vector on a plane defined by a normal orthogonal to the
/// plane. /// plane.
/// @param v The vector to project /// @param v The vector to project
/// @param n The normal of the plane to project on /// @param n The normal of the plane to project on
/// @return Teh projected vector /// @return Teh projected vector
static Vector3 ProjectOnPlane(const Vector3 &v, const Vector3 &n); static Vector3 ProjectOnPlane(const Vector3& v, const Vector3& n);
/// @brief The angle between two vectors /// @brief The angle between two vectors
/// @param v1 The first vector /// @param v1 The first vector
@ -194,14 +204,15 @@ public:
/// @remark This reterns an unsigned angle which is the shortest distance /// @remark This reterns an unsigned angle which is the shortest distance
/// between the two vectors. Use Vector3::SignedAngle if a signed angle is /// between the two vectors. Use Vector3::SignedAngle if a signed angle is
/// needed. /// needed.
static float Angle(const Vector3 &v1, const Vector3 &v2); static float Angle(const Vector3& v1, const Vector3& v2);
/// @brief The signed angle between two vectors /// @brief The signed angle between two vectors
/// @param v1 The starting vector /// @param v1 The starting vector
/// @param v2 The ending vector /// @param v2 The ending vector
/// @param axis The axis to rotate around /// @param axis The axis to rotate around
/// @return The signed angle between the two vectors /// @return The signed angle between the two vectors
static float SignedAngle(const Vector3 &v1, const Vector3 &v2, static float SignedAngle(const Vector3& v1,
const Vector3 &axis); const Vector3& v2,
const Vector3& axis);
/// @brief Lerp (linear interpolation) between two vectors /// @brief Lerp (linear interpolation) between two vectors
/// @param v1 The starting vector /// @param v1 The starting vector
@ -211,11 +222,11 @@ public:
/// @remark The factor f is unclamped. Value 0 matches the vector *v1*, Value /// @remark The factor f is unclamped. Value 0 matches the vector *v1*, Value
/// 1 matches vector *v2*. Value -1 is vector *v1* minus the difference /// 1 matches vector *v2*. Value -1 is vector *v1* minus the difference
/// between *v1* and *v2* etc. /// between *v1* and *v2* etc.
static Vector3 Lerp(const Vector3 &v1, const Vector3 &v2, float f); static Vector3 Lerp(const Vector3& v1, const Vector3& v2, float f);
}; };
} // namespace LinearAlgebra } // namespace LinearAlgebra
} // namespace Passer } // namespace Passer
using namespace Passer::LinearAlgebra; using namespace Passer::LinearAlgebra;
#include "Spherical.h" #include "Spherical.h"