RoboidControl-cpp/test/Vector3_test.cc
Pascal Serrarens e50c8eb9c8 Squashed 'LinearAlgebra/' changes from bfa1123..8b6f628
8b6f628 Fix Matrix unit test
28a3064 Fix tests
91f4280 Reduced the use of raw pointers
83539df Fixes to make it work againg, but failing at udp.begin()
3cca327 Optimizations
361807c Performance improvements
7bd83fa Processomg Acc data * propagating
0eb2851 Linking works
06ff5e9 Added ESP-IDF Wifi/UDP support (but it still give linker errors)
7461a1f Implemented integrate function
b7f102a Fix matrix2 tests
7d2dd08 First steps implementation Matrix operations
f05b411 Cleanup
05a3b09 Update namespace, Windows compatibility
95a248a First udp communcation is working
fea15c3 removed namespace Passer
753de2d Fixes
9674f68 Disabled test failing on MacOS
5b89234 Made it work on MacOS
d0ba29e Updated LinearAlgebra
ebfb4fb Merge commit '0b63a044eb84175cc922f3f1fe0ce039d101bf7b'
0b63a04 Updated documentation, cleanup
a0082bd Add direction documentation
770ce32 Merge commit '2b5f5cd175b20fa01e04b696dfe0cfbe2c4ad9da'
2b5f5cd Removed shorthand Deg/Rad aliases... (see below)
d212db2 Trying to fix specialization before instantiation error
e445e5b Trying to fix specialization before instantiation error
f47e504 Trying to fix specialization before instantiation error
b877d4d Trying to fix specialization before instantiation error
06e8623 Trying to fix specialization before instantiation error
e97aee9 Trying to fix specialization before instantiation error
0e00e5d Merge branch 'main' of http://gitlab.passervr.com/passer/cpp/linear-algebra
52de55d Trying to fix specialization before instantiation error
47ba024 Trying to fix specialization before instantiation error
2402030 Trying to fix specialization before instantiation error
4e3f253 Fixed gitignore
06c70e2 Merge branch 'Experimental'
6f30334 Updated PolarOf, removed default Polar type
94a3105 Cleanup
89a5711 Fixed typo in documentation
64b7f11 Removed default Angle type
58beb36 Completed AngleOf documentation
5f58a2c Updated documentation
97d937e Fixed (copilot) unit tests
585a3b0 Removed default Spherical type
d3226fd Added copilot test documentation
a7aa679 Added a performance test
2c57c3f Fixed direction for spherical
28ee225 Normalize Spherical at creation
800eb75 improved rounding of discrete angles
536d6ce Add Binary support
18756ba Correct axis on quaternion from swingtwist
06e42c5 Normalized swing twist
edbb4b1 Removes Angle::deg90/180 because of issues
0a07b23 SwingTwist == and Angle
9406b57 SwingTwist::AngleAxis using Direction
06da9e5 Removed AngleAxis, Sperhical will be used instead
2e61e1b Fix unit test
54d0318 Extended unit tests (plus fixes)
8286c1c Minor improvements
95a6fb3 Improved Angle quality
9eca318 Fixed inverse
0ebfce4 Spherical direction
136e44e Fixed unit tests
fb5cee8 Proper angle implementation (unit tests still fail)
92d5ef0 Normalizing directions
1ea65d5 Made toQuestion const
f1c70c7 Fix unit tests
2ad6a5a Fix include
11259a9 Extend functionality
3363388 Extended AngleAxis & Direction
09e25a8 Add Asin and Atan
a646e93 Add ACos
407e771 Add WithDistance
69bad8f Added degrees, radians, cos, sin, and tan functions
5c3dfa6 Adde degrees/readians and poc ACos
05c61a3 Add distance between
6a1d043 Added Angle comparison
6b3bcfc Another anglebetween fix
b5a6330 Fix anglebetween
b975aed Added angle and rotate functions
f483439 Moved Polar/Spherical to template class completely
e0ef43a Merge branch 'Experimental' of http://gitlab.passervr.com/passer/cpp/linear-algebra into Experimental
b460bec Added scaling to SphericalOf<T>
e10e010 Added Direction to library sources
dedaa31 Fix unit tests
1da93ca Fix ToVector3
9c3503f Added SphericalOf
353cb1b Add conversion from Quaternion
cf86ba8 Cleanup template classes
ea6894e Fix generic template functions
1ce7234 Bug fixes
38ebb34 Added Direction to replace Axis
c72bba4 Change Vector3::Angle return type to AngleOf<float>
18cf653 Added scaling support
51772a1 Added add/subtract for discrete angles
49c6740 Make Angle -> float conversion explicit
608c45c Fix precision error
4591aef Added Spherical16
48828e2 Fix int/float issues
86b7c21 Added Degrees inline function
a4b0491 Fix unit tests
b81b77b Extend AngleOf support
c70c079 Add spherical subtract
2bad384 Added spherical addition
a25a8be Fixed namespace issues
f8009a7 Updated namespace
91c7b20 Fix gitlab test runner
78468e3 Renamed VectorAlgebra project to LinearAlgebra
47a6368 Fix Vector3
ee62cba XYZ deprecation
62d7439 Extend ulitity functions
95713c8 Cleanup, added utility functions
f7d9d97 Cleanup
66e47d7 Cleanup Vector2 and Polar
e922a01 fix == operator
5693097 Initial subtractop test
c411b43 Textual improvement
0c54276 equality support
b1e34b6 Improved unit tests
6ddb074 Improved unit tests
5489b3c Fix test
3d971c1 Improve namespace
791bd78 namespace improvement
9bea94f Use Angle type for Polar
8a2ce21 Swapped polar constructor param order
e5f8d73 namespace fix
8e7a8c6 Fix namespaces
64ca768 normalize toAngleAxis result
4385bef Add angle-axis
4b07328 Add conversion from Vector3
fe12c99 Fix Spherical reference
c274c3e Add conversion from Spherical
66ff721 Fixed wrong conversion to short
264bcbc Added 32 bit angle
f190dd7 Merge branch 'DiscreteAngle' into Experimental
ae55a24 Further  vector3 conversion fixes
ec0cc47 Fix spherical to vector
89b5da8 Fix ambiguity
e62fa96 Fix specialization again
430344a Fix specialization error
3e5ede0 Removed old file
e62bacc First Discrete Angle functions
87d2c11 Set strict warnings
5141766 Add spherical.toVector3 test (and fixes)
8e3b9e2 Fix Polar test
7b85556 Addedfirst Polar test
395f82d Fix Spherical Unit test
0cbef79 Add first Spherical Unit test
dc601a1 Removed Vector2.tofactor
159bdae Added spherical.tovector (but is is buggy)
273ebae Fixes
0468031 Bug fix
3714507 Implemented templated angles
69e7ee1 Added DiscreteAgle
2cbf259 Make negation virtual override
2b50bab Add negation for DiscreteAngle
de3a647 Updated negation
254bb27 Added negation
bd04285 Make superclass accessable
2bb0009 Initial implementation

