/* * JaamSim Discrete Event Simulation * Copyright (C) 2012 Ausenco Engineering Canada Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.jaamsim.math; import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.Test; public class TestQuaternion { private static final Vec4d X_AXIS = new Vec4d(1, 0, 0, 1.0d); private static final Vec4d Y_AXIS = new Vec4d(0, 1, 0, 1.0d); private static final Vec4d Z_AXIS = new Vec4d(0, 0, 1, 1.0d); private static final Vec4d NEG_X_AXIS = new Vec4d(-1, 0, 0, 1.0d); private static final Vec4d NEG_Y_AXIS = new Vec4d( 0, -1, 0, 1.0d); private static final Vec4d NEG_Z_AXIS = new Vec4d( 0, 0, -1, 1.0d); private Quaternion x_pi; private Quaternion x_halfPi; private Quaternion y_pi; private Quaternion y_halfPi; private Quaternion z_pi; private Quaternion z_halfPi; private Quaternion ident; @Before public void setup() { x_pi = new Quaternion(); x_pi.setRotXAxis(Math.PI); x_halfPi = new Quaternion(); x_halfPi.setRotXAxis(Math.PI / 2.0d); y_pi = new Quaternion(); y_pi.setRotYAxis(Math.PI); y_halfPi = new Quaternion(); y_halfPi.setRotYAxis(Math.PI / 2.0d); z_pi = new Quaternion(); z_pi.setRotZAxis(Math.PI); z_halfPi = new Quaternion(); z_halfPi.setRotZAxis(Math.PI / 2.0d); ident = new Quaternion(); } @Test public void testSimpleQuatRotation() { Mat4d tempRot = new Mat4d(); Vec4d res = new Vec4d(0.0d, 0.0d, 0.0d, 1.0d); tempRot.setRot3(z_halfPi); res.mult3(tempRot, X_AXIS); assertTrue(res.near4(Y_AXIS)); tempRot.setRot3(z_pi); res.mult3(tempRot, X_AXIS); assertTrue(res.near4(NEG_X_AXIS)); tempRot.setRot3(y_halfPi); res.mult3(tempRot, X_AXIS); assertTrue(res.near4(NEG_Z_AXIS)); tempRot.setRot3(y_pi); res.mult3(tempRot, X_AXIS); assertTrue(res.near4(NEG_X_AXIS)); tempRot.setRot3(x_halfPi); res.mult3(tempRot, Y_AXIS); assertTrue(res.near4(Z_AXIS)); tempRot.setRot3(x_pi); res.mult3(tempRot, Y_AXIS); assertTrue(res.near4(NEG_Y_AXIS)); } @Test public void testSlerp() { Mat4d tempRot = new Mat4d(); Quaternion x_quarterPi = new Quaternion(); ident.slerp(x_halfPi, 0.5, x_quarterPi); Quaternion x_eighthPi = new Quaternion(); ident.slerp(x_halfPi, 0.25, x_eighthPi); Vec4d res = new Vec4d(0.0d, 0.0d, 0.0d, 1.0d); Vec4d expected = new Vec4d(0, 1, 1, 1); expected.normalize3(); tempRot.setRot3(x_quarterPi); res.mult3(tempRot, Y_AXIS); assertTrue(res.near3(expected)); tempRot.setRot3(x_eighthPi); res.mult3(tempRot, Y_AXIS); expected.set3(0, Math.cos(Math.PI/8), Math.sin(Math.PI/8)); assertTrue(res.near3(expected)); } @Test public void testConstructor() { Quaternion x_eighthPi = new Quaternion(); ident.slerp(x_halfPi, 0.25, x_eighthPi); Quaternion x_eighthPi2 = new Quaternion(); x_eighthPi2.setRotXAxis(Math.PI/8); assertTrue(x_eighthPi.near(x_eighthPi2)); Quaternion x_negEighthPi = new Quaternion(); x_negEighthPi.conjugate(x_eighthPi); Quaternion x_negEighthPi2 = new Quaternion(); x_negEighthPi2.setRotXAxis(-Math.PI/8); assertTrue(x_negEighthPi.near(x_negEighthPi2)); } @Test public void testSelfAssignment() { Quaternion q1 = new Quaternion(x_halfPi); Quaternion q2 = new Quaternion(z_pi); Quaternion q3 = new Quaternion(); q3.mult(q1, q2); q1.mult(q1, q2); assertTrue(q1.equals(q3)); q3.mult(q1, q2); q2.mult(q1, q2); assertTrue(q2.equals(q3)); } } // class