Test quaternion interpolation.
#include <visp3/core/vpConfig.h>
#if defined(VISP_HAVE_CATCH2)
#include <visp3/core/vpQuaternionVector.h>
#include <catch_amalgamated.hpp>
#ifdef ENABLE_VISP_NAMESPACE
#endif
TEST_CASE("Quaternion interpolation", "[quaternion]")
{
const double t = 0.5;
const double ref_angle_middle = t * (angle0 + angle1);
const double margin = 1e-3;
const double marginLerp = 1e-1;
SECTION("LERP")
{
CHECK(
vpThetaUVector(qLerp).getTheta() == Catch::Approx(ref_angle_middle).margin(marginLerp));
}
SECTION("NLERP")
{
CHECK(
vpThetaUVector(qNlerp).getTheta() == Catch::Approx(ref_angle_middle).margin(margin));
}
SECTION("SERP")
{
CHECK(
vpThetaUVector(qSlerp).getTheta() == Catch::Approx(ref_angle_middle).margin(margin));
}
}
TEST_CASE("Quaternion operators", "[quaternion]")
{
SECTION("Addition and subtraction")
{
const double margin = std::numeric_limits<double>::epsilon();
std::cout << "q3=" << q3 << std::endl;
CHECK(q3.
x() == Catch::Approx(2.6).margin(margin));
CHECK(q3.
y() == Catch::Approx(0.4).margin(margin));
CHECK(q3.
z() == Catch::Approx(-3.0).margin(margin));
CHECK(q3.
w() == Catch::Approx(4.0).margin(margin));
std::cout << "q4=" << q4 << std::endl;
CHECK(q4.
x() == Catch::Approx(q2.x()).margin(margin));
CHECK(q4.
y() == Catch::Approx(q2.y()).margin(margin));
CHECK(q4.
z() == Catch::Approx(q2.z()).margin(margin));
CHECK(q4.
w() == Catch::Approx(q2.w()).margin(margin));
}
SECTION("Multiplication")
{
const double margin = std::numeric_limits<double>::epsilon() * 1e4;
CHECK(q3.
x() == Catch::Approx(3.0).margin(margin));
CHECK(q3.
y() == Catch::Approx(36.7).margin(margin));
CHECK(q3.
z() == Catch::Approx(-6.6).margin(margin));
CHECK(q3.
w() == Catch::Approx(1.3).margin(margin));
}
SECTION("Conjugate")
{
const double margin = std::numeric_limits<double>::epsilon();
CHECK(q1_conj.
x() == Catch::Approx(-q1.x()).margin(margin));
CHECK(q1_conj.
y() == Catch::Approx(-q1.y()).margin(margin));
CHECK(q1_conj.
z() == Catch::Approx(-q1.z()).margin(margin));
CHECK(q1_conj.
w() == Catch::Approx(q1.w()).margin(margin));
}
SECTION("Inverse")
{
const double margin = 1e-6;
CHECK(q1_inv.
x() == Catch::Approx(-0.00214111).margin(margin));
CHECK(q1_inv.
y() == Catch::Approx(-0.026193).margin(margin));
CHECK(q1_inv.
z() == Catch::Approx(0.00471045).margin(margin));
CHECK(q1_inv.
w() == Catch::Approx(0.000927816).margin(margin));
}
SECTION("Norm")
{
const double norm = q1.magnitude();
CHECK(norm == Catch::Approx(37.4318).margin(1e-4));
}
SECTION("Normalization")
{
q1.normalize();
const double margin = 1e-6;
const double norm = q1.magnitude();
CHECK(norm == Catch::Approx(1.0).margin(1e-4));
CHECK(q1.x() == Catch::Approx(0.0801457).margin(margin));
CHECK(q1.y() == Catch::Approx(0.98045).margin(margin));
CHECK(q1.z() == Catch::Approx(-0.176321).margin(margin));
CHECK(q1.w() == Catch::Approx(0.0347298).margin(margin));
}
SECTION("Copy constructor")
{
std::cout << "q_copy1=" << q_copy1 << std::endl;
q_copy1.
set(1, 0, 1, 10);
std::cout << "q_copy1 after set = " << q_copy1 << std::endl;
std::cout << "q_copy2=" << q_copy2 << std::endl;
}
SECTION("operator=")
{
q_same = q1;
CHECK(q_same.data != q1.
data);
}
}
int main(int argc, char *argv[])
{
Catch::Session session;
session.applyCommandLine(argc, argv);
int numFailed = session.run();
return numFailed;
}
#else
#include <iostream>
int main() { return EXIT_SUCCESS; }
#endif
Type * data
Address of the first element of the data array.
Implementation of column vector and the associated operations.
vpColVector & normalize()
static double rad(double deg)
static bool equal(double x, double y, double threshold=0.001)
Implementation of a rotation vector as quaternion angle minimal representation.
const double & z() const
Returns the z-component of the quaternion.
vpQuaternionVector conjugate() const
vpQuaternionVector inverse() const
void set(double x, double y, double z, double w)
static vpQuaternionVector slerp(const vpQuaternionVector &q0, const vpQuaternionVector &q1, double t)
static vpQuaternionVector nlerp(const vpQuaternionVector &q0, const vpQuaternionVector &q1, double t)
const double & x() const
Returns the x-component of the quaternion.
const double & y() const
Returns the y-component of the quaternion.
const double & w() const
Returns the w-component of the quaternion.
static vpQuaternionVector lerp(const vpQuaternionVector &q0, const vpQuaternionVector &q1, double t)
Implementation of a rotation vector as axis-angle minimal representation.