prosperon/scripts/spline.js
2024-03-09 14:27:02 -06:00

116 lines
2.6 KiB
JavaScript

var Spline = {};
Spline.sample_angle = function(type, points, angle) {
return spline_cmd(0, type, points[0].length, points, angle);
}
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]));
cp.push(cp[0].slice());
return cp;
}
Spline.bezier_node_count = function(cp)
{
if (cp.length === 4) return 2;
return 2 + (cp.length-4)/3;
}
Spline.is_bezier = function(t) { return t === Spline.type.bezier; }
Spline.is_catmull = function(t) { return t === Spline.type.catmull; }
Spline.bezier2catmull = function(b)
{
var c = [];
for (var i = 0; i < b.length; i += 3)
c.push(b[i]);
return c;
}
Spline.catmull2bezier = function(c)
{
var b = [];
for (var i = 1; i < c.length-2; i++) {
b.push(c[i].slice());
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]));
}
b.push(c[c.length-2]);
return b;
}
Spline.catmull_loop = function(cp)
{
cp = cp.slice();
cp.unshift(cp.last());
cp.push(cp[1]);
cp.push(cp[2]);
return cp;
}
Spline.catmull_caps = function(cp)
{
if (cp.length < 2) return;
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;
}
Spline.catmull_caps.doc = "Given a set of control points cp, return the necessary caps added to the spline.";
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."
Spline.type = {
catmull: 0,
bezier: 1,
bspline: 2,
cubichermite: 3
};
Spline.bezier_tan_partner = function(points, i)
{
if (i%3 === 0) return undefined;
var partner_i = (i%3) === 2 ? i-1 : i+1;
return points[i];
}
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;
if (partner_i >= points.length || node_i >= points.length) return;
points[partner_i] = points[node_i].sub(points[i]).add(points[node_i]);
}
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);
if (b < points.length)
c.push(b);
return c;
}
Spline.bezier_nodes = function(points)
{
var c = [];
for (var i = 0; i < points.length; i+=3)
c.push(points[i].slice());
return c;
}
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); }
return {Spline};