mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-09-02 12:54:23 +02:00
more than one S(t) for curve fitting
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
var invert = require('./matrix-invert.js');
|
||||
var matrices = [];
|
||||
|
||||
const POLYGONAL = 'polygonal', EQUIDISTANT = 'equidistant';
|
||||
|
||||
var binomialCoefficients = [[1],[1,1]];
|
||||
|
||||
function binomial(n,k) {
|
||||
@@ -108,7 +110,9 @@ function computeBasisMatrix(n) {
|
||||
return M;
|
||||
}
|
||||
|
||||
function computeTimeValues(P, n) {
|
||||
var computeTimeValues = {};
|
||||
|
||||
computeTimeValues[POLYGONAL] = function computePolygonalTimeValues(P, n) {
|
||||
n = n || P.length;
|
||||
var D = [0];
|
||||
for(var i = 1; i<n; i++) {
|
||||
@@ -119,6 +123,10 @@ function computeTimeValues(P, n) {
|
||||
return S;
|
||||
}
|
||||
|
||||
computeTimeValues[EQUIDISTANT] = function computeEquidistantTimeValues(P, n) {
|
||||
return '0'.repeat(n).split('').map((_,i) =>i/(n-1));
|
||||
}
|
||||
|
||||
function raiseRowPower(row, i) {
|
||||
return row.map(v => Math.pow(v,i));
|
||||
}
|
||||
@@ -150,13 +158,17 @@ function computeBestFit(P, M, S, n) {
|
||||
return { x: Cx, y: Cy };
|
||||
}
|
||||
|
||||
function fit(points) {
|
||||
function fit(points, mode) {
|
||||
mode = mode || 0;
|
||||
console.log("mode: ", mode);
|
||||
var n = points.length,
|
||||
P = Array.from(points),
|
||||
M = computeBasisMatrix(n),
|
||||
S = computeTimeValues(P, n),
|
||||
S = computeTimeValues[fit.modes[mode]](P, n),
|
||||
C = computeBestFit(P, M, S, n);
|
||||
return { n, P, M, S, C };
|
||||
}
|
||||
|
||||
fit.modes = [ POLYGONAL, EQUIDISTANT];
|
||||
|
||||
module.exports = window.makeFit = fit;
|
||||
|
@@ -2371,14 +2371,23 @@ return {
|
||||
reset: function() {
|
||||
this.points = [];
|
||||
this.curveset = false;
|
||||
let api = this.api;
|
||||
if (api) {
|
||||
this.mode = 0;
|
||||
if (this.api) {
|
||||
let api = this.api;
|
||||
api.setCurve(false);
|
||||
api.reset();
|
||||
api.redraw();
|
||||
}
|
||||
},
|
||||
|
||||
toggle: function() {
|
||||
if (this.api) {
|
||||
this.mode = (this.mode + 1) % fit.modes.length;
|
||||
this.fitCurve(this.api);
|
||||
this.api.redraw();
|
||||
}
|
||||
},
|
||||
|
||||
draw: function(api, curve) {
|
||||
api.setPanelCount(1);
|
||||
api.reset();
|
||||
@@ -2387,19 +2396,7 @@ return {
|
||||
|
||||
api.setColor('black');
|
||||
if (!this.curveset && this.points.length > 2) {
|
||||
let bestFitData = fit(this.points),
|
||||
x = bestFitData.C.x,
|
||||
y = bestFitData.C.y,
|
||||
bpoints = [];
|
||||
x.forEach((r,i) => {
|
||||
bpoints.push({
|
||||
x: r[0],
|
||||
y: y[i][0]
|
||||
});
|
||||
});
|
||||
curve = new api.Bezier(bpoints);
|
||||
api.setCurve(curve);
|
||||
this.curveset = true;
|
||||
this.fitCurve(api);
|
||||
}
|
||||
|
||||
if (curve) {
|
||||
@@ -2407,6 +2404,25 @@ return {
|
||||
api.drawSkeleton(curve);
|
||||
}
|
||||
api.drawPoints(this.points);
|
||||
|
||||
api.setFill(0);
|
||||
api.text("using "+fit.modes[this.mode]+" t values", {x: 5, y: 10});
|
||||
},
|
||||
|
||||
fitCurve(api) {
|
||||
let bestFitData = fit(this.points, this.mode),
|
||||
x = bestFitData.C.x,
|
||||
y = bestFitData.C.y,
|
||||
bpoints = [];
|
||||
x.forEach((r,i) => {
|
||||
bpoints.push({
|
||||
x: r[0],
|
||||
y: y[i][0]
|
||||
});
|
||||
});
|
||||
var curve = new api.Bezier(bpoints);
|
||||
api.setCurve(curve);
|
||||
this.curveset = true;
|
||||
},
|
||||
|
||||
onClick: function(evt, api) {
|
||||
|
Reference in New Issue
Block a user