@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.
Files changed (136) hide show
  1. package/clear-firebase.js +37 -0
  2. package/core/command-bus.js +6 -3
  3. package/core/server.js +98 -3
  4. package/domains/art-tree/README.md +134 -0
  5. package/domains/art-tree/REORGANIZATION_PLAN.md +168 -0
  6. package/domains/art-tree/REORGANIZATION_SUMMARY.md +260 -0
  7. package/domains/art-tree/index.js +58 -58
  8. package/domains/art-tree/lessons/3d/box-properties.js +38 -0
  9. package/domains/art-tree/lessons/3d/cone-properties.js +31 -0
  10. package/domains/art-tree/lessons/3d/cylinder-properties.js +29 -0
  11. package/domains/art-tree/lessons/3d/sphere-properties.js +25 -0
  12. package/domains/art-tree/lessons/advanced/angles.js +30 -0
  13. package/domains/art-tree/lessons/advanced/distances.js +26 -0
  14. package/domains/art-tree/lessons/advanced/shape-ratios.js +25 -0
  15. package/domains/art-tree/lessons/advanced/shape-relationships.js +28 -0
  16. package/domains/art-tree/lessons/advanced/symmetry-and-axis.js +26 -0
  17. package/domains/art-tree/{analysis_lessons.js → lessons/analysis/object-analysis.js} +5 -16
  18. package/domains/art-tree/lessons/basic/circles.js +26 -0
  19. package/domains/art-tree/lessons/basic/composition.js +34 -0
  20. package/domains/art-tree/lessons/basic/curves.js +31 -0
  21. package/domains/art-tree/lessons/basic/ellipses.js +26 -0
  22. package/domains/art-tree/lessons/basic/freehand.js +19 -0
  23. package/domains/art-tree/lessons/basic/index.js +36 -0
  24. package/domains/art-tree/lessons/basic/lines.js +38 -0
  25. package/domains/art-tree/lessons/basic/parallel-and-intersecting.js +22 -0
  26. package/domains/art-tree/lessons/basic/polygons.js +25 -0
  27. package/domains/art-tree/lessons/basic/proportions-and-angles.js +20 -0
  28. package/domains/art-tree/lessons/basic/spiral.js +21 -0
  29. package/domains/art-tree/lessons/basic/squares.js +28 -0
  30. package/domains/art-tree/lessons/basic/strokes.js +23 -0
  31. package/domains/art-tree/lessons/basic/triangles.js +30 -0
  32. package/domains/art-tree/lessons/cross-sections/bottle-sections.js +26 -0
  33. package/domains/art-tree/lessons/cross-sections/glass-sections.js +24 -0
  34. package/domains/art-tree/lessons/cross-sections/head-sections.js +17 -0
  35. package/domains/art-tree/lessons/curves/curve-properties.js +50 -0
  36. package/domains/art-tree/lessons/curves/curve-topology.js +45 -0
  37. package/domains/art-tree/lessons/curves/curve-types.js +44 -0
  38. package/domains/art-tree/lessons/ellipses/coaxial-ellipses.js +29 -0
  39. package/domains/art-tree/lessons/ellipses/ellipse-anatomy.js +26 -0
  40. package/domains/art-tree/lessons/ellipses/ellipse-orientations.js +28 -0
  41. package/domains/art-tree/lessons/ellipses/ellipse-proportions.js +27 -0
  42. package/domains/art-tree/lessons/hidden/hidden-box.js +20 -0
  43. package/domains/art-tree/lessons/hidden/hidden-cup.js +19 -0
  44. package/domains/art-tree/lessons/hidden/hidden-head.js +18 -0
  45. package/domains/art-tree/lessons/index.js +42 -0
  46. package/domains/art-tree/{layer_lessons.js → lessons/layers/layer-step.js} +5 -16
  47. package/domains/art-tree/lessons/lighting/contact-shadow.js +33 -0
  48. package/domains/art-tree/lessons/lighting/light-direction.js +30 -0
  49. package/domains/art-tree/lessons/lighting/light-zones.js +30 -0
  50. package/domains/art-tree/lessons/materials/material-glass.js +21 -0
  51. package/domains/art-tree/lessons/materials/material-shiny.js +26 -0
  52. package/domains/art-tree/lessons/materials/material-texture.js +26 -0
  53. package/domains/art-tree/lessons/perspective/1point-perspective.js +30 -0
  54. package/domains/art-tree/lessons/perspective/2point-perspective.js +30 -0
  55. package/domains/art-tree/lessons/perspective/3point-perspective.js +45 -0
  56. package/domains/art-tree/lessons/perspective/foreshortening.js +38 -0
  57. package/domains/art-tree/lessons/sky/sun-shapes.js +25 -0
  58. package/domains/art-tree/lessons/sky/sunset-colors.js +27 -0
  59. package/domains/art-tree/lessons/sky/sunset-sky.js +32 -0
  60. package/domains/art-tree/{structure_lessons.js → lessons/structure/axis-orientation.js} +3 -53
  61. package/domains/art-tree/lessons/structure/complex-structure.js +21 -0
  62. package/domains/art-tree/lessons/structure/x-yzaxes.js +28 -0
  63. package/domains/art-tree/lessons/surfaces/chair-analysis.js +17 -0
  64. package/domains/art-tree/lessons/surfaces/cup-analysis.js +18 -0
  65. package/domains/art-tree/lessons/surfaces/edge-types.js +40 -0
  66. package/domains/art-tree/lessons/surfaces/surface-types.js +42 -0
  67. package/domains/art-tree/lessons/transforms/bend.js +27 -0
  68. package/domains/art-tree/{transform_lessons_2.js → lessons/transforms/combine.js} +3 -54
  69. package/domains/art-tree/lessons/transforms/cut.js +25 -0
  70. package/domains/art-tree/lessons/transforms/hollow.js +24 -0
  71. package/domains/art-tree/lessons/transforms/rotate.js +16 -0
  72. package/domains/art-tree/lessons/transforms/squash.js +31 -0
  73. package/domains/art-tree/lessons/transforms/stretch.js +31 -0
  74. package/domains/art-tree/lessons/transforms/taper-swell.js +33 -0
  75. package/domains/art-tree/{vocab_lessons.js → lessons/vocab/vocab-house.js} +5 -16
  76. package/domains/art-tree/lib/tool-register.js +104 -0
  77. package/domains/art-tree/lib/validators.js +78 -0
  78. package/domains/art-tree/shapes/grid.js +37 -0
  79. package/domains/art-tree/shapes/polyline.js +26 -0
  80. package/domains/art-tree/{3d_tools.js → tools/3d.js} +2 -2
  81. package/domains/art-tree/{advanced_tools.js → tools/advanced.js} +2 -2
  82. package/domains/art-tree/{analysis_tools.js → tools/analysis.js} +2 -2
  83. package/domains/art-tree/{tools.js → tools/basic.js} +3 -3
  84. package/domains/art-tree/{cross_section_tools.js → tools/cross-sections.js} +2 -2
  85. package/domains/art-tree/{curve_tools.js → tools/curves.js} +2 -2
  86. package/domains/art-tree/{ellipse_tools.js → tools/ellipses.js} +2 -2
  87. package/domains/art-tree/{hidden_tools.js → tools/hidden.js} +2 -2
  88. package/domains/art-tree/tools/index.js +53 -0
  89. package/domains/art-tree/{layer_tools.js → tools/layers.js} +2 -2
  90. package/domains/art-tree/{light_tools.js → tools/lighting.js} +2 -2
  91. package/domains/art-tree/{material_tools.js → tools/materials.js} +2 -2
  92. package/domains/art-tree/{perspective_tools.js → tools/perspective.js} +2 -2
  93. package/domains/art-tree/{sky_tools.js → tools/sky.js} +2 -2
  94. package/domains/art-tree/{structure_tools.js → tools/structure.js} +2 -2
  95. package/domains/art-tree/{surface_tools.js → tools/surfaces.js} +2 -2
  96. package/domains/art-tree/{transform_tools.js → tools/transforms.js} +3 -3
  97. package/domains/art-tree/{vocab_tools.js → tools/vocab.js} +2 -2
  98. package/package.json +1 -1
  99. package/rules/README.md +358 -285
  100. package/rules/index.js +9 -9
  101. package/rules/prerequisites.js +121 -64
  102. package/rules/rules.js +76 -35
  103. package/rules/workflow.js +270 -56
  104. package/tools/canvas-tools.js +2 -2
  105. package/tools/drawing-tools.js +23 -12
  106. package/tools/workspace-tools.js +5 -4
  107. package/domains/art-tree/3d_lessons.js +0 -114
  108. package/domains/art-tree/advanced_lessons.js +0 -124
  109. package/domains/art-tree/cross_section_lessons.js +0 -65
  110. package/domains/art-tree/curve_lessons.js +0 -138
  111. package/domains/art-tree/ellipse_lessons.js +0 -105
  112. package/domains/art-tree/hidden_lessons.js +0 -55
  113. package/domains/art-tree/lessons.js +0 -305
  114. package/domains/art-tree/light_lessons.js +0 -92
  115. package/domains/art-tree/material_lessons.js +0 -71
  116. package/domains/art-tree/perspective_lessons.js +0 -138
  117. package/domains/art-tree/sky_lessons_1.js +0 -82
  118. package/domains/art-tree/surface_lessons.js +0 -112
  119. package/domains/art-tree/transform_lessons_1.js +0 -108
  120. /package/domains/art-tree/{3d_shapes.js → shapes/3d.js} +0 -0
  121. /package/domains/art-tree/{advanced_shapes.js → shapes/advanced.js} +0 -0
  122. /package/domains/art-tree/{analysis_shapes.js → shapes/analysis.js} +0 -0
  123. /package/domains/art-tree/{shapes.js → shapes/basic.js} +0 -0
  124. /package/domains/art-tree/{cross_section_shapes.js → shapes/cross-sections.js} +0 -0
  125. /package/domains/art-tree/{curve_shapes.js → shapes/curves.js} +0 -0
  126. /package/domains/art-tree/{ellipse_shapes.js → shapes/ellipses.js} +0 -0
  127. /package/domains/art-tree/{hidden_shapes.js → shapes/hidden.js} +0 -0
  128. /package/domains/art-tree/{layer_shapes.js → shapes/layers.js} +0 -0
  129. /package/domains/art-tree/{light_shapes.js → shapes/lighting.js} +0 -0
  130. /package/domains/art-tree/{material_shapes.js → shapes/materials.js} +0 -0
  131. /package/domains/art-tree/{perspective_shapes.js → shapes/perspective.js} +0 -0
  132. /package/domains/art-tree/{sky_shapes_1.js → shapes/sky.js} +0 -0
  133. /package/domains/art-tree/{structure_shapes.js → shapes/structure.js} +0 -0
  134. /package/domains/art-tree/{surface_shapes.js → shapes/surfaces.js} +0 -0
  135. /package/domains/art-tree/{transform_shapes.js → shapes/transforms.js} +0 -0
  136. /package/domains/art-tree/{vocab_shapes.js → shapes/vocab.js} +0 -0
