mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-30 19:50:01 +02:00
figured out how to reuse sketches with data-attribute parameters
This commit is contained in:
29
docs/chapters/arclengthapprox/approximate.js
Normal file
29
docs/chapters/arclengthapprox/approximate.js
Normal file
@@ -0,0 +1,29 @@
|
||||
let curve;
|
||||
|
||||
setup() {
|
||||
let type = getParameter(`type`, `quadratic`);
|
||||
curve = (type === `quadratic`) ? Bezier.defaultQuadratic(this) : Bezier.defaultCubic(this);
|
||||
setMovable(curve.points);
|
||||
setSlider(`.slide-control`, `steps`, type === `quadratic` ? 4 : 8);
|
||||
}
|
||||
|
||||
draw() {
|
||||
clear();
|
||||
|
||||
let alen = 0;
|
||||
const len = curve.length();
|
||||
const LUT = curve.getLUT(this.steps + 1);
|
||||
|
||||
setStroke("red");
|
||||
curve.drawSkeleton(`lightblue`);
|
||||
LUT.forEach((p1,i) => {
|
||||
if (i===0) return;
|
||||
let p0 = LUT[i-1];
|
||||
line(p0.x, p0.y, p1.x, p1.y);
|
||||
alen += dist(p0.x, p0.y, p1.x, p1.y);
|
||||
});
|
||||
|
||||
curve.drawPoints();
|
||||
setFill(`black`);
|
||||
text(`Approximate length, ${this.steps} steps: ${alen.toFixed(2)} (true: ${len.toFixed(2)})`, 10, 15);
|
||||
};
|
@@ -4,7 +4,16 @@ Sometimes, we don't actually need the precision of a true arc length, and we can
|
||||
|
||||
If we combine the work done in the previous sections on curve flattening and arc length computation, we can implement these with minimal effort:
|
||||
|
||||
<Graphic title="Approximate quadratic curve arc length" setup={this.setupQuadratic} draw={this.draw} onKeyDown={this.props.onKeyDown} />
|
||||
<Graphic title="Approximate cubic curve arc length" setup={this.setupCubic} draw={this.draw} onKeyDown={this.props.onKeyDown} />
|
||||
<div class="figure">
|
||||
|
||||
Try clicking on the sketch and using your up and down arrow keys to lower the number of segments for both the quadratic and cubic curve. You may notice that the error in length is actually pretty significant, even if the percentage is fairly low: if the number of segments used yields an error of 0.1% or higher, the flattened curve already looks fairly obviously flattened. And of course, the longer the curve, the more significant the error will be.
|
||||
<graphics-element title="Approximate quadratic curve arc length" src="./approximate.js" data-type="quadratic">
|
||||
<input type="range" min="1" max="24" step="1" value="4" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
<graphics-element title="Approximate cubic curve arc length" src="./approximate.js" data-type="cubic">
|
||||
<input type="range" min="1" max="32" step="1" value="8" class="slide-control">
|
||||
</graphics-element>
|
||||
|
||||
</div>
|
||||
|
||||
You may notice that even though the error in length is actually pretty significant in absolute terms, even at a low number of segments we get a length that agrees with the true length when it comes to just the integer part of the arc length. Quite often, approximations can drastically speed things up!
|
||||
|
@@ -1,72 +0,0 @@
|
||||
module.exports = {
|
||||
// These are functions that can be called "From the page",
|
||||
// rather than being internal to the sketch. This is useful
|
||||
// for making on-page controls hook into the sketch code.
|
||||
statics: {
|
||||
keyHandlingOptions: {
|
||||
propName: "steps",
|
||||
values: {
|
||||
"38": 1, // up arrow
|
||||
"40": -1 // down arrow
|
||||
},
|
||||
controller: function(api) {
|
||||
if (api.steps < 1) {
|
||||
api.steps = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set up the default quadratic curve.
|
||||
*/
|
||||
setupQuadratic: function(api) {
|
||||
var curve = api.getDefaultQuadratic();
|
||||
api.setCurve(curve);
|
||||
api.steps = 10;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set up the default cubic curve.
|
||||
*/
|
||||
setupCubic: function(api) {
|
||||
var curve = api.getDefaultCubic();
|
||||
api.setCurve(curve);
|
||||
api.steps = 16;
|
||||
},
|
||||
|
||||
/**
|
||||
* Draw a curve and its polygon-approximation,
|
||||
* showing the "true" length of the curve vs. the
|
||||
* length based on tallying up the polygon sections.
|
||||
*/
|
||||
draw: function(api, curve) {
|
||||
api.reset();
|
||||
api.drawSkeleton(curve);
|
||||
|
||||
var pts = curve.getLUT(api.steps);
|
||||
|
||||
var step = 1 / api.steps;
|
||||
var p0 = curve.points[0], pc;
|
||||
for(var t=step; t<1.0+step; t+=step) {
|
||||
pc = curve.get(Math.min(t,1));
|
||||
api.setColor("red");
|
||||
api.drawLine(p0,pc);
|
||||
p0 = pc;
|
||||
}
|
||||
|
||||
var len = curve.length();
|
||||
var alen = 0;
|
||||
for(var i=0,p1,dx,dy; i<pts.length-1; i++) {
|
||||
p0 = pts[i];
|
||||
p1 = pts[i+1];
|
||||
dx = p1.x-p0.x;
|
||||
dy = p1.y-p0.y;
|
||||
alen += Math.sqrt(dx*dx+dy*dy);
|
||||
}
|
||||
alen = ((100*alen)|0)/100;
|
||||
len = ((100*len)|0)/100;
|
||||
|
||||
api.text("Approximate length, "+api.steps+" steps: "+alen+" (true: "+len+")", {x:10, y: 15});
|
||||
}
|
||||
};
|
Reference in New Issue
Block a user