Extend AngleOf support
This commit is contained in:
parent
c70c079efc
commit
b81b77b1c9
31
Angle.cpp
31
Angle.cpp
@ -3,8 +3,8 @@
|
||||
// file, You can obtain one at https ://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "Angle.h"
|
||||
#include "FloatSingle.h"
|
||||
#include <math.h>
|
||||
#include "FloatSingle.h"
|
||||
|
||||
/*
|
||||
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 <> AngleOf<float> AngleOf<float>::Deg2Rad = (pi * 2) / 360.0f;
|
||||
template <>
|
||||
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 <>
|
||||
bool Passer::LinearAlgebra::AngleOf<float>::operator==(AngleOf<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;
|
||||
if (!isfinite(angleValue))
|
||||
return angleValue;
|
||||
@ -96,7 +108,8 @@ template <> AngleOf<float> AngleOf<float>::Normalize(AngleOf<float> angle) {
|
||||
}
|
||||
|
||||
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) {
|
||||
float normalizedAngle = Normalize(angle);
|
||||
float r = Float::Clamp(normalizedAngle, min, max);
|
||||
@ -120,7 +133,8 @@ AngleOf<float> AngleOf<float>::MoveTowards(AngleOf<float> fromAngle,
|
||||
}
|
||||
|
||||
template <>
|
||||
AngleOf<float> AngleOf<float>::CosineRuleSide(float a, float b,
|
||||
AngleOf<float> AngleOf<float>::CosineRuleSide(float a,
|
||||
float b,
|
||||
AngleOf<float> gamma) {
|
||||
float a2 = a * a;
|
||||
float b2 = b * b;
|
||||
@ -150,7 +164,8 @@ AngleOf<float> AngleOf<float>::CosineRuleAngle(float a, float b, float c) {
|
||||
}
|
||||
|
||||
template <>
|
||||
AngleOf<float> AngleOf<float>::SineRuleAngle(float a, AngleOf<float> beta,
|
||||
AngleOf<float> AngleOf<float>::SineRuleAngle(float a,
|
||||
AngleOf<float> beta,
|
||||
float b) {
|
||||
float alpha = asin(a * sin(beta * Angle::Deg2Rad) / b);
|
||||
return alpha;
|
||||
|
24
Angle.h
24
Angle.h
@ -8,11 +8,15 @@
|
||||
namespace Passer {
|
||||
namespace LinearAlgebra {
|
||||
|
||||
template <typename T> class AngleOf {
|
||||
public:
|
||||
AngleOf(){};
|
||||
AngleOf(T v) : value(v) {}
|
||||
operator T() const { return value; }
|
||||
template <typename T>
|
||||
class AngleOf {
|
||||
public:
|
||||
AngleOf() {};
|
||||
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> Deg2Rad;
|
||||
@ -27,7 +31,8 @@ public:
|
||||
AngleOf<T> r = Normalize(b - a);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
private:
|
||||
private:
|
||||
T value;
|
||||
};
|
||||
|
||||
using Angle = AngleOf<float>;
|
||||
// using Angle = AngleOf<signed short>;
|
||||
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
using namespace Passer::LinearAlgebra;
|
||||
|
||||
#endif
|
74
Angle16.cpp
Normal file
74
Angle16.cpp
Normal 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;
|
||||
}
|
34
Angle16.h
34
Angle16.h
@ -1,28 +1,28 @@
|
||||
#include "AngleUsing.h"
|
||||
// #include "AngleUsing.h"
|
||||
|
||||
#include "Angle.h"
|
||||
#include <math.h>
|
||||
#include "Angle.h"
|
||||
|
||||
namespace Passer {
|
||||
namespace LinearAlgebra {
|
||||
|
||||
typedef AngleUsing<signed short> Angle16;
|
||||
typedef AngleOf<signed short> Angle16;
|
||||
|
||||
template <> Angle16::AngleUsing(float angle) {
|
||||
if (!isfinite(angle)) {
|
||||
value = 0;
|
||||
return;
|
||||
}
|
||||
// template <> Angle16::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);
|
||||
}
|
||||
// // map float [-180..180) to integer [-32768..32767]
|
||||
// this->value = (signed short)((angle / 360.0F) * 65536.0F);
|
||||
// }
|
||||
|
||||
template <> float Angle16::ToFloat() const {
|
||||
float f = ((this->value * 180) / 32768.0F);
|
||||
return f;
|
||||
}
|
||||
// template <> float Angle16::ToFloat() const {
|
||||
// float f = ((this->value * 180) / 32768.0F);
|
||||
// return f;
|
||||
// }
|
||||
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
using namespace Passer::LinearAlgebra;
|
36
Angle32.h
36
Angle32.h
@ -1,28 +1,30 @@
|
||||
#include "AngleUsing.h"
|
||||
// #include "AngleUsing.h"
|
||||
|
||||
#include "Angle.h"
|
||||
#include <math.h>
|
||||
#include "Angle.h"
|
||||
|
||||
namespace Passer {
|
||||
namespace LinearAlgebra {
|
||||
|
||||
typedef AngleUsing<signed long> Angle32;
|
||||
typedef AngleOf<signed long> Angle32;
|
||||
|
||||
template <> Angle32::AngleUsing(float angle) {
|
||||
if (!isfinite(angle)) {
|
||||
value = 0;
|
||||
return;
|
||||
}
|
||||
// template <>
|
||||
// Angle32::AngleOf(float angle) {
|
||||
// if (!isfinite(angle)) {
|
||||
// value = 0;
|
||||
// return;
|
||||
// }
|
||||
|
||||
// map float [-180..180) to integer [-2147483648..2147483647]
|
||||
this->value = (signed long)((angle / 360.0F) * 4294967295.0F);
|
||||
}
|
||||
// // map float [-180..180) to integer [-2147483648..2147483647]
|
||||
// this->value = (signed long)((angle / 360.0F) * 4294967295.0F);
|
||||
// }
|
||||
|
||||
template <> float Angle32::ToFloat() const {
|
||||
float f = ((this->value * 180) / 2147483648.0F);
|
||||
return f;
|
||||
}
|
||||
// template <>
|
||||
// float Angle32::ToFloat() const {
|
||||
// float f = ((this->value * 180) / 2147483648.0F);
|
||||
// return f;
|
||||
// }
|
||||
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
using namespace Passer::LinearAlgebra;
|
24
Angle8.cpp
Normal file
24
Angle8.cpp
Normal 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;
|
||||
}
|
36
Angle8.h
36
Angle8.h
@ -1,29 +1,29 @@
|
||||
#include "AngleUsing.h"
|
||||
// #include "AngleUsing.h"
|
||||
|
||||
#include "Angle.h"
|
||||
#include <math.h>
|
||||
#include "Angle.h"
|
||||
|
||||
namespace Passer {
|
||||
namespace LinearAlgebra {
|
||||
|
||||
typedef AngleUsing<signed char> Angle8;
|
||||
typedef AngleOf<signed char> Angle8;
|
||||
|
||||
template <> Angle8::AngleUsing(float angle) {
|
||||
if (!isfinite(angle)) {
|
||||
value = 0;
|
||||
return;
|
||||
}
|
||||
// template <> Angle8::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);
|
||||
}
|
||||
// // map float [-180..180) to integer [-128..127]
|
||||
// float f = angle / 360.0F;
|
||||
// this->value = (signed char)(f * 256.0F);
|
||||
// }
|
||||
|
||||
template <> float Angle8::ToFloat() const {
|
||||
float f = (this->value * 180) / 128.0F;
|
||||
return f;
|
||||
}
|
||||
// template <> float Angle8::ToFloat() const {
|
||||
// float f = (this->value * 180) / 128.0F;
|
||||
// return f;
|
||||
// }
|
||||
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
using namespace Passer::LinearAlgebra;
|
11
AngleUsing.h
11
AngleUsing.h
@ -1,3 +1,4 @@
|
||||
/*
|
||||
#ifndef DISCRETEANGLE_H
|
||||
#define DISCRETEANGLE_H
|
||||
|
||||
@ -9,8 +10,9 @@ namespace LinearAlgebra {
|
||||
|
||||
// A fixed angle between (-180..180]
|
||||
|
||||
template <typename T> class AngleUsing {
|
||||
public:
|
||||
template <typename T>
|
||||
class AngleUsing {
|
||||
public:
|
||||
AngleUsing(T sourceValue) { this->value = sourceValue; }
|
||||
AngleUsing(float f);
|
||||
float ToFloat() const;
|
||||
@ -42,8 +44,9 @@ public:
|
||||
T value;
|
||||
};
|
||||
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
using namespace Passer::LinearAlgebra;
|
||||
|
||||
#endif
|
||||
*/
|
40
Polar.cpp
40
Polar.cpp
@ -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::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);
|
||||
}
|
||||
|
||||
Polar Polar::Normalize(const Polar &v) {
|
||||
Polar Polar::Normalize(const Polar& v) {
|
||||
Polar r = Polar(1, v.angle);
|
||||
return r;
|
||||
}
|
||||
@ -55,15 +55,15 @@ Polar Polar::operator-() const {
|
||||
return v;
|
||||
}
|
||||
|
||||
Polar Polar::operator-(const Polar &v) const {
|
||||
Polar Polar::operator-(const Polar& v) const {
|
||||
Polar r = -v;
|
||||
return *this + r;
|
||||
}
|
||||
Polar Polar::operator-=(const Polar &v) {
|
||||
Polar Polar::operator-=(const Polar& v) {
|
||||
*this = *this - v;
|
||||
return *this;
|
||||
}
|
||||
Polar Polar::operator+(const Polar &v) const {
|
||||
Polar Polar::operator+(const Polar& v) const {
|
||||
if (v.distance == 0)
|
||||
return Polar(this->distance, this->angle);
|
||||
if (this->distance == 0.0f)
|
||||
@ -89,39 +89,39 @@ Polar Polar::operator+(const Polar &v) const {
|
||||
Polar vector = Polar(newDistance, newAngle);
|
||||
return vector;
|
||||
}
|
||||
Polar Polar::operator+=(const Polar &v) {
|
||||
Polar Polar::operator+=(const Polar& v) {
|
||||
*this = *this + v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Polar Passer::LinearAlgebra::operator*(const Polar &v, float f) {
|
||||
return Polar(v.distance * f, v.angle);
|
||||
}
|
||||
Polar Passer::LinearAlgebra::operator*(float f, const Polar &v) {
|
||||
return Polar(v.distance * f, v.angle);
|
||||
}
|
||||
// Polar Passer::LinearAlgebra::operator*(const Polar &v, float f) {
|
||||
// return Polar(v.distance * f, v.angle);
|
||||
// }
|
||||
// Polar Passer::LinearAlgebra::operator*(float f, const Polar &v) {
|
||||
// return Polar(v.distance * f, v.angle);
|
||||
// }
|
||||
Polar Polar::operator*=(float f) {
|
||||
this->distance *= f;
|
||||
return *this;
|
||||
}
|
||||
Polar Passer::LinearAlgebra::operator/(const Polar &v, float f) {
|
||||
return Polar(v.distance / f, v.angle);
|
||||
}
|
||||
Polar Passer::LinearAlgebra::operator/(float f, const Polar &v) {
|
||||
return Polar(v.distance / f, v.angle);
|
||||
}
|
||||
// Polar Passer::LinearAlgebra::operator/(const Polar& v, float f) {
|
||||
// return Polar(v.distance / f, v.angle);
|
||||
// }
|
||||
// Polar Passer::LinearAlgebra::operator/(float f, const Polar& v) {
|
||||
// return Polar(v.distance / f, v.angle);
|
||||
// }
|
||||
Polar Polar::operator/=(float f) {
|
||||
this->distance /= f;
|
||||
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)v2.angle - (float)v1.angle);
|
||||
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);
|
||||
Polar r = Polar(v.distance, a);
|
||||
return r;
|
||||
|
40
Polar.h
40
Polar.h
@ -17,7 +17,7 @@ struct Spherical;
|
||||
/// @details This will use the polar coordinate system consisting of a angle
|
||||
/// from a reference direction and a distance.
|
||||
struct Polar {
|
||||
public:
|
||||
public:
|
||||
/// @brief The distance in meters
|
||||
/// @remark The distance shall never be negative
|
||||
float distance;
|
||||
@ -59,12 +59,12 @@ public:
|
||||
/// @return true: if it is identical to the given vector
|
||||
/// @note This uses float comparison to check equality which may have
|
||||
/// strange effects. Equality on floats should be avoided.
|
||||
bool operator==(const Polar &v) const;
|
||||
bool operator==(const Polar& v) const;
|
||||
|
||||
/// @brief The vector length
|
||||
/// @param v The vector for which you need the 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
|
||||
/// @return The vector length
|
||||
inline float magnitude() const { return this->distance; }
|
||||
@ -72,7 +72,7 @@ public:
|
||||
/// @brief Convert the vector to a length of 1
|
||||
/// @param v The vector to convert
|
||||
/// @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
|
||||
/// @return The vector normalized to a length of 1
|
||||
Polar normalized() const;
|
||||
@ -85,45 +85,53 @@ public:
|
||||
/// @brief Subtract a polar vector from this vector
|
||||
/// @param v The vector to subtract
|
||||
/// @return The result of the subtraction
|
||||
Polar operator-(const Polar &v) const;
|
||||
Polar operator-=(const Polar &v);
|
||||
Polar operator-(const Polar& v) const;
|
||||
Polar operator-=(const Polar& v);
|
||||
/// @brief Add a polar vector to this vector
|
||||
/// @param v The vector to add
|
||||
/// @return The result of the addition
|
||||
Polar operator+(const Polar &v) const;
|
||||
Polar operator+=(const Polar &v);
|
||||
Polar operator+(const Polar& v) const;
|
||||
Polar operator+=(const Polar& v);
|
||||
|
||||
/// @brief Scale the vector uniformly up
|
||||
/// @param f The scaling factor
|
||||
/// @return The scaled vector
|
||||
/// @remark This operation will scale the distance of the vector. The angle
|
||||
/// will be unaffected.
|
||||
friend Polar operator*(const Polar &v, float f);
|
||||
friend Polar operator*(float f, const Polar &v);
|
||||
friend Polar operator*(const Polar& v, float f) {
|
||||
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);
|
||||
/// @brief Scale the vector uniformly down
|
||||
/// @param f The scaling factor
|
||||
/// @return The scaled factor
|
||||
/// @remark This operation will scale the distance of the vector. The angle
|
||||
/// will be unaffected.
|
||||
friend Polar operator/(const Polar &v, float f);
|
||||
friend Polar operator/(float f, const Polar &v);
|
||||
friend Polar operator/(const Polar& v, float f) {
|
||||
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);
|
||||
|
||||
/// @brief The distance between two vectors
|
||||
/// @param v1 The first vector
|
||||
/// @param v2 The second vector
|
||||
/// @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
|
||||
/// @param v The vector to rotate
|
||||
/// @param a The angle in degreesto rotate
|
||||
/// @return The rotated vector
|
||||
static Polar Rotate(const Polar &v, Angle a);
|
||||
static Polar Rotate(const Polar& v, Angle a);
|
||||
};
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
using namespace Passer::LinearAlgebra;
|
||||
|
||||
#include "Spherical.h"
|
||||
|
@ -17,7 +17,8 @@ Spherical::Spherical(Polar polar) {
|
||||
this->verticalAngle = 0.0f;
|
||||
}
|
||||
|
||||
Spherical::Spherical(float distance, Angle horizontalAngle,
|
||||
Spherical::Spherical(float distance,
|
||||
Angle horizontalAngle,
|
||||
Angle verticalAngle) {
|
||||
if (distance < 0) {
|
||||
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::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 &&
|
||||
this->horizontalAngle == v.horizontalAngle &&
|
||||
this->verticalAngle == v.verticalAngle);
|
||||
}
|
||||
|
||||
Spherical Spherical::Normalize(const Spherical &v) {
|
||||
Spherical Spherical::Normalize(const Spherical& v) {
|
||||
Spherical r = Spherical(1, v.horizontalAngle, v.verticalAngle);
|
||||
return r;
|
||||
}
|
||||
@ -71,7 +72,7 @@ Spherical Spherical::operator-() const {
|
||||
return v;
|
||||
}
|
||||
|
||||
Spherical Spherical::operator-(const Spherical &s2) const {
|
||||
Spherical Spherical::operator-(const Spherical& s2) const {
|
||||
// let's do it the easy way...
|
||||
Vector3 v1 = Vector3(*this);
|
||||
Vector3 v2 = Vector3(s2);
|
||||
@ -79,12 +80,12 @@ Spherical Spherical::operator-(const Spherical &s2) const {
|
||||
Spherical r = Spherical(v);
|
||||
return r;
|
||||
}
|
||||
Spherical Spherical::operator-=(const Spherical &v) {
|
||||
Spherical Spherical::operator-=(const Spherical& v) {
|
||||
*this = *this - v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Spherical Spherical::operator+(const Spherical &s2) const {
|
||||
Spherical Spherical::operator+(const Spherical& s2) const {
|
||||
// let's do it the easy way...
|
||||
Vector3 v1 = Vector3(*this);
|
||||
Vector3 v2 = Vector3(s2);
|
||||
@ -138,28 +139,28 @@ Spherical Spherical::operator+(const Spherical &s2) const {
|
||||
Spherical v = Spherical(newDistance, newHorizontalAngle, newVerticalAngle);
|
||||
*/
|
||||
}
|
||||
Spherical Spherical::operator+=(const Spherical &v) {
|
||||
Spherical Spherical::operator+=(const Spherical& v) {
|
||||
*this = *this + v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Spherical Passer::LinearAlgebra::operator*(const Spherical &v, float f) {
|
||||
return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle);
|
||||
}
|
||||
Spherical Passer::LinearAlgebra::operator*(float f, const Spherical &v) {
|
||||
return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle);
|
||||
}
|
||||
// Spherical Passer::LinearAlgebra::operator*(const Spherical &v, float f) {
|
||||
// return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle);
|
||||
// }
|
||||
// Spherical Passer::LinearAlgebra::operator*(float f, const Spherical &v) {
|
||||
// return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle);
|
||||
// }
|
||||
Spherical Spherical::operator*=(float f) {
|
||||
this->distance *= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Spherical Passer::LinearAlgebra::operator/(const Spherical &v, float f) {
|
||||
return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle);
|
||||
}
|
||||
Spherical Passer::LinearAlgebra::operator/(float f, const Spherical &v) {
|
||||
return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle);
|
||||
}
|
||||
// Spherical Passer::LinearAlgebra::operator/(const Spherical &v, float f) {
|
||||
// return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle);
|
||||
// }
|
||||
// Spherical Passer::LinearAlgebra::operator/(float f, const Spherical &v) {
|
||||
// return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle);
|
||||
// }
|
||||
Spherical Spherical::operator/=(float f) {
|
||||
this->distance /= f;
|
||||
return *this;
|
||||
@ -183,12 +184,11 @@ Spherical Spherical::operator/=(float f) {
|
||||
const float epsilon = 1E-05f;
|
||||
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 =
|
||||
v1.distance * v2.distance; // sqrtf(v1.distance * v1.distance *
|
||||
// v2.distance * v2.distance);
|
||||
v1.distance * v2.distance; // sqrtf(v1.distance * v1.distance *
|
||||
// v2.distance * v2.distance);
|
||||
if (denominator < epsilon)
|
||||
return 0;
|
||||
|
||||
@ -197,24 +197,25 @@ Angle Spherical::AngleBetween(const Spherical &v1, const Spherical &v2) {
|
||||
float dot = Vector3::Dot(v1_3, v2_3);
|
||||
float fraction = dot / denominator;
|
||||
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 r = ((float)acos(cdot)) * Rad2Deg;
|
||||
return r;
|
||||
}
|
||||
|
||||
Spherical Spherical::Rotate(const Spherical &v, Angle horizontalAngle,
|
||||
Spherical Spherical::Rotate(const Spherical& v,
|
||||
Angle horizontalAngle,
|
||||
Angle verticalAngle) {
|
||||
Spherical r = Spherical(v.distance, v.horizontalAngle + horizontalAngle,
|
||||
v.verticalAngle + verticalAngle);
|
||||
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);
|
||||
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);
|
||||
return r;
|
||||
}
|
47
Spherical.h
47
Spherical.h
@ -19,7 +19,7 @@ struct Vector3;
|
||||
/// reference direction. The reference direction is typically thought of
|
||||
/// as a forward direction.
|
||||
struct Spherical {
|
||||
public:
|
||||
public:
|
||||
/// @brief The distance in meters
|
||||
/// @remark The distance should never be negative
|
||||
float distance;
|
||||
@ -66,12 +66,12 @@ public:
|
||||
/// @return true: if it is identical to the given vector
|
||||
/// @note This uses float comparison to check equality which may have strange
|
||||
/// effects. Equality on floats should be avoided.
|
||||
bool operator==(const Spherical &v) const;
|
||||
bool operator==(const Spherical& v) const;
|
||||
|
||||
/// @brief The vector length
|
||||
/// @param v The vector for which you need the 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
|
||||
/// @return The vector length
|
||||
inline float magnitude() const { return this->distance; }
|
||||
@ -79,7 +79,7 @@ public:
|
||||
/// @brief Convert the vector to a length of 1
|
||||
/// @param v The vector to convert
|
||||
/// @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
|
||||
/// @return The vector normalized to a length of 1
|
||||
Spherical normalized() const;
|
||||
@ -93,29 +93,39 @@ public:
|
||||
/// @brief Subtract a spherical vector from this vector
|
||||
/// @param v The vector to subtract
|
||||
/// @return The result of the subtraction
|
||||
Spherical operator-(const Spherical &v) const;
|
||||
Spherical operator-=(const Spherical &v);
|
||||
Spherical operator-(const Spherical& v) const;
|
||||
Spherical operator-=(const Spherical& v);
|
||||
/// @brief Add a spherical vector to this vector
|
||||
/// @param v The vector to add
|
||||
/// @return The result of the addition
|
||||
Spherical operator+(const Spherical &v) const;
|
||||
Spherical operator+=(const Spherical &v);
|
||||
Spherical operator+(const Spherical& v) const;
|
||||
Spherical operator+=(const Spherical& v);
|
||||
|
||||
/// @brief Scale the vector uniformly up
|
||||
/// @param f The scaling factor
|
||||
/// @return The scaled vector
|
||||
/// @remark This operation will scale the distance of the vector. The angle
|
||||
/// will be unaffected.
|
||||
friend Spherical operator*(const Spherical &v, float f);
|
||||
friend Spherical operator*(float f, const Spherical &v);
|
||||
friend Spherical operator*(const Spherical& v, float f) {
|
||||
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);
|
||||
/// @brief Scale the vector uniformly down
|
||||
/// @param f The scaling factor
|
||||
/// @return The scaled factor
|
||||
/// @remark This operation will scale the distance of the vector. The angle
|
||||
/// will be unaffected.
|
||||
friend Spherical operator/(const Spherical &v, float f);
|
||||
friend Spherical operator/(float f, const Spherical &v);
|
||||
friend Spherical operator/(const Spherical& v, float f) {
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
@ -126,16 +136,17 @@ public:
|
||||
/// <returns>The distance between the two vectors</returns>
|
||||
// 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);
|
||||
static Spherical RotateHorizontal(const Spherical &v, Angle angle);
|
||||
static Spherical RotateVertical(const Spherical &v, Angle angle);
|
||||
static Spherical RotateHorizontal(const Spherical& v, Angle angle);
|
||||
static Spherical RotateVertical(const Spherical& v, Angle angle);
|
||||
};
|
||||
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
using namespace Passer::LinearAlgebra;
|
||||
|
||||
#include "Vector3.h"
|
||||
|
74
Vector2.cpp
74
Vector2.cpp
@ -26,8 +26,8 @@ Vector2::Vector2(float _x, float _y) {
|
||||
// y = v.y;
|
||||
// }
|
||||
Vector2::Vector2(Vector3 v) {
|
||||
x = v.Right(); // x;
|
||||
y = v.Forward(); // z;
|
||||
x = v.Right(); // x;
|
||||
y = v.Forward(); // z;
|
||||
}
|
||||
Vector2::Vector2(Polar p) {
|
||||
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::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);
|
||||
}
|
||||
|
||||
float Vector2::Magnitude(const Vector2 &v) {
|
||||
float Vector2::Magnitude(const Vector2& v) {
|
||||
return sqrtf(v.x * v.x + v.y * v.y);
|
||||
}
|
||||
float Vector2::magnitude() const { return (float)sqrtf(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); }
|
||||
float Vector2::magnitude() const {
|
||||
return (float)sqrtf(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);
|
||||
Vector2 result = Vector2::zero;
|
||||
if (num > Float::epsilon) {
|
||||
@ -77,63 +83,65 @@ Vector2 Vector2::normalized() const {
|
||||
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);
|
||||
}
|
||||
Vector2 Vector2::operator-=(const Vector2 &v) {
|
||||
Vector2 Vector2::operator-=(const Vector2& v) {
|
||||
this->x -= v.x;
|
||||
this->y -= v.y;
|
||||
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);
|
||||
}
|
||||
Vector2 Vector2::operator+=(const Vector2 &v) {
|
||||
Vector2 Vector2::operator+=(const Vector2& v) {
|
||||
this->x += v.x;
|
||||
this->y += v.y;
|
||||
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);
|
||||
}
|
||||
Vector2 Passer::LinearAlgebra::operator*(const Vector2 &v, float f) {
|
||||
return Vector2(v.x * f, v.y * f);
|
||||
}
|
||||
Vector2 Passer::LinearAlgebra::operator*(float f, const Vector2 &v) {
|
||||
return Vector2(v.x * f, v.y * f);
|
||||
}
|
||||
// Vector2 Passer::LinearAlgebra::operator*(const Vector2 &v, float f) {
|
||||
// return Vector2(v.x * f, v.y * f);
|
||||
// }
|
||||
// Vector2 Passer::LinearAlgebra::operator*(float f, const Vector2 &v) {
|
||||
// return Vector2(v.x * f, v.y * f);
|
||||
// }
|
||||
Vector2 Vector2::operator*=(float f) {
|
||||
this->x *= f;
|
||||
this->y *= f;
|
||||
return *this;
|
||||
}
|
||||
Vector2 Passer::LinearAlgebra::operator/(const Vector2 &v, float f) {
|
||||
return Vector2(v.x / f, v.y / f);
|
||||
}
|
||||
Vector2 Passer::LinearAlgebra::operator/(float f, const Vector2 &v) {
|
||||
return Vector2(v.x / f, v.y / f);
|
||||
}
|
||||
// Vector2 Passer::LinearAlgebra::operator/(const Vector2 &v, float f) {
|
||||
// return Vector2(v.x / f, v.y / f);
|
||||
// }
|
||||
// Vector2 Passer::LinearAlgebra::operator/(float f, const Vector2 &v) {
|
||||
// return Vector2(v.x / f, v.y / f);
|
||||
// }
|
||||
Vector2 Vector2::operator/=(float f) {
|
||||
this->x /= f;
|
||||
this->y /= f;
|
||||
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;
|
||||
}
|
||||
|
||||
float Vector2::Distance(const Vector2 &v1, const Vector2 &v2) {
|
||||
float Vector2::Distance(const Vector2& v1, const Vector2& 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));
|
||||
}
|
||||
float Vector2::SignedAngle(const Vector2 &v1, const Vector2 &v2) {
|
||||
float Vector2::SignedAngle(const Vector2& v1, const Vector2& v2) {
|
||||
float sqrMagFrom = v1.sqrMagnitude();
|
||||
float sqrMagTo = v2.sqrMagnitude();
|
||||
|
||||
@ -151,11 +159,11 @@ float Vector2::SignedAngle(const Vector2 &v1, const Vector2 &v2) {
|
||||
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;
|
||||
#if defined(AVR)
|
||||
float sinValue = sin(angleRad);
|
||||
float cosValue = cos(angleRad); // * Angle::Deg2Rad);
|
||||
float cosValue = cos(angleRad); // * Angle::Deg2Rad);
|
||||
#else
|
||||
float sinValue = (float)sinf(angleRad);
|
||||
float cosValue = (float)cosf(angleRad);
|
||||
@ -168,7 +176,7 @@ Vector2 Vector2::Rotate(const Vector2 &v, Passer::LinearAlgebra::Angle a) {
|
||||
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;
|
||||
return v;
|
||||
}
|
||||
|
49
Vector2.h
49
Vector2.h
@ -38,7 +38,7 @@ struct Polar;
|
||||
struct Vector2 : Vec2 {
|
||||
friend struct Vec2;
|
||||
|
||||
public:
|
||||
public:
|
||||
/// @brief A new 2-dimensional zero vector
|
||||
Vector2();
|
||||
/// @brief A new 2-dimensional vector
|
||||
@ -80,12 +80,12 @@ public:
|
||||
/// @return true if it is identical to the given vector
|
||||
/// @note This uses float comparison to check equality which may have strange
|
||||
/// effects. Equality on floats should be avoided.
|
||||
bool operator==(const Vector2 &v);
|
||||
bool operator==(const Vector2& v);
|
||||
|
||||
/// @brief The vector length
|
||||
/// @param v The vector for which you need the length
|
||||
/// @return The vector length
|
||||
static float Magnitude(const Vector2 &v);
|
||||
static float Magnitude(const Vector2& v);
|
||||
/// @brief The vector length
|
||||
/// @return The vector length
|
||||
float magnitude() const;
|
||||
@ -95,7 +95,7 @@ public:
|
||||
/// @remark The squared length is computationally simpler than the real
|
||||
/// length. Think of Pythagoras A^2 + B^2 = C^2. This prevents the calculation
|
||||
/// of the squared root of C.
|
||||
static float SqrMagnitude(const Vector2 &v);
|
||||
static float SqrMagnitude(const Vector2& v);
|
||||
/// @brief The squared vector length
|
||||
/// @return The squared vector length
|
||||
/// @remark The squared length is computationally simpler than the real
|
||||
@ -106,7 +106,7 @@ public:
|
||||
/// @brief Convert the vector to a length of 1
|
||||
/// @param v The vector to convert
|
||||
/// @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
|
||||
/// @return The vector normalized to a length of 1
|
||||
Vector2 normalized() const;
|
||||
@ -118,13 +118,13 @@ public:
|
||||
/// @brief Subtract a vector from this vector
|
||||
/// @param v The vector to subtract from this vector
|
||||
/// @return The result of the subtraction
|
||||
Vector2 operator-(const Vector2 &v) const;
|
||||
Vector2 operator-=(const Vector2 &v);
|
||||
Vector2 operator-(const Vector2& v) const;
|
||||
Vector2 operator-=(const Vector2& v);
|
||||
/// @brief Add a vector to this vector
|
||||
/// @param v The vector to add to this vector
|
||||
/// @return The result of the addition
|
||||
Vector2 operator+(const Vector2 &v) const;
|
||||
Vector2 operator+=(const Vector2 &v);
|
||||
Vector2 operator+(const Vector2& v) const;
|
||||
Vector2 operator+=(const Vector2& v);
|
||||
|
||||
/// @brief Scale the vector using another vector
|
||||
/// @param v1 The vector to scale
|
||||
@ -132,34 +132,39 @@ public:
|
||||
/// @return The scaled vector
|
||||
/// @remark Each component of the vector v1 will be multiplied with the
|
||||
/// 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
|
||||
/// @param f The scaling factor
|
||||
/// @return The scaled vector
|
||||
/// @remark Each component of the vector will be multipled with the same
|
||||
/// factor f.
|
||||
friend Vector2 operator*(const Vector2 &v, float f);
|
||||
friend Vector2 operator*(float f, const Vector2 &v);
|
||||
friend Vector2 operator*(const Vector2& v, float f) {
|
||||
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);
|
||||
/// @brief Scale the vector uniformly down
|
||||
/// @param f The scaling factor
|
||||
/// @return The scaled vector
|
||||
/// @remark Each componet of the vector will be divided by the same factor.
|
||||
friend Vector2 operator/(const Vector2 &v, float f);
|
||||
friend Vector2 operator/(float f, const Vector2 &v);
|
||||
friend Vector2 operator/(const Vector2& v, float f);
|
||||
friend Vector2 operator/(float f, const Vector2& v);
|
||||
Vector2 operator/=(float f);
|
||||
|
||||
/// @brief The dot product of two vectors
|
||||
/// @param v1 The first vector
|
||||
/// @param v2 The second vector
|
||||
/// @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
|
||||
/// @param v1 The first vector
|
||||
/// @param v2 The second vector
|
||||
/// @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
|
||||
/// @param v1 The first vector
|
||||
@ -168,18 +173,18 @@ public:
|
||||
/// @remark This reterns an unsigned angle which is the shortest distance
|
||||
/// between the two vectors. Use Vector2::SignedAngle if a signed angle is
|
||||
/// 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
|
||||
/// @param v1 The starting vector
|
||||
/// @param v2 The ending vector
|
||||
/// @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
|
||||
/// @param v The vector to rotate
|
||||
/// @param a The angle in degrees to rotate
|
||||
/// @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
|
||||
/// @param v1 The starting vector
|
||||
@ -189,11 +194,11 @@ public:
|
||||
/// @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
|
||||
/// 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 Passer
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
using namespace Passer::LinearAlgebra;
|
||||
|
||||
#include "Polar.h"
|
||||
|
71
Vector3.cpp
71
Vector3.cpp
@ -65,17 +65,21 @@ const Vector3 Vector3::back = Vector3(0, 0, -1);
|
||||
// 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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
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);
|
||||
Vector3 result = Vector3::zero;
|
||||
if (num > epsilon) {
|
||||
@ -96,46 +100,46 @@ Vector3 Vector3::operator-() const {
|
||||
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);
|
||||
}
|
||||
Vector3 Vector3::operator-=(const Vector3 &v) {
|
||||
Vector3 Vector3::operator-=(const Vector3& v) {
|
||||
this->x -= v.x;
|
||||
this->y -= v.y;
|
||||
this->z -= v.z;
|
||||
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);
|
||||
}
|
||||
Vector3 Vector3::operator+=(const Vector3 &v) {
|
||||
Vector3 Vector3::operator+=(const Vector3& v) {
|
||||
this->x += v.x;
|
||||
this->y += v.y;
|
||||
this->z += v.z;
|
||||
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);
|
||||
}
|
||||
Vector3 Passer::LinearAlgebra::operator*(const Vector3 &v, float f) {
|
||||
return Vector3(v.x * f, v.y * f, v.z * f);
|
||||
}
|
||||
Vector3 Passer::LinearAlgebra::operator*(float f, const Vector3 &v) {
|
||||
return Vector3(v.x * f, v.y * f, v.z * f);
|
||||
}
|
||||
// Vector3 Passer::LinearAlgebra::operator*(const Vector3 &v, float f) {
|
||||
// return Vector3(v.x * f, v.y * f, v.z * f);
|
||||
// }
|
||||
// Vector3 Passer::LinearAlgebra::operator*(float f, const Vector3 &v) {
|
||||
// return Vector3(v.x * f, v.y * f, v.z * f);
|
||||
// }
|
||||
Vector3 Vector3::operator*=(float f) {
|
||||
this->x *= f;
|
||||
this->y *= f;
|
||||
this->z *= f;
|
||||
return *this;
|
||||
}
|
||||
Vector3 Passer::LinearAlgebra::operator/(const Vector3 &v, float f) {
|
||||
return Vector3(v.x / f, v.y / f, v.z / f);
|
||||
}
|
||||
Vector3 Passer::LinearAlgebra::operator/(float f, const Vector3 &v) {
|
||||
return Vector3(v.x / f, v.y / f, v.z / f);
|
||||
}
|
||||
// Vector3 Passer::LinearAlgebra::operator/(const Vector3 &v, float f) {
|
||||
// return Vector3(v.x / f, v.y / f, v.z / f);
|
||||
// }
|
||||
// Vector3 Passer::LinearAlgebra::operator/(float f, const Vector3 &v) {
|
||||
// return Vector3(v.x / f, v.y / f, v.z / f);
|
||||
// }
|
||||
Vector3 Vector3::operator/=(float f) {
|
||||
this->x /= f;
|
||||
this->y /= f;
|
||||
@ -143,24 +147,24 @@ Vector3 Vector3::operator/=(float f) {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
float Vector3::Distance(const Vector3 &v1, const Vector3 &v2) {
|
||||
float Vector3::Distance(const Vector3& v1, const Vector3& 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,
|
||||
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);
|
||||
if (sqrMagnitude < epsilon)
|
||||
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);
|
||||
return r;
|
||||
}
|
||||
@ -182,7 +186,7 @@ float clamp(float x, float lower, float upper) {
|
||||
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());
|
||||
if (denominator < epsilon)
|
||||
return 0;
|
||||
@ -190,15 +194,16 @@ float Vector3::Angle(const Vector3 &v1, const Vector3 &v2) {
|
||||
float dot = Vector3::Dot(v1, v2);
|
||||
float fraction = dot / denominator;
|
||||
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 r = ((float)acos(cdot)) * Rad2Deg;
|
||||
return r;
|
||||
}
|
||||
|
||||
float Vector3::SignedAngle(const Vector3 &v1, const Vector3 &v2,
|
||||
const Vector3 &axis) {
|
||||
float Vector3::SignedAngle(const Vector3& v1,
|
||||
const Vector3& v2,
|
||||
const Vector3& axis) {
|
||||
// angle in [0,180]
|
||||
float angle = Vector3::Angle(v1, v2);
|
||||
|
||||
@ -212,7 +217,7 @@ float Vector3::SignedAngle(const Vector3 &v1, const Vector3 &v2,
|
||||
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;
|
||||
return v;
|
||||
}
|
||||
|
63
Vector3.h
63
Vector3.h
@ -19,7 +19,7 @@ extern "C" {
|
||||
/// This is a C-style implementation
|
||||
/// This uses the right-handed coordinate system.
|
||||
typedef struct Vec3 {
|
||||
protected:
|
||||
protected:
|
||||
/// <summary>
|
||||
/// The right axis of the vector
|
||||
/// </summary>
|
||||
@ -42,7 +42,7 @@ protected:
|
||||
struct Vector3 : Vec3 {
|
||||
friend struct Vec3;
|
||||
|
||||
public:
|
||||
public:
|
||||
/// @brief A new 3-dimensional zero vector
|
||||
Vector3();
|
||||
/// @brief A new 3-dimensional vector
|
||||
@ -88,12 +88,12 @@ public:
|
||||
/// @return true if it is identical to the given vector
|
||||
/// @note This uses float comparison to check equality which may have strange
|
||||
/// effects. Equality on floats should be avoided.
|
||||
bool operator==(const Vector3 &v);
|
||||
bool operator==(const Vector3& v);
|
||||
|
||||
/// @brief The vector length
|
||||
/// @param v The vector for which you need the length
|
||||
/// @return The vector length
|
||||
static float Magnitude(const Vector3 &v);
|
||||
static float Magnitude(const Vector3& v);
|
||||
/// @brief The vector length
|
||||
/// @return The vector length
|
||||
float magnitude() const;
|
||||
@ -103,7 +103,7 @@ public:
|
||||
/// @remark 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 &v);
|
||||
static float SqrMagnitude(const Vector3& v);
|
||||
/// @brief The squared vector length
|
||||
/// @return The squared vector length
|
||||
/// @remark The squared length is computationally simpler than the real
|
||||
@ -114,7 +114,7 @@ public:
|
||||
/// @brief Convert the vector to a length of 1
|
||||
/// @param v The vector to convert
|
||||
/// @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
|
||||
/// @return The vector normalized to a length of 1
|
||||
Vector3 normalized() const;
|
||||
@ -126,13 +126,13 @@ public:
|
||||
/// @brief Subtract a vector from this vector
|
||||
/// @param v The vector to subtract from this vector
|
||||
/// @return The result of this subtraction
|
||||
Vector3 operator-(const Vector3 &v) const;
|
||||
Vector3 operator-=(const Vector3 &v);
|
||||
Vector3 operator-(const Vector3& v) const;
|
||||
Vector3 operator-=(const Vector3& v);
|
||||
/// @brief Add a vector to this vector
|
||||
/// @param v The vector to add to this vector
|
||||
/// @return The result of the addition
|
||||
Vector3 operator+(const Vector3 &v) const;
|
||||
Vector3 operator+=(const Vector3 &v);
|
||||
Vector3 operator+(const Vector3& v) const;
|
||||
Vector3 operator+=(const Vector3& v);
|
||||
|
||||
/// @brief Scale the vector using another vector
|
||||
/// @param v1 The vector to scale
|
||||
@ -140,52 +140,62 @@ public:
|
||||
/// @return The scaled vector
|
||||
/// @remark Each component of the vector v1 will be multiplied with the
|
||||
/// 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
|
||||
/// @param f The scaling factor
|
||||
/// @return The scaled vector
|
||||
/// @remark Each component of the vector will be multipled with the same
|
||||
/// factor f.
|
||||
friend Vector3 operator*(const Vector3 &v, float f);
|
||||
friend Vector3 operator*(float f, const Vector3 &v);
|
||||
friend Vector3 operator*(const Vector3& v, float f) {
|
||||
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);
|
||||
/// @brief Scale the vector uniformly down
|
||||
/// @param f The scaling factor
|
||||
/// @return The scaled vector
|
||||
/// @remark Each componet of the vector will be divided by the same factor.
|
||||
friend Vector3 operator/(const Vector3 &v, float f);
|
||||
friend Vector3 operator/(float f, const Vector3 &v);
|
||||
friend Vector3 operator/(const Vector3& v, float f) {
|
||||
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);
|
||||
|
||||
/// @brief The distance between two vectors
|
||||
/// @param v1 The first vector
|
||||
/// @param v2 The second vector
|
||||
/// @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
|
||||
/// @param v1 The first vector
|
||||
/// @param v2 The second vector
|
||||
/// @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
|
||||
/// @param v1 The first vector
|
||||
/// @param v2 The second vector
|
||||
/// @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
|
||||
/// @param v The vector to project
|
||||
/// @param n The normal vecto to project on
|
||||
/// @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
|
||||
/// plane.
|
||||
/// @param v The vector to project
|
||||
/// @param n The normal of the plane to project on
|
||||
/// @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
|
||||
/// @param v1 The first vector
|
||||
@ -194,14 +204,15 @@ public:
|
||||
/// @remark 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(const Vector3 &v1, const Vector3 &v2);
|
||||
static float Angle(const Vector3& v1, const Vector3& v2);
|
||||
/// @brief The signed angle between two vectors
|
||||
/// @param v1 The starting vector
|
||||
/// @param v2 The ending vector
|
||||
/// @param axis The axis to rotate around
|
||||
/// @return The signed angle between the two vectors
|
||||
static float SignedAngle(const Vector3 &v1, const Vector3 &v2,
|
||||
const Vector3 &axis);
|
||||
static float SignedAngle(const Vector3& v1,
|
||||
const Vector3& v2,
|
||||
const Vector3& axis);
|
||||
|
||||
/// @brief Lerp (linear interpolation) between two vectors
|
||||
/// @param v1 The starting vector
|
||||
@ -211,11 +222,11 @@ public:
|
||||
/// @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
|
||||
/// 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 Passer
|
||||
} // namespace LinearAlgebra
|
||||
} // namespace Passer
|
||||
using namespace Passer::LinearAlgebra;
|
||||
|
||||
#include "Spherical.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user