mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-18 06:21:26 +02:00
184 lines
5.1 KiB
JavaScript
184 lines
5.1 KiB
JavaScript
let points;
|
|
|
|
setup() {
|
|
var w = this.width,
|
|
h = this.height,
|
|
cx = w/2,
|
|
cy = h/2,
|
|
pad = 40,
|
|
type = this.type = this.parameters.type ?? `quadratic`;
|
|
|
|
if (type === `quadratic`) {
|
|
points = [
|
|
// first curve:
|
|
{x:cx,y:pad}, {x:w-pad,y:pad}, {x:w-pad,y:cy},
|
|
// subsequent curve
|
|
{x:w-pad,y:h-pad}, {x:cx,y:h-pad},
|
|
// subsequent curve
|
|
{x:pad,y:h-pad}, {x:pad,y:cy},
|
|
// final curve control point
|
|
{x:pad,y:pad}
|
|
];
|
|
} else {
|
|
let r = (w - 2*pad)/2,
|
|
k = 0.55228,
|
|
kr = k*r;
|
|
points = [
|
|
// first curve:
|
|
{x:cx,y:pad}, {x:cx+kr,y:pad}, {x:w-pad,y:cy-kr}, {x:w-pad,y:cy},
|
|
// subsequent curve
|
|
{x:w-pad,y:cy+kr}, {x:cx+kr,y:h-pad}, {x:cx,y:h-pad},
|
|
// subsequent curve
|
|
{x:cx-kr,y:h-pad}, {x:pad,y:cy+kr}, {x:pad,y:cy},
|
|
// final curve control point
|
|
{x:pad,y:cy-kr}, {x:cx-kr,y:pad}
|
|
];
|
|
}
|
|
setMovable(points);
|
|
}
|
|
|
|
draw() {
|
|
clear()
|
|
var pts = points;
|
|
var quad = pts.length === 8;
|
|
|
|
var c1 = quad ? new Bezier(this, pts[0],pts[1],pts[2]) : new Bezier(this, pts[0],pts[1],pts[2],pts[3]);
|
|
c1.drawSkeleton();
|
|
c1.drawCurve();
|
|
c1.drawPoints(false);
|
|
|
|
var c2 = quad ? new Bezier(this, pts[2],pts[3],pts[4]) : new Bezier(this, pts[3],pts[4],pts[5],pts[6]);
|
|
c2.drawSkeleton();
|
|
c2.drawCurve();
|
|
c2.drawPoints(false);
|
|
|
|
var c3 = quad ? new Bezier(this, pts[4],pts[5],pts[6]) : new Bezier(this, pts[6],pts[7],pts[8],pts[9]);
|
|
c3.drawSkeleton();
|
|
c3.drawCurve();
|
|
c3.drawPoints(false);
|
|
|
|
var c4 = quad ? new Bezier(this, pts[6],pts[7],pts[0]) : new Bezier(this, pts[9],pts[10],pts[11],pts[0]);
|
|
c4.drawSkeleton();
|
|
c4.drawCurve();
|
|
c4.drawPoints(false);
|
|
|
|
if (this.problem) {
|
|
noFill();
|
|
setStroke(`red`);
|
|
circle(this.problem.x, this.problem.y, 7);
|
|
}
|
|
}
|
|
|
|
movePointsQuadratic(i, link) {
|
|
const l = points.length;
|
|
|
|
// Logic for "conventional" moving of an on-curve point,
|
|
// moving its associated control points, too.
|
|
if (link === `conventional` && i%2 === 0) {
|
|
let ppl = points[(l+i-3)%l];
|
|
let pl = points[(l+i-1)%l];
|
|
let pr = points[(l+i+1)%l];
|
|
let ppr = points[(l+i+3)%l];
|
|
pl.x += this.cursor.diff.x;
|
|
pl.y += this.cursor.diff.y;
|
|
pr.x += this.cursor.diff.x;
|
|
pr.y += this.cursor.diff.y;
|
|
ppl.x -= this.cursor.diff.x;
|
|
ppl.y -= this.cursor.diff.y;
|
|
ppr.x -= this.cursor.diff.x;
|
|
ppr.y -= this.cursor.diff.y;
|
|
|
|
this.problem = points[(l+i+4)%l];
|
|
if (ppr.y === this.problem.y) {
|
|
this.problem = false;
|
|
}
|
|
}
|
|
|
|
// Moving a control points moves literally every
|
|
// other control points, too.
|
|
if (i%2 === 1) {
|
|
let c1 = points[(l+i-2)%l];
|
|
let p1 = points[(l+i-1)%l];
|
|
let p2 = points[(l+i+1)%l];
|
|
let c2 = points[(l+i+2)%l];
|
|
let p3 = points[(l+i+3)%l];
|
|
let c3 = points[(l+i+4)%l];
|
|
let p4 = points[(l+i+5)%l];
|
|
if (link === `derivative`) {
|
|
c1.x = p1.x + (p1.x - this.currentPoint.x)
|
|
c1.y = p1.y + (p1.y - this.currentPoint.y)
|
|
c2.x = p2.x + (p2.x - this.currentPoint.x)
|
|
c2.y = p2.y + (p2.y - this.currentPoint.y)
|
|
c3.x = p3.x + (p3.x - c2.x)
|
|
c3.y = p3.y + (p3.y - c2.y)
|
|
this.problem = false;
|
|
if (c3.x !== p4.x + (p4.x - c1.x) || c3.y !== p4.y + (p4.y - c1.y)) {
|
|
this.problem = c3;
|
|
}
|
|
}
|
|
if (link === `direction` || link === `conventional`) {
|
|
let a1 = atan2(this.currentPoint.y-p1.y,this.currentPoint.x-p1.x) + PI;
|
|
let d1 = dist(c1.x, c1.y, p1.x, p1.y);
|
|
c1.x = p1.x + d1 * cos(a1);
|
|
c1.y = p1.y + d1 * sin(a1);
|
|
let a2 = atan2(this.currentPoint.y-p2.y,this.currentPoint.x-p2.x) + PI;
|
|
let d2 = dist(c2.x, c2.y, p2.x, p2.y);
|
|
c2.x = p2.x + d2 * cos(a2);
|
|
c2.y = p2.y + d2 * sin(a2);
|
|
this.problem = c3;
|
|
}
|
|
}
|
|
}
|
|
|
|
movePointsCubic(i, link) {
|
|
const l = points.length;
|
|
|
|
// Logic for "conventional" moving of an on-curve point,
|
|
// moving its associated control points, too.
|
|
if (link === `conventional` && i%3 === 0) {
|
|
let left = points[(l+i-1)%l];
|
|
left.x += this.cursor.diff.x;
|
|
left.y += this.cursor.diff.y;
|
|
|
|
let right = points[(l+i+1)%l];
|
|
right.x += this.cursor.diff.x;
|
|
right.y += this.cursor.diff.y;
|
|
}
|
|
|
|
// Moving a control points moves the control "across its on-curve point".
|
|
if (i%3 > 0) {
|
|
let c, p;
|
|
if (i%3 === 1) {
|
|
c = points[(l+i-2)%l];
|
|
p = points[(l+i-1)%l];
|
|
}
|
|
if (i%3 === 2) {
|
|
c = points[(l+i+2)%l];
|
|
p = points[(l+i+1)%l];
|
|
}
|
|
if (link === `derivative`) {
|
|
c.x = p.x + (p.x - this.currentPoint.x)
|
|
c.y = p.y + (p.y - this.currentPoint.y)
|
|
}
|
|
if (link === `direction` || link === `conventional`) {
|
|
let a = atan2(this.currentPoint.y-p.y,this.currentPoint.x-p.x) + PI;
|
|
let d = dist(c.x, c.y, p.x, p.y);
|
|
c.x = p.x + d * cos(a);
|
|
c.y = p.y + d * sin(a);
|
|
}
|
|
}
|
|
}
|
|
|
|
onMouseMove() {
|
|
if (this.currentPoint) {
|
|
const position = points.indexOf(this.currentPoint);
|
|
const link = this.parameters.link;
|
|
if (this.type === `quadratic`) {
|
|
this.movePointsQuadratic(position, link);
|
|
} else {
|
|
this.movePointsCubic(position, link);
|
|
}
|
|
redraw();
|
|
}
|
|
}
|