From 11259a92a6a802b090679bfb951d09acaa01910e Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Fri, 20 Sep 2024 12:29:47 +0200 Subject: [PATCH] Extend functionality --- Direction.cpp | 6 +++ Direction.h | 1 + Spherical.cpp | 29 +++++++++---- Spherical.h | 3 ++ SwingTwist.cpp | 109 +++++++++++++++++++++++++++++++++++++++++++++++++ SwingTwist.h | 69 +++++++++++++++++++++++++++++++ 6 files changed, 210 insertions(+), 7 deletions(-) create mode 100644 SwingTwist.cpp create mode 100644 SwingTwist.h diff --git a/Direction.cpp b/Direction.cpp index dac8e50..ae5b503 100644 --- a/Direction.cpp +++ b/Direction.cpp @@ -41,6 +41,12 @@ const DirectionOf DirectionOf::left = DirectionOf(-90.0f, 0.0f); template const DirectionOf DirectionOf::right = DirectionOf(90.0f, 0.0f); +template +DirectionOf Passer::LinearAlgebra::DirectionOf::operator-() const { + DirectionOf r = DirectionOf(-this->horizontal, -this->vertical); + return r; +} + template DirectionOf Passer::LinearAlgebra::DirectionOf::operator+( const DirectionOf& v) const { diff --git a/Direction.h b/Direction.h index 348f4d7..96d5bac 100644 --- a/Direction.h +++ b/Direction.h @@ -29,6 +29,7 @@ class DirectionOf { const static DirectionOf left; const static DirectionOf right; + DirectionOf operator-() const; DirectionOf operator+(const DirectionOf& v) const; DirectionOf operator+=(const DirectionOf& v); diff --git a/Spherical.cpp b/Spherical.cpp index 9552373..a6c74cc 100644 --- a/Spherical.cpp +++ b/Spherical.cpp @@ -70,10 +70,9 @@ SphericalOf SphericalOf::FromVector3(Vector3 v) { template Vector3 SphericalOf::ToVector3() const { - float verticalRad = - (90.0f - this->vertical.ToFloat()) * Passer::LinearAlgebra::Deg2Rad; - float horizontalRad = - this->horizontal.ToFloat() * Passer::LinearAlgebra::Deg2Rad; + float verticalRad = (pi / 2) - this->vertical.InRadians(); + float horizontalRad = this->horizontal.InRadians(); + float cosVertical = cosf(verticalRad); float sinVertical = sinf(verticalRad); float cosHorizontal = cosf(horizontalRad); @@ -217,8 +216,12 @@ const float epsilon = 1E-05f; template float SphericalOf::DistanceBetween(const SphericalOf& v1, const SphericalOf& v2) { - SphericalOf difference = v1 - v2; - return difference.distance; + // SphericalOf difference = v1 - v2; + // return difference.distance; + Vector3 vec1 = v1.ToVector3(); + Vector3 vec2 = v2.ToVector3(); + float distance = Vector3::Distance(vec1, vec2); + return distance; } template @@ -238,7 +241,19 @@ AngleOf SphericalOf::AngleBetween(const SphericalOf& v1, // float cdot = Float::Clamp(fraction, -1.0, 1.0); // float r = ((float)acos(cdot)) * Rad2Deg; Angle r = Vector3::Angle(v1_3, v2_3); - return AngleOf(r.ToFloat()); + return AngleOf::Degrees(r.InDegrees()); +} + +template +AngleOf Passer::LinearAlgebra::SphericalOf::SignedAngleBetween( + const SphericalOf& v1, + const SphericalOf& v2, + const SphericalOf& axis) { + Vector3 v1_vector = v1.ToVector3(); + Vector3 v2_vector = v2.ToVector3(); + Vector3 axis_vector = axis.ToVector3(); + Angle r = Vector3::SignedAngle(v1_vector, v2_vector, axis_vector); + return AngleOf::Degrees(r.InDegrees()); } template diff --git a/Spherical.h b/Spherical.h index 159520a..89480e2 100644 --- a/Spherical.h +++ b/Spherical.h @@ -109,6 +109,9 @@ class SphericalOf { 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, diff --git a/SwingTwist.cpp b/SwingTwist.cpp new file mode 100644 index 0000000..7899631 --- /dev/null +++ b/SwingTwist.cpp @@ -0,0 +1,109 @@ +// 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 "SwingTwist.h" + +template +SwingTwistOf::SwingTwistOf() { + // this->horizontal = AngleOf(0); + // this->vertical = AngleOf(0); + this->swing = DirectionOf(0, 0); + this->twist = AngleOf(0); +} + +template +Passer::LinearAlgebra::SwingTwistOf::SwingTwistOf(DirectionOf swing, + AngleOf twist) { + this->swing = swing; + this->twist = twist; +} + +template +SwingTwistOf::SwingTwistOf(AngleOf horizontal, + AngleOf vertical, + AngleOf twist) { + // this->horizontal = horizontal; + // this->vertical = vertical; + this->swing = DirectionOf(horizontal, vertical); + this->twist = twist; +} + +template +SwingTwistOf SwingTwistOf::Degrees(float horizontal, + float vertical, + float twist) { + DirectionOf swing = DirectionOf(AngleOf::Degrees(horizontal), + AngleOf::Degrees(vertical)); + AngleOf twistAngle = AngleOf::Degrees(twist); + SwingTwistOf orientation = SwingTwistOf(swing, twistAngle); + return orientation; +} + +template +Quaternion SwingTwistOf::ToQuaternion() { + Quaternion q = Quaternion::Euler(this->swing.vertical.ToFloat(), + this->swing.horizontal.ToFloat(), + this->twist.ToFloat()); + return q; +} + +template +SwingTwistOf Passer::LinearAlgebra::SwingTwistOf::FromQuaternion( + Quaternion q) { + Vector3 angles = Quaternion::ToAngles(q); + SwingTwistOf r = + SwingTwistOf(angles.Up(), angles.Right(), angles.Forward()); + + return r; +} + +template +const SwingTwistOf SwingTwistOf::identity = SwingTwistOf(); + +template +SphericalOf SwingTwistOf::operator*(const SphericalOf& vector) const { + SphericalOf v = SphericalOf(vector.distance, + vector.horizontal + this->swing.horizontal, + vector.vertical + this->swing.vertical); + return v; +} + +template +SwingTwistOf SwingTwistOf::operator*( + const SwingTwistOf& rotation) const { + SwingTwistOf r = + SwingTwistOf(this->swing.horizontal + rotation.swing.horizontal, + this->swing.vertical + rotation.swing.vertical, + this->twist + rotation.twist); + return r; +} + +template +SwingTwistOf SwingTwistOf::operator*=(const SwingTwistOf& rotation) { + // this->swing.horizontal += rotation.swing.horizontal; + // this->swing.vertical += rotation.swing.vertical; + this->swing += rotation.swing; + this->twist += rotation.twist; + return *this; +} + +template +SwingTwistOf Passer::LinearAlgebra::SwingTwistOf::Inverse( + SwingTwistOf rotation) { + SwingTwistOf r = SwingTwistOf(-rotation.swing, -rotation.twist); + return r; +} + +template +SwingTwistOf Passer::LinearAlgebra::SwingTwistOf::AngleAxis( + float angle, + const SphericalOf& axis) { + Vector3 axis_vector = axis.ToVector3(); + Quaternion q = Quaternion::AngleAxis(angle, axis_vector); + SwingTwistOf r = SwingTwistOf::FromQuaternion(q); + return r; +} + +template class SwingTwistOf; +template class SwingTwistOf; \ No newline at end of file diff --git a/SwingTwist.h b/SwingTwist.h new file mode 100644 index 0000000..6258ced --- /dev/null +++ b/SwingTwist.h @@ -0,0 +1,69 @@ +// 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 SWINGTWIST_H +#define SWINGTWIST_H + +#include "RoboidControlCore/LinearAlgebra/Angle.h" +#include "RoboidControlCore/LinearAlgebra/Direction.h" +#include "RoboidControlCore/LinearAlgebra/Quaternion.h" +#include "RoboidControlCore/LinearAlgebra/Spherical.h" +// #include "RoboidControlCore/LinearAlgebra/Spherical16.h" + +namespace Passer { +namespace LinearAlgebra { + +template +class SwingTwistOf { + public: + DirectionOf swing; + AngleOf twist; + + SwingTwistOf(); + SwingTwistOf(DirectionOf swing, AngleOf twist); + SwingTwistOf(AngleOf horizontal, AngleOf vertical, AngleOf twist); + + static SwingTwistOf Degrees(float horizontal, + float vertical = 0, + float twist = 0); + Quaternion ToQuaternion(); + static SwingTwistOf FromQuaternion(Quaternion q); + + const static SwingTwistOf identity; + + /// + /// Rotate a vector using this rotation + /// + /// The vector to rotate + /// The rotated vector + SphericalOf operator*(const SphericalOf& vector) const; + /// + /// Multiply this rotation with another rotation + /// + /// The swing/twist rotation to multiply with + /// The resulting swing/twist rotation + /// The result will be this rotation rotated according to + /// the give rotation. + SwingTwistOf operator*(const SwingTwistOf& rotation) const; + SwingTwistOf operator*=(const SwingTwistOf& rotation); + + static SwingTwistOf Inverse(SwingTwistOf rotation); + + /// + /// Convert an angle/axis representation to a swingt + /// + /// The angle + /// The axis + /// The resulting quaternion + static SwingTwistOf AngleAxis(float angle, const SphericalOf& axis); +}; + +using SwingTwistSingle = SwingTwistOf; +using SwingTwist16 = SwingTwistOf; + +} // namespace LinearAlgebra +} // namespace Passer +using namespace Passer::LinearAlgebra; + +#endif