Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
72f1472f2e | |||
![]() |
54634f0582 |
113
Angle.cpp
113
Angle.cpp
@ -3,15 +3,15 @@
|
|||||||
// 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 <math.h>
|
|
||||||
#include "FloatSingle.h"
|
#include "FloatSingle.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
namespace LinearAlgebra {
|
const float Rad2Deg = 57.29578F;
|
||||||
|
const float Deg2Rad = 0.0174532924F;
|
||||||
|
|
||||||
//===== AngleSingle, AngleOf<float>
|
//===== AngleSingle, AngleOf<float>
|
||||||
|
|
||||||
template <>
|
template <> AngleOf<float> Passer::LinearAlgebra::AngleOf<float>::Degrees(float degrees) {
|
||||||
AngleOf<float> AngleOf<float>::Degrees(float degrees) {
|
|
||||||
if (isfinite(degrees)) {
|
if (isfinite(degrees)) {
|
||||||
while (degrees < -180)
|
while (degrees < -180)
|
||||||
degrees += 360;
|
degrees += 360;
|
||||||
@ -22,8 +22,7 @@ AngleOf<float> AngleOf<float>::Degrees(float degrees) {
|
|||||||
return AngleOf<float>(degrees);
|
return AngleOf<float>(degrees);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <> AngleOf<float> AngleOf<float>::Radians(float radians) {
|
||||||
AngleOf<float> AngleOf<float>::Radians(float radians) {
|
|
||||||
if (isfinite(radians)) {
|
if (isfinite(radians)) {
|
||||||
while (radians <= -pi)
|
while (radians <= -pi)
|
||||||
radians += 2 * pi;
|
radians += 2 * pi;
|
||||||
@ -34,13 +33,9 @@ AngleOf<float> AngleOf<float>::Radians(float radians) {
|
|||||||
return Binary(radians * Rad2Deg);
|
return Binary(radians * Rad2Deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <> float AngleOf<float>::InDegrees() const { return this->value; }
|
||||||
float AngleOf<float>::InDegrees() const {
|
|
||||||
return this->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <>
|
template <> float AngleOf<float>::InRadians() const {
|
||||||
float AngleOf<float>::InRadians() const {
|
|
||||||
return this->value * Deg2Rad;
|
return this->value * Deg2Rad;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,29 +58,25 @@ AngleOf<signed short> AngleOf<signed short>::Radians(float radians) {
|
|||||||
return Binary(value);
|
return Binary(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <> float AngleOf<signed short>::InDegrees() const {
|
||||||
float AngleOf<signed short>::InDegrees() const {
|
|
||||||
float degrees = this->value / 65536.0f * 360.0f;
|
float degrees = this->value / 65536.0f * 360.0f;
|
||||||
return degrees;
|
return degrees;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <> float AngleOf<signed short>::InRadians() const {
|
||||||
float AngleOf<signed short>::InRadians() const {
|
|
||||||
float radians = this->value / 65536.0f * (2 * pi);
|
float radians = this->value / 65536.0f * (2 * pi);
|
||||||
return radians;
|
return radians;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===== Angle8, AngleOf<signed char>
|
//===== Angle8, AngleOf<signed char>
|
||||||
|
|
||||||
template <>
|
template <> AngleOf<signed char> AngleOf<signed char>::Degrees(float degrees) {
|
||||||
AngleOf<signed char> AngleOf<signed char>::Degrees(float degrees) {
|
|
||||||
// map float [-180..180) to integer [-128..127)
|
// map float [-180..180) to integer [-128..127)
|
||||||
signed char value = (signed char)roundf(degrees / 360.0F * 256.0F);
|
signed char value = (signed char)roundf(degrees / 360.0F * 256.0F);
|
||||||
return Binary(value);
|
return Binary(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <> AngleOf<signed char> AngleOf<signed char>::Radians(float radians) {
|
||||||
AngleOf<signed char> AngleOf<signed char>::Radians(float radians) {
|
|
||||||
if (!isfinite(radians))
|
if (!isfinite(radians))
|
||||||
return AngleOf<signed char>::zero;
|
return AngleOf<signed char>::zero;
|
||||||
|
|
||||||
@ -94,42 +85,32 @@ AngleOf<signed char> AngleOf<signed char>::Radians(float radians) {
|
|||||||
return Binary(value);
|
return Binary(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <> float AngleOf<signed char>::InDegrees() const {
|
||||||
float AngleOf<signed char>::InDegrees() const {
|
|
||||||
float degrees = this->value / 256.0f * 360.0f;
|
float degrees = this->value / 256.0f * 360.0f;
|
||||||
return degrees;
|
return degrees;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <> float AngleOf<signed char>::InRadians() const {
|
||||||
float AngleOf<signed char>::InRadians() const {
|
|
||||||
float radians = this->value / 128.0f * pi;
|
float radians = this->value / 128.0f * pi;
|
||||||
return radians;
|
return radians;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===== Generic
|
//===== Generic
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> AngleOf<T>::AngleOf() : value(0) {}
|
||||||
AngleOf<T>::AngleOf() : value(0) {}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> AngleOf<T>::AngleOf(T rawValue) : value(rawValue) {}
|
||||||
AngleOf<T>::AngleOf(T rawValue) : value(rawValue) {}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> const AngleOf<T> AngleOf<T>::zero = AngleOf<T>();
|
||||||
const AngleOf<T> AngleOf<T>::zero = AngleOf<T>();
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> AngleOf<T> AngleOf<T>::Binary(T rawValue) {
|
||||||
AngleOf<T> AngleOf<T>::Binary(T rawValue) {
|
|
||||||
AngleOf<T> angle = AngleOf<T>();
|
AngleOf<T> angle = AngleOf<T>();
|
||||||
angle.SetBinary(rawValue);
|
angle.SetBinary(rawValue);
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> T AngleOf<T>::GetBinary() const { return this->value; }
|
||||||
T AngleOf<T>::GetBinary() const {
|
template <typename T> void AngleOf<T>::SetBinary(T rawValue) {
|
||||||
return this->value;
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
void AngleOf<T>::SetBinary(T rawValue) {
|
|
||||||
this->value = rawValue;
|
this->value = rawValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,28 +119,24 @@ bool AngleOf<T>::operator==(const AngleOf<T> angle) const {
|
|||||||
return this->value == angle.value;
|
return this->value == angle.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> bool AngleOf<T>::operator>(AngleOf<T> angle) const {
|
||||||
bool AngleOf<T>::operator>(AngleOf<T> angle) const {
|
|
||||||
return this->value > angle.value;
|
return this->value > angle.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> bool AngleOf<T>::operator>=(AngleOf<T> angle) const {
|
||||||
bool AngleOf<T>::operator>=(AngleOf<T> angle) const {
|
|
||||||
return this->value >= angle.value;
|
return this->value >= angle.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> bool AngleOf<T>::operator<(AngleOf<T> angle) const {
|
||||||
bool AngleOf<T>::operator<(AngleOf<T> angle) const {
|
|
||||||
return this->value < angle.value;
|
return this->value < angle.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> bool AngleOf<T>::operator<=(AngleOf<T> angle) const {
|
||||||
bool AngleOf<T>::operator<=(AngleOf<T> angle) const {
|
|
||||||
return this->value <= angle.value;
|
return this->value <= angle.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
signed int AngleOf<T>::Sign(AngleOf<T> angle) {
|
signed int Passer::LinearAlgebra::AngleOf<T>::Sign(AngleOf<T> angle) {
|
||||||
if (angle.value < 0)
|
if (angle.value < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (angle.value > 0)
|
if (angle.value > 0)
|
||||||
@ -168,15 +145,14 @@ signed int AngleOf<T>::Sign(AngleOf<T> angle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
AngleOf<T> AngleOf<T>::Abs(AngleOf<T> angle) {
|
AngleOf<T> Passer::LinearAlgebra::AngleOf<T>::Abs(AngleOf<T> angle) {
|
||||||
if (Sign(angle) < 0)
|
if (Sign(angle) < 0)
|
||||||
return -angle;
|
return -angle;
|
||||||
else
|
else
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> AngleOf<T> AngleOf<T>::operator-() const {
|
||||||
AngleOf<T> AngleOf<T>::operator-() const {
|
|
||||||
AngleOf<T> angle = Binary(-this->value);
|
AngleOf<T> angle = Binary(-this->value);
|
||||||
return angle;
|
return angle;
|
||||||
}
|
}
|
||||||
@ -230,8 +206,7 @@ AngleOf<T> AngleOf<T>::operator+=(const AngleOf<T>& angle) {
|
|||||||
// return AngleOf::Degrees((float)factor * angle.InDegrees());
|
// return AngleOf::Degrees((float)factor * angle.InDegrees());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> void AngleOf<T>::Normalize() {
|
||||||
void AngleOf<T>::Normalize() {
|
|
||||||
float angleValue = this->InDegrees();
|
float angleValue = this->InDegrees();
|
||||||
if (!isfinite(angleValue))
|
if (!isfinite(angleValue))
|
||||||
return;
|
return;
|
||||||
@ -243,8 +218,7 @@ void AngleOf<T>::Normalize() {
|
|||||||
*this = AngleOf::Degrees(angleValue);
|
*this = AngleOf::Degrees(angleValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> AngleOf<T> AngleOf<T>::Normalize(AngleOf<T> angle) {
|
||||||
AngleOf<T> AngleOf<T>::Normalize(AngleOf<T> angle) {
|
|
||||||
float angleValue = angle.InDegrees();
|
float angleValue = angle.InDegrees();
|
||||||
if (!isfinite(angleValue))
|
if (!isfinite(angleValue))
|
||||||
return angle;
|
return angle;
|
||||||
@ -263,8 +237,7 @@ AngleOf<T> AngleOf<T>::Clamp(AngleOf<T> angle, AngleOf<T> min, AngleOf<T> max) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
AngleOf<T> AngleOf<T>::MoveTowards(AngleOf<T> fromAngle,
|
AngleOf<T> AngleOf<T>::MoveTowards(AngleOf<T> fromAngle, AngleOf<T> toAngle,
|
||||||
AngleOf<T> toAngle,
|
|
||||||
float maxDegrees) {
|
float maxDegrees) {
|
||||||
maxDegrees = fmaxf(0, maxDegrees); // filter out negative distances
|
maxDegrees = fmaxf(0, maxDegrees); // filter out negative distances
|
||||||
AngleOf<T> d = toAngle - fromAngle;
|
AngleOf<T> d = toAngle - fromAngle;
|
||||||
@ -276,34 +249,28 @@ AngleOf<T> AngleOf<T>::MoveTowards(AngleOf<T> fromAngle,
|
|||||||
return fromAngle + d;
|
return fromAngle + d;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> float AngleOf<T>::Cos(AngleOf<T> angle) {
|
||||||
float AngleOf<T>::Cos(AngleOf<T> angle) {
|
|
||||||
return cosf(angle.InRadians());
|
return cosf(angle.InRadians());
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T> float AngleOf<T>::Sin(AngleOf<T> angle) {
|
||||||
float AngleOf<T>::Sin(AngleOf<T> angle) {
|
|
||||||
return sinf(angle.InRadians());
|
return sinf(angle.InRadians());
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T> float AngleOf<T>::Tan(AngleOf<T> angle) {
|
||||||
float AngleOf<T>::Tan(AngleOf<T> angle) {
|
|
||||||
return tanf(angle.InRadians());
|
return tanf(angle.InRadians());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> AngleOf<T> AngleOf<T>::Acos(float f) {
|
||||||
AngleOf<T> AngleOf<T>::Acos(float f) {
|
|
||||||
return AngleOf<T>::Radians(acosf(f));
|
return AngleOf<T>::Radians(acosf(f));
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T> AngleOf<T> AngleOf<T>::Asin(float f) {
|
||||||
AngleOf<T> AngleOf<T>::Asin(float f) {
|
|
||||||
return AngleOf<T>::Radians(asinf(f));
|
return AngleOf<T>::Radians(asinf(f));
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T> AngleOf<T> AngleOf<T>::Atan(float f) {
|
||||||
AngleOf<T> AngleOf<T>::Atan(float f) {
|
|
||||||
return AngleOf<T>::Radians(atanf(f));
|
return AngleOf<T>::Radians(atanf(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
AngleOf<T> AngleOf<T>::Atan2(float y, float x) {
|
AngleOf<T> Passer::LinearAlgebra::AngleOf<T>::Atan2(float y, float x) {
|
||||||
return AngleOf<T>::Radians(atan2f(y, x));
|
return AngleOf<T>::Radians(atan2f(y, x));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,8 +354,6 @@ AngleOf<T> AngleOf<T>::SineRuleAngle(float a, AngleOf<T> beta, float b) {
|
|||||||
return alpha;
|
return alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
template class AngleOf<float>;
|
template class Passer::LinearAlgebra::AngleOf<float>;
|
||||||
template class AngleOf<signed char>;
|
template class Passer::LinearAlgebra::AngleOf<signed char>;
|
||||||
template class AngleOf<signed short>;
|
template class Passer::LinearAlgebra::AngleOf<signed short>;
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
|
19
Angle.h
19
Angle.h
@ -5,6 +5,7 @@
|
|||||||
#ifndef ANGLE_H
|
#ifndef ANGLE_H
|
||||||
#define ANGLE_H
|
#define ANGLE_H
|
||||||
|
|
||||||
|
namespace Passer {
|
||||||
namespace LinearAlgebra {
|
namespace LinearAlgebra {
|
||||||
|
|
||||||
static float pi = 3.1415927410125732421875F;
|
static float pi = 3.1415927410125732421875F;
|
||||||
@ -17,11 +18,10 @@ static float Deg2Rad = (pi * 2) / 360.0f;
|
|||||||
/// The angle is internally limited to (-180..180] degrees or (-PI...PI]
|
/// The angle is internally limited to (-180..180] degrees or (-PI...PI]
|
||||||
/// radians. When an angle exceeds this range, it is normalized to a value
|
/// radians. When an angle exceeds this range, it is normalized to a value
|
||||||
/// within the range.
|
/// within the range.
|
||||||
template <typename T>
|
template <typename T> class AngleOf {
|
||||||
class AngleOf {
|
|
||||||
public:
|
public:
|
||||||
/// @brief Create a new angle with a zero value
|
/// @brief Create a new angle with a zero value
|
||||||
AngleOf();
|
AngleOf<T>();
|
||||||
|
|
||||||
/// @brief An zero value angle
|
/// @brief An zero value angle
|
||||||
const static AngleOf<T> zero;
|
const static AngleOf<T> zero;
|
||||||
@ -150,8 +150,7 @@ class AngleOf {
|
|||||||
/// @param toAngle The angle to rotate towards
|
/// @param toAngle The angle to rotate towards
|
||||||
/// @param maxAngle The maximum angle to rotate
|
/// @param maxAngle The maximum angle to rotate
|
||||||
/// @return The rotated angle
|
/// @return The rotated angle
|
||||||
static AngleOf<T> MoveTowards(AngleOf<T> fromAngle,
|
static AngleOf<T> MoveTowards(AngleOf<T> fromAngle, AngleOf<T> toAngle,
|
||||||
AngleOf<T> toAngle,
|
|
||||||
float maxAngle);
|
float maxAngle);
|
||||||
|
|
||||||
/// @brief Calculates the cosine of an angle
|
/// @brief Calculates the cosine of an angle
|
||||||
@ -209,19 +208,15 @@ class AngleOf {
|
|||||||
private:
|
private:
|
||||||
T value;
|
T value;
|
||||||
|
|
||||||
AngleOf(T rawValue);
|
AngleOf<T>(T rawValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
using AngleSingle = AngleOf<float>;
|
using AngleSingle = AngleOf<float>;
|
||||||
using Angle16 = AngleOf<signed short>;
|
using Angle16 = AngleOf<signed short>;
|
||||||
using Angle8 = AngleOf<signed char>;
|
using Angle8 = AngleOf<signed char>;
|
||||||
|
|
||||||
#if defined(ARDUINO)
|
|
||||||
using Angle = Angle16;
|
|
||||||
#else
|
|
||||||
using Angle = AngleSingle;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
} // namespace LinearAlgebra
|
||||||
|
} // namespace Passer
|
||||||
|
using namespace Passer::LinearAlgebra;
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -9,9 +9,7 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
namespace LinearAlgebra {
|
template <typename T> DirectionOf<T>::DirectionOf() {
|
||||||
template <typename T>
|
|
||||||
DirectionOf<T>::DirectionOf() {
|
|
||||||
this->horizontal = AngleOf<T>();
|
this->horizontal = AngleOf<T>();
|
||||||
this->vertical = AngleOf<T>();
|
this->vertical = AngleOf<T>();
|
||||||
}
|
}
|
||||||
@ -43,7 +41,7 @@ const DirectionOf<T> DirectionOf<T>::right =
|
|||||||
DirectionOf<T>(AngleOf<T>::Degrees(90), AngleOf<T>());
|
DirectionOf<T>(AngleOf<T>::Degrees(90), AngleOf<T>());
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Vector3 DirectionOf<T>::ToVector3() const {
|
Vector3 Passer::LinearAlgebra::DirectionOf<T>::ToVector3() const {
|
||||||
Quaternion q = Quaternion::Euler(-this->vertical.InDegrees(),
|
Quaternion q = Quaternion::Euler(-this->vertical.InDegrees(),
|
||||||
this->horizontal.InDegrees(), 0);
|
this->horizontal.InDegrees(), 0);
|
||||||
Vector3 v = q * Vector3::forward;
|
Vector3 v = q * Vector3::forward;
|
||||||
@ -51,12 +49,12 @@ Vector3 DirectionOf<T>::ToVector3() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
DirectionOf<T> DirectionOf<T>::FromVector3(Vector3 vector) {
|
DirectionOf<T>
|
||||||
|
Passer::LinearAlgebra::DirectionOf<T>::FromVector3(Vector3 vector) {
|
||||||
DirectionOf<T> d;
|
DirectionOf<T> d;
|
||||||
d.horizontal = AngleOf<T>::Atan2(
|
d.horizontal = AngleOf<T>::Atan2(
|
||||||
vector.Right(),
|
vector.Right(),
|
||||||
vector
|
vector.Forward()); // AngleOf<T>::Radians(atan2f(v.Right(), v.Forward()));
|
||||||
.Forward()); // AngleOf<T>::Radians(atan2f(v.Right(), v.Forward()));
|
|
||||||
d.vertical =
|
d.vertical =
|
||||||
AngleOf<T>::Degrees(-90) -
|
AngleOf<T>::Degrees(-90) -
|
||||||
AngleOf<T>::Acos(
|
AngleOf<T>::Acos(
|
||||||
@ -66,32 +64,34 @@ DirectionOf<T> DirectionOf<T>::FromVector3(Vector3 vector) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
DirectionOf<T> DirectionOf<T>::Degrees(float horizontal, float vertical) {
|
DirectionOf<T> Passer::LinearAlgebra::DirectionOf<T>::Degrees(float horizontal,
|
||||||
|
float vertical) {
|
||||||
return DirectionOf<T>(AngleOf<T>::Degrees(horizontal),
|
return DirectionOf<T>(AngleOf<T>::Degrees(horizontal),
|
||||||
AngleOf<T>::Degrees(vertical));
|
AngleOf<T>::Degrees(vertical));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
DirectionOf<T> DirectionOf<T>::Radians(float horizontal, float vertical) {
|
DirectionOf<T> Passer::LinearAlgebra::DirectionOf<T>::Radians(float horizontal,
|
||||||
|
float vertical) {
|
||||||
return DirectionOf<T>(AngleOf<T>::Radians(horizontal),
|
return DirectionOf<T>(AngleOf<T>::Radians(horizontal),
|
||||||
AngleOf<T>::Radians(vertical));
|
AngleOf<T>::Radians(vertical));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool DirectionOf<T>::operator==(const DirectionOf<T> direction) const {
|
bool Passer::LinearAlgebra::DirectionOf<T>::operator==(
|
||||||
|
const DirectionOf<T> direction) const {
|
||||||
return (this->horizontal == direction.horizontal) &&
|
return (this->horizontal == direction.horizontal) &&
|
||||||
(this->vertical == direction.vertical);
|
(this->vertical == direction.vertical);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
DirectionOf<T> DirectionOf<T>::operator-() const {
|
DirectionOf<T> Passer::LinearAlgebra::DirectionOf<T>::operator-() const {
|
||||||
DirectionOf<T> r = DirectionOf<T>(this->horizontal + AngleOf<T>::Degrees(180),
|
DirectionOf<T> r = DirectionOf<T>(this->horizontal + AngleOf<T>::Degrees(180),
|
||||||
-this->vertical);
|
-this->vertical);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> void DirectionOf<T>::Normalize() {
|
||||||
void DirectionOf<T>::Normalize() {
|
|
||||||
if (this->vertical > AngleOf<T>::Degrees(90) ||
|
if (this->vertical > AngleOf<T>::Degrees(90) ||
|
||||||
this->vertical < AngleOf<T>::Degrees(-90)) {
|
this->vertical < AngleOf<T>::Degrees(-90)) {
|
||||||
this->horizontal += AngleOf<T>::Degrees(180);
|
this->horizontal += AngleOf<T>::Degrees(180);
|
||||||
@ -99,6 +99,5 @@ void DirectionOf<T>::Normalize() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template class LinearAlgebra::DirectionOf<float>;
|
template class Passer::LinearAlgebra::DirectionOf<float>;
|
||||||
template class LinearAlgebra::DirectionOf<signed short>;
|
template class Passer::LinearAlgebra::DirectionOf<signed short>;
|
||||||
}
|
|
||||||
|
26
Direction.h
26
Direction.h
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "Angle.h"
|
#include "Angle.h"
|
||||||
|
|
||||||
|
namespace Passer {
|
||||||
namespace LinearAlgebra {
|
namespace LinearAlgebra {
|
||||||
|
|
||||||
struct Vector3;
|
struct Vector3;
|
||||||
@ -21,21 +22,20 @@ struct Vector3;
|
|||||||
/// rotation has been applied.
|
/// rotation has been applied.
|
||||||
/// The angles are automatically normalized to stay within the abovenmentioned
|
/// The angles are automatically normalized to stay within the abovenmentioned
|
||||||
/// ranges.
|
/// ranges.
|
||||||
template <typename T>
|
template <typename T> class DirectionOf {
|
||||||
class DirectionOf {
|
|
||||||
public:
|
public:
|
||||||
|
/// @brief Create a new direction with zero angles
|
||||||
|
DirectionOf<T>();
|
||||||
|
/// @brief Create a new direction
|
||||||
|
/// @param horizontal The horizontal angle
|
||||||
|
/// @param vertical The vertical angle.
|
||||||
|
DirectionOf<T>(AngleOf<T> horizontal, AngleOf<T> vertical);
|
||||||
|
|
||||||
/// @brief horizontal angle, range= (-180..180]
|
/// @brief horizontal angle, range= (-180..180]
|
||||||
AngleOf<T> horizontal;
|
AngleOf<T> horizontal;
|
||||||
/// @brief vertical angle, range in degrees = (-90..90]
|
/// @brief vertical angle, range in degrees = (-90..90]
|
||||||
AngleOf<T> vertical;
|
AngleOf<T> vertical;
|
||||||
|
|
||||||
/// @brief Create a new direction with zero angles
|
|
||||||
DirectionOf();
|
|
||||||
/// @brief Create a new direction
|
|
||||||
/// @param horizontal The horizontal angle
|
|
||||||
/// @param vertical The vertical angle.
|
|
||||||
DirectionOf(AngleOf<T> horizontal, AngleOf<T> vertical);
|
|
||||||
|
|
||||||
/// @brief Convert the direction into a carthesian vector
|
/// @brief Convert the direction into a carthesian vector
|
||||||
/// @return The carthesian vector corresponding to this direction.
|
/// @return The carthesian vector corresponding to this direction.
|
||||||
Vector3 ToVector3() const;
|
Vector3 ToVector3() const;
|
||||||
@ -91,12 +91,8 @@ class DirectionOf {
|
|||||||
using DirectionSingle = DirectionOf<float>;
|
using DirectionSingle = DirectionOf<float>;
|
||||||
using Direction16 = DirectionOf<signed short>;
|
using Direction16 = DirectionOf<signed short>;
|
||||||
|
|
||||||
#if defined(ARDUINO)
|
|
||||||
using Direction = Direction16;
|
|
||||||
#else
|
|
||||||
using Direction = DirectionSingle;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
} // namespace LinearAlgebra
|
||||||
|
} // namespace Passer
|
||||||
|
using namespace Passer::LinearAlgebra;
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -5,6 +5,7 @@
|
|||||||
#ifndef FLOAT_H
|
#ifndef FLOAT_H
|
||||||
#define FLOAT_H
|
#define FLOAT_H
|
||||||
|
|
||||||
|
namespace Passer {
|
||||||
namespace LinearAlgebra {
|
namespace LinearAlgebra {
|
||||||
|
|
||||||
class Float {
|
class Float {
|
||||||
@ -16,7 +17,7 @@ class Float {
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
} // namespace LinearAlgebra
|
||||||
|
} // namespace Passer
|
||||||
using namespace LinearAlgebra;
|
using namespace Passer::LinearAlgebra;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
295
Matrix.cpp
295
Matrix.cpp
@ -1,290 +1,6 @@
|
|||||||
#include "Matrix.h"
|
#include "Matrix.h"
|
||||||
#if !defined(NO_STD)
|
|
||||||
#include <iostream>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace LinearAlgebra {
|
template <> MatrixOf<float>::MatrixOf(unsigned int rows, unsigned int cols) {
|
||||||
|
|
||||||
#pragma region Matrix1
|
|
||||||
|
|
||||||
Matrix1::Matrix1(int size) : size(size) {
|
|
||||||
if (this->size == 0)
|
|
||||||
data = nullptr;
|
|
||||||
else {
|
|
||||||
this->data = new float[size]();
|
|
||||||
this->externalData = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix1::Matrix1(float* data, int size) : data(data), size(size) {
|
|
||||||
this->externalData = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix1 LinearAlgebra::Matrix1::FromQuaternion(Quaternion q) {
|
|
||||||
Matrix1 r = Matrix1(4);
|
|
||||||
float* data = r.data;
|
|
||||||
data[0] = q.x;
|
|
||||||
data[1] = q.y;
|
|
||||||
data[2] = q.z;
|
|
||||||
data[3] = q.w;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Quaternion LinearAlgebra::Matrix1::ToQuaternion() {
|
|
||||||
return Quaternion(this->data[0], this->data[1], this->data[2], this->data[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Matrix1
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
#pragma region Matrix2
|
|
||||||
|
|
||||||
Matrix2::Matrix2() {}
|
|
||||||
|
|
||||||
Matrix2::Matrix2(int nRows, int nCols) : nRows(nRows), nCols(nCols) {
|
|
||||||
this->nValues = nRows * nCols;
|
|
||||||
if (this->nValues == 0)
|
|
||||||
this->data = nullptr;
|
|
||||||
else {
|
|
||||||
this->data = new float[this->nValues];
|
|
||||||
this->externalData = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2::Matrix2(float* data, int nRows, int nCols)
|
|
||||||
: nRows(nRows), nCols(nCols), data(data) {
|
|
||||||
this->nValues = nRows * nCols;
|
|
||||||
this->externalData = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2::Matrix2(const Matrix2& m)
|
|
||||||
: nRows(m.nRows), nCols(m.nCols), nValues(m.nValues) {
|
|
||||||
if (this->nValues == 0)
|
|
||||||
this->data = nullptr;
|
|
||||||
else {
|
|
||||||
this->data = new float[this->nValues];
|
|
||||||
|
|
||||||
for (int ix = 0; ix < this->nValues; ++ix)
|
|
||||||
this->data[ix] = m.data[ix];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2& Matrix2::operator=(const Matrix2& m) {
|
|
||||||
if (this != &m) {
|
|
||||||
delete[] this->data; // Free the current memory
|
|
||||||
|
|
||||||
this->nRows = m.nRows;
|
|
||||||
this->nCols = m.nCols;
|
|
||||||
this->nValues = m.nValues;
|
|
||||||
if (this->nValues == 0)
|
|
||||||
this->data = nullptr;
|
|
||||||
else {
|
|
||||||
this->data = new float[this->nValues];
|
|
||||||
for (int ix = 0; ix < this->nValues; ++ix)
|
|
||||||
this->data[ix] = m.data[ix];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2::~Matrix2() {
|
|
||||||
if (!this->externalData)
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2 Matrix2::Clone() const {
|
|
||||||
Matrix2 r = Matrix2(this->nRows, this->nCols);
|
|
||||||
for (int ix = 0; ix < this->nValues; ++ix)
|
|
||||||
r.data[ix] = this->data[ix];
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move constructor
|
|
||||||
Matrix2::Matrix2(Matrix2&& other) noexcept
|
|
||||||
: nRows(other.nRows),
|
|
||||||
nCols(other.nCols),
|
|
||||||
nValues(other.nValues),
|
|
||||||
data(other.data) {
|
|
||||||
other.data = nullptr; // Set the other object's pointer to nullptr to avoid
|
|
||||||
// double deletion
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move assignment operator
|
|
||||||
Matrix2& Matrix2::operator=(Matrix2&& other) noexcept {
|
|
||||||
if (this != &other) {
|
|
||||||
delete[] data; // Clean up current data
|
|
||||||
nRows = other.nRows;
|
|
||||||
nCols = other.nCols;
|
|
||||||
nValues = other.nValues;
|
|
||||||
data = other.data;
|
|
||||||
other.data = nullptr; // Avoid double deletion
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2 Matrix2::Zero(int nRows, int nCols) {
|
|
||||||
Matrix2 r = Matrix2(nRows, nCols);
|
|
||||||
for (int ix = 0; ix < r.nValues; ix++)
|
|
||||||
r.data[ix] = 0;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Matrix2::Clear() {
|
|
||||||
for (int ix = 0; ix < this->nValues; ix++)
|
|
||||||
this->data[ix] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2 Matrix2::Identity(int size) {
|
|
||||||
return Diagonal(1, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2 Matrix2::Diagonal(float f, int size) {
|
|
||||||
Matrix2 r = Matrix2::Zero(size, size);
|
|
||||||
float* data = r.data;
|
|
||||||
int valueIx = 0;
|
|
||||||
for (int ix = 0; ix < size; ix++) {
|
|
||||||
data[valueIx] = f;
|
|
||||||
valueIx += size + 1;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2 Matrix2::SkewMatrix(const Vector3& v) {
|
|
||||||
Matrix2 r = Matrix2(3, 3);
|
|
||||||
float* data = r.data;
|
|
||||||
data[0 * 3 + 1] = -v.z; // result(0, 1)
|
|
||||||
data[0 * 3 + 2] = v.y; // result(0, 2)
|
|
||||||
data[1 * 3 + 0] = v.z; // result(1, 0)
|
|
||||||
data[1 * 3 + 2] = -v.x; // result(1, 2)
|
|
||||||
data[2 * 3 + 0] = -v.y; // result(2, 0)
|
|
||||||
data[2 * 3 + 1] = v.x; // result(2, 1)
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2 Matrix2::Transpose() const {
|
|
||||||
Matrix2 r = Matrix2(this->nCols, this->nRows);
|
|
||||||
|
|
||||||
for (int rowIx = 0; rowIx < this->nRows; rowIx++) {
|
|
||||||
for (int colIx = 0; colIx < this->nCols; colIx++)
|
|
||||||
r.data[colIx * this->nCols + rowIx] =
|
|
||||||
this->data[rowIx * this->nCols + colIx];
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2 LinearAlgebra::Matrix2::operator-() const {
|
|
||||||
Matrix2 r = Matrix2(this->nRows, this->nCols);
|
|
||||||
for (int ix = 0; ix < r.nValues; ix++)
|
|
||||||
r.data[ix] = -this->data[ix];
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2 LinearAlgebra::Matrix2::operator+(const Matrix2& v) const {
|
|
||||||
Matrix2 r = Matrix2(this->nRows, this->nCols);
|
|
||||||
for (int ix = 0; ix < r.nValues; ix++)
|
|
||||||
r.data[ix] = this->data[ix] + v.data[ix];
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2 Matrix2::operator+=(const Matrix2& v) {
|
|
||||||
for (int ix = 0; ix < this->nValues; ix++)
|
|
||||||
this->data[ix] += v.data[ix];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2 LinearAlgebra::Matrix2::operator*(const Matrix2& B) const {
|
|
||||||
Matrix2 r = Matrix2(this->nRows, B.nCols);
|
|
||||||
|
|
||||||
int ACols = this->nCols;
|
|
||||||
int BCols = B.nCols;
|
|
||||||
int ARows = this->nRows;
|
|
||||||
// int BRows = B.nRows;
|
|
||||||
|
|
||||||
for (int i = 0; i < ARows; ++i) {
|
|
||||||
// Pre-compute row offsets
|
|
||||||
int ARowOffset = i * ACols; // ARowOffset is constant for each row of A
|
|
||||||
int BColOffset = i * BCols; // BColOffset is constant for each row of B
|
|
||||||
for (int j = 0; j < BCols; ++j) {
|
|
||||||
float sum = 0;
|
|
||||||
std::cout << " 0";
|
|
||||||
int BIndex = j;
|
|
||||||
for (int k = 0; k < ACols; ++k) {
|
|
||||||
std::cout << " + " << this->data[ARowOffset + k] << " * "
|
|
||||||
<< B.data[BIndex];
|
|
||||||
sum += this->data[ARowOffset + k] * B.data[BIndex];
|
|
||||||
BIndex += BCols;
|
|
||||||
}
|
|
||||||
r.data[BColOffset + j] = sum;
|
|
||||||
std::cout << " = " << sum << " ix: " << BColOffset + j << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2 Matrix2::Slice(int rowStart, int rowStop, int colStart, int colStop) {
|
|
||||||
Matrix2 r = Matrix2(rowStop - rowStart, colStop - colStart);
|
|
||||||
|
|
||||||
int resultRowIx = 0;
|
|
||||||
int resultColIx = 0;
|
|
||||||
for (int i = rowStart; i < rowStop; i++) {
|
|
||||||
for (int j = colStart; j < colStop; j++)
|
|
||||||
r.data[resultRowIx * r.nCols + resultColIx] =
|
|
||||||
this->data[i * this->nCols + j];
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Matrix2::UpdateSlice(int rowStart,
|
|
||||||
int rowStop,
|
|
||||||
int colStart,
|
|
||||||
int colStop,
|
|
||||||
const Matrix2& m) const {
|
|
||||||
// for (int i = rowStart; i < rowStop; i++) {
|
|
||||||
// for (int j = colStart; j < colStop; j++)
|
|
||||||
// this->data[i * this->nCols + j] =
|
|
||||||
// m.data[(i - rowStart) * m.nCols + (j - colStart)];
|
|
||||||
// }
|
|
||||||
|
|
||||||
int rRowDataIx = rowStart * this->nCols;
|
|
||||||
int mRowDataIx = 0;
|
|
||||||
for (int rowIx = rowStart; rowIx < rowStop; rowIx++) {
|
|
||||||
rRowDataIx = rowIx * this->nCols;
|
|
||||||
// rRowDataIx += this->nCols;
|
|
||||||
mRowDataIx += m.nCols;
|
|
||||||
for (int colIx = colStart; colIx < colStop; colIx++) {
|
|
||||||
this->data[rRowDataIx + colIx] = m.data[mRowDataIx + (colIx - colStart)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Compute the Omega matrix of a 3D vector
|
|
||||||
/// @param v The vector
|
|
||||||
/// @return 4x4 Omega matrix
|
|
||||||
Matrix2 LinearAlgebra::Matrix2::Omega(const Vector3& v) {
|
|
||||||
Matrix2 r = Matrix2::Zero(4, 4);
|
|
||||||
r.UpdateSlice(0, 3, 0, 3, -Matrix2::SkewMatrix(v));
|
|
||||||
|
|
||||||
// set last row to -v
|
|
||||||
int ix = 3 * 4;
|
|
||||||
r.data[ix++] = -v.x;
|
|
||||||
r.data[ix++] = -v.y;
|
|
||||||
r.data[ix] = -v.z;
|
|
||||||
|
|
||||||
// Set last column to v
|
|
||||||
ix = 3;
|
|
||||||
r.data[ix += 4] = v.x;
|
|
||||||
r.data[ix += 4] = v.y;
|
|
||||||
r.data[ix] = v.z;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Matrix2
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
|
||||||
|
|
||||||
template <>
|
|
||||||
MatrixOf<float>::MatrixOf(unsigned int rows, unsigned int cols) {
|
|
||||||
if (rows <= 0 || cols <= 0) {
|
if (rows <= 0 || cols <= 0) {
|
||||||
this->rows = 0;
|
this->rows = 0;
|
||||||
this->cols = 0;
|
this->cols = 0;
|
||||||
@ -298,8 +14,7 @@ MatrixOf<float>::MatrixOf(unsigned int rows, unsigned int cols) {
|
|||||||
this->data = new float[matrixSize]{0.0f};
|
this->data = new float[matrixSize]{0.0f};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <> MatrixOf<float>::MatrixOf(Vector3 v) : MatrixOf(3, 1) {
|
||||||
MatrixOf<float>::MatrixOf(Vector3 v) : MatrixOf(3, 1) {
|
|
||||||
Set(0, 0, v.Right());
|
Set(0, 0, v.Right());
|
||||||
Set(1, 0, v.Up());
|
Set(1, 0, v.Up());
|
||||||
Set(2, 0, v.Forward());
|
Set(2, 0, v.Forward());
|
||||||
@ -307,8 +22,7 @@ MatrixOf<float>::MatrixOf(Vector3 v) : MatrixOf(3, 1) {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
void MatrixOf<float>::Multiply(const MatrixOf<float> *m1,
|
void MatrixOf<float>::Multiply(const MatrixOf<float> *m1,
|
||||||
const MatrixOf<float>* m2,
|
const MatrixOf<float> *m2, MatrixOf<float> *r) {
|
||||||
MatrixOf<float>* r) {
|
|
||||||
for (unsigned int rowIx1 = 0; rowIx1 < m1->rows; rowIx1++) {
|
for (unsigned int rowIx1 = 0; rowIx1 < m1->rows; rowIx1++) {
|
||||||
for (unsigned int colIx2 = 0; colIx2 < m2->cols; colIx2++) {
|
for (unsigned int colIx2 = 0; colIx2 < m2->cols; colIx2++) {
|
||||||
unsigned int rDataIx = colIx2 * m2->cols + rowIx1;
|
unsigned int rDataIx = colIx2 * m2->cols + rowIx1;
|
||||||
@ -333,8 +47,7 @@ Vector3 MatrixOf<float>::Multiply(const MatrixOf<float>* m, Vector3 v) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> Vector3 MatrixOf<T>::operator*(const Vector3 v) const {
|
||||||
Vector3 MatrixOf<T>::operator*(const Vector3 v) const {
|
|
||||||
float *vData = new float[3]{v.Right(), v.Up(), v.Forward()};
|
float *vData = new float[3]{v.Right(), v.Up(), v.Forward()};
|
||||||
MatrixOf<float> v_m = MatrixOf<float>(3, 1, vData);
|
MatrixOf<float> v_m = MatrixOf<float>(3, 1, vData);
|
||||||
float *rData = new float[3]{};
|
float *rData = new float[3]{};
|
||||||
|
119
Matrix.h
119
Matrix.h
@ -1,122 +1,13 @@
|
|||||||
#ifndef MATRIX_H
|
#ifndef MATRIX_H
|
||||||
#define MATRIX_H
|
#define MATRIX_H
|
||||||
|
|
||||||
#include "Quaternion.h"
|
|
||||||
#include "Vector3.h"
|
#include "Vector3.h"
|
||||||
|
|
||||||
|
namespace Passer {
|
||||||
namespace LinearAlgebra {
|
namespace LinearAlgebra {
|
||||||
|
|
||||||
/// @brief A 1-dimensional matrix or vector of arbitrary size
|
|
||||||
class Matrix1 {
|
|
||||||
public:
|
|
||||||
float* data = nullptr;
|
|
||||||
int size = 0;
|
|
||||||
|
|
||||||
Matrix1(int size);
|
|
||||||
Matrix1(float* data, int size);
|
|
||||||
|
|
||||||
static Matrix1 FromQuaternion(Quaternion q);
|
|
||||||
Quaternion ToQuaternion();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool externalData = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @brief A 2-dimensional matrix of arbitrary size
|
|
||||||
class Matrix2 {
|
|
||||||
public:
|
|
||||||
int nRows = 0;
|
|
||||||
int nCols = 0;
|
|
||||||
int nValues = 0;
|
|
||||||
float* data = nullptr;
|
|
||||||
|
|
||||||
Matrix2();
|
|
||||||
Matrix2(int nRows, int nCols);
|
|
||||||
Matrix2(float* data, int nRows, int nCols);
|
|
||||||
Matrix2(const Matrix2& m);
|
|
||||||
Matrix2& operator=(const Matrix2& other);
|
|
||||||
|
|
||||||
~Matrix2();
|
|
||||||
|
|
||||||
Matrix2 Clone() const;
|
|
||||||
|
|
||||||
static Matrix2 Zero(int nRows, int nCols);
|
|
||||||
void Clear();
|
|
||||||
|
|
||||||
static Matrix2 Identity(int size);
|
|
||||||
|
|
||||||
static Matrix2 Diagonal(float f, int size);
|
|
||||||
|
|
||||||
static Matrix2 SkewMatrix(const Vector3& v);
|
|
||||||
|
|
||||||
Matrix2 Transpose() const;
|
|
||||||
|
|
||||||
Matrix2 operator-() const;
|
|
||||||
|
|
||||||
/// @brief Add a matrix to this matrix
|
|
||||||
/// @param m The matrix to add to this matrix
|
|
||||||
/// @return The result of the addition
|
|
||||||
Matrix2 operator+(const Matrix2& v) const;
|
|
||||||
Matrix2 operator+=(const Matrix2& v);
|
|
||||||
|
|
||||||
Matrix2 operator*(const Matrix2& m) const;
|
|
||||||
friend Matrix2 operator*(const Matrix2& m, float f) {
|
|
||||||
Matrix2 r = Matrix2(m.nRows, m.nCols);
|
|
||||||
for (int ix = 0; ix < r.nValues; ix++)
|
|
||||||
r.data[ix] = m.data[ix] * f;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
friend Matrix2 operator*(float f, const Matrix2& m) {
|
|
||||||
Matrix2 r = Matrix2(m.nRows, m.nCols);
|
|
||||||
for (int ix = 0; ix < r.nValues; ix++)
|
|
||||||
r.data[ix] = f * m.data[ix];
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend Matrix1 operator*(const Matrix2& m, const Matrix1& v) {
|
|
||||||
Matrix1 r = Matrix1(m.nRows);
|
|
||||||
for (int rowIx = 0; rowIx < m.nRows; rowIx++) {
|
|
||||||
int mRowIx = rowIx * m.nCols;
|
|
||||||
for (int colIx = 0; colIx < m.nCols; colIx++)
|
|
||||||
r.data[rowIx] += m.data[mRowIx + colIx] * v.data[rowIx];
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend Matrix2 operator/(const Matrix2& m, float f) {
|
|
||||||
Matrix2 r = Matrix2(m.nRows, m.nCols);
|
|
||||||
for (int ix = 0; ix < r.nValues; ix++)
|
|
||||||
r.data[ix] = m.data[ix] / f;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
friend Matrix2 operator/(float f, const Matrix2& m) {
|
|
||||||
Matrix2 r = Matrix2(m.nRows, m.nCols);
|
|
||||||
for (int ix = 0; ix < r.nValues; ix++)
|
|
||||||
r.data[ix] = f / m.data[ix];
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix2 Slice(int rawStart, int rowStop, int colStart, int colStop);
|
|
||||||
|
|
||||||
void UpdateSlice(int rowStart,
|
|
||||||
int rowStop,
|
|
||||||
int colStart,
|
|
||||||
int colStop,
|
|
||||||
const Matrix2& m) const;
|
|
||||||
// private:
|
|
||||||
// move constructor and move assignment operator
|
|
||||||
Matrix2(Matrix2&& other) noexcept;
|
|
||||||
Matrix2& operator=(Matrix2&& other) noexcept;
|
|
||||||
|
|
||||||
static Matrix2 Omega(const Vector3& v);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool externalData = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @brief Single precision float matrix
|
/// @brief Single precision float matrix
|
||||||
template <typename T>
|
template <typename T> class MatrixOf {
|
||||||
class MatrixOf {
|
|
||||||
public:
|
public:
|
||||||
MatrixOf(unsigned int rows, unsigned int cols);
|
MatrixOf(unsigned int rows, unsigned int cols);
|
||||||
MatrixOf(unsigned int rows, unsigned int cols, const T *source)
|
MatrixOf(unsigned int rows, unsigned int cols, const T *source)
|
||||||
@ -163,8 +54,7 @@ class MatrixOf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Multiply(const MatrixOf<T>* m1,
|
static void Multiply(const MatrixOf<T> *m1, const MatrixOf<T> *m2,
|
||||||
const MatrixOf<T>* m2,
|
|
||||||
MatrixOf<T> *r);
|
MatrixOf<T> *r);
|
||||||
void Multiply(const MatrixOf<T> *m, MatrixOf<T> *r) const {
|
void Multiply(const MatrixOf<T> *m, MatrixOf<T> *r) const {
|
||||||
Multiply(this, m, r);
|
Multiply(this, m, r);
|
||||||
@ -225,6 +115,7 @@ class MatrixOf {
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
} // namespace LinearAlgebra
|
||||||
// using namespace LinearAlgebra;
|
} // namespace Passer
|
||||||
|
using namespace Passer::LinearAlgebra;
|
||||||
|
|
||||||
#endif
|
#endif
|
50
Polar.cpp
50
Polar.cpp
@ -3,13 +3,11 @@
|
|||||||
#include "Polar.h"
|
#include "Polar.h"
|
||||||
#include "Vector2.h"
|
#include "Vector2.h"
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> PolarOf<T>::PolarOf() {
|
||||||
PolarOf<T>::PolarOf() {
|
|
||||||
this->distance = 0.0f;
|
this->distance = 0.0f;
|
||||||
this->angle = AngleOf<T>();
|
this->angle = AngleOf<T>();
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T> PolarOf<T>::PolarOf(float distance, AngleOf<T> angle) {
|
||||||
PolarOf<T>::PolarOf(float distance, AngleOf<T> angle) {
|
|
||||||
// distance should always be 0 or greater
|
// distance should always be 0 or greater
|
||||||
if (distance < 0.0f) {
|
if (distance < 0.0f) {
|
||||||
this->distance = -distance;
|
this->distance = -distance;
|
||||||
@ -36,18 +34,16 @@ PolarOf<T> PolarOf<T>::Radians(float distance, float radians) {
|
|||||||
return PolarOf<T>(distance, AngleOf<T>::Radians(radians));
|
return PolarOf<T>(distance, AngleOf<T>::Radians(radians));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> PolarOf<T> PolarOf<T>::FromVector2(Vector2 v) {
|
||||||
PolarOf<T> PolarOf<T>::FromVector2(Vector2 v) {
|
|
||||||
float distance = v.magnitude();
|
float distance = v.magnitude();
|
||||||
AngleOf<T> angle =
|
AngleOf<T> angle =
|
||||||
AngleOf<T>::Degrees(Vector2::SignedAngle(Vector2::forward, v));
|
AngleOf<T>::Degrees(Vector2::SignedAngle(Vector2::forward, v));
|
||||||
PolarOf<T> p = PolarOf(distance, angle);
|
PolarOf<T> p = PolarOf(distance, angle);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T> PolarOf<T> PolarOf<T>::FromSpherical(SphericalOf<T> v) {
|
||||||
PolarOf<T> PolarOf<T>::FromSpherical(SphericalOf<T> v) {
|
float distance = v.distance * cosf(v.direction.vertical.InDegrees() *
|
||||||
float distance =
|
Passer::LinearAlgebra::Deg2Rad);
|
||||||
v.distance * cosf(v.direction.vertical.InDegrees() * Deg2Rad);
|
|
||||||
AngleOf<T> angle = v.direction.horizontal;
|
AngleOf<T> angle = v.direction.horizontal;
|
||||||
PolarOf<T> p = PolarOf(distance, angle);
|
PolarOf<T> p = PolarOf(distance, angle);
|
||||||
return p;
|
return p;
|
||||||
@ -64,37 +60,31 @@ const PolarOf<T> PolarOf<T>::right = PolarOf(1.0, AngleOf<T>::Degrees(90));
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
const PolarOf<T> PolarOf<T>::left = PolarOf(1.0, AngleOf<T>::Degrees(-90));
|
const PolarOf<T> PolarOf<T>::left = PolarOf(1.0, AngleOf<T>::Degrees(-90));
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> bool PolarOf<T>::operator==(const PolarOf &v) const {
|
||||||
bool PolarOf<T>::operator==(const PolarOf& v) const {
|
|
||||||
return (this->distance == v.distance &&
|
return (this->distance == v.distance &&
|
||||||
this->angle.InDegrees() == v.angle.InDegrees());
|
this->angle.InDegrees() == v.angle.InDegrees());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> PolarOf<T> PolarOf<T>::Normalize(const PolarOf &v) {
|
||||||
PolarOf<T> PolarOf<T>::Normalize(const PolarOf& v) {
|
|
||||||
PolarOf<T> r = PolarOf(1, v.angle);
|
PolarOf<T> r = PolarOf(1, v.angle);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T> PolarOf<T> PolarOf<T>::normalized() const {
|
||||||
PolarOf<T> PolarOf<T>::normalized() const {
|
|
||||||
PolarOf<T> r = PolarOf(1, this->angle);
|
PolarOf<T> r = PolarOf(1, this->angle);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> PolarOf<T> PolarOf<T>::operator-() const {
|
||||||
PolarOf<T> PolarOf<T>::operator-() const {
|
|
||||||
PolarOf<T> v =
|
PolarOf<T> v =
|
||||||
PolarOf(this->distance, this->angle + AngleOf<T>::Degrees(180));
|
PolarOf(this->distance, this->angle + AngleOf<T>::Degrees(180));
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> PolarOf<T> PolarOf<T>::operator-(const PolarOf &v) const {
|
||||||
PolarOf<T> PolarOf<T>::operator-(const PolarOf& v) const {
|
|
||||||
PolarOf<T> r = -v;
|
PolarOf<T> r = -v;
|
||||||
return *this + r;
|
return *this + r;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T> PolarOf<T> PolarOf<T>::operator-=(const PolarOf &v) {
|
||||||
PolarOf<T> PolarOf<T>::operator-=(const PolarOf& v) {
|
|
||||||
*this = *this - v;
|
*this = *this - v;
|
||||||
return *this;
|
return *this;
|
||||||
// angle = AngleOf<T>::Normalize(newAngle);
|
// angle = AngleOf<T>::Normalize(newAngle);
|
||||||
@ -115,8 +105,7 @@ PolarOf<T> PolarOf<T>::operator-=(const PolarOf& v) {
|
|||||||
// return d;
|
// return d;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> PolarOf<T> PolarOf<T>::operator+(const PolarOf &v) const {
|
||||||
PolarOf<T> PolarOf<T>::operator+(const PolarOf& v) const {
|
|
||||||
if (v.distance == 0)
|
if (v.distance == 0)
|
||||||
return PolarOf(this->distance, this->angle);
|
return PolarOf(this->distance, this->angle);
|
||||||
if (this->distance == 0.0f)
|
if (this->distance == 0.0f)
|
||||||
@ -144,19 +133,16 @@ PolarOf<T> PolarOf<T>::operator+(const PolarOf& v) const {
|
|||||||
PolarOf vector = PolarOf(newDistance, newAngleA);
|
PolarOf vector = PolarOf(newDistance, newAngleA);
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T> PolarOf<T> PolarOf<T>::operator+=(const PolarOf &v) {
|
||||||
PolarOf<T> PolarOf<T>::operator+=(const PolarOf& v) {
|
|
||||||
*this = *this + v;
|
*this = *this + v;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> PolarOf<T> PolarOf<T>::operator*=(float f) {
|
||||||
PolarOf<T> PolarOf<T>::operator*=(float f) {
|
|
||||||
this->distance *= f;
|
this->distance *= f;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T> PolarOf<T> PolarOf<T>::operator/=(float f) {
|
||||||
PolarOf<T> PolarOf<T>::operator/=(float f) {
|
|
||||||
this->distance /= f;
|
this->distance /= f;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -175,5 +161,5 @@ PolarOf<T> PolarOf<T>::Rotate(const PolarOf& v, AngleOf<T> angle) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template class LinearAlgebra::PolarOf<float>;
|
template class Passer::LinearAlgebra::PolarOf<float>;
|
||||||
template class LinearAlgebra::PolarOf<signed short>;
|
template class Passer::LinearAlgebra::PolarOf<signed short>;
|
10
Polar.h
10
Polar.h
@ -7,16 +7,15 @@
|
|||||||
|
|
||||||
#include "Angle.h"
|
#include "Angle.h"
|
||||||
|
|
||||||
|
namespace Passer {
|
||||||
namespace LinearAlgebra {
|
namespace LinearAlgebra {
|
||||||
|
|
||||||
struct Vector2;
|
struct Vector2;
|
||||||
template <typename T>
|
template <typename T> class SphericalOf;
|
||||||
class SphericalOf;
|
|
||||||
|
|
||||||
/// @brief A polar vector using an angle in various representations
|
/// @brief A polar vector using an angle in various representations
|
||||||
/// @tparam T The implementation type used for the representation of the angle
|
/// @tparam T The implementation type used for the representation of the angle
|
||||||
template <typename T>
|
template <typename T> class PolarOf {
|
||||||
class PolarOf {
|
|
||||||
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
|
||||||
@ -154,7 +153,8 @@ using Polar16 = PolarOf<signed short>;
|
|||||||
// using Polar = PolarSingle;
|
// using Polar = PolarSingle;
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
} // namespace LinearAlgebra
|
||||||
using namespace LinearAlgebra;
|
} // namespace Passer
|
||||||
|
using namespace Passer::LinearAlgebra;
|
||||||
|
|
||||||
#include "Spherical.h"
|
#include "Spherical.h"
|
||||||
#include "Vector2.h"
|
#include "Vector2.h"
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "Angle.h"
|
#include "Angle.h"
|
||||||
#include "Matrix.h"
|
|
||||||
#include "Vector3.h"
|
#include "Vector3.h"
|
||||||
|
|
||||||
void CopyQuat(const Quat& q1, Quat& q2) {
|
void CopyQuat(const Quat& q1, Quat& q2) {
|
||||||
@ -98,28 +97,6 @@ Vector3 Quaternion::ToAngles(const Quaternion& q1) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix2 LinearAlgebra::Quaternion::ToRotationMatrix() {
|
|
||||||
Matrix2 r = Matrix2(3, 3);
|
|
||||||
|
|
||||||
float x = this->x;
|
|
||||||
float y = this->y;
|
|
||||||
float z = this->z;
|
|
||||||
float w = this->w;
|
|
||||||
|
|
||||||
float* data = r.data;
|
|
||||||
data[0 * 3 + 0] = 1 - 2 * (y * y + z * z);
|
|
||||||
data[0 * 3 + 1] = 2 * (x * y - w * z);
|
|
||||||
data[0 * 3 + 2] = 2 * (x * z + w * y);
|
|
||||||
data[1 * 3 + 0] = 2 * (x * y + w * z);
|
|
||||||
data[1 * 3 + 1] = 1 - 2 * (x * x + z * z);
|
|
||||||
data[1 * 3 + 2] = 2 * (y * z - w * x);
|
|
||||||
data[2 * 3 + 0] = 2 * (x * z - w * y);
|
|
||||||
data[2 * 3 + 1] = 2 * (y * z + w * x);
|
|
||||||
data[2 * 3 + 2] = 1 - 2 * (x * x + y * y);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Quaternion Quaternion::operator*(const Quaternion& r2) const {
|
Quaternion Quaternion::operator*(const Quaternion& r2) const {
|
||||||
return Quaternion(
|
return Quaternion(
|
||||||
this->x * r2.w + this->y * r2.z - this->z * r2.y + this->w * r2.x,
|
this->x * r2.w + this->y * r2.z - this->z * r2.y + this->w * r2.x,
|
||||||
|
23
Quaternion.h
23
Quaternion.h
@ -32,10 +32,9 @@ typedef struct Quat {
|
|||||||
} Quat;
|
} Quat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Passer {
|
||||||
namespace LinearAlgebra {
|
namespace LinearAlgebra {
|
||||||
|
|
||||||
class Matrix2;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A quaternion
|
/// A quaternion
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -91,8 +90,6 @@ struct Quaternion : Quat {
|
|||||||
/// The euler angles performed in the order: Z, X, Y
|
/// The euler angles performed in the order: Z, X, Y
|
||||||
static Vector3 ToAngles(const Quaternion &q);
|
static Vector3 ToAngles(const Quaternion &q);
|
||||||
|
|
||||||
Matrix2 ToRotationMatrix();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Rotate a vector using this quaterion
|
/// Rotate a vector using this quaterion
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -160,8 +157,7 @@ struct Quaternion : Quat {
|
|||||||
/// <param name="to">The destination rotation</param>
|
/// <param name="to">The destination rotation</param>
|
||||||
/// <param name="maxDegreesDelta">The maximum amount of degrees to
|
/// <param name="maxDegreesDelta">The maximum amount of degrees to
|
||||||
/// rotate</param> <returns>The possibly limited rotation</returns>
|
/// rotate</param> <returns>The possibly limited rotation</returns>
|
||||||
static Quaternion RotateTowards(const Quaternion& from,
|
static Quaternion RotateTowards(const Quaternion &from, const Quaternion &to,
|
||||||
const Quaternion& to,
|
|
||||||
float maxDegreesDelta);
|
float maxDegreesDelta);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -195,8 +191,7 @@ struct Quaternion : Quat {
|
|||||||
/// <returns>The resulting rotation</returns>
|
/// <returns>The resulting rotation</returns>
|
||||||
/// A factor 0 returns rotation1, factor1 returns rotation2.
|
/// A factor 0 returns rotation1, factor1 returns rotation2.
|
||||||
static Quaternion Slerp(const Quaternion &rotation1,
|
static Quaternion Slerp(const Quaternion &rotation1,
|
||||||
const Quaternion& rotation2,
|
const Quaternion &rotation2, float factor);
|
||||||
float factor);
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unclamped sherical lerp between two rotations
|
/// Unclamped sherical lerp between two rotations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -207,8 +202,7 @@ struct Quaternion : Quat {
|
|||||||
/// A factor 0 returns rotation1, factor1 returns rotation2.
|
/// A factor 0 returns rotation1, factor1 returns rotation2.
|
||||||
/// Values outside the 0..1 range will result in extrapolated rotations
|
/// Values outside the 0..1 range will result in extrapolated rotations
|
||||||
static Quaternion SlerpUnclamped(const Quaternion &rotation1,
|
static Quaternion SlerpUnclamped(const Quaternion &rotation1,
|
||||||
const Quaternion& rotation2,
|
const Quaternion &rotation2, float factor);
|
||||||
float factor);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a rotation from euler angles
|
/// Create a rotation from euler angles
|
||||||
@ -266,10 +260,8 @@ struct Quaternion : Quat {
|
|||||||
/// <param name="swing">A pointer to the quaternion for the swing
|
/// <param name="swing">A pointer to the quaternion for the swing
|
||||||
/// result</param> <param name="twist">A pointer to the quaternion for the
|
/// result</param> <param name="twist">A pointer to the quaternion for the
|
||||||
/// twist result</param>
|
/// twist result</param>
|
||||||
static void GetSwingTwist(Vector3 axis,
|
static void GetSwingTwist(Vector3 axis, Quaternion rotation,
|
||||||
Quaternion rotation,
|
Quaternion *swing, Quaternion *twist);
|
||||||
Quaternion* swing,
|
|
||||||
Quaternion* twist);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Calculate the dot product of two quaternions
|
/// Calculate the dot product of two quaternions
|
||||||
@ -292,6 +284,7 @@ struct Quaternion : Quat {
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
} // namespace LinearAlgebra
|
||||||
using namespace LinearAlgebra;
|
} // namespace Passer
|
||||||
|
using namespace Passer::LinearAlgebra;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -5,17 +5,13 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
namespace LinearAlgebra {
|
template <typename T> SphericalOf<T>::SphericalOf() {
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
SphericalOf<T>::SphericalOf() {
|
|
||||||
this->distance = 0.0f;
|
this->distance = 0.0f;
|
||||||
this->direction = DirectionOf<T>();
|
this->direction = DirectionOf<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SphericalOf<T>::SphericalOf(float distance,
|
SphericalOf<T>::SphericalOf(float distance, AngleOf<T> horizontal,
|
||||||
AngleOf<T> horizontal,
|
|
||||||
AngleOf<T> vertical) {
|
AngleOf<T> vertical) {
|
||||||
if (distance < 0) {
|
if (distance < 0) {
|
||||||
this->distance = -distance;
|
this->distance = -distance;
|
||||||
@ -38,8 +34,7 @@ SphericalOf<T>::SphericalOf(float distance, DirectionOf<T> direction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SphericalOf<T> SphericalOf<T>::Degrees(float distance,
|
SphericalOf<T> SphericalOf<T>::Degrees(float distance, float horizontal,
|
||||||
float horizontal,
|
|
||||||
float vertical) {
|
float vertical) {
|
||||||
AngleOf<T> horizontalAngle = AngleOf<T>::Degrees(horizontal);
|
AngleOf<T> horizontalAngle = AngleOf<T>::Degrees(horizontal);
|
||||||
AngleOf<T> verticalAngle = AngleOf<T>::Degrees(vertical);
|
AngleOf<T> verticalAngle = AngleOf<T>::Degrees(vertical);
|
||||||
@ -48,8 +43,7 @@ SphericalOf<T> SphericalOf<T>::Degrees(float distance,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SphericalOf<T> SphericalOf<T>::Radians(float distance,
|
SphericalOf<T> SphericalOf<T>::Radians(float distance, float horizontal,
|
||||||
float horizontal,
|
|
||||||
float vertical) {
|
float vertical) {
|
||||||
return SphericalOf<T>(distance, AngleOf<T>::Radians(horizontal),
|
return SphericalOf<T>(distance, AngleOf<T>::Radians(horizontal),
|
||||||
AngleOf<T>::Radians(vertical));
|
AngleOf<T>::Radians(vertical));
|
||||||
@ -63,8 +57,7 @@ SphericalOf<T> SphericalOf<T>::FromPolar(PolarOf<T> polar) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> SphericalOf<T> SphericalOf<T>::FromVector3(Vector3 v) {
|
||||||
SphericalOf<T> SphericalOf<T>::FromVector3(Vector3 v) {
|
|
||||||
float distance = v.magnitude();
|
float distance = v.magnitude();
|
||||||
if (distance == 0.0f) {
|
if (distance == 0.0f) {
|
||||||
return SphericalOf(distance, AngleOf<T>(), AngleOf<T>());
|
return SphericalOf(distance, AngleOf<T>(), AngleOf<T>());
|
||||||
@ -88,8 +81,7 @@ SphericalOf<T> SphericalOf<T>::FromVector3(Vector3 v) {
|
|||||||
* @tparam T The type of the distance and direction values.
|
* @tparam T The type of the distance and direction values.
|
||||||
* @return Vector3 The 3D vector representation of the spherical coordinates.
|
* @return Vector3 The 3D vector representation of the spherical coordinates.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T> Vector3 SphericalOf<T>::ToVector3() const {
|
||||||
Vector3 SphericalOf<T>::ToVector3() const {
|
|
||||||
float verticalRad = (pi / 2) - this->direction.vertical.InRadians();
|
float verticalRad = (pi / 2) - this->direction.vertical.InRadians();
|
||||||
float horizontalRad = this->direction.horizontal.InRadians();
|
float horizontalRad = this->direction.horizontal.InRadians();
|
||||||
|
|
||||||
@ -134,8 +126,7 @@ SphericalOf<T> SphericalOf<T>::WithDistance(float distance) {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> SphericalOf<T> SphericalOf<T>::operator-() const {
|
||||||
SphericalOf<T> SphericalOf<T>::operator-() const {
|
|
||||||
SphericalOf<T> v = SphericalOf<T>(
|
SphericalOf<T> v = SphericalOf<T>(
|
||||||
this->distance, this->direction.horizontal + AngleOf<T>::Degrees(180),
|
this->distance, this->direction.horizontal + AngleOf<T>::Degrees(180),
|
||||||
this->direction.vertical + AngleOf<T>::Degrees(180));
|
this->direction.vertical + AngleOf<T>::Degrees(180));
|
||||||
@ -218,14 +209,12 @@ SphericalOf<T> SphericalOf<T>::operator+=(const SphericalOf<T>& v) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> SphericalOf<T> SphericalOf<T>::operator*=(float f) {
|
||||||
SphericalOf<T> SphericalOf<T>::operator*=(float f) {
|
|
||||||
this->distance *= f;
|
this->distance *= f;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> SphericalOf<T> SphericalOf<T>::operator/=(float f) {
|
||||||
SphericalOf<T> SphericalOf<T>::operator/=(float f) {
|
|
||||||
this->distance /= f;
|
this->distance /= f;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -267,8 +256,8 @@ AngleOf<T> SphericalOf<T>::AngleBetween(const SphericalOf& v1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
AngleOf<T> SphericalOf<T>::SignedAngleBetween(const SphericalOf<T>& v1,
|
AngleOf<T> Passer::LinearAlgebra::SphericalOf<T>::SignedAngleBetween(
|
||||||
const SphericalOf<T>& v2,
|
const SphericalOf<T> &v1, const SphericalOf<T> &v2,
|
||||||
const SphericalOf<T> &axis) {
|
const SphericalOf<T> &axis) {
|
||||||
Vector3 v1_vector = v1.ToVector3();
|
Vector3 v1_vector = v1.ToVector3();
|
||||||
Vector3 v2_vector = v2.ToVector3();
|
Vector3 v2_vector = v2.ToVector3();
|
||||||
@ -301,7 +290,5 @@ SphericalOf<T> SphericalOf<T>::RotateVertical(const SphericalOf<T>& v,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template class SphericalOf<float>;
|
template class Passer::LinearAlgebra::SphericalOf<float>;
|
||||||
template class SphericalOf<signed short>;
|
template class Passer::LinearAlgebra::SphericalOf<signed short>;
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
|
||||||
|
37
Spherical.h
37
Spherical.h
@ -7,26 +7,30 @@
|
|||||||
|
|
||||||
#include "Direction.h"
|
#include "Direction.h"
|
||||||
|
|
||||||
|
namespace Passer {
|
||||||
namespace LinearAlgebra {
|
namespace LinearAlgebra {
|
||||||
|
|
||||||
struct Vector3;
|
struct Vector3;
|
||||||
template <typename T>
|
template <typename T> class PolarOf;
|
||||||
class PolarOf;
|
|
||||||
|
|
||||||
/// @brief A spherical vector using angles in various representations
|
/// @brief A spherical vector using angles in various representations
|
||||||
/// @tparam T The implementation type used for the representations of the agles
|
/// @tparam T The implementation type used for the representations of the agles
|
||||||
template <typename T>
|
template <typename T> class SphericalOf {
|
||||||
class SphericalOf {
|
|
||||||
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;
|
||||||
/// @brief The direction of the vector
|
/// @brief The angle in the horizontal plane in degrees, clockwise rotation
|
||||||
|
/// @details The angle is automatically normalized to -180 .. 180
|
||||||
|
// AngleOf<T> horizontal;
|
||||||
|
/// @brief The angle in the vertical plane in degrees. Positive is upward.
|
||||||
|
/// @details The angle is automatically normalized to -180 .. 180
|
||||||
|
// AngleOf<T> vertical;
|
||||||
DirectionOf<T> direction;
|
DirectionOf<T> direction;
|
||||||
|
|
||||||
SphericalOf();
|
SphericalOf<T>();
|
||||||
SphericalOf(float distance, AngleOf<T> horizontal, AngleOf<T> vertical);
|
SphericalOf<T>(float distance, AngleOf<T> horizontal, AngleOf<T> vertical);
|
||||||
SphericalOf(float distance, DirectionOf<T> direction);
|
SphericalOf<T>(float distance, DirectionOf<T> direction);
|
||||||
|
|
||||||
/// @brief Create spherical vector without using AngleOf type. All given
|
/// @brief Create spherical vector without using AngleOf type. All given
|
||||||
/// angles are in degrees
|
/// angles are in degrees
|
||||||
@ -34,8 +38,7 @@ class SphericalOf {
|
|||||||
/// @param horizontal The horizontal angle in degrees
|
/// @param horizontal The horizontal angle in degrees
|
||||||
/// @param vertical The vertical angle in degrees
|
/// @param vertical The vertical angle in degrees
|
||||||
/// @return The spherical vector
|
/// @return The spherical vector
|
||||||
static SphericalOf<T> Degrees(float distance,
|
static SphericalOf<T> Degrees(float distance, float horizontal,
|
||||||
float horizontal,
|
|
||||||
float vertical);
|
float vertical);
|
||||||
/// @brief Short-hand Deg alias for the Degrees function
|
/// @brief Short-hand Deg alias for the Degrees function
|
||||||
constexpr static auto Deg = Degrees;
|
constexpr static auto Deg = Degrees;
|
||||||
@ -45,8 +48,7 @@ class SphericalOf {
|
|||||||
/// @param horizontal The horizontal angle in radians
|
/// @param horizontal The horizontal angle in radians
|
||||||
/// @param vertical The vertical angle in radians
|
/// @param vertical The vertical angle in radians
|
||||||
/// @return The spherical vectpr
|
/// @return The spherical vectpr
|
||||||
static SphericalOf<T> Radians(float distance,
|
static SphericalOf<T> Radians(float distance, float horizontal,
|
||||||
float horizontal,
|
|
||||||
float vertical);
|
float vertical);
|
||||||
// Short-hand Rad alias for the Radians function
|
// Short-hand Rad alias for the Radians function
|
||||||
constexpr static auto Rad = Radians;
|
constexpr static auto Rad = Radians;
|
||||||
@ -152,8 +154,7 @@ class SphericalOf {
|
|||||||
/// @param horizontalAngle The horizontal rotation angle in local space
|
/// @param horizontalAngle The horizontal rotation angle in local space
|
||||||
/// @param verticalAngle The vertical rotation angle in local space
|
/// @param verticalAngle The vertical rotation angle in local space
|
||||||
/// @return The rotated vector
|
/// @return The rotated vector
|
||||||
static SphericalOf<T> Rotate(const SphericalOf& v,
|
static SphericalOf<T> Rotate(const SphericalOf &v, AngleOf<T> horizontalAngle,
|
||||||
AngleOf<T> horizontalAngle,
|
|
||||||
AngleOf<T> verticalAngle);
|
AngleOf<T> verticalAngle);
|
||||||
/// @brief Rotate a spherical vector horizontally
|
/// @brief Rotate a spherical vector horizontally
|
||||||
/// @param v The vector to rotate
|
/// @param v The vector to rotate
|
||||||
@ -179,13 +180,9 @@ using SphericalSingle = SphericalOf<float>;
|
|||||||
/// hardware
|
/// hardware
|
||||||
using Spherical16 = SphericalOf<signed short>;
|
using Spherical16 = SphericalOf<signed short>;
|
||||||
|
|
||||||
#if defined(ARDUINO)
|
|
||||||
using Spherical = Spherical16;
|
|
||||||
#else
|
|
||||||
using Spherical = SphericalSingle;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
} // namespace LinearAlgebra
|
||||||
|
} // namespace Passer
|
||||||
|
using namespace Passer::LinearAlgebra;
|
||||||
|
|
||||||
#include "Polar.h"
|
#include "Polar.h"
|
||||||
#include "Vector3.h"
|
#include "Vector3.h"
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#include "SwingTwist.h"
|
#include "SwingTwist.h"
|
||||||
|
|
||||||
namespace LinearAlgebra {
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
SwingTwistOf<T>::SwingTwistOf() {
|
SwingTwistOf<T>::SwingTwistOf() {
|
||||||
this->swing = DirectionOf<T>(AngleOf<T>(), AngleOf<T>());
|
this->swing = DirectionOf<T>(AngleOf<T>(), AngleOf<T>());
|
||||||
@ -166,7 +164,5 @@ void SwingTwistOf<T>::Normalize() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template class SwingTwistOf<float>;
|
template class Passer::LinearAlgebra::SwingTwistOf<float>;
|
||||||
template class SwingTwistOf<signed short>;
|
template class Passer::LinearAlgebra::SwingTwistOf<signed short>;
|
||||||
|
|
||||||
}
|
|
22
SwingTwist.h
22
SwingTwist.h
@ -10,23 +10,22 @@
|
|||||||
#include "Quaternion.h"
|
#include "Quaternion.h"
|
||||||
#include "Spherical.h"
|
#include "Spherical.h"
|
||||||
|
|
||||||
|
namespace Passer {
|
||||||
namespace LinearAlgebra {
|
namespace LinearAlgebra {
|
||||||
|
|
||||||
/// @brief An orientation using swing and twist angles in various
|
/// @brief An orientation using swing and twist angles in various
|
||||||
/// representations
|
/// representations
|
||||||
/// @tparam T The implmentation type used for the representation of the angles
|
/// @tparam T The implmentation type used for the representation of the angles
|
||||||
template <typename T>
|
template <typename T> class SwingTwistOf {
|
||||||
class SwingTwistOf {
|
|
||||||
public:
|
public:
|
||||||
DirectionOf<T> swing;
|
DirectionOf<T> swing;
|
||||||
AngleOf<T> twist;
|
AngleOf<T> twist;
|
||||||
|
|
||||||
SwingTwistOf();
|
SwingTwistOf<T>();
|
||||||
SwingTwistOf(DirectionOf<T> swing, AngleOf<T> twist);
|
SwingTwistOf<T>(DirectionOf<T> swing, AngleOf<T> twist);
|
||||||
SwingTwistOf(AngleOf<T> horizontal, AngleOf<T> vertical, AngleOf<T> twist);
|
SwingTwistOf<T>(AngleOf<T> horizontal, AngleOf<T> vertical, AngleOf<T> twist);
|
||||||
|
|
||||||
static SwingTwistOf<T> Degrees(float horizontal,
|
static SwingTwistOf<T> Degrees(float horizontal, float vertical = 0,
|
||||||
float vertical = 0,
|
|
||||||
float twist = 0);
|
float twist = 0);
|
||||||
|
|
||||||
Quaternion ToQuaternion() const;
|
Quaternion ToQuaternion() const;
|
||||||
@ -73,13 +72,8 @@ class SwingTwistOf {
|
|||||||
using SwingTwistSingle = SwingTwistOf<float>;
|
using SwingTwistSingle = SwingTwistOf<float>;
|
||||||
using SwingTwist16 = SwingTwistOf<signed short>;
|
using SwingTwist16 = SwingTwistOf<signed short>;
|
||||||
|
|
||||||
#if defined(ARDUINO)
|
|
||||||
using SwingTwist = SwingTwist16;
|
|
||||||
#else
|
|
||||||
using SwingTwist = SwingTwistSingle;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
} // namespace LinearAlgebra
|
||||||
using namespace LinearAlgebra;
|
} // namespace Passer
|
||||||
|
using namespace Passer::LinearAlgebra;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
25
Vector2.cpp
25
Vector2.cpp
@ -30,7 +30,7 @@ Vector2::Vector2(Vector3 v) {
|
|||||||
y = v.Forward(); // z;
|
y = v.Forward(); // z;
|
||||||
}
|
}
|
||||||
Vector2::Vector2(PolarSingle p) {
|
Vector2::Vector2(PolarSingle p) {
|
||||||
float horizontalRad = p.angle.InDegrees() * Deg2Rad;
|
float horizontalRad = p.angle.InDegrees() * Passer::LinearAlgebra::Deg2Rad;
|
||||||
float cosHorizontal = cosf(horizontalRad);
|
float cosHorizontal = cosf(horizontalRad);
|
||||||
float sinHorizontal = sinf(horizontalRad);
|
float sinHorizontal = sinf(horizontalRad);
|
||||||
|
|
||||||
@ -56,15 +56,9 @@ bool Vector2::operator==(const Vector2& v) {
|
|||||||
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 {
|
float Vector2::magnitude() const { return (float)sqrtf(x * x + y * y); }
|
||||||
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::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);
|
||||||
@ -83,9 +77,7 @@ Vector2 Vector2::normalized() const {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 Vector2::operator-() {
|
Vector2 Vector2::operator-() { return Vector2(-this->x, -this->y); }
|
||||||
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);
|
||||||
@ -156,11 +148,12 @@ float Vector2::SignedAngle(const Vector2& v1, const Vector2& v2) {
|
|||||||
|
|
||||||
float angleFrom = atan2f(v1.y, v1.x);
|
float angleFrom = atan2f(v1.y, v1.x);
|
||||||
float angleTo = atan2f(v2.y, v2.x);
|
float angleTo = atan2f(v2.y, v2.x);
|
||||||
return -(angleTo - angleFrom) * Rad2Deg;
|
return -(angleTo - angleFrom) * Passer::LinearAlgebra::Rad2Deg;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 Vector2::Rotate(const Vector2& v, AngleSingle a) {
|
Vector2 Vector2::Rotate(const Vector2 &v,
|
||||||
float angleRad = a.InDegrees() * Deg2Rad;
|
Passer::LinearAlgebra::AngleSingle a) {
|
||||||
|
float angleRad = a.InDegrees() * Passer::LinearAlgebra::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);
|
||||||
|
@ -26,11 +26,11 @@ typedef struct Vec2 {
|
|||||||
} Vec2;
|
} Vec2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Passer {
|
||||||
namespace LinearAlgebra {
|
namespace LinearAlgebra {
|
||||||
|
|
||||||
struct Vector3;
|
struct Vector3;
|
||||||
template <typename T>
|
template <typename T> class PolarOf;
|
||||||
class PolarOf;
|
|
||||||
|
|
||||||
/// @brief A 2-dimensional vector
|
/// @brief A 2-dimensional vector
|
||||||
/// @remark This uses the right=handed carthesian coordinate system.
|
/// @remark This uses the right=handed carthesian coordinate system.
|
||||||
@ -188,7 +188,7 @@ struct Vector2 : Vec2 {
|
|||||||
/// @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, AngleSingle a);
|
static Vector2 Rotate(const Vector2 &v, Passer::LinearAlgebra::AngleSingle 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
|
||||||
@ -202,7 +202,8 @@ struct Vector2 : Vec2 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
} // namespace LinearAlgebra
|
||||||
using namespace LinearAlgebra;
|
} // namespace Passer
|
||||||
|
using namespace Passer::LinearAlgebra;
|
||||||
|
|
||||||
#include "Polar.h"
|
#include "Polar.h"
|
||||||
|
|
||||||
|
17
Vector3.cpp
17
Vector3.cpp
@ -31,8 +31,10 @@ Vector3::Vector3(Vector2 v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector3::Vector3(SphericalOf<float> s) {
|
Vector3::Vector3(SphericalOf<float> s) {
|
||||||
float verticalRad = (90.0f - s.direction.vertical.InDegrees()) * Deg2Rad;
|
float verticalRad = (90.0f - s.direction.vertical.InDegrees()) *
|
||||||
float horizontalRad = s.direction.horizontal.InDegrees() * Deg2Rad;
|
Passer::LinearAlgebra::Deg2Rad;
|
||||||
|
float horizontalRad =
|
||||||
|
s.direction.horizontal.InDegrees() * Passer::LinearAlgebra::Deg2Rad;
|
||||||
float cosVertical = cosf(verticalRad);
|
float cosVertical = cosf(verticalRad);
|
||||||
float sinVertical = sinf(verticalRad);
|
float sinVertical = sinf(verticalRad);
|
||||||
float cosHorizontal = cosf(horizontalRad);
|
float cosHorizontal = cosf(horizontalRad);
|
||||||
@ -68,16 +70,12 @@ const Vector3 Vector3::back = Vector3(0, 0, -1);
|
|||||||
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 {
|
float Vector3::magnitude() const { return (float)sqrtf(x * x + y * y + z * z); }
|
||||||
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 {
|
float Vector3::sqrMagnitude() const { return (x * x + y * y + z * z); }
|
||||||
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);
|
||||||
@ -202,8 +200,7 @@ AngleOf<float> Vector3::Angle(const Vector3& v1, const Vector3& v2) {
|
|||||||
return AngleOf<float>::Radians(r);
|
return AngleOf<float>::Radians(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
AngleOf<float> Vector3::SignedAngle(const Vector3& v1,
|
AngleOf<float> Vector3::SignedAngle(const Vector3 &v1, const Vector3 &v2,
|
||||||
const Vector3& v2,
|
|
||||||
const Vector3 &axis) {
|
const Vector3 &axis) {
|
||||||
// angle in [0,180]
|
// angle in [0,180]
|
||||||
AngleOf<float> angle = Vector3::Angle(v1, v2);
|
AngleOf<float> angle = Vector3::Angle(v1, v2);
|
||||||
|
12
Vector3.h
12
Vector3.h
@ -14,7 +14,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 {
|
||||||
public:
|
protected:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The right axis of the vector
|
/// The right axis of the vector
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -31,10 +31,10 @@ typedef struct Vec3 {
|
|||||||
} Vec3;
|
} Vec3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Passer {
|
||||||
namespace LinearAlgebra {
|
namespace LinearAlgebra {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> class SphericalOf;
|
||||||
class SphericalOf;
|
|
||||||
|
|
||||||
/// @brief A 3-dimensional vector
|
/// @brief A 3-dimensional vector
|
||||||
/// @remark This uses a right-handed carthesian coordinate system.
|
/// @remark This uses a right-handed carthesian coordinate system.
|
||||||
@ -210,8 +210,7 @@ struct Vector3 : Vec3 {
|
|||||||
/// @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 AngleOf<float> SignedAngle(const Vector3& v1,
|
static AngleOf<float> SignedAngle(const Vector3 &v1, const Vector3 &v2,
|
||||||
const Vector3& v2,
|
|
||||||
const Vector3 &axis);
|
const Vector3 &axis);
|
||||||
|
|
||||||
/// @brief Lerp (linear interpolation) between two vectors
|
/// @brief Lerp (linear interpolation) between two vectors
|
||||||
@ -226,7 +225,8 @@ struct Vector3 : Vec3 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LinearAlgebra
|
} // namespace LinearAlgebra
|
||||||
using namespace LinearAlgebra;
|
} // namespace Passer
|
||||||
|
using namespace Passer::LinearAlgebra;
|
||||||
|
|
||||||
#include "Spherical.h"
|
#include "Spherical.h"
|
||||||
|
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
#if GTEST
|
#if GTEST
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "Angle.h"
|
#include "Angle.h"
|
||||||
|
|
||||||
using namespace LinearAlgebra;
|
|
||||||
|
|
||||||
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
||||||
|
|
||||||
TEST(Angle16, Construct) {
|
TEST(Angle16, Construct) {
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
#if GTEST
|
#if GTEST
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "Angle.h"
|
#include "Angle.h"
|
||||||
|
|
||||||
using namespace LinearAlgebra;
|
|
||||||
|
|
||||||
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
||||||
|
|
||||||
TEST(Angle8, Construct) {
|
TEST(Angle8, Construct) {
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
#if GTEST
|
#if GTEST
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "Angle.h"
|
#include "Angle.h"
|
||||||
|
|
||||||
using namespace LinearAlgebra;
|
|
||||||
|
|
||||||
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
||||||
|
|
||||||
TEST(AngleSingle, Construct) {
|
TEST(AngleSingle, Construct) {
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
#include "Direction.h"
|
#include "Direction.h"
|
||||||
|
|
||||||
using namespace LinearAlgebra;
|
|
||||||
|
|
||||||
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
|
||||||
|
|
||||||
TEST(Direction16, Compare) {
|
TEST(Direction16, Compare) {
|
||||||
|
@ -1,90 +1,10 @@
|
|||||||
#if GTEST
|
#if GTEST
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <math.h>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "Matrix.h"
|
#include "Matrix.h"
|
||||||
|
|
||||||
TEST(Matrix2, Zero) {
|
|
||||||
// Test case 1: 2x2 zero matrix
|
|
||||||
Matrix2 zeroMatrix = Matrix2::Zero(2, 2);
|
|
||||||
EXPECT_TRUE(zeroMatrix.nRows == 2);
|
|
||||||
EXPECT_TRUE(zeroMatrix.nCols == 2);
|
|
||||||
for (int i = 0; i < zeroMatrix.nValues; ++i) {
|
|
||||||
EXPECT_TRUE(zeroMatrix.data[i] == 0.0f);
|
|
||||||
}
|
|
||||||
std::cout << "Test case 1 passed: 2x2 zero matrix\n";
|
|
||||||
|
|
||||||
// Test case 2: 3x3 zero matrix
|
|
||||||
zeroMatrix = Matrix2::Zero(3, 3);
|
|
||||||
EXPECT_TRUE(zeroMatrix.nRows == 3);
|
|
||||||
EXPECT_TRUE(zeroMatrix.nCols == 3);
|
|
||||||
for (int i = 0; i < zeroMatrix.nValues; ++i) {
|
|
||||||
EXPECT_TRUE(zeroMatrix.data[i] == 0.0f);
|
|
||||||
}
|
|
||||||
std::cout << "Test case 2 passed: 3x3 zero matrix\n";
|
|
||||||
|
|
||||||
// Test case 3: 1x1 zero matrix
|
|
||||||
zeroMatrix = Matrix2::Zero(1, 1);
|
|
||||||
EXPECT_TRUE(zeroMatrix.nRows == 1);
|
|
||||||
EXPECT_TRUE(zeroMatrix.nCols == 1);
|
|
||||||
EXPECT_TRUE(zeroMatrix.data[0] == 0.0f);
|
|
||||||
std::cout << "Test case 3 passed: 1x1 zero matrix\n";
|
|
||||||
|
|
||||||
// Test case 4: 0x0 matrix (edge case)
|
|
||||||
zeroMatrix = Matrix2::Zero(0, 0);
|
|
||||||
EXPECT_TRUE(zeroMatrix.nRows == 0);
|
|
||||||
EXPECT_TRUE(zeroMatrix.nCols == 0);
|
|
||||||
EXPECT_TRUE(zeroMatrix.data == nullptr);
|
|
||||||
std::cout << "Test case 4 passed: 0x0 matrix\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Matrix2, Multiplication) {
|
|
||||||
// Test 1: Multiplying two 2x2 matrices
|
|
||||||
float dataA[] = {1, 2, 3, 4};
|
|
||||||
float dataB[] = {5, 6, 7, 8};
|
|
||||||
Matrix2 A(dataA, 2, 2);
|
|
||||||
Matrix2 B(dataB, 2, 2);
|
|
||||||
|
|
||||||
Matrix2 result = A * B;
|
|
||||||
|
|
||||||
float expectedData[] = {19, 22, 43, 50};
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
EXPECT_TRUE(result.data[i] == expectedData[i]);
|
|
||||||
std::cout << "Test 1 passed: 2x2 matrix multiplication.\n";
|
|
||||||
|
|
||||||
|
|
||||||
// Test 2: Multiplying a 3x2 matrix with a 2x3 matrix
|
|
||||||
float dataC[] = {1, 2, 3, 4, 5, 6};
|
|
||||||
float dataD[] = {7, 8, 9, 10, 11, 12};
|
|
||||||
Matrix2 C(dataC, 3, 2);
|
|
||||||
Matrix2 D(dataD, 2, 3);
|
|
||||||
|
|
||||||
Matrix2 result2 = C * D;
|
|
||||||
|
|
||||||
float expectedData2[] = {27, 30, 33, 61, 68, 75, 95, 106, 117};
|
|
||||||
for (int i = 0; i < 9; ++i)
|
|
||||||
EXPECT_TRUE(result2.data[i] == expectedData2[i]);
|
|
||||||
std::cout << "Test 2 passed: 3x2 * 2x3 matrix multiplication.\n";
|
|
||||||
|
|
||||||
// Test 3: Multiplying with a zero matrix
|
|
||||||
Matrix2 zeroMatrix = Matrix2::Zero(2, 2);
|
|
||||||
Matrix2 result3 = A * zeroMatrix;
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
EXPECT_TRUE(result3.data[i] == 0);
|
|
||||||
std::cout << "Test 3 passed: Multiplication with zero matrix.\n";
|
|
||||||
|
|
||||||
// Test 4: Multiplying with an identity matrix
|
|
||||||
Matrix2 identityMatrix = Matrix2::Identity(2);
|
|
||||||
Matrix2 result4 = A * identityMatrix;
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
EXPECT_TRUE(result4.data[i] == A.data[i]);
|
|
||||||
std::cout << "Test 4 passed: Multiplication with identity matrix.\n";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(MatrixSingle, Init) {
|
TEST(MatrixSingle, Init) {
|
||||||
// zero
|
// zero
|
||||||
MatrixOf<float> m0 = MatrixOf<float>(0, 0);
|
MatrixOf<float> m0 = MatrixOf<float>(0, 0);
|
||||||
|
@ -34,32 +34,26 @@ TEST(Vector2, FromPolar) {
|
|||||||
EXPECT_FLOAT_EQ(r.y, 0.0F) << "FromPolar(0 0)";
|
EXPECT_FLOAT_EQ(r.y, 0.0F) << "FromPolar(0 0)";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Magnitude) {
|
TEST(Vector2, Equality) {
|
||||||
Vector2 v = Vector2(1, 2);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
float m = 0;
|
Vector2 v2 = Vector2(1, 2);
|
||||||
|
bool r = false;
|
||||||
|
|
||||||
m = v.magnitude();
|
r = v1 == v2;
|
||||||
EXPECT_FLOAT_EQ(m, 2.236068F) << "v.magnitude 1 2";
|
EXPECT_FALSE(r) << "4 5 == 1 2";
|
||||||
|
|
||||||
m = Vector2::Magnitude(v);
|
v2 = Vector2(4, 5);
|
||||||
EXPECT_FLOAT_EQ(m, 2.236068F) << "Vector2::Magnitude 1 2";
|
r = v1 == v2;
|
||||||
|
EXPECT_TRUE(r) << "4 5 == 1 2";
|
||||||
v = Vector2(-1, -2);
|
|
||||||
m = v.magnitude();
|
|
||||||
EXPECT_FLOAT_EQ(m, 2.236068F) << "v.magnitude -1 -2";
|
|
||||||
|
|
||||||
v = Vector2(0, 0);
|
|
||||||
m = v.magnitude();
|
|
||||||
EXPECT_FLOAT_EQ(m, 0) << "v.magnitude 0 0 ";
|
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
m = v.magnitude();
|
r = v1 == v2;
|
||||||
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY) << "v.magnitude INFINITY INFINITY ";
|
EXPECT_FALSE(r) << "4 5 == INFINITY INFINITY";
|
||||||
|
|
||||||
v = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY);
|
v1 = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
m = v.magnitude();
|
r = v1 == v2;
|
||||||
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY) << "v.magnitude -INFINITY -INFINITY ";
|
EXPECT_FALSE(r) << "-INFINITY -INFINITY == INFINITY INFINITY";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,6 +86,35 @@ TEST(Vector2, SqrMagnitude) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Vector2, Magnitude) {
|
||||||
|
Vector2 v = Vector2(1, 2);
|
||||||
|
float m = 0;
|
||||||
|
|
||||||
|
m = v.magnitude();
|
||||||
|
EXPECT_FLOAT_EQ(m, 2.236068F) << "v.magnitude 1 2";
|
||||||
|
|
||||||
|
m = Vector2::Magnitude(v);
|
||||||
|
EXPECT_FLOAT_EQ(m, 2.236068F) << "Vector2::Magnitude 1 2";
|
||||||
|
|
||||||
|
v = Vector2(-1, -2);
|
||||||
|
m = v.magnitude();
|
||||||
|
EXPECT_FLOAT_EQ(m, 2.236068F) << "v.magnitude -1 -2";
|
||||||
|
|
||||||
|
v = Vector2(0, 0);
|
||||||
|
m = v.magnitude();
|
||||||
|
EXPECT_FLOAT_EQ(m, 0) << "v.magnitude 0 0 ";
|
||||||
|
|
||||||
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
|
v = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
|
m = v.magnitude();
|
||||||
|
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY) << "v.magnitude INFINITY INFINITY ";
|
||||||
|
|
||||||
|
v = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
|
m = v.magnitude();
|
||||||
|
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY) << "v.magnitude -INFINITY -INFINITY ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Vector2, Normalize) {
|
TEST(Vector2, Normalize) {
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
@ -311,56 +334,6 @@ TEST(Vector2, Divide) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Vector2, Dot) {
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
|
||||||
Vector2 v2 = Vector2(1, 2);
|
|
||||||
float f = 0;
|
|
||||||
|
|
||||||
f = Vector2::Dot(v1, v2);
|
|
||||||
EXPECT_FLOAT_EQ(f, 14) << "Dot(4 5, 1 2)";
|
|
||||||
|
|
||||||
v2 = Vector2(-1, -2);
|
|
||||||
f = Vector2::Dot(v1, v2);
|
|
||||||
EXPECT_FLOAT_EQ(f, -14) << "Dot(4 5, -1 -2)";
|
|
||||||
|
|
||||||
v2 = Vector2(0, 0);
|
|
||||||
f = Vector2::Dot(v1, v2);
|
|
||||||
EXPECT_FLOAT_EQ(f, 0) << "Dot(4 5, 0 0)";
|
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
|
||||||
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
|
||||||
f = Vector2::Dot(v1, v2);
|
|
||||||
EXPECT_FLOAT_EQ(f, FLOAT_INFINITY) << "Dot(4 5, INFINITY INFINITY)";
|
|
||||||
|
|
||||||
v2 = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY);
|
|
||||||
f = Vector2::Dot(v1, v2);
|
|
||||||
EXPECT_FLOAT_EQ(f, -FLOAT_INFINITY) << "Dot(4 5, -INFINITY -INFINITY)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Vector2, Equality) {
|
|
||||||
Vector2 v1 = Vector2(4, 5);
|
|
||||||
Vector2 v2 = Vector2(1, 2);
|
|
||||||
bool r = false;
|
|
||||||
|
|
||||||
r = v1 == v2;
|
|
||||||
EXPECT_FALSE(r) << "4 5 == 1 2";
|
|
||||||
|
|
||||||
v2 = Vector2(4, 5);
|
|
||||||
r = v1 == v2;
|
|
||||||
EXPECT_TRUE(r) << "4 5 == 1 2";
|
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
|
||||||
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
|
||||||
r = v1 == v2;
|
|
||||||
EXPECT_FALSE(r) << "4 5 == INFINITY INFINITY";
|
|
||||||
|
|
||||||
v1 = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY);
|
|
||||||
r = v1 == v2;
|
|
||||||
EXPECT_FALSE(r) << "-INFINITY -INFINITY == INFINITY INFINITY";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Vector2, Distance) {
|
TEST(Vector2, Distance) {
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
Vector2 v2 = Vector2(1, 2);
|
Vector2 v2 = Vector2(1, 2);
|
||||||
@ -388,6 +361,33 @@ TEST(Vector2, Distance) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Vector2, Dot) {
|
||||||
|
Vector2 v1 = Vector2(4, 5);
|
||||||
|
Vector2 v2 = Vector2(1, 2);
|
||||||
|
float f = 0;
|
||||||
|
|
||||||
|
f = Vector2::Dot(v1, v2);
|
||||||
|
EXPECT_FLOAT_EQ(f, 14) << "Dot(4 5, 1 2)";
|
||||||
|
|
||||||
|
v2 = Vector2(-1, -2);
|
||||||
|
f = Vector2::Dot(v1, v2);
|
||||||
|
EXPECT_FLOAT_EQ(f, -14) << "Dot(4 5, -1 -2)";
|
||||||
|
|
||||||
|
v2 = Vector2(0, 0);
|
||||||
|
f = Vector2::Dot(v1, v2);
|
||||||
|
EXPECT_FLOAT_EQ(f, 0) << "Dot(4 5, 0 0)";
|
||||||
|
|
||||||
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
|
v2 = Vector2(FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
|
f = Vector2::Dot(v1, v2);
|
||||||
|
EXPECT_FLOAT_EQ(f, FLOAT_INFINITY) << "Dot(4 5, INFINITY INFINITY)";
|
||||||
|
|
||||||
|
v2 = Vector2(-FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
|
f = Vector2::Dot(v1, v2);
|
||||||
|
EXPECT_FLOAT_EQ(f, -FLOAT_INFINITY) << "Dot(4 5, -INFINITY -INFINITY)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Vector2, Angle) {
|
TEST(Vector2, Angle) {
|
||||||
Vector2 v1 = Vector2(4, 5);
|
Vector2 v1 = Vector2(4, 5);
|
||||||
Vector2 v2 = Vector2(1, 2);
|
Vector2 v2 = Vector2(1, 2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user