Change Vector3::Angle return type to AngleOf<float>
This commit is contained in:
parent
18cf653aff
commit
c72bba4f7a
@ -3,9 +3,10 @@
|
|||||||
// 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 "Quaternion.h"
|
#include "Quaternion.h"
|
||||||
#include "Vector3.h"
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include "Angle.h"
|
||||||
|
#include "Vector3.h"
|
||||||
|
|
||||||
void CopyQuat(const Quat& q1, Quat& q2) {
|
void CopyQuat(const Quat& q1, Quat& q2) {
|
||||||
q2.x = q1.x;
|
q2.x = q1.x;
|
||||||
@ -42,7 +43,9 @@ Quaternion::~Quaternion() {}
|
|||||||
|
|
||||||
const Quaternion Quaternion::identity = Quaternion(0, 0, 0, 1);
|
const Quaternion Quaternion::identity = Quaternion(0, 0, 0, 1);
|
||||||
|
|
||||||
Vector3 Quaternion::xyz() const { return Vector3(x, y, z); }
|
Vector3 Quaternion::xyz() const {
|
||||||
|
return Vector3(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
float Quaternion::GetLength() const {
|
float Quaternion::GetLength() const {
|
||||||
return sqrtf(x * x + y * y + z * z + w * w);
|
return sqrtf(x * x + y * y + z * z + w * w);
|
||||||
@ -202,8 +205,8 @@ Quaternion Quaternion::FromToRotation(Vector3 fromDirection,
|
|||||||
Vector3 toDirection) {
|
Vector3 toDirection) {
|
||||||
Vector3 axis = Vector3::Cross(fromDirection, toDirection);
|
Vector3 axis = Vector3::Cross(fromDirection, toDirection);
|
||||||
axis = Vector3::Normalize(axis);
|
axis = Vector3::Normalize(axis);
|
||||||
float angle = Vector3::SignedAngle(fromDirection, toDirection, axis);
|
AngleOf<float> angle = Vector3::SignedAngle(fromDirection, toDirection, axis);
|
||||||
Quaternion rotation = Quaternion::AngleAxis(angle, axis);
|
Quaternion rotation = Quaternion::AngleAxis(angle.ToFloat(), axis);
|
||||||
return rotation;
|
return rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +248,8 @@ void Quaternion::ToAngleAxis(float *angle, Vector3 *axis) {
|
|||||||
*angle *= Rad2Deg;
|
*angle *= Rad2Deg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quaternion::ToAxisAngleRad(const Quaternion &q, Vector3 *const axis,
|
void Quaternion::ToAxisAngleRad(const Quaternion& q,
|
||||||
|
Vector3* const axis,
|
||||||
float* angle) {
|
float* angle) {
|
||||||
Quaternion q1 = (fabs(q.w) > 1.0f) ? Quaternion::Normalize(q) : q;
|
Quaternion q1 = (fabs(q.w) > 1.0f) ? Quaternion::Normalize(q) : q;
|
||||||
*angle = 2.0f * acosf(q1.w); // angle
|
*angle = 2.0f * acosf(q1.w); // angle
|
||||||
@ -258,7 +262,8 @@ void Quaternion::ToAxisAngleRad(const Quaternion &q, Vector3 *const axis,
|
|||||||
*axis = Vector3(1, 0, 0);
|
*axis = Vector3(1, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Quaternion Quaternion::SlerpUnclamped(const Quaternion &a, const Quaternion &b,
|
Quaternion Quaternion::SlerpUnclamped(const Quaternion& a,
|
||||||
|
const Quaternion& b,
|
||||||
float t) {
|
float t) {
|
||||||
// if either input is zero, return the other.
|
// if either input is zero, return the other.
|
||||||
if (Quaternion::GetLengthSquared(a) == 0.0f) {
|
if (Quaternion::GetLengthSquared(a) == 0.0f) {
|
||||||
@ -309,7 +314,8 @@ Quaternion Quaternion::SlerpUnclamped(const Quaternion &a, const Quaternion &b,
|
|||||||
return Quaternion();
|
return Quaternion();
|
||||||
}
|
}
|
||||||
|
|
||||||
Quaternion Quaternion::Slerp(const Quaternion &a, const Quaternion &b,
|
Quaternion Quaternion::Slerp(const Quaternion& a,
|
||||||
|
const Quaternion& b,
|
||||||
float t) {
|
float t) {
|
||||||
if (t > 1)
|
if (t > 1)
|
||||||
t = 1;
|
t = 1;
|
||||||
@ -403,8 +409,10 @@ Quaternion Quaternion::GetRotationAround(Vector3 axis, Quaternion rotation) {
|
|||||||
return twist;
|
return twist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quaternion::GetSwingTwist(Vector3 axis, Quaternion rotation,
|
void Quaternion::GetSwingTwist(Vector3 axis,
|
||||||
Quaternion *swing, Quaternion *twist) {
|
Quaternion rotation,
|
||||||
|
Quaternion* swing,
|
||||||
|
Quaternion* twist) {
|
||||||
*twist = GetRotationAround(axis, rotation);
|
*twist = GetRotationAround(axis, rotation);
|
||||||
*swing = rotation * Quaternion::Inverse(*twist);
|
*swing = rotation * Quaternion::Inverse(*twist);
|
||||||
}
|
}
|
||||||
|
12
Vector3.cpp
12
Vector3.cpp
@ -188,7 +188,7 @@ float clamp(float x, float lower, float upper) {
|
|||||||
return upperClamp;
|
return upperClamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Vector3::Angle(const Vector3& v1, const Vector3& v2) {
|
AngleOf<float> Vector3::Angle(const Vector3& v1, const Vector3& v2) {
|
||||||
float denominator = sqrtf(v1.sqrMagnitude() * v2.sqrMagnitude());
|
float denominator = sqrtf(v1.sqrMagnitude() * v2.sqrMagnitude());
|
||||||
if (denominator < epsilon)
|
if (denominator < epsilon)
|
||||||
return 0;
|
return 0;
|
||||||
@ -200,23 +200,23 @@ float Vector3::Angle(const Vector3& v1, const Vector3& v2) {
|
|||||||
|
|
||||||
float cdot = clamp(fraction, -1.0, 1.0);
|
float cdot = clamp(fraction, -1.0, 1.0);
|
||||||
float r = ((float)acos(cdot)) * Rad2Deg;
|
float r = ((float)acos(cdot)) * Rad2Deg;
|
||||||
return r;
|
return AngleOf<float>(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
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]
|
||||||
float angle = Vector3::Angle(v1, v2);
|
AngleOf<float> angle = Vector3::Angle(v1, v2);
|
||||||
|
|
||||||
Vector3 cross = Vector3::Cross(v1, v2);
|
Vector3 cross = Vector3::Cross(v1, v2);
|
||||||
float b = Vector3::Dot(axis, cross);
|
float b = Vector3::Dot(axis, cross);
|
||||||
float signd = b < 0 ? -1.0F : (b > 0 ? 1.0F : 0.0F);
|
float signd = b < 0 ? -1.0F : (b > 0 ? 1.0F : 0.0F);
|
||||||
|
|
||||||
// angle in [-179,180]
|
// angle in [-179,180]
|
||||||
float signed_angle = angle * signd;
|
AngleOf<float> signed_angle = angle * signd;
|
||||||
|
|
||||||
return signed_angle;
|
return AngleOf<float>(signed_angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Vector3::Lerp(const Vector3& v1, const Vector3& v2, float f) {
|
Vector3 Vector3::Lerp(const Vector3& v1, const Vector3& v2, float f) {
|
||||||
|
@ -204,13 +204,13 @@ struct Vector3 : Vec3 {
|
|||||||
/// @remark This reterns an unsigned angle which is the shortest distance
|
/// @remark This reterns an unsigned angle which is the shortest distance
|
||||||
/// between the two vectors. Use Vector3::SignedAngle if a signed angle is
|
/// between the two vectors. Use Vector3::SignedAngle if a signed angle is
|
||||||
/// needed.
|
/// needed.
|
||||||
static float Angle(const Vector3& v1, const Vector3& v2);
|
static AngleOf<float> Angle(const Vector3& v1, const Vector3& v2);
|
||||||
/// @brief The signed angle between two vectors
|
/// @brief The signed angle between two vectors
|
||||||
/// @param v1 The starting vector
|
/// @param v1 The starting vector
|
||||||
/// @param v2 The ending vector
|
/// @param v2 The ending vector
|
||||||
/// @param axis The axis to rotate around
|
/// @param axis The axis to rotate around
|
||||||
/// @return The signed angle between the two vectors
|
/// @return The signed angle between the two vectors
|
||||||
static float SignedAngle(const Vector3& v1,
|
static AngleOf<float> SignedAngle(const Vector3& v1,
|
||||||
const Vector3& v2,
|
const Vector3& v2,
|
||||||
const Vector3& axis);
|
const Vector3& axis);
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#if GTEST
|
#if GTEST
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <limits>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include "Vector3.h"
|
#include "Vector3.h"
|
||||||
|
|
||||||
@ -488,29 +488,29 @@ TEST(Vector3, ProjectOnPlane) {
|
|||||||
TEST(Vector3, Angle) {
|
TEST(Vector3, Angle) {
|
||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
float f = 0;
|
AngleOf<float> f = 0;
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
f = Vector3::Angle(v1, v2);
|
f = Vector3::Angle(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(f, 12.9331388F) << "Angle(4 5 6, 1 2 3)";
|
EXPECT_FLOAT_EQ(f.ToFloat(), 12.9331388F) << "Angle(4 5 6, 1 2 3)";
|
||||||
|
|
||||||
v2 = Vector3(-1, -2, -3);
|
v2 = Vector3(-1, -2, -3);
|
||||||
f = Vector3::Angle(v1, v2);
|
f = Vector3::Angle(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(f, 167.066864F) << "Angle(4 5 6, -1 -2 -3)";
|
EXPECT_FLOAT_EQ(f.ToFloat(), 167.066864F) << "Angle(4 5 6, -1 -2 -3)";
|
||||||
|
|
||||||
v2 = Vector3(0, 0, 0);
|
v2 = Vector3(0, 0, 0);
|
||||||
f = Vector3::Angle(v1, v2);
|
f = Vector3::Angle(v1, v2);
|
||||||
EXPECT_FLOAT_EQ(f, 0) << "Angle(4 5 6, 0 0 0)";
|
EXPECT_FLOAT_EQ(f.ToFloat(), 0) << "Angle(4 5 6, 0 0 0)";
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
f = Vector3::Angle(v1, v2);
|
f = Vector3::Angle(v1, v2);
|
||||||
r = isnan(f);
|
r = isnan(f.ToFloat());
|
||||||
EXPECT_TRUE(r) << "Angle(4 5 6, INFINITY INFINITY INFINITY)";
|
EXPECT_TRUE(r) << "Angle(4 5 6, INFINITY INFINITY INFINITY)";
|
||||||
|
|
||||||
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
f = Vector3::Angle(v1, v2);
|
f = Vector3::Angle(v1, v2);
|
||||||
r = isnan(f);
|
r = isnan(f.ToFloat());
|
||||||
EXPECT_TRUE(r) << "Angle(4 5 6, -INFINITY -INFINITY -INFINITY)";
|
EXPECT_TRUE(r) << "Angle(4 5 6, -INFINITY -INFINITY -INFINITY)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -519,39 +519,42 @@ TEST(Vector3, SignedAngle) {
|
|||||||
Vector3 v1 = Vector3(4, 5, 6);
|
Vector3 v1 = Vector3(4, 5, 6);
|
||||||
Vector3 v2 = Vector3(1, 2, 3);
|
Vector3 v2 = Vector3(1, 2, 3);
|
||||||
Vector3 v3 = Vector3(7, 8, -9);
|
Vector3 v3 = Vector3(7, 8, -9);
|
||||||
float f = 0;
|
AngleOf<float> f = 0;
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
|
||||||
f = Vector3::SignedAngle(v1, v2, v3);
|
f = Vector3::SignedAngle(v1, v2, v3);
|
||||||
EXPECT_FLOAT_EQ(f, -12.9331388F) << "SignedAngle(4 5 6, 1 2 3, 7 8 -9)";
|
EXPECT_FLOAT_EQ(f.ToFloat(), -12.9331388F)
|
||||||
|
<< "SignedAngle(4 5 6, 1 2 3, 7 8 -9)";
|
||||||
|
|
||||||
v2 = Vector3(-1, -2, -3);
|
v2 = Vector3(-1, -2, -3);
|
||||||
f = Vector3::SignedAngle(v1, v2, v3);
|
f = Vector3::SignedAngle(v1, v2, v3);
|
||||||
EXPECT_FLOAT_EQ(f, 167.066864F) << "SignedAngle(4 5 6, -1 -2 -3, 7 8 -9)";
|
EXPECT_FLOAT_EQ(f.ToFloat(), 167.066864F)
|
||||||
|
<< "SignedAngle(4 5 6, -1 -2 -3, 7 8 -9)";
|
||||||
|
|
||||||
v2 = Vector3(0, 0, 0);
|
v2 = Vector3(0, 0, 0);
|
||||||
f = Vector3::SignedAngle(v1, v2, v3);
|
f = Vector3::SignedAngle(v1, v2, v3);
|
||||||
EXPECT_FLOAT_EQ(f, 0) << "SignedAngle(4 5 6, 0 0 0, 7 8 -9 )";
|
EXPECT_FLOAT_EQ(f.ToFloat(), 0) << "SignedAngle(4 5 6, 0 0 0, 7 8 -9 )";
|
||||||
|
|
||||||
v2 = Vector3(1, 2, 3);
|
v2 = Vector3(1, 2, 3);
|
||||||
|
|
||||||
v3 = Vector3(-7, -8, 9);
|
v3 = Vector3(-7, -8, 9);
|
||||||
f = Vector3::SignedAngle(v1, v2, v3);
|
f = Vector3::SignedAngle(v1, v2, v3);
|
||||||
EXPECT_FLOAT_EQ(f, 12.9331388F) << "SignedAngle(4 5 6, 1 2 3, -7 -8 9)";
|
EXPECT_FLOAT_EQ(f.ToFloat(), 12.9331388F)
|
||||||
|
<< "SignedAngle(4 5 6, 1 2 3, -7 -8 9)";
|
||||||
|
|
||||||
v3 = Vector3(0, 0, 0);
|
v3 = Vector3(0, 0, 0);
|
||||||
f = Vector3::SignedAngle(v1, v2, v3);
|
f = Vector3::SignedAngle(v1, v2, v3);
|
||||||
EXPECT_FLOAT_EQ(f, 0) << "SignedAngle(4 5 6, 1 2 3, 0 0 0)";
|
EXPECT_FLOAT_EQ(f.ToFloat(), 0) << "SignedAngle(4 5 6, 1 2 3, 0 0 0)";
|
||||||
|
|
||||||
if (std::numeric_limits<float>::is_iec559) {
|
if (std::numeric_limits<float>::is_iec559) {
|
||||||
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
|
||||||
f = Vector3::SignedAngle(v1, v2, v3);
|
f = Vector3::SignedAngle(v1, v2, v3);
|
||||||
r = isnan(f);
|
r = isnan(f.ToFloat());
|
||||||
EXPECT_TRUE(r) << "SignedAngle(4 5 6, INFINITY INFINITY INFINITY)";
|
EXPECT_TRUE(r) << "SignedAngle(4 5 6, INFINITY INFINITY INFINITY)";
|
||||||
|
|
||||||
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
|
||||||
f = Vector3::SignedAngle(v1, v2, v3);
|
f = Vector3::SignedAngle(v1, v2, v3);
|
||||||
r = isnan(f);
|
r = isnan(f.ToFloat());
|
||||||
EXPECT_TRUE(r) << "SignedAngle(4 5 6, -INFINITY -INFINITY -INFINITY)";
|
EXPECT_TRUE(r) << "SignedAngle(4 5 6, -INFINITY -INFINITY -INFINITY)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user