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());
}
}
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);
}
Aggregations