diff --git a/chapters/pointvectors/content.en-GB.md b/chapters/pointvectors/content.en-GB.md index 34407b12..8be2cf24 100644 --- a/chapters/pointvectors/content.en-GB.md +++ b/chapters/pointvectors/content.en-GB.md @@ -73,6 +73,6 @@ treated as a sequence of three (elementary) shear operations. When we combine th The following two graphics show the tangent and normal along a quadratic and cubic curve, with the direction vector coloured blue, and the normal vector coloured red (the markers are spaced out evenly as *t*-intervals, not spaced equidistant).
- - + +
diff --git a/chapters/pointvectors/cubic.js b/chapters/pointvectors/cubic.js new file mode 100644 index 00000000..d27e4370 --- /dev/null +++ b/chapters/pointvectors/cubic.js @@ -0,0 +1,67 @@ +setup() { + this.curve = Bezier.defaultCubic(this); + setMovable(this.curve.points); +} + +draw() { + clear(); + const curve = this.curve; + curve.drawSkeleton(); + const pts = curve.points; + const f = 15; + + for(let i=0; i<=10; i++) { + let t = i/10.0; + let p = curve.get(t); + let d = this.getDerivative(t, pts); + + let m = sqrt(d.x*d.x + d.y*d.y); + d = { x: d.x/m, y: d.y/m }; + let n = this.getNormal(t, d); + + setStroke(`blue`); + line(p.x, p.y, p.x + d.x*f, p.y + d.y*f); + + setStroke(`red`); + line(p.x, p.y, p.x + n.x*f, p.y + n.y*f); + + setStroke(`purple`); + line(p.x, p.y, p.x - n.x*f, p.y - n.y*f); + + setStroke(`black`); + circle(p.x, p.y, 3); + } + + curve.drawPoints(); +} + +getDerivative(t, points) { + let mt = (1 - t), a = mt*mt, b = mt*t, c = t*t, d = [ + { + x: 3 * (points[1].x - points[0].x), + y: 3 * (points[1].y - points[0].y) + }, + { + x: 3 * (points[2].x - points[1].x), + y: 3 * (points[2].y - points[1].y) + }, + { + x: 3 * (points[3].x - points[2].x), + y: 3 * (points[3].y - points[2].y) + } + ]; + + return { + x: a * d[0].x + b * d[1].x + c * d[2].x, + y: a * d[0].y + b * d[1].y + c * d[2].y + }; +} + +getNormal(t, d) { + const q = sqrt(d.x * d.x + d.y * d.y); + return { x: -d.y / q, y: d.x / q }; +} + +onMouseMove() { + redraw(); +} diff --git a/chapters/pointvectors/quadratic.js b/chapters/pointvectors/quadratic.js new file mode 100644 index 00000000..0e64461f --- /dev/null +++ b/chapters/pointvectors/quadratic.js @@ -0,0 +1,63 @@ +setup() { + this.curve = Bezier.defaultQuadratic(this); + setMovable(this.curve.points); +} + +draw() { + clear(); + const curve = this.curve; + curve.drawSkeleton(); + const pts = curve.points; + const f = 15; + + for(let i=0; i<=10; i++) { + let t = i/10.0; + let p = curve.get(t); + let d = this.getDerivative(t, pts); + + let m = sqrt(d.x*d.x + d.y*d.y); + d = { x: d.x/m, y: d.y/m }; + let n = this.getNormal(t, d); + + setStroke(`blue`); + line(p.x, p.y, p.x + d.x*f, p.y + d.y*f); + + setStroke(`red`); + line(p.x, p.y, p.x + n.x*f, p.y + n.y*f); + + setStroke(`purple`); + line(p.x, p.y, p.x - n.x*f, p.y - n.y*f); + + setStroke(`black`); + circle(p.x, p.y, 3); + } + + curve.drawPoints(); +} + +getDerivative(t, points) { + let mt = (1 - t), d = [ + { + x: 2 * (points[1].x - points[0].x), + y: 2 * (points[1].y - points[0].y) + }, + { + x: 2 * (points[2].x - points[1].x), + y: 2 * (points[2].y - points[1].y) + } + ]; + + return { + x: mt * d[0].x + t * d[1].x, + y: mt * d[0].y + t * d[1].y + }; +} + +getNormal(t, d) { + const q = sqrt(d.x * d.x + d.y * d.y); + return { x: -d.y / q, y: d.x / q }; +} + +onMouseMove() { + redraw(); +} diff --git a/images/chapters/pointvectors/05a1ee3b81a4838292814a7097b4cf50.png b/images/chapters/pointvectors/05a1ee3b81a4838292814a7097b4cf50.png new file mode 100644 index 00000000..5da69142 Binary files /dev/null and b/images/chapters/pointvectors/05a1ee3b81a4838292814a7097b4cf50.png differ diff --git a/images/chapters/pointvectors/3158c82ea512f70ec17d4a1ce2e7c7b2.png b/images/chapters/pointvectors/3158c82ea512f70ec17d4a1ce2e7c7b2.png new file mode 100644 index 00000000..d4d2f0df Binary files /dev/null and b/images/chapters/pointvectors/3158c82ea512f70ec17d4a1ce2e7c7b2.png differ diff --git a/images/chapters/reordering/140b23b10b4159b03b2a555db7ddf826.png b/images/chapters/reordering/140b23b10b4159b03b2a555db7ddf826.png deleted file mode 100644 index 36384d8a..00000000 Binary files a/images/chapters/reordering/140b23b10b4159b03b2a555db7ddf826.png and /dev/null differ diff --git a/images/chapters/reordering/4541eeb2113d81cbc0c0a56122570d48.png b/images/chapters/reordering/4541eeb2113d81cbc0c0a56122570d48.png index 9b71de14..7afa0c92 100644 Binary files a/images/chapters/reordering/4541eeb2113d81cbc0c0a56122570d48.png and b/images/chapters/reordering/4541eeb2113d81cbc0c0a56122570d48.png differ diff --git a/index.html b/index.html index 8107e51a..e186d5fd 100644 --- a/index.html +++ b/index.html @@ -2586,18 +2586,38 @@ function drawCurve(points[], t): evenly as t-intervals, not spaced equidistant).

