From 4aef67e662d46dd438926c320264ec46bb5805f0 Mon Sep 17 00:00:00 2001 From: Pomax Date: Tue, 1 Sep 2020 22:28:09 -0700 Subject: [PATCH] generalised curve fitting --- docs/chapters/curvefitting/comments.txt | 3 - docs/chapters/curvefitting/content.en-GB.md | 14 +- docs/chapters/curvefitting/curve-fitter.js | 148 ++++++++++++++++++ docs/chapters/curvefitting/curve-fitting.js | 113 +++++++++++++ docs/chapters/curvefitting/handler.js | 87 ---------- docs/chapters/curvefitting/matrix-invert.js | 110 +++++++++++++ .../fe32474b4616ee9478e1308308f1b6bf.svg | 1 + .../14cb9fbbaae9e7d87ae6bef3ea7a782e.svg | 1 + .../49423783987ac4bc49fbe4c519dbc1d1.png | Bin 16338 -> 16303 bytes .../afd21a9ba16965c2e7ec2d0d14892250.png | Bin 29226 -> 29182 bytes .../ecc15848fbe7b2176b0c89973f07c694.png | Bin 13785 -> 13779 bytes .../03ec73258d5c95eed39a2ea8665e0b07.svg | 2 +- .../08f4beaebf83dca594ad125bdca7e436.svg | 2 +- .../283bc9e8fe59a78d3c74860f62a66ecb.svg | 2 +- .../2b8334727d3b004c6e87263fec6b32b7.svg | 2 +- .../2bef3da3828d63d690460ce9947dbde2.svg | 2 +- .../2d42758fba3370f52191306752c2705c.svg | 2 +- .../4ffad56e281ee79d0688e93033429f0a.svg | 2 +- .../5f7fcb86ae1c19612b9fe02e23229e31.svg | 2 +- .../6202d7bd150c852b432d807c40fb1647.svg | 2 +- .../78b8ba1aba2e4c9ad3f7890299c90152.svg | 2 +- .../7e5d59272621baf942bc722208ce70c2.svg | 2 +- .../7eada6f12045423de24d9a2ab8e293b1.svg | 2 +- .../875ca8eea72e727ccb881b4c0b6a3224.svg | 2 +- .../8d09f2be2c6db79ee966f170ffc25815.svg | 2 +- .../9151c0fdf9689ee598a2d029ab2ffe34.svg | 2 +- .../94acb5850778dcb16c2ba3cfa676f537.svg | 2 +- .../ab334858d3fa309cc1a5ba535a2ca168.svg | 2 +- .../bd8e8e294eec10d2bf6ef857c7c0c2c2.svg | 2 +- .../c2c92587a184efa6c4fee45e4a3e32ed.png | Bin 0 -> 1703 bytes .../d84d1c71a3ce1918f53eaf8f9fe98ac4.svg | 2 +- .../77a11d65d7cffc4b84a85c4bec837792.svg | 1 + docs/index.html | 62 ++++---- docs/ja-JP/index.html | 60 +++---- docs/js/custom-element/api/graphics-api.js | 7 +- docs/placeholder-style.css | 3 +- docs/zh-CN/index.html | 62 ++++---- 37 files changed, 500 insertions(+), 210 deletions(-) delete mode 100644 docs/chapters/curvefitting/comments.txt create mode 100644 docs/chapters/curvefitting/curve-fitter.js create mode 100644 docs/chapters/curvefitting/curve-fitting.js delete mode 100644 docs/chapters/curvefitting/handler.js create mode 100644 docs/chapters/curvefitting/matrix-invert.js create mode 100644 docs/images/chapters/circles/fe32474b4616ee9478e1308308f1b6bf.svg create mode 100644 docs/images/chapters/control/14cb9fbbaae9e7d87ae6bef3ea7a782e.svg create mode 100644 docs/images/chapters/curvefitting/c2c92587a184efa6c4fee45e4a3e32ed.png create mode 100644 docs/images/chapters/matrixsplit/77a11d65d7cffc4b84a85c4bec837792.svg diff --git a/docs/chapters/curvefitting/comments.txt b/docs/chapters/curvefitting/comments.txt deleted file mode 100644 index 53ebcdb2..00000000 --- a/docs/chapters/curvefitting/comments.txt +++ /dev/null @@ -1,3 +0,0 @@ -## Additionals - -http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.96.5193&rep=rep1&type=pdf ? diff --git a/docs/chapters/curvefitting/content.en-GB.md b/docs/chapters/curvefitting/content.en-GB.md index 44ad1e95..fa0cc825 100644 --- a/docs/chapters/curvefitting/content.en-GB.md +++ b/docs/chapters/curvefitting/content.en-GB.md @@ -251,13 +251,11 @@ Here, the "to the power negative one" is the notation for the [matrix inverse](h So before we try that out, how much code is involved in implementing this? Honestly, that answer depends on how much you're going to be writing yourself. If you already have a matrix maths library available, then really not that much code at all. On the other hand, if you are writing this from scratch, you're going to have to write some utility functions for doing your matrix work for you, so it's really anywhere from 50 lines of code to maybe 200 lines of code. Not a bad price to pay for being able to fit curves to prespecified coordinates. -So let's try it out! The following graphic lets you place points, and will start computing exact-fit curves once you've placed at least three. You can click for more points, and the code will simply try to compute an exact fit using a Bézier curve of the appropriate order. Four points? Cubic Bézier. Five points? Quartic. And so on. Of course, this does break down at some point: depending on where you place your points, it might become mighty hard for the fitter to find an exact fit, and things might actually start looking horribly off once you hit 10th or higher order curves. But it might not! +So let's try it out! The following graphic lets you place points, and will start computing exact-fit curves once you've placed at least three. You can click for more points, and the code will simply try to compute an exact fit using a Bézier curve of the appropriate order. Four points? Cubic Bézier. Five points? Quartic. And so on. Of course, this does break down at some point: depending on where you place your points, it might become mighty hard for the fitter to find an exact fit, and things might actually start looking horribly off once there's enough points for compound [floating point rounding errors](https://en.wikipedia.org/wiki/Round-off_error#Floating-point_number_system) to start making a difference (which is around 10~11 points). -
- - - (this.sliders=set) } onChange={this.processTimeUpdate} /> - -
+ + +
+
-You'll note there is a convenient "toggle" buttons that lets you toggle between equidistance `t` values, and distance ratio along the polygon. Arguably more interesting is that once you have points to abstract a curve, you also get direct control over the time values through sliders for each, because if the time values are our degree of freedom, you should be able to freely manipulate them and see what the effect on your curve is. +You'll note there is a convenient "toggle" buttons that lets you toggle between equidistant `t` values, and distance ratio along the polygon formed by the points. Arguably more interesting is that once you have points to abstract a curve, you also get direct control over the time values through sliders for each, because if the time values are our degree of freedom, you should be able to freely manipulate them and see what the effect on your curve is. diff --git a/docs/chapters/curvefitting/curve-fitter.js b/docs/chapters/curvefitting/curve-fitter.js new file mode 100644 index 00000000..cd7956ab --- /dev/null +++ b/docs/chapters/curvefitting/curve-fitter.js @@ -0,0 +1,148 @@ +import invert from "./matrix-invert.js"; + +var binomialCoefficients = [[1],[1,1]]; + +function binomial(n,k) { + if (n===0) return 1; + var lut = binomialCoefficients; + while(n >= lut.length) { + var s = lut.length; + var nextRow = [1]; + for(var i=1,prev=s-1; i Mt.push([])); + M.forEach((row,r) => row.forEach((v,c) => Mt[c][r] = v)); + return Mt; +} + +function row(M,i) { + return M[i]; +} + +function col(M,i) { + var col = []; + for(var r=0, l=M.length; r a + _col[i]*v; + M[r][c] = _row.reduce(reducer, 0); + } + } + return M; +} + +function getValueColumn(P, prop) { + var col = []; + P.forEach(v => col.push([v[prop]])); + return col; +} + +function computeBasisMatrix(n) { + /* + We can form any basis matrix using a generative approach: + + - it's an M = (n x n) matrix + - it's a lower triangular matrix: all the entries above the main diagonal are zero + - the main diagonal consists of the binomial coefficients for n + - all entries are symmetric about the antidiagonal. + + What's more, if we number rows and columns starting at 0, then + the value at position M[r,c], with row=r and column=c, can be + expressed as: + + M[r,c] = (r choose c) * M[r,r] * S, + + where S = 1 if r+c is even, or -1 otherwise + + That is: the values in column c are directly computed off of the + binomial coefficients on the main diagonal, through multiplication + by a binomial based on matrix position, with the sign of the value + also determined by matrix position. This is actually very easy to + write out in code: + */ + + // form the square matrix, and set it to all zeroes + var M = [], i = n; + while (i--) { M[i] = "0".repeat(n).split('').map(v => parseInt(v)); } + + // populate the main diagonal + var k = n - 1; + for (i=0; i Math.pow(v,i)); +} + +function formTMatrix(S, n) { + n = n || S.length; + var Tp = []; + // it's easier to generate the transposed matrix: + for(var i=0; i this.toggle()); + sliders = find(`.sliders`); + this.mode = 0; + this.label = `Using equidistant t values`; +} + +toggle() { + this.mode = (this.mode + 1) % 2; + if (sliders) this.setSliderValues(this.mode); + redraw(); +} + +draw() { + clear(); + setColor('lightgrey'); + drawGrid(10); + + setColor('black'); + setFontSize(16); + setTextStroke(`white`, 4); + if (points.length > 2) { + curve = this.fitCurve(points); + curve.drawSkeleton(`blue`); + curve.drawCurve(); + + text(this.label, this.width/2, 20, CENTER); + } + + points.forEach(p => circle(p.x, p.y, 3)); +} + +fitCurve(points) { + let n = points.length; + let tvalues = sliders ? sliders.values : [...new Array(n)].map((_,i) =>i/(n-1)); + let bestFitData = fit(points, tvalues), + x = bestFitData.C.x, + y = bestFitData.C.y, + bpoints = x.map((r,i) => ( + {x: r[0], y: y[i][0]} + )); + return new Bezier(this, bpoints); +} + +updateSliders() { + if (sliders && points.length > 2) { + sliders.innerHTML = ``; + sliders.values = []; + this.sliders = points.map((p,i) => { + // TODO: this should probably be built into the graphics API as a + // things that you can do, e.g. clearSliders() and addSlider() + let s = document.createElement(`input`); + s.setAttribute(`type`, `range`); + s.setAttribute(`min`, `0`); + s.setAttribute(`max`, `1`); + s.setAttribute(`step`, `0.01`); + s.classList.add(`slide-control`); + sliders.values[i] = i/(points.length-1); + s.setAttribute(`value`, sliders.values[i]); + s.addEventListener(`input`, evt => { + this.label = `Using custom t values`; + sliders.values[i] = parseFloat(evt.target.value); + redraw(); + }); + sliders.append(s); + }); + } +} + +setSliderValues(mode) { + let n = points.length; + + // equidistant + if (mode === 0) { + this.label = `Using equidistant t values`; + sliders.values = [...new Array(n)].map((_,i) =>i/(n-1)); + } + + // polygonal distance + if (mode === 1) { + this.label = `Using polygonal distance t values`; + const D = [0]; + for(let i = 1; i { S[i] = v/len; }); + sliders.values = S; + } + + findAll(`.sliders input[type=range]`).forEach((s,i) => { + s.setAttribute(`value`, sliders.values[i]); + s.value = sliders.values[i]; + }); +} + +onMouseDown() { + if (!this.currentPoint) { + const {x, y} = this.cursor; + points.push({ x, y }); + resetMovable(points); + this.updateSliders(); + redraw(); + } +} diff --git a/docs/chapters/curvefitting/handler.js b/docs/chapters/curvefitting/handler.js deleted file mode 100644 index 62947ca2..00000000 --- a/docs/chapters/curvefitting/handler.js +++ /dev/null @@ -1,87 +0,0 @@ -var fit = require('../../../lib/curve-fitter.js'); - -module.exports = { - setup: function(api) { - this.api = api; - api.noDrag = true; // do not allow points to be dragged around - this.reset(); - }, - - reset: function() { - this.points = []; - this.sliders.setOptions([]); - this.curveset = false; - this.mode = 0; - if (this.api) { - let api = this.api; - api.setCurve(false); - api.reset(); - api.redraw(); - } - }, - - toggle: function() { - if (this.api) { - this.customTimeValues = false; - this.mode = (this.mode + 1) % fit.modes.length; - this.fitCurve(this.api); - this.api.redraw(); - } - }, - - draw: function(api, curve) { - api.setPanelCount(1); - api.reset(); - api.setColor('lightgrey'); - api.drawGrid(10,10); - - api.setColor('black'); - - if (!this.curveset && this.points.length > 2) { - curve = this.fitCurve(api); - } - - if (curve) { - api.drawCurve(curve); - api.drawSkeleton(curve); - } - - api.drawPoints(this.points); - - if (!this.customTimeValues) { - api.setFill(0); - api.text("using "+fit.modes[this.mode]+" t values", {x: 5, y: 10}); - } - }, - - processTimeUpdate(sliderid, timeValues) { - var api = this.api; - this.customTimeValues = true; - this.fitCurve(api, timeValues); - api.redraw(); - }, - - fitCurve(api, timeValues) { - let bestFitData = fit(this.points, timeValues || 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; - this.sliders.setOptions(bestFitData.S); - return curve; - }, - - onClick: function(evt, api) { - this.curveset = false; - this.points.push({x: api.mx, y: api.my }); - api.redraw(); - } -}; diff --git a/docs/chapters/curvefitting/matrix-invert.js b/docs/chapters/curvefitting/matrix-invert.js new file mode 100644 index 00000000..819e1d86 --- /dev/null +++ b/docs/chapters/curvefitting/matrix-invert.js @@ -0,0 +1,110 @@ +// Copied from http://blog.acipo.com/matrix-inversion-in-javascript/ + +// Returns the inverse of matrix `M`. +export default function matrix_invert(M) { + // I use Guassian Elimination to calculate the inverse: + // (1) 'augment' the matrix (left) by the identity (on the right) + // (2) Turn the matrix on the left into the identity by elemetry row ops + // (3) The matrix on the right is the inverse (was the identity matrix) + // There are 3 elemtary row ops: (I combine b and c in my code) + // (a) Swap 2 rows + // (b) Multiply a row by a scalar + // (c) Add 2 rows + + //if the matrix isn't square: exit (error) + if (M.length !== M[0].length) { + console.log('not square'); + return; + } + + //create the identity matrix (I), and a copy (C) of the original + var i = 0, + ii = 0, + j = 0, + dim = M.length, + e = 0, + t = 0; + var I = [], + C = []; + for (i = 0; i < dim; i += 1) { + // Create the row + I[I.length] = []; + C[C.length] = []; + for (j = 0; j < dim; j += 1) { + //if we're on the diagonal, put a 1 (for identity) + if (i == j) { + I[i][j] = 1; + } else { + I[i][j] = 0; + } + + // Also, make the copy of the original + C[i][j] = M[i][j]; + } + } + + // Perform elementary row operations + for (i = 0; i < dim; i += 1) { + // get the element e on the diagonal + e = C[i][i]; + + // if we have a 0 on the diagonal (we'll need to swap with a lower row) + if (e == 0) { + //look through every row below the i'th row + for (ii = i + 1; ii < dim; ii += 1) { + //if the ii'th row has a non-0 in the i'th col + if (C[ii][i] != 0) { + //it would make the diagonal have a non-0 so swap it + for (j = 0; j < dim; j++) { + e = C[i][j]; //temp store i'th row + C[i][j] = C[ii][j]; //replace i'th row by ii'th + C[ii][j] = e; //repace ii'th by temp + e = I[i][j]; //temp store i'th row + I[i][j] = I[ii][j]; //replace i'th row by ii'th + I[ii][j] = e; //repace ii'th by temp + } + //don't bother checking other rows since we've swapped + break; + } + } + //get the new diagonal + e = C[i][i]; + //if it's still 0, not invertable (error) + if (e == 0) { + return; + } + } + + // Scale this row down by e (so we have a 1 on the diagonal) + for (j = 0; j < dim; j++) { + C[i][j] = C[i][j] / e; //apply to original matrix + I[i][j] = I[i][j] / e; //apply to identity + } + + // Subtract this row (scaled appropriately for each row) from ALL of + // the other rows so that there will be 0's in this column in the + // rows above and below this one + for (ii = 0; ii < dim; ii++) { + // Only apply to other rows (we want a 1 on the diagonal) + if (ii == i) { + continue; + } + + // We want to change this element to 0 + e = C[ii][i]; + + // Subtract (the row above(or below) scaled by e) from (the + // current row) but start at the i'th column and assume all the + // stuff left of diagonal is 0 (which it should be if we made this + // algorithm correctly) + for (j = 0; j < dim; j++) { + C[ii][j] -= e * C[i][j]; //apply to original matrix + I[ii][j] -= e * I[i][j]; //apply to identity + } + } + } + + //we've done all operations, C should be the identity + //matrix I should be the inverse: + return I; +}; \ No newline at end of file diff --git a/docs/images/chapters/circles/fe32474b4616ee9478e1308308f1b6bf.svg b/docs/images/chapters/circles/fe32474b4616ee9478e1308308f1b6bf.svg new file mode 100644 index 00000000..0a70cf4b --- /dev/null +++ b/docs/images/chapters/circles/fe32474b4616ee9478e1308308f1b6bf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/images/chapters/control/14cb9fbbaae9e7d87ae6bef3ea7a782e.svg b/docs/images/chapters/control/14cb9fbbaae9e7d87ae6bef3ea7a782e.svg new file mode 100644 index 00000000..7e17c4e5 --- /dev/null +++ b/docs/images/chapters/control/14cb9fbbaae9e7d87ae6bef3ea7a782e.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/images/chapters/control/49423783987ac4bc49fbe4c519dbc1d1.png b/docs/images/chapters/control/49423783987ac4bc49fbe4c519dbc1d1.png index c6757884a840254f7e793a5b0bdcf113facce0fa..aa6f0a674f050f9406d9ff95ad6ea3879770ec72 100644 GIT binary patch literal 16303 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 Z;6gu^V;P9B6ByEmk`j{_tr9i}{6CtBcoP5s diff --git a/docs/images/chapters/control/afd21a9ba16965c2e7ec2d0d14892250.png b/docs/images/chapters/control/afd21a9ba16965c2e7ec2d0d14892250.png index f49dedc575cbdbd3f1ff2e32561f59a274d7896c..bb0f9ac16f03c74e6bfabe51819671499038cd76 100644 GIT binary patch literal 29182 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 O5R&3@VwEBW{{IIT4ptuk literal 29226 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 A82|tP diff --git a/docs/images/chapters/control/ecc15848fbe7b2176b0c89973f07c694.png b/docs/images/chapters/control/ecc15848fbe7b2176b0c89973f07c694.png index a051179031b288d81683cdea5963504ccad058bf..35cc064a5d1f9c040b649953f141137b670ccd59 100644 GIT binary patch literal 13779 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 C-&1k` literal 13785 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 \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/08f4beaebf83dca594ad125bdca7e436.svg b/docs/images/chapters/curvefitting/08f4beaebf83dca594ad125bdca7e436.svg index e9658b08..ef635a3d 100644 --- a/docs/images/chapters/curvefitting/08f4beaebf83dca594ad125bdca7e436.svg +++ b/docs/images/chapters/curvefitting/08f4beaebf83dca594ad125bdca7e436.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/283bc9e8fe59a78d3c74860f62a66ecb.svg b/docs/images/chapters/curvefitting/283bc9e8fe59a78d3c74860f62a66ecb.svg index a8172fcd..600081ad 100644 --- a/docs/images/chapters/curvefitting/283bc9e8fe59a78d3c74860f62a66ecb.svg +++ b/docs/images/chapters/curvefitting/283bc9e8fe59a78d3c74860f62a66ecb.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/2b8334727d3b004c6e87263fec6b32b7.svg b/docs/images/chapters/curvefitting/2b8334727d3b004c6e87263fec6b32b7.svg index 9e2dfcf1..0067f321 100644 --- a/docs/images/chapters/curvefitting/2b8334727d3b004c6e87263fec6b32b7.svg +++ b/docs/images/chapters/curvefitting/2b8334727d3b004c6e87263fec6b32b7.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/2bef3da3828d63d690460ce9947dbde2.svg b/docs/images/chapters/curvefitting/2bef3da3828d63d690460ce9947dbde2.svg index 14d83cad..d1e4cbe5 100644 --- a/docs/images/chapters/curvefitting/2bef3da3828d63d690460ce9947dbde2.svg +++ b/docs/images/chapters/curvefitting/2bef3da3828d63d690460ce9947dbde2.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/2d42758fba3370f52191306752c2705c.svg b/docs/images/chapters/curvefitting/2d42758fba3370f52191306752c2705c.svg index 17881f45..d0a2d5c8 100644 --- a/docs/images/chapters/curvefitting/2d42758fba3370f52191306752c2705c.svg +++ b/docs/images/chapters/curvefitting/2d42758fba3370f52191306752c2705c.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/4ffad56e281ee79d0688e93033429f0a.svg b/docs/images/chapters/curvefitting/4ffad56e281ee79d0688e93033429f0a.svg index 79cc7461..2717e29e 100644 --- a/docs/images/chapters/curvefitting/4ffad56e281ee79d0688e93033429f0a.svg +++ b/docs/images/chapters/curvefitting/4ffad56e281ee79d0688e93033429f0a.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/5f7fcb86ae1c19612b9fe02e23229e31.svg b/docs/images/chapters/curvefitting/5f7fcb86ae1c19612b9fe02e23229e31.svg index bc0bf6c5..255d87f1 100644 --- a/docs/images/chapters/curvefitting/5f7fcb86ae1c19612b9fe02e23229e31.svg +++ b/docs/images/chapters/curvefitting/5f7fcb86ae1c19612b9fe02e23229e31.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/6202d7bd150c852b432d807c40fb1647.svg b/docs/images/chapters/curvefitting/6202d7bd150c852b432d807c40fb1647.svg index 9da51301..510cb83d 100644 --- a/docs/images/chapters/curvefitting/6202d7bd150c852b432d807c40fb1647.svg +++ b/docs/images/chapters/curvefitting/6202d7bd150c852b432d807c40fb1647.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/78b8ba1aba2e4c9ad3f7890299c90152.svg b/docs/images/chapters/curvefitting/78b8ba1aba2e4c9ad3f7890299c90152.svg index cccbc329..6895819c 100644 --- a/docs/images/chapters/curvefitting/78b8ba1aba2e4c9ad3f7890299c90152.svg +++ b/docs/images/chapters/curvefitting/78b8ba1aba2e4c9ad3f7890299c90152.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/7e5d59272621baf942bc722208ce70c2.svg b/docs/images/chapters/curvefitting/7e5d59272621baf942bc722208ce70c2.svg index 170d27e1..24a48dd5 100644 --- a/docs/images/chapters/curvefitting/7e5d59272621baf942bc722208ce70c2.svg +++ b/docs/images/chapters/curvefitting/7e5d59272621baf942bc722208ce70c2.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/7eada6f12045423de24d9a2ab8e293b1.svg b/docs/images/chapters/curvefitting/7eada6f12045423de24d9a2ab8e293b1.svg index 25f02428..e0c1ceec 100644 --- a/docs/images/chapters/curvefitting/7eada6f12045423de24d9a2ab8e293b1.svg +++ b/docs/images/chapters/curvefitting/7eada6f12045423de24d9a2ab8e293b1.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/875ca8eea72e727ccb881b4c0b6a3224.svg b/docs/images/chapters/curvefitting/875ca8eea72e727ccb881b4c0b6a3224.svg index a02129e9..ab5b0a03 100644 --- a/docs/images/chapters/curvefitting/875ca8eea72e727ccb881b4c0b6a3224.svg +++ b/docs/images/chapters/curvefitting/875ca8eea72e727ccb881b4c0b6a3224.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/8d09f2be2c6db79ee966f170ffc25815.svg b/docs/images/chapters/curvefitting/8d09f2be2c6db79ee966f170ffc25815.svg index 1c31f02e..21b32468 100644 --- a/docs/images/chapters/curvefitting/8d09f2be2c6db79ee966f170ffc25815.svg +++ b/docs/images/chapters/curvefitting/8d09f2be2c6db79ee966f170ffc25815.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/9151c0fdf9689ee598a2d029ab2ffe34.svg b/docs/images/chapters/curvefitting/9151c0fdf9689ee598a2d029ab2ffe34.svg index def94e94..dd636864 100644 --- a/docs/images/chapters/curvefitting/9151c0fdf9689ee598a2d029ab2ffe34.svg +++ b/docs/images/chapters/curvefitting/9151c0fdf9689ee598a2d029ab2ffe34.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/94acb5850778dcb16c2ba3cfa676f537.svg b/docs/images/chapters/curvefitting/94acb5850778dcb16c2ba3cfa676f537.svg index 90d4c93e..06f1c69c 100644 --- a/docs/images/chapters/curvefitting/94acb5850778dcb16c2ba3cfa676f537.svg +++ b/docs/images/chapters/curvefitting/94acb5850778dcb16c2ba3cfa676f537.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/ab334858d3fa309cc1a5ba535a2ca168.svg b/docs/images/chapters/curvefitting/ab334858d3fa309cc1a5ba535a2ca168.svg index 4d82266c..c160e8af 100644 --- a/docs/images/chapters/curvefitting/ab334858d3fa309cc1a5ba535a2ca168.svg +++ b/docs/images/chapters/curvefitting/ab334858d3fa309cc1a5ba535a2ca168.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/bd8e8e294eec10d2bf6ef857c7c0c2c2.svg b/docs/images/chapters/curvefitting/bd8e8e294eec10d2bf6ef857c7c0c2c2.svg index 0cd86b17..202dc477 100644 --- a/docs/images/chapters/curvefitting/bd8e8e294eec10d2bf6ef857c7c0c2c2.svg +++ b/docs/images/chapters/curvefitting/bd8e8e294eec10d2bf6ef857c7c0c2c2.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/curvefitting/c2c92587a184efa6c4fee45e4a3e32ed.png b/docs/images/chapters/curvefitting/c2c92587a184efa6c4fee45e4a3e32ed.png new file mode 100644 index 0000000000000000000000000000000000000000..7cf3f91870603eafee3a161f16c5ad721022c6b3 GIT binary patch literal 1703 zcmeAS@N?(olHy`uVBq!ia0y~yU{YgXU=-$H1Bx(BJbM&Ku_bxCyDsT2+xVLdKOh}x;z#w_Ma$fv?!=3M|)6%}x*8d4ue)%O(>AUN5 zyMZb;{tWK}>UvqS%j2XhOxB@kjF_?j$qBiW^YL bzK3zmdv7c2gA#?nnuo#D)z4*}Q$iB}Kd@-7 literal 0 HcmV?d00001 diff --git a/docs/images/chapters/curvefitting/d84d1c71a3ce1918f53eaf8f9fe98ac4.svg b/docs/images/chapters/curvefitting/d84d1c71a3ce1918f53eaf8f9fe98ac4.svg index 047757ec..3f29b46c 100644 --- a/docs/images/chapters/curvefitting/d84d1c71a3ce1918f53eaf8f9fe98ac4.svg +++ b/docs/images/chapters/curvefitting/d84d1c71a3ce1918f53eaf8f9fe98ac4.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/matrixsplit/77a11d65d7cffc4b84a85c4bec837792.svg b/docs/images/chapters/matrixsplit/77a11d65d7cffc4b84a85c4bec837792.svg new file mode 100644 index 00000000..36cae683 --- /dev/null +++ b/docs/images/chapters/matrixsplit/77a11d65d7cffc4b84a85c4bec837792.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 2a6b7ba4..56f8d640 100644 --- a/docs/index.html +++ b/docs/index.html @@ -353,7 +353,7 @@ function Bezier(3,t):

Also shown is the interpolation function for a 15th order Bézier function. As you can see, the start and end point contribute considerably more to the curve's shape than any other point in the control point set.

If we want to change the curve, we need to change the weights of each point, effectively changing the interpolations. The way to do this is about as straightforward as possible: just multiply each point with a value that changes its strength. These values are conventionally called "weights", and we can add them to our original Bézier function:

- +

That looks complicated, but as it so happens, the "weights" are actually just the coordinate values we want our curve to have: for an nth order curve, w0 is our start coordinate, wn is our last coordinate, and everything in between is a controlling coordinate. Say we want a cubic curve that starts at (110,150), is controlled by (25,190) and (210,250) and ends at (210,30), we use this Bézier curve:

Which gives us the curve we saw at the top of the article:

@@ -637,7 +637,7 @@ function drawCurve(points[], t):

Splitting curves using matrices

Another way to split curves is to exploit the matrix representation of a Bézier curve. In the section on matrices, we saw that we can represent curves as matrix multiplications. Specifically, we saw these two forms for the quadratic and cubic curves respectively: (we'll reverse the Bézier coefficients vector for legibility)

- +

and

Let's say we want to split the curve at some point t = z, forming two new (obviously smaller) Bézier curves. To find the coordinates for these two Bézier curves, we can use the matrix representation and some linear algebra. First, we separate out the actual "point on the curve" information into a new matrix multiplication:

@@ -1725,25 +1725,25 @@ for (coordinate, index) in LUT:

Revisiting the matrix representation

Rewriting Bézier functions to matrix form is fairly easy, if you first expand the function, and then arrange them into a multiple line form, where each line corresponds to a power of t, and each column is for a specific coefficient. First, we expand the function:

- +

And then we (trivially) rearrange the terms across multiple lines:

- +

This rearrangement has "factors of t" at each row (the first row is t⁰, i.e. "1", the second row is t¹, i.e. "t", the third row is t²) and "coefficient" at each column (the first column is all terms involving "a", the second all terms involving "b", the third all terms involving "c").

With that arrangement, we can easily decompose this as a matrix multiplication:

- +

We can do the same for the cubic curve, of course. We know the base function for cubics:

- +

So we write out the expansion and rearrange:

- +

Which we can then decompose:

- +

And, of course, we can do this for quartic curves too (skipping the expansion step):

- +

And so and on so on. Now, let's see how to use these T, M, and C, to do some curve fitting.

Let's get started: we're going to assume we picked the right order curve: for n points we're fitting an n-1th order curve, so we "start" with a vector P that represents the coordinates we already know, and for which we want to do curve fitting:

- +

Next, we need to figure out appropriate t values for each point in the curve, because we need something that lets us tie "the actual coordinate" to "some point on the curve". There's a fair number of different ways to do this (and a large part of optimizing "the perfect fit" is about picking appropriate t values), but in this case let's look at two "obvious" choices:

  1. equally spaced t values, and
  2. @@ -1752,27 +1752,27 @@ for (coordinate, index) in LUT:

    The first one is really simple: if we have n points, then we'll just assign each point i a t value of (i-1)/(n-1). So if we have four points, the first point will have t=(1-1)/(4-1)=0/3, the second point will have t=(2-1)/(4-1)=1/3, the third point will have t=2/3, and the last point will be t=1. We're just straight up spacing the t values to match the number of points we have.

    The second one is a little more interesting: since we're doing polynomial regression, we might as well exploit the fact that our base coordinates just constitute a collection of line segments. At the first point, we're fixing t=0, and the last point, we want t=1, and anywhere in between we're simply going to say that t is equal to the distance along the polygon, scaled to the [0,1] domain.

    To get these values, we first compute the general "distance along the polygon" matrix:

    - +

    Where length() is literally just that: the length of the line segment between the point we're looking at, and the previous point. This isn't quite enough, of course: we still need to make sure that all the values between i=1 and i=n fall in the [0,1] interval, so we need to scale all values down by whatever the total length of the polygon is:

    - +

    And now we can move on to the actual "curve fitting" part: what we want is a function that lets us compute "ideal" control point values such that if we build a Bézier curve with them, that curve passes through all our original points. Or, failing that, have an overall error distance that is as close to zero as we can get it. So, let's write out what the error distance looks like.

    As mentioned before, this function is really just "the distance between the actual coordinate, and the coordinate that the curve evaluates to for the associated t value", which we'll square to get rid of any pesky negative signs:

    - +

    Since this function only deals with individual coordinates, we'll need to sum over all coordinates in order to get the full error function. So, we literally just do that; the total error function is simply the sum of all these individual errors:

    - +

    And here's the trick that justifies using matrices: while we can work with individual values using calculus, with matrices we can compute as many values as we make our matrices big, all at the "same time", We can replace the individual terms pi with the full P coordinate matrix, and we can replace Bézier(si) with the matrix representation T x M x C we talked about before, which gives us:

    - +

    In which we can replace the rather cumbersome "squaring" operation with a more conventional matrix equivalent:

    - +

    Here, the letter T is used instead of the number 2, to represent the matrix transpose; each row in the original matrix becomes a column in the transposed matrix instead (row one becomes column one, row two becomes column two, and so on).

    This leaves one problem: T isn't actually the matrix we want: we don't want symbolic t values, we want the actual numerical values that we computed for S, so we need to form a new matrix, which we'll call 𝕋, that makes use of those, and then use that 𝕋 instead of T in our error function:

    - +

    Which, because of the first and last values in S, means:

    - +

    Now we can properly write out the error function as matrix operations:

    - +

    So, we have our error function: we now need to figure out the expression for where that function has minimal value, e.g. where the error between the true coordinates and the coordinates generated by the curve fitting is smallest. Like in standard calculus, this requires taking the derivative, and determining where that derivative is zero:

    - +

    Where did this derivative come from?

    @@ -1782,18 +1782,20 @@ for (coordinate, index) in LUT:

    Now, given the above derivative, we can rearrange the terms (following the rules of matrix algebra) so that we end up with an expression for C:

    - +

    Here, the "to the power negative one" is the notation for the matrix inverse. But that's all we have to do: we're done. Starting with P and inventing some t values based on the polygon the coordinates in P define, we can compute the corresponding Bézier coordinates C that specify a curve that goes through our points. Or, if it can't go through them exactly, as near as possible.

    So before we try that out, how much code is involved in implementing this? Honestly, that answer depends on how much you're going to be writing yourself. If you already have a matrix maths library available, then really not that much code at all. On the other hand, if you are writing this from scratch, you're going to have to write some utility functions for doing your matrix work for you, so it's really anywhere from 50 lines of code to maybe 200 lines of code. Not a bad price to pay for being able to fit curves to prespecified coordinates.

    -

    So let's try it out! The following graphic lets you place points, and will start computing exact-fit curves once you've placed at least three. You can click for more points, and the code will simply try to compute an exact fit using a Bézier curve of the appropriate order. Four points? Cubic Bézier. Five points? Quartic. And so on. Of course, this does break down at some point: depending on where you place your points, it might become mighty hard for the fitter to find an exact fit, and things might actually start looking horribly off once you hit 10th or higher order curves. But it might not!

    -
    - - - (this.sliders=set) } onChange={this.processTimeUpdate} /> - -
    +

    So let's try it out! The following graphic lets you place points, and will start computing exact-fit curves once you've placed at least three. You can click for more points, and the code will simply try to compute an exact fit using a Bézier curve of the appropriate order. Four points? Cubic Bézier. Five points? Quartic. And so on. Of course, this does break down at some point: depending on where you place your points, it might become mighty hard for the fitter to find an exact fit, and things might actually start looking horribly off once there's enough points for compound floating point rounding errors to start making a difference (which is around 10~11 points).

    + + + + Scripts are disabled. Showing fallback image. + + +
    +
    -

    You'll note there is a convenient "toggle" buttons that lets you toggle between equidistance t values, and distance ratio along the polygon. Arguably more interesting is that once you have points to abstract a curve, you also get direct control over the time values through sliders for each, because if the time values are our degree of freedom, you should be able to freely manipulate them and see what the effect on your curve is.

    +

    You'll note there is a convenient "toggle" buttons that lets you toggle between equidistant t values, and distance ratio along the polygon formed by the points. Arguably more interesting is that once you have points to abstract a curve, you also get direct control over the time values through sliders for each, because if the time values are our degree of freedom, you should be able to freely manipulate them and see what the effect on your curve is.

@@ -2042,7 +2044,7 @@ for (coordinate, index) in LUT:

which we can then substitute in the expression for a:

A quick check shows that plugging these values for a and b into the expressions for Cx and Cy give the same x/y coordinates for both "a away from A" and "b away from B", so let's continue: now that we know the coordinate values for C, we know where our on-curve point T for t=0.5 (or angle φ/2) is, because we can just evaluate the Bézier polynomial, and we know where the circle arc's actual point P is for angle φ/2:

- +

We compute T, observing that if t=0.5, the polynomial values (1-t)², 2(1-t)t, and t² are 0.25, 0.5, and 0.25 respectively:

Which, worked out for the x and y components, gives:

diff --git a/docs/ja-JP/index.html b/docs/ja-JP/index.html index 073a3792..1d95fdf8 100644 --- a/docs/ja-JP/index.html +++ b/docs/ja-JP/index.html @@ -634,7 +634,7 @@ function drawCurve(points[], t):

行列による曲線の分割

曲線分割には、ベジエ曲線の行列表現を利用する方法もあります。行列についての節では、行列の乗算で曲線が表現できることを確認しました。特に2次・3次のベジエ曲線に関しては、それぞれ以下のような形になりました(読みやすさのため、ベジエの係数ベクトルを反転させています)。

- +

ならびに

曲線をある点t = zで分割し、新しく2つの(自明ですが、より短い)ベジエ曲線を作ることを考えましょう。曲線の行列表現と線形代数を利用すると、この2つのベジエ曲線の座標を求めることができます。まず、実際の「曲線上の点」の情報を分解し、新しい行列の積のかたちにします。

@@ -1722,25 +1722,25 @@ for (coordinate, index) in LUT:

Revisiting the matrix representation

Rewriting Bézier functions to matrix form is fairly easy, if you first expand the function, and then arrange them into a multiple line form, where each line corresponds to a power of t, and each column is for a specific coefficient. First, we expand the function:

- +

And then we (trivially) rearrange the terms across multiple lines:

- +

This rearrangement has "factors of t" at each row (the first row is t⁰, i.e. "1", the second row is t¹, i.e. "t", the third row is t²) and "coefficient" at each column (the first column is all terms involving "a", the second all terms involving "b", the third all terms involving "c").

With that arrangement, we can easily decompose this as a matrix multiplication:

- +

We can do the same for the cubic curve, of course. We know the base function for cubics:

- +

So we write out the expansion and rearrange:

- +

Which we can then decompose:

- +

And, of course, we can do this for quartic curves too (skipping the expansion step):

- +

And so and on so on. Now, let's see how to use these T, M, and C, to do some curve fitting.

Let's get started: we're going to assume we picked the right order curve: for n points we're fitting an n-1th order curve, so we "start" with a vector P that represents the coordinates we already know, and for which we want to do curve fitting:

- +

Next, we need to figure out appropriate t values for each point in the curve, because we need something that lets us tie "the actual coordinate" to "some point on the curve". There's a fair number of different ways to do this (and a large part of optimizing "the perfect fit" is about picking appropriate t values), but in this case let's look at two "obvious" choices:

  1. equally spaced t values, and
  2. @@ -1749,27 +1749,27 @@ for (coordinate, index) in LUT:

    The first one is really simple: if we have n points, then we'll just assign each point i a t value of (i-1)/(n-1). So if we have four points, the first point will have t=(1-1)/(4-1)=0/3, the second point will have t=(2-1)/(4-1)=1/3, the third point will have t=2/3, and the last point will be t=1. We're just straight up spacing the t values to match the number of points we have.

    The second one is a little more interesting: since we're doing polynomial regression, we might as well exploit the fact that our base coordinates just constitute a collection of line segments. At the first point, we're fixing t=0, and the last point, we want t=1, and anywhere in between we're simply going to say that t is equal to the distance along the polygon, scaled to the [0,1] domain.

    To get these values, we first compute the general "distance along the polygon" matrix:

    - +

    Where length() is literally just that: the length of the line segment between the point we're looking at, and the previous point. This isn't quite enough, of course: we still need to make sure that all the values between i=1 and i=n fall in the [0,1] interval, so we need to scale all values down by whatever the total length of the polygon is:

    - +

    And now we can move on to the actual "curve fitting" part: what we want is a function that lets us compute "ideal" control point values such that if we build a Bézier curve with them, that curve passes through all our original points. Or, failing that, have an overall error distance that is as close to zero as we can get it. So, let's write out what the error distance looks like.

    As mentioned before, this function is really just "the distance between the actual coordinate, and the coordinate that the curve evaluates to for the associated t value", which we'll square to get rid of any pesky negative signs:

    - +

    Since this function only deals with individual coordinates, we'll need to sum over all coordinates in order to get the full error function. So, we literally just do that; the total error function is simply the sum of all these individual errors:

    - +

    And here's the trick that justifies using matrices: while we can work with individual values using calculus, with matrices we can compute as many values as we make our matrices big, all at the "same time", We can replace the individual terms pi with the full P coordinate matrix, and we can replace Bézier(si) with the matrix representation T x M x C we talked about before, which gives us:

    - +

    In which we can replace the rather cumbersome "squaring" operation with a more conventional matrix equivalent:

    - +

    Here, the letter T is used instead of the number 2, to represent the matrix transpose; each row in the original matrix becomes a column in the transposed matrix instead (row one becomes column one, row two becomes column two, and so on).

    This leaves one problem: T isn't actually the matrix we want: we don't want symbolic t values, we want the actual numerical values that we computed for S, so we need to form a new matrix, which we'll call 𝕋, that makes use of those, and then use that 𝕋 instead of T in our error function:

    - +

    Which, because of the first and last values in S, means:

    - +

    Now we can properly write out the error function as matrix operations:

    - +

    So, we have our error function: we now need to figure out the expression for where that function has minimal value, e.g. where the error between the true coordinates and the coordinates generated by the curve fitting is smallest. Like in standard calculus, this requires taking the derivative, and determining where that derivative is zero:

    - +

    Where did this derivative come from?

    @@ -1779,18 +1779,20 @@ for (coordinate, index) in LUT:

    Now, given the above derivative, we can rearrange the terms (following the rules of matrix algebra) so that we end up with an expression for C:

    - +

    Here, the "to the power negative one" is the notation for the matrix inverse. But that's all we have to do: we're done. Starting with P and inventing some t values based on the polygon the coordinates in P define, we can compute the corresponding Bézier coordinates C that specify a curve that goes through our points. Or, if it can't go through them exactly, as near as possible.

    So before we try that out, how much code is involved in implementing this? Honestly, that answer depends on how much you're going to be writing yourself. If you already have a matrix maths library available, then really not that much code at all. On the other hand, if you are writing this from scratch, you're going to have to write some utility functions for doing your matrix work for you, so it's really anywhere from 50 lines of code to maybe 200 lines of code. Not a bad price to pay for being able to fit curves to prespecified coordinates.

    -

    So let's try it out! The following graphic lets you place points, and will start computing exact-fit curves once you've placed at least three. You can click for more points, and the code will simply try to compute an exact fit using a Bézier curve of the appropriate order. Four points? Cubic Bézier. Five points? Quartic. And so on. Of course, this does break down at some point: depending on where you place your points, it might become mighty hard for the fitter to find an exact fit, and things might actually start looking horribly off once you hit 10th or higher order curves. But it might not!

    -
    - - - (this.sliders=set) } onChange={this.processTimeUpdate} /> - -
    +

    So let's try it out! The following graphic lets you place points, and will start computing exact-fit curves once you've placed at least three. You can click for more points, and the code will simply try to compute an exact fit using a Bézier curve of the appropriate order. Four points? Cubic Bézier. Five points? Quartic. And so on. Of course, this does break down at some point: depending on where you place your points, it might become mighty hard for the fitter to find an exact fit, and things might actually start looking horribly off once there's enough points for compound floating point rounding errors to start making a difference (which is around 10~11 points).

    + + + + Scripts are disabled. Showing fallback image. + + +
    +
    -

    You'll note there is a convenient "toggle" buttons that lets you toggle between equidistance t values, and distance ratio along the polygon. Arguably more interesting is that once you have points to abstract a curve, you also get direct control over the time values through sliders for each, because if the time values are our degree of freedom, you should be able to freely manipulate them and see what the effect on your curve is.

    +

    You'll note there is a convenient "toggle" buttons that lets you toggle between equidistant t values, and distance ratio along the polygon formed by the points. Arguably more interesting is that once you have points to abstract a curve, you also get direct control over the time values through sliders for each, because if the time values are our degree of freedom, you should be able to freely manipulate them and see what the effect on your curve is.

