DSDSWeb/static/js/Cesium-1.53/Specs/Core/QuaternionSpec.js

1019 lines
42 KiB
JavaScript

defineSuite([
'Core/Quaternion',
'Core/Cartesian3',
'Core/HeadingPitchRoll',
'Core/Math',
'Core/Matrix3',
'Specs/createPackableSpecs'
], function(
Quaternion,
Cartesian3,
HeadingPitchRoll,
CesiumMath,
Matrix3,
createPackableSpecs) {
'use strict';
it('construct with default values', function() {
var quaternion = new Quaternion();
expect(quaternion.x).toEqual(0.0);
expect(quaternion.y).toEqual(0.0);
expect(quaternion.z).toEqual(0.0);
expect(quaternion.w).toEqual(0.0);
});
it('construct with all values', function() {
var quaternion = new Quaternion(1.0, 2.0, 3.0, 4.0);
expect(quaternion.x).toEqual(1.0);
expect(quaternion.y).toEqual(2.0);
expect(quaternion.z).toEqual(3.0);
expect(quaternion.w).toEqual(4.0);
});
it('fromAxisAngle works without a result parameter', function() {
var axis = new Cartesian3(0.0, 0.0, 1.0);
var angle = CesiumMath.PI_OVER_TWO;
var s = Math.sin(angle / 2.0);
var c = Math.cos(angle / 2.0);
var a = Cartesian3.multiplyByScalar(axis, s, new Cartesian3());
var expected = new Quaternion(a.x, a.y, a.z, c);
var returnedResult = Quaternion.fromAxisAngle(axis, angle);
expect(returnedResult).toEqual(expected);
});
it('fromAxisAngle works with a result parameter', function() {
var axis = new Cartesian3(0.0, 0.0, 1.0);
var angle = CesiumMath.PI_OVER_TWO;
var s = Math.sin(angle / 2.0);
var c = Math.cos(angle / 2.0);
var a = Cartesian3.multiplyByScalar(axis, s, new Cartesian3());
var result = new Quaternion();
var expected = new Quaternion(a.x, a.y, a.z, c);
var returnedResult = Quaternion.fromAxisAngle(axis, angle, result);
expect(result).toBe(returnedResult);
expect(returnedResult).toEqual(expected);
});
it('fromRotationMatrix works when m22 is max', function() {
var q = Quaternion.fromAxisAngle(Cartesian3.negate(Cartesian3.UNIT_Z, new Cartesian3()), Math.PI);
var rotation = new Matrix3(-1.0, 0.0, 0.0,
0.0, -1.0, 0.0,
0.0, 0.0, 1.0);
expect(Quaternion.fromRotationMatrix(rotation)).toEqualEpsilon(q, CesiumMath.EPSILON15);
});
it('fromRotationMatrix works when m11 is max', function() {
var q = Quaternion.fromAxisAngle(Cartesian3.negate(Cartesian3.UNIT_Y, new Cartesian3()), Math.PI);
var rotation = new Matrix3(-1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, -1.0);
expect(Quaternion.fromRotationMatrix(rotation)).toEqualEpsilon(q, CesiumMath.EPSILON15);
});
it('fromRotationMatrix works when m00 is max', function() {
var q = Quaternion.fromAxisAngle(Cartesian3.negate(Cartesian3.UNIT_X, new Cartesian3()), Math.PI);
var rotation = new Matrix3(1.0, 0.0, 0.0,
0.0, -1.0, 0.0,
0.0, 0.0, -1.0);
expect(Quaternion.fromRotationMatrix(rotation)).toEqualEpsilon(q, CesiumMath.EPSILON15);
});
it('fromRotationMatrix works when trace is greater than zero', function() {
var rotation = new Matrix3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
var q = new Quaternion(0.0, 0.0, 0.0, 1.0);
expect(Quaternion.fromRotationMatrix(rotation)).toEqualEpsilon(q, CesiumMath.EPSILON15);
});
it('fromRotationMatrix works with result parameter', function() {
var rotation = new Matrix3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
var q = new Quaternion(0.0, 0.0, 0.0, 1.0);
var result = new Quaternion();
var returnedResult = Quaternion.fromRotationMatrix(rotation, result);
expect(returnedResult).toEqualEpsilon(q, CesiumMath.EPSILON15);
expect(returnedResult).toBe(result);
});
it('fromRotationMatrix using a view matrix', function() {
var direction = new Cartesian3(-0.2349326833984488, 0.8513513009480378, 0.46904967396353314);
var up = new Cartesian3(0.12477198625717335, -0.4521499177166376, 0.8831717858696695);
var right = new Cartesian3(0.9639702203483635, 0.26601017702986895, 6.456422901079747e-10);
var matrix = new Matrix3( right.x, right.y, right.z,
up.x, up.y, up.z,
-direction.x, -direction.y, -direction.z);
var quaternion = Quaternion.fromRotationMatrix(matrix);
expect(Matrix3.fromQuaternion(quaternion)).toEqualEpsilon(matrix, CesiumMath.EPSILON12);
});
it('fromHeadingPitchRoll with just heading', function() {
var angle = CesiumMath.toRadians(20.0);
var hpr = new HeadingPitchRoll(angle, 0.0, 0.0);
var quaternion = Quaternion.fromHeadingPitchRoll(hpr);
expect(Matrix3.fromQuaternion(quaternion)).toEqualEpsilon(Matrix3.fromRotationZ(-angle), CesiumMath.EPSILON11);
});
it('fromHeadingPitchRoll with just pitch', function() {
var angle = CesiumMath.toRadians(20.0);
var hpr = new HeadingPitchRoll(0.0, angle, 0.0);
var quaternion = Quaternion.fromHeadingPitchRoll(hpr);
expect(Matrix3.fromQuaternion(quaternion)).toEqualEpsilon(Matrix3.fromRotationY(-angle), CesiumMath.EPSILON11);
});
it('fromHeadingPitchRoll with just roll', function() {
var angle = CesiumMath.toRadians(20.0);
var hpr = new HeadingPitchRoll( 0.0, 0.0, angle);
var quaternion = Quaternion.fromHeadingPitchRoll(hpr);
expect(Matrix3.fromQuaternion(quaternion)).toEqualEpsilon(Matrix3.fromRotationX(angle), CesiumMath.EPSILON11);
});
it('fromHeadingPitchRoll with all angles (1)', function() {
var angle = CesiumMath.toRadians(20.0);
var hpr = new HeadingPitchRoll( angle, angle, angle);
var quaternion = Quaternion.fromHeadingPitchRoll(hpr);
var expected = Matrix3.fromRotationX(angle);
Matrix3.multiply(Matrix3.fromRotationY(-angle), expected, expected);
Matrix3.multiply(Matrix3.fromRotationZ(-angle), expected, expected);
expect(Matrix3.fromQuaternion(quaternion)).toEqualEpsilon(expected, CesiumMath.EPSILON11);
});
it('fromHeadingPitchRoll with all angles (2)', function() {
var heading = CesiumMath.toRadians(180.0);
var pitch = CesiumMath.toRadians(-45.0);
var roll = CesiumMath.toRadians(45.0);
var hpr = new HeadingPitchRoll( heading, pitch, roll);
var quaternion = Quaternion.fromHeadingPitchRoll(hpr);
var expected = Matrix3.fromRotationX(roll);
Matrix3.multiply(Matrix3.fromRotationY(-pitch), expected, expected);
Matrix3.multiply(Matrix3.fromRotationZ(-heading), expected, expected);
expect(Matrix3.fromQuaternion(quaternion)).toEqualEpsilon(expected, CesiumMath.EPSILON11);
});
it('fromHeadingPitchRoll works with result parameter', function() {
var angle = CesiumMath.toRadians(20.0);
var hpr = new HeadingPitchRoll(0.0, 0.0, angle);
var result = new Quaternion();
var quaternion = Quaternion.fromHeadingPitchRoll(hpr, result);
var expected = Quaternion.fromRotationMatrix(Matrix3.fromRotationX(angle));
expect(quaternion).toBe(result);
expect(quaternion).toEqualEpsilon(expected, CesiumMath.EPSILON11);
});
it('clone without a result parameter', function() {
var quaternion = new Quaternion(1.0, 2.0, 3.0, 4.0);
var result = quaternion.clone();
expect(quaternion).not.toBe(result);
expect(quaternion).toEqual(result);
});
it('clone with a result parameter', function() {
var quaternion = new Quaternion(1.0, 2.0, 3.0, 4.0);
var result = new Quaternion();
var returnedResult = quaternion.clone(result);
expect(quaternion).not.toBe(result);
expect(result).toBe(returnedResult);
expect(quaternion).toEqual(result);
});
it('clone works with a result parameter that is an input parameter', function() {
var quaternion = new Quaternion(1.0, 2.0, 3.0, 4.0);
var returnedResult = quaternion.clone(quaternion);
expect(quaternion).toBe(returnedResult);
});
it('conjugate works', function() {
var expected = new Quaternion(-1.0, -2.0, -3.0, 4.0);
var quaternion = new Quaternion(1.0, 2.0, 3.0, 4.0);
var result = new Quaternion();
var returnedResult = Quaternion.conjugate(quaternion, result);
expect(result).toBe(returnedResult);
expect(returnedResult).toEqual(expected);
});
it('conjugate works with a result parameter that is an input parameter', function() {
var expected = new Quaternion(-1.0, -2.0, -3.0, 4.0);
var quaternion = new Quaternion(1.0, 2.0, 3.0, 4.0);
var returnedResult = Quaternion.conjugate(quaternion, quaternion);
expect(quaternion).toBe(returnedResult);
expect(quaternion).toEqual(expected);
});
it('magnitudeSquared computes correct result', function() {
var expected = 2 * 2 + 3 * 3 + 4 * 4 + 5 * 5;
var quaternion = new Quaternion(2.0, 3.0, 4.0, 5.0);
var result = Quaternion.magnitudeSquared(quaternion);
expect(result).toEqual(expected);
});
it('norm computes correct result', function() {
var expected = Math.sqrt(2 * 2 + 3 * 3 + 4 * 4 + 5 * 5);
var quaternion = new Quaternion(2.0, 3.0, 4.0, 5.0);
var result = Quaternion.magnitude(quaternion);
expect(result).toEqual(expected);
});
it('normalize works', function() {
var quaternion = new Quaternion(2.0, 0.0, 0.0, 0.0);
var expectedResult = new Quaternion(1.0, 0.0, 0.0, 0.0);
var result = new Quaternion();
var returnedResult = Quaternion.normalize(quaternion, result);
expect(result).toBe(returnedResult);
expect(result).toEqual(expectedResult);
});
it('normalize works with a result parameter that is an input parameter', function() {
var quaternion = new Quaternion(2.0, 0.0, 0.0, 0.0);
var expectedResult = new Quaternion(1.0, 0.0, 0.0, 0.0);
var returnedResult = Quaternion.normalize(quaternion, quaternion);
expect(quaternion).toBe(returnedResult);
expect(quaternion).toEqual(expectedResult);
});
it('inverse works', function() {
var quaternion = new Quaternion(2.0, 3.0, 4.0, 5.0);
var magnitudeSquared = Quaternion.magnitudeSquared(quaternion);
var expected = new Quaternion(-2.0 / magnitudeSquared, -3.0 / magnitudeSquared, -4.0 / magnitudeSquared, 5.0 / magnitudeSquared);
var result = new Quaternion();
var returnedResult = Quaternion.inverse(quaternion, result);
expect(returnedResult).toEqual(expected);
expect(returnedResult).toBe(result);
});
it('inverse works with a result parameter that is an input parameter', function() {
var quaternion = new Quaternion(2.0, 3.0, 4.0, 5.0);
var magnitudeSquared = Quaternion.magnitudeSquared(quaternion);
var expected = new Quaternion(-2.0 / magnitudeSquared, -3.0 / magnitudeSquared, -4.0 / magnitudeSquared, 5.0 / magnitudeSquared);
var returnedResult = Quaternion.inverse(quaternion, quaternion);
expect(returnedResult).toEqual(expected);
expect(returnedResult).toBe(quaternion);
});
it('dot', function() {
var left = new Quaternion(2.0, 3.0, 6.0, 8.0);
var right = new Quaternion(4.0, 5.0, 7.0, 9.0);
var expectedResult = 137.0;
var result = Quaternion.dot(left, right);
expect(result).toEqual(expectedResult);
});
it('multiply works', function() {
var left = new Quaternion(1.0, 2.0, 3.0, 4.0);
var right = new Quaternion(8.0, 7.0, 6.0, 5.0);
var expected = new Quaternion(28.0, 56.0, 30.0, -20.0);
var result = new Quaternion();
var returnedResult = Quaternion.multiply(left, right, result);
expect(returnedResult).toEqual(expected);
expect(result).toBe(returnedResult);
});
it('multiply works with a result parameter that is an input parameter', function() {
var left = new Quaternion(1.0, 2.0, 3.0, 4.0);
var right = new Quaternion(8.0, 7.0, 6.0, 5.0);
var expected = new Quaternion(28.0, 56.0, 30.0, -20.0);
var returnedResult = Quaternion.multiply(left, right, left);
expect(returnedResult).toEqual(expected);
expect(left).toBe(returnedResult);
});
it('add works', function() {
var left = new Quaternion(2.0, 3.0, 6.0, 8.0);
var right = new Quaternion(4.0, 5.0, 7.0, 9.0);
var result = new Quaternion();
var expectedResult = new Quaternion(6.0, 8.0, 13.0, 17.0);
var returnedResult = Quaternion.add(left, right, result);
expect(result).toBe(returnedResult);
expect(result).toEqual(expectedResult);
});
it('add works with a result parameter that is an input parameter', function() {
var left = new Quaternion(2.0, 3.0, 6.0, 8.0);
var right = new Quaternion(4.0, 5.0, 7.0, 9.0);
var expectedResult = new Quaternion(6.0, 8.0, 13.0, 17.0);
var returnedResult = Quaternion.add(left, right, left);
expect(left).toBe(returnedResult);
expect(left).toEqual(expectedResult);
});
it('subtract works', function() {
var left = new Quaternion(2.0, 3.0, 4.0, 8.0);
var right = new Quaternion(1.0, 5.0, 7.0, 9.0);
var result = new Quaternion();
var expectedResult = new Quaternion(1.0, -2.0, -3.0, -1.0);
var returnedResult = Quaternion.subtract(left, right, result);
expect(result).toBe(returnedResult);
expect(result).toEqual(expectedResult);
});
it('subtract works with this result parameter', function() {
var left = new Quaternion(2.0, 3.0, 4.0, 8.0);
var right = new Quaternion(1.0, 5.0, 7.0, 9.0);
var expectedResult = new Quaternion(1.0, -2.0, -3.0, -1.0);
var returnedResult = Quaternion.subtract(left, right, left);
expect(returnedResult).toBe(left);
expect(left).toEqual(expectedResult);
});
it('multiplyByScalar works ', function() {
var quaternion = new Quaternion(1.0, 2.0, 3.0, 4.0);
var result = new Quaternion();
var scalar = 2;
var expectedResult = new Quaternion(2.0, 4.0, 6.0, 8.0);
var returnedResult = Quaternion.multiplyByScalar(quaternion, scalar, result);
expect(result).toBe(returnedResult);
expect(result).toEqual(expectedResult);
});
it('multiplyByScalar works with a result parameter that is an input parameter', function() {
var quaternion = new Quaternion(1.0, 2.0, 3.0, 4.0);
var scalar = 2;
var expectedResult = new Quaternion(2.0, 4.0, 6.0, 8.0);
var returnedResult = Quaternion.multiplyByScalar(quaternion, scalar, quaternion);
expect(quaternion).toBe(returnedResult);
expect(quaternion).toEqual(expectedResult);
});
it('divideByScalar works', function() {
var quaternion = new Quaternion(1.0, 2.0, 3.0, 4.0);
var result = new Quaternion();
var scalar = 2;
var expectedResult = new Quaternion(0.5, 1.0, 1.5, 2.0);
var returnedResult = Quaternion.divideByScalar(quaternion, scalar, result);
expect(result).toBe(returnedResult);
expect(result).toEqual(expectedResult);
});
it('divideByScalar works with a result parameter that is an input parameter', function() {
var quaternion = new Quaternion(1.0, 2.0, 3.0, 4.0);
var scalar = 2;
var expectedResult = new Quaternion(0.5, 1.0, 1.5, 2.0);
var returnedResult = Quaternion.divideByScalar(quaternion, scalar, quaternion);
expect(quaternion).toBe(returnedResult);
expect(quaternion).toEqual(expectedResult);
});
it('axis works', function() {
// 60 degrees is used here to ensure that the sine and cosine of the half angle are not equal.
var angle = Math.PI / 3.0;
var cos = Math.cos(angle / 2.0);
var sin = Math.sin(angle / 2.0);
var expected = Cartesian3.normalize(new Cartesian3(2.0, 3.0, 6.0), new Cartesian3());
var quaternion = new Quaternion(sin * expected.x, sin * expected.y, sin * expected.z, cos);
var result = new Cartesian3();
var returnedResult = Quaternion.computeAxis(quaternion, result);
expect(returnedResult).toEqualEpsilon(expected, CesiumMath.EPSILON15);
expect(result).toBe(returnedResult);
});
it('axis returns Cartesian3 0 when w equals 1.0', function() {
var expected = new Cartesian3(0.0, 0.0, 0.0);
var quaternion = new Quaternion(4.0, 2.0, 3.0, 1.0);
var result = new Cartesian3(1, 2, 3);
var returnedResult = Quaternion.computeAxis(quaternion, result);
expect(returnedResult).toEqual(expected);
expect(result).toBe(returnedResult);
});
it('angle works', function() {
// 60 degrees is used here to ensure that the sine and cosine of the half angle are not equal.
var angle = Math.PI / 3.0;
var cos = Math.cos(angle / 2.0);
var sin = Math.sin(angle / 2.0);
var axis = Cartesian3.normalize(new Cartesian3(2.0, 3.0, 6.0), new Cartesian3());
var quaternion = new Quaternion(sin * axis.x, sin * axis.y, sin * axis.z, cos);
var result = Quaternion.computeAngle(quaternion);
expect(result).toEqualEpsilon(angle, CesiumMath.EPSILON15);
});
it('negate works', function() {
var quaternion = new Quaternion(1.0, -2.0, -5.0, 4.0);
var result = new Quaternion();
var expectedResult = new Quaternion(-1.0, 2.0, 5.0, -4.0);
var returnedResult = Quaternion.negate(quaternion, result);
expect(result).toBe(returnedResult);
expect(result).toEqual(expectedResult);
});
it('negate works with a result parameter that is an input parameter', function() {
var quaternion = new Quaternion(1.0, -2.0, -5.0);
var expectedResult = new Quaternion(-1.0, 2.0, 5.0);
var returnedResult = Quaternion.negate(quaternion, quaternion);
expect(quaternion).toBe(returnedResult);
expect(quaternion).toEqual(expectedResult);
});
it('lerp works', function() {
var start = new Quaternion(4.0, 8.0, 10.0, 20.0);
var end = new Quaternion(8.0, 20.0, 20.0, 30.0);
var t = 0.25;
var result = new Quaternion();
var expectedResult = new Quaternion(5.0, 11.0, 12.5, 22.5);
var returnedResult = Quaternion.lerp(start, end, t, result);
expect(result).toBe(returnedResult);
expect(result).toEqual(expectedResult);
});
it('lerp works with a result parameter that is an input parameter', function() {
var start = new Quaternion(4.0, 8.0, 10.0, 20.0);
var end = new Quaternion(8.0, 20.0, 20.0, 30.0);
var t = 0.25;
var expectedResult = new Quaternion(5.0, 11.0, 12.5, 22.5);
var returnedResult = Quaternion.lerp(start, end, t, start);
expect(start).toBe(returnedResult);
expect(start).toEqual(expectedResult);
});
it('lerp extrapolate forward', function() {
var start = new Quaternion(4.0, 8.0, 10.0, 20.0);
var end = new Quaternion(8.0, 20.0, 20.0, 30.0);
var t = 2.0;
var expectedResult = new Quaternion(12.0, 32.0, 30.0, 40.0);
var result = Quaternion.lerp(start, end, t, new Quaternion());
expect(result).toEqual(expectedResult);
});
it('lerp extrapolate backward', function() {
var start = new Quaternion(4.0, 8.0, 10.0, 20.0);
var end = new Quaternion(8.0, 20.0, 20.0, 30.0);
var t = -1.0;
var expectedResult = new Quaternion(0.0, -4.0, 0.0, 10.0);
var result = Quaternion.lerp(start, end, t, new Quaternion());
expect(result).toEqual(expectedResult);
});
it('slerp works', function() {
var start = Quaternion.normalize(new Quaternion(0.0, 0.0, 0.0, 1.0), new Quaternion());
var end = new Quaternion(0.0, 0.0, Math.sin(CesiumMath.PI_OVER_FOUR), Math.cos(CesiumMath.PI_OVER_FOUR));
var expected = new Quaternion(0.0, 0.0, Math.sin(Math.PI / 8.0), Math.cos(Math.PI / 8.0));
var result = new Quaternion();
var returnedResult = Quaternion.slerp(start, end, 0.5, result);
expect(result).toEqualEpsilon(expected, CesiumMath.EPSILON15);
expect(result).toBe(returnedResult);
});
it('slerp works with a result parameter that is an input parameter', function() {
var start = Quaternion.normalize(new Quaternion(0.0, 0.0, 0.0, 1.0), new Quaternion());
var end = new Quaternion(0.0, 0.0, Math.sin(CesiumMath.PI_OVER_FOUR), Math.cos(CesiumMath.PI_OVER_FOUR));
var expected = new Quaternion(0.0, 0.0, Math.sin(Math.PI / 8.0), Math.cos(Math.PI / 8.0));
var returnedResult = Quaternion.slerp(start, end, 0.5, start);
expect(start).toEqualEpsilon(expected, CesiumMath.EPSILON15);
expect(start).toBe(returnedResult);
});
it('slerp works with obtuse angles', function() {
var start = Quaternion.normalize(new Quaternion(0.0, 0.0, 0.0, -1.0), new Quaternion());
var end = new Quaternion(0.0, 0.0, Math.sin(CesiumMath.PI_OVER_FOUR), Math.cos(CesiumMath.PI_OVER_FOUR));
var expected = new Quaternion(0.0, 0.0, -Math.sin(Math.PI / 8.0), -Math.cos(Math.PI / 8.0));
expect(Quaternion.slerp(start, end, 0.5, new Quaternion())).toEqualEpsilon(expected, CesiumMath.EPSILON15);
});
it('slerp uses lerp when dot product is close to 1', function() {
var start = new Quaternion(0.0, 0.0, 0.0, 1.0);
var end = new Quaternion(1.0, 2.0, 3.0, 1.0);
var expected = new Quaternion(0.5, 1.0, 1.5, 1.0);
var result = new Quaternion();
expect(Quaternion.slerp(start, end, 0.0, result)).toEqual(start);
expect(Quaternion.slerp(start, end, 1.0, result)).toEqual(end);
expect(Quaternion.slerp(start, end, 0.5, result)).toEqual(expected);
});
it('slerp uses lerp when dot product is close to 1 and a result parameter', function() {
var start = new Quaternion(0.0, 0.0, 0.0, 1.0);
var end = new Quaternion(1.0, 2.0, 3.0, 1.0);
var result = new Quaternion();
var actual = Quaternion.slerp(start, end, 0.0, result);
expect(actual).toBe(result);
expect(result).toEqual(start);
});
it('log works', function() {
var axis = Cartesian3.normalize(new Cartesian3(1.0, -1.0, 1.0), new Cartesian3());
var angle = CesiumMath.PI_OVER_FOUR;
var quat = Quaternion.fromAxisAngle(axis, angle);
var result = new Cartesian3();
var log = Quaternion.log(quat, result);
var expected = Cartesian3.multiplyByScalar(axis, angle * 0.5, new Cartesian3());
expect(log).toBe(result);
expect(log).toEqualEpsilon(expected, CesiumMath.EPSILON15);
});
it('exp works', function() {
var axis = Cartesian3.normalize(new Cartesian3(1.0, -1.0, 1.0), new Cartesian3());
var angle = CesiumMath.PI_OVER_FOUR;
var cartesian = Cartesian3.multiplyByScalar(axis, angle * 0.5, new Cartesian3());
var result = new Quaternion();
var exp = Quaternion.exp(cartesian, result);
var expected = Quaternion.fromAxisAngle(axis, angle);
expect(exp).toBe(result);
expect(exp).toEqualEpsilon(expected, CesiumMath.EPSILON15);
});
it('squad and computeInnerQuadrangle work', function() {
var q0 = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, 0.0);
var q1 = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, CesiumMath.PI_OVER_FOUR);
var q2 = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, CesiumMath.PI_OVER_FOUR);
var q3 = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, -CesiumMath.PI_OVER_FOUR);
var s1Result = new Quaternion();
var s1 = Quaternion.computeInnerQuadrangle(q0, q1, q2, s1Result);
expect(s1).toBe(s1Result);
var s2 = Quaternion.computeInnerQuadrangle(q1, q2, q3, new Quaternion());
var squadResult = new Quaternion();
var squad = Quaternion.squad(q1, q2, s1, s2, 0.0, squadResult);
expect(squad).toBe(squadResult);
expect(squad).toEqualEpsilon(q1, CesiumMath.EPSILON15);
});
it('fastSlerp works', function() {
var start = Quaternion.normalize(new Quaternion(0.0, 0.0, 0.0, 1.0), new Quaternion());
var end = new Quaternion(0.0, 0.0, Math.sin(CesiumMath.PI_OVER_FOUR), Math.cos(CesiumMath.PI_OVER_FOUR));
var expected = new Quaternion(0.0, 0.0, Math.sin(Math.PI / 8.0), Math.cos(Math.PI / 8.0));
var result = new Quaternion();
var returnedResult = Quaternion.fastSlerp(start, end, 0.5, result);
expect(result).toEqualEpsilon(expected, CesiumMath.EPSILON6);
expect(result).toBe(returnedResult);
});
it('fastSlerp works with a result parameter that is an input parameter', function() {
var start = Quaternion.normalize(new Quaternion(0.0, 0.0, 0.0, 1.0), new Quaternion());
var end = new Quaternion(0.0, 0.0, Math.sin(CesiumMath.PI_OVER_FOUR), Math.cos(CesiumMath.PI_OVER_FOUR));
var expected = new Quaternion(0.0, 0.0, Math.sin(Math.PI / 8.0), Math.cos(Math.PI / 8.0));
var returnedResult = Quaternion.fastSlerp(start, end, 0.5, start);
expect(start).toEqualEpsilon(expected, CesiumMath.EPSILON6);
expect(start).toBe(returnedResult);
});
it('fastSlerp works with obtuse angles', function() {
var start = Quaternion.normalize(new Quaternion(0.0, 0.0, 0.0, -1.0), new Quaternion());
var end = new Quaternion(0.0, 0.0, Math.sin(CesiumMath.PI_OVER_FOUR), Math.cos(CesiumMath.PI_OVER_FOUR));
var expected = new Quaternion(0.0, 0.0, -Math.sin(Math.PI / 8.0), -Math.cos(Math.PI / 8.0));
expect(Quaternion.fastSlerp(start, end, 0.5, new Quaternion())).toEqualEpsilon(expected, CesiumMath.EPSILON6);
});
it('fastSlerp vs slerp', function() {
var start = Quaternion.normalize(new Quaternion(0.0, 0.0, 0.0, 1.0), new Quaternion());
var end = new Quaternion(0.0, 0.0, Math.sin(CesiumMath.PI_OVER_FOUR), Math.cos(CesiumMath.PI_OVER_FOUR));
var expected = Quaternion.slerp(start, end, 0.25, new Quaternion());
var actual = Quaternion.fastSlerp(start, end, 0.25, new Quaternion());
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON6);
expected = Quaternion.slerp(start, end, 0.5, new Quaternion());
actual = Quaternion.fastSlerp(start, end, 0.5, new Quaternion());
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON6);
expected = Quaternion.slerp(start, end, 0.75, new Quaternion());
actual = Quaternion.fastSlerp(start, end, 0.75, new Quaternion());
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON6);
});
it('fastSquad works', function() {
var q0 = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, 0.0);
var q1 = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, CesiumMath.PI_OVER_FOUR);
var q2 = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, CesiumMath.PI_OVER_FOUR);
var q3 = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, -CesiumMath.PI_OVER_FOUR);
var s1 = Quaternion.computeInnerQuadrangle(q0, q1, q2, new Quaternion());
var s2 = Quaternion.computeInnerQuadrangle(q1, q2, q3, new Quaternion());
var squadResult = new Quaternion();
var squad = Quaternion.fastSquad(q1, q2, s1, s2, 0.0, squadResult);
expect(squad).toBe(squadResult);
expect(squad).toEqualEpsilon(q1, CesiumMath.EPSILON6);
});
it('fastSquad vs squad', function() {
var q0 = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, 0.0);
var q1 = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, CesiumMath.PI_OVER_FOUR);
var q2 = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, CesiumMath.PI_OVER_FOUR);
var q3 = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, -CesiumMath.PI_OVER_FOUR);
var s1 = Quaternion.computeInnerQuadrangle(q0, q1, q2, new Quaternion());
var s2 = Quaternion.computeInnerQuadrangle(q1, q2, q3, new Quaternion());
var actual = Quaternion.fastSquad(q1, q2, s1, s2, 0.25, new Quaternion());
var expected = Quaternion.squad(q1, q2, s1, s2, 0.25, new Quaternion());
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON6);
actual = Quaternion.fastSquad(q1, q2, s1, s2, 0.5, new Quaternion());
expected = Quaternion.squad(q1, q2, s1, s2, 0.5, new Quaternion());
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON6);
actual = Quaternion.fastSquad(q1, q2, s1, s2, 0.75, new Quaternion());
expected = Quaternion.squad(q1, q2, s1, s2, 0.75, new Quaternion());
expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON6);
});
it('equals', function() {
var quaternion = new Quaternion(1.0, 2.0, 3.0, 4.0);
expect(Quaternion.equals(quaternion, new Quaternion(1.0, 2.0, 3.0, 4.0))).toEqual(true);
expect(Quaternion.equals(quaternion, new Quaternion(2.0, 2.0, 3.0, 4.0))).toEqual(false);
expect(Quaternion.equals(quaternion, new Quaternion(2.0, 1.0, 3.0, 4.0))).toEqual(false);
expect(Quaternion.equals(quaternion, new Quaternion(1.0, 2.0, 4.0, 4.0))).toEqual(false);
expect(Quaternion.equals(quaternion, new Quaternion(1.0, 2.0, 3.0, 5.0))).toEqual(false);
expect(Quaternion.equals(quaternion, undefined)).toEqual(false);
});
it('equalsEpsilon', function() {
var quaternion = new Quaternion(1.0, 2.0, 3.0, 4.0);
expect(Quaternion.equalsEpsilon(quaternion, new Quaternion(1.0, 2.0, 3.0, 4.0), 0.0)).toEqual(true);
expect(Quaternion.equalsEpsilon(quaternion, new Quaternion(1.0, 2.0, 3.0, 4.0), 1.0)).toEqual(true);
expect(Quaternion.equalsEpsilon(quaternion, new Quaternion(2.0, 2.0, 3.0, 4.0), 1.0)).toEqual(true);
expect(Quaternion.equalsEpsilon(quaternion, new Quaternion(1.0, 3.0, 3.0, 4.0), 1.0)).toEqual(true);
expect(Quaternion.equalsEpsilon(quaternion, new Quaternion(1.0, 2.0, 4.0, 4.0), 1.0)).toEqual(true);
expect(Quaternion.equalsEpsilon(quaternion, new Quaternion(1.0, 2.0, 3.0, 5.0), 1.0)).toEqual(true);
expect(Quaternion.equalsEpsilon(quaternion, new Quaternion(2.0, 2.0, 3.0, 4.0), 0.99999)).toEqual(false);
expect(Quaternion.equalsEpsilon(quaternion, new Quaternion(1.0, 3.0, 3.0, 4.0), 0.99999)).toEqual(false);
expect(Quaternion.equalsEpsilon(quaternion, new Quaternion(1.0, 2.0, 4.0, 4.0), 0.99999)).toEqual(false);
expect(Quaternion.equalsEpsilon(quaternion, new Quaternion(1.0, 2.0, 3.0, 5.0), 0.99999)).toEqual(false);
expect(Quaternion.equalsEpsilon(quaternion, undefined, 1)).toEqual(false);
});
it('toString', function() {
var quaternion = new Quaternion(1.123, 2.345, 6.789, 6.123);
expect(quaternion.toString()).toEqual('(1.123, 2.345, 6.789, 6.123)');
});
it('fromAxisAngle throws with undefined axis', function() {
expect(function() {
Quaternion.fromAxisAngle(undefined, 1.0);
}).toThrowDeveloperError();
});
it('fromAxisAngle throws with non-numeric angle', function() {
expect(function() {
Quaternion.fromAxisAngle(Cartesian3.UNIT_X, {});
}).toThrowDeveloperError();
});
it('fromRotationMatrix throws with undefined matrix', function() {
expect(function() {
Quaternion.fromRotationMatrix(undefined);
}).toThrowDeveloperError();
});
it('clone returns undefined with no parameter', function() {
expect(Quaternion.clone()).toBeUndefined();
});
it('conjugate throws with no parameter', function() {
expect(function() {
Quaternion.conjugate();
}).toThrowDeveloperError();
});
it('magnitudeSquared throws with no parameter', function() {
expect(function() {
Quaternion.magnitudeSquared();
}).toThrowDeveloperError();
});
it('magnitude throws with no parameter', function() {
expect(function() {
Quaternion.magnitude();
}).toThrowDeveloperError();
});
it('normalize throws with no parameter', function() {
expect(function() {
Quaternion.normalize();
}).toThrowDeveloperError();
});
it('inverse throws with no parameter', function() {
expect(function() {
Quaternion.inverse();
}).toThrowDeveloperError();
});
it('dot throws with no left parameter', function() {
expect(function() {
Quaternion.dot(undefined, new Quaternion());
}).toThrowDeveloperError();
});
it('dot throws with no right parameter', function() {
expect(function() {
Quaternion.dot(new Quaternion(), undefined);
}).toThrowDeveloperError();
});
it('multiply throws with no right parameter', function() {
expect(function() {
Quaternion.multiply(new Quaternion(), undefined);
}).toThrowDeveloperError();
});
it('multiply throws with no left parameter', function() {
expect(function() {
Quaternion.multiply(undefined, new Quaternion());
}).toThrowDeveloperError();
});
it('add throws with no left parameter', function() {
expect(function() {
Quaternion.add(undefined, new Quaternion());
}).toThrowDeveloperError();
});
it('add throws with no right parameter', function() {
expect(function() {
Quaternion.add(new Quaternion(), undefined);
}).toThrowDeveloperError();
});
it('subtract throws with no left parameter', function() {
expect(function() {
Quaternion.subtract(undefined, new Quaternion());
}).toThrowDeveloperError();
});
it('subtract throws with no right parameter', function() {
expect(function() {
Quaternion.subtract(new Quaternion(), undefined);
}).toThrowDeveloperError();
});
it('multiplyByScalar throws with no quaternion parameter', function() {
expect(function() {
Quaternion.multiplyByScalar(undefined, 2.0);
}).toThrowDeveloperError();
});
it('multiplyByScalar throws with no scalar parameter', function() {
expect(function() {
Quaternion.multiplyByScalar(new Quaternion(), undefined);
}).toThrowDeveloperError();
});
it('divideByScalar throws with no quaternion parameter', function() {
expect(function() {
Quaternion.divideByScalar(undefined, 2.0);
}).toThrowDeveloperError();
});
it('divideByScalar throws with no scalar parameter', function() {
expect(function() {
Quaternion.divideByScalar(new Quaternion(), undefined);
}).toThrowDeveloperError();
});
it('axis throws with no parameter', function() {
expect(function() {
Quaternion.computeAxis(undefined);
}).toThrowDeveloperError();
});
it('angle throws with no parameter', function() {
expect(function() {
Quaternion.computeAngle(undefined);
}).toThrowDeveloperError();
});
it('negate throws with no quaternion parameter', function() {
expect(function() {
Quaternion.negate(undefined);
}).toThrowDeveloperError();
});
it('lerp throws with no start parameter', function() {
var end = new Quaternion(8.0, 20.0, 6.0);
var t = 0.25;
expect(function() {
Quaternion.lerp(undefined, end, t);
}).toThrowDeveloperError();
});
it('lerp throws with no end parameter', function() {
var start = new Quaternion(4.0, 8.0, 6.0);
var t = 0.25;
expect(function() {
Quaternion.lerp(start, undefined, t);
}).toThrowDeveloperError();
});
it('lerp throws with no t parameter', function() {
var start = new Quaternion(4.0, 8.0, 6.0, 7.0);
var end = new Quaternion(8.0, 20.0, 6.0, 7.0);
expect(function() {
Quaternion.lerp(start, end, undefined);
}).toThrowDeveloperError();
});
it('slerp throws with no start parameter', function() {
var end = new Quaternion(8.0, 20.0, 6.0);
var t = 0.25;
expect(function() {
Quaternion.slerp(undefined, end, t);
}).toThrowDeveloperError();
});
it('slerp throws with no end parameter', function() {
var start = new Quaternion(4.0, 8.0, 6.0);
var t = 0.25;
expect(function() {
Quaternion.slerp(start, undefined, t);
}).toThrowDeveloperError();
});
it('slerp throws with no t parameter', function() {
var start = new Quaternion(4.0, 8.0, 6.0, 7.0);
var end = new Quaternion(8.0, 20.0, 6.0, 7.0);
expect(function() {
Quaternion.slerp(start, end, undefined);
}).toThrowDeveloperError();
});
it('log throws with no quaternion parameter', function() {
expect(function() {
Quaternion.log();
}).toThrowDeveloperError();
});
it('exp throws with no cartesian parameter', function() {
expect(function() {
Quaternion.exp();
}).toThrowDeveloperError();
});
it('computeInnerQuadrangle throws without q0, q1, or q2 parameter', function() {
expect(function() {
Quaternion.computeInnerQuadrangle();
}).toThrowDeveloperError();
});
it('squad throws without q0, q1, s0, or s1 parameter', function() {
expect(function() {
Quaternion.squad();
}).toThrowDeveloperError();
});
it('squad throws without t parameter', function() {
expect(function() {
Quaternion.squad(new Quaternion(), new Quaternion(), new Quaternion(), new Quaternion());
}).toThrowDeveloperError();
});
it('equalsEpsilon throws with no epsilon', function() {
expect(function() {
Quaternion.equalsEpsilon(new Quaternion(), new Quaternion(), undefined);
}).toThrowDeveloperError();
});
it('conjugate throws with no result', function() {
expect(function() {
Quaternion.conjugate(new Quaternion());
}).toThrowDeveloperError();
});
it('add throws with no result', function() {
expect(function() {
Quaternion.add(new Quaternion(), new Quaternion());
}).toThrowDeveloperError();
});
it('subtract throws with no result', function() {
expect(function() {
Quaternion.subtract(new Quaternion(), new Quaternion());
}).toThrowDeveloperError();
});
it('negate throws with no result', function() {
expect(function() {
Quaternion.negate(new Quaternion());
}).toThrowDeveloperError();
});
it('multiply throws with no result', function() {
expect(function() {
Quaternion.multiply(new Quaternion(), new Quaternion());
}).toThrowDeveloperError();
});
it('multiplyByScalar throws with no result', function() {
expect(function() {
Quaternion.multiplyByScalar(new Quaternion(), 3);
}).toThrowDeveloperError();
});
it('divideByScalar throws with no result', function() {
expect(function() {
Quaternion.divideByScalar(new Quaternion(), 3);
}).toThrowDeveloperError();
});
it('axis throws with no result', function() {
expect(function() {
Quaternion.computeAxis(new Quaternion());
}).toThrowDeveloperError();
});
it('lerp throws with no result', function() {
expect(function() {
Quaternion.lerp(new Quaternion(), new Quaternion(), 2);
}).toThrowDeveloperError();
});
it('slerp throws with no result', function() {
expect(function() {
Quaternion.slerp(new Quaternion(), new Quaternion(), 2);
}).toThrowDeveloperError();
});
it('log throws with no result', function() {
expect(function() {
Quaternion.log(new Quaternion());
}).toThrowDeveloperError();
});
it('exp throws with no result', function() {
expect(function() {
Quaternion.exp(new Cartesian3());
}).toThrowDeveloperError();
});
it('computeInnerQuadrangle throws with no result', function() {
expect(function() {
Quaternion.computeInnerQuadrangle(new Quaternion(), new Quaternion(), new Quaternion());
}).toThrowDeveloperError();
});
it('squad throws with no result', function() {
expect(function() {
Quaternion.squad(new Quaternion(), new Quaternion(), new Quaternion(), new Quaternion(), 3);
}).toThrowDeveloperError();
});
it('fastSlerp throws with no start', function() {
expect(function() {
Quaternion.fastSlerp();
}).toThrowDeveloperError();
});
it('fastSlerp throws with no end', function() {
expect(function() {
Quaternion.fastSlerp(new Quaternion());
}).toThrowDeveloperError();
});
it('fastSlerp throws with no t', function() {
expect(function() {
Quaternion.fastSlerp(new Quaternion(), new Quaternion());
}).toThrowDeveloperError();
});
it('fastSlerp throws with no result', function() {
expect(function() {
Quaternion.fastSlerp(new Quaternion(), new Quaternion(), 2);
}).toThrowDeveloperError();
});
it('fastSquad throws with no q0', function() {
expect(function() {
Quaternion.fastSquad();
}).toThrowDeveloperError();
});
it('fastSquad throws with no q1', function() {
expect(function() {
Quaternion.fastSquad(new Quaternion());
}).toThrowDeveloperError();
});
it('fastSquad throws with no s0', function() {
expect(function() {
Quaternion.fastSquad(new Quaternion(), new Quaternion());
}).toThrowDeveloperError();
});
it('fastSquad throws with no s1', function() {
expect(function() {
Quaternion.fastSquad(new Quaternion(), new Quaternion(), new Quaternion());
}).toThrowDeveloperError();
});
it('fastSquad throws with no t', function() {
expect(function() {
Quaternion.fastSquad(new Quaternion(), new Quaternion(), new Quaternion(), new Quaternion());
}).toThrowDeveloperError();
});
it('fastSquad throws with no result', function() {
expect(function() {
Quaternion.fastSquad(new Quaternion(), new Quaternion(), new Quaternion(), new Quaternion(), 3);
}).toThrowDeveloperError();
});
var q = new Quaternion(1, 2, 3, 4);
Quaternion.normalize(q, q);
createPackableSpecs(Quaternion, q, [q.x, q.y, q.z, q.w]);
});