Fixed quaternion multiplication
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
#include "Quaternion.h"
|
#include "Quaternion.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
float Quaternion::operator[](uint8_t index)
|
float Quaternion::operator[](uint8_t index) const
|
||||||
{
|
{
|
||||||
if (index < 4)
|
if (index < 4)
|
||||||
{
|
{
|
||||||
@@ -12,24 +12,36 @@ float Quaternion::operator[](uint8_t index)
|
|||||||
return 1e+6;
|
return 1e+6;
|
||||||
}
|
}
|
||||||
|
|
||||||
Quaternion Quaternion::operator+(const Quaternion &other)
|
Quaternion Quaternion::operator+(const Quaternion &other) const
|
||||||
{
|
{
|
||||||
return Quaternion{this->v1 * other.v1, this->v2 * other.v2, this->v3 * other.v3, this->w * other.w};
|
return Quaternion{this->v1 * other.v1, this->v2 * other.v2, this->v3 * other.v3, this->w * other.w};
|
||||||
}
|
}
|
||||||
|
|
||||||
Quaternion &
|
Quaternion &
|
||||||
Quaternion::Rotate(Quaternion &other, Quaternion &buffer)
|
Quaternion::Q_Mult(Quaternion &other, Quaternion &buffer) const
|
||||||
{
|
{
|
||||||
|
|
||||||
// eq. 6
|
// eq. 6
|
||||||
buffer.v1 = this->w * other.v1 + other.w * this->v1 - this->v2 * other.v3 + this->v3 * other.v2;
|
buffer.w = (other.w * this->w - other.v1 * this->v1 - other.v2 * this->v2 - other.v3 * this->v3);
|
||||||
buffer.v2 = this->w * other.v2 + other.w * this->v2 - this->v3 * other.v1 + this->v1 * other.v3;
|
buffer.v1 = (other.w * this->v1 + other.v1 * this->w - other.v2 * this->v3 + other.v3 * this->v2);
|
||||||
buffer.v3 = this->w * other.v3 + other.w * this->v3 - this->v1 * other.v2 + this->v2 * other.v1;
|
buffer.v2 = (other.w * this->v2 + other.v1 * this->v3 + other.v2 * this->w - other.v3 * this->v1);
|
||||||
buffer.w = this->w * other.w - this->v1 * other.v1 - this->v2 * other.v2 - this->v3 * other.v3;
|
buffer.v3 = (other.w * this->v3 - other.v1 * this->v2 + other.v2 * this->v1 + other.v3 * this->w);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion &Quaternion::Rotate(Quaternion &other, Quaternion &buffer) const
|
||||||
|
{
|
||||||
|
Quaternion prime{-this->v1, -this->v2, -this->v3, this->w};
|
||||||
|
static_cast<Matrix<1, 4>>(buffer) = static_cast<Matrix<1, 4>>(other);
|
||||||
|
buffer.w = 0;
|
||||||
|
Quaternion temp{};
|
||||||
|
this->Q_Mult(buffer, temp);
|
||||||
|
temp.Q_Mult(prime, buffer);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix<1, 3> &
|
Matrix<1, 3> &
|
||||||
Quaternion::ToEulerAngles(Matrix<1, 3> &angleBuffer)
|
Quaternion::ToEulerAngles(Matrix<1, 3> &angleBuffer) const
|
||||||
{
|
{
|
||||||
// from https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
|
// from https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
|
||||||
// rotation sequence R = Rx * Ry * Rz
|
// rotation sequence R = Rx * Ry * Rz
|
||||||
@@ -53,7 +65,7 @@ Quaternion::ToEulerAngles(Matrix<1, 3> &angleBuffer)
|
|||||||
return angleBuffer;
|
return angleBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix<3, 3> &Quaternion::ToRotationMatrix(Matrix<3, 3> &rotationMatrixBuffer)
|
Matrix<3, 3> &Quaternion::ToRotationMatrix(Matrix<3, 3> &rotationMatrixBuffer) const
|
||||||
{
|
{
|
||||||
// eq. 4
|
// eq. 4
|
||||||
// from https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm
|
// from https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm
|
||||||
|
|||||||
@@ -18,44 +18,50 @@ public:
|
|||||||
* @param index The index of the element to access
|
* @param index The index of the element to access
|
||||||
* @return The value of the element at the index
|
* @return The value of the element at the index
|
||||||
*/
|
*/
|
||||||
float operator[](uint8_t index);
|
float operator[](uint8_t index) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add two quaternions together
|
* @brief Add two quaternions together
|
||||||
* @param other The quaternion to add to this one
|
* @param other The quaternion to add to this one
|
||||||
* @return The net quaternion
|
* @return The net quaternion
|
||||||
*/
|
*/
|
||||||
Quaternion operator+(const Quaternion &other);
|
Quaternion operator+(const Quaternion &other) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Rotate a quaternion by another quaternion
|
* @brief Q_Mult a quaternion by another quaternion
|
||||||
* @param other The quaternion to rotate by
|
* @param other The quaternion to rotate by
|
||||||
* @param buffer The buffer to store the result in
|
* @param buffer The buffer to store the result in
|
||||||
* @return A reference to the buffer
|
* @return A reference to the buffer
|
||||||
*/
|
*/
|
||||||
Quaternion &Rotate(Quaternion &other, Quaternion &buffer);
|
Quaternion &Q_Mult(Quaternion &other, Quaternion &buffer) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Rotate a quaternion by another quaternion
|
||||||
|
* @param other The quaternion to rotate
|
||||||
|
* @param buffer The buffer to store the result in
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Quaternion &Rotate(Quaternion &other, Quaternion &buffer) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calculate the Euler angles from the quaternion
|
* @brief Calculate the Euler angles from the quaternion
|
||||||
* @param angleBuffer The buffer to store the angles in
|
* @param angleBuffer The buffer to store the angles in
|
||||||
* @return A reference to the buffer
|
* @return A reference to the buffer
|
||||||
*/
|
*/
|
||||||
Matrix<1, 3> &ToEulerAngles(Matrix<1, 3> &angleBuffer);
|
Matrix<1, 3> &ToEulerAngles(Matrix<1, 3> &angleBuffer) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convert the quaternion to a rotation matrix
|
* @brief Convert the quaternion to a rotation matrix
|
||||||
* @param rotationMatrixBuffer The buffer to store the rotation matrix in
|
* @param rotationMatrixBuffer The buffer to store the rotation matrix in
|
||||||
* @return A reference to the buffer
|
* @return A reference to the buffer
|
||||||
*/
|
*/
|
||||||
Matrix<3, 3> &ToRotationMatrix(Matrix<3, 3> &rotationMatrixBuffer);
|
Matrix<3, 3> &ToRotationMatrix(Matrix<3, 3> &rotationMatrixBuffer) const;
|
||||||
|
|
||||||
// Give people an easy way to access the elements
|
// Give people an easy way to access the elements
|
||||||
float &v1{matrix[0]};
|
float &v1{matrix[0]};
|
||||||
float &v2{matrix[1]};
|
float &v2{matrix[1]};
|
||||||
float &v3{matrix[2]};
|
float &v3{matrix[2]};
|
||||||
float &w{matrix[3]};
|
float &w{matrix[3]};
|
||||||
|
|
||||||
private:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QUATERNION_H_
|
#endif // QUATERNION_H_
|
||||||
@@ -73,8 +73,8 @@ TEST_CASE("Vector Math", "Vector")
|
|||||||
SECTION("Rotation")
|
SECTION("Rotation")
|
||||||
{
|
{
|
||||||
Quaternion q3;
|
Quaternion q3;
|
||||||
q1.Rotate(q2, q3);
|
q1.Q_Mult(q2, q3);
|
||||||
REQUIRE(q3.v1 == -24);
|
REQUIRE(q3.v1 == 24);
|
||||||
REQUIRE(q3.v2 == 48);
|
REQUIRE(q3.v2 == 48);
|
||||||
REQUIRE(q3.v3 == 48);
|
REQUIRE(q3.v3 == 48);
|
||||||
REQUIRE(q3.w == -6);
|
REQUIRE(q3.w == -6);
|
||||||
|
|||||||
Reference in New Issue
Block a user