void test_basic_quaternion_multiply(void) {
    Quaternion q = { 1, 0, 0, 0 };
    Quaternion r = { 1, 0, 0, 0 };
    Quaternion t;
    Vector3F eulers;

    QuaternionMultiply(&q, &r, &t);
    QuaternionPrint(&t);
    assert(t.a == 1);
    assert(t.b == 0);
    assert(t.c == 0);
    assert(t.d == 0);

    q.a = 0.707107;
    q.b = 0.707107;
    QuaternionMultiply(&q, &r, &t);
    QuaternionPrint(&t);
    QuaternionToEulers(&t, &eulers);
    assert(NearEqual(eulers.a, PI_DIV_2, 0.001));
    assert(eulers.b == 0);
    assert(eulers.c == 0);

    QuaternionMultiply(&q, &q, &t);
    QuaternionPrint(&t);
    QuaternionToEulers(&t, &eulers);
    assert(NearEqual(eulers.a, PI, 0.001));
    assert(eulers.b == 0);
    assert(eulers.c == 0);
}
void test_basic_quaternion_from_eulers(void) {
    Quaternion q = { 0, 0, 0, 0 };

    Vector3F eulers = { 0, 0, 0 };
    QuaternionFromEulers(&eulers, &q);
    QuaternionPrint(&q);
    Vector4F res = { 1, 0, 0, 0 };
    assert(Vector4FEqual(&res, &q));

    eulers.a = PI;
    QuaternionFromEulers(&eulers, &q);
    QuaternionPrint(&q);
    assert(NearEqual(q.a, 0, .0001));
    assert(NearEqual(q.b, 1, .0001));
    assert(NearEqual(q.c, 0, .0001));
    assert(NearEqual(q.d, 0, .0001));

    eulers.a = PI_DIV_2;
    QuaternionFromEulers(&eulers, &q);
    QuaternionPrint(&q);
    assert(NearEqual(q.a, 0.70, 0.01));
    assert(NearEqual(q.b, 0.70, 0.01));
    assert(q.c == 0);
    assert(q.d == 0);

    eulers.a = 0;
    eulers.b = PI_DIV_2;
    QuaternionFromEulers(&eulers, &q);
    QuaternionPrint(&q);
    assert(NearEqual(q.a, 0.70, 0.01));
    assert(q.b == 0);
    assert(NearEqual(q.c, 0.70, 0.01));
    assert(q.d == 0);

    eulers.b = 0;
    eulers.c = PI_DIV_2;
    QuaternionFromEulers(&eulers, &q);
    QuaternionPrint(&q);
    assert(NearEqual(q.a, 0.70, 0.01));
    assert(q.b == 0);
    assert(q.c == 0);
    assert(NearEqual(q.d, 0.70, 0.01));
}
Example #3
0
/***
 * PURPOSE: Math test
 *  AUTHOR: Eliseev Dmitry
 ***/
