mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-20 07:21:43 +02:00
81 lines
2.2 KiB
JavaScript
81 lines
2.2 KiB
JavaScript
let curve;
|
|
|
|
setup() {
|
|
const type = this.parameters.type ?? `quadratic`;
|
|
curve = (type === `quadratic`) ? Bezier.defaultQuadratic(this) : Bezier.defaultCubic(this);
|
|
setMovable(curve.points);
|
|
}
|
|
|
|
draw() {
|
|
clear();
|
|
curve.drawSkeleton();
|
|
curve.drawCurve();
|
|
curve.drawPoints();
|
|
|
|
// Similar to aligning, we transform the curve first
|
|
let translated = this.translatePoints(curve.points);
|
|
let rotated = this.rotatePoints(translated);
|
|
let rtcurve = new Bezier(this, rotated);
|
|
let extrema = rtcurve.extrema();
|
|
|
|
// and the we run the regular bounding box code
|
|
let minx = Number.MAX_SAFE_INTEGER,
|
|
miny = minx,
|
|
maxx = Number.MIN_SAFE_INTEGER,
|
|
maxy = maxx;
|
|
|
|
setStroke(`red`);
|
|
|
|
[0, ...extrema.x, ...extrema.y, 1].forEach(t => {
|
|
let p = curve.get(t);
|
|
let rtp = rtcurve.get(t);
|
|
if (rtp.x < minx) minx = rtp.x;
|
|
if (rtp.x > maxx) maxx = rtp.x;
|
|
if (rtp.y < miny) miny = rtp.y;
|
|
if (rtp.y > maxy) maxy = rtp.y;
|
|
if (t > 0 && t< 1) circle(p.x, p.y, 3);
|
|
});
|
|
|
|
noFill();
|
|
setStroke(`#0F0`);
|
|
|
|
// But, crucially, we now need to reverse-transform the bbox corners:
|
|
|
|
let tx = curve.points[0].x;
|
|
let ty = curve.points[0].y;
|
|
let a = rotated[0].a;
|
|
|
|
start();
|
|
vertex(tx + minx * cos(a) - miny * sin(a), ty + minx * sin(a) + miny * cos(a));
|
|
vertex(tx + maxx * cos(a) - miny * sin(a), ty + maxx * sin(a) + miny * cos(a));
|
|
vertex(tx + maxx * cos(a) - maxy * sin(a), ty + maxx * sin(a) + maxy * cos(a));
|
|
vertex(tx + minx * cos(a) - maxy * sin(a), ty + minx * sin(a) + maxy * cos(a));
|
|
end(true);
|
|
}
|
|
|
|
translatePoints(points) {
|
|
// translate to (0,0)
|
|
let m = points[0];
|
|
return points.map(v => {
|
|
return {
|
|
x: v.x - m.x,
|
|
y: v.y - m.y
|
|
}
|
|
});
|
|
}
|
|
|
|
rotatePoints(points) {
|
|
// rotate so that last point is (...,0)
|
|
let last = points.length - 1;
|
|
let dx = points[last].x;
|
|
let dy = points[last].y;
|
|
let a = atan2(dy, dx);
|
|
return points.map(v => {
|
|
return {
|
|
a: a,
|
|
x: v.x * cos(-a) - v.y * sin(-a),
|
|
y: v.x * sin(-a) + v.y * cos(-a)
|
|
};
|
|
});
|
|
}
|