Search in sources :

Example 6 with Quaternion

use of com.bergerkiller.bukkit.common.math.Quaternion in project BKCommonLib by bergerhealer.

the class MathUtilTest method testQuaternionFromLookDirection.

@Test
public void testQuaternionFromLookDirection() {
    // The up and forward vectors of the produced quaternion should be the same as the input
    for (int i = 0; i < 10000; i++) {
        Vector dir = randUnitVec().multiply(0.2 + 2.0 * Math.random());
        Vector up = randOrtho(dir).multiply(0.2 + 2.0 * Math.random());
        Quaternion q = Quaternion.fromLookDirection(dir, up);
        dir.normalize();
        up.normalize();
        testVectorsEqual(dir, q.forwardVector(), 1e-8);
        testVectorsEqual(up, q.upVector(), 1e-8);
    }
    // Verify that up-vectors that aren't perfectly orthogonal also work
    {
        Vector dir = new Vector(0.0, 0.0, 1.0);
        Vector up = new Vector(0.0, 3.0, -4.0);
        Quaternion q = Quaternion.fromLookDirection(dir, up);
        Vector result_dir = q.forwardVector();
        Vector result_up = q.upVector();
        assertEquals(dir.getX(), result_dir.getX(), 0.00001);
        assertEquals(dir.getY(), result_dir.getY(), 0.00001);
        assertEquals(dir.getZ(), result_dir.getZ(), 0.00001);
        assertEquals(0.0, result_up.getX(), 0.01);
        assertEquals(1.0, result_up.getY(), 0.01);
        assertEquals(0.0, result_up.getZ(), 0.01);
    }
    // Verify special cases where up is 180-degrees rotated
    for (int dx = -1; dx <= 1; dx++) {
        for (int dz = -1; dz <= 1; dz++) {
            if (dx == 0 && dz == 0)
                continue;
            Vector dir = new Vector(dx, 0.0, dz);
            Vector up = new Vector(0.0, -1.0, 0.0);
            Quaternion q = Quaternion.fromLookDirection(dir, up);
            dir.normalize();
            up.normalize();
            testVectorsEqual(dir, q.forwardVector());
            testVectorsEqual(up, q.upVector());
        }
    }
    // The direction vector ended up swapped because (unknown)
    for (int i = 0; i < 10000; i++) {
        Vector dir = new Vector(0.0001 * Math.random(), Math.random(), -Math.random());
        Vector up = new Vector(0.0, 1.0, 0.0);
        Quaternion q = Quaternion.fromLookDirection(dir, up);
        dir.normalize();
        testVectorsEqual(dir, q.forwardVector(), 1e-7);
    }
    {
        Vector dir = new Vector(0.0, 0.0001, -0.4);
        Vector up = new Vector(0.0, 1.0, 0.0);
        Quaternion q = Quaternion.fromLookDirection(dir, up);
        dir.normalize();
        testVectorsEqual(dir, q.forwardVector());
    }
    {
        Vector dir = new Vector(-0.4, 0.0001, 0.0);
        Vector up = new Vector(0.0, 1.0, 0.0);
        Quaternion q = Quaternion.fromLookDirection(dir, up);
        dir.normalize();
        testVectorsEqual(dir, q.forwardVector());
    }
}
Also used : Quaternion(com.bergerkiller.bukkit.common.math.Quaternion) Vector(org.bukkit.util.Vector) Test(org.junit.Test)

Example 7 with Quaternion

use of com.bergerkiller.bukkit.common.math.Quaternion in project BKCommonLib by bergerhealer.

the class MathUtilTest method testQuaternionYPRSingularity.

@Test
public void testQuaternionYPRSingularity() {
    // Verify that, as the quaternion approaches a pitch of 90 degrees, the yaw/pitch/roll stays accurate
    // If there is an error here, it can happen an angle is calculated that is completely out of whack
    double exp = 1.0;
    double angle;
    do {
        // Slowly approach 90.0 but never quite reach it
        exp += 0.01;
        angle = 90.0 * (1.0 - (1.0 / (double) (Math.exp(exp))));
        Quaternion q = Quaternion.fromYawPitchRoll(angle, 90.0, 0.0);
        Vector ypr = q.getYawPitchRoll();
        assertEquals(angle, ypr.getX(), 0.00001);
        assertEquals(90.0, ypr.getY(), 0.00001);
        assertEquals(0.0, ypr.getZ(), 0.00001);
    } while (angle != 90.0);
    // Repeat for -90.0
    exp = 1.0;
    do {
        // Slowly approach -90.0 but never quite reach it
        exp += 0.01;
        angle = -90.0 * (1.0 - (1.0 / (double) (Math.exp(exp))));
        Quaternion q = Quaternion.fromYawPitchRoll(angle, 90.0, 0.0);
        Vector ypr = q.getYawPitchRoll();
        assertEquals(angle, ypr.getX(), 0.00001);
        assertEquals(90.0, ypr.getY(), 0.00001);
        assertEquals(0.0, ypr.getZ(), 0.00001);
    } while (angle != -90.0);
}
Also used : Quaternion(com.bergerkiller.bukkit.common.math.Quaternion) Vector(org.bukkit.util.Vector) Test(org.junit.Test)

Aggregations

Quaternion (com.bergerkiller.bukkit.common.math.Quaternion)7 Vector (org.bukkit.util.Vector)7 Test (org.junit.Test)6 Matrix4x4 (com.bergerkiller.bukkit.common.math.Matrix4x4)1 ArrayList (java.util.ArrayList)1