@@ -2039,7 +2041,7 @@ for (coordinate, index) in LUT:

which we can then substitute in the expression for a:

A quick check shows that plugging these values for a and b into the expressions for Cx and Cy give the same x/y coordinates for both "a away from A" and "b away from B", so let's continue: now that we know the coordinate values for C, we know where our on-curve point T for t=0.5 (or angle φ/2) is, because we can just evaluate the Bézier polynomial, and we know where the circle arc's actual point P is for angle φ/2:

- +

We compute T, observing that if t=0.5, the polynomial values (1-t)², 2(1-t)t, and t² are 0.25, 0.5, and 0.25 respectively:

Which, worked out for the x and y components, gives:

diff --git a/docs/js/custom-element/api/graphics-api.js b/docs/js/custom-element/api/graphics-api.js index a2ab9261..2e9e1298 100644 --- a/docs/js/custom-element/api/graphics-api.js +++ b/docs/js/custom-element/api/graphics-api.js @@ -633,11 +633,12 @@ class GraphicsAPI extends BaseAPI { * convenient grid drawing function */ drawGrid(division = 20) { - for (let x = (division / 2) | 0; x < this.width; x += division) { - this.line({ x, y: 0 }, { x, y: this.height }); + let w = this.panelWidth ?? this.width; + for (let x = (division / 2) | 0; x < w; x += division) { + this.line(x, 0, x, this.height); } for (let y = (division / 2) | 0; y < this.height; y += division) { - this.line({ x: 0, y }, { x: this.width, y }); + this.line(0, y, w, y); } } diff --git a/docs/placeholder-style.css b/docs/placeholder-style.css index 6a457e42..4c73a97b 100644 --- a/docs/placeholder-style.css +++ b/docs/placeholder-style.css @@ -143,5 +143,6 @@ p code { } .slide-control { + display: block; width: 100%; -} \ No newline at end of file +} diff --git a/docs/zh-CN/index.html b/docs/zh-CN/index.html index 7c5bc62a..c7c20560 100644 --- a/docs/zh-CN/index.html +++ b/docs/zh-CN/index.html @@ -349,7 +349,7 @@ function Bezier(3,t):

上面有一张是15th阶的插值方程。如你所见,在所有控制点中,起点和终点对曲线形状的贡献比其他点更大些。

如果我们要改变曲线,就需要改变每个点的权重,有效地改变插值。可以很直接地做到这个:只要用一个值乘以每个点,来改变它的强度。这个值照惯例称为“权重”,我们可以将它加入我们原始的贝塞尔函数:

- +

看起来很复杂,但实际上“权重”只是我们想让曲线所拥有的坐标值:对于一条nth阶曲线,w0是起始坐标,wn是终点坐标,中间的所有点都是控制点坐标。假设说一条曲线的起点为(120,160),终点为(220,40),并受点(35,200)和点(220,260)的控制,贝塞尔曲线方程就为:

这就是我们在文章开头看到的曲线:

@@ -628,7 +628,7 @@ function drawCurve(points[], t):

Splitting curves using matrices

Another way to split curves is to exploit the matrix representation of a Bézier curve. In the section on matrices, we saw that we can represent curves as matrix multiplications. Specifically, we saw these two forms for the quadratic and cubic curves respectively: (we'll reverse the Bézier coefficients vector for legibility)

- +

and

Let's say we want to split the curve at some point t = z, forming two new (obviously smaller) Bézier curves. To find the coordinates for these two Bézier curves, we can use the matrix representation and some linear algebra. First, we separate out the actual "point on the curve" information into a new matrix multiplication:

@@ -1716,25 +1716,25 @@ for (coordinate, index) in LUT:

Revisiting the matrix representation

Rewriting Bézier functions to matrix form is fairly easy, if you first expand the function, and then arrange them into a multiple line form, where each line corresponds to a power of t, and each column is for a specific coefficient. First, we expand the function:

- +

And then we (trivially) rearrange the terms across multiple lines:

- +

This rearrangement has "factors of t" at each row (the first row is t⁰, i.e. "1", the second row is t¹, i.e. "t", the third row is t²) and "coefficient" at each column (the first column is all terms involving "a", the second all terms involving "b", the third all terms involving "c").

With that arrangement, we can easily decompose this as a matrix multiplication:

- +

We can do the same for the cubic curve, of course. We know the base function for cubics:

- +

So we write out the expansion and rearrange:

- +

Which we can then decompose:

- +

And, of course, we can do this for quartic curves too (skipping the expansion step):

- +

And so and on so on. Now, let's see how to use these T, M, and C, to do some curve fitting.

Let's get started: we're going to assume we picked the right order curve: for n points we're fitting an n-1th order curve, so we "start" with a vector P that represents the coordinates we already know, and for which we want to do curve fitting:

- +

Next, we need to figure out appropriate t values for each point in the curve, because we need something that lets us tie "the actual coordinate" to "some point on the curve". There's a fair number of different ways to do this (and a large part of optimizing "the perfect fit" is about picking appropriate t values), but in this case let's look at two "obvious" choices:

  1. equally spaced t values, and
  2. @@ -1743,27 +1743,27 @@ for (coordinate, index) in LUT:

    The first one is really simple: if we have n points, then we'll just assign each point i a t value of (i-1)/(n-1). So if we have four points, the first point will have t=(1-1)/(4-1)=0/3, the second point will have t=(2-1)/(4-1)=1/3, the third point will have t=2/3, and the last point will be t=1. We're just straight up spacing the t values to match the number of points we have.

    The second one is a little more interesting: since we're doing polynomial regression, we might as well exploit the fact that our base coordinates just constitute a collection of line segments. At the first point, we're fixing t=0, and the last point, we want t=1, and anywhere in between we're simply going to say that t is equal to the distance along the polygon, scaled to the [0,1] domain.

    To get these values, we first compute the general "distance along the polygon" matrix:

    - +

    Where length() is literally just that: the length of the line segment between the point we're looking at, and the previous point. This isn't quite enough, of course: we still need to make sure that all the values between i=1 and i=n fall in the [0,1] interval, so we need to scale all values down by whatever the total length of the polygon is:

    - +

    And now we can move on to the actual "curve fitting" part: what we want is a function that lets us compute "ideal" control point values such that if we build a Bézier curve with them, that curve passes through all our original points. Or, failing that, have an overall error distance that is as close to zero as we can get it. So, let's write out what the error distance looks like.

    As mentioned before, this function is really just "the distance between the actual coordinate, and the coordinate that the curve evaluates to for the associated t value", which we'll square to get rid of any pesky negative signs:

    - +

    Since this function only deals with individual coordinates, we'll need to sum over all coordinates in order to get the full error function. So, we literally just do that; the total error function is simply the sum of all these individual errors:

    - +

    And here's the trick that justifies using matrices: while we can work with individual values using calculus, with matrices we can compute as many values as we make our matrices big, all at the "same time", We can replace the individual terms pi with the full P coordinate matrix, and we can replace Bézier(si) with the matrix representation T x M x C we talked about before, which gives us:

    - +

    In which we can replace the rather cumbersome "squaring" operation with a more conventional matrix equivalent:

    - +

    Here, the letter T is used instead of the number 2, to represent the matrix transpose; each row in the original matrix becomes a column in the transposed matrix instead (row one becomes column one, row two becomes column two, and so on).

    This leaves one problem: T isn't actually the matrix we want: we don't want symbolic t values, we want the actual numerical values that we computed for S, so we need to form a new matrix, which we'll call 𝕋, that makes use of those, and then use that 𝕋 instead of T in our error function:

    - +

    Which, because of the first and last values in S, means:

    - +

    Now we can properly write out the error function as matrix operations:

    - +

    So, we have our error function: we now need to figure out the expression for where that function has minimal value, e.g. where the error between the true coordinates and the coordinates generated by the curve fitting is smallest. Like in standard calculus, this requires taking the derivative, and determining where that derivative is zero:

    - +

    Where did this derivative come from?

    @@ -1773,18 +1773,20 @@ for (coordinate, index) in LUT:

    Now, given the above derivative, we can rearrange the terms (following the rules of matrix algebra) so that we end up with an expression for C:

    - +

    Here, the "to the power negative one" is the notation for the matrix inverse. But that's all we have to do: we're done. Starting with P and inventing some t values based on the polygon the coordinates in P define, we can compute the corresponding Bézier coordinates C that specify a curve that goes through our points. Or, if it can't go through them exactly, as near as possible.

    So before we try that out, how much code is involved in implementing this? Honestly, that answer depends on how much you're going to be writing yourself. If you already have a matrix maths library available, then really not that much code at all. On the other hand, if you are writing this from scratch, you're going to have to write some utility functions for doing your matrix work for you, so it's really anywhere from 50 lines of code to maybe 200 lines of code. Not a bad price to pay for being able to fit curves to prespecified coordinates.

    -

    So let's try it out! The following graphic lets you place points, and will start computing exact-fit curves once you've placed at least three. You can click for more points, and the code will simply try to compute an exact fit using a Bézier curve of the appropriate order. Four points? Cubic Bézier. Five points? Quartic. And so on. Of course, this does break down at some point: depending on where you place your points, it might become mighty hard for the fitter to find an exact fit, and things might actually start looking horribly off once you hit 10th or higher order curves. But it might not!

    -
    - - - (this.sliders=set) } onChange={this.processTimeUpdate} /> - -
    +

    So let's try it out! The following graphic lets you place points, and will start computing exact-fit curves once you've placed at least three. You can click for more points, and the code will simply try to compute an exact fit using a Bézier curve of the appropriate order. Four points? Cubic Bézier. Five points? Quartic. And so on. Of course, this does break down at some point: depending on where you place your points, it might become mighty hard for the fitter to find an exact fit, and things might actually start looking horribly off once there's enough points for compound floating point rounding errors to start making a difference (which is around 10~11 points).

    + + + + Scripts are disabled. Showing fallback image. + + +
    +
    -

    You'll note there is a convenient "toggle" buttons that lets you toggle between equidistance t values, and distance ratio along the polygon. Arguably more interesting is that once you have points to abstract a curve, you also get direct control over the time values through sliders for each, because if the time values are our degree of freedom, you should be able to freely manipulate them and see what the effect on your curve is.

    +

    You'll note there is a convenient "toggle" buttons that lets you toggle between equidistant t values, and distance ratio along the polygon formed by the points. Arguably more interesting is that once you have points to abstract a curve, you also get direct control over the time values through sliders for each, because if the time values are our degree of freedom, you should be able to freely manipulate them and see what the effect on your curve is.

@@ -2033,7 +2035,7 @@ for (coordinate, index) in LUT:

which we can then substitute in the expression for a:

A quick check shows that plugging these values for a and b into the expressions for Cx and Cy give the same x/y coordinates for both "a away from A" and "b away from B", so let's continue: now that we know the coordinate values for C, we know where our on-curve point T for t=0.5 (or angle φ/2) is, because we can just evaluate the Bézier polynomial, and we know where the circle arc's actual point P is for angle φ/2:

- +

We compute T, observing that if t=0.5, the polynomial values (1-t)², 2(1-t)t, and t² are 0.25, 0.5, and 0.25 respectively:

Which, worked out for the x and y components, gives: