37static const float PI = (float)M_PI;
38static const float HALF_PI = (float)M_PI_2;
40static const float EPSILON = std::numeric_limits<float>::epsilon();
63TEST_CASE(
"Test 01 Normalize",
"[quaternion][linear_algebra][math]" ) {
64 const Quat4f quat(0, 1, 2, 3);
70TEST_CASE(
"Test 02 Rotate Zero Vector",
"[quaternion][linear_algebra][math]" ) {
73 REQUIRE(
ZERO == rotVec0 );
76TEST_CASE(
"Test 03 Invert and Conugate",
"[quaternion][linear_algebra][math]" ) {
79 const Quat4f quat0(0, 1, 2, 3);
81 REQUIRE( quat0 == quat0Inv.
invert() );
85 const Quat4f quat0(-1, -2, -3, 4);
86 const Quat4f quat0Conj =
Quat4f( 1, 2, 3, 4).conjugate();
87 REQUIRE( quat0 == quat0Conj );
91TEST_CASE(
"Test 04 Dot",
"[quaternion][linear_algebra][math]" ) {
92 const Quat4f quat(7, 2, 5, -1);
93 REQUIRE( 35.0f == quat.
dot(3, 1, 2, -2));
94 REQUIRE( -11.0f == quat.
dot(
Quat4f(-1, 1, -1, 1)));
101TEST_CASE(
"Test 10 Angle Axis",
"[quaternion][linear_algebra][math]" ) {
105 REQUIRE( quat2 == quat1 );
107 REQUIRE( 1 - quat1.
magnitude() <= std::numeric_limits<float>::epsilon() );
111 REQUIRE( vecOut1 == vecOut2 );
122 REQUIRE( quat1 == quat2 );
124 quat1.
set(0, 0, 0, 0);
126 REQUIRE(0.0f == angle);
127 REQUIRE(
UNIT_X == vecOut1);
130TEST_CASE(
"Test 11 From Vec to Vec",
"[quaternion][linear_algebra][math]" ) {
137 REQUIRE( quat == quat2 );
140 REQUIRE( quat2 == quat );
144 REQUIRE_THAT(
std::abs(
NEG_UNIT_Z.
dist(vecOut) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
148 REQUIRE_THAT(
std::abs(
NEG_UNIT_X.
dist(vecOut) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
152 REQUIRE_THAT(
std::abs(
NEG_UNIT_Y.
dist(vecOut) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
156 REQUIRE_THAT(
std::abs(
NEG_ONE.
dist(vecOut) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
163TEST_CASE(
"Test 12 From and to Euler Angles",
"[quaternion][linear_algebra][math]" ) {
168 REQUIRE_THAT( quat.
magnitude(), Catch::Matchers::WithinAbs(1.0f,
EPSILON) );
171 REQUIRE( angles0Exp == angles0Has );
175 REQUIRE( quat == quat2 );
181 REQUIRE_THAT( quat.
magnitude(), Catch::Matchers::WithinAbs(1.0f,
EPSILON) );
184 REQUIRE( angles1Exp == angles1Has );
187 REQUIRE( quat == quat2 );
193 REQUIRE_THAT( quat.
magnitude(), Catch::Matchers::WithinAbs(1.0f,
EPSILON) );
196 REQUIRE( angles2Exp == angles2Has );
199 REQUIRE( quat == quat2 );
202TEST_CASE(
"Test 13 From Euler Angles and Rotate Vec",
"[quaternion][linear_algebra][math]" ) {
205 REQUIRE_THAT( quat.
magnitude(), Catch::Matchers::WithinAbs(1.0f,
EPSILON) );
211 REQUIRE_THAT( quat.
magnitude(), Catch::Matchers::WithinAbs(1.0f,
EPSILON) );
216 REQUIRE_THAT( quat.
magnitude(), Catch::Matchers::WithinAbs(1.0f,
EPSILON) );
221TEST_CASE(
"Test 14 Matrix",
"[matrix][quaternion][linear_algebra][math]" ) {
234 quat1.
set(0, 0, 0, 0);
237 REQUIRE( mat1 == mat2 );
246 0, std::cos(a), std::sin(a), 0,
247 0, -std::sin(a), std::cos(a), 0,
254 for(
int i=0; i<16; ++i) { REQUIRE_THAT( mat2_0[i], Catch::Matchers::WithinAbs(mat1_0[i],
EPSILON) ); }
262 REQUIRE( mat1 == mat2 );
264 REQUIRE( quat1 == quat2 );
270 REQUIRE( mat2 == mat2c );
271 REQUIRE( mat1 == mat2c );
274 REQUIRE_THAT(
std::abs(
UNIT_Z.
dist(vecHas) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
279 REQUIRE( quat1 == quat2 );
282 REQUIRE_THAT(
std::abs(
UNIT_Z.
dist(vecHas) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
285 REQUIRE( mat1 == mat2 );
291 REQUIRE_THAT(
std::abs( vecHas.
dist(vecOut3) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
292 REQUIRE( vecHas == vecOut3);
298 REQUIRE_THAT(
std::abs( vecHas.
dist(vecOut3) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
299 REQUIRE( vecHas == vecOut3);
309 0, std::cos(a), std::sin(a), 0,
310 0, -std::sin(a), std::cos(a), 0,
318 REQUIRE(mat1 == mat2);
320 REQUIRE_THAT(
std::abs(
NEG_UNIT_Y.
dist(vecHas) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
324 REQUIRE_THAT(
std::abs(
NEG_UNIT_Y.
dist(vecHas) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
327 REQUIRE(mat1 == mat2);
330 (mat2 *
ONE_v4).getVec3(vecOut3);
331 REQUIRE_THAT(
std::abs( vecHas.
dist(vecOut3) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
339 std::cos(a), 0, -std::sin(a), 0,
341 std::sin(a), 0, std::cos(a), 0,
349 REQUIRE(mat1 == mat2);
352 REQUIRE_THAT(
std::abs(
NEG_UNIT_X.
dist(vecHas) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
356 REQUIRE_THAT(
std::abs(
NEG_UNIT_X.
dist(vecHas) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
359 REQUIRE(mat1 == mat2);
363 REQUIRE_THAT(
std::abs( vecHas.
dist(vecOut3) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
371 std::cos(a), std::sin(a), 0, 0,
372 -std::sin(a), std::cos(a), 0, 0,
381 REQUIRE(mat1 == mat2);
383 REQUIRE_THAT(
std::abs(
NEG_UNIT_X.
dist(vecHas) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
387 REQUIRE_THAT(
std::abs(
NEG_UNIT_X.
dist(vecHas) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
390 REQUIRE(mat1 == mat2);
395 REQUIRE_THAT(
std::abs( vecHas.
dist(vecOut3) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
402 Vec3f vecExp0( std::cos(a), std::sin(a), 0);
403 Vec3f vecExp1(-std::sin(a), std::cos(a), 0);
404 Vec3f vecExp2( 0, 0, 1);
408 std::cos(a), std::sin(a), 0, 0,
409 -std::sin(a), std::cos(a), 0, 0,
415 REQUIRE(vecExp0 == vecCol);
416 REQUIRE_THAT(
std::abs( vecExp0.
dist(vecCol) ), Catch::Matchers::WithinAbs(0.0f,
EPSILON) );
419 REQUIRE(vecExp1 == vecCol);
420 REQUIRE_THAT(
std::abs( vecExp1.
dist(vecCol) ), Catch::Matchers::WithinAbs(0.0f,
EPSILON) );
423 REQUIRE(vecExp2 == vecCol);
424 REQUIRE_THAT(
std::abs( vecExp2.
dist(vecCol) ), Catch::Matchers::WithinAbs(0.0f,
EPSILON) );
427TEST_CASE(
"Test 15a Axes And Matrix",
"[matrix][quaternion][linear_algebra][math]" ) {
436 REQUIRE( matExp1 == matHas);
441 std::cout <<
"exp-euler " << eulerExp << std::endl;
442 std::cout <<
"has-euler " << eulerHas << std::endl;
443 REQUIRE(eulerExp == eulerHas);
445 REQUIRE(quat2 == quat1);
449 REQUIRE(quat2 == quat1);
452TEST_CASE(
"Test 15b Axes And Matrix",
"[matrix][quaternion][linear_algebra][math]" ) {
461 REQUIRE( matExp == matHas);
466 std::cout <<
"exp-euler " << eulerExp << std::endl;
467 std::cout <<
"has-euler " << eulerHas << std::endl;
468 REQUIRE(eulerExp == eulerHas);
470 REQUIRE(quat2 == quat1);
474 REQUIRE(quat2 == quat1);
477TEST_CASE(
"Test 15c Axes And Matrix",
"[matrix][quaternion][linear_algebra][math]" ) {
480 eulerExp1.
get(eulerExp0);
490 std::cout <<
"matExp " << matExp << std::endl;
491 std::cout <<
"matHas " << matHas << std::endl;
502 std::cout <<
"exp-euler " << eulerExp1 << std::endl;
503 std::cout <<
"has-euler " << eulerHas1 << std::endl;
504 std::cout <<
"diff-euler " << ( eulerExp1 - eulerHas1 ) << std::endl;
507 eulerHas1.
get(eulerHas0);
508 Vec3f eulerHas0v(eulerHas0), eulerExp0v(eulerExp0);
509 REQUIRE( eulerHas0v == eulerExp0v );
511 REQUIRE_THAT(
std::abs( eulerExp1.
dist(eulerHas1) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
512 REQUIRE(
true == eulerExp1.
equals(eulerHas1, Quat4f::allowed_deviation) );
514 REQUIRE(quat2 == quat1);
518 REQUIRE(quat2 == quat1);
525TEST_CASE(
"Test 20 Add Subtract",
"[quaternion][linear_algebra][math]" ) {
527 Quat4f quatExp(1, 2, 3, 4);
534 REQUIRE(quatExp == quatHas);
537 quatHas = quat1 + quat2;
538 REQUIRE(quatExp == quatHas);
542 Quat4f quatExp(-1, 0, 1, 2);
543 Quat4f quat1, quat2, quatHas;
544 quat1.
set(0, 1, 2, 3);
545 quat2.
set(1, 1, 1, 1);
550 REQUIRE(quatExp == quatHas);
553 quatHas = quat1 - quat2;
554 REQUIRE(quatExp == quatHas);
558TEST_CASE(
"Test 21 Multiply",
"[quaternion][linear_algebra][math]" ) {
561 Quat4f quatExp(1, 2, 4, 6);
562 Quat4f quat1(0.5f, 1, 2, 3);
568 REQUIRE(quatExp == quat2);
571 quat2 = quat1 * 2.0f;
572 REQUIRE(quatExp == quat2);
574 quat2 = 2.0f * quat1;
575 REQUIRE(quatExp == quat2);
591 REQUIRE_THAT(
std::abs(
UNIT_X.
dist(vecOut) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
595 quat2 = quat1 * quat1;
597 REQUIRE_THAT(
std::abs(
UNIT_X.
dist(vecOut) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
605 REQUIRE_THAT(
std::abs(
NEG_UNIT_Z.
dist(vecOut) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
609 quat1 = quat1 * quat1 * quat2;
611 REQUIRE_THAT(
std::abs(
NEG_UNIT_Z.
dist(vecOut) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
617 REQUIRE_THAT(
std::abs(
NEG_UNIT_X.
dist(vecOut) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
622TEST_CASE(
"Test 22 Invert-Mult-Normal-Conjugate",
"[quaternion][linear_algebra][math]" ) {
630 REQUIRE(quat0 == quat1);
636 quat2 = quat0 * quat1;
639 REQUIRE(quat0 == quat1);
642 quat0.
set(-1.0f, -2.0f, -3.0f, 4.0f);
643 quat1.
set( 1.0f, 2.0f, 3.0f, 4.0f);
646 REQUIRE(quat0 == quat2);
649TEST_CASE(
"Test 23 Rotation Order",
"[quaternion][linear_algebra][math]" ) {
653 REQUIRE(quat1 == quat2);
658 REQUIRE(quat1 == quat2);
663 REQUIRE(quat1 == quat2);
668 REQUIRE(quat1 == quat2);
686 REQUIRE_THAT( vecExp.
dist(vecRot), Catch::Matchers::WithinAbs(0.0f,
EPSILON) );
687 REQUIRE(vecExp == vecRot);
695 REQUIRE_THAT( vecExp.
dist(vecRot), Catch::Matchers::WithinAbs(0.0f,
EPSILON) );
696 REQUIRE(vecExp == vecRot);
703 REQUIRE_THAT( vecExp.
dist(vecRot), Catch::Matchers::WithinAbs(0.0f,
EPSILON) );
704 REQUIRE(vecExp == vecRot);
711 REQUIRE_THAT( vecExp.
dist(vecRot), Catch::Matchers::WithinAbs(0.0f,
EPSILON) );
712 REQUIRE(vecExp == vecRot);
716 REQUIRE(quat == worker);
719TEST_CASE(
"Test 24 Axes",
"[quaternion][linear_algebra][math]" ) {
723 Vec3f xAxis, yAxis, zAxis;
728 Quat4f quat1 =
Quat4f().setFromAxes(xAxis, yAxis, zAxis);
729 REQUIRE(quat0 == quat1);
731 REQUIRE(quat2 == quat1);
733 quat1.
toAxes(xAxis, yAxis, zAxis, rotMat);
735 REQUIRE(quat0 == quat2);
736 REQUIRE(quat1 == quat2);
739TEST_CASE(
"Test 25 Slerp",
"[quaternion][linear_algebra][math]" ) {
751 REQUIRE_THAT(
std::abs( vecExp.
dist(vecHas)), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
753 if( !vecExp.
equals(vecHas) ) {
754 std::cout <<
"Deviation: " << vecExp <<
", " << vecHas <<
": " << ( vecExp - vecHas ) <<
", dist " << vecExp.
dist(vecHas) << std::endl;
765 REQUIRE_THAT(
std::abs(
NEG_UNIT_X.
dist(vecHas)), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
774 REQUIRE_THAT(
std::abs(
UNIT_Y.
dist(vecHas)), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
776 std::cout <<
"Deviation: " <<
UNIT_Y <<
", " << vecHas <<
": " << (
UNIT_Y - vecHas ) <<
", dist " <<
UNIT_Y.
dist(vecHas) << std::endl;
787 REQUIRE_THAT(
std::abs(
UNIT_X.
dist(vecHas)), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
788 REQUIRE(
UNIT_X == vecHas);
793 quatS.
setSlerp(quat1, quat2, 0.25f);
797 REQUIRE_THAT(
std::abs(
UNIT_X.
dist(vecHas)), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
798 REQUIRE(
UNIT_X == vecHas);
809 REQUIRE_THAT(
std::abs( vecExp.
dist(vecHas)), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
810 if( !vecExp.
equals(vecHas) ) {
811 std::cout <<
"Deviation: " << vecExp <<
", " << vecHas <<
": " << ( vecExp - vecHas ) <<
", dist " << vecExp.
dist(vecHas) << std::endl;
816TEST_CASE(
"Test 26 LookAt",
"[quaternion][linear_algebra][math]" ) {
817 Vec3f xAxis, yAxis, zAxis, vecHas;
819 if(
DEBUG_MODE ) std::cout <<
"LookAt #01" << std::endl;
823 REQUIRE_THAT( direction.
dist( quat.
rotateVector(
UNIT_Z, vecHas) ), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
824 REQUIRE(direction == vecHas);
827 std::cout <<
"quat0 " << quat << std::endl;
828 std::cout <<
"exp0 " << direction <<
", len " << direction.
length() << std::endl;
829 std::cout <<
"has0 " << vecHas <<
", len " << vecHas.
length() << std::endl;
831 std::cout << std::endl <<
"LookAt #02" << std::endl;
833 (direction =
ONE).normalize();
836 std::cout <<
"direction " << direction << std::endl;
837 std::cout <<
"quat0.0 " << quat << std::endl;
841 std::cout <<
"quat0.1 " << quat << std::endl;
842 std::cout <<
"xAxis " << xAxis <<
", len " << xAxis.
length() << std::endl;
843 std::cout <<
"yAxis " << yAxis <<
", len " << yAxis.
length() << std::endl;
844 std::cout <<
"zAxis " << zAxis <<
", len " << zAxis.
length() << std::endl;
845 std::cout <<
"exp0 " << direction <<
", len " << direction.
length() << std::endl;
846 std::cout <<
"has0 " << vecHas <<
", len " << vecHas.
length() << std::endl;
849 REQUIRE_THAT( direction.
dist(vecHas), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
850 REQUIRE(direction == vecHas);
852 if(
DEBUG_MODE ) std::cout <<
"LookAt #03" << std::endl;
855 if(
DEBUG_MODE ) std::cout <<
"quat0 " << quat << std::endl;
858 std::cout <<
"xAxis " << xAxis <<
", len " << xAxis.
length() << std::endl;
859 std::cout <<
"yAxis " << yAxis <<
", len " << yAxis.
length() << std::endl;
860 std::cout <<
"zAxis " << zAxis <<
", len " << zAxis.
length() << std::endl;
861 std::cout <<
"exp0 " << direction <<
", len " << direction.
length() << std::endl;
862 std::cout <<
"has0 " << vecHas <<
", len " << vecHas.
length() << std::endl;
865 REQUIRE_THAT( direction.
dist(vecHas), Catch::Matchers::WithinAbs(0.0f, Quat4f::allowed_deviation) );
866 if( !direction.
equals(vecHas) ) {
867 std::cout <<
"Deviation: " << direction <<
", " << vecHas <<
": " << ( direction - vecHas ) <<
", dist " << direction.
dist(vecHas) << std::endl;
Basic 4x4 value_type matrix implementation using fields for intensive use-cases (host operations).
constexpr value_type get(const jau::nsize_t i) const noexcept
Returns the ith component of the given column-major order matrix, 0 <= i < 16, w/o boundary check.
constexpr Vec3 & mulVec3(const Vec3 &v_in, Vec3 &v_out) const noexcept
Affine 3f-vector transformation by 4x4 matrix.
constexpr bool equals(const Matrix4 &o, const value_type epsilon=std::numeric_limits< value_type >::epsilon()) const noexcept
constexpr Vec4 & getColumn(const jau::nsize_t column, Vec4 &v_out) const noexcept
Get the named column of the given column-major matrix to v_out w/o boundary check.
constexpr Matrix4 & loadIdentity() noexcept
Set this matrix to identity.
constexpr_cxx26 Matrix4 & setToRotationEuler(const value_type bankX, const value_type headingY, const value_type attitudeZ) noexcept
Set this matrix to rotation from the given Euler rotation angles in radians.
constexpr Matrix4 & load(const_iterator src) noexcept
Load the values of the given matrix src to this matrix w/o boundary check.
Quaternion implementation supporting Gimbal-Lock free rotations.
constexpr_cxx26 Quaternion & rotateByAngleX(const value_type angle) noexcept
Rotate this quaternion around X axis with the given angle in radians.
Vec3 rotateVector(const Vec3 &in) noexcept
constexpr Quaternion & set(const value_type x, const value_type y, const value_type z, const value_type w) noexcept
Set all values of this quaternion using the given components.
constexpr Quaternion & conjugate() noexcept
Conjugates this quaternion [-x, -y, -z, w].
constexpr void toAxes(Vec3 &xAxis, Vec3 &yAxis, Vec3 &zAxis, Matrix4< value_type > &tmp) const noexcept
Extracts this quaternion's orthogonal rotation axes.
constexpr_cxx26 Quaternion & setFromEuler(const Vec3 &angradXYZ) noexcept
Initializes this quaternion from the given Euler rotation array angradXYZ in radians.
constexpr_cxx26 Quaternion & setFromNormalVectors(const Vec3 &v1, const Vec3 &v2) noexcept
Initialize this quaternion from two normalized vectors.
constexpr_cxx26 Quaternion & rotateByAngleNormalAxis(const value_type angle, const value_type axisX, const value_type axisY, const value_type axisZ) noexcept
Rotate this quaternion by the given angle and axis.
constexpr value_type dot(value_type x, value_type y, value_type z, value_type w) const noexcept
Returns the dot product of this quaternion with the given x,y,z and m_w components.
constexpr Quaternion & invert() noexcept
Invert the quaternion If rotational, will produce a the inverse rotation.
constexpr_cxx26 Vec3 toEuler() noexcept
Transform this quaternion to Euler rotation angles in radians (pitchX, yawY and rollZ).
constexpr_cxx26 value_type magnitude() const noexcept
Return the magnitude of this quaternion, i.e.
constexpr Mat4f toMatrix() const noexcept
Transform this quaternion to a normalized 4x4 column matrix representing the rotation.
constexpr Quaternion & setIdentity() noexcept
Quaternion & setLookAt(const Vec3 &directionIn, const Vec3 &upIn, Vec3 &xAxisOut, Vec3 &yAxisOut, Vec3 &zAxisOut) noexcept
Set this quaternion to equal the rotation required to point the z-axis at direction and the y-axis to...
constexpr_cxx26 Quaternion & setFromAngleNormalAxis(const value_type angle, const Vec3 &vector) noexcept
Quaternion & setFromAngleAxis(const value_type angle, const Vec3 &vector) noexcept
constexpr Quaternion & setFromAxes(const Vec3 &xAxis, const Vec3 &yAxis, const Vec3 &zAxis) noexcept
Initializes this quaternion to represent a rotation formed by the given three orthogonal axes.
constexpr_cxx26 value_type toAngleAxis(Vec3 &axis) const noexcept
Transform the rotational quaternion to axis based rotation angles.
constexpr_cxx26 Quaternion & setFromVectors(const Vec3 &v1, const Vec3 &v2) noexcept
Initialize this quaternion from two vectors.
constexpr Quaternion & setFromMat(const value_type m00, const value_type m01, const value_type m02, const value_type m10, const value_type m11, const value_type m12, const value_type m20, const value_type m21, const value_type m22) noexcept
Compute the quaternion from a 3x3 column rotation matrix.
constexpr_cxx26 Quaternion & setSlerp(const Quaternion &a, const Quaternion &b, const value_type changeAmnt) noexcept
Set this quaternion to a spherical linear interpolation between the given start and end quaternions b...
constexpr_cxx26 Quaternion & rotateByAngleZ(value_type angle) noexcept
Rotate this quaternion around Z axis with the given angle in radians.
constexpr_cxx26 Quaternion & rotateByAngleY(value_type angle) noexcept
Rotate this quaternion around Y axis with the given angle in radians.
constexpr Vector3F & set(const Vec2f &o, const value_type z_) noexcept
TODO constexpr bool operator<=>(const vec3f_t& rhs ) const noexcept { return ... }.
constexpr Vector3F & normalize() noexcept
Normalize this vector in place.
constexpr iterator get(iterator xyz) const noexcept
xyz = this, returns xyz.
constexpr value_type length() const noexcept
Return the length of a vector, a.k.a the norm or magnitude
constexpr value_type dist(const Vector3F &o) const noexcept
Return the distance between this vector and the given one.
constexpr bool equals(const Vector3F &o, const value_type epsilon=std::numeric_limits< value_type >::epsilon()) const noexcept
4D vector using four value_type components.
std::enable_if< std::is_floating_point_v< T >, bool >::type constexpr equals(const T &a, const T &b, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if both values are equal, i.e.
constexpr T abs(const T x) noexcept
Returns the absolute value of an arithmetic number (w/ branching) in O(1)
constexpr Vector3F< T > to_vec3(const Vector4F< T > &v) noexcept
out = { this.x, this.y, this.z } dropping w, returns out.
Quaternion< float > Quat4f
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
static const float HALF_PI
static constexpr const bool DEBUG_MODE
static const Vec4f ONE_v4
static const Quat4f QUAT_IDENT
static const Vec3f UNIT_Y
static const Vec3f NEG_UNIT_X
static const Vec3f NEG_UNIT_Y
static const float QUARTER_PI
static const Vec3f NEG_ONE
static const Vec3f NEG_UNIT_Z
static const Vec3f UNIT_X
static const float EPSILON
static const Vec4f NEG_ONE_v4
static const Vec3f UNIT_Z
TEST_CASE("Test 01 Normalize", "[quaternion][linear_algebra][math]")
int printf(const char *format,...)
Operating Systems predefined macros.