- - + + + Scripts are disabled. Showing fallback image. + + + width="275" + height="275" + src="./chapters/pointvectors/cubic.js" + > + + + Scripts are disabled. Showing fallback image. +
diff --git a/ja-JP/index.html b/ja-JP/index.html index 3ea0641c..450aea6a 100644 --- a/ja-JP/index.html +++ b/ja-JP/index.html @@ -2180,18 +2180,38 @@ function drawCurve(points[], t): evenly as t-intervals, not spaced equidistant).

- - + + + Scripts are disabled. Showing fallback image. + + + width="275" + height="275" + src="./chapters/pointvectors/cubic.js" + > + + + Scripts are disabled. Showing fallback image. +
diff --git a/lib/custom-element/api/base-api.js b/lib/custom-element/api/base-api.js index e080a396..db0185b9 100644 --- a/lib/custom-element/api/base-api.js +++ b/lib/custom-element/api/base-api.js @@ -200,7 +200,7 @@ class BaseAPI { */ setup() { // console.log(`setup`); - this.moveable = []; + this.movable = []; } /** diff --git a/lib/custom-element/api/graphics-api.js b/lib/custom-element/api/graphics-api.js index 49caf566..83ae78c8 100644 --- a/lib/custom-element/api/graphics-api.js +++ b/lib/custom-element/api/graphics-api.js @@ -72,8 +72,8 @@ class GraphicsAPI extends BaseAPI { ? TOUCH_PRECISION_ZONE : MOUSE_PRECISION_ZONE; - for (let i = 0, e = this.moveable.length, p, d; i < e; i++) { - p = this.moveable[i]; + for (let i = 0, e = this.movable.length, p, d; i < e; i++) { + p = this.movable[i]; d = new Vector(p).dist(this.cursor); if (d <= cdist) { this.currentPoint = p; @@ -88,8 +88,8 @@ class GraphicsAPI extends BaseAPI { this.currentPoint.x = this.cursor.x; this.currentPoint.y = this.cursor.y; } else { - for (let i = 0, e = this.moveable.length, p; i < e; i++) { - p = this.moveable[i]; + for (let i = 0, e = this.movable.length, p; i < e; i++) { + p = this.movable[i]; if (new Vector(p).dist(this.cursor) <= 5) { this.setCursor(this.HAND); return; // NOTE: this is a return, not a break. @@ -105,12 +105,12 @@ class GraphicsAPI extends BaseAPI { } resetMovable(points) { - this.moveable.splice(0, this.moveable.length); + this.movable.splice(0, this.movable.length); if (points) this.setMovable(points); } setMovable(points) { - points.forEach((p) => this.moveable.push(p)); + points.forEach((p) => this.movable.push(p)); } /** diff --git a/tools/build/markdown/generate-fallback-image.js b/tools/build/markdown/generate-fallback-image.js index 23c0c25d..d1714e84 100644 --- a/tools/build/markdown/generate-fallback-image.js +++ b/tools/build/markdown/generate-fallback-image.js @@ -10,7 +10,9 @@ const __root = path.join(__dirname, `..`, `..`, `..`); /** * ...docs go here... */ -async function generateFallbackImage(src, width, height) { +async function generateFallbackImage(localeStrings, src, width, height) { + const locale = localeStrings.getCurrentLocale(); + // Get the sketch code const sourcePath = path.join(__root, src); let code; @@ -23,6 +25,9 @@ async function generateFallbackImage(src, width, height) { // Do we need to even generate a file here? const hash = createHash(`md5`).update(code).digest(`hex`); + + if (locale !== localeStrings.getDefaultLocale()) return hash; + const destPath = path.dirname(path.join(__root, `images`, src)); const filename = path.join(destPath, `${hash}.png`); if (fs.existsSync(filename)) return hash; @@ -50,7 +55,7 @@ async function generateFallbackImage(src, width, height) { fs.ensureDirSync(path.dirname(filename)); fs.writeFileSync(filename, imageData); - console.log(`Generated fallback image for ${src}`); + console.log(`Generated fallback image for ${src} (${locale})`); return hash; } diff --git a/tools/build/markdown/preprocess-graphics-element.js b/tools/build/markdown/preprocess-graphics-element.js index c560bd03..42c09faa 100644 --- a/tools/build/markdown/preprocess-graphics-element.js +++ b/tools/build/markdown/preprocess-graphics-element.js @@ -51,7 +51,12 @@ async function preprocessGraphicsElement(chapter, localeStrings, markdown) { src = src.replace(`./`, `./chapters/${chapter}/`); } - let imageHash = await generateFallbackImage(src, width, height); // ← this is super fancy functionality. + let imageHash = await generateFallbackImage( + localeStrings, + src, + width, + height + ); // ← this is super fancy functionality. let imgUrl = path.join( path.dirname(src.replace(`./`, `./images/`)), `${imageHash}.png` diff --git a/zh-CN/index.html b/zh-CN/index.html index 3c970dd6..8029c917 100644 --- a/zh-CN/index.html +++ b/zh-CN/index.html @@ -2190,18 +2190,38 @@ function drawCurve(points[], t): evenly as t-intervals, not spaced equidistant).

- - + + + Scripts are disabled. Showing fallback image. + + + width="275" + height="275" + src="./chapters/pointvectors/cubic.js" + > + + + Scripts are disabled. Showing fallback image. +