git-subtree-dir: LinearAlgebra
git-subtree-split: 8b6f628d0c6b9e72260ce1d9c0437124c2d7b6d8
2025-05-26 15:26:44 +02:00

583 lines
17 KiB
C++

#if GTEST
#include <gtest/gtest.h>
#include <limits>
#include <math.h>
#include "Vector3.h"
#define FLOAT_INFINITY std::numeric_limits<float>::infinity()
TEST(Vector3, FromSpherical) {
Vector3 v = Vector3(0, 0, 1);
SphericalOf<float> s = SphericalOf<float>::FromVector3(v);
Vector3 r = Vector3(s);
EXPECT_FLOAT_EQ(r.Right(), 0.0F) << "toVector3.x 0 0 1";
EXPECT_NEAR(r.Up(), 0.0F, 1.0e-06) << "toVector3.y 0 0 1";
EXPECT_FLOAT_EQ(r.Forward(), 1.0F) << "toVector3.z 0 0 1";
v = Vector3(0, 1, 0);
s = SphericalOf<float>::FromVector3(v);
r = Vector3(s);
EXPECT_FLOAT_EQ(r.Right(), 0.0F) << "toVector3.x 0 1 0";
EXPECT_FLOAT_EQ(r.Up(), 1.0F) << "toVector3.y 0 1 0";
EXPECT_NEAR(r.Forward(), 0.0F, 1.0e-06) << "toVector3.z 0 1 0";
v = Vector3(1, 0, 0);
s = SphericalOf<float>::FromVector3(v);
r = Vector3(s);
EXPECT_FLOAT_EQ(r.Right(), 1.0F) << "toVector3.x 1 0 0";
EXPECT_NEAR(r.Up(), 0.0F, 1.0e-06) << "toVector3.y 1 0 0";
EXPECT_NEAR(r.Forward(), 0.0F, 1.0e-06) << "toVector3.z 1 0 0";
}
TEST(Vector3, Magnitude) {
Vector3 v = Vector3(1, 2, 3);
float m = 0;
m = v.magnitude();
EXPECT_FLOAT_EQ(m, 3.741657F) << "v.magnitude 1 2 3";
m = Vector3::Magnitude(v);
EXPECT_FLOAT_EQ(m, 3.741657F) << "Vector3::Magnitude 1 2 3";
v = Vector3(-1, -2, -3);
m = v.magnitude();
EXPECT_FLOAT_EQ(m, 3.741657F) << "v.magnitude -1 -2 -3";
v = Vector3(0, 0, 0);
m = v.magnitude();
EXPECT_FLOAT_EQ(m, 0) << "v.magnitude 0 0 0 ";
if (std::numeric_limits<float>::is_iec559) {
v = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
m = v.magnitude();
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY)
<< "v.magnitude INFINITY INFINITY INFINITY ";
v = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
m = v.magnitude();
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY)
<< "v.magnitude -INFINITY -INFINITY -INFINITY ";
}
}
TEST(Vector3, SqrMagnitude) {
Vector3 v = Vector3(1, 2, 3);
float m = 0;
m = v.sqrMagnitude();
EXPECT_FLOAT_EQ(m, 14) << "v.sqrMagnitude 1 2 3";
m = Vector3::SqrMagnitude(v);
EXPECT_FLOAT_EQ(m, 14) << "Vector3::SqrMagnitude 1 2 3";
v = Vector3(-1, -2, -3);
m = v.sqrMagnitude();
EXPECT_FLOAT_EQ(m, 14) << "v.sqrMagnitude -1 -2 -3";
v = Vector3(0, 0, 0);
m = v.sqrMagnitude();
EXPECT_FLOAT_EQ(m, 0) << "v.sqrMagnitude 0 0 0 ";
if (std::numeric_limits<float>::is_iec559) {
v = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
m = v.sqrMagnitude();
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY)
<< "v.sqrMagnitude INFINITY INFINITY INFINITY ";
v = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
m = v.sqrMagnitude();
EXPECT_FLOAT_EQ(m, FLOAT_INFINITY)
<< "v.sqrMagnitude -INFINITY -INFINITY -INFINITY ";
}
}
TEST(Vector3, Normalize) {
bool r = false;
Vector3 v1 = Vector3(0, 2, 0);
Vector3 v = Vector3::zero;
v = v1.normalized();
EXPECT_TRUE(v == Vector3(0, 1, 0)) << "v.normalized 0 2 0";
v = Vector3::Normalize(v1);
EXPECT_TRUE(v == Vector3(0, 1, 0)) << "Vector3::Normalize 0 2 0";
v1 = Vector3(0, -2, 0);
v = v1.normalized();
EXPECT_TRUE(v == Vector3(0, -1, 0)) << "v.normalized 0 -2 0";
v1 = Vector3(0, 0, 0);
v = v1.normalized();
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "v.normalized 0 0 0";
if (std::numeric_limits<float>::is_iec559) {
v1 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
v = v1.normalized();
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
EXPECT_TRUE(r) << "v.normalized INFINITY INFINITY INFINITY";
v1 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
v = v1.normalized();
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
EXPECT_TRUE(r) << "v.normalized -INFINITY -INFINITY -INFINITY";
}
}
TEST(Vector3, Negate) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v = Vector3::zero;
v = -v1;
EXPECT_TRUE(v == Vector3(-4, -5, -6)) << "- 4 5 6";
v1 = Vector3(-4, -5, -6);
v = -v1;
EXPECT_TRUE(v == Vector3(4, 5, 6)) << "- -4 -5 -6";
v1 = Vector3(0, 0, 0);
v = -v1;
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "- 0 0 0";
if (std::numeric_limits<float>::is_iec559) {
v1 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
v = -v1;
EXPECT_TRUE(v == Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY))
<< "- INFINITY INFINITY INFINITY";
v1 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
v = -v1;
EXPECT_TRUE(v == Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY))
<< "- -INFINITY -INFINITY -INFINITY";
}
}
TEST(Vector3, Subtract) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
Vector3 v = Vector3::zero;
v = v1 - v2;
EXPECT_TRUE(v == Vector3(3, 3, 3)) << "4 5 6 - 1 2 3";
v2 = Vector3(-1, -2, -3);
v = v1 - v2;
EXPECT_TRUE(v == Vector3(5, 7, 9)) << "4 5 6 - -1 -2 -3";
v2 = Vector3(4, 5, 6);
v = v1 - v2;
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "4 5 6 - 4 5 6";
v2 = Vector3(0, 0, 0);
v = v1 - v2;
EXPECT_TRUE(v == Vector3(4, 5, 6)) << "4 5 6 - 0 0 0";
if (std::numeric_limits<float>::is_iec559) {
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
v = v1 - v2;
EXPECT_TRUE(v == Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY))
<< "4 5 6 - INFINITY INFINITY INFINITY";
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
v = v1 - v2;
EXPECT_TRUE(v == Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY))
<< "4 5 6 - -INFINITY -INFINITY -INFINITY";
}
}
TEST(Vector3, Addition) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
Vector3 v = Vector3::zero;
v = v1 + v2;
EXPECT_TRUE(v == Vector3(5, 7, 9)) << "4 5 6 + 1 2 3";
v2 = Vector3(-1, -2, -3);
v = v1 + v2;
EXPECT_TRUE(v == Vector3(3, 3, 3)) << "4 5 6 + -1 -2 -3";
v2 = Vector3(0, 0, 0);
v = v1 + v2;
EXPECT_TRUE(v == Vector3(4, 5, 6)) << "4 5 6 + 0 0 0";
if (std::numeric_limits<float>::is_iec559) {
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
v = v1 + v2;
EXPECT_TRUE(v == Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY))
<< "4 5 6 + INFINITY INFINITY INFINITY";
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
v = v1 + v2;
EXPECT_TRUE(v == Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY))
<< "4 5 6 + -INFINITY -INFINITY -INFINITY";
}
}
TEST(Vector3, Scale) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
Vector3 v = Vector3::zero;
v = Vector3::Scale(v1, v2);
EXPECT_TRUE(v == Vector3(4, 10, 18)) << "Scale 4 5 6 , 1 2 3";
v2 = Vector3(-1, -2, -3);
v = Vector3::Scale(v1, v2);
EXPECT_TRUE(v == Vector3(-4, -10, -18)) << "Scale 4 5 6 , -1 -2 -3";
v2 = Vector3(0, 0, 0);
v = Vector3::Scale(v1, v2);
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "Scale 4 5 6 , 0 0 0";
if (std::numeric_limits<float>::is_iec559) {
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
v = Vector3::Scale(v1, v2);
EXPECT_TRUE(v == Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY))
<< "4 5 6 + INFINITY INFINITY INFINITY";
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
v = Vector3::Scale(v1, v2);
EXPECT_TRUE(v == Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY))
<< "4 5 6 + -INFINITY -INFINITY -INFINITY";
}
}
TEST(Vector3, Multiply) {
Vector3 v1 = Vector3(4, 5, 6);
float f = 3;
Vector3 v = Vector3::zero;
v = v1 * f;
EXPECT_TRUE(v == Vector3(12, 15, 18)) << "4 5 6 * 3";
f = -3;
v = v1 * f;
EXPECT_TRUE(v == Vector3(-12, -15, -18)) << "4 5 6 * -3";
f = 0;
v = v1 * f;
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "4 5 6 * 0";
if (std::numeric_limits<float>::is_iec559) {
f = FLOAT_INFINITY;
v = v1 * f;
EXPECT_TRUE(v == Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY))
<< "4 5 6 * INFINITY";
f = -FLOAT_INFINITY;
v = v1 * f;
EXPECT_TRUE(v == Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY))
<< "4 5 6 * -INFINITY";
}
}
TEST(Vector3, Divide) {
Vector3 v1 = Vector3(4, 5, 6);
float f = 2;
Vector3 v = Vector3::zero;
v = v1 / f;
EXPECT_TRUE(v == Vector3(2, 2.5F, 3)) << "4 5 6 / 3";
f = -2;
v = v1 / f;
EXPECT_TRUE(v == Vector3(-2, -2.5F, -3)) << "4 5 6 / -3";
if (std::numeric_limits<float>::is_iec559) {
f = 0;
v = v1 / f;
EXPECT_TRUE(v == Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY))
<< "4 5 6 / 0";
f = FLOAT_INFINITY;
v = v1 / f;
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "4 5 6 / INFINITY";
f = -FLOAT_INFINITY;
v = v1 / f;
EXPECT_TRUE(v == Vector3(0, 0, 0)) << "4 5 6 / -INFINITY";
}
}
TEST(Vector3, Dot) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
float f = 0;
f = Vector3::Dot(v1, v2);
EXPECT_FLOAT_EQ(f, 32) << "Dot(4 5 6, 1 2 3)";
v2 = Vector3(-1, -2, -3);
f = Vector3::Dot(v1, v2);
EXPECT_FLOAT_EQ(f, -32) << "Dot(4 5 6, -1 -2 -3)";
v2 = Vector3(0, 0, 0);
f = Vector3::Dot(v1, v2);
EXPECT_FLOAT_EQ(f, 0) << "Dot(4 5 6, 0 0 0)";
if (std::numeric_limits<float>::is_iec559) {
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
f = Vector3::Dot(v1, v2);
EXPECT_FLOAT_EQ(f, FLOAT_INFINITY)
<< "Dot(4 5 6, INFINITY INFINITY INFINITY)";
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
f = Vector3::Dot(v1, v2);
EXPECT_FLOAT_EQ(f, -FLOAT_INFINITY)
<< "Dot(4 5 6, -INFINITY -INFINITY -INFINITY)";
}
}
TEST(Vector3, Equality) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
bool r = false;
r = v1 == v2;
EXPECT_FALSE(r) << "4 5 6 == 1 2 3";
v2 = Vector3(4, 5, 6);
r = v1 == v2;
EXPECT_TRUE(r) << "4 5 6 == 1 2 3";
if (std::numeric_limits<float>::is_iec559) {
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
r = v1 == v2;
EXPECT_FALSE(r) << "4 5 6 == INFINITY INFINITY INFINITY";
v1 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
r = v1 == v2;
EXPECT_FALSE(r)
<< "-INFINITY -INFINITY -INFINITY == INFINITY INFINITY INFINITY";
}
}
TEST(Vector3, Distance) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
float f = 0;
f = Vector3::Distance(v1, v2);
EXPECT_FLOAT_EQ(f, 5.19615221F) << "Distance(4 5 6, 1 2 3)";
v2 = Vector3(-1, -2, -3);
f = Vector3::Distance(v1, v2);
EXPECT_FLOAT_EQ(f, 12.4498997F) << "Distance(4 5 6, -1 -2 -3)";
v2 = Vector3(0, 0, 0);
f = Vector3::Distance(v1, v2);
EXPECT_FLOAT_EQ(f, 8.77496433F) << "Distance(4 5 6, 0 0 0)";
if (std::numeric_limits<float>::is_iec559) {
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
f = Vector3::Distance(v1, v2);
EXPECT_FLOAT_EQ(f, FLOAT_INFINITY)
<< "Distance(4 5 6, INFINITY INFINITY INFINITY)";
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
f = Vector3::Distance(v1, v2);
EXPECT_FLOAT_EQ(f, FLOAT_INFINITY)
<< "Distance(4 5 6, -INFINITY -INFINITY -INFINITY)";
}
}
TEST(Vector3, Cross) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
Vector3 v = Vector3::zero;
bool r = false;
v = Vector3::Cross(v1, v2);
r = v == Vector3(3, -6, 3);
EXPECT_TRUE(r) << "Cross(4 5 6, 1 2 3)";
v2 = Vector3(-1, -2, -3);
v = Vector3::Cross(v1, v2);
r = v == Vector3(-3, 6, -3);
EXPECT_TRUE(r) << "Cross(4 5 6, -1 -2 -3)";
v2 = Vector3(0, 0, 0);
v = Vector3::Cross(v1, v2);
r = v == Vector3(0, 0, 0);
EXPECT_TRUE(r) << "Cross(4 5 6, 0 0 0)";
if (std::numeric_limits<float>::is_iec559) {
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
v = Vector3::Cross(v1, v2);
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
EXPECT_TRUE(r) << "Cross(4 5 6, INFINITY INFINITY INFINITY)";
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
v = Vector3::Cross(v1, v2);
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
EXPECT_TRUE(r) << "Cross(4 5 6, -INFINITY -INFINITY -INFINITY)";
}
}
TEST(Vector3, Project) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
Vector3 v = Vector3::zero;
bool r = false;
v = Vector3::Project(v1, v2);
r = v == Vector3(2.28571439F, 4.57142878F, 6.85714293F);
EXPECT_TRUE(r) << "Project(4 5 6, 1 2 3)";
v2 = Vector3(-1, -2, -3);
v = Vector3::Project(v1, v2);
r = v == Vector3(2.28571439F, 4.57142878F, 6.85714293F);
EXPECT_TRUE(r) << "Project(4 5 6, -1 -2 -3)";
v2 = Vector3(0, 0, 0);
v = Vector3::Project(v1, v2);
r = v == Vector3(0, 0, 0);
EXPECT_TRUE(r) << "Project(4 5 6, 0 0 0)";
if (std::numeric_limits<float>::is_iec559) {
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
v = Vector3::Project(v1, v2);
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
EXPECT_TRUE(r) << "Project(4 5 6, INFINITY INFINITY INFINITY)";
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
v = Vector3::Project(v1, v2);
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
EXPECT_TRUE(r) << "Project(4 5 6, -INFINITY -INFINITY -INFINITY)";
}
}
TEST(Vector3, ProjectOnPlane) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
Vector3 v = Vector3::zero;
bool r = false;
v = Vector3::ProjectOnPlane(v1, v2);
r = v == Vector3(1.71428561F, 0.428571224F, -0.857142925F);
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, 1 2 3)";
v2 = Vector3(-1, -2, -3);
v = Vector3::ProjectOnPlane(v1, v2);
r = v == Vector3(1.71428561F, 0.428571224F, -0.857142925F);
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, -1 -2 -3)";
v2 = Vector3(0, 0, 0);
v = Vector3::ProjectOnPlane(v1, v2);
r = v == Vector3(4, 5, 6);
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, 0 0 0)";
if (std::numeric_limits<float>::is_iec559) {
v2 = Vector3(FLOAT_INFINITY, FLOAT_INFINITY, FLOAT_INFINITY);
v = Vector3::ProjectOnPlane(v1, v2);
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, INFINITY INFINITY INFINITY)";
v2 = Vector3(-FLOAT_INFINITY, -FLOAT_INFINITY, -FLOAT_INFINITY);
v = Vector3::ProjectOnPlane(v1, v2);
r = isnan(v.Right()) && isnan(v.Up()) && isnan(v.Forward());
EXPECT_TRUE(r) << "ProjectOnPlane(4 5 6, -INFINITY -INFINITY -INFINITY)";
}
}
TEST(Vector3, Angle) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
AngleOf<float> f = AngleOf<float>::Degrees(0);
bool r = false;
f = Vector3::Angle(v1, v2);
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.InDegrees(), 167.066864F) << "Angle(4 5 6, -1 -2 -3)";
v2 = Vector3(0, 0, 0);
f = Vector3::Angle(v1, v2);
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.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.InDegrees());
EXPECT_TRUE(r) << "Angle(4 5 6, -INFINITY -INFINITY -INFINITY)";
}
}
TEST(Vector3, SignedAngle) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
Vector3 v3 = Vector3(7, 8, -9);
AngleOf<float> f = AngleOf<float>::Degrees(0);
bool r = false;
f = Vector3::SignedAngle(v1, v2, v3);
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.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.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.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.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.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.InDegrees());
EXPECT_TRUE(r) << "SignedAngle(4 5 6, -INFINITY -INFINITY -INFINITY)";
}
}
TEST(Vector3, Lerp) {
Vector3 v1 = Vector3(4, 5, 6);
Vector3 v2 = Vector3(1, 2, 3);
Vector3 r = Vector3(0, 0, 0);
r = Vector3::Lerp(v1, v2, 0);
EXPECT_FLOAT_EQ(Vector3::Distance(r, v1), 0);
r = Vector3::Lerp(v1, v2, 1);
EXPECT_FLOAT_EQ(Vector3::Distance(r, v2), 0);
r = Vector3::Lerp(v1, v2, 0.5f);
EXPECT_FLOAT_EQ(Vector3::Distance(r, Vector3(2.5f, 3.5f, 4.5f)), 0);
r = Vector3::Lerp(v1, v2, -1);
EXPECT_FLOAT_EQ(Vector3::Distance(r, Vector3(7.0f, 8.0f, 9.0f)), 0);
r = Vector3::Lerp(v1, v2, 2);
EXPECT_FLOAT_EQ(Vector3::Distance(r, Vector3(-2.0, -1.0f, 0.0f)), 0);
}
#endif