1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-08-18 06:21:26 +02:00
Files
2020-09-19 22:51:19 -07:00

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();
}
}