mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-08 01:37:29 +02:00
204 lines
5.8 KiB
JavaScript
204 lines
5.8 KiB
JavaScript
var abs = Math.abs;
|
|
|
|
module.exports = {
|
|
setupQuadratic: function(api) {
|
|
api.setPanelCount(3);
|
|
var curve = api.getDefaultQuadratic();
|
|
curve.points[2].x -= 30;
|
|
api.setCurve(curve);
|
|
},
|
|
|
|
setupCubic: function(api) {
|
|
api.setPanelCount(3);
|
|
var curve = new api.Bezier([100,230, 30,160, 200,50, 210,160]);
|
|
curve.points[2].y -= 20;
|
|
api.setCurve(curve);
|
|
api.lut = curve.getLUT(100);
|
|
},
|
|
|
|
saveCurve: function(evt, api) {
|
|
if (!api.t) return;
|
|
if (!api.newcurve) return;
|
|
api.setCurve(api.newcurve);
|
|
api.t = false;
|
|
api.redraw();
|
|
},
|
|
|
|
findTValue: function(evt, api) {
|
|
var t = api.curve.on({x: evt.offsetX, y: evt.offsetY},7);
|
|
if (t < 0.05 || t > 0.95) return false;
|
|
return t;
|
|
},
|
|
|
|
markQB: function(evt, api) {
|
|
api.t = this.findTValue(evt, api);
|
|
if(api.t) {
|
|
var t = api.t,
|
|
t2 = 2*t,
|
|
top = t2*t - t2,
|
|
bottom = top + 1,
|
|
ratio = abs(top/bottom),
|
|
curve = api.curve,
|
|
A = api.A = curve.points[1],
|
|
B = api.B = curve.get(t);
|
|
api.C = api.utils.lli4(A, B, curve.points[0], curve.points[2]);
|
|
api.ratio = ratio;
|
|
this.dragQB(evt, api);
|
|
}
|
|
},
|
|
|
|
markCB: function(evt, api) {
|
|
api.t = this.findTValue(evt, api);
|
|
if(api.t) {
|
|
var t = api.t,
|
|
mt = (1-t),
|
|
t3 = t*t*t,
|
|
mt3 = mt*mt*mt,
|
|
bottom = t3 + mt3,
|
|
top = bottom - 1,
|
|
ratio = abs(top/bottom),
|
|
curve = api.curve,
|
|
hull = curve.hull(t),
|
|
A = api.A = hull[5],
|
|
B = api.B = curve.get(t);
|
|
api.db = curve.derivative(t);
|
|
api.C = api.utils.lli4(A, B, curve.points[0], curve.points[3]);
|
|
api.ratio = ratio;
|
|
this.dragCB(evt, api);
|
|
}
|
|
},
|
|
|
|
drag: function(evt, api) {
|
|
if (!api.t) return;
|
|
|
|
var newB = api.newB = {
|
|
x: evt.offsetX,
|
|
y: evt.offsetY
|
|
};
|
|
|
|
// now that we know A, B, C and the AB:BC ratio, we can compute the new A' based on the desired B'
|
|
api.newA = {
|
|
x: newB.x - (api.C.x - newB.x) / api.ratio,
|
|
y: newB.y - (api.C.y - newB.y) / api.ratio
|
|
};
|
|
},
|
|
|
|
dragQB: function(evt, api) {
|
|
if (!api.t) return;
|
|
this.drag(evt, api);
|
|
api.update = [api.newA];
|
|
},
|
|
|
|
dragCB: function(evt, api) {
|
|
if (!api.t) return;
|
|
this.drag(evt,api);
|
|
|
|
// preserve struts for B when repositioning
|
|
var curve = api.curve,
|
|
hull = curve.hull(api.t),
|
|
B = api.B,
|
|
Bl = hull[7],
|
|
Br = hull[8],
|
|
dbl = { x: Bl.x - B.x, y: Bl.y - B.y },
|
|
dbr = { x: Br.x - B.x, y: Br.y - B.y },
|
|
pts = curve.points,
|
|
// find new point on s--c1
|
|
p1 = {x: api.newB.x + dbl.x, y: api.newB.y + dbl.y},
|
|
sc1 = {
|
|
x: api.newA.x - (api.newA.x - p1.x)/(1-api.t),
|
|
y: api.newA.y - (api.newA.y - p1.y)/(1-api.t)
|
|
},
|
|
// find new point on c2--e
|
|
p2 = {x: api.newB.x + dbr.x, y: api.newB.y + dbr.y},
|
|
sc2 = {
|
|
x: api.newA.x + (p2.x - api.newA.x)/(api.t),
|
|
y: api.newA.y + (p2.y - api.newA.y)/(api.t)
|
|
},
|
|
// construct new c1` based on the fact that s--sc1 is s--c1 * t
|
|
nc1 = {
|
|
x: pts[0].x + (sc1.x - pts[0].x)/(api.t),
|
|
y: pts[0].y + (sc1.y - pts[0].y)/(api.t)
|
|
},
|
|
// construct new c2` based on the fact that e--sc2 is e--c2 * (1-t)
|
|
nc2 = {
|
|
x: pts[3].x - (pts[3].x - sc2.x)/(1-api.t),
|
|
y: pts[3].y - (pts[3].y - sc2.y)/(1-api.t)
|
|
};
|
|
|
|
api.p1 = p1;
|
|
api.p2 = p2;
|
|
api.sc1 = sc1;
|
|
api.sc2 = sc2;
|
|
api.nc1 = nc1;
|
|
api.nc2 = nc2;
|
|
|
|
api.update = [nc1, nc2];
|
|
},
|
|
|
|
drawMould: function(api, curve) {
|
|
api.reset();
|
|
|
|
api.drawSkeleton(curve);
|
|
api.drawCurve(curve);
|
|
|
|
var w = api.getPanelWidth(),
|
|
h = api.getPanelHeight(),
|
|
offset = {x:w, y:0},
|
|
round = api.utils.round;
|
|
|
|
api.setColor("black");
|
|
api.drawLine({x:0,y:0},{x:0,y:h}, offset);
|
|
api.drawLine({x:w,y:0},{x:w,y:h}, offset);
|
|
|
|
if (api.t && api.update) {
|
|
api.drawCircle(curve.get(api.t),3);
|
|
api.npts = [curve.points[0]].concat(api.update).concat([curve.points.slice(-1)[0]]);
|
|
api.newcurve = new api.Bezier(api.npts);
|
|
|
|
api.setColor("lightgrey");
|
|
api.drawCurve(api.newcurve);
|
|
var newhull = api.drawHull(api.newcurve, api.t, offset);
|
|
api.drawLine(api.npts[0], api.npts.slice(-1)[0], offset);
|
|
api.drawLine(api.newA, api.newB, offset);
|
|
|
|
api.setColor("grey");
|
|
api.drawCircle(api.newA, 3, offset);
|
|
api.setColor("blue");
|
|
api.drawCircle(api.B, 3, offset);
|
|
api.drawCircle(api.C, 3, offset);
|
|
api.drawCircle(api.newB, 3, offset);
|
|
api.drawLine(api.B, api.C, offset);
|
|
api.drawLine(api.newB, api.C, offset);
|
|
|
|
api.setFill("black");
|
|
api.text("A'", api.newA, {x:offset.x + 7, y:offset.y + 1});
|
|
api.text("start", curve.get(0), {x:offset.x + 7, y:offset.y + 1});
|
|
api.text("end", curve.get(1), {x:offset.x + 7, y:offset.y + 1});
|
|
api.setFill("blue");
|
|
api.text("B'", api.newB, {x:offset.x + 7, y:offset.y + 1});
|
|
api.text("B, at t = "+round(api.t,2), api.B, {x:offset.x + 7, y:offset.y + 1});
|
|
api.text("C", api.C, {x:offset.x + 7, y:offset.y + 1});
|
|
|
|
if(curve.order === 3) {
|
|
var hull = curve.hull(api.t);
|
|
api.drawLine(hull[7], hull[8], offset);
|
|
api.drawLine(newhull[7], newhull[8], offset);
|
|
api.drawCircle(newhull[7], 3, offset);
|
|
api.drawCircle(newhull[8], 3, offset);
|
|
api.text("e1", newhull[7], {x:offset.x + 7, y:offset.y + 1});
|
|
api.text("e2", newhull[8], {x:offset.x + 7, y:offset.y + 1});
|
|
}
|
|
|
|
offset.x += w;
|
|
|
|
api.setColor("lightgrey");
|
|
api.drawSkeleton(api.newcurve, offset);
|
|
api.setColor("black");
|
|
api.drawCurve(api.newcurve, offset);
|
|
} else {
|
|
offset.x += w;
|
|
api.drawCurve(curve, offset);
|
|
}
|
|
}
|
|
};
|