From c0a1207d670b8ef2ff49e310cd97f255e4815e1d Mon Sep 17 00:00:00 2001 From: Pomax Date: Sun, 13 Sep 2020 13:18:15 -0700 Subject: [PATCH] improved lazy loading --- docs/chapters/circles_cubic/circle.js | 22 ++--- docs/chapters/circles_cubic/content.en-GB.md | 11 ++- .../0364731626a530c8a9b30f424ada53c5.svg | 2 +- .../05d36e051a38905dcb81e65db8261f24.svg | 2 +- .../14c238eb17045cda3205c6ce9944004c.svg | 1 + .../178a838274748439778e2a29f5a27d0b.svg | 2 +- .../195790bae7de813aec342ea82b5d8781.svg | 2 +- .../1ab9827727b8f7fe466a124b0e1867ce.svg | 1 + .../3189cac1ddac07c1487e1e51740ecc88.svg | 2 +- .../49dbf244d50c787a4ab18694488d9b69.svg | 1 - .../63f35fb58d3571200ac6ccea0384b9d7.png | Bin 0 -> 13275 bytes .../8676cce0d4394ae095c7e50be1238aa0.png | Bin 12990 -> 0 bytes .../877f9c217c51c0087be751a7580ed459.svg | 2 +- .../a4f0dafbfe80c88723c3cc22277a9682.svg | 2 +- .../acbc5efb06bc34571ccc0322376e0b9b.svg | 2 +- .../dfb83eec053c30e0a41b0a52aba24cd4.svg | 2 +- .../e2258660a796dcd6189a6f5e14326dad.svg | 2 +- .../e75a848f5f8aead495e35175e2955e06.svg | 1 - .../ee08d86b7497c7ab042ee899bf15d453.svg | 2 +- .../fe32474b4616ee9478e1308308f1b6bf.svg | 2 +- docs/index.html | 56 ++++++------- docs/ja-JP/index.html | 56 ++++++------- docs/js/site/better-lazy-loading.js | 38 +++++++++ docs/js/site/disqus.js | 25 ++---- docs/js/site/faster-lazy-loading.js | 77 ------------------ docs/zh-CN/index.html | 56 ++++++------- src/index.template.html | 2 +- 27 files changed, 163 insertions(+), 208 deletions(-) create mode 100644 docs/images/chapters/circles_cubic/14c238eb17045cda3205c6ce9944004c.svg create mode 100644 docs/images/chapters/circles_cubic/1ab9827727b8f7fe466a124b0e1867ce.svg delete mode 100644 docs/images/chapters/circles_cubic/49dbf244d50c787a4ab18694488d9b69.svg create mode 100644 docs/images/chapters/circles_cubic/63f35fb58d3571200ac6ccea0384b9d7.png delete mode 100644 docs/images/chapters/circles_cubic/8676cce0d4394ae095c7e50be1238aa0.png delete mode 100644 docs/images/chapters/circles_cubic/e75a848f5f8aead495e35175e2955e06.svg create mode 100644 docs/js/site/better-lazy-loading.js delete mode 100644 docs/js/site/faster-lazy-loading.js diff --git a/docs/chapters/circles_cubic/circle.js b/docs/chapters/circles_cubic/circle.js index 32dc4ce3..d18cb30f 100644 --- a/docs/chapters/circles_cubic/circle.js +++ b/docs/chapters/circles_cubic/circle.js @@ -1,11 +1,11 @@ -let curve, r; +let curve, r, kappa = 0.5519768352769461; setup() { r = 100; curve = new Bezier(this, [ { x: r, y: 0 }, - { x: r, y: 0.55228 * r }, - { x: 0.55228 * r, y: r}, + { x: r, y: kappa * r }, + { x: kappa * r, y: r}, { x: 0, y: r } ]); } @@ -38,12 +38,12 @@ draw() { curve.drawCurve(`#CC00CC40`); setColor(`#CC00CC`); - line(r, 0, r, -0.55228 * r); - circle(r, -0.55228 * r, 2); - text(`reflected`, r + 7, -0.55228 * r + 3, LEFT); + line(r, 0, r, -kappa * r); + circle(r, -kappa * r, 2); + text(`reflected`, r + 7, -kappa * r + 3, LEFT); setColor(`#CC00CC40`); - line(0, -r, 0.55228 * r, -r); + line(0, -r, kappa * r, -r); curve.points.forEach(p => { p.x = -p.x; @@ -52,12 +52,12 @@ draw() { curve.drawCurve(`#0000CC40`); setColor(`#0000CC`); - line(0, r, -0.55228 * r, r); - circle(-0.55228 * r, r, 2); - text(`reflected`, -0.55228 * r - 5, r + 3, RIGHT); + line(0, r, -kappa * r, r); + circle(-kappa * r, r, 2); + text(`reflected`, -kappa * r - 5, r + 3, RIGHT); setColor(`#0000CC40`); - line(-r, 0, -r, 0.55228 * r); + line(-r, 0, -r, kappa * r); curve.points.forEach(p => p.y = -p.y); curve.drawCurve(`#00000040`); diff --git a/docs/chapters/circles_cubic/content.en-GB.md b/docs/chapters/circles_cubic/content.en-GB.md index 4d6af720..de372d2f 100644 --- a/docs/chapters/circles_cubic/content.en-GB.md +++ b/docs/chapters/circles_cubic/content.en-GB.md @@ -47,13 +47,13 @@ But we now need to find two control points, rather than one. If we want the deri C_1 = S + a \cdot \begin{pmatrix} 0 \\ 1 \end{pmatrix} \] -where "a" is some scaling factor, and: +where "a" is some scaling factor we'll need to find the expression for, and: \[ - C_2 = E + b \cdot \begin{pmatrix} -sin(φ) \\ cos(φ) \end{pmatrix} + C_2 = E + a \cdot \begin{pmatrix} sin(φ) \\ cos(φ) \end{pmatrix} \] -where "b" is also some scaling factor. +using the same scaling factor, because circular arcs are symmetrical, so our approximation will need to be symmetrical, too. Starting with this information, we slowly maths our way to success, but I won't lie: the maths for this is pretty trig-heavy, and it's easy to get lost if you remember (or know!) some of the core trigonometric identities, so if you just want to see the final result just skip past the next section! @@ -121,7 +121,10 @@ And after this tedious detour to find the coordinate for C1, we can f \[ \begin{array}{l} - E'_x = -sin(φ) \ , \ E'_y = cos(φ) \ , \ ||E'|| = \sqrt{ (-sin(φ))^2 + cos^2(φ)} = 1 \ , \\ + E'_x = -sin(φ) \ ,\\ + E'_y = cos(φ) \ , \\ + ||E'|| = \sqrt{ (-sin(φ))^2 + cos^2(φ)} = 1 \ , \\ + \\ \left\{\begin{array}{l} C_2x = E_x - C_{1y} \cdot \frac{E_x'}{||E'||} = cos(φ) + C_{1y} \cdot sin(φ) diff --git a/docs/images/chapters/circles_cubic/0364731626a530c8a9b30f424ada53c5.svg b/docs/images/chapters/circles_cubic/0364731626a530c8a9b30f424ada53c5.svg index 08f5460d..dfb2ece0 100644 --- a/docs/images/chapters/circles_cubic/0364731626a530c8a9b30f424ada53c5.svg +++ b/docs/images/chapters/circles_cubic/0364731626a530c8a9b30f424ada53c5.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/05d36e051a38905dcb81e65db8261f24.svg b/docs/images/chapters/circles_cubic/05d36e051a38905dcb81e65db8261f24.svg index 6c0e7823..6d2d3b15 100644 --- a/docs/images/chapters/circles_cubic/05d36e051a38905dcb81e65db8261f24.svg +++ b/docs/images/chapters/circles_cubic/05d36e051a38905dcb81e65db8261f24.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/14c238eb17045cda3205c6ce9944004c.svg b/docs/images/chapters/circles_cubic/14c238eb17045cda3205c6ce9944004c.svg new file mode 100644 index 00000000..fd34be51 --- /dev/null +++ b/docs/images/chapters/circles_cubic/14c238eb17045cda3205c6ce9944004c.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/178a838274748439778e2a29f5a27d0b.svg b/docs/images/chapters/circles_cubic/178a838274748439778e2a29f5a27d0b.svg index 7de57979..3eadf6f1 100644 --- a/docs/images/chapters/circles_cubic/178a838274748439778e2a29f5a27d0b.svg +++ b/docs/images/chapters/circles_cubic/178a838274748439778e2a29f5a27d0b.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/195790bae7de813aec342ea82b5d8781.svg b/docs/images/chapters/circles_cubic/195790bae7de813aec342ea82b5d8781.svg index a4cb1fd1..4a9ef33b 100644 --- a/docs/images/chapters/circles_cubic/195790bae7de813aec342ea82b5d8781.svg +++ b/docs/images/chapters/circles_cubic/195790bae7de813aec342ea82b5d8781.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/1ab9827727b8f7fe466a124b0e1867ce.svg b/docs/images/chapters/circles_cubic/1ab9827727b8f7fe466a124b0e1867ce.svg new file mode 100644 index 00000000..3d4afb89 --- /dev/null +++ b/docs/images/chapters/circles_cubic/1ab9827727b8f7fe466a124b0e1867ce.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/3189cac1ddac07c1487e1e51740ecc88.svg b/docs/images/chapters/circles_cubic/3189cac1ddac07c1487e1e51740ecc88.svg index 8ebfa042..50162924 100644 --- a/docs/images/chapters/circles_cubic/3189cac1ddac07c1487e1e51740ecc88.svg +++ b/docs/images/chapters/circles_cubic/3189cac1ddac07c1487e1e51740ecc88.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/49dbf244d50c787a4ab18694488d9b69.svg b/docs/images/chapters/circles_cubic/49dbf244d50c787a4ab18694488d9b69.svg deleted file mode 100644 index 84fc71e6..00000000 --- a/docs/images/chapters/circles_cubic/49dbf244d50c787a4ab18694488d9b69.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/63f35fb58d3571200ac6ccea0384b9d7.png b/docs/images/chapters/circles_cubic/63f35fb58d3571200ac6ccea0384b9d7.png new file mode 100644 index 0000000000000000000000000000000000000000..b2f6adb987b929397535963407134428589a212a GIT binary patch literal 13275 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 r%*a0gdxfH}*zL3t|Ch*IKgaF*h+E5?{{vntv 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 diff --git a/docs/images/chapters/circles_cubic/877f9c217c51c0087be751a7580ed459.svg b/docs/images/chapters/circles_cubic/877f9c217c51c0087be751a7580ed459.svg index b5d632c4..6baa4661 100644 --- a/docs/images/chapters/circles_cubic/877f9c217c51c0087be751a7580ed459.svg +++ b/docs/images/chapters/circles_cubic/877f9c217c51c0087be751a7580ed459.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/a4f0dafbfe80c88723c3cc22277a9682.svg b/docs/images/chapters/circles_cubic/a4f0dafbfe80c88723c3cc22277a9682.svg index a5458b6c..3730c296 100644 --- a/docs/images/chapters/circles_cubic/a4f0dafbfe80c88723c3cc22277a9682.svg +++ b/docs/images/chapters/circles_cubic/a4f0dafbfe80c88723c3cc22277a9682.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/acbc5efb06bc34571ccc0322376e0b9b.svg b/docs/images/chapters/circles_cubic/acbc5efb06bc34571ccc0322376e0b9b.svg index 7b252622..bb89e7c5 100644 --- a/docs/images/chapters/circles_cubic/acbc5efb06bc34571ccc0322376e0b9b.svg +++ b/docs/images/chapters/circles_cubic/acbc5efb06bc34571ccc0322376e0b9b.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/dfb83eec053c30e0a41b0a52aba24cd4.svg b/docs/images/chapters/circles_cubic/dfb83eec053c30e0a41b0a52aba24cd4.svg index 9299a7ca..c26acc14 100644 --- a/docs/images/chapters/circles_cubic/dfb83eec053c30e0a41b0a52aba24cd4.svg +++ b/docs/images/chapters/circles_cubic/dfb83eec053c30e0a41b0a52aba24cd4.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/e2258660a796dcd6189a6f5e14326dad.svg b/docs/images/chapters/circles_cubic/e2258660a796dcd6189a6f5e14326dad.svg index 12aa5b8a..6c823fc5 100644 --- a/docs/images/chapters/circles_cubic/e2258660a796dcd6189a6f5e14326dad.svg +++ b/docs/images/chapters/circles_cubic/e2258660a796dcd6189a6f5e14326dad.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/e75a848f5f8aead495e35175e2955e06.svg b/docs/images/chapters/circles_cubic/e75a848f5f8aead495e35175e2955e06.svg deleted file mode 100644 index 3f8655ad..00000000 --- a/docs/images/chapters/circles_cubic/e75a848f5f8aead495e35175e2955e06.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/ee08d86b7497c7ab042ee899bf15d453.svg b/docs/images/chapters/circles_cubic/ee08d86b7497c7ab042ee899bf15d453.svg index 426522ad..7cd57442 100644 --- a/docs/images/chapters/circles_cubic/ee08d86b7497c7ab042ee899bf15d453.svg +++ b/docs/images/chapters/circles_cubic/ee08d86b7497c7ab042ee899bf15d453.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/images/chapters/circles_cubic/fe32474b4616ee9478e1308308f1b6bf.svg b/docs/images/chapters/circles_cubic/fe32474b4616ee9478e1308308f1b6bf.svg index dea287d7..a3533922 100644 --- a/docs/images/chapters/circles_cubic/fe32474b4616ee9478e1308308f1b6bf.svg +++ b/docs/images/chapters/circles_cubic/fe32474b4616ee9478e1308308f1b6bf.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index cf0a30ac..bdc3d6a0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -59,7 +59,7 @@ - + @@ -5344,7 +5344,7 @@ for p = 1 to points.length-3 (inclusive): @@ -5356,19 +5356,19 @@ for p = 1 to points.length-3 (inclusive): -

where "a" is some scaling factor, and:

+

where "a" is some scaling factor we'll need to find the expression for, and:

-

where "b" is also some scaling factor.

+

using the same scaling factor, because circular arcs are symmetrical, so our approximation will need to be symmetrical, too.

Starting with this information, we slowly maths our way to success, but I won't lie: the maths for this is pretty trig-heavy, and it's easy to get lost if you remember (or know!) some of the core trigonometric identities, so if you just want to see the final result just @@ -5401,8 +5401,8 @@ for p = 1 to points.length-3 (inclusive):

@@ -5413,8 +5413,8 @@ for p = 1 to points.length-3 (inclusive):

@@ -5424,8 +5424,8 @@ for p = 1 to points.length-3 (inclusive):

@@ -5435,15 +5435,15 @@ for p = 1 to points.length-3 (inclusive):

@@ -5453,8 +5453,8 @@ for p = 1 to points.length-3 (inclusive):

@@ -5463,9 +5463,9 @@ for p = 1 to points.length-3 (inclusive):

And that's it, we have all four points now for an approximation of an arbitrary circular arc with angle φ.

@@ -5475,7 +5475,7 @@ for p = 1 to points.length-3 (inclusive): @@ -5483,7 +5483,7 @@ for p = 1 to points.length-3 (inclusive): @@ -5494,15 +5494,15 @@ for p = 1 to points.length-3 (inclusive):

Which, in decimal values, rounded to six significant digits, is:

@@ -5513,7 +5513,7 @@ for p = 1 to points.length-3 (inclusive): Scripts are disabled. Showing fallback image. - + diff --git a/docs/ja-JP/index.html b/docs/ja-JP/index.html index a38eb186..40399b7a 100644 --- a/docs/ja-JP/index.html +++ b/docs/ja-JP/index.html @@ -60,7 +60,7 @@ - + @@ -5179,7 +5179,7 @@ for p = 1 to points.length-3 (inclusive): @@ -5191,19 +5191,19 @@ for p = 1 to points.length-3 (inclusive): -

where "a" is some scaling factor, and:

+

where "a" is some scaling factor we'll need to find the expression for, and:

-

where "b" is also some scaling factor.

+

using the same scaling factor, because circular arcs are symmetrical, so our approximation will need to be symmetrical, too.

Starting with this information, we slowly maths our way to success, but I won't lie: the maths for this is pretty trig-heavy, and it's easy to get lost if you remember (or know!) some of the core trigonometric identities, so if you just want to see the final result just @@ -5236,8 +5236,8 @@ for p = 1 to points.length-3 (inclusive):

@@ -5248,8 +5248,8 @@ for p = 1 to points.length-3 (inclusive):

@@ -5259,8 +5259,8 @@ for p = 1 to points.length-3 (inclusive):

@@ -5270,15 +5270,15 @@ for p = 1 to points.length-3 (inclusive):

@@ -5288,8 +5288,8 @@ for p = 1 to points.length-3 (inclusive):

@@ -5298,9 +5298,9 @@ for p = 1 to points.length-3 (inclusive):

And that's it, we have all four points now for an approximation of an arbitrary circular arc with angle φ.

@@ -5310,7 +5310,7 @@ for p = 1 to points.length-3 (inclusive): @@ -5318,7 +5318,7 @@ for p = 1 to points.length-3 (inclusive): @@ -5329,15 +5329,15 @@ for p = 1 to points.length-3 (inclusive):

Which, in decimal values, rounded to six significant digits, is:

@@ -5348,7 +5348,7 @@ for p = 1 to points.length-3 (inclusive): Scripts are disabled. Showing fallback image. - + diff --git a/docs/js/site/better-lazy-loading.js b/docs/js/site/better-lazy-loading.js new file mode 100644 index 00000000..9c0897ee --- /dev/null +++ b/docs/js/site/better-lazy-loading.js @@ -0,0 +1,38 @@ +/** + * This file takes any with loading="lazy" and rewrites it + * so that it starts to load much earlier than browsers would load + * them, so that they're already done by the time the user gets to + * them. This (mostly) prevents the whole "you can see the image + * loading in", which is super shitty UX. + */ + +const images = Array.from( + document.querySelectorAll(`img.LaTeX.SVG[loading=lazy]`) +); + +// Deactivate the images +images.forEach((img) => { + img.dataset.src = img.src; + img.src = ``; + img.removeAttribute(`loading`); +}); + +// Then make their activation conditional on whether +// they're close to being on-screen or not. +let observer = new IntersectionObserver( + function (entries) { + entries.forEach((entry) => { + if (entry.isIntersecting) { + const img = entry.target; + img.src = img.dataset.src; + const pos = images.indexOf(img); + images.splice(pos, 1); + } + }); + }, + { rootMargin: `100%` } +); + +images.forEach((image) => { + observer.observe(image); +}); diff --git a/docs/js/site/disqus.js b/docs/js/site/disqus.js index 7e4fac84..b60a028d 100644 --- a/docs/js/site/disqus.js +++ b/docs/js/site/disqus.js @@ -1,17 +1,13 @@ -const comments = document.getElementById(`disqus_thread`); - -document.addEventListener("scroll", scrollHandler, { passive: true }); - -function scrollHandler() { - var bbox = comments.getBoundingClientRect(); - var top = bbox.top; - var limit = window.innerHeight; - if (top < limit) { - loadDisqus(); - } -} +new IntersectionObserver(function (entries) { + entries.forEach((entry) => { + if (entry.isIntersecting) { + loadDisqus(); + } + }); +}).observe(document.getElementById(`disqus_thread`)); let loadDisqus = () => { + loadDisqus = () => {}; console.log(`loading Disqus comments`); globalThis.disqus_config = function () { @@ -24,9 +20,4 @@ let loadDisqus = () => { script.async = true; script.setAttribute("data-timestamp", Date.now()); document.head.appendChild(script); - - loadDisqus = () => {}; - document.removeEventListener("scroll", scrollHandler); }; - -scrollHandler(); diff --git a/docs/js/site/faster-lazy-loading.js b/docs/js/site/faster-lazy-loading.js deleted file mode 100644 index 476bda0e..00000000 --- a/docs/js/site/faster-lazy-loading.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * This file takes any with loading="lazy" and rewrites it - * so that it starts to load much earlier than browsers would load - * them, so that they're already done by the time the user gets to - * them. This prevents the ridiculous "don't start loading the img - * until we're already looking at the empty bounding box". - */ - -const images = Array.from( - document.querySelectorAll(`img.LaTeX.SVG[loading=lazy]`) -); - -// First, make images inert. As this happens before the document -// becomes active, this prevents images from loading anything. -// -// Also, by having JS deactivate the images, anyone running with -// JS disabled will still see images load in properly. In fact, -// the "lazy" attribute gets ignored when JS is disabled and all -// images will just load in immediately. - -images.forEach((img) => { - // non-negotiable order of operations: - img.dataset.src = img.src; - img.src = ``; - img.removeAttribute(`loading`); -}); - -// Then tack on the functionality that reactivates them based on viewport distance. - -let lock = false; -let retry = false; - -/** - * Test all images during scroll, in a way that doesn't hang the browser. - */ -function testImages() { - if (lock) { - if (retry) retry = clearTimeout(retry); - retry = setTimeout(testImages, 200); - } - - lock = true; - - let height = document.documentElement.clientHeight; - - for (let pos = images.length - 1; pos >= 0; pos--) { - test(images[pos], pos, height); - } - - if (images.length === 0) { - window.removeEventListener("scroll", testImages); - if (retry) clearTimeout(retry); - } - - lock = false; -} - -/** - * Test individual images for whether or not they should load. - */ -function test(img, pos, height) { - let top = img.getBoundingClientRect().top; - top = top < height; - - let bottom = img.getBoundingClientRect().bottom; - bottom = bottom > -height; - - if (top || bottom) { - img.src = img.dataset.src; - images.splice(pos, 1); - } -} - -/** - * Remember to listen for scroll passively. If you don't, bad things happen. - */ -window.addEventListener("scroll", testImages, { passive: true }); diff --git a/docs/zh-CN/index.html b/docs/zh-CN/index.html index fcd57e40..a38a9fc1 100644 --- a/docs/zh-CN/index.html +++ b/docs/zh-CN/index.html @@ -60,7 +60,7 @@ - + @@ -5151,7 +5151,7 @@ for p = 1 to points.length-3 (inclusive): @@ -5163,19 +5163,19 @@ for p = 1 to points.length-3 (inclusive): -

where "a" is some scaling factor, and:

+

where "a" is some scaling factor we'll need to find the expression for, and:

-

where "b" is also some scaling factor.

+

using the same scaling factor, because circular arcs are symmetrical, so our approximation will need to be symmetrical, too.

Starting with this information, we slowly maths our way to success, but I won't lie: the maths for this is pretty trig-heavy, and it's easy to get lost if you remember (or know!) some of the core trigonometric identities, so if you just want to see the final result just @@ -5208,8 +5208,8 @@ for p = 1 to points.length-3 (inclusive):

@@ -5220,8 +5220,8 @@ for p = 1 to points.length-3 (inclusive):

@@ -5231,8 +5231,8 @@ for p = 1 to points.length-3 (inclusive):

@@ -5242,15 +5242,15 @@ for p = 1 to points.length-3 (inclusive):

@@ -5260,8 +5260,8 @@ for p = 1 to points.length-3 (inclusive):

@@ -5270,9 +5270,9 @@ for p = 1 to points.length-3 (inclusive):

And that's it, we have all four points now for an approximation of an arbitrary circular arc with angle φ.

@@ -5282,7 +5282,7 @@ for p = 1 to points.length-3 (inclusive): @@ -5290,7 +5290,7 @@ for p = 1 to points.length-3 (inclusive): @@ -5301,15 +5301,15 @@ for p = 1 to points.length-3 (inclusive):

Which, in decimal values, rounded to six significant digits, is:

@@ -5320,7 +5320,7 @@ for p = 1 to points.length-3 (inclusive): Scripts are disabled. Showing fallback image. - + diff --git a/src/index.template.html b/src/index.template.html index 5e0722e3..a857bdf1 100644 --- a/src/index.template.html +++ b/src/index.template.html @@ -50,7 +50,7 @@ - +