2024-02-29 13:54:33 -06:00
|
|
|
var Spline = {};
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.sample_angle = function (type, points, angle) {
|
2024-03-19 14:39:19 -05:00
|
|
|
if (type === 0) return spline.catmull(points, angle);
|
2024-09-26 11:36:09 -05:00
|
|
|
else if (type === 1) return spline.bezier(points, angle);
|
2024-03-19 14:39:19 -05:00
|
|
|
return undefined;
|
2024-09-26 11:36:09 -05:00
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.bezier_loop = function (cp) {
|
|
|
|
cp.push(Vector.reflect_point(cp.at(-2), cp.at(-1)));
|
|
|
|
cp.push(Vector.reflect_point(cp[1], cp[0]));
|
2024-02-29 13:54:33 -06:00
|
|
|
cp.push(cp[0].slice());
|
|
|
|
return cp;
|
2024-09-26 11:36:09 -05:00
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.bezier_node_count = function (cp) {
|
2024-02-29 13:54:33 -06:00
|
|
|
if (cp.length === 4) return 2;
|
2024-09-26 11:36:09 -05:00
|
|
|
return 2 + (cp.length - 4) / 3;
|
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.is_bezier = function (t) {
|
|
|
|
return t === Spline.type.bezier;
|
|
|
|
};
|
|
|
|
Spline.is_catmull = function (t) {
|
|
|
|
return t === Spline.type.catmull;
|
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.bezier2catmull = function (b) {
|
2024-02-29 13:54:33 -06:00
|
|
|
var c = [];
|
2024-09-26 11:36:09 -05:00
|
|
|
for (var i = 0; i < b.length; i += 3) c.push(b[i]);
|
2024-02-29 13:54:33 -06:00
|
|
|
return c;
|
2024-09-26 11:36:09 -05:00
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.catmull2bezier = function (c) {
|
2024-02-29 13:54:33 -06:00
|
|
|
var b = [];
|
2024-09-26 11:36:09 -05:00
|
|
|
for (var i = 1; i < c.length - 2; i++) {
|
2024-02-29 13:54:33 -06:00
|
|
|
b.push(c[i].slice());
|
2024-09-26 11:36:09 -05:00
|
|
|
b.push(
|
|
|
|
c[i + 1]
|
|
|
|
.sub(c[i - 1])
|
|
|
|
.scale(0.25)
|
|
|
|
.add(c[i]),
|
|
|
|
);
|
|
|
|
b.push(
|
|
|
|
c[i]
|
|
|
|
.sub(c[i + 2])
|
|
|
|
.scale(0.25)
|
|
|
|
.add(c[i + 1]),
|
|
|
|
);
|
2024-02-29 13:54:33 -06:00
|
|
|
}
|
2024-09-26 11:36:09 -05:00
|
|
|
b.push(c[c.length - 2]);
|
2024-02-29 13:54:33 -06:00
|
|
|
return b;
|
2024-09-26 11:36:09 -05:00
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.catmull_loop = function (cp) {
|
2024-02-29 13:54:33 -06:00
|
|
|
cp = cp.slice();
|
|
|
|
cp.unshift(cp.last());
|
|
|
|
cp.push(cp[1]);
|
|
|
|
cp.push(cp[2]);
|
|
|
|
return cp;
|
2024-09-26 11:36:09 -05:00
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.catmull_caps = function (cp) {
|
2024-03-09 18:22:06 -06:00
|
|
|
if (cp.length < 2) return;
|
2024-02-29 13:54:33 -06:00
|
|
|
cp = cp.slice();
|
|
|
|
cp.unshift(cp[0].sub(cp[1]).add(cp[0]));
|
|
|
|
cp.push(cp.last().sub(cp.at(-2).add(cp.last())));
|
|
|
|
return cp;
|
2024-09-26 11:36:09 -05:00
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-03-09 18:22:06 -06:00
|
|
|
Spline.catmull_caps.doc = "Given a set of control points cp, return the necessary caps added to the spline.";
|
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.catmull2bezier.doc = "Given a set of control points C for a camtull-rom type curve, return a set of cubic bezier points to give the same curve.";
|
2024-02-29 13:54:33 -06:00
|
|
|
|
|
|
|
Spline.type = {
|
|
|
|
catmull: 0,
|
|
|
|
bezier: 1,
|
|
|
|
bspline: 2,
|
2024-09-26 11:36:09 -05:00
|
|
|
cubichermite: 3,
|
2024-02-29 13:54:33 -06:00
|
|
|
};
|
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.bezier_tan_partner = function (points, i) {
|
|
|
|
if (i % 3 === 0) return undefined;
|
|
|
|
var partner_i = i % 3 === 2 ? i - 1 : i + 1;
|
2024-02-29 13:54:33 -06:00
|
|
|
return points[i];
|
2024-09-26 11:36:09 -05:00
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.bezier_cp_mirror = function (points, i) {
|
|
|
|
if (i % 3 === 0) return undefined;
|
|
|
|
var partner_i = i % 3 === 2 ? i + 2 : i - 2;
|
|
|
|
var node_i = i % 3 === 2 ? i + 1 : i - 1;
|
2024-02-29 13:54:33 -06:00
|
|
|
if (partner_i >= points.length || node_i >= points.length) return;
|
|
|
|
points[partner_i] = points[node_i].sub(points[i]).add(points[node_i]);
|
2024-09-26 11:36:09 -05:00
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.bezier_point_handles = function (points, i) {
|
|
|
|
if (!Spline.bezier_is_node(points, i)) return [];
|
|
|
|
var a = i - 1;
|
|
|
|
var b = i + 1;
|
|
|
|
var c = [];
|
|
|
|
if (a > 0) c.push(a);
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
if (b < points.length) c.push(b);
|
2024-02-29 13:54:33 -06:00
|
|
|
|
|
|
|
return c;
|
2024-09-26 11:36:09 -05:00
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.bezier_nodes = function (points) {
|
2024-02-29 13:54:33 -06:00
|
|
|
var c = [];
|
2024-09-26 11:36:09 -05:00
|
|
|
for (var i = 0; i < points.length; i += 3) c.push(points[i].slice());
|
2024-02-29 13:54:33 -06:00
|
|
|
|
|
|
|
return c;
|
2024-09-26 11:36:09 -05:00
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
Spline.bezier_is_node = function (points, i) {
|
|
|
|
return i % 3 === 0;
|
|
|
|
};
|
|
|
|
Spline.bezier_is_handle = function (points, i) {
|
|
|
|
return !Spline.bezier_is_node(points, i);
|
|
|
|
};
|
2024-02-29 13:54:33 -06:00
|
|
|
|
2024-09-26 11:36:09 -05:00
|
|
|
return { Spline };
|