1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-08-30 19:50:01 +02:00

arc length

This commit is contained in:
Pomax
2020-08-25 18:38:38 -07:00
parent 22ffc4b6c2
commit bf88ba4e4c
43 changed files with 23663 additions and 5474 deletions

View File

@@ -1,6 +1,88 @@
const Tvalues24 = [
-0.0640568928626056260850430826247450385909,
0.0640568928626056260850430826247450385909,
-0.1911188674736163091586398207570696318404,
0.1911188674736163091586398207570696318404,
-0.3150426796961633743867932913198102407864,
0.3150426796961633743867932913198102407864,
-0.4337935076260451384870842319133497124524,
0.4337935076260451384870842319133497124524,
-0.5454214713888395356583756172183723700107,
0.5454214713888395356583756172183723700107,
-0.6480936519369755692524957869107476266696,
0.6480936519369755692524957869107476266696,
-0.7401241915785543642438281030999784255232,
0.7401241915785543642438281030999784255232,
-0.8200019859739029219539498726697452080761,
0.8200019859739029219539498726697452080761,
-0.8864155270044010342131543419821967550873,
0.8864155270044010342131543419821967550873,
-0.9382745520027327585236490017087214496548,
0.9382745520027327585236490017087214496548,
-0.9747285559713094981983919930081690617411,
0.9747285559713094981983919930081690617411,
-0.9951872199970213601799974097007368118745,
0.9951872199970213601799974097007368118745,
];
const Cvalues24 = [
0.1279381953467521569740561652246953718517,
0.1279381953467521569740561652246953718517,
0.1258374563468282961213753825111836887264,
0.1258374563468282961213753825111836887264,
0.121670472927803391204463153476262425607,
0.121670472927803391204463153476262425607,
0.1155056680537256013533444839067835598622,
0.1155056680537256013533444839067835598622,
0.1074442701159656347825773424466062227946,
0.1074442701159656347825773424466062227946,
0.0976186521041138882698806644642471544279,
0.0976186521041138882698806644642471544279,
0.086190161531953275917185202983742667185,
0.086190161531953275917185202983742667185,
0.0733464814110803057340336152531165181193,
0.0733464814110803057340336152531165181193,
0.0592985849154367807463677585001085845412,
0.0592985849154367807463677585001085845412,
0.0442774388174198061686027482113382288593,
0.0442774388174198061686027482113382288593,
0.0285313886289336631813078159518782864491,
0.0285313886289336631813078159518782864491,
0.0123412297999871995468056670700372915759,
0.0123412297999871995468056670700372915759,
];
setup() {
this.curve = Bezier.defaultCubic(this);
setMovable(this.curve.points);
}
draw() {
clear();
const curve = this.curve;
curve.drawSkeleton();
curve.drawCurve();
curve.drawPoints();
const len = this.computeLength(curve);
setFill("black");
text(`Curve length: ${len.toFixed(2)} pixels`, 10, 15);
}
computeLength(curve) {
const z = 0.5,
len = Tvalues24.length;
let sum = 0;
for (let i = 0, t; i < len; i++) {
t = z * Tvalues24[i] + z;
sum += Cvalues24[i] * this.arcfn(t, curve.derivative(t));
}
return z * sum;
}
arcfn(t, d) {
return sqrt(d.x * d.x + d.y * d.y);
}

View File

@@ -1,125 +0,0 @@
var sin = Math.sin;
var tau = Math.PI*2;
module.exports = {
/**
* Set up a sinusoid generating function,
* which we'll use to draw the "progressively
* better looking" integral approximations.
*/
setup: function(api) {
var w = api.getPanelWidth();
var h = api.getPanelHeight();
var generator;
if (!this.generator) {
generator = ((v,scale) => {
scale = scale || 1;
return {
x: v*w/tau,
y: scale * sin(v)
};
});
generator.start = 0;
generator.end = tau;
generator.step = 0.1;
generator.scale = h/3;
this.generator = generator;
}
},
/**
* Draw the generator's sine function:
*/
drawSine: function(api, dheight) {
var w = api.getPanelWidth();
var h = api.getPanelHeight();
var generator = this.generator;
generator.dheight = dheight;
api.setColor("black");
api.drawLine({x:0,y:h/2}, {x:w,y:h/2});
api.drawFunction(generator, {x:0, y:h/2});
},
/**
* Draw the sliced between the sine curve and
* the x-axis, with a variable number of steps so
* we can show the approximation becoming better
* and better as we increase the step count.
*/
drawSlices: function(api, steps) {
var w = api.getPanelWidth();
var h = api.getPanelHeight();
var f = w/tau;
var area = 0;
var c = steps <= 25 ? 1 : 0;
api.reset();
api.setColor("transparent");
api.setFill("rgba(150,150,255, 0.4)");
for (var step=tau/steps, i=step/2, v, p1, p2; i<tau+step/2; i+=step) {
v = this.generator(i);
// draw a rectangular strip between the curve and the x-axis:
p1 = {x:v.x - f*step/2 + c, y: 0};
p2 = {x:v.x + f*step/2 - c, y: v.y * this.generator.scale};
if (!c) { api.setFill("rgba(150,150,255,"+(0.4 + 0.3*Math.random())+")"); }
api.drawRect(p1, p2, {x:0, y:h/2});
// and keep track of the (much simpler to compute) approximated area under the curve so far:
area += step * Math.abs(v.y * this.generator.scale);
}
api.setFill("black");
var trueArea = ((100 * 4 * h/3)|0)/100;
var currArea = ((100 * area)|0)/100;
api.text("Approximating with "+steps+" strips (true area: "+trueArea+"): " + currArea, {x: 10, y: h-15});
},
/**
* Draw the sine curve, with a 10 slice approximation:
*/
drawCoarseIntegral: function(api) {
api.reset();
this.drawSlices(api, 10);
this.drawSine(api);
},
/**
* Draw the sine curve, with a 24 slice approximation:
*/
drawFineIntegral: function(api) {
api.reset();
this.drawSlices(api, 24);
this.drawSine(api);
},
/**
* Draw the sine curve, with a 99 slice approximation:
*/
drawSuperFineIntegral: function(api) {
api.reset();
this.drawSlices(api, 99);
this.drawSine(api);
},
/**
* Set up a default cubic curve for which we'll be determining
* its length, using the iterative integral approach:
*/
setupCurve: function(api) {
var curve = api.getDefaultCubic();
api.setCurve(curve);
},
/**
* Draw our curve, and show its computed length:
*/
drawCurve: function(api, curve) {
api.reset();
api.drawSkeleton(curve);
api.drawCurve(curve);
var len = curve.length();
api.setFill("black");
api.text("Curve length: "+len+" pixels", {x:10, y:15});
}
};