Blame ImathTest/testQuatSetRotation.cpp

Packit 8dc392
///////////////////////////////////////////////////////////////////////////
Packit 8dc392
//
Packit 8dc392
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
Packit 8dc392
// Digital Ltd. LLC
Packit 8dc392
// 
Packit 8dc392
// All rights reserved.
Packit 8dc392
// 
Packit 8dc392
// Redistribution and use in source and binary forms, with or without
Packit 8dc392
// modification, are permitted provided that the following conditions are
Packit 8dc392
// met:
Packit 8dc392
// *       Redistributions of source code must retain the above copyright
Packit 8dc392
// notice, this list of conditions and the following disclaimer.
Packit 8dc392
// *       Redistributions in binary form must reproduce the above
Packit 8dc392
// copyright notice, this list of conditions and the following disclaimer
Packit 8dc392
// in the documentation and/or other materials provided with the
Packit 8dc392
// distribution.
Packit 8dc392
// *       Neither the name of Industrial Light & Magic nor the names of
Packit 8dc392
// its contributors may be used to endorse or promote products derived
Packit 8dc392
// from this software without specific prior written permission. 
Packit 8dc392
// 
Packit 8dc392
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit 8dc392
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit 8dc392
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit 8dc392
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit 8dc392
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit 8dc392
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit 8dc392
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit 8dc392
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit 8dc392
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit 8dc392
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 8dc392
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 8dc392
//
Packit 8dc392
///////////////////////////////////////////////////////////////////////////
Packit 8dc392
Packit 8dc392
Packit 8dc392
#include <testQuatSetRotation.h>
Packit 8dc392
#include "ImathQuat.h"
Packit 8dc392
#include "ImathRandom.h"
Packit 8dc392
#include <iostream>
Packit 8dc392
#include <assert.h>
Packit 8dc392
Packit 8dc392
Packit 8dc392
using namespace std;
Packit 8dc392
using namespace IMATH_INTERNAL_NAMESPACE;
Packit 8dc392
Packit 8dc392
namespace {
Packit 8dc392
Packit 8dc392
void
Packit 8dc392
testRotation (const V3f &from, const V3f &to)
Packit 8dc392
{
Packit 8dc392
    //
Packit 8dc392
    // Build a quaternion.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    Quatf Q;
Packit 8dc392
    Q.setRotation (from, to);
Packit 8dc392
    M44f M = Q.toMatrix44();
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // Verify that the quaternion rotates vector from into vector to.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    float e = 20 * limits<float>::epsilon();
Packit 8dc392
Packit 8dc392
    V3f fromM = from * M;
Packit 8dc392
    V3f fromQ = from * Q;
Packit 8dc392
    V3f t0 = to.normalized();
Packit 8dc392
    V3f fM0 = fromM.normalized();
Packit 8dc392
    V3f fQ0 = fromQ.normalized();
Packit 8dc392
Packit 8dc392
    assert (t0.equalWithAbsError (fM0, e));
Packit 8dc392
    assert (t0.equalWithAbsError (fQ0, e));
Packit 8dc392
Packit 8dc392
    //
Packit 8dc392
    // Verify that the rotation axis is the cross product of from and to.
Packit 8dc392
    //
Packit 8dc392
Packit 8dc392
    V3f f0 = from.normalized();
Packit 8dc392
Packit 8dc392
    if (abs (f0 ^ t0) < 0.9)
Packit 8dc392
    {
Packit 8dc392
	V3f n0 = (from % to).normalized();
Packit 8dc392
	V3f n0M = n0 * M;
Packit 8dc392
Packit 8dc392
	assert (n0.equalWithAbsError (n0M, e));
Packit 8dc392
    }
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
void
Packit 8dc392
specificVectors ()
Packit 8dc392
{
Packit 8dc392
    cout << "  exact 90-degree rotations" << endl;
Packit 8dc392
Packit 8dc392
    testRotation (V3f (1, 0, 0), V3f (0, 1, 0));
Packit 8dc392
    testRotation (V3f (1, 0, 0), V3f (0, 0, 1));
Packit 8dc392
    testRotation (V3f (0, 1, 0), V3f (1, 0, 0));
Packit 8dc392
    testRotation (V3f (0, 1, 0), V3f (0, 0, 1));
Packit 8dc392
    testRotation (V3f (0, 0, 1), V3f (1, 0, 0));
Packit 8dc392
    testRotation (V3f (0, 0, 1), V3f (0, 1, 0));
Packit 8dc392
Packit 8dc392
    cout << "  exact zero-degree rotations" << endl;
Packit 8dc392
Packit 8dc392
    testRotation (V3f (1, 0, 0), V3f (1, 0, 0));
Packit 8dc392
    testRotation (V3f (0, 1, 0), V3f (0, 1, 0));
Packit 8dc392
    testRotation (V3f (0, 0, 1), V3f (0, 0, 1));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (2, 4, 6));
Packit 8dc392
Packit 8dc392
    cout << "  exact 180-degree rotations" << endl;
Packit 8dc392
Packit 8dc392
    testRotation (V3f (1, 0, 0), V3f (-1, 0, 0));
Packit 8dc392
    testRotation (V3f (0, 1, 0), V3f (0, -1, 0));
Packit 8dc392
    testRotation (V3f (0, 0, 1), V3f (0, 0, -1));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (-2, -4, -6));
Packit 8dc392
    testRotation (V3f (1, 3, 2), V3f (-2, -6, -4));
Packit 8dc392
    testRotation (V3f (2, 1, 3), V3f (-4, -2, -6));
Packit 8dc392
    testRotation (V3f (3, 1, 2), V3f (-6, -2, -4));
Packit 8dc392
    testRotation (V3f (2, 3, 1), V3f (-4, -6, -2));
Packit 8dc392
    testRotation (V3f (3, 2, 1), V3f (-6, -4, -2));
Packit 8dc392
Packit 8dc392
    cout << "  other angles" << endl;
Packit 8dc392
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (4, 5, 6));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (4, 6, 5));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (5, 4, 6));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (6, 4, 5));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (5, 6, 4));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (6, 5, 4));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (-4, -5, -6));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (-4, -6, -5));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (-5, -4, -6));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (-6, -4, -5));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (-5, -6, -4));
Packit 8dc392
    testRotation (V3f (1, 2, 3), V3f (-6, -5, -4));
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
void
Packit 8dc392
randomVectors ()
Packit 8dc392
{
Packit 8dc392
    cout << "  random from and to vectors" << endl;
Packit 8dc392
Packit 8dc392
    Rand48 rand (17);
Packit 8dc392
Packit 8dc392
    for (int i = 0; i < 500000; ++i)
Packit 8dc392
    {
Packit 8dc392
	V3f from = hollowSphereRand<V3f> (rand) * rand.nextf (0.1, 10.0);
Packit 8dc392
	V3f to = hollowSphereRand<V3f> (rand) * rand.nextf (0.1, 10.0);
Packit 8dc392
	testRotation (from, to);
Packit 8dc392
    }
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
void
Packit 8dc392
nearlyEqualVectors ()
Packit 8dc392
{
Packit 8dc392
    cout << "  nearly equal from and to vectors" << endl;
Packit 8dc392
Packit 8dc392
    Rand48 rand (19);
Packit 8dc392
    float e = 100 * limits<float>::epsilon();
Packit 8dc392
Packit 8dc392
    for (int i = 0; i < 500000; ++i)
Packit 8dc392
    {
Packit 8dc392
	V3f from = hollowSphereRand<V3f> (rand);
Packit 8dc392
	V3f to = from + e * hollowSphereRand<V3f> (rand);
Packit 8dc392
	testRotation (from, to);
Packit 8dc392
    }
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
void
Packit 8dc392
nearlyOppositeVectors ()
Packit 8dc392
{
Packit 8dc392
    cout << "  nearly opposite from and to vectors" << endl;
Packit 8dc392
Packit 8dc392
    Rand48 rand (19);
Packit 8dc392
    float e = 100 * limits<float>::epsilon();
Packit 8dc392
Packit 8dc392
    for (int i = 0; i < 500000; ++i)
Packit 8dc392
    {
Packit 8dc392
	V3f from = hollowSphereRand<V3f> (rand);
Packit 8dc392
	V3f to = -from + e * hollowSphereRand<V3f> (rand);
Packit 8dc392
	testRotation (from, to);
Packit 8dc392
    }
Packit 8dc392
}
Packit 8dc392
Packit 8dc392
Packit 8dc392
Packit 8dc392
} // namespace
Packit 8dc392
Packit 8dc392
Packit 8dc392
void
Packit 8dc392
testQuatSetRotation ()
Packit 8dc392
{
Packit 8dc392
    cout << "Testing quaternion rotations" << endl;
Packit 8dc392
Packit 8dc392
    specificVectors();
Packit 8dc392
    randomVectors();
Packit 8dc392
    nearlyEqualVectors();
Packit 8dc392
    nearlyOppositeVectors();
Packit 8dc392
Packit 8dc392
    cout << "ok\n" << endl;
Packit 8dc392
}