From 585a3b0fe590ca740b7303a7f83108788d40c640 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Thu, 26 Dec 2024 11:02:35 +0100 Subject: [PATCH] Removed default Spherical type --- Spherical.cpp | 225 ------------------------------------------- Spherical.h | 191 +++++------------------------------- Vector3.cpp | 49 +++++----- test/Vector3_test.cc | 8 +- 4 files changed, 49 insertions(+), 424 deletions(-) diff --git a/Spherical.cpp b/Spherical.cpp index dbbba17..2b841f3 100644 --- a/Spherical.cpp +++ b/Spherical.cpp @@ -276,228 +276,3 @@ SphericalOf SphericalOf::RotateVertical(const SphericalOf &v, template class SphericalOf; template class SphericalOf; - -//--------------------------------------- -/* -Spherical::Spherical() { - this->distance = 0.0f; - this->horizontalAngle = 0.0f; - this->verticalAngle = 0.0f; -} - -// Spherical::Spherical(Polar polar) { -// this->distance = polar.distance; -// this->horizontalAngle = polar.angle; -// this->verticalAngle = 0.0f; -// } - -Spherical::Spherical(float distance, - Angle horizontalAngle, - Angle verticalAngle) { - if (distance < 0) { - this->distance = -distance; - this->horizontalAngle = - Angle::Normalize(horizontalAngle.ToFloat() - 180.0f); - this->verticalAngle = verticalAngle; - } else { - this->distance = distance; - this->horizontalAngle = Angle::Normalize(horizontalAngle); - this->verticalAngle = Angle::Normalize(verticalAngle); - } -} - -Spherical::Spherical(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; - } -} - -const Spherical Spherical::zero = Spherical(0.0f, 0.0f, 0.0f); -const Spherical Spherical::forward = Spherical(1.0f, 0.0f, 0.0f); -const Spherical Spherical::back = Spherical(1.0f, 180.0f, 0.0f); -const Spherical Spherical::right = Spherical(1.0f, 90.0f, 0.0f); -const Spherical Spherical::left = Spherical(1.0f, -90.0f, 0.0f); -const Spherical Spherical::up = Spherical(1.0f, 0.0f, 90.0f); -const Spherical Spherical::down = Spherical(1.0f, 0.0f, -90.0f); - -bool Spherical::operator==(const Spherical& v) const { - return (this->distance == v.distance && - this->horizontalAngle.ToFloat() == v.horizontalAngle.ToFloat() && - this->verticalAngle.ToFloat() == v.verticalAngle.ToFloat()); -} - -Spherical Spherical::Normalize(const Spherical& v) { - Spherical r = Spherical(1, v.horizontalAngle, v.verticalAngle); - return r; -} -Spherical Spherical::normalized() const { - Spherical r = Spherical(1, this->horizontalAngle, this->verticalAngle); - return r; -} - -Spherical Spherical::operator-() const { - Spherical v = - Spherical(this->distance, this->horizontalAngle.ToFloat() + 180.0f, - this->verticalAngle.ToFloat() + 180.0f); - return v; -} - -Spherical Spherical::operator-(const Spherical& s2) const { - // let's do it the easy way... - Vector3 v1 = Vector3(*this); - Vector3 v2 = Vector3(s2); - Vector3 v = v1 - v2; - Spherical r = Spherical(v); - return r; -} -Spherical Spherical::operator-=(const Spherical& v) { - *this = *this - v; - return *this; -} - -Spherical Spherical::operator+(const Spherical& s2) const { - // let's do it the easy way... - Vector3 v1 = Vector3(*this); - Vector3 v2 = Vector3(s2); - Vector3 v = v1 + v2; - Spherical r = Spherical(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); - -} -Spherical Spherical::operator+=(const Spherical& v) { - *this = *this + v; - return *this; -} - -// Spherical Passer::LinearAlgebra::operator*(const Spherical &v, float f) { -// return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle); -// } -// Spherical Passer::LinearAlgebra::operator*(float f, const Spherical &v) { -// return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle); -// } -Spherical Spherical::operator*=(float f) { - this->distance *= f; - return *this; -} - -// Spherical Passer::LinearAlgebra::operator/(const Spherical &v, float f) { -// return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle); -// } -// Spherical Passer::LinearAlgebra::operator/(float f, const Spherical &v) { -// return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle); -// } -Spherical Spherical::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 Spherical::AngleBetween(const Spherical& v1, const Spherical& v2) { - // float denominator = sqrtf(v1_3.sqrMagnitude() * v2_3.sqrMagnitude()); - float denominator = - v1.distance * v2.distance; // sqrtf(v1.distance * v1.distance * - // v2.distance * v2.distance); - if (denominator < epsilon) - return 0.0f; - - Vector3 v1_3 = Vector3(v1); - Vector3 v2_3 = Vector3(v2); - 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; -} - -Spherical Spherical::Rotate(const Spherical& v, - Angle horizontalAngle, - Angle verticalAngle) { - Spherical r = Spherical( - v.distance, v.horizontalAngle.ToFloat() + horizontalAngle.ToFloat(), - v.verticalAngle.ToFloat() + verticalAngle.ToFloat()); - return r; -} -Spherical Spherical::RotateHorizontal(const Spherical& v, Angle a) { - Spherical r = Spherical(v.distance, v.horizontalAngle.ToFloat() + a.ToFloat(), - v.verticalAngle.ToFloat()); - return r; -} -Spherical Spherical::RotateVertical(const Spherical& v, Angle a) { - Spherical r = Spherical(v.distance, v.horizontalAngle.ToFloat(), - v.verticalAngle.ToFloat() + a.ToFloat()); - return r; -} -*/ diff --git a/Spherical.h b/Spherical.h index 8d71891..3d21bab 100644 --- a/Spherical.h +++ b/Spherical.h @@ -11,12 +11,10 @@ namespace Passer { namespace LinearAlgebra { struct Vector3; -template -class PolarOf; +template class PolarOf; -template -class SphericalOf { - public: +template class SphericalOf { +public: /// @brief The distance in meters /// @remark The distance should never be negative float distance; @@ -63,23 +61,23 @@ class SphericalOf { /// @brief Subtract a spherical vector from this vector /// @param v The vector to subtract /// @return The result of the subtraction - SphericalOf operator-(const SphericalOf& v) const; - SphericalOf operator-=(const SphericalOf& v); + SphericalOf operator-(const SphericalOf &v) const; + SphericalOf operator-=(const SphericalOf &v); /// @brief Add a spherical vector to this vector /// @param v The vector to add /// @return The result of the addition - SphericalOf operator+(const SphericalOf& v) const; - SphericalOf operator+=(const SphericalOf& v); + SphericalOf operator+(const SphericalOf &v) const; + SphericalOf operator+=(const SphericalOf &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 SphericalOf operator*(const SphericalOf& v, float f) { + friend SphericalOf operator*(const SphericalOf &v, float f) { return SphericalOf(v.distance * f, v.direction); } - friend SphericalOf operator*(float f, const SphericalOf& v) { + friend SphericalOf operator*(float f, const SphericalOf &v) { return SphericalOf(f * v.distance, v.direction); } SphericalOf operator*=(float f); @@ -88,178 +86,35 @@ class SphericalOf { /// @return The scaled factor /// @remark This operation will scale the distance of the vector. The angle /// will be unaffected. - friend SphericalOf operator/(const SphericalOf& v, float f) { + friend SphericalOf operator/(const SphericalOf &v, float f) { return SphericalOf(v.distance / f, v.direction); } - friend SphericalOf operator/(float f, const SphericalOf& v) { + friend SphericalOf operator/(float f, const SphericalOf &v) { return SphericalOf(f / v.distance, v.direction); } SphericalOf operator/=(float f); - /// - /// The distance between two vectors - /// - /// The first vector - /// The second vector - /// The distance between the two vectors - // static float Distance(const Spherical &s1, const Spherical &s2); + static float DistanceBetween(const SphericalOf &v1, + const SphericalOf &v2); + static AngleOf AngleBetween(const SphericalOf &v1, + const SphericalOf &v2); + static AngleOf SignedAngleBetween(const SphericalOf &v1, + const SphericalOf &v2, + const SphericalOf &axis); - static float DistanceBetween(const SphericalOf& v1, - const SphericalOf& v2); - static AngleOf AngleBetween(const SphericalOf& v1, - const SphericalOf& v2); - static AngleOf SignedAngleBetween(const SphericalOf& v1, - const SphericalOf& v2, - const SphericalOf& axis); - - static SphericalOf Rotate(const SphericalOf& v, - AngleOf horizontalAngle, + static SphericalOf Rotate(const SphericalOf &v, AngleOf horizontalAngle, AngleOf verticalAngle); - static SphericalOf RotateHorizontal(const SphericalOf& v, + static SphericalOf RotateHorizontal(const SphericalOf &v, AngleOf angle); - static SphericalOf RotateVertical(const SphericalOf& v, + static SphericalOf RotateVertical(const SphericalOf &v, AngleOf angle); }; using SphericalSingle = SphericalOf; using Spherical16 = SphericalOf; -using Spherical = SphericalSingle; -/* -/// @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. -struct Spherical { - 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 - Angle horizontalAngle; - /// @brief The angle in the vertical plane in degrees. Positive is upward. - /// @details The angle is automatically normalized to -180 .. 180 - Angle verticalAngle; - /// @brief Create a new spherical vector with zero degrees and distance - Spherical(); - /// @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 - Spherical(float distance, Angle horizontalAngle, Angle verticalAngle); - /// @brief Convert polar coordinates to spherical coordinates - /// @param polar The polar coordinate - // Spherical(Polar polar); - /// @brief Convert 3D carthesian coordinates to spherical coordinates - /// @param v Vector in 3D carthesian coordinates; - Spherical(Vector3 v); - - /// @brief A spherical vector with zero degree angles and distance - const static Spherical zero; - /// @brief A normalized forward-oriented vector - const static Spherical forward; - /// @brief A normalized back-oriented vector - const static Spherical back; - /// @brief A normalized right-oriented vector - const static Spherical right; - /// @brief A normalized left-oriented vector - const static Spherical left; - /// @brief A normalized up-oriented vector - const static Spherical up; - /// @brief A normalized down-oriented vector - const static Spherical 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 Spherical& v) const; - - /// @brief The vector length - /// @param v The vector for which you need the length - /// @return The vector length; - inline static float Magnitude(const Spherical& v) { return v.distance; } - /// @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 Spherical Normalize(const Spherical& v); - /// @brief Convert the vector to a length of a - /// @return The vector normalized to a length of 1 - Spherical normalized() const; - - /// @brief Negate the vector - /// @return The negated vector - /// This will rotate the vector by 180 degrees horizontally and - /// vertically. Distance will stay the same. - Spherical operator-() const; - - /// @brief Subtract a spherical vector from this vector - /// @param v The vector to subtract - /// @return The result of the subtraction - Spherical operator-(const Spherical& v) const; - Spherical operator-=(const Spherical& v); - /// @brief Add a spherical vector to this vector - /// @param v The vector to add - /// @return The result of the addition - Spherical operator+(const Spherical& v) const; - Spherical operator+=(const Spherical& v); - - /// @brief Scale the vector uniformly up - /// @param f The scaling factor - /// @return The scaled vector - /// @remark This operation will scale the distance of the vector. The angle - /// will be unaffected. - friend Spherical operator*(const Spherical& v, float f) { - return Spherical(v.distance * f, v.horizontalAngle, v.verticalAngle); - } - friend Spherical operator*(float f, const Spherical& v) { - return Spherical(v.distance * f, v.horizontalAngle, - v.verticalAngle); // not correct, should be f * v.distance - } - Spherical operator*=(float f); - /// @brief Scale the vector uniformly down - /// @param f The scaling factor - /// @return The scaled factor - /// @remark This operation will scale the distance of the vector. The angle - /// will be unaffected. - friend Spherical operator/(const Spherical& v, float f) { - return Spherical(v.distance / f, v.horizontalAngle, v.verticalAngle); - } - friend Spherical operator/(float f, const Spherical& v) { - return Spherical(v.distance / f, v.horizontalAngle, - v.verticalAngle); // not correct, should be f / v.distance - } - Spherical operator/=(float f); - - /// - /// The distance between two vectors - /// - /// The first vector - /// The second vector - /// The distance between the two vectors - // static float Distance(const Spherical &s1, const Spherical &s2); - - static Angle AngleBetween(const Spherical& v1, const Spherical& v2); - - static Spherical Rotate(const Spherical& v, - Angle horizontalAngle, - Angle verticalAngle); - static Spherical RotateHorizontal(const Spherical& v, Angle angle); - static Spherical RotateVertical(const Spherical& v, Angle angle); -}; -*/ - -} // namespace LinearAlgebra -} // namespace Passer +} // namespace LinearAlgebra +} // namespace Passer using namespace Passer::LinearAlgebra; #include "Polar.h" diff --git a/Vector3.cpp b/Vector3.cpp index e3f1b8e..8a63923 100644 --- a/Vector3.cpp +++ b/Vector3.cpp @@ -30,7 +30,7 @@ Vector3::Vector3(Vector2 v) { this->z = v.y; } -Vector3::Vector3(Spherical s) { +Vector3::Vector3(SphericalOf s) { float verticalRad = (90.0f - s.direction.vertical.InDegrees()) * Passer::LinearAlgebra::Deg2Rad; float horizontalRad = @@ -67,21 +67,17 @@ const Vector3 Vector3::back = Vector3(0, 0, -1); // return Vector3(v.x, 0, v.y); // } -float Vector3::Magnitude(const Vector3& v) { +float Vector3::Magnitude(const Vector3 &v) { return sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); } -float Vector3::magnitude() const { - return (float)sqrtf(x * x + y * y + z * z); -} +float Vector3::magnitude() const { return (float)sqrtf(x * x + y * y + z * z); } -float Vector3::SqrMagnitude(const Vector3& v) { +float Vector3::SqrMagnitude(const Vector3 &v) { return v.x * v.x + v.y * v.y + v.z * v.z; } -float Vector3::sqrMagnitude() const { - return (x * x + y * y + z * z); -} +float Vector3::sqrMagnitude() const { return (x * x + y * y + z * z); } -Vector3 Vector3::Normalize(const Vector3& v) { +Vector3 Vector3::Normalize(const Vector3 &v) { float num = Vector3::Magnitude(v); Vector3 result = Vector3::zero; if (num > epsilon) { @@ -102,26 +98,26 @@ Vector3 Vector3::operator-() const { return Vector3(-this->x, -this->y, -this->z); } -Vector3 Vector3::operator-(const Vector3& v) const { +Vector3 Vector3::operator-(const Vector3 &v) const { return Vector3(this->x - v.x, this->y - v.y, this->z - v.z); } -Vector3 Vector3::operator-=(const Vector3& v) { +Vector3 Vector3::operator-=(const Vector3 &v) { this->x -= v.x; this->y -= v.y; this->z -= v.z; return *this; } -Vector3 Vector3::operator+(const Vector3& v) const { +Vector3 Vector3::operator+(const Vector3 &v) const { return Vector3(this->x + v.x, this->y + v.y, this->z + v.z); } -Vector3 Vector3::operator+=(const Vector3& v) { +Vector3 Vector3::operator+=(const Vector3 &v) { this->x += v.x; this->y += v.y; this->z += v.z; return *this; } -Vector3 Vector3::Scale(const Vector3& v1, const Vector3& v2) { +Vector3 Vector3::Scale(const Vector3 &v1, const Vector3 &v2) { return Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z); } // Vector3 Passer::LinearAlgebra::operator*(const Vector3 &v, float f) { @@ -149,24 +145,24 @@ Vector3 Vector3::operator/=(float f) { return *this; } -float Vector3::Dot(const Vector3& v1, const Vector3& v2) { +float Vector3::Dot(const Vector3 &v1, const Vector3 &v2) { return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; } -bool Vector3::operator==(const Vector3& v) const { +bool Vector3::operator==(const Vector3 &v) const { return (this->x == v.x && this->y == v.y && this->z == v.z); } -float Vector3::Distance(const Vector3& v1, const Vector3& v2) { +float Vector3::Distance(const Vector3 &v1, const Vector3 &v2) { return Magnitude(v1 - v2); } -Vector3 Vector3::Cross(const Vector3& v1, const Vector3& v2) { +Vector3 Vector3::Cross(const Vector3 &v1, const Vector3 &v2) { return Vector3(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x); } -Vector3 Vector3::Project(const Vector3& v, const Vector3& n) { +Vector3 Vector3::Project(const Vector3 &v, const Vector3 &n) { float sqrMagnitude = Dot(n, n); if (sqrMagnitude < epsilon) return Vector3::zero; @@ -177,7 +173,7 @@ Vector3 Vector3::Project(const Vector3& v, const Vector3& n) { } } -Vector3 Vector3::ProjectOnPlane(const Vector3& v, const Vector3& n) { +Vector3 Vector3::ProjectOnPlane(const Vector3 &v, const Vector3 &n) { Vector3 r = v - Project(v, n); return r; } @@ -188,7 +184,7 @@ float clamp(float x, float lower, float upper) { return upperClamp; } -AngleOf Vector3::Angle(const Vector3& v1, const Vector3& v2) { +AngleOf Vector3::Angle(const Vector3 &v1, const Vector3 &v2) { float denominator = sqrtf(v1.sqrMagnitude() * v2.sqrMagnitude()); if (denominator < epsilon) return AngleOf(); @@ -197,16 +193,15 @@ AngleOf Vector3::Angle(const Vector3& v1, const Vector3& v2) { float fraction = dot / denominator; if (isnan(fraction)) return AngleOf::Degrees( - fraction); // short cut to returning NaN universally + fraction); // short cut to returning NaN universally float cdot = clamp(fraction, -1.0, 1.0); float r = ((float)acos(cdot)); return AngleOf::Radians(r); } -AngleOf Vector3::SignedAngle(const Vector3& v1, - const Vector3& v2, - const Vector3& axis) { +AngleOf Vector3::SignedAngle(const Vector3 &v1, const Vector3 &v2, + const Vector3 &axis) { // angle in [0,180] AngleOf angle = Vector3::Angle(v1, v2); @@ -220,7 +215,7 @@ AngleOf Vector3::SignedAngle(const Vector3& v1, return AngleOf(signed_angle); } -Vector3 Vector3::Lerp(const Vector3& v1, const Vector3& v2, float f) { +Vector3 Vector3::Lerp(const Vector3 &v1, const Vector3 &v2, float f) { Vector3 v = v1 + (v2 - v1) * f; return v; } diff --git a/test/Vector3_test.cc b/test/Vector3_test.cc index bd53b5a..82e57e9 100644 --- a/test/Vector3_test.cc +++ b/test/Vector3_test.cc @@ -1,7 +1,7 @@ #if GTEST #include -#include #include +#include #include "Vector3.h" @@ -9,7 +9,7 @@ TEST(Vector3, FromSpherical) { Vector3 v = Vector3(0, 0, 1); - Spherical s = Spherical::FromVector3(v); + SphericalOf s = SphericalOf::FromVector3(v); Vector3 r = Vector3(s); EXPECT_FLOAT_EQ(r.Right(), 0.0F) << "toVector3.x 0 0 1"; @@ -17,7 +17,7 @@ TEST(Vector3, FromSpherical) { EXPECT_FLOAT_EQ(r.Forward(), 1.0F) << "toVector3.z 0 0 1"; v = Vector3(0, 1, 0); - s = Spherical::FromVector3(v); + s = SphericalOf::FromVector3(v); r = Vector3(s); EXPECT_FLOAT_EQ(r.Right(), 0.0F) << "toVector3.x 0 1 0"; @@ -25,7 +25,7 @@ TEST(Vector3, FromSpherical) { EXPECT_NEAR(r.Forward(), 0.0F, 1.0e-06) << "toVector3.z 0 1 0"; v = Vector3(1, 0, 0); - s = Spherical::FromVector3(v); + s = SphericalOf::FromVector3(v); r = Vector3(s); EXPECT_FLOAT_EQ(r.Right(), 1.0F) << "toVector3.x 1 0 0";