@@ -1,114 +0,0 @@
1
- const shapes3d = require('./3d_shapes');
2
- const advShapes = require('./advanced_shapes');
3
-
4
- /**
5
- * Lesson: Box Properties (Width, Height, Depth, Planes, Edges)
6
- */
7
- function lessonBoxProperties(canvasSize = 32, color = '#2196f3') {
8
- const commands = [];
9
- const cx = Math.floor(canvasSize / 2);
10
- const cy = Math.floor(canvasSize / 2);
11
- const w = Math.floor(canvasSize * 0.4);
12
- const h = Math.floor(canvasSize * 0.4);
13
- const d = Math.floor(canvasSize * 0.3);
14
-
15
- // Draw wireframe box
16
- commands.push(...shapes3d.drawWireframeBox(cx, cy, w, h, d, color));
17
-
18
- // Highlight dimensions
19
- const fX = cx - Math.floor(w/2);
20
- const fY = cy - Math.floor(h/2);
21
-
22
- // Width
23
- commands.push(...advShapes.drawDistance(fX, fY + h + 2, fX + w, fY + h + 2, '#4caf50'));
24
- // Height
25
- commands.push(...advShapes.drawDistance(fX - 2, fY, fX - 2, fY + h, '#ff9800'));
26
-
27
- // Depth (approximate along the oblique edge)
28
- const dx = Math.floor(d * 0.7);
29
- const dy = Math.floor(d * 0.5);
30
- commands.push(...advShapes.drawDistance(fX + w + 2, fY + h, fX + w + 2 + dx, fY + h - dy, '#e91e63'));
31
-
32
- return commands;
33
- }
34
-
35
- /**
36
- * Lesson: Sphere Properties (Center, Radius, Cross contours, Axis)
37
- */
38
- function lessonSphereProperties(canvasSize = 32, color = '#9c27b0') {
39
- const commands = [];
40
- const cx = Math.floor(canvasSize / 2);
41
- const cy = Math.floor(canvasSize / 2);
42
- const r = Math.floor(canvasSize * 0.35);
43
-
44
- // Draw sphere with volume lines
45
- commands.push(...shapes3d.drawSphereVolume(cx, cy, r, color));
46
-
47
- // Highlight radius
48
- commands.push(...advShapes.drawDistance(cx, cy, cx + r, cy, '#ff9800'));
49
-
50
- return commands;
51
- }
52
-
53
- /**
54
- * Lesson: Cylinder Properties (Central axis, Bases, Perspective change)
55
- */
56
- function lessonCylinderProperties(canvasSize = 32, color = '#00bcd4') {
57
- const commands = [];
58
- const cx = Math.floor(canvasSize / 2);
59
- const cy = Math.floor(canvasSize / 2);
60
- const r = Math.floor(canvasSize * 0.3);
61
- const h = Math.floor(canvasSize * 0.6);
62
-
63
- // Draw cylinder volume
64
- commands.push(...shapes3d.drawCylinderVolume(cx, cy, r, h, color));
65
-
66
- // Highlight Height
67
- commands.push(...advShapes.drawDistance(cx + r + 4, cy - Math.floor(h/2), cx + r + 4, cy + Math.floor(h/2), '#4caf50'));
68
-
69
- // Highlight Radius (top base)
70
- commands.push(...advShapes.drawDistance(cx, cy - Math.floor(h/2), cx + r, cy - Math.floor(h/2), '#ff9800'));
71
-
72
- return commands;
73
- }
74
-
75
- /**
76
- * Lesson: Cone Properties (Apex, Base, Axis)
77
- */
78
- function lessonConeProperties(canvasSize = 32, color = '#ff5722') {
79
- const commands = [];
80
- const cx = Math.floor(canvasSize / 2);
81
- const cy = Math.floor(canvasSize / 2);
82
- const r = Math.floor(canvasSize * 0.35);
83
- const h = Math.floor(canvasSize * 0.6);
84
-
85
- // Draw cone volume
86
- commands.push(...shapes3d.drawConeVolume(cx, cy, r, h, color));
87
-
88
- // Highlight Height
89
- const apexY = cy - Math.floor(h/2);
90
- const baseY = cy + Math.floor(h/2);
91
- commands.push(...advShapes.drawDistance(cx + r + 4, apexY, cx + r + 4, baseY, '#4caf50'));
92
-
93
- // Highlight Radius (base)
94
- commands.push(...advShapes.drawDistance(cx, baseY, cx + r, baseY, '#ff9800'));
95
-
96
- return commands;
97
- }
98
-
99
- function get3DLessonCatalog() {
100
- return [
101
- { id: '3d_box', name: '3D Box Properties', description: 'Width, height, depth, planes, inner structure', fn: lessonBoxProperties },
102
- { id: '3d_sphere', name: '3D Sphere Properties', description: 'Center, radius, axis, cross contours', fn: lessonSphereProperties },
103
- { id: '3d_cylinder', name: '3D Cylinder Properties', description: 'Axis, bases, height, perspective changes', fn: lessonCylinderProperties },
104
- { id: '3d_cone', name: '3D Cone Properties', description: 'Apex, base, axis, radius', fn: lessonConeProperties },
105
- ];
106
- }
107
-
108
- module.exports = {
109
- lessonBoxProperties,
110
- lessonSphereProperties,
111
- lessonCylinderProperties,
112
- lessonConeProperties,
113
- get3DLessonCatalog
114
- };
@@ -1,124 +0,0 @@
1
- const shapes = require('./shapes');
2
- const advShapes = require('./advanced_shapes');
3
-
4
- /**
5
- * Lesson: Shape Ratios
6
- */
7
- function lessonShapeRatios(canvasSize = 32, color = '#2196f3') {
8
- const margin = Math.floor(canvasSize * 0.1);
9
- const w1 = Math.floor(canvasSize * 0.2);
10
- const h1 = w1; // 1:1
11
- const w2 = Math.floor(canvasSize * 0.2);
12
- const h2 = Math.floor(canvasSize * 0.4); // 1:2
13
-
14
- return [
15
- shapes.drawRectangle(margin, margin, w1, h1, color, false),
16
- shapes.drawRectangle(canvasSize - margin - w2, margin, w2, h2, '#4caf50', false),
17
- ...advShapes.drawDistance(margin, margin + h1 + 2, margin + w1, margin + h1 + 2, '#888'),
18
- ...advShapes.drawDistance(canvasSize - margin - w2, margin + h2 + 2, canvasSize - margin, margin + h2 + 2, '#888')
19
- ];
20
- }
21
-
22
- /**
23
- * Lesson: Symmetry & Axes
24
- */
25
- function lessonSymmetryAndAxis(canvasSize = 32, color = '#9c27b0') {
26
- const mid = Math.floor(canvasSize / 2);
27
- const w = Math.floor(canvasSize * 0.5);
28
- const h = Math.floor(canvasSize * 0.5);
29
- const commands = [];
30
-
31
- // Draw Rhombus
32
- commands.push(advShapes.drawRhombus(mid, mid, w, h, color, false));
33
- // Vertical axis
34
- commands.push(advShapes.drawAxis(mid, Math.floor(canvasSize * 0.1), mid, canvasSize - Math.floor(canvasSize * 0.1)));
35
- // Horizontal axis
36
- commands.push(advShapes.drawAxis(Math.floor(canvasSize * 0.1), mid, canvasSize - Math.floor(canvasSize * 0.1), mid));
37
-
38
- return commands;
39
- }
40
-
41
- /**
42
- * Lesson: Angles
43
- */
44
- function lessonAngles(canvasSize = 32, color = '#ff5722') {
45
- const mid = Math.floor(canvasSize / 2);
46
- const w = Math.floor(canvasSize * 0.6);
47
- const h = Math.floor(canvasSize * 0.3);
48
- const margin = Math.floor(canvasSize * 0.2);
49
-
50
- const commands = [];
51
- // Trapezoid (shows acute and obtuse angles)
52
- commands.push(advShapes.drawTrapezoid(margin, margin, Math.floor(w/2), w, h, color, false));
53
-
54
- // Right Triangle (shows 90 degree angle)
55
- commands.push(shapes.drawTriangle([
56
- { x: margin, y: canvasSize - margin },
57
- { x: margin, y: mid + margin },
58
- { x: margin + w, y: canvasSize - margin }
59
- ], '#3f51b5', false));
60
-
61
- return commands;
62
- }
63
-
64
- /**
65
- * Lesson: Distances
66
- */
67
- function lessonDistances(canvasSize = 32, color = '#00bcd4') {
68
- const margin = Math.floor(canvasSize * 0.2);
69
- const commands = [];
70
-
71
- // Points
72
- commands.push(shapes.drawCircle(margin, margin, 1, color, true));
73
- commands.push(shapes.drawCircle(canvasSize - margin, margin, 1, color, true));
74
- commands.push(shapes.drawCircle(margin, canvasSize - margin, 1, color, true));
75
-
76
- // Distances between them
77
- commands.push(...advShapes.drawDistance(margin, margin, canvasSize - margin, margin));
78
- commands.push(...advShapes.drawDistance(margin, margin, margin, canvasSize - margin));
79
-
80
- return commands;
81
- }
82
-
83
- /**
84
- * Lesson: Shape Relationships
85
- */
86
- function lessonShapeRelationships(canvasSize = 32, color = '#607d8b') {
87
- const mid = Math.floor(canvasSize / 2);
88
- const r = Math.floor(canvasSize * 0.2);
89
- const commands = [];
90
-
91
- // Overlapping circles
92
- commands.push(shapes.drawCircle(mid - Math.floor(r/2), mid, r, color, false));
93
- commands.push(shapes.drawCircle(mid + Math.floor(r/2), mid, r, '#e91e63', false));
94
-
95
- // Nested squares (top left)
96
- const margin = Math.floor(canvasSize * 0.1);
97
- const size = Math.floor(canvasSize * 0.25);
98
- commands.push(shapes.drawSquare(margin, margin, size, '#4caf50', false));
99
- commands.push(shapes.drawSquare(margin + 2, margin + 2, size - 4, '#8bc34a', false));
100
-
101
- return commands;
102
- }
103
-
104
- /**
105
- * Get catalog of advanced lessons
106
- */
107
- function getAdvancedLessonCatalog() {
108
- return [
109
- { id: 'adv_ratios', name: 'Shape Ratios', description: 'Width-to-height ratios of shapes', fn: lessonShapeRatios },
110
- { id: 'adv_symmetry', name: 'Symmetry & Axes', description: 'Symmetry and central axes', fn: lessonSymmetryAndAxis },
111
- { id: 'adv_angles', name: 'Angles', description: 'Acute, right, and obtuse angles', fn: lessonAngles },
112
- { id: 'adv_distances', name: 'Distances', description: 'Distances between points', fn: lessonDistances },
113
- { id: 'adv_relationships', name: 'Shape Relationships', description: 'Overlap and nesting of shapes', fn: lessonShapeRelationships },
114
- ];
115
- }
116
-
117
- module.exports = {
118
- lessonShapeRatios,
119
- lessonSymmetryAndAxis,
120
- lessonAngles,
121
- lessonDistances,
122
- lessonShapeRelationships,
123
- getAdvancedLessonCatalog
124
- };
@@ -1,65 +0,0 @@
1
- const csShapes = require('./cross_section_shapes');
2
-
3
- /**
4
- * Lesson: Bottle Sections (Base, Body, Shoulder, Neck, Mouth)
5
- */
6
- function lessonBottleSections(canvasSize = 32, color = '#2196f3') {
7
- const cx = Math.floor(canvasSize / 2);
8
- const totalH = Math.floor(canvasSize * 0.8);
9
- const topY = Math.floor(canvasSize * 0.1);
10
- const bottomY = topY + totalH;
11
-
12
- const sections = [
13
- { y: topY, r: Math.floor(canvasSize * 0.08) }, // Mouth (slightly open)
14
- { y: topY + Math.floor(totalH * 0.1), r: Math.floor(canvasSize * 0.06) }, // Neck (narrow)
15
- { y: topY + Math.floor(totalH * 0.3), r: Math.floor(canvasSize * 0.2) }, // Shoulder (shrinking to body)
16
- { y: topY + Math.floor(totalH * 0.6), r: Math.floor(canvasSize * 0.25) }, // Body (wide)
17
- { y: bottomY, r: Math.floor(canvasSize * 0.25) } // Base (wide)
18
- ];
19
-
20
- return csShapes.drawLoftedForm(cx, topY, bottomY, sections, color, true);
21
- }
22
-
23
- /**
24
- * Lesson: Glass Sections (Base, Mid, Mouth)
25
- */
26
- function lessonGlassSections(canvasSize = 32, color = '#9c27b0') {
27
- const cx = Math.floor(canvasSize / 2);
28
- const totalH = Math.floor(canvasSize * 0.6);
29
- const topY = Math.floor(canvasSize * 0.2);
30
- const bottomY = topY + totalH;
31
-
32
- const sections = [
33
- { y: topY, r: Math.floor(canvasSize * 0.3) }, // Mouth (wide)
34
- { y: topY + Math.floor(totalH * 0.5), r: Math.floor(canvasSize * 0.2) }, // Mid body (widening)
35
- { y: bottomY, r: Math.floor(canvasSize * 0.15) } // Base (small)
36
- ];
37
-
38
- return csShapes.drawLoftedForm(cx, topY, bottomY, sections, color, true);
39
- }
40
-
41
- /**
42
- * Lesson: Head Sections (Cranium, Face, Jaw)
43
- */
44
- function lessonHeadSections(canvasSize = 32, color = '#ff9800') {
45
- const cx = Math.floor(canvasSize / 2);
46
- const cy = Math.floor(canvasSize / 2);
47
- const height = Math.floor(canvasSize * 0.8);
48
-
49
- return csShapes.drawHeadStructure(cx, cy, height, color);
50
- }
51
-
52
- function getCrossSectionLessonCatalog() {
53
- return [
54
- { id: 'cs_bottle', name: 'Bottle Cross-sections', description: 'Base, body, shoulder, neck, mouth', fn: lessonBottleSections },
55
- { id: 'cs_glass', name: 'Glass Cross-sections', description: 'Base, body, mouth', fn: lessonGlassSections },
56
- { id: 'cs_head', name: 'Head Cross-sections', description: 'Cranium, face, jaw', fn: lessonHeadSections },
57
- ];
58
- }
59
-
60
- module.exports = {
61
- lessonBottleSections,
62
- lessonGlassSections,
63
- lessonHeadSections,
64
- getCrossSectionLessonCatalog
65
- };
@@ -1,138 +0,0 @@
1
- const shapes = require('./shapes');
2
- const curveShapes = require('./curve_shapes');
3
-
4
- /**
5
- * Lesson 1: Curve Types (C, S, Convex, Concave)
6
- */
7
- function lessonCurveTypes(canvasSize = 32, color = '#2196f3') {
8
- const margin = Math.floor(canvasSize * 0.1);
9
- const commands = [];
10
-
11
- const w = Math.floor(canvasSize / 2) - margin * 2;
12
- const h = Math.floor(canvasSize / 2) - margin * 2;
13
-
14
- // C Curve (Top Left)
15
- const cP0 = { x: margin + w, y: margin };
16
- const cP1 = { x: margin - w, y: margin + Math.floor(h/2) }; // Pulls curve left
17
- const cP2 = { x: margin + w, y: margin + h };
18
- commands.push(...curveShapes.drawQuadraticCurve(cP0, cP1, cP2, color));
19
-
20
- // S Curve (Top Right)
21
- const sP0 = { x: canvasSize - margin, y: margin };
22
- const sP1 = { x: canvasSize - margin - w*2, y: margin };
23
- const sP2 = { x: canvasSize - margin + w, y: margin + h };
24
- const sP3 = { x: canvasSize - margin - w, y: margin + h };
25
- commands.push(...curveShapes.drawCubicCurve(sP0, sP1, sP2, sP3, '#e91e63'));
26
-
27
- // Convex (Bottom Left, viewed from bottom)
28
- const cvxP0 = { x: margin, y: canvasSize - margin };
29
- const cvxP1 = { x: margin + Math.floor(w/2), y: canvasSize - margin - h };
30
- const cvxP2 = { x: margin + w, y: canvasSize - margin };
31
- commands.push(...curveShapes.drawQuadraticCurve(cvxP0, cvxP1, cvxP2, '#4caf50'));
32
-
33
- // Concave (Bottom Right, viewed from bottom)
34
- const cnvP0 = { x: canvasSize - margin - w, y: canvasSize - margin - Math.floor(h/2) };
35
- const cnvP1 = { x: canvasSize - margin - Math.floor(w/2), y: canvasSize - margin + h };
36
- const cnvP2 = { x: canvasSize - margin, y: canvasSize - margin - Math.floor(h/2) };
37
- commands.push(...curveShapes.drawQuadraticCurve(cnvP0, cnvP1, cnvP2, '#ff9800'));
38
-
39
- return commands;
40
- }
41
-
42
- /**
43
- * Lesson 2: Curve Topology (Closed, Open, Symmetrical, Asymmetrical)
44
- */
45
- function lessonCurveTopology(canvasSize = 32, color = '#9c27b0') {
46
- const mid = Math.floor(canvasSize / 2);
47
- const q = Math.floor(canvasSize / 4);
48
- const commands = [];
49
-
50
- // Closed Curve (Circle-like using Bezier for demonstration)
51
- // Since we already have drawCircle, we just draw a circle to represent a closed curve
52
- commands.push(shapes.drawCircle(q, q, Math.floor(q*0.8), color, false));
53
-
54
- // Open Curve (Quadratic)
55
- commands.push(...curveShapes.drawQuadraticCurve(
56
- { x: canvasSize - q*1.5, y: q },
57
- { x: canvasSize - q*0.5, y: q - q/2 },
58
- { x: canvasSize - q*0.5, y: q + q/2 },
59
- '#3f51b5'
60
- ));
61
-
62
- // Symmetrical Curve (Parabola-like)
63
- commands.push(...curveShapes.drawQuadraticCurve(
64
- { x: q*0.5, y: canvasSize - q*0.5 },
65
- { x: q, y: canvasSize - q*1.5 },
66
- { x: q*1.5, y: canvasSize - q*0.5 },
67
- '#00bcd4'
68
- ));
69
-
70
- // Asymmetrical Curve
71
- commands.push(...curveShapes.drawQuadraticCurve(
72
- { x: canvasSize - q*1.5, y: canvasSize - q*0.5 },
73
- { x: canvasSize - q*0.2, y: canvasSize - q*1.8 }, // Pull point is skewed
74
- { x: canvasSize - q*0.5, y: canvasSize - q*0.5 },
75
- '#ff5722'
76
- ));
77
-
78
- return commands;
79
- }
80
-
81
- /**
82
- * Lesson 3: Curve Properties (Start, Direction, Curvature, Inflection, Transition)
83
- */
84
- function lessonCurveProperties(canvasSize = 32, color = '#607d8b') {
85
- const margin = Math.floor(canvasSize * 0.1);
86
- const commands = [];
87
-
88
- // 1. Start point and Direction (Top Left Curve)
89
- const p0 = { x: margin, y: margin * 2 };
90
- const p1 = { x: margin + canvasSize*0.3, y: margin };
91
- const p2 = { x: margin + canvasSize*0.3, y: margin + canvasSize*0.3 };
92
- commands.push(...curveShapes.drawQuadraticCurve(p0, p1, p2, color));
93
- commands.push(curveShapes.drawStartMarker(p0.x, p0.y, '#00ff00')); // Green dot at start
94
- commands.push(...curveShapes.drawDirectionArrow(p0, p1, p2, null, '#ff0000')); // Red arrow
95
-
96
- // 2. Curvature comparison (Bottom Left)
97
- // Strong vs Weak curve with same endpoints
98
- const bp0 = { x: margin, y: canvasSize - margin };
99
- const bp2 = { x: margin + canvasSize*0.4, y: canvasSize - margin };
100
- // Weak curve
101
- commands.push(...curveShapes.drawQuadraticCurve(bp0, { x: margin + canvasSize*0.2, y: canvasSize - margin - canvasSize*0.1 }, bp2, '#8bc34a'));
102
- // Strong curve
103
- commands.push(...curveShapes.drawQuadraticCurve(bp0, { x: margin + canvasSize*0.2, y: canvasSize - margin - canvasSize*0.4 }, bp2, '#388e3c'));
104
-
105
- // 3. Inflection point (Top Right S Curve)
106
- const sP0 = { x: canvasSize - margin - canvasSize*0.3, y: margin };
107
- const sP1 = { x: canvasSize - margin, y: margin };
108
- const sP2 = { x: canvasSize - margin - canvasSize*0.4, y: margin + canvasSize*0.3 };
109
- const sP3 = { x: canvasSize - margin, y: margin + canvasSize*0.3 };
110
- commands.push(...curveShapes.drawCubicCurve(sP0, sP1, sP2, sP3, '#03a9f4'));
111
- // Inflection point roughly at t=0.5
112
- const inflection = curveShapes.cubicBezier(sP0, sP1, sP2, sP3, 0.5);
113
- commands.push(curveShapes.drawInflectionMarker(inflection.x, inflection.y, '#ff9800'));
114
-
115
- // 4. Transition (Bottom Right - line transitioning to curve)
116
- const startLine = { x: canvasSize - margin - canvasSize*0.3, y: canvasSize - margin - canvasSize*0.2 };
117
- const transPt = { x: canvasSize - margin - canvasSize*0.1, y: canvasSize - margin - canvasSize*0.2 };
118
- commands.push(shapes.drawLine(startLine.x, startLine.y, transPt.x, transPt.y, '#9e9e9e'));
119
- // Curve starting tangentially
120
- commands.push(...curveShapes.drawQuadraticCurve(transPt, { x: canvasSize - margin, y: canvasSize - margin - canvasSize*0.2 }, { x: canvasSize - margin, y: canvasSize - margin }, '#795548'));
121
-
122
- return commands;
123
- }
124
-
125
- function getCurveLessonCatalog() {
126
- return [
127
- { id: 'curve_types', name: 'Curve Types', description: 'C, S, Convex, and Concave curves', fn: lessonCurveTypes },
128
- { id: 'curve_topology', name: 'Curve Topology', description: 'Closed, Open, Symmetrical, Asymmetrical curves', fn: lessonCurveTopology },
129
- { id: 'curve_properties', name: 'Curve Properties', description: 'Start point, Direction, Curvature, Inflection, and Transitions', fn: lessonCurveProperties },
130
- ];
131
- }
132
-
133
- module.exports = {
134
- lessonCurveTypes,
135
- lessonCurveTopology,
136
- lessonCurveProperties,
137
- getCurveLessonCatalog
138
- };
@@ -1,105 +0,0 @@
1
- const shapes = require('./shapes');
2
- const ellipseShapes = require('./ellipse_shapes');
3
-
4
- /**
5
- * Lesson: Ellipse Orientations (Horizontal, Vertical, Tilted)
6
- */
7
- function lessonEllipseOrientations(canvasSize = 32, color = '#2196f3') {
8
- const commands = [];
9
- const midY = Math.floor(canvasSize / 2);
10
- const qX = Math.floor(canvasSize / 4);
11
- const rLong = Math.floor(canvasSize * 0.2);
12
- const rShort = Math.floor(canvasSize * 0.1);
13
-
14
- // Horizontal (Left)
15
- commands.push(shapes.drawEllipse(qX, midY, rLong, rShort, color, false));
16
-
17
- // Vertical (Middle)
18
- commands.push(shapes.drawEllipse(qX * 2, midY, rShort, rLong, '#e91e63', false));
19
-
20
- // Tilted (Right) - 45 degrees
21
- commands.push(...ellipseShapes.drawRotatedEllipse(qX * 3, midY, rLong, rShort, Math.PI / 4, '#4caf50'));
22
-
23
- return commands;
24
- }
25
-
26
- /**
27
- * Lesson: Ellipse Proportions (Wide vs Narrow)
28
- */
29
- function lessonEllipseProportions(canvasSize = 32, color = '#ff9800') {
30
- const commands = [];
31
- const midY = Math.floor(canvasSize / 2);
32
- const qX = Math.floor(canvasSize / 4);
33
- const rx = Math.floor(canvasSize * 0.2);
34
-
35
- // Wide Ellipse (Closer to a circle)
36
- commands.push(shapes.drawEllipse(qX, midY, rx, Math.floor(rx * 0.8), color, false));
37
-
38
- // Medium Ellipse
39
- commands.push(shapes.drawEllipse(qX * 2, midY, rx, Math.floor(rx * 0.4), '#9c27b0', false));
40
-
41
- // Narrow Ellipse (Almost a line)
42
- commands.push(shapes.drawEllipse(qX * 3, midY, rx, Math.floor(rx * 0.1), '#f44336', false));
43
-
44
- return commands;
45
- }
46
-
47
- /**
48
- * Lesson: Ellipse Anatomy (Symmetry, Major/Minor axes, Center)
49
- */
50
- function lessonEllipseAnatomy(canvasSize = 32, color = '#00bcd4') {
51
- const commands = [];
52
- const cx = Math.floor(canvasSize / 2);
53
- const cy = Math.floor(canvasSize / 2);
54
- const rx = Math.floor(canvasSize * 0.35);
55
- const ry = Math.floor(canvasSize * 0.2);
56
- const angle = Math.PI / 6; // 30 degrees tilt to show axes clearly
57
-
58
- // Draw ellipse
59
- commands.push(...ellipseShapes.drawRotatedEllipse(cx, cy, rx, ry, angle, color));
60
-
61
- // Draw anatomy (axes and center)
62
- commands.push(...ellipseShapes.drawEllipseAxes(cx, cy, rx, ry, angle));
63
-
64
- return commands;
65
- }
66
-
67
- /**
68
- * Lesson: Coaxial Ellipses (Multiple ellipses on the same axis)
69
- */
70
- function lessonCoaxialEllipses(canvasSize = 32, color = '#795548') {
71
- const commands = [];
72
- const cx = Math.floor(canvasSize / 2);
73
- const rx = Math.floor(canvasSize * 0.3);
74
-
75
- // Central axis line
76
- commands.push(shapes.drawLine(cx, Math.floor(canvasSize * 0.1), cx, canvasSize - Math.floor(canvasSize * 0.1), '#bdbdbd'));
77
-
78
- // Top ellipse (narrower, viewed from steeper angle)
79
- commands.push(shapes.drawEllipse(cx, Math.floor(canvasSize * 0.2), rx, Math.floor(rx * 0.2), color, false));
80
-
81
- // Middle ellipse
82
- commands.push(shapes.drawEllipse(cx, Math.floor(canvasSize * 0.5), rx, Math.floor(rx * 0.3), color, false));
83
-
84
- // Bottom ellipse (wider, viewed from less steep angle)
85
- commands.push(shapes.drawEllipse(cx, canvasSize - Math.floor(canvasSize * 0.2), rx, Math.floor(rx * 0.4), color, false));
86
-
87
- return commands;
88
- }
89
-
90
- function getEllipseLessonCatalog() {
91
- return [
92
- { id: 'ellipse_orientations', name: 'Ellipse Orientations', description: 'Horizontal, Vertical, and Tilted ellipses', fn: lessonEllipseOrientations },
93
- { id: 'ellipse_proportions', name: 'Ellipse Proportions', description: 'Wide vs Narrow ellipses', fn: lessonEllipseProportions },
94
- { id: 'ellipse_anatomy', name: 'Ellipse Anatomy', description: 'Symmetry, Major/Minor axes, and Center', fn: lessonEllipseAnatomy },
95
- { id: 'ellipse_coaxial', name: 'Coaxial Ellipses', description: 'Multiple ellipses sharing the same axis', fn: lessonCoaxialEllipses },
96
- ];
97
- }
98
-
99
- module.exports = {
100
- lessonEllipseOrientations,
101
- lessonEllipseProportions,
102
- lessonEllipseAnatomy,
103
- lessonCoaxialEllipses,
104
- getEllipseLessonCatalog
105
- };
@@ -1,55 +0,0 @@
1
- const hiddenShapes = require('./hidden_shapes');
2
-
3
- /**
4
- * Lesson: Hidden Box (6-sided box)
5
- * You see 3 faces, but you must understand all 6.
6
- */
7
- function lessonHiddenBox(canvasSize = 32, visibleColor = '#2196f3', hiddenColor = '#e0e0e0') {
8
- const cx = Math.floor(canvasSize / 2);
9
- const cy = Math.floor(canvasSize / 2);
10
- const w = Math.floor(canvasSize * 0.4);
11
- const h = Math.floor(canvasSize * 0.4);
12
- const d = Math.floor(canvasSize * 0.4);
13
-
14
- return hiddenShapes.drawXRayBox(cx, cy, w, h, d, visibleColor, hiddenColor);
15
- }
16
-
17
- /**
18
- * Lesson: Hidden Head (Human head and skull)
19
- * You don't see the whole skull, but must understand the structure behind it.
20
- */
21
- function lessonHiddenHead(canvasSize = 32, visibleColor = '#ff5722', hiddenColor = '#e0e0e0') {
22
- const cx = Math.floor(canvasSize / 2);
23
- const cy = Math.floor(canvasSize * 0.4);
24
- const r = Math.floor(canvasSize * 0.25);
25
-
26
- return hiddenShapes.drawXRayHead(cx, cy, r, visibleColor, hiddenColor);
27
- }
28
-
29
- /**
30
- * Lesson: Hidden Cup (Cup and inner bottom)
31
- * You don't see the full inside bottom, but must understand how the wall goes down.
32
- */
33
- function lessonHiddenCup(canvasSize = 32, visibleColor = '#4caf50', hiddenColor = '#e0e0e0') {
34
- const cx = Math.floor(canvasSize / 2);
35
- const cy = Math.floor(canvasSize / 2);
36
- const r = Math.floor(canvasSize * 0.25);
37
- const h = Math.floor(canvasSize * 0.5);
38
-
39
- return hiddenShapes.drawXRayCup(cx, cy, r, h, visibleColor, hiddenColor);
40
- }
41
-
42
- function getHiddenLessonCatalog() {
43
- return [
44
- { id: 'hidden_box', name: 'Hidden Box', description: 'See all 6 faces of a box, not just 3', fn: lessonHiddenBox },
45
- { id: 'hidden_head', name: 'Hidden Head', description: 'Understand the cranium sphere behind the face', fn: lessonHiddenHead },
46
- { id: 'hidden_cup', name: 'Hidden Cup', description: 'Understand the inner depth and bottom of a cup', fn: lessonHiddenCup },
47
- ];
48
- }
49
-
50
- module.exports = {
51
- lessonHiddenBox,
52
- lessonHiddenHead,
53
- lessonHiddenCup,
54
- getHiddenLessonCatalog
55
- };