Proper angle implementation (unit tests still fail)

This commit is contained in:
Pascal Serrarens 2024-09-24 10:29:21 +02:00
parent 92d5ef028c
commit fb5cee851f
27 changed files with 539 additions and 839 deletions

173
Angle.cpp
View File

@ -72,44 +72,105 @@ float Angle::SineRuleAngle(float a, float beta, float b) {
*/
//----------------------
template <>
AngleOf<float>::AngleOf(signed int angle) : value((float)angle) {}
template <>
AngleOf<float>::AngleOf(float angle) : value(angle) {}
template <typename T>
AngleOf<T>::AngleOf() : value(0) {}
template <typename T>
AngleOf<T> AngleOf<T>::Degrees(float a) {
AngleOf<T> angle = AngleOf<T>(a);
return angle;
}
AngleOf<T>::AngleOf(T angle) : value(angle) {}
template <typename T>
AngleOf<T> AngleOf<T>::Radians(float a) {
AngleOf<T> angle = AngleOf<T>((a / pi) * 180);
return angle;
//===== AngleSingle, AngleOf<float>
template <>
AngleOf<float> AngleOf<float>::Degrees(float angle) {
return AngleOf(angle);
}
template <>
float AngleOf<float>::ToFloat() const {
return value;
}
template <typename T>
float AngleOf<T>::InDegrees() const {
return this->ToFloat();
}
template <typename T>
float AngleOf<T>::InRadians() const {
return this->ToFloat() * Deg2Rad;
AngleOf<float> AngleOf<float>::Radians(float angle) {
return AngleOf(angle * Rad2Deg);
}
// template <>
// AngleOf<float> AngleOf<float>::pi = 3.1415927410125732421875F;
template <>
float AngleOf<float>::InDegrees() const {
return this->value;
}
// template <>
// AngleOf<float> AngleOf<float>::Rad2Deg = 360.0f / (pi * 2);
// template <>
// AngleOf<float> AngleOf<float>::Deg2Rad = (pi * 2) / 360.0f;
template <>
float AngleOf<float>::InRadians() const {
return this->value * Deg2Rad;
}
//===== Angle16, AngleOf<signed short>
template <>
AngleOf<signed short> AngleOf<signed short>::Degrees(float angle) {
if (!isfinite(angle)) {
return AngleOf<signed short>(0);
}
// map float [-180..180) to integer [-32768..32767]
signed short value = (signed short)(angle / 360.0F * 65536.0F);
return AngleOf<signed short>(value);
}
template <>
AngleOf<signed short> AngleOf<signed short>::Radians(float angle) {
if (!isfinite(angle)) {
return AngleOf<signed short>(0);
}
// map float [-PI..PI) to integer [-32768..32767]
signed short value = (signed short)(angle / pi * 32768.0F);
return AngleOf<signed short>(value);
}
template <>
float AngleOf<signed short>::InDegrees() const {
float degrees = this->value / 65536.0f * 360.0f;
return degrees;
}
template <>
float AngleOf<signed short>::InRadians() const {
float radians = this->value / 65536.0f * (2 * pi);
return radians;
}
//===== Angle8, AngleOf<signed char>
template <>
AngleOf<signed char> AngleOf<signed char>::Degrees(float angle) {
if (!isfinite(angle))
return AngleOf<signed char>(0);
// map float [-180..180) to integer [-128..127)
signed char value = (signed char)(angle / 360.0F * 256.0F);
return AngleOf<signed char>(value);
}
template <>
AngleOf<signed char> AngleOf<signed char>::Radians(float angle) {
if (!isfinite(angle))
return AngleOf<signed char>(0);
// map float [-pi..pi) to integer [-128..127)
signed char value = (signed char)(angle / pi * 128.0f);
return AngleOf<signed char>(value);
}
template <>
float AngleOf<signed char>::InDegrees() const {
float degrees = this->value / 256.0f * 360.0f;
return degrees;
}
template <>
float AngleOf<signed char>::InRadians() const {
float radians = this->value / 128.0f * pi;
return radians;
}
//===== Generic
template <typename T>
bool AngleOf<T>::operator==(const AngleOf<T> a) const {
@ -136,23 +197,33 @@ bool AngleOf<T>::operator<=(AngleOf<T> a) {
return this->value <= a.value;
}
template <>
AngleOf<float> AngleOf<float>::operator-() const {
AngleOf<float> angle = AngleOf(-this->value);
template <typename T>
AngleOf<T> AngleOf<T>::operator-() const {
AngleOf<T> angle = AngleOf(-this->value);
return angle;
}
template <>
AngleOf<float> AngleOf<float>::operator-(const AngleOf<float>& a) const {
AngleOf<float> angle = AngleOf();
angle.value = this->value - a.value;
AngleOf<float> angle = AngleOf(this->value - a.value);
angle = Normalize(angle);
return angle;
}
template <typename T>
AngleOf<T> AngleOf<T>::operator-(const AngleOf<T>& a) const {
AngleOf<T> angle = AngleOf(this->value - a.value);
return angle;
}
template <>
AngleOf<float> AngleOf<float>::operator+(const AngleOf<float>& a) const {
AngleOf<float> angle = AngleOf();
angle.value = this->value + a.value;
AngleOf<float> angle = AngleOf(this->value + a.value);
angle = Normalize(angle);
return angle;
}
template <typename T>
AngleOf<T> AngleOf<T>::operator+(const AngleOf<T>& a) const {
AngleOf<T> angle = AngleOf(this->value + a.value);
return angle;
}
@ -164,7 +235,7 @@ AngleOf<T> AngleOf<T>::operator+=(const AngleOf<T>& a) {
template <typename T>
AngleOf<T> AngleOf<T>::Normalize(AngleOf<T> angle) {
float angleValue = angle.ToFloat();
float angleValue = angle.InDegrees();
if (!isfinite(angleValue))
return angle;
@ -172,32 +243,26 @@ AngleOf<T> AngleOf<T>::Normalize(AngleOf<T> angle) {
angleValue += 360;
while (angleValue > 180)
angleValue -= 360;
return AngleOf(angleValue);
return AngleOf::Degrees(angleValue);
}
template <>
AngleOf<float> AngleOf<float>::Clamp(AngleOf<float> angle,
AngleOf<float> min,
AngleOf<float> max) {
float normalizedAngle = Normalize(angle).ToFloat();
float r = Float::Clamp(normalizedAngle, min.ToFloat(), max.ToFloat());
float normalizedAngle = Normalize(angle).InDegrees();
float r = Float::Clamp(normalizedAngle, min.InDegrees(), max.InDegrees());
return r;
}
// template <typename T>
// Angle2<T> Angle2<T>::Difference(Angle2<T> a, Angle2<T> b) {
// Angle2<T> r = Normalize(b - a);
// return r;
// }
template <>
AngleOf<float> AngleOf<float>::MoveTowards(AngleOf<float> fromAngle,
AngleOf<float> toAngle,
AngleOf<float> maxAngle) {
float d = toAngle.ToFloat() - fromAngle.ToFloat();
float d = toAngle.InDegrees() - fromAngle.InDegrees();
int sign = signbit(d) ? -1 : 1;
d = sign * Float::Clamp(fabsf(d), 0, maxAngle.ToFloat());
return fromAngle.ToFloat() + d;
d = sign * Float::Clamp(fabsf(d), 0, maxAngle.InDegrees());
return fromAngle.InDegrees() + d;
}
template <typename T>
@ -227,13 +292,10 @@ AngleOf<T> AngleOf<T>::Atan(float f) {
}
template <>
AngleOf<float> AngleOf<float>::CosineRuleSide(float a,
float b,
AngleOf<float> gamma) {
AngleOf<float> AngleOf<float>::CosineRuleSide(float a, float b, float gamma) {
float a2 = a * a;
float b2 = b * b;
float d = a2 + b2 -
2 * a * b * cosf(gamma.ToFloat() * Passer::LinearAlgebra::Deg2Rad);
float d = a2 + b2 - 2 * a * b * cosf(gamma * Passer::LinearAlgebra::Deg2Rad);
// Catch edge cases where float inacuracies lead tot nans
if (d < 0)
return 0.0f;
@ -263,9 +325,10 @@ AngleOf<float> AngleOf<float>::SineRuleAngle(float a,
AngleOf<float> beta,
float b) {
float deg2rad = Deg2Rad;
float alpha = asinf(a * sinf(beta.ToFloat() * deg2rad) / b);
float alpha = asinf(a * sinf(beta.InDegrees() * deg2rad) / b);
return alpha;
}
template class AngleOf<float>;
template class AngleOf<signed char>;
template class AngleOf<signed short>;

29
Angle.h
View File

@ -16,16 +16,12 @@ static float Deg2Rad = (pi * 2) / 360.0f;
template <typename T>
class AngleOf {
public:
AngleOf() {};
// These are deprecated, will move to private.
// Use Degrees/Radians instead
AngleOf(signed int f);
AngleOf(float f);
AngleOf<T>();
static AngleOf<T> Degrees(float f);
static AngleOf<T> Radians(float f);
float ToFloat() const;
// float ToFloat() const;
float InDegrees() const;
float InRadians() const;
@ -45,18 +41,18 @@ class AngleOf {
AngleOf<T> operator+=(const AngleOf<T>& a);
friend AngleOf<T> operator*(const AngleOf<T>& a, float f) {
return AngleOf((float)a.ToFloat() * f);
return AngleOf::Degrees((float)a.InDegrees() * f);
}
friend AngleOf<T> operator*(float f, const AngleOf<T>& a) {
return AngleOf((float)f * a.ToFloat());
return AngleOf::Degrees((float)f * a.InDegrees());
}
static AngleOf<T> Normalize(AngleOf<T> a);
static AngleOf<T> Clamp(AngleOf<T> a, AngleOf<T> min, AngleOf<T> max);
static AngleOf<T> Difference(AngleOf<T> a, AngleOf<T> b) {
AngleOf<T> r = Normalize(b.ToFloat() - a.ToFloat());
return r;
};
// static AngleOf<T> Difference(AngleOf<T> a, AngleOf<T> b) {
// AngleOf<T> r = Normalize(b.InDegrees() - a.InDegrees());
// return r;
// };
static AngleOf<T> MoveTowards(AngleOf<T> fromAngle,
AngleOf<T> toAngle,
AngleOf<T> maxAngle);
@ -69,18 +65,25 @@ class AngleOf {
static AngleOf<T> Asin(float f);
static AngleOf<T> Atan(float f);
static AngleOf<T> CosineRuleSide(float a, float b, AngleOf<T> gamma);
static AngleOf<T> CosineRuleSide(float a, float b, float gamma);
static AngleOf<T> CosineRuleAngle(float a, float b, float c);
static AngleOf<T> SineRuleAngle(float a, AngleOf<T> beta, float c);
private:
T value;
AngleOf<T>(T value);
// These are deprecated, will move to private.
// Use Degrees/Radians instead
// AngleOf(signed int f);
// AngleOf(float f);
};
using Angle = AngleOf<float>;
using AngleSingle = AngleOf<float>;
using Angle16 = AngleOf<signed short>;
using Angle8 = AngleOf<signed char>;
} // namespace LinearAlgebra
} // namespace Passer

View File

@ -1,7 +1,7 @@
// 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 <stdlib.h>
#include "Angle.h"
@ -94,3 +94,4 @@ AngleOf<signed short> AngleOf<signed short>::CosineRuleAngle(float a,
float gamma = acosf(d) * Passer::LinearAlgebra::Rad2Deg;
return gamma;
}
*/

View File

@ -1,5 +1,5 @@
// #include "AngleUsing.h"
/*
#include <math.h>
#include <stdlib.h>
#include "Angle.h"
@ -37,4 +37,5 @@ typedef AngleOf<signed short> Angle16;
} // namespace LinearAlgebra
} // namespace Passer
using namespace Passer::LinearAlgebra;
using namespace Passer::LinearAlgebra;
*/

View File

@ -1,5 +1,5 @@
// #include "AngleUsing.h"
/*
#include <math.h>
#include "Angle.h"
@ -27,4 +27,5 @@ typedef AngleOf<signed long> Angle32;
} // namespace LinearAlgebra
} // namespace Passer
using namespace Passer::LinearAlgebra;
using namespace Passer::LinearAlgebra;
*/

View File

@ -1,7 +1,7 @@
// 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"
@ -56,4 +56,5 @@ AngleOf<signed char> AngleOf<signed char>::operator+(
AngleOf<signed char> angle = AngleOf();
angle.value = this->value + a.value;
return angle;
}
}
*/

View File

@ -1,5 +1,5 @@
// #include "AngleUsing.h"
/*
#include <math.h>
#include "Angle.h"
@ -31,4 +31,5 @@ typedef AngleOf<signed char> Angle8;
} // namespace LinearAlgebra
} // namespace Passer
using namespace Passer::LinearAlgebra;
using namespace Passer::LinearAlgebra;
*/

View File

@ -33,7 +33,7 @@ AngleAxisOf<T>::AngleAxisOf(Quaternion q) {
template <typename T>
const AngleAxisOf<T> AngleAxisOf<T>::zero =
AngleAxisOf<T>(0.0, DirectionOf<T>(0, 0));
AngleAxisOf<T>(0.0, DirectionOf<T>(AngleOf<T>(), AngleOf<T>()));
template <typename T>
Quaternion AngleAxisOf<T>::ToQuaternion() {

View File

@ -1,7 +1,7 @@
// 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 "Axis.h"
#include "Quaternion.h"
@ -10,8 +10,8 @@
#include <math.h>
Axis::Axis() {
horizontalAngle = 0.0f;
verticalAngle = 0.0f;
horizontalAngle = Angle();
verticalAngle = Angle();
}
Axis::Axis(Angle horizontal, Angle vertical) {
@ -37,4 +37,5 @@ Vector3 Axis::ToVector3() {
this->horizontalAngle.ToFloat(), 0) *
Vector3::forward;
return v;
}
}
*/

5
Axis.h
View File

@ -1,7 +1,7 @@
// 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/.
/*
#ifndef AXIS_H
#define AXIS_H
@ -35,4 +35,5 @@ public:
} // namespace Passer
using namespace Passer::LinearAlgebra;
#endif
#endif
*/

View File

@ -26,14 +26,11 @@ else()
add_library(LinearAlgebra STATIC
"FloatSingle.cpp"
"Angle.cpp"
"Angle8.cpp"
"Angle16.cpp"
"Vector2.cpp"
"Vector3.cpp"
"Quaternion.cpp"
"Polar.cpp"
"Spherical.cpp"
"Spherical16.cpp"
"Matrix.cpp"
"Axis.cpp"
"AngleAxis.cpp"

View File

@ -11,8 +11,8 @@
template <typename T>
DirectionOf<T>::DirectionOf() {
this->horizontal = AngleOf<T>(0.0f);
this->vertical = AngleOf<T>(0.0f);
this->horizontal = AngleOf<T>();
this->vertical = AngleOf<T>();
}
template <typename T>
@ -24,24 +24,29 @@ DirectionOf<T>::DirectionOf(AngleOf<T> horizontal, AngleOf<T> vertical) {
template <typename T>
DirectionOf<T>::DirectionOf(Vector3 v) {
this->horizontal =
atan2f(v.Right(), v.Forward()) * Passer::LinearAlgebra::Rad2Deg;
this->vertical = 90 - acosf(v.Up()) * Passer::LinearAlgebra::Rad2Deg;
this->horizontal = AngleOf<T>::Radians(atan2f(v.Right(), v.Forward()));
this->vertical = AngleOf<T>::Radians(-(0.5f * pi) - acosf(v.Up()));
Normalize();
}
template <typename T>
const DirectionOf<T> DirectionOf<T>::forward = DirectionOf<T>(0.0f, 0.0f);
const DirectionOf<T> DirectionOf<T>::forward =
DirectionOf<T>(AngleOf<T>(), AngleOf<T>());
template <typename T>
const DirectionOf<T> DirectionOf<T>::back = DirectionOf<T>(180.0f, 0.0f);
const DirectionOf<T> DirectionOf<T>::back =
DirectionOf<T>(AngleOf<T>::Degrees(180), AngleOf<T>());
template <typename T>
const DirectionOf<T> DirectionOf<T>::up = DirectionOf<T>(0.0f, 90.0f);
const DirectionOf<T> DirectionOf<T>::up =
DirectionOf<T>(AngleOf<T>(), AngleOf<T>::Degrees(90));
template <typename T>
const DirectionOf<T> DirectionOf<T>::down = DirectionOf<T>(0.0f, -90.0f);
const DirectionOf<T> DirectionOf<T>::down =
DirectionOf<T>(AngleOf<T>(), AngleOf<T>::Degrees(-90));
template <typename T>
const DirectionOf<T> DirectionOf<T>::left = DirectionOf<T>(-90.0f, 0.0f);
const DirectionOf<T> DirectionOf<T>::left =
DirectionOf<T>(AngleOf<T>::Degrees(-90), AngleOf<T>());
template <typename T>
const DirectionOf<T> DirectionOf<T>::right = DirectionOf<T>(90.0f, 0.0f);
const DirectionOf<T> DirectionOf<T>::right =
DirectionOf<T>(AngleOf<T>::Degrees(90), AngleOf<T>());
template <typename T>
DirectionOf<T> Passer::LinearAlgebra::DirectionOf<T>::Degrees(float horizontal,

View File

@ -5,19 +5,19 @@
template <typename T>
PolarOf<T>::PolarOf() {
this->distance = 0.0f;
this->angle = 0.0f;
this->angle = AngleOf<T>();
}
template <typename T>
PolarOf<T>::PolarOf(float distance, AngleOf<T> angle) {
// distance should always be 0 or greater
if (distance < 0.0f) {
this->distance = -distance;
this->angle = AngleOf<T>::Normalize(angle.ToFloat() - 180.0f);
this->angle = AngleOf<T>::Normalize(angle - AngleOf<T>::Degrees(180));
} else {
this->distance = distance;
if (this->distance == 0.0f)
// angle is always 0 if distance is 0
this->angle = 0.0f;
this->angle = AngleOf<T>();
else
this->angle = AngleOf<T>::Normalize(angle);
}
@ -26,34 +26,35 @@ PolarOf<T>::PolarOf(float distance, AngleOf<T> angle) {
template <typename T>
PolarOf<T> PolarOf<T>::FromVector2(Vector2 v) {
float distance = v.magnitude();
AngleOf<T> angle = Vector2::SignedAngle(Vector2::forward, v);
AngleOf<T> angle =
AngleOf<T>::Degrees(Vector2::SignedAngle(Vector2::forward, v));
PolarOf<T> p = PolarOf(distance, angle);
return p;
}
template <typename T>
PolarOf<T> PolarOf<T>::FromSpherical(SphericalOf<T> v) {
float distance =
v.distance * cosf(v.vertical.ToFloat() * Passer::LinearAlgebra::Deg2Rad);
float distance = v.distance * cosf(v.vertical.InDegrees() *
Passer::LinearAlgebra::Deg2Rad);
AngleOf<T> angle = v.horizontal;
PolarOf<T> p = PolarOf(distance, angle);
return p;
}
template <typename T>
const PolarOf<T> PolarOf<T>::zero = PolarOf(0.0f, 0.0f);
const PolarOf<T> PolarOf<T>::zero = PolarOf(0.0f, AngleOf<T>());
template <typename T>
const PolarOf<T> PolarOf<T>::forward = PolarOf(1.0f, 0.0f);
const PolarOf<T> PolarOf<T>::forward = PolarOf(1.0f, AngleOf<T>());
template <typename T>
const PolarOf<T> PolarOf<T>::back = PolarOf(1.0, 180.0f);
const PolarOf<T> PolarOf<T>::back = PolarOf(1.0, AngleOf<T>::Degrees(180));
template <typename T>
const PolarOf<T> PolarOf<T>::right = PolarOf(1.0, 90.0f);
const PolarOf<T> PolarOf<T>::right = PolarOf(1.0, AngleOf<T>::Degrees(90));
template <typename T>
const PolarOf<T> PolarOf<T>::left = PolarOf(1.0, -90.0f);
const PolarOf<T> PolarOf<T>::left = PolarOf(1.0, AngleOf<T>::Degrees(-90));
template <typename T>
bool PolarOf<T>::operator==(const PolarOf& v) const {
return (this->distance == v.distance &&
this->angle.ToFloat() == v.angle.ToFloat());
this->angle.InDegrees() == v.angle.InDegrees());
}
template <typename T>
@ -69,7 +70,8 @@ PolarOf<T> PolarOf<T>::normalized() const {
template <typename T>
PolarOf<T> PolarOf<T>::operator-() const {
PolarOf<T> v = PolarOf(this->distance, this->angle + AngleOf<T>(180));
PolarOf<T> v =
PolarOf(this->distance, this->angle + AngleOf<T>::Degrees(180));
return v;
}
@ -91,8 +93,7 @@ PolarOf<T> PolarOf<T>::operator+(const PolarOf& v) const {
if (this->distance == 0.0f)
return v;
float deltaAngle =
Angle::Normalize(v.angle.ToFloat() - this->angle.ToFloat()).ToFloat();
float deltaAngle = AngleOf<T>::Normalize(v.angle - this->angle).InDegrees();
float rotation =
deltaAngle < 0.0f ? 180.0f + deltaAngle : 180.0f - deltaAngle;
@ -102,15 +103,15 @@ PolarOf<T> PolarOf<T>::operator+(const PolarOf& v) const {
}
float newDistance =
Angle::CosineRuleSide(v.distance, this->distance, rotation).ToFloat();
Angle::CosineRuleSide(v.distance, this->distance, rotation).InDegrees();
float angle =
Angle::CosineRuleAngle(newDistance, this->distance, v.distance).ToFloat();
float angle = Angle::CosineRuleAngle(newDistance, this->distance, v.distance)
.InDegrees();
float newAngle = deltaAngle < 0.0f ? this->angle.ToFloat() - angle
: this->angle.ToFloat() + angle;
newAngle = Angle::Normalize(newAngle).ToFloat();
PolarOf vector = PolarOf(newDistance, newAngle);
float newAngle = deltaAngle < 0.0f ? this->angle.InDegrees() - angle
: this->angle.InDegrees() + angle;
AngleOf<T> newAngleA = AngleOf<T>::Normalize(AngleOf<T>::Degrees(newAngle));
PolarOf vector = PolarOf(newDistance, newAngleA);
return vector;
}
template <typename T>
@ -133,8 +134,8 @@ PolarOf<T> PolarOf<T>::operator/=(float f) {
template <typename T>
float PolarOf<T>::Distance(const PolarOf& v1, const PolarOf& v2) {
float d = Angle::CosineRuleSide(v1.distance, v2.distance,
v2.angle.ToFloat() - v1.angle.ToFloat())
.ToFloat();
v2.angle.InDegrees() - v1.angle.InDegrees())
.InDegrees();
return d;
}

View File

@ -206,7 +206,7 @@ Quaternion Quaternion::FromToRotation(Vector3 fromDirection,
Vector3 axis = Vector3::Cross(fromDirection, toDirection);
axis = Vector3::Normalize(axis);
AngleOf<float> angle = Vector3::SignedAngle(fromDirection, toDirection, axis);
Quaternion rotation = Quaternion::AngleAxis(angle.ToFloat(), axis);
Quaternion rotation = Quaternion::AngleAxis(angle.InDegrees(), axis);
return rotation;
}

View File

@ -8,8 +8,8 @@
template <typename T>
SphericalOf<T>::SphericalOf() {
this->distance = 0.0f;
this->horizontal = AngleOf<T>(0);
this->vertical = AngleOf<T>(0);
this->horizontal = AngleOf<T>();
this->vertical = AngleOf<T>();
}
// template <>
@ -49,7 +49,7 @@ SphericalOf<T>::SphericalOf(float distance,
template <typename T>
SphericalOf<T> SphericalOf<T>::FromPolar(PolarOf<T> polar) {
AngleOf<T> horizontal = polar.angle;
AngleOf<T> vertical = AngleOf<T>(0);
AngleOf<T> vertical = AngleOf<T>();
SphericalOf<T> r = SphericalOf(polar.distance, horizontal, vertical);
return r;
}
@ -58,12 +58,12 @@ template <typename T>
SphericalOf<T> SphericalOf<T>::FromVector3(Vector3 v) {
float distance = v.magnitude();
if (distance == 0.0f) {
return SphericalOf(distance, 0, 0);
return SphericalOf(distance, AngleOf<T>(), AngleOf<T>());
} else {
float verticalAngle =
(90.0f - acosf(v.Up() / distance) * Passer::LinearAlgebra::Rad2Deg);
float horizontalAngle =
atan2f(v.Right(), v.Forward()) * Passer::LinearAlgebra::Rad2Deg;
AngleOf<T> verticalAngle =
AngleOf<T>::Radians((90.0f - acosf(v.Up() / distance)));
AngleOf<T> horizontalAngle =
AngleOf<T>::Radians(atan2f(v.Right(), v.Forward()));
return SphericalOf(distance, horizontalAngle, verticalAngle);
}
}
@ -88,23 +88,29 @@ Vector3 SphericalOf<T>::ToVector3() const {
template <typename T>
const SphericalOf<T> SphericalOf<T>::zero =
SphericalOf<T>(0.0f, AngleOf<T>(0), AngleOf<T>(0));
SphericalOf<T>(0.0f, AngleOf<T>(), AngleOf<T>());
template <typename T>
const SphericalOf<T> SphericalOf<T>::forward = SphericalOf<T>(1.0f, 0.0f, 0.0f);
const SphericalOf<T> SphericalOf<T>::forward =
SphericalOf<T>(1.0f, AngleOf<T>(), AngleOf<T>());
template <typename T>
const SphericalOf<T> SphericalOf<T>::back = SphericalOf<T>(1.0f, 180.0f, 0.0f);
const SphericalOf<T> SphericalOf<T>::back =
SphericalOf<T>(1.0f, AngleOf<T>::Degrees(180), AngleOf<T>());
template <typename T>
const SphericalOf<T> SphericalOf<T>::right = SphericalOf<T>(1.0f, 90.0f, 0.0f);
const SphericalOf<T> SphericalOf<T>::right =
SphericalOf<T>(1.0f, AngleOf<T>::Degrees(90), AngleOf<T>());
template <typename T>
const SphericalOf<T> SphericalOf<T>::left = SphericalOf<T>(1.0f, -90.0f, 0.0f);
const SphericalOf<T> SphericalOf<T>::left =
SphericalOf<T>(1.0f, AngleOf<T>::Degrees(-90), AngleOf<T>());
template <typename T>
const SphericalOf<T> SphericalOf<T>::up = SphericalOf<T>(1.0f, 0.0f, 90.0f);
const SphericalOf<T> SphericalOf<T>::up =
SphericalOf<T>(1.0f, AngleOf<T>(), AngleOf<T>::Degrees(90));
template <typename T>
const SphericalOf<T> SphericalOf<T>::down = SphericalOf<T>(1.0f, 0.0f, -90.0f);
const SphericalOf<T> SphericalOf<T>::down =
SphericalOf<T>(1.0f, AngleOf<T>(), AngleOf<T>::Degrees(-90));
template <>
const SphericalOf<signed short> SphericalOf<signed short>::zero =
SphericalOf(0.0f, AngleOf<signed short>(0), AngleOf<signed short>(0));
SphericalOf(0.0f, AngleOf<signed short>(), AngleOf<signed short>());
template <typename T>
SphericalOf<T> SphericalOf<T>::WithDistance(float distance) {
@ -114,9 +120,9 @@ SphericalOf<T> SphericalOf<T>::WithDistance(float distance) {
template <typename T>
SphericalOf<T> SphericalOf<T>::operator-() const {
SphericalOf<T> v =
SphericalOf<T>(this->distance, this->horizontal.ToFloat() + 180.0f,
this->vertical.ToFloat() + 180.0f);
SphericalOf<T> v = SphericalOf<T>(this->distance,
this->horizontal + AngleOf<T>::Degrees(180),
this->vertical + AngleOf<T>::Degrees(180));
return v;
}

View File

@ -1,257 +0,0 @@
/*
#include "Spherical16.h"
#include "Quaternion.h"
#include "Spherical.h"
#include <math.h>
Spherical16::Spherical16() {
this->distance = 0.0f;
this->horizontalAngle = Angle16(0);
this->verticalAngle = Angle16(0);
}
Spherical16::Spherical16(Polar polar) {
this->distance = polar.distance;
this->horizontalAngle = Angle16(polar.angle.ToFloat());
this->verticalAngle = Angle16(0);
}
Spherical16::Spherical16(float distance,
Angle16 horizontalAngle,
Angle16 verticalAngle) {
if (distance < 0) {
this->distance = -distance;
this->horizontalAngle = horizontalAngle.ToFloat() - Angle16(180).ToFloat();
this->verticalAngle = verticalAngle;
} else {
this->distance = distance;
this->horizontalAngle = horizontalAngle;
this->verticalAngle = verticalAngle;
}
}
Spherical16::Spherical16(Vector3 v) {
this->distance = v.magnitude();
if (distance == 0.0f) {
this->verticalAngle = 0.0f;
this->horizontalAngle = 0.0f;
} else {
this->verticalAngle = (90.0f - acosf(v.Up() / this->distance) *
Passer::LinearAlgebra::Rad2Deg);
this->horizontalAngle =
atan2f(v.Right(), v.Forward()) * Passer::LinearAlgebra::Rad2Deg;
}
}
Vector3 Passer::LinearAlgebra::Spherical16::ToVector3() {
float verticalRad =
(90.0f - this->verticalAngle.ToFloat()) * Passer::LinearAlgebra::Deg2Rad;
float horizontalRad =
this->horizontalAngle.ToFloat() * Passer::LinearAlgebra::Deg2Rad;
float cosVertical = cosf(verticalRad);
float sinVertical = sinf(verticalRad);
float cosHorizontal = cosf(horizontalRad);
float sinHorizontal = sinf(horizontalRad);
float x = this->distance * sinVertical * sinHorizontal;
float y = this->distance * cosVertical;
float z = this->distance * sinVertical * cosHorizontal;
Vector3 v = Vector3(x, y, z);
return Vector3();
}
const Spherical16 Spherical16::zero = Spherical16(0.0f, 0.0f, 0.0f);
const Spherical16 Spherical16::forward = Spherical16(1.0f, 0.0f, 0.0f);
const Spherical16 Spherical16::back = Spherical16(1.0f, 180.0f, 0.0f);
const Spherical16 Spherical16::right = Spherical16(1.0f, 90.0f, 0.0f);
const Spherical16 Spherical16::left = Spherical16(1.0f, -90.0f, 0.0f);
const Spherical16 Spherical16::up = Spherical16(1.0f, 0.0f, 90.0f);
const Spherical16 Spherical16::down = Spherical16(1.0f, 0.0f, -90.0f);
bool Spherical16::operator==(const Spherical16& v) const {
return (this->distance == v.distance &&
this->horizontalAngle.ToFloat() == v.horizontalAngle.ToFloat() &&
this->verticalAngle.ToFloat() == v.verticalAngle.ToFloat());
}
Spherical16 Spherical16::Normalize(const Spherical16& v) {
Spherical16 r = Spherical16(1, v.horizontalAngle, v.verticalAngle);
return r;
}
Spherical16 Spherical16::normalized() const {
Spherical16 r = Spherical16(1, this->horizontalAngle, this->verticalAngle);
return r;
}
Spherical16 Spherical16::operator-() const {
Spherical16 v =
Spherical16(this->distance, this->horizontalAngle.ToFloat() + 180.0f,
this->verticalAngle.ToFloat() + 180.0f);
return v;
}
Spherical16 Spherical16::operator-(const Spherical16& s2) const {
Spherical thisSpherical =
Spherical(this->distance, this->horizontalAngle.ToFloat(),
this->verticalAngle.ToFloat());
Spherical spherical2 = Spherical(s2.distance, s2.horizontalAngle.ToFloat(),
s2.verticalAngle.ToFloat());
// let's do it the easy way...
Vector3 v1 = Vector3(thisSpherical);
Vector3 v2 = Vector3(spherical2);
Vector3 v = v1 - v2;
Spherical16 r = Spherical16(v);
return r;
}
Spherical16 Spherical16::operator-=(const Spherical16& v) {
*this = *this - v;
return *this;
}
Spherical16 Spherical16::operator+(const Spherical16& s2) const {
// let's do it the easy way...
Vector3 v1 =
Vector3(Spherical(this->distance, this->horizontalAngle.ToFloat(),
this->verticalAngle.ToFloat()));
Vector3 v2 = Vector3(Spherical(s2.distance, s2.horizontalAngle.ToFloat(),
s2.verticalAngle.ToFloat()));
Vector3 v = v1 + v2;
Spherical16 r = Spherical16(v);
return r;
// This is the hard way...
if (v2.distance <= 0)
return Spherical(this->distance, this->horizontalAngle,
this->verticalAngle);
if (this->distance <= 0)
return v2;
float deltaHorizontalAngle =
(float)Angle::Normalize(v2.horizontalAngle - this->horizontalAngle);
float horizontalRotation = deltaHorizontalAngle < 0
? 180 + deltaHorizontalAngle
: 180 - deltaHorizontalAngle;
float deltaVerticalAngle =
Angle::Normalize(v2.verticalAngle - this->verticalAngle);
float verticalRotation = deltaVerticalAngle < 0 ? 180 + deltaVerticalAngle
: 180 - deltaVerticalAngle;
if (horizontalRotation == 180 && verticalRotation == 180)
// angle is too small, take this angle and add the distances
return Spherical(this->distance + v2.distance, this->horizontalAngle,
this->verticalAngle);
Angle rotation = AngleBetween(*this, v2);
float newDistance =
Angle::CosineRuleSide(v2.distance, this->distance, rotation);
float angle =
Angle::CosineRuleAngle(newDistance, this->distance, v2.distance);
// Now we have to project the angle to the horizontal and vertical planes...
// The axis for the angle is the cross product of the two spherical vectors
// (which function we do not have either...)
float horizontalAngle = 0;
float verticalAngle = 0;
float newHorizontalAngle =
deltaHorizontalAngle < 0
? Angle::Normalize(this->horizontalAngle - horizontalAngle)
: Angle::Normalize(this->horizontalAngle + horizontalAngle);
float newVerticalAngle =
deltaVerticalAngle < 0
? Angle::Normalize(this->verticalAngle - verticalAngle)
: Angle::Normalize(this->verticalAngle + verticalAngle);
Spherical v = Spherical(newDistance, newHorizontalAngle, newVerticalAngle);
}
Spherical16 Spherical16::operator+=(const Spherical16& 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);
// }
Spherical16 Spherical16::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);
// }
Spherical16 Spherical16::operator/=(float f) {
this->distance /= f;
return *this;
}
// float Spherical::GetSwing() {
// // Not sure if this is correct
// return sqrtf(horizontalAngle * horizontalAngle +
// verticalAngle * verticalAngle);
// }
// float Spherical::Distance(const Spherical &s1, const Spherical &s2) {
// float d = 0;
// return d;
// }
#include "AngleUsing.h"
#include "FloatSingle.h"
#include "Vector3.h"
const float epsilon = 1E-05f;
const float Rad2Deg = 57.29578F;
Angle Spherical16::AngleBetween(const Spherical16& v1, const Spherical16& 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);
if (denominator < epsilon)
return 0.0f;
Vector3 v1_3 = Vector3(Spherical(v1.distance, v1.horizontalAngle.ToFloat(),
v1.verticalAngle.ToFloat()));
Vector3 v2_3 = Vector3(Spherical(v2.distance, v2.horizontalAngle.ToFloat(),
v2.verticalAngle.ToFloat()));
float dot = Vector3::Dot(v1_3, v2_3);
float fraction = dot / denominator;
if (isnan(fraction))
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;
}
Spherical16 Spherical16::Rotate(const Spherical16& v,
Angle horizontalAngle,
Angle verticalAngle) {
Spherical16 r = Spherical16(
v.distance, v.horizontalAngle.ToFloat() + horizontalAngle.ToFloat(),
v.verticalAngle.ToFloat() + verticalAngle.ToFloat());
return r;
}
Spherical16 Spherical16::RotateHorizontal(const Spherical16& v, Angle a) {
Spherical16 r = Spherical16(
v.distance, v.horizontalAngle.ToFloat() + a.ToFloat(), v.verticalAngle);
return r;
}
Spherical16 Spherical16::RotateVertical(const Spherical16& v, Angle a) {
Spherical16 r = Spherical16(v.distance, v.horizontalAngle,
v.verticalAngle.ToFloat() + a.ToFloat());
return r;
}
*/

View File

@ -1,162 +0,0 @@
/*
// 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/.
#ifndef SPHERICAL16_H
#define SPHERICAL16_H
#include "Angle16.h"
#include "Polar.h"
namespace Passer {
namespace LinearAlgebra {
struct Vector3;
/// @brief A spherical vector
/// @details This is a vector in 3D space using a spherical coordinate system.
/// It consists of a distance and the polar and elevation angles from a
/// reference direction. The reference direction is typically thought of
/// as a forward direction.
/// In contrast to the normal Spherical type, this version uses 16 bit integers
/// for the angles
struct Spherical16 {
public:
/// @brief The distance in meters
/// @remark The distance should never be negative
float distance;
/// @brief The angle in the horizontal plane in degrees, clockwise rotation
/// @details The angle is automatically normalized to -180 .. 180
Angle16 horizontalAngle;
/// @brief The angle in the vertical plane in degrees. Positive is upward.
/// @details The angle is automatically normalized to -180 .. 180
Angle16 verticalAngle;
/// @brief Create a new spherical vector with zero degrees and distance
Spherical16();
/// @brief Create a new spherical vector
/// @param distance The distance in meters
/// @param horizontalAngle The angle in the horizontal plane in degrees,
/// clockwise rotation
/// @param verticalAngle The angle in the vertical plan in degrees,
/// zero is forward, positive is upward
Spherical16(float distance, Angle16 horizontalAngle, Angle16 verticalAngle);
/// @brief Convert polar coordinates to spherical coordinates
/// @param polar The polar coordinate
Spherical16(Polar polar);
/// @brief Convert 3D carthesian coordinates to spherical coordinates
/// @param v Vector in 3D carthesian coordinates;
Spherical16(Vector3 v);
Vector3 ToVector3();
/// @brief A spherical vector with zero degree angles and distance
const static Spherical16 zero;
/// @brief A normalized forward-oriented vector
const static Spherical16 forward;
/// @brief A normalized back-oriented vector
const static Spherical16 back;
/// @brief A normalized right-oriented vector
const static Spherical16 right;
/// @brief A normalized left-oriented vector
const static Spherical16 left;
/// @brief A normalized up-oriented vector
const static Spherical16 up;
/// @brief A normalized down-oriented vector
const static Spherical16 down;
/// @brief Equality test to another vector
/// @param v The vector to check against
/// @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 Spherical16& 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 Spherical16& v) { return v.distance; }
/// @brief The vector length
/// @return The vector length
inline float magnitude() const { return this->distance; }
/// @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 Spherical16 Normalize(const Spherical16& v);
/// @brief Convert the vector to a length of a
/// @return The vector normalized to a length of 1
Spherical16 normalized() const;
/// @brief Negate the vector
/// @return The negated vector
/// This will rotate the vector by 180 degrees horizontally and
/// vertically. Distance will stay the same.
Spherical16 operator-() const;
/// @brief Subtract a spherical vector from this vector
/// @param v The vector to subtract
/// @return The result of the subtraction
Spherical16 operator-(const Spherical16& v) const;
Spherical16 operator-=(const Spherical16& v);
/// @brief Add a spherical vector to this vector
/// @param v The vector to add
/// @return The result of the addition
Spherical16 operator+(const Spherical16& v) const;
Spherical16 operator+=(const Spherical16& 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 Spherical16 operator*(const Spherical16& v, float f) {
return Spherical16(v.distance * f, v.horizontalAngle, v.verticalAngle);
}
friend Spherical16 operator*(float f, const Spherical16& v) {
return Spherical16(
v.distance * f, v.horizontalAngle,
v.verticalAngle); // not correct, should be f * v.distance
}
Spherical16 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 Spherical16 operator/(const Spherical16& v, float f) {
return Spherical16(v.distance / f, v.horizontalAngle, v.verticalAngle);
}
friend Spherical16 operator/(float f, const Spherical16& v) {
return Spherical16(
v.distance / f, v.horizontalAngle,
v.verticalAngle); // not correct, should be f / v.distance
}
Spherical16 operator/=(float f);
/// <summary>
/// The distance between two vectors
/// </summary>
/// <param name="v1">The first vector</param>
/// <param name="v2">The second vector</param>
/// <returns>The distance between the two vectors</returns>
// static float Distance(const Spherical16 &s1, const Spherical16 &s2);
static Angle AngleBetween(const Spherical16& v1, const Spherical16& v2);
static Spherical16 Rotate(const Spherical16& v,
Angle horizontalAngle,
Angle verticalAngle);
static Spherical16 RotateHorizontal(const Spherical16& v, Angle angle);
static Spherical16 RotateVertical(const Spherical16& v, Angle angle);
};
} // namespace LinearAlgebra
} // namespace Passer
using namespace Passer::LinearAlgebra;
#include "Vector3.h"
#endif
*/

View File

@ -6,8 +6,8 @@
template <typename T>
SwingTwistOf<T>::SwingTwistOf() {
this->swing = DirectionOf<T>(0, 0);
this->twist = AngleOf<T>(0);
this->swing = DirectionOf<T>(AngleOf<T>(), AngleOf<T>());
this->twist = AngleOf<T>();
}
template <typename T>
@ -40,9 +40,9 @@ SwingTwistOf<T> SwingTwistOf<T>::Degrees(float horizontal,
template <typename T>
Quaternion SwingTwistOf<T>::ToQuaternion() const {
Quaternion q = Quaternion::Euler(this->swing.vertical.ToFloat(),
this->swing.horizontal.ToFloat(),
this->twist.ToFloat());
Quaternion q = Quaternion::Euler(this->swing.vertical.InDegrees(),
this->swing.horizontal.InDegrees(),
this->twist.InDegrees());
return q;
}
@ -50,8 +50,9 @@ template <typename T>
SwingTwistOf<T> Passer::LinearAlgebra::SwingTwistOf<T>::FromQuaternion(
Quaternion q) {
Vector3 angles = Quaternion::ToAngles(q);
SwingTwistOf<T> r =
SwingTwistOf<T>(angles.Up(), angles.Right(), angles.Forward());
SwingTwistOf<T> r = SwingTwistOf<T>(AngleOf<T>::Degrees(angles.Up()),
AngleOf<T>::Degrees(angles.Right()),
AngleOf<T>::Degrees(angles.Forward()));
return r;
}

View File

@ -30,7 +30,7 @@ Vector2::Vector2(Vector3 v) {
y = v.Forward(); // z;
}
Vector2::Vector2(Polar p) {
float horizontalRad = p.angle.ToFloat() * Passer::LinearAlgebra::Deg2Rad;
float horizontalRad = p.angle.InDegrees() * Passer::LinearAlgebra::Deg2Rad;
float cosHorizontal = cosf(horizontalRad);
float sinHorizontal = sinf(horizontalRad);
@ -160,7 +160,7 @@ float Vector2::SignedAngle(const Vector2& v1, const Vector2& v2) {
}
Vector2 Vector2::Rotate(const Vector2& v, Passer::LinearAlgebra::Angle a) {
float angleRad = a.ToFloat() * Passer::LinearAlgebra::Deg2Rad;
float angleRad = a.InDegrees() * Passer::LinearAlgebra::Deg2Rad;
#if defined(AVR)
float sinValue = sin(angleRad);
float cosValue = cos(angleRad); // * Angle::Deg2Rad);

View File

@ -32,8 +32,9 @@ Vector3::Vector3(Vector2 v) {
Vector3::Vector3(Spherical s) {
float verticalRad =
(90.0f - s.vertical.ToFloat()) * Passer::LinearAlgebra::Deg2Rad;
float horizontalRad = s.horizontal.ToFloat() * Passer::LinearAlgebra::Deg2Rad;
(90.0f - s.vertical.InDegrees()) * Passer::LinearAlgebra::Deg2Rad;
float horizontalRad =
s.horizontal.InDegrees() * Passer::LinearAlgebra::Deg2Rad;
float cosVertical = cosf(verticalRad);
float sinVertical = sinf(verticalRad);
float cosHorizontal = cosf(horizontalRad);
@ -190,16 +191,17 @@ float clamp(float x, float lower, float upper) {
AngleOf<float> Vector3::Angle(const Vector3& v1, const Vector3& v2) {
float denominator = sqrtf(v1.sqrMagnitude() * v2.sqrMagnitude());
if (denominator < epsilon)
return 0;
return AngleOf<float>();
float dot = Vector3::Dot(v1, v2);
float fraction = dot / denominator;
if (isnan(fraction))
return fraction; // short cut to returning NaN universally
return AngleOf<float>::Degrees(
fraction); // short cut to returning NaN universally
float cdot = clamp(fraction, -1.0, 1.0);
float r = ((float)acos(cdot)) * Rad2Deg;
return AngleOf<float>(r);
float r = ((float)acos(cdot));
return AngleOf<float>::Radians(r);
}
AngleOf<float> Vector3::SignedAngle(const Vector3& v1,

View File

@ -9,187 +9,213 @@
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
TEST(Angle16, Compare) {
Angle16 a = Angle16(45);
Angle16 a = Angle16::Degrees(45);
bool r = false;
r = a > Angle16(0);
r = a > Angle16::Degrees(0);
EXPECT_TRUE(r) << "45 > 0";
r = a > Angle16(90);
r = a > Angle16::Degrees(90);
EXPECT_FALSE(r) << "45 > 90";
r = a > Angle16(-90);
r = a > Angle16::Degrees(-90);
EXPECT_TRUE(r) << "45 > -90";
}
TEST(AngleSingle, Compare) {
AngleSingle a = AngleSingle(45);
AngleSingle a = AngleSingle::Degrees(45);
bool r = false;
r = a > AngleSingle(0);
r = a > AngleSingle::Degrees(0);
EXPECT_TRUE(r) << "45 > 0";
r = a > AngleSingle(90);
r = a > AngleSingle::Degrees(90);
EXPECT_FALSE(r) << "45 > 90";
r = a > AngleSingle(-90);
r = a > AngleSingle::Degrees(-90);
EXPECT_TRUE(r) << "45 > -90";
}
TEST(Angle, Normalize) {
Angle r = 0;
Angle r = AngleSingle();
r = Angle::Normalize(90.0f);
EXPECT_FLOAT_EQ(r.ToFloat(), 90) << "Normalize 90";
r = Angle::Normalize(AngleSingle::Degrees(90.0f));
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "Normalize 90";
r = Angle::Normalize(-90);
EXPECT_FLOAT_EQ(r.ToFloat(), -90) << "Normalize -90";
r = Angle::Normalize(AngleSingle::Degrees(-90));
EXPECT_FLOAT_EQ(r.InDegrees(), -90) << "Normalize -90";
r = Angle::Normalize(270);
EXPECT_FLOAT_EQ(r.ToFloat(), -90) << "Normalize 270";
r = Angle::Normalize(AngleSingle::Degrees(270));
EXPECT_FLOAT_EQ(r.InDegrees(), -90) << "Normalize 270";
r = Angle::Normalize(270 + 360);
EXPECT_FLOAT_EQ(r.ToFloat(), -90) << "Normalize 270+360";
r = Angle::Normalize(AngleSingle::Degrees(270 + 360));
EXPECT_FLOAT_EQ(r.InDegrees(), -90) << "Normalize 270+360";
r = Angle::Normalize(-270);
EXPECT_FLOAT_EQ(r.ToFloat(), 90) << "Normalize -270";
r = Angle::Normalize(AngleSingle::Degrees(-270));
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "Normalize -270";
r = Angle::Normalize(-270 - 360);
EXPECT_FLOAT_EQ(r.ToFloat(), 90) << "Normalize -270-360";
r = Angle::Normalize(AngleSingle::Degrees(-270 - 360));
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "Normalize -270-360";
r = Angle::Normalize(0);
EXPECT_FLOAT_EQ(r.ToFloat(), 0) << "Normalize 0";
r = Angle::Normalize(AngleSingle::Degrees(0));
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Normalize 0";
if (std::numeric_limits<float>::is_iec559) {
r = Angle::Normalize(FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r.ToFloat(), FLOAT_INFINITY) << "Normalize INFINITY";
r = Angle::Normalize(AngleSingle::Degrees(FLOAT_INFINITY));
EXPECT_FLOAT_EQ(r.InDegrees(), FLOAT_INFINITY) << "Normalize INFINITY";
r = Angle::Normalize(-FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r.ToFloat(), -FLOAT_INFINITY) << "Normalize INFINITY";
r = Angle::Normalize(AngleSingle::Degrees(-FLOAT_INFINITY));
EXPECT_FLOAT_EQ(r.InDegrees(), -FLOAT_INFINITY) << "Normalize INFINITY";
}
}
TEST(Angle, Clamp) {
Angle r = 0;
Angle r = AngleSingle();
r = Angle::Clamp(1, 0, 2);
EXPECT_FLOAT_EQ(r.ToFloat(), 1) << "Clamp 1 0 2";
r = Angle::Clamp(AngleSingle::Degrees(1), AngleSingle::Degrees(0),
AngleSingle::Degrees(2));
EXPECT_FLOAT_EQ(r.InDegrees(), 1) << "Clamp 1 0 2";
r = Angle::Clamp(-1, 0, 2);
EXPECT_FLOAT_EQ(r.ToFloat(), 0) << "Clamp -1 0 2";
r = Angle::Clamp(AngleSingle::Degrees(-1), AngleSingle::Degrees(0),
AngleSingle::Degrees(2));
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Clamp -1 0 2";
r = Angle::Clamp(3, 0, 2);
EXPECT_FLOAT_EQ(r.ToFloat(), 2) << "Clamp 3 0 2";
r = Angle::Clamp(AngleSingle::Degrees(3), AngleSingle::Degrees(0),
AngleSingle::Degrees(2));
EXPECT_FLOAT_EQ(r.InDegrees(), 2) << "Clamp 3 0 2";
r = Angle::Clamp(1, 0, 0);
EXPECT_FLOAT_EQ(r.ToFloat(), 0) << "Clamp 1 0 0";
r = Angle::Clamp(AngleSingle::Degrees(1), AngleSingle::Degrees(0),
AngleSingle::Degrees(0));
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Clamp 1 0 0";
r = Angle::Clamp(0, 0, 0);
EXPECT_FLOAT_EQ(r.ToFloat(), 0) << "Clamp 0 0 0";
r = Angle::Clamp(AngleSingle::Degrees(0), AngleSingle::Degrees(0),
AngleSingle::Degrees(0));
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Clamp 0 0 0";
r = Angle::Clamp(0, 1, -1);
EXPECT_FLOAT_EQ(r.ToFloat(), 1) << "Clamp 0 1 -1";
r = Angle::Clamp(AngleSingle::Degrees(0), AngleSingle::Degrees(1),
AngleSingle::Degrees(-1));
EXPECT_FLOAT_EQ(r.InDegrees(), 1) << "Clamp 0 1 -1";
if (std::numeric_limits<float>::is_iec559) {
r = Angle::Clamp(1, 0, FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r.ToFloat(), 1) << "Clamp 1 0 INFINITY";
r = Angle::Clamp(AngleSingle::Degrees(1), AngleSingle::Degrees(0),
AngleSingle::Degrees(FLOAT_INFINITY));
EXPECT_FLOAT_EQ(r.InDegrees(), 1) << "Clamp 1 0 INFINITY";
r = Angle::Clamp(1, -FLOAT_INFINITY, 1);
EXPECT_FLOAT_EQ(r.ToFloat(), 1) << "Clamp 1 -INFINITY 1";
r = Angle::Clamp(AngleSingle::Degrees(1),
AngleSingle::Degrees(-FLOAT_INFINITY),
AngleSingle::Degrees(1));
EXPECT_FLOAT_EQ(r.InDegrees(), 1) << "Clamp 1 -INFINITY 1";
}
}
TEST(Angle, Difference) {
Angle r = 0;
// TEST(Angle, Difference) {
// Angle r = 0;
r = Angle::Difference(0, 90);
EXPECT_FLOAT_EQ(r.ToFloat(), 90) << "Difference 0 90";
// r = Angle::Difference(0, 90);
// EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "Difference 0 90";
r = Angle::Difference(0, -90);
EXPECT_FLOAT_EQ(r.ToFloat(), -90) << "Difference 0 -90";
// r = Angle::Difference(0, -90);
// EXPECT_FLOAT_EQ(r.InDegrees(), -90) << "Difference 0 -90";
r = Angle::Difference(0, 270);
EXPECT_FLOAT_EQ(r.ToFloat(), -90) << "Difference 0 270";
// r = Angle::Difference(0, 270);
// EXPECT_FLOAT_EQ(r.InDegrees(), -90) << "Difference 0 270";
r = Angle::Difference(0, -270);
EXPECT_FLOAT_EQ(r.ToFloat(), 90) << "Difference 0 -270";
// r = Angle::Difference(0, -270);
// EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "Difference 0 -270";
r = Angle::Difference(90, 0);
EXPECT_FLOAT_EQ(r.ToFloat(), -90) << "Difference 90 0";
// r = Angle::Difference(90, 0);
// EXPECT_FLOAT_EQ(r.InDegrees(), -90) << "Difference 90 0";
r = Angle::Difference(-90, 0);
EXPECT_FLOAT_EQ(r.ToFloat(), 90) << "Difference -90 0";
// r = Angle::Difference(-90, 0);
// EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "Difference -90 0";
r = Angle::Difference(0, 0);
EXPECT_FLOAT_EQ(r.ToFloat(), 0) << "Difference 0 0";
// r = Angle::Difference(0, 0);
// EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Difference 0 0";
r = Angle::Difference(90, 90);
EXPECT_FLOAT_EQ(r.ToFloat(), 0) << "Difference 90 90";
// r = Angle::Difference(90, 90);
// EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "Difference 90 90";
if (std::numeric_limits<float>::is_iec559) {
r = Angle::Difference(0, INFINITY);
EXPECT_FLOAT_EQ(r.ToFloat(), INFINITY) << "Difference 0 INFINITY";
// if (std::numeric_limits<float>::is_iec559) {
// r = Angle::Difference(0, INFINITY);
// EXPECT_FLOAT_EQ(r.InDegrees(), INFINITY) << "Difference 0 INFINITY";
r = Angle::Difference(0, -INFINITY);
EXPECT_FLOAT_EQ(r.ToFloat(), -INFINITY) << "Difference 0 -INFINITY";
// r = Angle::Difference(0, -INFINITY);
// EXPECT_FLOAT_EQ(r.InDegrees(), -INFINITY) << "Difference 0 -INFINITY";
r = Angle::Difference(-INFINITY, INFINITY);
EXPECT_FLOAT_EQ(r.ToFloat(), INFINITY) << "Difference -INFINITY INFINITY";
}
}
// r = Angle::Difference(-INFINITY, INFINITY);
// EXPECT_FLOAT_EQ(r.InDegrees(), INFINITY) << "Difference -INFINITY
// INFINITY";
// }
// }
TEST(Angle, MoveTowards) {
Angle r = 0;
Angle r = Angle();
r = Angle::MoveTowards(0, 90, 30);
EXPECT_FLOAT_EQ(r.ToFloat(), 30) << "MoveTowards 0 90 30";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90),
Angle::Degrees(30));
EXPECT_FLOAT_EQ(r.InDegrees(), 30) << "MoveTowards 0 90 30";
r = Angle::MoveTowards(0, 90, 90);
EXPECT_FLOAT_EQ(r.ToFloat(), 90) << "MoveTowards 0 90 90";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90),
Angle::Degrees(90));
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "MoveTowards 0 90 90";
r = Angle::MoveTowards(0, 90, 180);
EXPECT_FLOAT_EQ(r.ToFloat(), 90) << "MoveTowards 0 90 180";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90),
Angle::Degrees(180));
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "MoveTowards 0 90 180";
r = Angle::MoveTowards(0, 90, 270);
EXPECT_FLOAT_EQ(r.ToFloat(), 90) << "MoveTowards 0 90 270";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90),
Angle::Degrees(270));
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "MoveTowards 0 90 270";
r = Angle::MoveTowards(0, 90, -30);
EXPECT_FLOAT_EQ(r.ToFloat(), -30) << "MoveTowards 0 90 -30";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90),
Angle::Degrees(-30));
EXPECT_FLOAT_EQ(r.InDegrees(), -30) << "MoveTowards 0 90 -30";
r = Angle::MoveTowards(0, -90, -30);
EXPECT_FLOAT_EQ(r.ToFloat(), 30) << "MoveTowards 0 -90 -30";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(-90),
Angle::Degrees(-30));
EXPECT_FLOAT_EQ(r.InDegrees(), 30) << "MoveTowards 0 -90 -30";
r = Angle::MoveTowards(0, -90, -90);
EXPECT_FLOAT_EQ(r.ToFloat(), 90) << "MoveTowards 0 -90 -90";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(-90),
Angle::Degrees(-90));
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "MoveTowards 0 -90 -90";
r = Angle::MoveTowards(0, -90, -180);
EXPECT_FLOAT_EQ(r.ToFloat(), 180) << "MoveTowards 0 -90 -180";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(-90),
Angle::Degrees(-180));
EXPECT_FLOAT_EQ(r.InDegrees(), 180) << "MoveTowards 0 -90 -180";
r = Angle::MoveTowards(0, -90, -270);
EXPECT_FLOAT_EQ(r.ToFloat(), 270) << "MoveTowards 0 -90 -270";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(-90),
Angle::Degrees(-270));
EXPECT_FLOAT_EQ(r.InDegrees(), 270) << "MoveTowards 0 -90 -270";
r = Angle::MoveTowards(0, 90, 0);
EXPECT_FLOAT_EQ(r.ToFloat(), 0) << "MoveTowards 0 90 0";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90),
Angle::Degrees(0));
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "MoveTowards 0 90 0";
r = Angle::MoveTowards(0, 0, 0);
EXPECT_FLOAT_EQ(r.ToFloat(), 0) << "MoveTowards 0 0 0";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(0),
Angle::Degrees(0));
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "MoveTowards 0 0 0";
r = Angle::MoveTowards(0, 0, 30);
EXPECT_FLOAT_EQ(r.ToFloat(), 0) << "MoveTowards 0 0 30";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(0),
Angle::Degrees(30));
EXPECT_FLOAT_EQ(r.InDegrees(), 0) << "MoveTowards 0 0 30";
if (std::numeric_limits<float>::is_iec559) {
r = Angle::MoveTowards(0, 90, FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r.ToFloat(), 90) << "MoveTowards 0 90 FLOAT_INFINITY";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(90),
Angle::Degrees(FLOAT_INFINITY));
EXPECT_FLOAT_EQ(r.InDegrees(), 90) << "MoveTowards 0 90 FLOAT_INFINITY";
r = Angle::MoveTowards(0, FLOAT_INFINITY, 30);
EXPECT_FLOAT_EQ(r.ToFloat(), 30) << "MoveTowards 0 FLOAT_INFINITY 30";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(FLOAT_INFINITY),
Angle::Degrees(30));
EXPECT_FLOAT_EQ(r.InDegrees(), 30) << "MoveTowards 0 FLOAT_INFINITY 30";
r = Angle::MoveTowards(0, -90, -FLOAT_INFINITY);
EXPECT_FLOAT_EQ(r.ToFloat(), FLOAT_INFINITY)
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(-90),
Angle::Degrees(-FLOAT_INFINITY));
EXPECT_FLOAT_EQ(r.InDegrees(), FLOAT_INFINITY)
<< "MoveTowards 0 -90 -FLOAT_INFINITY";
r = Angle::MoveTowards(0, -FLOAT_INFINITY, -30);
EXPECT_FLOAT_EQ(r.ToFloat(), 30) << "MoveTowards 0 -FLOAT_INFINITY -30";
r = Angle::MoveTowards(Angle::Degrees(0), Angle::Degrees(-FLOAT_INFINITY),
Angle::Degrees(-30));
EXPECT_FLOAT_EQ(r.InDegrees(), 30) << "MoveTowards 0 -FLOAT_INFINITY -30";
}
}

View File

@ -4,76 +4,77 @@
#include <math.h>
#include <limits>
#include "Angle16.h"
#include "Angle8.h"
#include "Angle.h"
// #include "Angle16.h"
// #include "Angle8.h"
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
TEST(Angle8, Construct) {
float angle = 0.0F;
Angle8 a = Angle8(angle);
EXPECT_FLOAT_EQ(a.ToFloat(), angle);
Angle8 a = Angle8::Degrees(angle);
EXPECT_FLOAT_EQ(a.InDegrees(), angle);
angle = -180.0F;
a = Angle8(angle);
EXPECT_FLOAT_EQ(a.ToFloat(), angle);
a = Angle8::Degrees(angle);
EXPECT_FLOAT_EQ(a.InDegrees(), angle);
}
TEST(Angle8, Negate) {
float angle = 0;
Angle8 a = Angle8(angle);
Angle8 a = Angle8::Degrees(angle);
a = -a;
EXPECT_FLOAT_EQ(a.ToFloat(), angle);
EXPECT_FLOAT_EQ(a.InDegrees(), angle);
angle = 90.0F;
a = Angle8(angle);
a = Angle8::Degrees(angle);
a = -a;
EXPECT_FLOAT_EQ(a.ToFloat(), -angle);
EXPECT_FLOAT_EQ(a.InDegrees(), -angle);
}
TEST(Angle8, Add) {
Angle8 a = Angle8(-45);
Angle8 b = Angle8(45.0F);
Angle8 a = Angle8::Degrees(-45);
Angle8 b = Angle8::Degrees(45.0F);
Angle8 r = a + b;
EXPECT_FLOAT_EQ(r.ToFloat(), 0);
EXPECT_FLOAT_EQ(r.InDegrees(), 0);
}
TEST(Angle8, Subtract) {
Angle8 a = Angle8(0);
Angle8 b = Angle8(45.0F);
Angle8 a = Angle8::Degrees(0);
Angle8 b = Angle8::Degrees(45.0F);
Angle8 r = a - b;
EXPECT_FLOAT_EQ(r.ToFloat(), -45);
EXPECT_FLOAT_EQ(r.InDegrees(), -45);
}
TEST(Angle16, Construct) {
Angle16 a = Angle16(0.0F);
EXPECT_FLOAT_EQ(a.ToFloat(), 0);
Angle16 a = Angle16::Degrees(0.0F);
EXPECT_FLOAT_EQ(a.InDegrees(), 0);
}
TEST(Angle16, Negate) {
float angle = 0;
Angle16 a = Angle16(angle);
Angle16 a = Angle16::Degrees(angle);
a = -a;
EXPECT_FLOAT_EQ(a.ToFloat(), angle);
EXPECT_FLOAT_EQ(a.InDegrees(), angle);
angle = 90.0F;
a = Angle16(angle);
a = Angle16::Degrees(angle);
a = -a;
EXPECT_FLOAT_EQ(a.ToFloat(), -angle);
EXPECT_FLOAT_EQ(a.InDegrees(), -angle);
}
TEST(Angle16, Subtract) {
Angle16 a = Angle16(0);
Angle16 b = Angle16(45.0F);
Angle16 a = Angle16::Degrees(0);
Angle16 b = Angle16::Degrees(45.0F);
Angle16 r = a - b;
EXPECT_FLOAT_EQ(r.ToFloat(), -45);
EXPECT_FLOAT_EQ(r.InDegrees(), -45);
}
TEST(Angle16, Add) {
Angle16 a = Angle16(-45);
Angle16 b = Angle16(45.0F);
Angle16 a = Angle16::Degrees(-45);
Angle16 b = Angle16::Degrees(45.0F);
Angle16 r = a + b;
EXPECT_FLOAT_EQ(r.ToFloat(), 0);
EXPECT_FLOAT_EQ(r.InDegrees(), 0);
}
#endif

View File

@ -13,90 +13,92 @@ TEST(Polar, FromVector2) {
Polar p = Polar::FromVector2(v);
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance 0 1";
EXPECT_FLOAT_EQ(p.angle.ToFloat(), 0.0F) << "s.angle 0 0 1";
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 0.0F) << "s.angle 0 0 1";
v = Vector2(1, 0);
p = Polar::FromVector2(v);
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance 1 0";
EXPECT_FLOAT_EQ(p.angle.ToFloat(), 90.0F) << "s.angle 1 0";
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 90.0F) << "s.angle 1 0";
v = Vector2(-1, 1);
p = Polar::FromVector2(v);
EXPECT_FLOAT_EQ(p.distance, sqrt(2.0F)) << "p.distance -1 1";
EXPECT_NEAR(p.angle.ToFloat(), -45.0F, 1.0e-05) << "s.angle -1 1";
EXPECT_NEAR(p.angle.InDegrees(), -45.0F, 1.0e-05) << "s.angle -1 1";
}
TEST(Polar, FromSpherical) {
Spherical s;
Polar p;
s = Spherical(1, 0, 0);
s = Spherical(1, Angle::Degrees(0), Angle::Degrees(0));
p = Polar::FromSpherical(s);
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance FromSpherical(1 0 0)";
EXPECT_FLOAT_EQ(p.angle.ToFloat(), 0.0F) << "p.angle FromSpherical(1 0 0)";
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 0.0F) << "p.angle FromSpherical(1 0 0)";
s = Spherical(1, 45, 0);
s = Spherical(1, Angle::Degrees(45), Angle::Degrees(0));
p = Polar::FromSpherical(s);
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance FromSpherical(1 45 0)";
EXPECT_FLOAT_EQ(p.angle.ToFloat(), 45.0F) << "p.angle FromSpherical(1 45 0)";
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 45.0F)
<< "p.angle FromSpherical(1 45 0)";
s = Spherical(1, -45, 0);
s = Spherical(1, Angle::Degrees(-45), Angle::Degrees(0));
p = Polar::FromSpherical(s);
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance FromSpherical(1 -45 0)";
EXPECT_FLOAT_EQ(p.angle.ToFloat(), -45.0F)
EXPECT_FLOAT_EQ(p.angle.InDegrees(), -45.0F)
<< "p.angle FromSpherical(1 -45 0)";
s = Spherical(0, 0, 0);
s = Spherical(0, Angle::Degrees(0), Angle::Degrees(0));
p = Polar::FromSpherical(s);
EXPECT_FLOAT_EQ(p.distance, 0.0F) << "p.distance FromSpherical(0 0 0)";
EXPECT_FLOAT_EQ(p.angle.ToFloat(), 0.0F) << "p.angle FromSpherical(0 0 0)";
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 0.0F) << "p.angle FromSpherical(0 0 0)";
s = Spherical(-1, 0, 0);
s = Spherical(-1, Angle::Degrees(0), Angle::Degrees(0));
p = Polar::FromSpherical(s);
EXPECT_FLOAT_EQ(p.distance, 1.0F) << "p.distance FromSpherical(-1 0 0)";
EXPECT_FLOAT_EQ(p.angle.ToFloat(), 180.0F) << "p.angle FromSpherical(-1 0 0)";
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 180.0F)
<< "p.angle FromSpherical(-1 0 0)";
s = Spherical(0, 0, 90);
s = Spherical(0, Angle::Degrees(0), Angle::Degrees(90));
p = Polar::FromSpherical(s);
EXPECT_FLOAT_EQ(p.distance, 0.0F) << "p.distance FromSpherical(0 0 90)";
EXPECT_FLOAT_EQ(p.angle.ToFloat(), 0.0F) << "p.angle FromSpherical(0 0 90)";
EXPECT_FLOAT_EQ(p.angle.InDegrees(), 0.0F) << "p.angle FromSpherical(0 0 90)";
}
TEST(Polar, Negation) {
Polar v = Polar(2, 45);
Polar v = Polar(2, Angle::Degrees(45));
Polar r = Polar::zero;
r = -v;
EXPECT_FLOAT_EQ(r.distance, 2);
EXPECT_FLOAT_EQ(r.angle.ToFloat(), -135);
EXPECT_TRUE(r == Polar(2, -135)) << "Negate(2 45)";
EXPECT_FLOAT_EQ(r.angle.InDegrees(), -135);
EXPECT_TRUE(r == Polar(2, Angle::Degrees(-135))) << "Negate(2 45)";
v = Polar(2, -45);
v = Polar(2, Angle::Degrees(-45));
r = -v;
EXPECT_TRUE(r == Polar(2, 135)) << "Negate(2 -45)";
EXPECT_TRUE(r == Polar(2, Angle::Degrees(135))) << "Negate(2 -45)";
v = Polar(2, 0);
v = Polar(2, Angle::Degrees(0));
r = -v;
EXPECT_TRUE(r == Polar(2, 180)) << "Negate(2 0)";
EXPECT_TRUE(r == Polar(2, Angle::Degrees(180))) << "Negate(2 0)";
v = Polar(0, 0);
v = Polar(0, Angle::Degrees(0));
r = -v;
EXPECT_FLOAT_EQ(r.distance, 0.0f);
EXPECT_FLOAT_EQ(r.angle.ToFloat(), 0.0f);
EXPECT_TRUE(r == Polar(0, 0)) << "Negate(0 0)";
EXPECT_FLOAT_EQ(r.angle.InDegrees(), 0.0f);
EXPECT_TRUE(r == Polar(0, Angle::Degrees(0))) << "Negate(0 0)";
}
TEST(Polar, Subtraction) {
Polar v1 = Polar(4, 45);
Polar v2 = Polar(1, -90);
Polar v1 = Polar(4, Angle::Degrees(45));
Polar v2 = Polar(1, Angle::Degrees(-90));
Polar r = Polar::zero;
r = v1 - v2;
@ -108,8 +110,8 @@ TEST(Polar, Subtraction) {
}
TEST(Polar, Addition) {
Polar v1 = Polar(1, 45);
Polar v2 = Polar(1, -90);
Polar v1 = Polar(1, Angle::Degrees(45));
Polar v2 = Polar(1, Angle::Degrees(-90));
Polar r = Polar::zero;
r = v1 - v2;
@ -123,34 +125,35 @@ TEST(Polar, Addition) {
r += v2;
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0)";
v2 = Polar(1, -45);
v2 = Polar(1, Angle::Degrees(-45));
r = v1 + v2;
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(0 0 0)";
EXPECT_FLOAT_EQ(r.angle.ToFloat(), 0) << "Addition(0 0 0)";
EXPECT_FLOAT_EQ(r.angle.InDegrees(), 0) << "Addition(0 0 0)";
}
TEST(Polar, Scale_Multiply) {
Polar v1 = Polar(4, 45);
Polar v1 = Polar(4, Angle::Degrees(45));
Polar r = Polar::zero;
r = v1 * 2.0f;
EXPECT_FLOAT_EQ(r.distance, v1.distance * 2) << "ScaleMult(4 45, 2)";
EXPECT_FLOAT_EQ(r.angle.ToFloat(), v1.angle.ToFloat())
EXPECT_FLOAT_EQ(r.angle.InDegrees(), v1.angle.InDegrees())
<< "ScaleMult(4 45, 2)";
}
TEST(Polar, Scale_Divide) {
Polar v1 = Polar(4, 45);
Polar v1 = Polar(4, Angle::Degrees(45));
Polar r = Polar::zero;
r = v1 / 2.0f;
EXPECT_FLOAT_EQ(r.distance, v1.distance / 2) << "ScaleDiv(4 45, 2)";
EXPECT_FLOAT_EQ(r.angle.ToFloat(), v1.angle.ToFloat()) << "ScaleDiv(4 45, 2)";
EXPECT_FLOAT_EQ(r.angle.InDegrees(), v1.angle.InDegrees())
<< "ScaleDiv(4 45, 2)";
}
TEST(Polar, Distance) {
Polar v1 = Polar(4, 45);
Polar v2 = Polar(1, -90);
Polar v1 = Polar(4, Angle::Degrees(45));
Polar v2 = Polar(1, Angle::Degrees(-90));
float d = 0;
d = Polar::Distance(v1, v2);
@ -162,12 +165,12 @@ TEST(Polar, Distance) {
}
TEST(Polar, Rotate) {
Polar v = Polar(4, 45);
Polar v = Polar(4, Angle::Degrees(45));
Polar r = Polar::zero;
r = Polar::Rotate(v, 45);
r = Polar::Rotate(v, Angle::Degrees(45));
EXPECT_FLOAT_EQ(r.distance, v.distance) << "Rotate(4 45, 45)";
EXPECT_FLOAT_EQ(r.angle.ToFloat(), 90.0f) << "Rotate(4 45, 45)";
EXPECT_FLOAT_EQ(r.angle.InDegrees(), 90.0f) << "Rotate(4 45, 45)";
}
#endif

View File

@ -13,22 +13,22 @@ TEST(Spherical16, FromVector3) {
Spherical16 s = Spherical16::FromVector3(v);
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 0 0 1";
EXPECT_FLOAT_EQ((float)s.horizontal.ToFloat(), 0.0F) << "s.hor 0 0 1";
EXPECT_FLOAT_EQ((float)s.vertical.ToFloat(), 0.0F) << "s.vert 0 0 1";
EXPECT_FLOAT_EQ((float)s.horizontal.InDegrees(), 0.0F) << "s.hor 0 0 1";
EXPECT_FLOAT_EQ((float)s.vertical.InDegrees(), 0.0F) << "s.vert 0 0 1";
v = Vector3(0, 1, 0);
s = Spherical16::FromVector3(v);
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 0 1 0";
EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), 0.0F) << "s.hor 0 1 0";
EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 90.0F) << "s.vert 0 1 0";
EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor 0 1 0";
EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 90.0F) << "s.vert 0 1 0";
v = Vector3(1, 0, 0);
s = Spherical16::FromVector3(v);
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 1 0 0";
EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), 90.0F) << "s.hor 1 0 0";
EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert 1 0 0";
EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 90.0F) << "s.hor 1 0 0";
EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert 1 0 0";
}
// TEST(Spherical16, FromPolar) {
@ -36,46 +36,47 @@ TEST(Spherical16, FromVector3) {
// Spherical16 s = Spherical16::FromPolar(p);
// EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 0)";
// EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), 0.0F) << "s.hor Polar(1 0)";
// EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert Polar(1 0)";
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor Polar(1 0)";
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 0)";
// p = Polar(1, 45);
// s = Spherical16::FromPolar(p);
// EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 45)";
// EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), 45.0F) << "s.hor Polar(1 45)";
// EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert Polar(1 45)";
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 45.0F) << "s.hor Polar(1 45)";
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 45)";
// p = Polar(1, -45);
// s = Spherical16::FromPolar(p);
// EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 -45)";
// EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), -45.0F) << "s.hor Polar(1 -45)";
// EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert Polar(1 -45)";
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), -45.0F) << "s.hor Polar(1 -45)";
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 -45)";
// p = Polar(0, 0);
// s = Spherical16::FromPolar(p);
// EXPECT_FLOAT_EQ(s.distance, 0.0F) << "s.distance Polar(0 0)";
// EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), 0.0F) << "s.hor Polar(0 0)";
// EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert Polar(0 0)";
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor Polar(0 0)";
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(0 0)";
// p = Polar(-1, 0);
// s = Spherical16::FromPolar(p);
// EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(-1 0)";
// EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), -180.0F) << "s.hor Polar(-1 0)";
// EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert Polar(-1 0)";
// EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), -180.0F) << "s.hor Polar(-1 0)";
// EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(-1 0)";
// }
TEST(Spherical16, Incident1) {
Vector3 v = Vector3(2.242557f, 1.027884f, -0.322347f);
Spherical16 s = Spherical16::FromVector3(v);
Spherical16 sr = Spherical16(2.49F, 98.18f, 24.4F);
Spherical16 sr =
Spherical16(2.49F, Angle16::Degrees(98.18f), Angle16::Degrees(24.4F));
EXPECT_NEAR(s.distance, sr.distance, 1.0e-01);
EXPECT_NEAR(s.horizontal.ToFloat(), sr.horizontal.ToFloat(), 1.0e-02);
EXPECT_NEAR(s.vertical.ToFloat(), sr.vertical.ToFloat(), 1.0e-02);
EXPECT_NEAR(s.horizontal.InDegrees(), sr.horizontal.InDegrees(), 1.0e-02);
EXPECT_NEAR(s.vertical.InDegrees(), sr.vertical.InDegrees(), 1.0e-02);
Vector3 r = Spherical16(sr.distance, sr.horizontal, sr.vertical).ToVector3();
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-02) << "toVector3.x 1 0 0";
@ -87,10 +88,11 @@ TEST(Spherical16, Incident2) {
Vector3 v = Vector3(1.0f, 0.0f, 1.0f);
Spherical16 s = Spherical16::FromVector3(v);
Spherical16 sr = Spherical16(1.4142135623F, 45.0f, 0.0F);
Spherical16 sr = Spherical16(1.4142135623F, Angle16::Degrees(45.0f),
Angle16::Degrees(0.0F));
EXPECT_NEAR(s.distance, sr.distance, 1.0e-05);
EXPECT_NEAR(s.horizontal.ToFloat(), sr.horizontal.ToFloat(), 1.0e-05);
EXPECT_NEAR(s.vertical.ToFloat(), sr.vertical.ToFloat(), 1.0e-05);
EXPECT_NEAR(s.horizontal.InDegrees(), sr.horizontal.InDegrees(), 1.0e-05);
EXPECT_NEAR(s.vertical.InDegrees(), sr.vertical.InDegrees(), 1.0e-05);
Vector3 r = Spherical16(sr.distance, sr.horizontal, sr.vertical).ToVector3();
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-06);
@ -100,10 +102,10 @@ TEST(Spherical16, Incident2) {
v = Vector3(0.0f, 1.0f, 1.0f);
s = Spherical16::FromVector3(v);
sr = Spherical16(1.4142135623F, 0.0f, 45.0F);
sr = Spherical16(1.4142135623F, Angle16::Degrees(0), Angle16::Degrees(45));
EXPECT_NEAR(s.distance, sr.distance, 1.0e-05);
EXPECT_NEAR(s.horizontal.ToFloat(), sr.horizontal.ToFloat(), 1.0e-05);
EXPECT_NEAR(s.vertical.ToFloat(), sr.vertical.ToFloat(), 1.0e-05);
EXPECT_NEAR(s.horizontal.InDegrees(), sr.horizontal.InDegrees(), 1.0e-05);
EXPECT_NEAR(s.vertical.InDegrees(), sr.vertical.InDegrees(), 1.0e-05);
r = Spherical16(sr.distance, sr.horizontal, sr.vertical).ToVector3();
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-06);
@ -115,8 +117,8 @@ TEST(Spherical16, Incident2) {
r = Spherical16(s.distance, s.horizontal, s.vertical).ToVector3();
EXPECT_NEAR(s.distance, 1.73205080F, 1.0e-02);
EXPECT_NEAR(s.horizontal.ToFloat(), 45.0F, 1.0e-02);
EXPECT_NEAR(s.vertical.ToFloat(), 35.26F, 1.0e-02);
EXPECT_NEAR(s.horizontal.InDegrees(), 45.0F, 1.0e-02);
EXPECT_NEAR(s.vertical.InDegrees(), 35.26F, 1.0e-02);
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-04);
EXPECT_NEAR(r.Up(), v.Up(), 1.0e-04);
@ -130,7 +132,7 @@ TEST(Spherical16, Incident2) {
}
TEST(Spherical16, Addition) {
Spherical16 v1 = Spherical16(1, 45, 0);
Spherical16 v1 = Spherical16(1, Angle16::Degrees(45), Angle16::Degrees(0));
Spherical16 v2 = Spherical16::zero;
Spherical16 r = Spherical16::zero;
@ -141,17 +143,17 @@ TEST(Spherical16, Addition) {
r += v2;
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0 0)";
v2 = Spherical16(1, -45, 0);
v2 = Spherical16(1, Angle16::Degrees(-45), Angle16::Degrees(0));
r = v1 + v2;
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(1 -45 0)";
EXPECT_FLOAT_EQ(r.horizontal.ToFloat(), 0) << "Addition(1 -45 0)";
EXPECT_FLOAT_EQ(r.vertical.ToFloat(), 0) << "Addition(1 -45 0)";
EXPECT_FLOAT_EQ(r.horizontal.InDegrees(), 0) << "Addition(1 -45 0)";
EXPECT_FLOAT_EQ(r.vertical.InDegrees(), 0) << "Addition(1 -45 0)";
v2 = Spherical16(1, 0, 90);
v2 = Spherical16(1, Angle16::Degrees(0), Angle16::Degrees(90));
r = v1 + v2;
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(1 0 90)";
EXPECT_FLOAT_EQ(r.horizontal.ToFloat(), 45) << "Addition(1 0 90)";
EXPECT_FLOAT_EQ(r.vertical.ToFloat(), 45) << "Addition(1 0 90)";
EXPECT_FLOAT_EQ(r.horizontal.InDegrees(), 45) << "Addition(1 0 90)";
EXPECT_FLOAT_EQ(r.vertical.InDegrees(), 45) << "Addition(1 0 90)";
}
#endif

