@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
|
@@ -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
|
-
};
|