VEVOID TestMath( VEVOID )
{
  VEVECTOR3D   i  = VEVector3D(1.0, 0.0, 0.0);
  VEVECTOR3D   j  = VEVector3D(0.0, 1.0, 0.0);
  VEVECTOR3D   k  = VEVector3D(0.0, 0.0, 1.0);
  VEQUATERNION q1 = VEQuaternion(i, M_PI_2);
  VEQUATERNION q2 = VEQuaternion(j, M_PI_2);
  VEQUATERNION q3 = VEQuaternion(k, M_PI_2);

  VEVECTOR3D   v  = VEVector3D(0.1, 0.3, 0.6);
  VEQUATERNION q  = VEQuaternion(v, M_PI_2);

  printf("i = [%.2lf, %.2lf, %.2lf]\n", i.m_X, i.m_Y, i.m_Z);
  printf("j = [%.2lf, %.2lf, %.2lf]\n", j.m_X, j.m_Y, j.m_Z);
  printf("k = [%.2lf, %.2lf, %.2lf]\n", k.m_X, k.m_Y, k.m_Z);
  printf("v = [%.2lf, %.2lf, %.2lf]\n", v.m_X, v.m_Y, v.m_Z);
  printf("\n");

  printf("   q1 = "); QuaternionPrint(q1);
  printf("   q2 = "); QuaternionPrint(q2);
  printf("   q3 = "); QuaternionPrint(q3);
  printf("    q = "); QuaternionPrint(q);
  printf("\n");

  { /* Vectors multiplication */
    VEVECTOR3D cv  = VEVector3DCross(i, j);
    VEREAL dotProd = VEVector3DDot(i, j);
    printf("  ixj = [%.2lf, %.2lf, %.2lf]\n", cv.m_X, cv.m_Y, cv.m_Z);
    printf("   ij = %.2lf\n", dotProd);
    printf("\n");
  }

  { /* Test quaternion sum & difference */
    VEQUATERNION sum   = VEQuaternionAdd(q1, q2);
    VEQUATERNION diff  = VEQuaternionDiff(q1, q2);
    printf("q1+q2 = "); QuaternionPrint(sum);
    printf("q1-q2 = "); QuaternionPrint(diff);
    printf("\n");
  }

  { /* Test quaternion multiplication */
    VEQUATERNION t = VEQuaternionMult(q, 2.0);
    printf("q*2.0 = "); QuaternionPrint(t);
    printf("\n");
  }

  { /* Test quaternion multiplication */
    VEQUATERNION m1 = VEQuaternionMultiply(q1, q2);
    VEQUATERNION m2 = VEQuaternionMultiply(q2, q1);
    printf("q1*q2 = "); QuaternionPrint(m1);
    printf("q2*q1 = "); QuaternionPrint(m2);
    printf("\n");
  }

  { /* Test dot, norm, magnitude */
    VEREAL dotProduct = VEQuaternionDot(q1, q2);
    VEREAL norm       = VEQuaternionNorm(q);
    VEREAL magnitude  = VEQuaternionMagnitude(q);

    printf(" q1q2 = %.2lf\n", dotProduct);
    printf(" N(q) = %.2lf\n", norm);
    printf("  |q| = %.2lf\n", magnitude);
    printf("\n");
  }

  { /* Test conjugate & inversion */
    VEQUATERNION cq = VEQuaternionConjugate(q);
    VEQUATERNION iq = VEQuaternionInverse(q);
    VEQUATERNION m1 = VEQuaternionMultiply(q, iq);
    VEQUATERNION m2 = VEQuaternionMultiply(iq, q);

    printf(" c(q) = "); QuaternionPrint(cq);
    printf(" q^-1 = "); QuaternionPrint(iq);
    printf(" q*iq = "); QuaternionPrint(m1);
    printf(" iq*q = "); QuaternionPrint(m2);
    printf("\n");
  }

  { /* Vectors rotation */
    VEVECTOR3D r1 = VEVector3DRotate(i, q2);
    VEVECTOR3D r2 = VEVector3DRotate(k, q2);
    VEVECTOR3D r3 = VEVector3DRotate(j, q1);

    printf("(i,j) = [%.2lf, %.2lf, %.2lf]\n", r1.m_X, r1.m_Y, r1.m_Z);
    printf("(k,j) = [%.2lf, %.2lf, %.2lf]\n", r2.m_X, r2.m_Y, r2.m_Z);
    printf("(j,i) = [%.2lf, %.2lf, %.2lf]\n", r3.m_X, r3.m_Y, r3.m_Z);
    printf("\n");
  }

  { /* SLERP */
    VEQUATERNION t1 = VEQuaternionInterpolate(q2, q1, 0.0);
    VEQUATERNION t2 = VEQuaternionInterpolate(q2, q1, 0.5);
    VEQUATERNION t3 = VEQuaternionInterpolate(q2, q1, 1.0);

    printf("   t1 = "); QuaternionPrint(t1);
    printf("   t2 = "); QuaternionPrint(t2);
    printf("   t3 = "); QuaternionPrint(t3);
    printf("\n");
  }

  { /* Test quaternion to matrix conversion */
    VEMATRIX3D m = VEQuaternionToMatrix(q1);
    printf("M(q1):\n");
    Matrix3DPrint(m);
    printf("\n");
  }
} /* End of 'TestMath' function */