View File

@ -12,69 +12,70 @@ TEST(Spherical, FromVector3) {
Spherical s = Spherical::FromVector3(v);
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 0 0 1";
EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), 0.0F) << "s.hor 0 0 1";
EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert 0 0 1";
EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor 0 0 1";
EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert 0 0 1";
v = Vector3(0, 1, 0);
s = Spherical::FromVector3(v);
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 0 1 0";
EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), 0.0F) << "s.hor 0 1 0";
EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 90.0F) << "s.vert 0 1 0";
EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor 0 1 0";
EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 90.0F) << "s.vert 0 1 0";
v = Vector3(1, 0, 0);
s = Spherical::FromVector3(v);
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance 1 0 0";
EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), 90.0F) << "s.hor 1 0 0";
EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert 1 0 0";
EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 90.0F) << "s.hor 1 0 0";
EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert 1 0 0";
}
TEST(Spherical, FromPolar) {
Polar p = Polar(1, 0);
Polar p = Polar(1, Angle::Degrees(0));
Spherical s = Spherical::FromPolar(p);
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 0)";
EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), 0.0F) << "s.hor Polar(1 0)";
EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert Polar(1 0)";
EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor Polar(1 0)";
EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 0)";
p = Polar(1, 45);
p = Polar(1, Angle::Degrees(45));
s = Spherical::FromPolar(p);
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 45)";
EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), 45.0F) << "s.hor Polar(1 45)";
EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert Polar(1 45)";
EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 45.0F) << "s.hor Polar(1 45)";
EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 45)";
p = Polar(1, -45);
p = Polar(1, Angle::Degrees(-45));
s = Spherical::FromPolar(p);
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(1 -45)";
EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), -45.0F) << "s.hor Polar(1 -45)";
EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert Polar(1 -45)";
EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), -45.0F) << "s.hor Polar(1 -45)";
EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(1 -45)";
p = Polar(0, 0);
p = Polar(0, Angle::Degrees(0));
s = Spherical::FromPolar(p);
EXPECT_FLOAT_EQ(s.distance, 0.0F) << "s.distance Polar(0 0)";
EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), 0.0F) << "s.hor Polar(0 0)";
EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert Polar(0 0)";
EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 0.0F) << "s.hor Polar(0 0)";
EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(0 0)";
p = Polar(-1, 0);
p = Polar(-1, Angle::Degrees(0));
s = Spherical::FromPolar(p);
EXPECT_FLOAT_EQ(s.distance, 1.0F) << "s.distance Polar(-1 0)";
EXPECT_FLOAT_EQ(s.horizontal.ToFloat(), 180.0F) << "s.hor Polar(-1 0)";
EXPECT_FLOAT_EQ(s.vertical.ToFloat(), 0.0F) << "s.vert Polar(-1 0)";
EXPECT_FLOAT_EQ(s.horizontal.InDegrees(), 180.0F) << "s.hor Polar(-1 0)";
EXPECT_FLOAT_EQ(s.vertical.InDegrees(), 0.0F) << "s.vert Polar(-1 0)";
}
TEST(Spherical, Incident1) {
Vector3 v = Vector3(2.242557f, 1.027884f, -0.322347f);
Spherical s = Spherical::FromVector3(v);
Spherical sr = Spherical(2.49F, 98.18f, 24.4F);
Spherical sr =
Spherical(2.49F, Angle::Degrees(98.18f), Angle::Degrees(24.4F));
EXPECT_NEAR(s.distance, sr.distance, 1.0e-01);
EXPECT_NEAR(s.horizontal.ToFloat(), sr.horizontal.ToFloat(), 1.0e-02);
EXPECT_NEAR(s.vertical.ToFloat(), sr.vertical.ToFloat(), 1.0e-02);
EXPECT_NEAR(s.horizontal.InDegrees(), sr.horizontal.InDegrees(), 1.0e-02);
EXPECT_NEAR(s.vertical.InDegrees(), sr.vertical.InDegrees(), 1.0e-02);
Vector3 r = Vector3(sr);
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-02) << "toVector3.x 1 0 0";
@ -86,10 +87,11 @@ TEST(Spherical, Incident2) {
Vector3 v = Vector3(1.0f, 0.0f, 1.0f);
Spherical s = Spherical::FromVector3(v);
Spherical sr = Spherical(1.4142135623F, 45.0f, 0.0F);
Spherical sr =
Spherical(1.4142135623F, Angle::Degrees(45.0f), Angle::Degrees(0.0F));
EXPECT_NEAR(s.distance, sr.distance, 1.0e-05);
EXPECT_NEAR(s.horizontal.ToFloat(), sr.horizontal.ToFloat(), 1.0e-05);
EXPECT_NEAR(s.vertical.ToFloat(), sr.vertical.ToFloat(), 1.0e-05);
EXPECT_NEAR(s.horizontal.InDegrees(), sr.horizontal.InDegrees(), 1.0e-05);
EXPECT_NEAR(s.vertical.InDegrees(), sr.vertical.InDegrees(), 1.0e-05);
Vector3 r = Vector3(sr);
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-06);
@ -99,10 +101,10 @@ TEST(Spherical, Incident2) {
v = Vector3(0.0f, 1.0f, 1.0f);
s = Spherical::FromVector3(v);
sr = Spherical(1.4142135623F, 0.0f, 45.0F);
sr = Spherical(1.4142135623F, Angle::Degrees(0.0f), Angle::Degrees(45.0F));
EXPECT_NEAR(s.distance, sr.distance, 1.0e-05);
EXPECT_NEAR(s.horizontal.ToFloat(), sr.horizontal.ToFloat(), 1.0e-05);
EXPECT_NEAR(s.vertical.ToFloat(), sr.vertical.ToFloat(), 1.0e-05);
EXPECT_NEAR(s.horizontal.InDegrees(), sr.horizontal.InDegrees(), 1.0e-05);
EXPECT_NEAR(s.vertical.InDegrees(), sr.vertical.InDegrees(), 1.0e-05);
r = Vector3(sr);
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-06);
@ -114,8 +116,8 @@ TEST(Spherical, Incident2) {
r = Vector3(s);
EXPECT_NEAR(s.distance, 1.73205080F, 1.0e-02);
EXPECT_NEAR(s.horizontal.ToFloat(), 45.0F, 1.0e-02);
EXPECT_NEAR(s.vertical.ToFloat(), 35.26F, 1.0e-02);
EXPECT_NEAR(s.horizontal.InDegrees(), 45.0F, 1.0e-02);
EXPECT_NEAR(s.vertical.InDegrees(), 35.26F, 1.0e-02);
EXPECT_NEAR(r.Right(), v.Right(), 1.0e-06);
EXPECT_NEAR(r.Up(), v.Up(), 1.0e-06);
@ -129,7 +131,7 @@ TEST(Spherical, Incident2) {
}
TEST(Spherical, Addition) {
Spherical v1 = Spherical(1, 45, 0);
Spherical v1 = Spherical(1, Angle::Degrees(45), Angle::Degrees(0));
Spherical v2 = Spherical::zero;
Spherical r = Spherical::zero;
@ -140,17 +142,17 @@ TEST(Spherical, Addition) {
r += v2;
EXPECT_FLOAT_EQ(r.distance, v1.distance) << "Addition(0 0 0)";
v2 = Spherical(1, -45, 0);
v2 = Spherical(1, Angle::Degrees(-45), Angle::Degrees(0));
r = v1 + v2;
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(1 -45 0)";
EXPECT_FLOAT_EQ(r.horizontal.ToFloat(), 0) << "Addition(1 -45 0)";
EXPECT_FLOAT_EQ(r.vertical.ToFloat(), 0) << "Addition(1 -45 0)";
EXPECT_FLOAT_EQ(r.horizontal.InDegrees(), 0) << "Addition(1 -45 0)";
EXPECT_FLOAT_EQ(r.vertical.InDegrees(), 0) << "Addition(1 -45 0)";
v2 = Spherical(1, 0, 90);
v2 = Spherical(1, Angle::Degrees(0), Angle::Degrees(90));
r = v1 + v2;
EXPECT_FLOAT_EQ(r.distance, sqrtf(2)) << "Addition(1 0 90)";
EXPECT_FLOAT_EQ(r.horizontal.ToFloat(), 45) << "Addition(1 0 90)";
EXPECT_FLOAT_EQ(r.vertical.ToFloat(), 45) << "Addition(1 0 90)";
EXPECT_FLOAT_EQ(r.horizontal.InDegrees(), 45) << "Addition(1 0 90)";
EXPECT_FLOAT_EQ(r.vertical.InDegrees(), 45) << "Addition(1 0 90)";
}
#endif

View File

@ -462,16 +462,16 @@ TEST(Vector2, Rotate) {
Vector2 v1 = Vector2(1, 2);
Vector2 r = Vector2(0, 0);
r = Vector2::Rotate(v1, 0);
r = Vector2::Rotate(v1, Angle::Degrees(0));
EXPECT_FLOAT_EQ(Vector2::Distance(r, v1), 0);
r = Vector2::Rotate(v1, 180);
r = Vector2::Rotate(v1, Angle::Degrees(180));
EXPECT_NEAR(Vector2::Distance(r, Vector2(-1, -2)), 0, 1.0e-06);
r = Vector2::Rotate(v1, -90);
r = Vector2::Rotate(v1, Angle::Degrees(-90));
EXPECT_NEAR(Vector2::Distance(r, Vector2(2, -1)), 0, 1.0e-06);
r = Vector2::Rotate(v1, 270);
r = Vector2::Rotate(v1, Angle::Degrees(270));
EXPECT_NEAR(Vector2::Distance(r, Vector2(2, -1)), 0, 1.0e-06);
}

View File

@ -488,29 +488,29 @@ TEST(Vector3, ProjectOnPlane) {
TEST(Vector3, Angle) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
AngleOf<float> f = 0;
AngleOf<float> f = AngleOf<float>::Degrees(0);
bool r = false;
f = Vector3::Angle(v1, v2);
EXPECT_FLOAT_EQ(f.ToFloat(), 12.9331388F) << "Angle(4 5 6, 1 2 3)";
EXPECT_FLOAT_EQ(f.InDegrees(), 12.9331388F) << "Angle(4 5 6, 1 2 3)";
v2 = Vector3(-1, -2, -3);
f = Vector3::Angle(v1, v2);
EXPECT_FLOAT_EQ(f.ToFloat(), 167.066864F) << "Angle(4 5 6, -1 -2 -3)";
EXPECT_FLOAT_EQ(f.InDegrees(), 167.066864F) << "Angle(4 5 6, -1 -2 -3)";
v2 = Vector3(0, 0, 0);
f = Vector3::Angle(v1, v2);
EXPECT_FLOAT_EQ(f.ToFloat(), 0) << "Angle(4 5 6, 0 0 0)";
EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "Angle(4 5 6, 0 0 0)";
if (std::numeric_limits<float>::is_iec559) {
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
f = Vector3::Angle(v1, v2);
r = isnan(f.ToFloat());
r = isnan(f.InDegrees());
EXPECT_TRUE(r) << "Angle(4 5 6, INFINITY INFINITY INFINITY)";
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
f = Vector3::Angle(v1, v2);
r = isnan(f.ToFloat());
r = isnan(f.InDegrees());
EXPECT_TRUE(r) << "Angle(4 5 6, -INFINITY -INFINITY -INFINITY)";
}
}
@ -519,42 +519,42 @@ TEST(Vector3, SignedAngle) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
Vector3 v3 = Vector3(7, 8, -9);
AngleOf<float> f = 0;
AngleOf<float> f = AngleOf<float>::Degrees(0);
bool r = false;
f = Vector3::SignedAngle(v1, v2, v3);
EXPECT_FLOAT_EQ(f.ToFloat(), -12.9331388F)
EXPECT_FLOAT_EQ(f.InDegrees(), -12.9331388F)
<< "SignedAngle(4 5 6, 1 2 3, 7 8 -9)";
v2 = Vector3(-1, -2, -3);
f = Vector3::SignedAngle(v1, v2, v3);
EXPECT_FLOAT_EQ(f.ToFloat(), 167.066864F)
EXPECT_FLOAT_EQ(f.InDegrees(), 167.066864F)
<< "SignedAngle(4 5 6, -1 -2 -3, 7 8 -9)";
v2 = Vector3(0, 0, 0);
f = Vector3::SignedAngle(v1, v2, v3);
EXPECT_FLOAT_EQ(f.ToFloat(), 0) << "SignedAngle(4 5 6, 0 0 0, 7 8 -9 )";
EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "SignedAngle(4 5 6, 0 0 0, 7 8 -9 )";
v2 = Vector3(1, 2, 3);
v3 = Vector3(-7, -8, 9);
f = Vector3::SignedAngle(v1, v2, v3);
EXPECT_FLOAT_EQ(f.ToFloat(), 12.9331388F)
EXPECT_FLOAT_EQ(f.InDegrees(), 12.9331388F)
<< "SignedAngle(4 5 6, 1 2 3, -7 -8 9)";
v3 = Vector3(0, 0, 0);
f = Vector3::SignedAngle(v1, v2, v3);
EXPECT_FLOAT_EQ(f.ToFloat(), 0) << "SignedAngle(4 5 6, 1 2 3, 0 0 0)";
EXPECT_FLOAT_EQ(f.InDegrees(), 0) << "SignedAngle(4 5 6, 1 2 3, 0 0 0)";
if (std::numeric_limits<float>::is_iec559) {
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
f = Vector3::SignedAngle(v1, v2, v3);
r = isnan(f.ToFloat());
r = isnan(f.InDegrees());
EXPECT_TRUE(r) << "SignedAngle(4 5 6, INFINITY INFINITY INFINITY)";
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
f = Vector3::SignedAngle(v1, v2, v3);
r = isnan(f.ToFloat());
r = isnan(f.InDegrees());
EXPECT_TRUE(r) << "SignedAngle(4 5 6, -INFINITY -INFINITY -INFINITY)";
}
}