mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-31 03:59:58 +02:00
added sliders to sketches that should have one, improved lazy loading
This commit is contained in:
@@ -2,7 +2,9 @@
|
||||
|
||||
Using de Casteljau's algorithm, we can also find all the points we need to split up a Bézier curve into two, smaller curves, which taken together form the original curve. When we construct de Casteljau's skeleton for some value `t`, the procedure gives us all the points we need to split a curve at that `t` value: one curve is defined by all the inside skeleton points found prior to our on-curve point, with the other curve being defined by all the inside skeleton points after our on-curve point.
|
||||
|
||||
<graphics-element title="Splitting a curve" width="825" src="./splitting.js"></graphics-element>
|
||||
<graphics-element title="Splitting a curve" width="825" src="./splitting.js">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0.5" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<div class="howtocode">
|
||||
|
||||
|
@@ -2,7 +2,9 @@
|
||||
|
||||
ベジエ曲線を分割して、繫ぎ合わせたときに元に戻るような小さい2曲線にしたい場合にも、ド・カステリョのアルゴリズムを使えば、これに必要な点をすべて求めることができます。ある値`t`に対してド・カステリョの骨格を組み立てると、その`t`で曲線を分割する際に必要になる点がすべて得られます。骨格内部の点のうち、曲線上の点から見て手前側にある点によって一方の曲線が定義され、向こう側にある点によってもう一方の曲線が定義されます。
|
||||
|
||||
<graphics-element title="曲線の分割" width="825" src="./splitting.js"></graphics-element>
|
||||
<graphics-element title="曲線の分割" width="825" src="./splitting.js">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0.5" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<div class="howtocode">
|
||||
|
||||
|
@@ -2,7 +2,9 @@
|
||||
|
||||
使用 de Casteljau 算法我们也可以将一条贝塞尔曲线分割成两条更小的曲线,二者拼接起来即可形成原来的曲线。当采用某个 `t` 值构造 de Casteljau 算法时,该过程会给到我们在 `t` 点分割曲线的所有点: 一条曲线包含该曲线上点之前的所有点,另一条曲线包含该曲线上点之后的所有点。
|
||||
|
||||
<graphics-element title="分割一条曲线" width="825" src="./splitting.js"></graphics-element>
|
||||
<graphics-element title="分割一条曲线" width="825" src="./splitting.js">
|
||||
<input type="range" min="0" max="1" step="0.01" value="0.5" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<div class="howtocode">
|
||||
|
||||
|
@@ -1,91 +0,0 @@
|
||||
module.exports = {
|
||||
setupCubic: function(api) {
|
||||
var curve = api.getDefaultCubic();
|
||||
api.setCurve(curve);
|
||||
api.forward = true;
|
||||
},
|
||||
|
||||
drawSplit: function(api, curve) {
|
||||
api.setPanelCount(2);
|
||||
api.reset();
|
||||
api.drawSkeleton(curve);
|
||||
api.drawCurve(curve);
|
||||
|
||||
var offset = {x:0, y:0};
|
||||
var t = 0.5;
|
||||
var pt = curve.get(0.5);
|
||||
var split = curve.split(t);
|
||||
api.drawCurve(split.left);
|
||||
api.drawCurve(split.right);
|
||||
api.setColor("red");
|
||||
api.drawCircle(pt,3);
|
||||
|
||||
api.setColor("black");
|
||||
offset.x = api.getPanelWidth();
|
||||
api.drawLine({x:0,y:0},{x:0,y:api.getPanelHeight()}, offset);
|
||||
|
||||
api.setColor("lightgrey");
|
||||
api.drawCurve(curve, offset);
|
||||
api.drawCircle(pt,4);
|
||||
|
||||
offset.x -= 20;
|
||||
offset.y -= 20;
|
||||
api.drawSkeleton(split.left, offset, true);
|
||||
api.drawCurve(split.left, offset);
|
||||
|
||||
offset.x += 40;
|
||||
offset.y += 40;
|
||||
api.drawSkeleton(split.right, offset, true);
|
||||
api.drawCurve(split.right, offset);
|
||||
},
|
||||
|
||||
drawAnimated: function(api, curve) {
|
||||
api.setPanelCount(3);
|
||||
api.reset();
|
||||
|
||||
var frame = api.getFrame();
|
||||
var interval = 5 * api.getPlayInterval();
|
||||
var t = (frame%interval)/interval;
|
||||
var forward = (frame%(2*interval)) < interval;
|
||||
if (forward) { t = t%1; } else { t = 1 - t%1; }
|
||||
var offset = {x:0, y:0};
|
||||
|
||||
api.setColor("lightblue");
|
||||
api.drawHull(curve, t);
|
||||
api.drawSkeleton(curve);
|
||||
api.drawCurve(curve);
|
||||
var pt = curve.get(t);
|
||||
api.drawCircle(pt, 4);
|
||||
|
||||
api.setColor("black");
|
||||
offset.x += api.getPanelWidth();
|
||||
api.drawLine({x:0,y:0},{x:0,y:api.getPanelHeight()}, offset);
|
||||
|
||||
var split = curve.split(t);
|
||||
|
||||
api.setColor("lightgrey");
|
||||
api.drawCurve(curve, offset);
|
||||
api.drawHull(curve, t, offset);
|
||||
api.setColor("black");
|
||||
api.drawCurve(split.left, offset);
|
||||
api.drawPoints(split.left.points, offset);
|
||||
api.setFill("black");
|
||||
api.text("Left side of curve split at t = " + (((100*t)|0)/100), {x: 10 + offset.x, y: 15 + offset.y});
|
||||
|
||||
offset.x += api.getPanelWidth();
|
||||
api.drawLine({x:0,y:0},{x:0,y:api.getPanelHeight()}, offset);
|
||||
|
||||
api.setColor("lightgrey");
|
||||
api.drawCurve(curve, offset);
|
||||
api.drawHull(curve, t, offset);
|
||||
api.setColor("black");
|
||||
api.drawCurve(split.right, offset);
|
||||
api.drawPoints(split.right.points, offset);
|
||||
api.setFill("black");
|
||||
api.text("Right side of curve split at t = " + (((100*t)|0)/100), {x: 10 + offset.x, y: 15 + offset.y});
|
||||
},
|
||||
|
||||
togglePlay: function(evt, api) {
|
||||
if (api.playing) { api.pause(); } else { api.play(); }
|
||||
}
|
||||
};
|
@@ -1,28 +0,0 @@
|
||||
|
||||
|
||||
/*
|
||||
|
||||
// const { left, right } = this.getLeftAndRight(this.t, this.curve.points);
|
||||
// const c1 = new Bezier(this, left);
|
||||
// const c2 = new Bezier(this, right);
|
||||
|
||||
getLeftAndRight(t, points, left=[], right=[]) {
|
||||
if(points.length === 1) {
|
||||
left.push(points[0]);
|
||||
right.push(points[0]);
|
||||
return { left, right };
|
||||
}
|
||||
|
||||
let newpoints = points.slice(1);
|
||||
for(let i=0; i<newpoints.length; i++) {
|
||||
if(i === 0) left.push(points[i]);
|
||||
if(i === newpoints.length-1) right.push(points[i+1]);
|
||||
newpoints[i] = {
|
||||
x: (1-t) * points[i].x + t * points[i+1].x,
|
||||
y: (1-t) * points[i].y + t * points[i+1].y,
|
||||
}
|
||||
}
|
||||
|
||||
return this.getLeftAndRight(t, newpoints, left, right);
|
||||
}
|
||||
*/
|
@@ -2,6 +2,11 @@ setup() {
|
||||
this.t = 0.5;
|
||||
this.curve = Bezier.defaultCubic(this);
|
||||
setMovable(this.curve.points);
|
||||
setSlider(`.slide-control`, v => this.setPosition(v));
|
||||
}
|
||||
|
||||
setPosition(v) {
|
||||
this.t = v;
|
||||
}
|
||||
|
||||
draw() {
|
||||
@@ -19,13 +24,13 @@ draw() {
|
||||
setStroke(`black`);
|
||||
line(0, 0, 0, this.height);
|
||||
|
||||
this.drawSegment(c1, p);
|
||||
this.drawSegment(c1, p, `first`);
|
||||
|
||||
translate(this.width/3, 0);
|
||||
setStroke(`black`);
|
||||
line(0, 0, 0, this.height);
|
||||
|
||||
this.drawSegment(c2, p);
|
||||
this.drawSegment(c2, p, `second`);
|
||||
}
|
||||
|
||||
drawBasics(p) {
|
||||
@@ -42,7 +47,7 @@ drawBasics(p) {
|
||||
text(`The full curve, with struts`, 10, 15);
|
||||
}
|
||||
|
||||
drawSegment(c, p) {
|
||||
drawSegment(c, p, halfLabel) {
|
||||
setStroke(`lightblue`);
|
||||
this.curve.drawCurve(`lightblue`);
|
||||
this.curve.drawSkeleton(`lightblue`);
|
||||
@@ -53,28 +58,9 @@ drawSegment(c, p) {
|
||||
setStroke(`red`);
|
||||
circle(p.x, p.y, 3);
|
||||
setFill(`black`)
|
||||
text(`The first half`, 10, 15);
|
||||
}
|
||||
|
||||
onKeyDown() {
|
||||
let key = this.keyboard.currentKey;
|
||||
|
||||
if(key === `ArrowUp`) {
|
||||
this.t += 0.01;
|
||||
}
|
||||
|
||||
if(key === `ArrowDown`) {
|
||||
this.t -= 0.01
|
||||
}
|
||||
|
||||
this.t = this.t < 0 ? 0 : this.t > 1 ? 1 : this.t;
|
||||
|
||||
redraw();
|
||||
text(`The ${halfLabel} half`, 10, 15);
|
||||
}
|
||||
|
||||
onMouseMove() {
|
||||
if (this.cursor.down && !this.currentPoint) {
|
||||
this.t = map(this.cursor.y, 0,this.height, 0, 1);
|
||||
}
|
||||
redraw();
|
||||
}
|
||||
|
Reference in New Issue
Block a user