@pixel-normal-edit/mcp 2.1.0 → 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.
Files changed (132) hide show
  1. package/clear-firebase.js +37 -0
  2. package/domains/art-tree/README.md +134 -0
  3. package/domains/art-tree/REORGANIZATION_PLAN.md +168 -0
  4. package/domains/art-tree/REORGANIZATION_SUMMARY.md +260 -0
  5. package/domains/art-tree/index.js +58 -58
  6. package/domains/art-tree/lessons/3d/box-properties.js +38 -0
  7. package/domains/art-tree/lessons/3d/cone-properties.js +31 -0
  8. package/domains/art-tree/lessons/3d/cylinder-properties.js +29 -0
  9. package/domains/art-tree/lessons/3d/sphere-properties.js +25 -0
  10. package/domains/art-tree/lessons/advanced/angles.js +30 -0
  11. package/domains/art-tree/lessons/advanced/distances.js +26 -0
  12. package/domains/art-tree/lessons/advanced/shape-ratios.js +25 -0
  13. package/domains/art-tree/lessons/advanced/shape-relationships.js +28 -0
  14. package/domains/art-tree/lessons/advanced/symmetry-and-axis.js +26 -0
  15. package/domains/art-tree/{analysis_lessons.js → lessons/analysis/object-analysis.js} +5 -16
  16. package/domains/art-tree/lessons/basic/circles.js +26 -0
  17. package/domains/art-tree/lessons/basic/composition.js +34 -0
  18. package/domains/art-tree/lessons/basic/curves.js +31 -0
  19. package/domains/art-tree/lessons/basic/ellipses.js +26 -0
  20. package/domains/art-tree/lessons/basic/freehand.js +19 -0
  21. package/domains/art-tree/lessons/basic/index.js +36 -0
  22. package/domains/art-tree/lessons/basic/lines.js +38 -0
  23. package/domains/art-tree/lessons/basic/parallel-and-intersecting.js +22 -0
  24. package/domains/art-tree/lessons/basic/polygons.js +25 -0
  25. package/domains/art-tree/lessons/basic/proportions-and-angles.js +20 -0
  26. package/domains/art-tree/lessons/basic/spiral.js +21 -0
  27. package/domains/art-tree/lessons/basic/squares.js +28 -0
  28. package/domains/art-tree/lessons/basic/strokes.js +23 -0
  29. package/domains/art-tree/lessons/basic/triangles.js +30 -0
  30. package/domains/art-tree/lessons/cross-sections/bottle-sections.js +26 -0
  31. package/domains/art-tree/lessons/cross-sections/glass-sections.js +24 -0
  32. package/domains/art-tree/lessons/cross-sections/head-sections.js +17 -0
  33. package/domains/art-tree/lessons/curves/curve-properties.js +50 -0
  34. package/domains/art-tree/lessons/curves/curve-topology.js +45 -0
  35. package/domains/art-tree/lessons/curves/curve-types.js +44 -0
  36. package/domains/art-tree/lessons/ellipses/coaxial-ellipses.js +29 -0
  37. package/domains/art-tree/lessons/ellipses/ellipse-anatomy.js +26 -0
  38. package/domains/art-tree/lessons/ellipses/ellipse-orientations.js +28 -0
  39. package/domains/art-tree/lessons/ellipses/ellipse-proportions.js +27 -0
  40. package/domains/art-tree/lessons/hidden/hidden-box.js +20 -0
  41. package/domains/art-tree/lessons/hidden/hidden-cup.js +19 -0
  42. package/domains/art-tree/lessons/hidden/hidden-head.js +18 -0
  43. package/domains/art-tree/lessons/index.js +42 -0
  44. package/domains/art-tree/{layer_lessons.js → lessons/layers/layer-step.js} +5 -16
  45. package/domains/art-tree/lessons/lighting/contact-shadow.js +33 -0
  46. package/domains/art-tree/lessons/lighting/light-direction.js +30 -0
  47. package/domains/art-tree/lessons/lighting/light-zones.js +30 -0
  48. package/domains/art-tree/lessons/materials/material-glass.js +21 -0
  49. package/domains/art-tree/lessons/materials/material-shiny.js +26 -0
  50. package/domains/art-tree/lessons/materials/material-texture.js +26 -0
  51. package/domains/art-tree/lessons/perspective/1point-perspective.js +30 -0
  52. package/domains/art-tree/lessons/perspective/2point-perspective.js +30 -0
  53. package/domains/art-tree/lessons/perspective/3point-perspective.js +45 -0
  54. package/domains/art-tree/lessons/perspective/foreshortening.js +38 -0
  55. package/domains/art-tree/lessons/sky/sun-shapes.js +25 -0
  56. package/domains/art-tree/lessons/sky/sunset-colors.js +27 -0
  57. package/domains/art-tree/lessons/sky/sunset-sky.js +32 -0
  58. package/domains/art-tree/{structure_lessons.js → lessons/structure/axis-orientation.js} +3 -53
  59. package/domains/art-tree/lessons/structure/complex-structure.js +21 -0
  60. package/domains/art-tree/lessons/structure/x-yzaxes.js +28 -0
  61. package/domains/art-tree/lessons/surfaces/chair-analysis.js +17 -0
  62. package/domains/art-tree/lessons/surfaces/cup-analysis.js +18 -0
  63. package/domains/art-tree/lessons/surfaces/edge-types.js +40 -0
  64. package/domains/art-tree/lessons/surfaces/surface-types.js +42 -0
  65. package/domains/art-tree/lessons/transforms/bend.js +27 -0
  66. package/domains/art-tree/{transform_lessons_2.js → lessons/transforms/combine.js} +3 -54
  67. package/domains/art-tree/lessons/transforms/cut.js +25 -0
  68. package/domains/art-tree/lessons/transforms/hollow.js +24 -0
  69. package/domains/art-tree/lessons/transforms/rotate.js +16 -0
  70. package/domains/art-tree/lessons/transforms/squash.js +31 -0
  71. package/domains/art-tree/lessons/transforms/stretch.js +31 -0
  72. package/domains/art-tree/lessons/transforms/taper-swell.js +33 -0
  73. package/domains/art-tree/{vocab_lessons.js → lessons/vocab/vocab-house.js} +5 -16
  74. package/domains/art-tree/lib/tool-register.js +104 -0
  75. package/domains/art-tree/lib/validators.js +78 -0
  76. package/domains/art-tree/shapes/grid.js +37 -0
  77. package/domains/art-tree/shapes/polyline.js +26 -0
  78. package/domains/art-tree/{3d_tools.js → tools/3d.js} +2 -2
  79. package/domains/art-tree/{advanced_tools.js → tools/advanced.js} +2 -2
  80. package/domains/art-tree/{analysis_tools.js → tools/analysis.js} +2 -2
  81. package/domains/art-tree/{tools.js → tools/basic.js} +3 -3
  82. package/domains/art-tree/{cross_section_tools.js → tools/cross-sections.js} +2 -2
  83. package/domains/art-tree/{curve_tools.js → tools/curves.js} +2 -2
  84. package/domains/art-tree/{ellipse_tools.js → tools/ellipses.js} +2 -2
  85. package/domains/art-tree/{hidden_tools.js → tools/hidden.js} +2 -2
  86. package/domains/art-tree/tools/index.js +53 -0
  87. package/domains/art-tree/{layer_tools.js → tools/layers.js} +2 -2
  88. package/domains/art-tree/{light_tools.js → tools/lighting.js} +2 -2
  89. package/domains/art-tree/{material_tools.js → tools/materials.js} +2 -2
  90. package/domains/art-tree/{perspective_tools.js → tools/perspective.js} +2 -2
  91. package/domains/art-tree/{sky_tools.js → tools/sky.js} +2 -2
  92. package/domains/art-tree/{structure_tools.js → tools/structure.js} +2 -2
  93. package/domains/art-tree/{surface_tools.js → tools/surfaces.js} +2 -2
  94. package/domains/art-tree/{transform_tools.js → tools/transforms.js} +3 -3
  95. package/domains/art-tree/{vocab_tools.js → tools/vocab.js} +2 -2
  96. package/package.json +1 -1
  97. package/rules/prerequisites.js +30 -30
  98. package/rules/rules.js +1 -1
  99. package/rules/workflow.js +28 -20
  100. package/tools/canvas-tools.js +2 -2
  101. package/tools/drawing-tools.js +23 -12
  102. package/tools/workspace-tools.js +5 -4
  103. package/domains/art-tree/3d_lessons.js +0 -114
  104. package/domains/art-tree/advanced_lessons.js +0 -124
  105. package/domains/art-tree/cross_section_lessons.js +0 -65
  106. package/domains/art-tree/curve_lessons.js +0 -138
  107. package/domains/art-tree/ellipse_lessons.js +0 -105
  108. package/domains/art-tree/hidden_lessons.js +0 -55
  109. package/domains/art-tree/lessons.js +0 -305
  110. package/domains/art-tree/light_lessons.js +0 -92
  111. package/domains/art-tree/material_lessons.js +0 -71
  112. package/domains/art-tree/perspective_lessons.js +0 -138
  113. package/domains/art-tree/sky_lessons_1.js +0 -82
  114. package/domains/art-tree/surface_lessons.js +0 -112
  115. package/domains/art-tree/transform_lessons_1.js +0 -108
  116. /package/domains/art-tree/{3d_shapes.js → shapes/3d.js} +0 -0
  117. /package/domains/art-tree/{advanced_shapes.js → shapes/advanced.js} +0 -0
  118. /package/domains/art-tree/{analysis_shapes.js → shapes/analysis.js} +0 -0
  119. /package/domains/art-tree/{shapes.js → shapes/basic.js} +0 -0
  120. /package/domains/art-tree/{cross_section_shapes.js → shapes/cross-sections.js} +0 -0
  121. /package/domains/art-tree/{curve_shapes.js → shapes/curves.js} +0 -0
  122. /package/domains/art-tree/{ellipse_shapes.js → shapes/ellipses.js} +0 -0
  123. /package/domains/art-tree/{hidden_shapes.js → shapes/hidden.js} +0 -0
  124. /package/domains/art-tree/{layer_shapes.js → shapes/layers.js} +0 -0
  125. /package/domains/art-tree/{light_shapes.js → shapes/lighting.js} +0 -0
  126. /package/domains/art-tree/{material_shapes.js → shapes/materials.js} +0 -0
  127. /package/domains/art-tree/{perspective_shapes.js → shapes/perspective.js} +0 -0
  128. /package/domains/art-tree/{sky_shapes_1.js → shapes/sky.js} +0 -0
  129. /package/domains/art-tree/{structure_shapes.js → shapes/structure.js} +0 -0
  130. /package/domains/art-tree/{surface_shapes.js → shapes/surfaces.js} +0 -0
  131. /package/domains/art-tree/{transform_shapes.js → shapes/transforms.js} +0 -0
  132. /package/domains/art-tree/{vocab_shapes.js → shapes/vocab.js} +0 -0
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Auto-extracted from light_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: Light Direction & Intensity (Light direction and plane values)
8
+ * Shows a box with planes facing/turning away from light.
9
+ */
10
+ function lessonLightDirection(canvasSize = 32) {
11
+ const commands = [];
12
+ const cx = Math.floor(canvasSize / 2);
13
+ const cy = Math.floor(canvasSize / 2);
14
+ const w = Math.floor(canvasSize * 0.25);
15
+ const h = Math.floor(canvasSize * 0.25);
16
+
17
+ // Light from top-left
18
+ const lightAngle = -Math.PI * 0.8;
19
+
20
+ const lx = cx - Math.floor(canvasSize * 0.35);
21
+ const ly = cy - Math.floor(canvasSize * 0.35);
22
+ commands.push(...lightShapes.drawLightSource(lx, ly, Math.floor(canvasSize * 0.05)));
23
+
24
+ // Draw shaded box
25
+ commands.push(...lightShapes.drawShadedBox(cx, cy, w, h, lightAngle));
26
+
27
+ return commands;
28
+ }
29
+
30
+ module.exports = { lessonLightDirection };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Auto-extracted from light_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: 6 Zones of Light (Sphere)
8
+ * Highlight, Light, Halftone, Core shadow, Reflected light, Cast shadow.
9
+ */
10
+ function lessonLightZones(canvasSize = 32) {
11
+ const commands = [];
12
+ const cx = Math.floor(canvasSize / 2);
13
+ const cy = Math.floor(canvasSize / 2);
14
+ const r = Math.floor(canvasSize * 0.25);
15
+
16
+ // Light from top-left (approx -45 degrees or -135 degrees mathematically)
17
+ const lightAngle = -Math.PI * 0.75;
18
+
19
+ // Draw light source
20
+ const lx = cx + Math.floor(r * 2 * Math.cos(lightAngle));
21
+ const ly = cy + Math.floor(r * 2 * Math.sin(lightAngle));
22
+ commands.push(...lightShapes.drawLightSource(lx, ly, Math.floor(canvasSize * 0.05)));
23
+
24
+ // Draw shaded sphere
25
+ commands.push(...lightShapes.drawShadedSphere(cx, cy, r, lightAngle));
26
+
27
+ return commands;
28
+ }
29
+
30
+ module.exports = { lessonLightZones };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Auto-extracted from material_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: Transparent (Glass)
8
+ * Demonstrates Fresnel effect, sharp reflections, and light transmission.
9
+ */
10
+ function lessonMaterialGlass(canvasSize = 32) {
11
+ const commands = [];
12
+ const cx = Math.floor(canvasSize / 2);
13
+ const cy = Math.floor(canvasSize / 2);
14
+ const r = Math.floor(canvasSize * 0.35);
15
+
16
+ commands.push(...materialShapes.drawGlassSphere(cx, cy, r));
17
+
18
+ return commands;
19
+ }
20
+
21
+ module.exports = { lessonMaterialGlass };
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Auto-extracted from material_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: Shiny vs Matte (Metal vs Plastic/Rubber)
8
+ * Compares high contrast sharp highlights vs low contrast diffused highlights.
9
+ */
10
+ function lessonMaterialShiny(canvasSize = 32) {
11
+ const commands = [];
12
+ const cx1 = Math.floor(canvasSize * 0.3);
13
+ const cx2 = Math.floor(canvasSize * 0.7);
14
+ const cy = Math.floor(canvasSize / 2);
15
+ const r = Math.floor(canvasSize * 0.2);
16
+
17
+ // 1. Metal Sphere (Left)
18
+ commands.push(...materialShapes.drawMetalSphere(cx1, cy, r));
19
+
20
+ // 2. Matte/Plastic Sphere (Right)
21
+ commands.push(...materialShapes.drawMatteSphere(cx2, cy, r, '#e65100'));
22
+
23
+ return commands;
24
+ }
25
+
26
+ module.exports = { lessonMaterialShiny };
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Auto-extracted from material_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: Texture (Wood vs Stone)
8
+ * Compares organic lines vs rough cracks.
9
+ */
10
+ function lessonMaterialTexture(canvasSize = 32) {
11
+ const commands = [];
12
+ const cx1 = Math.floor(canvasSize * 0.3);
13
+ const cx2 = Math.floor(canvasSize * 0.7);
14
+ const cy = Math.floor(canvasSize / 2);
15
+ const r = Math.floor(canvasSize * 0.2);
16
+
17
+ // 1. Wood Sphere (Left)
18
+ commands.push(...materialShapes.drawTexturedSphere(cx1, cy, r, 'wood'));
19
+
20
+ // 2. Stone Sphere (Right)
21
+ commands.push(...materialShapes.drawTexturedSphere(cx2, cy, r, 'stone'));
22
+
23
+ return commands;
24
+ }
25
+
26
+ module.exports = { lessonMaterialTexture };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Auto-extracted from perspective_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: 1-Point Perspective
8
+ */
9
+ function lesson1PointPerspective(canvasSize = 32, color = '#2196f3') {
10
+ const commands = [];
11
+ const horizonY = Math.floor(canvasSize * 0.4);
12
+ const vpX = Math.floor(canvasSize * 0.5);
13
+ const vpY = horizonY;
14
+
15
+ // Horizon & VP
16
+ commands.push(...perspShapes.drawHorizon(canvasSize, horizonY));
17
+ commands.push(...perspShapes.drawVP(vpX, vpY));
18
+
19
+ // Box below horizon (seeing top face)
20
+ const w = Math.floor(canvasSize * 0.2);
21
+ const h = Math.floor(canvasSize * 0.15);
22
+ commands.push(...perspShapes.draw1PointBox(vpX, vpY, Math.floor(canvasSize * 0.2), horizonY + Math.floor(canvasSize * 0.2), w, h, 0.4, color));
23
+
24
+ // Box above horizon (seeing bottom face)
25
+ commands.push(...perspShapes.draw1PointBox(vpX, vpY, Math.floor(canvasSize * 0.6), horizonY - Math.floor(canvasSize * 0.3), w, h, 0.4, '#e91e63'));
26
+
27
+ return commands;
28
+ }
29
+
30
+ module.exports = { lesson1PointPerspective };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Auto-extracted from perspective_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: 2-Point Perspective
8
+ */
9
+ function lesson2PointPerspective(canvasSize = 32, color = '#4caf50') {
10
+ const commands = [];
11
+ const horizonY = Math.floor(canvasSize * 0.5);
12
+ const vp1X = Math.floor(canvasSize * 0.1);
13
+ const vp2X = Math.floor(canvasSize * 0.9);
14
+
15
+ // Horizon & VPs
16
+ commands.push(...perspShapes.drawHorizon(canvasSize, horizonY));
17
+ commands.push(...perspShapes.drawVP(vp1X, horizonY));
18
+ commands.push(...perspShapes.drawVP(vp2X, horizonY));
19
+
20
+ // 2-Point Box straddling the horizon
21
+ const startX = Math.floor(canvasSize * 0.4);
22
+ const startY = Math.floor(canvasSize * 0.3);
23
+ const h = Math.floor(canvasSize * 0.4);
24
+
25
+ commands.push(...perspShapes.draw2PointBox(vp1X, horizonY, vp2X, horizonY, startX, startY, h, 0.3, 0.4, color));
26
+
27
+ return commands;
28
+ }
29
+
30
+ module.exports = { lesson2PointPerspective };
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Auto-extracted from perspective_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: 3-Point Perspective (Bird's eye view)
8
+ */
9
+ function lesson3PointPerspective(canvasSize = 32, color = '#ff9800') {
10
+ const commands = [];
11
+ const horizonY = Math.floor(canvasSize * 0.2);
12
+ const vp1X = Math.floor(canvasSize * 0.1);
13
+ const vp2X = Math.floor(canvasSize * 0.9);
14
+ const vp3X = Math.floor(canvasSize * 0.5);
15
+ const vp3Y = Math.floor(canvasSize * 1.5); // VP3 far below (Bird's eye)
16
+
17
+ // Horizon & VPs
18
+ commands.push(...perspShapes.drawHorizon(canvasSize, horizonY));
19
+ commands.push(...perspShapes.drawVP(vp1X, horizonY));
20
+ commands.push(...perspShapes.drawVP(vp2X, horizonY));
21
+ // VP3 is usually off-canvas, but we draw a line to it to show direction
22
+
23
+ // We approximate a 3-point box by drawing converging vertical lines to VP3
24
+ const topY = Math.floor(canvasSize * 0.4);
25
+ const h = Math.floor(canvasSize * 0.4);
26
+
27
+ // Center edge converging to VP3
28
+ commands.push(shapes.drawLine(vp3X, topY, vp3X, topY+h, color)); // simplified
29
+ commands.push(shapes.drawLine(vp3X, topY+h, vp3X, vp3Y, '#e0e0e0')); // Guide to VP3
30
+
31
+ // Left and Right top edges to VP1, VP2
32
+ commands.push(shapes.drawLine(vp3X, topY, vp1X, horizonY, '#e0e0e0'));
33
+ commands.push(shapes.drawLine(vp3X, topY, vp2X, horizonY, '#e0e0e0'));
34
+
35
+ // Draw the rest of the box structure to simulate 3-point
36
+ const lX = vp3X - Math.floor(canvasSize * 0.15);
37
+ const rX = vp3X + Math.floor(canvasSize * 0.2);
38
+ // Vertical edges also converge to VP3 slightly (foreshortening)
39
+ commands.push(shapes.drawLine(lX, topY + Math.floor(canvasSize * 0.1), lX + 2, topY + h, color));
40
+ commands.push(shapes.drawLine(rX, topY + Math.floor(canvasSize * 0.15), rX - 3, topY + h - 5, color));
41
+
42
+ return commands;
43
+ }
44
+
45
+ module.exports = { lesson3PointPerspective };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Auto-extracted from perspective_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: Foreshortening (Depth foreshortening)
8
+ * Drawing a cylinder pointing directly at the viewer
9
+ */
10
+ function lessonForeshortening(canvasSize = 32, color = '#9c27b0') {
11
+ const commands = [];
12
+ const cx = Math.floor(canvasSize / 2);
13
+ const cy = Math.floor(canvasSize / 2);
14
+
15
+ // Draw overlapping circles getting larger (coming towards viewer)
16
+ const numCircles = 5;
17
+ const maxR = Math.floor(canvasSize * 0.4);
18
+ const minR = Math.floor(canvasSize * 0.15);
19
+
20
+ for(let i=0; i<numCircles; i++) {
21
+ const t = i / (numCircles - 1); // 0 to 1
22
+ // Radius grows exponentially to simulate perspective
23
+ const r = minR + (maxR - minR) * (t * t);
24
+ // Y position shifts slightly to show overlap
25
+ const y = cy - Math.floor(canvasSize * 0.2) + Math.floor(canvasSize * 0.4 * t);
26
+
27
+ // Draw the circle
28
+ commands.push(shapes.drawCircle(cx, y, Math.floor(r), color, false));
29
+ }
30
+
31
+ // Draw bounding lines converging
32
+ commands.push(shapes.drawLine(cx - minR, cy - Math.floor(canvasSize * 0.2), cx - maxR, cy + Math.floor(canvasSize * 0.2), '#bdbdbd'));
33
+ commands.push(shapes.drawLine(cx + minR, cy - Math.floor(canvasSize * 0.2), cx + maxR, cy + Math.floor(canvasSize * 0.2), '#bdbdbd'));
34
+
35
+ return commands;
36
+ }
37
+
38
+ module.exports = { lessonForeshortening };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Auto-extracted from sky_lessons_1.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson 1: Sun Shapes (Hình dạng mặt trời)
8
+ * Compares Basic, Soft, and Rays
9
+ */
10
+ function lessonSunShapes(canvasSize = 32) {
11
+ const commands = [];
12
+ const y = Math.floor(canvasSize / 2);
13
+ const r = Math.floor(canvasSize * 0.15);
14
+
15
+ // Left: Basic
16
+ commands.push(...skyShapes1.drawSunBasic(Math.floor(canvasSize * 0.2), y, r));
17
+ // Center: Soft
18
+ commands.push(...skyShapes1.drawSunSoft(Math.floor(canvasSize * 0.5), y, r));
19
+ // Right: Rays
20
+ commands.push(...skyShapes1.drawSunRays(Math.floor(canvasSize * 0.8), y, r));
21
+
22
+ return commands;
23
+ }
24
+
25
+ module.exports = { lessonSunShapes };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Auto-extracted from sky_lessons_1.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson 2: Sunset Colors (Màu sắc buổi chiều)
8
+ * Shows the progression of colors from blue to yellow
9
+ */
10
+ function lessonSunsetColors(canvasSize = 32) {
11
+ const commands = [];
12
+
13
+ // The classic sunset gradient: Blue -> Purple -> Pink -> Orange -> Yellow (top to bottom)
14
+ const sunsetPalette = [
15
+ '#3f51b5', // Blue
16
+ '#9c27b0', // Purple
17
+ '#e91e63', // Pink
18
+ '#ff9800', // Orange
19
+ '#ffeb3b' // Yellow
20
+ ];
21
+
22
+ commands.push(...skyShapes1.drawSkyGradient(0, 0, canvasSize, canvasSize, sunsetPalette));
23
+
24
+ return commands;
25
+ }
26
+
27
+ module.exports = { lessonSunsetColors };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Auto-extracted from sky_lessons_1.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson 3: Sunset Sky (Bầu trời hoàng hôn)
8
+ * Combines the gradient sky with a soft sun setting at the bottom
9
+ */
10
+ function lessonSunsetSky(canvasSize = 32) {
11
+ const commands = [];
12
+
13
+ // 1. Draw the Sky
14
+ const sunsetPalette = [
15
+ '#1a237e', // Dark Blue
16
+ '#512da8', // Deep Purple
17
+ '#c2185b', // Magenta
18
+ '#ff5722', // Deep Orange
19
+ '#ffb300' // Amber
20
+ ];
21
+ commands.push(...skyShapes1.drawSkyGradient(0, 0, canvasSize, canvasSize, sunsetPalette));
22
+
23
+ // 2. Draw the Sun (Soft glowing sun near the bottom)
24
+ const cx = Math.floor(canvasSize / 2);
25
+ const cy = Math.floor(canvasSize * 0.8);
26
+ const r = Math.floor(canvasSize * 0.15);
27
+ commands.push(...skyShapes1.drawSunSoft(cx, cy, r));
28
+
29
+ return commands;
30
+ }
31
+
32
+ module.exports = { lessonSunsetSky };
@@ -1,44 +1,7 @@
1
- const shapes = require('./shapes');
2
- const structureShapes = require('./structure_shapes');
3
- const shapes3d = require('./3d_shapes');
4
- const ellipseShapes = require('./ellipse_shapes');
5
-
6
- /**
7
- * Lesson: XYZ Axes (Vertical, Horizontal, Depth)
8
- */
9
- function lessonXYZAxes(canvasSize = 32, color = '#2196f3') {
10
- const commands = [];
11
- const cx = Math.floor(canvasSize / 2);
12
- const cy = Math.floor(canvasSize / 2);
13
- const length = Math.floor(canvasSize * 0.4);
14
-
15
- // Draw the axes
16
- commands.push(...structureShapes.drawXYZAxes(cx, cy, length));
17
-
18
- // Draw a simple box aligned with these axes to show how objects follow them
19
- const w = Math.floor(length * 0.5);
20
- const h = Math.floor(length * 0.5);
21
- const d = Math.floor(length * 0.5);
22
- // Using a lighter color for the reference box
23
- commands.push(...shapes3d.drawWireframeBox(cx + Math.floor(w/2), cy - Math.floor(h/2), w, h, d, '#e0e0e0'));
24
-
25
- return commands;
26
- }
27
-
28
1
  /**
29
- * Lesson: Complex Structure Analysis (e.g. A Bottle)
2
+ * Auto-extracted from structure_lessons.js
30
3
  */
31
- function lessonComplexStructure(canvasSize = 32, color = '#9c27b0') {
32
- const commands = [];
33
- const cx = Math.floor(canvasSize / 2);
34
- const cy = Math.floor(canvasSize / 2);
35
- const totalHeight = Math.floor(canvasSize * 0.8);
36
-
37
- // Draw bottle structure showing cross-sections and central axis
38
- commands.push(...structureShapes.drawBottleAnatomy(cx, cy, totalHeight, color));
39
-
40
- return commands;
41
- }
4
+ const shapes = require('../../shapes');
42
5
 
43
6
  /**
44
7
  * Lesson: Axis Orientation (Object pointing along different axes)
@@ -86,17 +49,4 @@ function lessonAxisOrientation(canvasSize = 32, color = '#00bcd4') {
86
49
  return commands;
87
50
  }
88
51
 
89
- function getStructureLessonCatalog() {
90
- return [
91
- { id: 'structure_xyz', name: 'XYZ Axes', description: 'Understanding 3D space directions (Vertical, Horizontal, Depth)', fn: lessonXYZAxes },
92
- { id: 'structure_bottle', name: 'Complex Structure (Bottle)', description: 'Analyzing an object using a central axis and multiple cross-sections', fn: lessonComplexStructure },
93
- { id: 'structure_orientation', name: 'Axis Orientation', description: 'Identifying which axis an object is oriented along', fn: lessonAxisOrientation },
94
- ];
95
- }
96
-
97
- module.exports = {
98
- lessonXYZAxes,
99
- lessonComplexStructure,
100
- lessonAxisOrientation,
101
- getStructureLessonCatalog
102
- };
52
+ module.exports = { lessonAxisOrientation };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Auto-extracted from structure_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: Complex Structure Analysis (e.g. A Bottle)
8
+ */
9
+ function lessonComplexStructure(canvasSize = 32, color = '#9c27b0') {
10
+ const commands = [];
11
+ const cx = Math.floor(canvasSize / 2);
12
+ const cy = Math.floor(canvasSize / 2);
13
+ const totalHeight = Math.floor(canvasSize * 0.8);
14
+
15
+ // Draw bottle structure showing cross-sections and central axis
16
+ commands.push(...structureShapes.drawBottleAnatomy(cx, cy, totalHeight, color));
17
+
18
+ return commands;
19
+ }
20
+
21
+ module.exports = { lessonComplexStructure };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Auto-extracted from structure_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: XYZ Axes (Vertical, Horizontal, Depth)
8
+ */
9
+ function lessonXYZAxes(canvasSize = 32, color = '#2196f3') {
10
+ const commands = [];
11
+ const cx = Math.floor(canvasSize / 2);
12
+ const cy = Math.floor(canvasSize / 2);
13
+ const length = Math.floor(canvasSize * 0.4);
14
+
15
+ // Draw the axes
16
+ commands.push(...structureShapes.drawXYZAxes(cx, cy, length));
17
+
18
+ // Draw a simple box aligned with these axes to show how objects follow them
19
+ const w = Math.floor(length * 0.5);
20
+ const h = Math.floor(length * 0.5);
21
+ const d = Math.floor(length * 0.5);
22
+ // Using a lighter color for the reference box
23
+ commands.push(...shapes3d.drawWireframeBox(cx + Math.floor(w/2), cy - Math.floor(h/2), w, h, d, '#e0e0e0'));
24
+
25
+ return commands;
26
+ }
27
+
28
+ module.exports = { lessonXYZAxes };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Auto-extracted from surface_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: Chair Analysis (Analyzing surfaces and edges of a chair)
8
+ */
9
+ function lessonChairAnalysis(canvasSize = 32, color = '#795548') {
10
+ const cx = Math.floor(canvasSize / 2);
11
+ const cy = Math.floor(canvasSize / 2);
12
+ const w = Math.floor(canvasSize * 0.3);
13
+
14
+ return surfaceShapes.drawChairAnalysis(cx, cy, w);
15
+ }
16
+
17
+ module.exports = { lessonChairAnalysis };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Auto-extracted from surface_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: Cup Analysis (Analyzing surfaces of a cup)
8
+ */
9
+ function lessonCupAnalysis(canvasSize = 32, color = '#607d8b') {
10
+ const cx = Math.floor(canvasSize / 2);
11
+ const cy = Math.floor(canvasSize / 2);
12
+ const r = Math.floor(canvasSize * 0.2);
13
+ const h = Math.floor(canvasSize * 0.4);
14
+
15
+ return surfaceShapes.drawCupAnalysis(cx, cy, r, h);
16
+ }
17
+
18
+ module.exports = { lessonCupAnalysis };
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Auto-extracted from surface_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: Edge Types (Hard sharp corners vs Soft rounded edges)
8
+ */
9
+ function lessonEdgeTypes(canvasSize = 32, color = '#ff5722') {
10
+ const commands = [];
11
+ const qX1 = Math.floor(canvasSize * 0.3);
12
+ const qX2 = Math.floor(canvasSize * 0.7);
13
+ const midY = Math.floor(canvasSize / 2);
14
+ const w = Math.floor(canvasSize * 0.25);
15
+
16
+ // 1. Hard Edge (Sharp corners)
17
+ commands.push(shapes.drawRectangle(qX1 - w/2, midY - w/2, w, w, '#e91e63', false));
18
+
19
+ // 2. Soft Edge / Transitional
20
+ // Draw a box with rounded corners (fillet)
21
+ const r = Math.floor(w * 0.2); // Corner radius
22
+ const rx = qX2 - w/2;
23
+ const ry = midY - w/2;
24
+
25
+ // Straight segments
26
+ commands.push(shapes.drawLine(rx + r, ry, rx + w - r, ry, '#00bcd4')); // Top
27
+ commands.push(shapes.drawLine(rx + w, ry + r, rx + w, ry + w - r, '#00bcd4')); // Right
28
+ commands.push(shapes.drawLine(rx + r, ry + w, rx + w - r, ry + w, '#00bcd4')); // Bottom
29
+ commands.push(shapes.drawLine(rx, ry + r, rx, ry + w - r, '#00bcd4')); // Left
30
+
31
+ // Rounded corners (approximated with small circles for visual simplicity)
32
+ commands.push(shapes.drawCircle(rx + r, ry + r, r, '#00bcd4', false)); // TL
33
+ commands.push(shapes.drawCircle(rx + w - r, ry + r, r, '#00bcd4', false)); // TR
34
+ commands.push(shapes.drawCircle(rx + w - r, ry + w - r, r, '#00bcd4', false)); // BR
35
+ commands.push(shapes.drawCircle(rx + r, ry + w - r, r, '#00bcd4', false)); // BL
36
+
37
+ return commands;
38
+ }
39
+
40
+ module.exports = { lessonEdgeTypes };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Auto-extracted from surface_lessons.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: Surface Types (Flat, convex, concave)
8
+ */
9
+ function lessonSurfaceTypes(canvasSize = 32, color = '#2196f3') {
10
+ const commands = [];
11
+ const midY = Math.floor(canvasSize / 2);
12
+ const qX = Math.floor(canvasSize / 4);
13
+ const r = Math.floor(canvasSize * 0.15);
14
+
15
+ // 1. Flat Plane
16
+ const w = Math.floor(canvasSize * 0.2);
17
+ commands.push(shapes.drawRectangle(qX - w/2, midY - w/2, w, w, '#4caf50', false));
18
+ // Add some grid lines to show it's flat
19
+ commands.push(shapes.drawLine(qX, midY - w/2, qX, midY + w/2, '#4caf50'));
20
+ commands.push(shapes.drawLine(qX - w/2, midY, qX + w/2, midY, '#4caf50'));
21
+
22
+ // 2. Convex Surface (e.g. Dome/Sphere)
23
+ // We use an ellipse that curves outwards (downwards)
24
+ commands.push(shapes.drawEllipse(qX * 2, midY, r, r, '#ff9800', false));
25
+ // Cross contour curving DOWN (convex towards viewer)
26
+ commands.push(shapes.drawEllipse(qX * 2, midY + Math.floor(r*0.2), r, Math.floor(r*0.3), '#ff9800', false));
27
+
28
+ // 3. Concave Surface (e.g. Bowl)
29
+ // Draw the top rim of a bowl
30
+ commands.push(shapes.drawEllipse(qX * 3, midY, r, Math.floor(r*0.3), '#9c27b0', false));
31
+ // Draw the bottom curve (the inside of the bowl)
32
+ const bowlPoints = [];
33
+ for(let i=0; i<=18; i++) {
34
+ const a = (i/18) * Math.PI; // 0 to 180 degrees (bottom half)
35
+ bowlPoints.push({ x: Math.round(qX * 3 + r * Math.cos(a)), y: Math.round(midY + r * Math.sin(a)) });
36
+ }
37
+ commands.push(shapes.drawPolyline(bowlPoints, '#9c27b0'));
38
+
39
+ return commands;
40
+ }
41
+
42
+ module.exports = { lessonSurfaceTypes };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Auto-extracted from transform_lessons_1.js
3
+ */
4
+ const shapes = require('../../shapes');
5
+
6
+ /**
7
+ * Lesson: Bend (Curved bending)
8
+ * Cylinder -> Bent Tube
9
+ */
10
+ function lessonBend(canvasSize = 32, color = '#e91e63') {
11
+ const commands = [];
12
+ const cx = Math.floor(canvasSize / 2);
13
+ const cy = Math.floor(canvasSize / 2);
14
+ const r = Math.floor(canvasSize * 0.1);
15
+ const length = Math.floor(canvasSize * 0.35);
16
+
17
+ // Original straight tube (ghost, pointing right)
18
+ commands.push(shapes.drawLine(cx, cy - r, cx + length * 2, cy - r, '#bdbdbd'));
19
+ commands.push(shapes.drawLine(cx, cy + r, cx + length * 2, cy + r, '#bdbdbd'));
20
+
21
+ // Bent tube
22
+ commands.push(...transformShapes.drawBentTube(cx, cy + length, r, length, color));
23
+
24
+ return commands;
25
+ }
26
+
27
+ module.exports = { lessonBend };