mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-05 00:07:58 +02:00
174 lines
4.8 KiB
JavaScript
174 lines
4.8 KiB
JavaScript
module.exports = {
|
|
|
|
// ============== first sketch set =====================
|
|
|
|
/**
|
|
* The entry point for the quadratic curve example
|
|
*/
|
|
setupQuadratic: function(api) {
|
|
var curve = api.getDefaultQuadratic();
|
|
curve.points[0].y -= 10;
|
|
api.setCurve(curve);
|
|
},
|
|
|
|
/**
|
|
* The entry point for the cubic curve example
|
|
*/
|
|
setupCubic: function(api) {
|
|
var curve = api.getDefaultCubic();
|
|
curve.points[2].y -= 20;
|
|
api.setCurve(curve);
|
|
api.lut = curve.getLUT(100);
|
|
},
|
|
|
|
/**
|
|
* When someone clicks a graphic, find the associated
|
|
* on-curve t value and redraw with that new knowledge.
|
|
*/
|
|
onClick: function(evt, api) {
|
|
api.t = api.curve.on({x: evt.offsetX, y: evt.offsetY},7);
|
|
if (api.t < 0.05 || api.t > 0.95) api.t = false;
|
|
api.redraw();
|
|
},
|
|
|
|
/**
|
|
* The master draw function for the "projection" sketches
|
|
*/
|
|
draw: function(api, curve) {
|
|
// draw the basic curve and curve control points
|
|
api.reset();
|
|
api.drawSkeleton(curve);
|
|
api.drawCurve(curve);
|
|
|
|
api.setColor("black");
|
|
if (!api.t) return;
|
|
|
|
// draw the user-clicked on-curve point
|
|
api.drawCircle(api.curve.get(api.t),3);
|
|
api.setColor("lightgrey");
|
|
|
|
var utils = api.utils;
|
|
|
|
// find the A/B/C values as described in the section text
|
|
var hull = api.drawHull(curve, api.t);
|
|
var A, B, C;
|
|
if(hull.length === 6) {
|
|
A = curve.points[1];
|
|
B = hull[5];
|
|
C = utils.lli4(A, B, curve.points[0], curve.points[2]);
|
|
api.setColor("lightgrey");
|
|
api.drawLine(curve.points[0], curve.points[2]);
|
|
} else if(hull.length === 10) {
|
|
A = hull[5];
|
|
B = hull[9];
|
|
C = utils.lli4(A, B, curve.points[0], curve.points[3]);
|
|
api.setColor("lightgrey");
|
|
api.drawLine(curve.points[0], curve.points[3]);
|
|
}
|
|
|
|
// show the lines between the A/B/C values
|
|
api.setColor("#00FF00");
|
|
api.drawLine(A,B);
|
|
api.setColor("red");
|
|
api.drawLine(B,C);
|
|
api.setColor("black");
|
|
api.drawCircle(C,3);
|
|
|
|
// with their associated labels
|
|
api.setFill("black");
|
|
api.text("A", {x:10 + A.x, y: A.y});
|
|
api.text("B (t = " + api.utils.round(api.t,2) + ")", {x:10 + B.x, y: B.y});
|
|
api.text("C", {x:10 + C.x, y: C.y});
|
|
|
|
// and show the distance ratio, which we see does not change irrespective of whether A/B/C change.
|
|
var d1 = utils.dist(A, B);
|
|
var d2 = utils.dist(B, C);
|
|
var ratio = d1/d2;
|
|
var h = api.getPanelHeight();
|
|
api.text("d1 (A-B): " + utils.round(d1,2) + ", d2 (B-C): "+ utils.round(d2,2) + ", ratio (d1/d2): " + utils.round(ratio,4), {x:10, y:h-7});
|
|
},
|
|
|
|
// ============== second sketch set =====================
|
|
|
|
/**
|
|
* on mouse move, fix the t value for drawing based on the
|
|
* cursor position over the sketch. All the way on the left
|
|
* is t=0, all the way on the right is t=1, with a linear
|
|
* interpolation for anything in between.
|
|
*/
|
|
setCT: function(evt,api) {
|
|
api.t = evt.offsetX / api.getPanelWidth();
|
|
},
|
|
|
|
/**
|
|
* Draw the quadratic C(t) values
|
|
*/
|
|
drawQCT: function(api) {
|
|
api.u = api.u || function(t) {
|
|
var top = (t-1) * (t-1),
|
|
bottom = 2*t*t - 2*t + 1;
|
|
return top/bottom;
|
|
};
|
|
this.drawCTgraph(api);
|
|
},
|
|
|
|
/**
|
|
* Draw the cubic C(t) values
|
|
*/
|
|
drawCCT: function(api) {
|
|
api.u = api.u || function(t) {
|
|
var top = (1-t) * (1-t) * (1-t),
|
|
bottom = t*t*t + top;
|
|
return top/bottom;
|
|
};
|
|
this.drawCTgraph(api);
|
|
},
|
|
|
|
/**
|
|
* Draw a C(t) curve
|
|
*/
|
|
drawCTgraph: function(api) {
|
|
api.reset();
|
|
var w = api.getPanelWidth();
|
|
var pad = 20;
|
|
var fwh = w - 2*pad;
|
|
|
|
// draw some axes
|
|
api.setColor("black");
|
|
api.drawAxes(pad, "t",0,1, "u",0,1);
|
|
|
|
// draw the C(t) function using an
|
|
// indirection function that takes a
|
|
// t value and spits out the C(t) value
|
|
// as a point coordinate.
|
|
api.setColor("blue");
|
|
var uPoint = function(t) {
|
|
var value = api.u(t),
|
|
res = { x: pad + t*fwh, y: pad + value*fwh };
|
|
return res;
|
|
};
|
|
api.drawFunction(uPoint);
|
|
|
|
// if the cursor is (or was ever) over this
|
|
// graphic, draw the "crosshair" that pinpoints
|
|
// where in the function the associated t/C(t)
|
|
// coordinate is.
|
|
if (api.t) {
|
|
var v = api.u(api.t),
|
|
v1 = api.utils.round(v,3),
|
|
v2 = api.utils.round(1-v,3),
|
|
up = uPoint(api.t);
|
|
api.drawLine({x:up.x,y:pad}, up);
|
|
api.drawLine({x:pad,y:up.y}, up);
|
|
api.drawCircle(up,3);
|
|
|
|
// with some handy text that shows the actual computed values
|
|
api.setFill("blue");
|
|
api.text(" t = " + api.utils.round(api.t,3), {x:up.x+10, y:up.y-7});
|
|
api.text("u(t) = " + api.utils.round(v,3), {x:up.x+10, y:up.y+7});
|
|
api.setFill("black");
|
|
api.text("C = "+v1+" * start + "+v2+" * end", {x:w/2 - pad, y:pad+fwh});
|
|
}
|
|
}
|
|
};
|