@pixel-normal-edit/mcp 2.0.10 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/clear-firebase.js +37 -0
- package/core/command-bus.js +6 -3
- package/core/server.js +98 -3
- package/domains/art-tree/README.md +134 -0
- package/domains/art-tree/REORGANIZATION_PLAN.md +168 -0
- package/domains/art-tree/REORGANIZATION_SUMMARY.md +260 -0
- package/domains/art-tree/index.js +58 -58
- package/domains/art-tree/lessons/3d/box-properties.js +38 -0
- package/domains/art-tree/lessons/3d/cone-properties.js +31 -0
- package/domains/art-tree/lessons/3d/cylinder-properties.js +29 -0
- package/domains/art-tree/lessons/3d/sphere-properties.js +25 -0
- package/domains/art-tree/lessons/advanced/angles.js +30 -0
- package/domains/art-tree/lessons/advanced/distances.js +26 -0
- package/domains/art-tree/lessons/advanced/shape-ratios.js +25 -0
- package/domains/art-tree/lessons/advanced/shape-relationships.js +28 -0
- package/domains/art-tree/lessons/advanced/symmetry-and-axis.js +26 -0
- package/domains/art-tree/{analysis_lessons.js → lessons/analysis/object-analysis.js} +5 -16
- package/domains/art-tree/lessons/basic/circles.js +26 -0
- package/domains/art-tree/lessons/basic/composition.js +34 -0
- package/domains/art-tree/lessons/basic/curves.js +31 -0
- package/domains/art-tree/lessons/basic/ellipses.js +26 -0
- package/domains/art-tree/lessons/basic/freehand.js +19 -0
- package/domains/art-tree/lessons/basic/index.js +36 -0
- package/domains/art-tree/lessons/basic/lines.js +38 -0
- package/domains/art-tree/lessons/basic/parallel-and-intersecting.js +22 -0
- package/domains/art-tree/lessons/basic/polygons.js +25 -0
- package/domains/art-tree/lessons/basic/proportions-and-angles.js +20 -0
- package/domains/art-tree/lessons/basic/spiral.js +21 -0
- package/domains/art-tree/lessons/basic/squares.js +28 -0
- package/domains/art-tree/lessons/basic/strokes.js +23 -0
- package/domains/art-tree/lessons/basic/triangles.js +30 -0
- package/domains/art-tree/lessons/cross-sections/bottle-sections.js +26 -0
- package/domains/art-tree/lessons/cross-sections/glass-sections.js +24 -0
- package/domains/art-tree/lessons/cross-sections/head-sections.js +17 -0
- package/domains/art-tree/lessons/curves/curve-properties.js +50 -0
- package/domains/art-tree/lessons/curves/curve-topology.js +45 -0
- package/domains/art-tree/lessons/curves/curve-types.js +44 -0
- package/domains/art-tree/lessons/ellipses/coaxial-ellipses.js +29 -0
- package/domains/art-tree/lessons/ellipses/ellipse-anatomy.js +26 -0
- package/domains/art-tree/lessons/ellipses/ellipse-orientations.js +28 -0
- package/domains/art-tree/lessons/ellipses/ellipse-proportions.js +27 -0
- package/domains/art-tree/lessons/hidden/hidden-box.js +20 -0
- package/domains/art-tree/lessons/hidden/hidden-cup.js +19 -0
- package/domains/art-tree/lessons/hidden/hidden-head.js +18 -0
- package/domains/art-tree/lessons/index.js +42 -0
- package/domains/art-tree/{layer_lessons.js → lessons/layers/layer-step.js} +5 -16
- package/domains/art-tree/lessons/lighting/contact-shadow.js +33 -0
- package/domains/art-tree/lessons/lighting/light-direction.js +30 -0
- package/domains/art-tree/lessons/lighting/light-zones.js +30 -0
- package/domains/art-tree/lessons/materials/material-glass.js +21 -0
- package/domains/art-tree/lessons/materials/material-shiny.js +26 -0
- package/domains/art-tree/lessons/materials/material-texture.js +26 -0
- package/domains/art-tree/lessons/perspective/1point-perspective.js +30 -0
- package/domains/art-tree/lessons/perspective/2point-perspective.js +30 -0
- package/domains/art-tree/lessons/perspective/3point-perspective.js +45 -0
- package/domains/art-tree/lessons/perspective/foreshortening.js +38 -0
- package/domains/art-tree/lessons/sky/sun-shapes.js +25 -0
- package/domains/art-tree/lessons/sky/sunset-colors.js +27 -0
- package/domains/art-tree/lessons/sky/sunset-sky.js +32 -0
- package/domains/art-tree/{structure_lessons.js → lessons/structure/axis-orientation.js} +3 -53
- package/domains/art-tree/lessons/structure/complex-structure.js +21 -0
- package/domains/art-tree/lessons/structure/x-yzaxes.js +28 -0
- package/domains/art-tree/lessons/surfaces/chair-analysis.js +17 -0
- package/domains/art-tree/lessons/surfaces/cup-analysis.js +18 -0
- package/domains/art-tree/lessons/surfaces/edge-types.js +40 -0
- package/domains/art-tree/lessons/surfaces/surface-types.js +42 -0
- package/domains/art-tree/lessons/transforms/bend.js +27 -0
- package/domains/art-tree/{transform_lessons_2.js → lessons/transforms/combine.js} +3 -54
- package/domains/art-tree/lessons/transforms/cut.js +25 -0
- package/domains/art-tree/lessons/transforms/hollow.js +24 -0
- package/domains/art-tree/lessons/transforms/rotate.js +16 -0
- package/domains/art-tree/lessons/transforms/squash.js +31 -0
- package/domains/art-tree/lessons/transforms/stretch.js +31 -0
- package/domains/art-tree/lessons/transforms/taper-swell.js +33 -0
- package/domains/art-tree/{vocab_lessons.js → lessons/vocab/vocab-house.js} +5 -16
- package/domains/art-tree/lib/tool-register.js +104 -0
- package/domains/art-tree/lib/validators.js +78 -0
- package/domains/art-tree/shapes/grid.js +37 -0
- package/domains/art-tree/shapes/polyline.js +26 -0
- package/domains/art-tree/{3d_tools.js → tools/3d.js} +2 -2
- package/domains/art-tree/{advanced_tools.js → tools/advanced.js} +2 -2
- package/domains/art-tree/{analysis_tools.js → tools/analysis.js} +2 -2
- package/domains/art-tree/{tools.js → tools/basic.js} +3 -3
- package/domains/art-tree/{cross_section_tools.js → tools/cross-sections.js} +2 -2
- package/domains/art-tree/{curve_tools.js → tools/curves.js} +2 -2
- package/domains/art-tree/{ellipse_tools.js → tools/ellipses.js} +2 -2
- package/domains/art-tree/{hidden_tools.js → tools/hidden.js} +2 -2
- package/domains/art-tree/tools/index.js +53 -0
- package/domains/art-tree/{layer_tools.js → tools/layers.js} +2 -2
- package/domains/art-tree/{light_tools.js → tools/lighting.js} +2 -2
- package/domains/art-tree/{material_tools.js → tools/materials.js} +2 -2
- package/domains/art-tree/{perspective_tools.js → tools/perspective.js} +2 -2
- package/domains/art-tree/{sky_tools.js → tools/sky.js} +2 -2
- package/domains/art-tree/{structure_tools.js → tools/structure.js} +2 -2
- package/domains/art-tree/{surface_tools.js → tools/surfaces.js} +2 -2
- package/domains/art-tree/{transform_tools.js → tools/transforms.js} +3 -3
- package/domains/art-tree/{vocab_tools.js → tools/vocab.js} +2 -2
- package/package.json +1 -1
- package/rules/README.md +358 -285
- package/rules/index.js +9 -9
- package/rules/prerequisites.js +121 -64
- package/rules/rules.js +76 -35
- package/rules/workflow.js +270 -56
- package/tools/canvas-tools.js +2 -2
- package/tools/drawing-tools.js +23 -12
- package/tools/workspace-tools.js +5 -4
- package/domains/art-tree/3d_lessons.js +0 -114
- package/domains/art-tree/advanced_lessons.js +0 -124
- package/domains/art-tree/cross_section_lessons.js +0 -65
- package/domains/art-tree/curve_lessons.js +0 -138
- package/domains/art-tree/ellipse_lessons.js +0 -105
- package/domains/art-tree/hidden_lessons.js +0 -55
- package/domains/art-tree/lessons.js +0 -305
- package/domains/art-tree/light_lessons.js +0 -92
- package/domains/art-tree/material_lessons.js +0 -71
- package/domains/art-tree/perspective_lessons.js +0 -138
- package/domains/art-tree/sky_lessons_1.js +0 -82
- package/domains/art-tree/surface_lessons.js +0 -112
- package/domains/art-tree/transform_lessons_1.js +0 -108
- /package/domains/art-tree/{3d_shapes.js → shapes/3d.js} +0 -0
- /package/domains/art-tree/{advanced_shapes.js → shapes/advanced.js} +0 -0
- /package/domains/art-tree/{analysis_shapes.js → shapes/analysis.js} +0 -0
- /package/domains/art-tree/{shapes.js → shapes/basic.js} +0 -0
- /package/domains/art-tree/{cross_section_shapes.js → shapes/cross-sections.js} +0 -0
- /package/domains/art-tree/{curve_shapes.js → shapes/curves.js} +0 -0
- /package/domains/art-tree/{ellipse_shapes.js → shapes/ellipses.js} +0 -0
- /package/domains/art-tree/{hidden_shapes.js → shapes/hidden.js} +0 -0
- /package/domains/art-tree/{layer_shapes.js → shapes/layers.js} +0 -0
- /package/domains/art-tree/{light_shapes.js → shapes/lighting.js} +0 -0
- /package/domains/art-tree/{material_shapes.js → shapes/materials.js} +0 -0
- /package/domains/art-tree/{perspective_shapes.js → shapes/perspective.js} +0 -0
- /package/domains/art-tree/{sky_shapes_1.js → shapes/sky.js} +0 -0
- /package/domains/art-tree/{structure_shapes.js → shapes/structure.js} +0 -0
- /package/domains/art-tree/{surface_shapes.js → shapes/surfaces.js} +0 -0
- /package/domains/art-tree/{transform_shapes.js → shapes/transforms.js} +0 -0
- /package/domains/art-tree/{vocab_shapes.js → shapes/vocab.js} +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 3: Circles — Learning curves and symmetry.
|
|
8
|
+
* @param {number} canvasSize - Canvas dimension
|
|
9
|
+
* @param {string} color - Primary color
|
|
10
|
+
* @returns {Array<Object>} Array of command payloads
|
|
11
|
+
*/
|
|
12
|
+
function lessonCircles(canvasSize = 32, color = '#e91e63') {
|
|
13
|
+
const mid = Math.floor(canvasSize / 2);
|
|
14
|
+
const r1 = Math.floor(canvasSize * 0.15);
|
|
15
|
+
const r2 = Math.floor(canvasSize * 0.3);
|
|
16
|
+
return [
|
|
17
|
+
// Small circle (outline)
|
|
18
|
+
shapes.drawCircle(mid, mid, r1, color, false),
|
|
19
|
+
// Large circle (filled)
|
|
20
|
+
shapes.drawCircle(mid, mid, r2, '#2196f3', true),
|
|
21
|
+
// Small filled circle offset
|
|
22
|
+
shapes.drawCircle(mid + r1, mid - r1, Math.floor(r1 / 2), '#ff9800', true),
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = { lessonCircles };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 7: Composition — Combining basic shapes to create simple objects.
|
|
8
|
+
* @param {number} canvasSize - Canvas dimension
|
|
9
|
+
* @returns {Array<Object>} Array of command payloads
|
|
10
|
+
*/
|
|
11
|
+
function lessonComposition(canvasSize = 32) {
|
|
12
|
+
const mid = Math.floor(canvasSize / 2);
|
|
13
|
+
const q1 = Math.floor(canvasSize * 0.25);
|
|
14
|
+
const q3 = Math.floor(canvasSize * 0.75);
|
|
15
|
+
const small = Math.floor(canvasSize * 0.1);
|
|
16
|
+
return [
|
|
17
|
+
// House: square body
|
|
18
|
+
shapes.drawSquare(q1, mid, q3 - q1, '#8d6e63', true),
|
|
19
|
+
// House: triangle roof
|
|
20
|
+
shapes.drawTriangle([
|
|
21
|
+
{ x: q1 - 1, y: mid },
|
|
22
|
+
{ x: mid, y: q1 },
|
|
23
|
+
{ x: q3 + 1, y: mid },
|
|
24
|
+
], '#d32f2f', true),
|
|
25
|
+
// Sun: circle
|
|
26
|
+
shapes.drawCircle(canvasSize - small - 2, small + 2, small, '#ffc107', true),
|
|
27
|
+
// Tree: rectangle trunk
|
|
28
|
+
shapes.drawRectangle(q1 + small, canvasSize - small - 2, Math.floor(small / 2), small, '#5d4037', true),
|
|
29
|
+
// Tree: circle top
|
|
30
|
+
shapes.drawCircle(q1 + Math.floor(small / 4), canvasSize - small - 4, Math.floor(small / 2), '#388e3c', true),
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = { lessonComposition };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 10: Curves — C-curves and S-curves.
|
|
8
|
+
*/
|
|
9
|
+
function lessonCurves(canvasSize = 32, color = '#9c27b0') {
|
|
10
|
+
const commands = [];
|
|
11
|
+
const mid = Math.floor(canvasSize / 2);
|
|
12
|
+
const r = Math.floor(canvasSize * 0.15);
|
|
13
|
+
// C curve
|
|
14
|
+
const cPoints = [];
|
|
15
|
+
for (let i = -Math.PI/2; i <= Math.PI/2; i += 0.2) {
|
|
16
|
+
cPoints.push({ x: Math.round(mid - r - r * Math.cos(i)), y: Math.round(mid / 2 + r * Math.sin(i)) });
|
|
17
|
+
}
|
|
18
|
+
commands.push(...shapes.drawPolyline(cPoints, color));
|
|
19
|
+
// S curve
|
|
20
|
+
const sPoints = [];
|
|
21
|
+
for (let i = -Math.PI/2; i <= Math.PI*1.5; i += 0.2) {
|
|
22
|
+
const isTop = i < Math.PI/2;
|
|
23
|
+
const cy = isTop ? (mid + Math.floor(canvasSize*0.1)) : (mid + Math.floor(canvasSize*0.1) + r*2);
|
|
24
|
+
const signX = isTop ? -1 : 1;
|
|
25
|
+
sPoints.push({ x: Math.round(mid + r + signX * r * Math.cos(i)), y: Math.round(cy + r * Math.sin(i)) });
|
|
26
|
+
}
|
|
27
|
+
commands.push(...shapes.drawPolyline(sPoints, '#e91e63'));
|
|
28
|
+
return commands;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = { lessonCurves };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 4: Ellipses — Understanding oval shapes and proportions.
|
|
8
|
+
* @param {number} canvasSize - Canvas dimension
|
|
9
|
+
* @param {string} color - Primary color
|
|
10
|
+
* @returns {Array<Object>} Array of command payloads
|
|
11
|
+
*/
|
|
12
|
+
function lessonEllipses(canvasSize = 32, color = '#9c27b0') {
|
|
13
|
+
const mid = Math.floor(canvasSize / 2);
|
|
14
|
+
const rx = Math.floor(canvasSize * 0.3);
|
|
15
|
+
const ry = Math.floor(canvasSize * 0.15);
|
|
16
|
+
return [
|
|
17
|
+
// Horizontal ellipse (outline)
|
|
18
|
+
shapes.drawEllipse(mid, mid, rx, ry, color, false),
|
|
19
|
+
// Vertical ellipse (filled)
|
|
20
|
+
shapes.drawEllipse(mid, mid, ry, rx, '#4caf50', true),
|
|
21
|
+
// Small circle-like ellipse
|
|
22
|
+
shapes.drawEllipse(mid + rx, mid - ry, Math.floor(rx / 3), Math.floor(ry / 2), '#ff5722', true),
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = { lessonEllipses };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 8: Freehand — Practice freehand drawing with simulated hand tremor.
|
|
8
|
+
*/
|
|
9
|
+
function lessonFreehand(canvasSize = 32, color = '#795548') {
|
|
10
|
+
const margin = Math.floor(canvasSize * 0.1);
|
|
11
|
+
const points = [];
|
|
12
|
+
let y = Math.floor(canvasSize / 2);
|
|
13
|
+
for (let x = margin; x < canvasSize - margin; x += 2) {
|
|
14
|
+
points.push({ x, y: y + Math.floor(Math.random() * 3) - 1 });
|
|
15
|
+
}
|
|
16
|
+
return shapes.drawPolyline(points, color);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = { lessonFreehand };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* lessons/basic/index.js — Art Tree: Basic Lessons Index
|
|
4
|
+
*
|
|
5
|
+
* Exports all basic shape lesson functions and catalog.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const lines = require('./lines');
|
|
9
|
+
const squares = require('./squares');
|
|
10
|
+
const circles = require('./circles');
|
|
11
|
+
const ellipses = require('./ellipses');
|
|
12
|
+
const triangles = require('./triangles');
|
|
13
|
+
const polygons = require('./polygons');
|
|
14
|
+
const composition = require('./composition');
|
|
15
|
+
const freehand = require('./freehand');
|
|
16
|
+
const proportions = require('./proportions');
|
|
17
|
+
const curves = require('./curves');
|
|
18
|
+
const spiral = require('./spiral');
|
|
19
|
+
const strokes = require('./strokes');
|
|
20
|
+
const parallelIntersecting = require('./parallel-intersecting');
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
...lines,
|
|
24
|
+
...squares,
|
|
25
|
+
...circles,
|
|
26
|
+
...ellipses,
|
|
27
|
+
...triangles,
|
|
28
|
+
...polygons,
|
|
29
|
+
...composition,
|
|
30
|
+
...freehand,
|
|
31
|
+
...proportions,
|
|
32
|
+
...curves,
|
|
33
|
+
...spiral,
|
|
34
|
+
...strokes,
|
|
35
|
+
...parallelIntersecting,
|
|
36
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* lessons.js — Art Tree: Basic Shapes Lessons
|
|
8
|
+
*
|
|
9
|
+
* Layer: Lesson API (built on top of Shape API)
|
|
10
|
+
*
|
|
11
|
+
* Provides structured lessons that guide learners through
|
|
12
|
+
* drawing basic geometric shapes step by step.
|
|
13
|
+
* Each lesson returns a sequence of command payloads.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Lesson 1: Lines — Introduction to drawing straight lines.
|
|
18
|
+
* Teaches horizontal, vertical, and diagonal lines.
|
|
19
|
+
* @param {number} canvasSize - Canvas dimension (assumes square)
|
|
20
|
+
* @param {string} color - Primary color for the lesson
|
|
21
|
+
* @returns {Array<Object>} Array of command payloads
|
|
22
|
+
*/
|
|
23
|
+
function lessonLines(canvasSize = 32, color = '#ff0000') {
|
|
24
|
+
const mid = Math.floor(canvasSize / 2);
|
|
25
|
+
const margin = Math.floor(canvasSize * 0.15);
|
|
26
|
+
return [
|
|
27
|
+
// Horizontal line
|
|
28
|
+
shapes.drawLine(margin, mid, canvasSize - margin, mid, color),
|
|
29
|
+
// Vertical line
|
|
30
|
+
shapes.drawLine(mid, margin, mid, canvasSize - margin, '#0000ff'),
|
|
31
|
+
// Diagonal (top-left to bottom-right)
|
|
32
|
+
shapes.drawLine(margin, margin, canvasSize - margin, canvasSize - margin, '#00aa00'),
|
|
33
|
+
// Diagonal (top-right to bottom-left)
|
|
34
|
+
shapes.drawLine(canvasSize - margin, margin, margin, canvasSize - margin, '#ff8800'),
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = { lessonLines };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 13: Parallel & Intersecting Lines — Drawing parallel and intersecting lines.
|
|
8
|
+
*/
|
|
9
|
+
function lessonParallelAndIntersecting(canvasSize = 32, color = '#00bcd4') {
|
|
10
|
+
const margin = Math.floor(canvasSize * 0.1);
|
|
11
|
+
const mid = Math.floor(canvasSize / 2);
|
|
12
|
+
const offset = 4;
|
|
13
|
+
return [
|
|
14
|
+
shapes.drawLine(margin, margin, canvasSize - margin, margin, color),
|
|
15
|
+
shapes.drawLine(margin, margin + offset, canvasSize - margin, margin + offset, color),
|
|
16
|
+
shapes.drawLine(margin, margin + offset * 2, canvasSize - margin, margin + offset * 2, color),
|
|
17
|
+
shapes.drawLine(mid - offset*2, mid, mid + offset*2, canvasSize - margin, '#ff5722'),
|
|
18
|
+
shapes.drawLine(mid + offset*2, mid, mid - offset*2, canvasSize - margin, '#ff5722')
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = { lessonParallelAndIntersecting };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 6: Polygons — Multi-sided shapes.
|
|
8
|
+
* @param {number} canvasSize - Canvas dimension
|
|
9
|
+
* @param {string} color - Primary color
|
|
10
|
+
* @returns {Array<Object>} Array of command payloads
|
|
11
|
+
*/
|
|
12
|
+
function lessonPolygons(canvasSize = 32, color = '#607d8b') {
|
|
13
|
+
const mid = Math.floor(canvasSize / 2);
|
|
14
|
+
const r = Math.floor(canvasSize * 0.35);
|
|
15
|
+
return [
|
|
16
|
+
// Pentagon
|
|
17
|
+
shapes.drawRegularPolygon(mid, mid, 5, r, '#4caf50', false),
|
|
18
|
+
// Hexagon (filled)
|
|
19
|
+
shapes.drawRegularPolygon(mid, mid, 6, Math.floor(r * 0.7), '#ff9800', true),
|
|
20
|
+
// Octagon
|
|
21
|
+
shapes.drawRegularPolygon(mid, mid, 8, Math.floor(r * 0.5), '#9c27b0', false),
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = { lessonPolygons };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 9: Proportions and Angles — Practice maintaining proportions and angles.
|
|
8
|
+
*/
|
|
9
|
+
function lessonProportionsAndAngles(canvasSize = 32, color = '#3f51b5') {
|
|
10
|
+
const mid = Math.floor(canvasSize / 2);
|
|
11
|
+
const size1 = Math.floor(canvasSize * 0.4);
|
|
12
|
+
const size2 = Math.floor(size1 / 2);
|
|
13
|
+
return [
|
|
14
|
+
shapes.drawSquare(mid - Math.floor(size1/2), mid - Math.floor(size1/2), size1, color, false),
|
|
15
|
+
shapes.drawSquare(mid - Math.floor(size2/2), mid - Math.floor(size2/2), size2, '#e91e63', false),
|
|
16
|
+
shapes.drawLine(mid, mid, mid + size1, mid - size1, '#009688')
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = { lessonProportionsAndAngles };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 11: Spiral — Drawing spiral curves.
|
|
8
|
+
*/
|
|
9
|
+
function lessonSpiral(canvasSize = 32, color = '#ff9800') {
|
|
10
|
+
const mid = Math.floor(canvasSize / 2);
|
|
11
|
+
const points = [];
|
|
12
|
+
const maxRadius = Math.floor(canvasSize * 0.4);
|
|
13
|
+
const loops = 3;
|
|
14
|
+
for (let angle = 0; angle < Math.PI * 2 * loops; angle += 0.3) {
|
|
15
|
+
const r = (angle / (Math.PI * 2 * loops)) * maxRadius;
|
|
16
|
+
points.push({ x: Math.round(mid + r * Math.cos(angle)), y: Math.round(mid + r * Math.sin(angle)) });
|
|
17
|
+
}
|
|
18
|
+
return shapes.drawPolyline(points, color);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = { lessonSpiral };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 2: Squares & Rectangles — Understanding right angles and proportions.
|
|
8
|
+
* @param {number} canvasSize - Canvas dimension
|
|
9
|
+
* @param {string} color - Primary color
|
|
10
|
+
* @returns {Array<Object>} Array of command payloads
|
|
11
|
+
*/
|
|
12
|
+
function lessonSquares(canvasSize = 32, color = '#1565c0') {
|
|
13
|
+
const margin = Math.floor(canvasSize * 0.1);
|
|
14
|
+
const small = Math.floor(canvasSize * 0.2);
|
|
15
|
+
const large = Math.floor(canvasSize * 0.35);
|
|
16
|
+
return [
|
|
17
|
+
// Small square (outline)
|
|
18
|
+
shapes.drawSquare(margin, margin, small, color, false),
|
|
19
|
+
// Large square (filled)
|
|
20
|
+
shapes.drawSquare(canvasSize - margin - large, margin, large, '#ff7043', true),
|
|
21
|
+
// Rectangle (horizontal)
|
|
22
|
+
shapes.drawRectangle(margin, canvasSize - margin - small, large + small, small, '#4caf50', false),
|
|
23
|
+
// Rectangle (vertical, filled)
|
|
24
|
+
shapes.drawRectangle(canvasSize - margin - small, canvasSize - margin - large, small, large, '#9c27b0', true),
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = { lessonSquares };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 12: Strokes — Long strokes, short strokes, thick and thin lines.
|
|
8
|
+
*/
|
|
9
|
+
function lessonStrokes(canvasSize = 32, color = '#2196f3') {
|
|
10
|
+
const margin = Math.floor(canvasSize * 0.1);
|
|
11
|
+
const y1 = Math.floor(canvasSize * 0.3);
|
|
12
|
+
const y2 = Math.floor(canvasSize * 0.5);
|
|
13
|
+
const y3 = Math.floor(canvasSize * 0.7);
|
|
14
|
+
return [
|
|
15
|
+
shapes.drawLine(margin, y1, canvasSize - margin, y1, color),
|
|
16
|
+
shapes.drawLine(margin, y2, Math.floor(canvasSize / 2), y2, '#4caf50'),
|
|
17
|
+
shapes.drawLine(margin, y3, canvasSize - margin, y3, '#f44336'),
|
|
18
|
+
shapes.drawLine(margin, y3 + 1, canvasSize - margin, y3 + 1, '#f44336'),
|
|
19
|
+
shapes.drawLine(margin, y3 + 2, canvasSize - margin, y3 + 2, '#f44336'),
|
|
20
|
+
];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = { lessonStrokes };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 5: Triangles — Three-point shapes and stability.
|
|
8
|
+
* @param {number} canvasSize - Canvas dimension
|
|
9
|
+
* @param {string} color - Primary color
|
|
10
|
+
* @returns {Array<Object>} Array of command payloads
|
|
11
|
+
*/
|
|
12
|
+
function lessonTriangles(canvasSize = 32, color = '#ff5722') {
|
|
13
|
+
const mid = Math.floor(canvasSize / 2);
|
|
14
|
+
const size = Math.floor(canvasSize * 0.4);
|
|
15
|
+
const margin = Math.floor(canvasSize * 0.1);
|
|
16
|
+
return [
|
|
17
|
+
// Equilateral triangle (outline)
|
|
18
|
+
shapes.drawEquilateralTriangle(mid, mid, size, color, false),
|
|
19
|
+
// Right triangle (filled)
|
|
20
|
+
shapes.drawTriangle([
|
|
21
|
+
{ x: margin, y: canvasSize - margin },
|
|
22
|
+
{ x: margin, y: margin },
|
|
23
|
+
{ x: Math.floor(canvasSize * 0.35), y: canvasSize - margin },
|
|
24
|
+
], '#3f51b5', true),
|
|
25
|
+
// Inverted triangle
|
|
26
|
+
shapes.drawEquilateralTriangle(mid, mid, Math.floor(size * 0.6), '#009688', true),
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = { lessonTriangles };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from cross_section_lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson: Bottle Sections (Base, Body, Shoulder, Neck, Mouth)
|
|
8
|
+
*/
|
|
9
|
+
function lessonBottleSections(canvasSize = 32, color = '#2196f3') {
|
|
10
|
+
const cx = Math.floor(canvasSize / 2);
|
|
11
|
+
const totalH = Math.floor(canvasSize * 0.8);
|
|
12
|
+
const topY = Math.floor(canvasSize * 0.1);
|
|
13
|
+
const bottomY = topY + totalH;
|
|
14
|
+
|
|
15
|
+
const sections = [
|
|
16
|
+
{ y: topY, r: Math.floor(canvasSize * 0.08) }, // Mouth (slightly open)
|
|
17
|
+
{ y: topY + Math.floor(totalH * 0.1), r: Math.floor(canvasSize * 0.06) }, // Neck (narrow)
|
|
18
|
+
{ y: topY + Math.floor(totalH * 0.3), r: Math.floor(canvasSize * 0.2) }, // Shoulder (shrinking to body)
|
|
19
|
+
{ y: topY + Math.floor(totalH * 0.6), r: Math.floor(canvasSize * 0.25) }, // Body (wide)
|
|
20
|
+
{ y: bottomY, r: Math.floor(canvasSize * 0.25) } // Base (wide)
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
return csShapes.drawLoftedForm(cx, topY, bottomY, sections, color, true);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = { lessonBottleSections };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from cross_section_lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson: Glass Sections (Base, Mid, Mouth)
|
|
8
|
+
*/
|
|
9
|
+
function lessonGlassSections(canvasSize = 32, color = '#9c27b0') {
|
|
10
|
+
const cx = Math.floor(canvasSize / 2);
|
|
11
|
+
const totalH = Math.floor(canvasSize * 0.6);
|
|
12
|
+
const topY = Math.floor(canvasSize * 0.2);
|
|
13
|
+
const bottomY = topY + totalH;
|
|
14
|
+
|
|
15
|
+
const sections = [
|
|
16
|
+
{ y: topY, r: Math.floor(canvasSize * 0.3) }, // Mouth (wide)
|
|
17
|
+
{ y: topY + Math.floor(totalH * 0.5), r: Math.floor(canvasSize * 0.2) }, // Mid body (widening)
|
|
18
|
+
{ y: bottomY, r: Math.floor(canvasSize * 0.15) } // Base (small)
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
return csShapes.drawLoftedForm(cx, topY, bottomY, sections, color, true);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = { lessonGlassSections };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from cross_section_lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson: Head Sections (Cranium, Face, Jaw)
|
|
8
|
+
*/
|
|
9
|
+
function lessonHeadSections(canvasSize = 32, color = '#ff9800') {
|
|
10
|
+
const cx = Math.floor(canvasSize / 2);
|
|
11
|
+
const cy = Math.floor(canvasSize / 2);
|
|
12
|
+
const height = Math.floor(canvasSize * 0.8);
|
|
13
|
+
|
|
14
|
+
return csShapes.drawHeadStructure(cx, cy, height, color);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = { lessonHeadSections };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from curve_lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 3: Curve Properties (Start, Direction, Curvature, Inflection, Transition)
|
|
8
|
+
*/
|
|
9
|
+
function lessonCurveProperties(canvasSize = 32, color = '#607d8b') {
|
|
10
|
+
const margin = Math.floor(canvasSize * 0.1);
|
|
11
|
+
const commands = [];
|
|
12
|
+
|
|
13
|
+
// 1. Start point and Direction (Top Left Curve)
|
|
14
|
+
const p0 = { x: margin, y: margin * 2 };
|
|
15
|
+
const p1 = { x: margin + canvasSize*0.3, y: margin };
|
|
16
|
+
const p2 = { x: margin + canvasSize*0.3, y: margin + canvasSize*0.3 };
|
|
17
|
+
commands.push(...curveShapes.drawQuadraticCurve(p0, p1, p2, color));
|
|
18
|
+
commands.push(curveShapes.drawStartMarker(p0.x, p0.y, '#00ff00')); // Green dot at start
|
|
19
|
+
commands.push(...curveShapes.drawDirectionArrow(p0, p1, p2, null, '#ff0000')); // Red arrow
|
|
20
|
+
|
|
21
|
+
// 2. Curvature comparison (Bottom Left)
|
|
22
|
+
// Strong vs Weak curve with same endpoints
|
|
23
|
+
const bp0 = { x: margin, y: canvasSize - margin };
|
|
24
|
+
const bp2 = { x: margin + canvasSize*0.4, y: canvasSize - margin };
|
|
25
|
+
// Weak curve
|
|
26
|
+
commands.push(...curveShapes.drawQuadraticCurve(bp0, { x: margin + canvasSize*0.2, y: canvasSize - margin - canvasSize*0.1 }, bp2, '#8bc34a'));
|
|
27
|
+
// Strong curve
|
|
28
|
+
commands.push(...curveShapes.drawQuadraticCurve(bp0, { x: margin + canvasSize*0.2, y: canvasSize - margin - canvasSize*0.4 }, bp2, '#388e3c'));
|
|
29
|
+
|
|
30
|
+
// 3. Inflection point (Top Right S Curve)
|
|
31
|
+
const sP0 = { x: canvasSize - margin - canvasSize*0.3, y: margin };
|
|
32
|
+
const sP1 = { x: canvasSize - margin, y: margin };
|
|
33
|
+
const sP2 = { x: canvasSize - margin - canvasSize*0.4, y: margin + canvasSize*0.3 };
|
|
34
|
+
const sP3 = { x: canvasSize - margin, y: margin + canvasSize*0.3 };
|
|
35
|
+
commands.push(...curveShapes.drawCubicCurve(sP0, sP1, sP2, sP3, '#03a9f4'));
|
|
36
|
+
// Inflection point roughly at t=0.5
|
|
37
|
+
const inflection = curveShapes.cubicBezier(sP0, sP1, sP2, sP3, 0.5);
|
|
38
|
+
commands.push(curveShapes.drawInflectionMarker(inflection.x, inflection.y, '#ff9800'));
|
|
39
|
+
|
|
40
|
+
// 4. Transition (Bottom Right - line transitioning to curve)
|
|
41
|
+
const startLine = { x: canvasSize - margin - canvasSize*0.3, y: canvasSize - margin - canvasSize*0.2 };
|
|
42
|
+
const transPt = { x: canvasSize - margin - canvasSize*0.1, y: canvasSize - margin - canvasSize*0.2 };
|
|
43
|
+
commands.push(shapes.drawLine(startLine.x, startLine.y, transPt.x, transPt.y, '#9e9e9e'));
|
|
44
|
+
// Curve starting tangentially
|
|
45
|
+
commands.push(...curveShapes.drawQuadraticCurve(transPt, { x: canvasSize - margin, y: canvasSize - margin - canvasSize*0.2 }, { x: canvasSize - margin, y: canvasSize - margin }, '#795548'));
|
|
46
|
+
|
|
47
|
+
return commands;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module.exports = { lessonCurveProperties };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from curve_lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 2: Curve Topology (Closed, Open, Symmetrical, Asymmetrical)
|
|
8
|
+
*/
|
|
9
|
+
function lessonCurveTopology(canvasSize = 32, color = '#9c27b0') {
|
|
10
|
+
const mid = Math.floor(canvasSize / 2);
|
|
11
|
+
const q = Math.floor(canvasSize / 4);
|
|
12
|
+
const commands = [];
|
|
13
|
+
|
|
14
|
+
// Closed Curve (Circle-like using Bezier for demonstration)
|
|
15
|
+
// Since we already have drawCircle, we just draw a circle to represent a closed curve
|
|
16
|
+
commands.push(shapes.drawCircle(q, q, Math.floor(q*0.8), color, false));
|
|
17
|
+
|
|
18
|
+
// Open Curve (Quadratic)
|
|
19
|
+
commands.push(...curveShapes.drawQuadraticCurve(
|
|
20
|
+
{ x: canvasSize - q*1.5, y: q },
|
|
21
|
+
{ x: canvasSize - q*0.5, y: q - q/2 },
|
|
22
|
+
{ x: canvasSize - q*0.5, y: q + q/2 },
|
|
23
|
+
'#3f51b5'
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
// Symmetrical Curve (Parabola-like)
|
|
27
|
+
commands.push(...curveShapes.drawQuadraticCurve(
|
|
28
|
+
{ x: q*0.5, y: canvasSize - q*0.5 },
|
|
29
|
+
{ x: q, y: canvasSize - q*1.5 },
|
|
30
|
+
{ x: q*1.5, y: canvasSize - q*0.5 },
|
|
31
|
+
'#00bcd4'
|
|
32
|
+
));
|
|
33
|
+
|
|
34
|
+
// Asymmetrical Curve
|
|
35
|
+
commands.push(...curveShapes.drawQuadraticCurve(
|
|
36
|
+
{ x: canvasSize - q*1.5, y: canvasSize - q*0.5 },
|
|
37
|
+
{ x: canvasSize - q*0.2, y: canvasSize - q*1.8 }, // Pull point is skewed
|
|
38
|
+
{ x: canvasSize - q*0.5, y: canvasSize - q*0.5 },
|
|
39
|
+
'#ff5722'
|
|
40
|
+
));
|
|
41
|
+
|
|
42
|
+
return commands;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = { lessonCurveTopology };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from curve_lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson 1: Curve Types (C, S, Convex, Concave)
|
|
8
|
+
*/
|
|
9
|
+
function lessonCurveTypes(canvasSize = 32, color = '#2196f3') {
|
|
10
|
+
const margin = Math.floor(canvasSize * 0.1);
|
|
11
|
+
const commands = [];
|
|
12
|
+
|
|
13
|
+
const w = Math.floor(canvasSize / 2) - margin * 2;
|
|
14
|
+
const h = Math.floor(canvasSize / 2) - margin * 2;
|
|
15
|
+
|
|
16
|
+
// C Curve (Top Left)
|
|
17
|
+
const cP0 = { x: margin + w, y: margin };
|
|
18
|
+
const cP1 = { x: margin - w, y: margin + Math.floor(h/2) }; // Pulls curve left
|
|
19
|
+
const cP2 = { x: margin + w, y: margin + h };
|
|
20
|
+
commands.push(...curveShapes.drawQuadraticCurve(cP0, cP1, cP2, color));
|
|
21
|
+
|
|
22
|
+
// S Curve (Top Right)
|
|
23
|
+
const sP0 = { x: canvasSize - margin, y: margin };
|
|
24
|
+
const sP1 = { x: canvasSize - margin - w*2, y: margin };
|
|
25
|
+
const sP2 = { x: canvasSize - margin + w, y: margin + h };
|
|
26
|
+
const sP3 = { x: canvasSize - margin - w, y: margin + h };
|
|
27
|
+
commands.push(...curveShapes.drawCubicCurve(sP0, sP1, sP2, sP3, '#e91e63'));
|
|
28
|
+
|
|
29
|
+
// Convex (Bottom Left, viewed from bottom)
|
|
30
|
+
const cvxP0 = { x: margin, y: canvasSize - margin };
|
|
31
|
+
const cvxP1 = { x: margin + Math.floor(w/2), y: canvasSize - margin - h };
|
|
32
|
+
const cvxP2 = { x: margin + w, y: canvasSize - margin };
|
|
33
|
+
commands.push(...curveShapes.drawQuadraticCurve(cvxP0, cvxP1, cvxP2, '#4caf50'));
|
|
34
|
+
|
|
35
|
+
// Concave (Bottom Right, viewed from bottom)
|
|
36
|
+
const cnvP0 = { x: canvasSize - margin - w, y: canvasSize - margin - Math.floor(h/2) };
|
|
37
|
+
const cnvP1 = { x: canvasSize - margin - Math.floor(w/2), y: canvasSize - margin + h };
|
|
38
|
+
const cnvP2 = { x: canvasSize - margin, y: canvasSize - margin - Math.floor(h/2) };
|
|
39
|
+
commands.push(...curveShapes.drawQuadraticCurve(cnvP0, cnvP1, cnvP2, '#ff9800'));
|
|
40
|
+
|
|
41
|
+
return commands;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = { lessonCurveTypes };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from ellipse_lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson: Coaxial Ellipses (Multiple ellipses on the same axis)
|
|
8
|
+
*/
|
|
9
|
+
function lessonCoaxialEllipses(canvasSize = 32, color = '#795548') {
|
|
10
|
+
const commands = [];
|
|
11
|
+
const cx = Math.floor(canvasSize / 2);
|
|
12
|
+
const rx = Math.floor(canvasSize * 0.3);
|
|
13
|
+
|
|
14
|
+
// Central axis line
|
|
15
|
+
commands.push(shapes.drawLine(cx, Math.floor(canvasSize * 0.1), cx, canvasSize - Math.floor(canvasSize * 0.1), '#bdbdbd'));
|
|
16
|
+
|
|
17
|
+
// Top ellipse (narrower, viewed from steeper angle)
|
|
18
|
+
commands.push(shapes.drawEllipse(cx, Math.floor(canvasSize * 0.2), rx, Math.floor(rx * 0.2), color, false));
|
|
19
|
+
|
|
20
|
+
// Middle ellipse
|
|
21
|
+
commands.push(shapes.drawEllipse(cx, Math.floor(canvasSize * 0.5), rx, Math.floor(rx * 0.3), color, false));
|
|
22
|
+
|
|
23
|
+
// Bottom ellipse (wider, viewed from less steep angle)
|
|
24
|
+
commands.push(shapes.drawEllipse(cx, canvasSize - Math.floor(canvasSize * 0.2), rx, Math.floor(rx * 0.4), color, false));
|
|
25
|
+
|
|
26
|
+
return commands;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = { lessonCoaxialEllipses };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-extracted from ellipse_lessons.js
|
|
3
|
+
*/
|
|
4
|
+
const shapes = require('../../shapes');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lesson: Ellipse Anatomy (Symmetry, Major/Minor axes, Center)
|
|
8
|
+
*/
|
|
9
|
+
function lessonEllipseAnatomy(canvasSize = 32, color = '#00bcd4') {
|
|
10
|
+
const commands = [];
|
|
11
|
+
const cx = Math.floor(canvasSize / 2);
|
|
12
|
+
const cy = Math.floor(canvasSize / 2);
|
|
13
|
+
const rx = Math.floor(canvasSize * 0.35);
|
|
14
|
+
const ry = Math.floor(canvasSize * 0.2);
|
|
15
|
+
const angle = Math.PI / 6; // 30 degrees tilt to show axes clearly
|
|
16
|
+
|
|
17
|
+
// Draw ellipse
|
|
18
|
+
commands.push(...ellipseShapes.drawRotatedEllipse(cx, cy, rx, ry, angle, color));
|
|
19
|
+
|
|
20
|
+
// Draw anatomy (axes and center)
|
|
21
|
+
commands.push(...ellipseShapes.drawEllipseAxes(cx, cy, rx, ry, angle));
|
|
22
|
+
|
|
23
|
+
return commands;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = { lessonEllipseAnatomy };
|