You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
209 lines
5.3 KiB
JavaScript
209 lines
5.3 KiB
JavaScript
import { Cartesian3 } from "../../Source/Cesium.js";
|
|
import { CatmullRomSpline } from "../../Source/Cesium.js";
|
|
import { HermiteSpline } from "../../Source/Cesium.js";
|
|
import { Math as CesiumMath } from "../../Source/Cesium.js";
|
|
|
|
describe("Core/CatmullRomSpline", function () {
|
|
var points;
|
|
var times;
|
|
|
|
beforeEach(function () {
|
|
points = [
|
|
new Cartesian3(-1.0, -1.0, 0.0),
|
|
new Cartesian3(-0.5, -0.125, 0.0),
|
|
new Cartesian3(0.5, 0.125, 0.0),
|
|
new Cartesian3(1.0, 1.0, 0.0),
|
|
];
|
|
times = [0.0, 1.0, 2.0, 3.0];
|
|
});
|
|
|
|
it("constructor throws without points or times", function () {
|
|
expect(function () {
|
|
return new CatmullRomSpline();
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("constructor throws when control points length is less than 2", function () {
|
|
expect(function () {
|
|
return new CatmullRomSpline({
|
|
points: [Cartesian3.ZERO],
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("constructor throws when times.length is not equal to points.length", function () {
|
|
expect(function () {
|
|
return new CatmullRomSpline({
|
|
points: points,
|
|
times: [0.0, 1.0],
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("sets start and end tangents", function () {
|
|
var start = Cartesian3.subtract(points[1], points[0], new Cartesian3());
|
|
var end = Cartesian3.subtract(
|
|
points[points.length - 1],
|
|
points[points.length - 2],
|
|
new Cartesian3()
|
|
);
|
|
var crs = new CatmullRomSpline({
|
|
points: points,
|
|
times: times,
|
|
firstTangent: start,
|
|
lastTangent: end,
|
|
});
|
|
|
|
expect(start).toEqual(crs.firstTangent);
|
|
expect(end).toEqual(crs.lastTangent);
|
|
});
|
|
|
|
it("computes start and end tangents", function () {
|
|
var controlPoint0 = Cartesian3.clone(points[0]);
|
|
var controlPoint1 = Cartesian3.clone(points[1]);
|
|
var controlPoint2 = Cartesian3.clone(points[2]);
|
|
|
|
var start = new Cartesian3();
|
|
start = Cartesian3.multiplyByScalar(
|
|
Cartesian3.subtract(
|
|
Cartesian3.subtract(
|
|
Cartesian3.multiplyByScalar(controlPoint1, 2.0, start),
|
|
controlPoint2,
|
|
start
|
|
),
|
|
controlPoint0,
|
|
start
|
|
),
|
|
0.5,
|
|
start
|
|
);
|
|
|
|
var controlPointn0 = Cartesian3.clone(points[points.length - 1]);
|
|
var controlPointn1 = Cartesian3.clone(points[points.length - 2]);
|
|
var controlPointn2 = Cartesian3.clone(points[points.length - 3]);
|
|
|
|
var end = new Cartesian3();
|
|
end = Cartesian3.multiplyByScalar(
|
|
Cartesian3.add(
|
|
Cartesian3.subtract(
|
|
controlPointn0,
|
|
Cartesian3.multiplyByScalar(controlPointn1, 2.0, end),
|
|
end
|
|
),
|
|
controlPointn2,
|
|
end
|
|
),
|
|
0.5,
|
|
end
|
|
);
|
|
|
|
var crs = new CatmullRomSpline({
|
|
points: points,
|
|
times: times,
|
|
});
|
|
|
|
expect(start).toEqual(crs.firstTangent);
|
|
expect(end).toEqual(crs.lastTangent);
|
|
});
|
|
|
|
it("evaluate throws without time", function () {
|
|
var crs = new CatmullRomSpline({
|
|
points: points,
|
|
times: times,
|
|
});
|
|
|
|
expect(function () {
|
|
crs.evaluate();
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("evaluate throws when time is out of range", function () {
|
|
var crs = new CatmullRomSpline({
|
|
points: points,
|
|
times: times,
|
|
});
|
|
|
|
expect(function () {
|
|
crs.evaluate(times[0] - 1.0);
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("check Catmull-Rom spline against a Hermite spline", function () {
|
|
var crs = new CatmullRomSpline({
|
|
points: points,
|
|
times: times,
|
|
});
|
|
|
|
var tangents = [crs.firstTangent];
|
|
for (var i = 1; i < points.length - 1; ++i) {
|
|
tangents.push(
|
|
Cartesian3.multiplyByScalar(
|
|
Cartesian3.subtract(points[i + 1], points[i - 1], new Cartesian3()),
|
|
0.5,
|
|
new Cartesian3()
|
|
)
|
|
);
|
|
}
|
|
tangents.push(crs.lastTangent);
|
|
|
|
var hs = HermiteSpline.createC1({
|
|
points: points,
|
|
tangents: tangents,
|
|
times: times,
|
|
});
|
|
|
|
var granularity = 0.5;
|
|
for (var j = times[0]; j <= times[points.length - 1]; j = j + granularity) {
|
|
expect(hs.evaluate(j)).toEqualEpsilon(
|
|
crs.evaluate(j),
|
|
CesiumMath.EPSILON4
|
|
);
|
|
}
|
|
});
|
|
|
|
it("evaluate with result parameter", function () {
|
|
var crs = new CatmullRomSpline({
|
|
points: points,
|
|
times: times,
|
|
});
|
|
var result = new Cartesian3();
|
|
|
|
var point = crs.evaluate(times[0], result);
|
|
expect(point).toBe(result);
|
|
expect(result).toEqual(points[0]);
|
|
});
|
|
|
|
it("spline with 2 control points defaults to lerp", function () {
|
|
points = points.slice(0, 2);
|
|
times = times.slice(0, 2);
|
|
|
|
var crs = new CatmullRomSpline({
|
|
points: points,
|
|
times: times,
|
|
});
|
|
|
|
var t = (times[0] + times[1]) * 0.5;
|
|
expect(crs.evaluate(t)).toEqual(
|
|
Cartesian3.lerp(points[0], points[1], t, new Cartesian3())
|
|
);
|
|
});
|
|
|
|
it("spline with 2 control points defaults to lerp and result parameter", function () {
|
|
points = points.slice(0, 2);
|
|
times = times.slice(0, 2);
|
|
|
|
var crs = new CatmullRomSpline({
|
|
points: points,
|
|
times: times,
|
|
});
|
|
|
|
var t = (times[0] + times[1]) * 0.5;
|
|
var result = new Cartesian3();
|
|
var actual = crs.evaluate(t, result);
|
|
expect(actual).toBe(result);
|
|
expect(actual).toEqual(
|
|
Cartesian3.lerp(points[0], points[1], t, new Cartesian3())
|
|
);
|
|
});
|
|
});
|