math-exercises 3.0.152 → 3.0.153

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 (116) hide show
  1. package/lib/exercises/exercise.d.ts +2 -0
  2. package/lib/exercises/exercise.d.ts.map +1 -1
  3. package/lib/exercises/math/calculLitteral/equation/index.d.ts +1 -1
  4. package/lib/exercises/math/calculLitteral/equation/index.d.ts.map +1 -1
  5. package/lib/exercises/math/calculLitteral/equation/index.js +1 -1
  6. package/lib/exercises/math/calculLitteral/equation/square/equationSimpleSquare.d.ts +10 -0
  7. package/lib/exercises/math/calculLitteral/equation/square/equationSimpleSquare.d.ts.map +1 -0
  8. package/lib/exercises/math/calculLitteral/equation/square/equationSimpleSquare.js +183 -0
  9. package/lib/exercises/math/calculLitteral/equation/square/equationSquareWithSteps.d.ts +10 -0
  10. package/lib/exercises/math/calculLitteral/equation/square/equationSquareWithSteps.d.ts.map +1 -0
  11. package/lib/exercises/math/calculLitteral/equation/square/equationSquareWithSteps.js +173 -0
  12. package/lib/exercises/math/calculLitteral/equation/square/index.d.ts +3 -0
  13. package/lib/exercises/math/calculLitteral/equation/square/index.d.ts.map +1 -0
  14. package/lib/exercises/math/calculLitteral/equation/square/index.js +2 -0
  15. package/lib/exercises/math/functions/sqrt/squareRootCalculation.d.ts.map +1 -1
  16. package/lib/exercises/math/functions/sqrt/squareRootCalculation.js +4 -2
  17. package/lib/exercises/math/geometry/euclidian/homothetyFactorFromPoints.d.ts +15 -0
  18. package/lib/exercises/math/geometry/euclidian/homothetyFactorFromPoints.d.ts.map +1 -0
  19. package/lib/exercises/math/geometry/euclidian/homothetyFactorFromPoints.js +301 -0
  20. package/lib/exercises/math/geometry/euclidian/index.d.ts +7 -0
  21. package/lib/exercises/math/geometry/euclidian/index.d.ts.map +1 -1
  22. package/lib/exercises/math/geometry/euclidian/index.js +7 -0
  23. package/lib/exercises/math/geometry/euclidian/pinPointFromAxialOrCentralSymmetry.d.ts +21 -0
  24. package/lib/exercises/math/geometry/euclidian/pinPointFromAxialOrCentralSymmetry.d.ts.map +1 -0
  25. package/lib/exercises/math/geometry/euclidian/pinPointFromAxialOrCentralSymmetry.js +406 -0
  26. package/lib/exercises/math/geometry/euclidian/pinPointFromRotation.d.ts +18 -0
  27. package/lib/exercises/math/geometry/euclidian/pinPointFromRotation.d.ts.map +1 -0
  28. package/lib/exercises/math/geometry/euclidian/pinPointFromRotation.js +315 -0
  29. package/lib/exercises/math/geometry/euclidian/pinPointFromTranslation.d.ts +20 -0
  30. package/lib/exercises/math/geometry/euclidian/pinPointFromTranslation.d.ts.map +1 -0
  31. package/lib/exercises/math/geometry/euclidian/pinPointFromTranslation.js +314 -0
  32. package/lib/exercises/math/geometry/euclidian/pinSegmentFromRotation.d.ts +18 -0
  33. package/lib/exercises/math/geometry/euclidian/pinSegmentFromRotation.d.ts.map +1 -0
  34. package/lib/exercises/math/geometry/euclidian/pinSegmentFromRotation.js +387 -0
  35. package/lib/exercises/math/geometry/euclidian/recognizeAngleFromRotation.d.ts +18 -0
  36. package/lib/exercises/math/geometry/euclidian/recognizeAngleFromRotation.d.ts.map +1 -0
  37. package/lib/exercises/math/geometry/euclidian/recognizeAngleFromRotation.js +309 -0
  38. package/lib/exercises/math/geometry/euclidian/recognizeHomothetyCenter.d.ts +17 -0
  39. package/lib/exercises/math/geometry/euclidian/recognizeHomothetyCenter.d.ts.map +1 -0
  40. package/lib/exercises/math/geometry/euclidian/recognizeHomothetyCenter.js +301 -0
  41. package/lib/exercises/math/geometry/euclidianConstructions/buildPointFromAxialSymetry.d.ts.map +1 -1
  42. package/lib/exercises/math/geometry/euclidianConstructions/buildPointFromAxialSymetry.js +22 -8
  43. package/lib/exercises/math/geometry/euclidianConstructions/buildPointFromCentralSymmetry.d.ts +11 -0
  44. package/lib/exercises/math/geometry/euclidianConstructions/buildPointFromCentralSymmetry.d.ts.map +1 -0
  45. package/lib/exercises/math/geometry/euclidianConstructions/buildPointFromCentralSymmetry.js +169 -0
  46. package/lib/exercises/math/geometry/euclidianConstructions/index.d.ts +2 -0
  47. package/lib/exercises/math/geometry/euclidianConstructions/index.d.ts.map +1 -1
  48. package/lib/exercises/math/geometry/euclidianConstructions/index.js +2 -0
  49. package/lib/exercises/math/geometry/euclidianConstructions/placeHomothetyCenter.d.ts +16 -0
  50. package/lib/exercises/math/geometry/euclidianConstructions/placeHomothetyCenter.d.ts.map +1 -0
  51. package/lib/exercises/math/geometry/euclidianConstructions/placeHomothetyCenter.js +309 -0
  52. package/lib/exercises/math/probaStat/stats1var/averageWithClasses.d.ts +9 -0
  53. package/lib/exercises/math/probaStat/stats1var/averageWithClasses.d.ts.map +1 -0
  54. package/lib/exercises/math/probaStat/stats1var/averageWithClasses.js +140 -0
  55. package/lib/exercises/math/probaStat/stats1var/averageWithTableWithContext.d.ts +8 -0
  56. package/lib/exercises/math/probaStat/stats1var/averageWithTableWithContext.d.ts.map +1 -0
  57. package/lib/exercises/math/probaStat/stats1var/averageWithTableWithContext.js +113 -0
  58. package/lib/exercises/math/probaStat/stats1var/index.d.ts +2 -0
  59. package/lib/exercises/math/probaStat/stats1var/index.d.ts.map +1 -1
  60. package/lib/exercises/math/probaStat/stats1var/index.js +2 -0
  61. package/lib/exercises/math/scratch/index.d.ts +3 -0
  62. package/lib/exercises/math/scratch/index.d.ts.map +1 -1
  63. package/lib/exercises/math/scratch/index.js +3 -0
  64. package/lib/exercises/math/scratch/scratchListElemAtIndex.d.ts +13 -0
  65. package/lib/exercises/math/scratch/scratchListElemAtIndex.d.ts.map +1 -0
  66. package/lib/exercises/math/scratch/scratchListElemAtIndex.js +189 -0
  67. package/lib/exercises/math/scratch/scratchListElemAtIndex2.d.ts +23 -0
  68. package/lib/exercises/math/scratch/scratchListElemAtIndex2.d.ts.map +1 -0
  69. package/lib/exercises/math/scratch/scratchListElemAtIndex2.js +207 -0
  70. package/lib/exercises/math/scratch/scratchListFilter.d.ts +13 -0
  71. package/lib/exercises/math/scratch/scratchListFilter.d.ts.map +1 -0
  72. package/lib/exercises/math/scratch/scratchListFilter.js +397 -0
  73. package/lib/exercises/math/spaceGeometry/basis/findSpacePointOnRectangularPrism.d.ts +14 -0
  74. package/lib/exercises/math/spaceGeometry/basis/findSpacePointOnRectangularPrism.d.ts.map +1 -0
  75. package/lib/exercises/math/spaceGeometry/basis/findSpacePointOnRectangularPrism.js +347 -0
  76. package/lib/exercises/math/spaceGeometry/basis/index.d.ts +1 -0
  77. package/lib/exercises/math/spaceGeometry/basis/index.d.ts.map +1 -1
  78. package/lib/exercises/math/spaceGeometry/basis/index.js +1 -0
  79. package/lib/exercises/math/spaceGeometry/index.d.ts +2 -0
  80. package/lib/exercises/math/spaceGeometry/index.d.ts.map +1 -1
  81. package/lib/exercises/math/spaceGeometry/index.js +2 -0
  82. package/lib/exercises/math/spaceGeometry/sections/areaOfConeSection.js +3 -3
  83. package/lib/exercises/math/spaceGeometry/solids/index.d.ts +3 -0
  84. package/lib/exercises/math/spaceGeometry/solids/index.d.ts.map +1 -0
  85. package/lib/exercises/math/spaceGeometry/solids/index.js +2 -0
  86. package/lib/exercises/math/spaceGeometry/solids/recognizeSolidFrom3D.d.ts +15 -0
  87. package/lib/exercises/math/spaceGeometry/solids/recognizeSolidFrom3D.d.ts.map +1 -0
  88. package/lib/exercises/math/spaceGeometry/solids/recognizeSolidFrom3D.js +440 -0
  89. package/lib/exercises/math/spaceGeometry/solids/recognizeSolidFromSolidPattern.d.ts +11 -0
  90. package/lib/exercises/math/spaceGeometry/solids/recognizeSolidFromSolidPattern.d.ts.map +1 -0
  91. package/lib/exercises/math/spaceGeometry/solids/recognizeSolidFromSolidPattern.js +1089 -0
  92. package/lib/exercises/math/spaceGeometry/sphere/index.d.ts +3 -0
  93. package/lib/exercises/math/spaceGeometry/sphere/index.d.ts.map +1 -0
  94. package/lib/exercises/math/spaceGeometry/sphere/index.js +2 -0
  95. package/lib/exercises/math/spaceGeometry/sphere/pickIsPointInSphereOrBall.d.ts +9 -0
  96. package/lib/exercises/math/spaceGeometry/sphere/pickIsPointInSphereOrBall.d.ts.map +1 -0
  97. package/lib/exercises/math/spaceGeometry/sphere/pickIsPointInSphereOrBall.js +127 -0
  98. package/lib/exercises/math/spaceGeometry/sphere/sphereLatLonReading.d.ts +14 -0
  99. package/lib/exercises/math/spaceGeometry/sphere/sphereLatLonReading.d.ts.map +1 -0
  100. package/lib/exercises/math/spaceGeometry/sphere/sphereLatLonReading.js +390 -0
  101. package/lib/geogebra/geogebraConstructor.d.ts +2 -0
  102. package/lib/geogebra/geogebraConstructor.d.ts.map +1 -1
  103. package/lib/geogebra/geogebraConstructor.js +6 -0
  104. package/lib/index.d.ts +178 -5
  105. package/lib/index.d.ts.map +1 -1
  106. package/lib/math/geometry/point.d.ts +6 -0
  107. package/lib/math/geometry/point.d.ts.map +1 -1
  108. package/lib/math/geometry/point.js +28 -0
  109. package/lib/tree/nodes/equations/equalNode.d.ts +1 -1
  110. package/lib/tree/nodes/equations/equalNode.d.ts.map +1 -1
  111. package/lib/tree/nodes/equations/equalNode.js +0 -1
  112. package/lib/tree/utilities/nodeSimplifier.d.ts +1 -1
  113. package/lib/utils/arrays/arrayZip.d.ts +2 -0
  114. package/lib/utils/arrays/arrayZip.d.ts.map +1 -0
  115. package/lib/utils/arrays/arrayZip.js +12 -0
  116. package/package.json +1 -1
@@ -0,0 +1,1089 @@
1
+ import { shuffleProps, addValidProp, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
2
+ import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
3
+ import { blueMain, greenMain, orange, pinkMain, purpleMain, red, } from "../../../../geogebra/colors.js";
4
+ import { GeogebraConstructor } from "../../../../geogebra/geogebraConstructor.js";
5
+ import { Point } from "../../../../math/geometry/point.js";
6
+ import { Segment } from "../../../../math/geometry/segment.js";
7
+ import { Vector, VectorConstructor } from "../../../../math/geometry/vector.js";
8
+ import { randint } from "../../../../math/utils/random/randint.js";
9
+ import { round } from "../../../../math/utils/round.js";
10
+ import { tan } from "../../../../tree/nodes/functions/tanNode.js";
11
+ import { PiNode } from "../../../../tree/nodes/numbers/piNode.js";
12
+ import { add } from "../../../../tree/nodes/operators/addNode.js";
13
+ import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
14
+ import { multiply } from "../../../../tree/nodes/operators/multiplyNode.js";
15
+ import { substract } from "../../../../tree/nodes/operators/substractNode.js";
16
+ import { random, randomMany } from "../../../../utils/alea/random.js";
17
+ import { zip } from "../../../../utils/arrays/arrayZip.js";
18
+ import { arrayRotation } from "../../../../utils/arrays/rotation.js";
19
+ const colors = [greenMain, orange, blueMain, pinkMain, purpleMain, red];
20
+ const rectangleGGBCommands = (iRect, coordsTL, lengthTopSide, lengthLeftSide, styles) => {
21
+ const [x, y] = coordsTL;
22
+ const pointTL = new Point(`P0_${iRect}`, x, y);
23
+ const pointTR = new Point(`P1_${iRect}`, add(pointTL.x, lengthTopSide).evaluate(), pointTL.y);
24
+ const pointBL = new Point(`P2_${iRect}`, pointTL.x, substract(pointTL.y, lengthLeftSide).evaluate());
25
+ const pointBR = new Point(`P3_${iRect}`, pointTR.x, pointBL.y);
26
+ const segmentTop = new Segment(pointTL, pointTR);
27
+ const segmentRight = new Segment(pointTR, pointBR);
28
+ const segmentBottom = new Segment(pointBR, pointBL);
29
+ const segmentLeft = new Segment(pointBL, pointTL);
30
+ const commands = [
31
+ //create points
32
+ ...[pointTL, pointTR, pointBR, pointBL].flatMap((point) => {
33
+ return [
34
+ `${point.name} = ${point.toMathString()}`,
35
+ `SetVisibleInView(${point.name}, 1, false)`,
36
+ ];
37
+ }),
38
+ //create segments
39
+ ...[segmentTop, segmentRight, segmentBottom, segmentLeft].flatMap((segment, i) => [
40
+ ...segment.toGGBCommands(false, {
41
+ isFixed: true,
42
+ showLabel: false,
43
+ showLength: false,
44
+ style: styles[i][1] === 1 ? 2 : 0,
45
+ }),
46
+ `SetColor(${segment.ggbName}, "${colors[styles[i][0]]}")`,
47
+ ]),
48
+ ];
49
+ return commands;
50
+ };
51
+ const createVector = (from, to, name, precision = 5) => {
52
+ return new Vector(name, round(substract(to.x, from.x).evaluate(), precision).toTree(), round(substract(to.y, from.y).evaluate(), precision).toTree());
53
+ };
54
+ const createPoint = (x, y, name, precision = 5) => {
55
+ return new Point(name, round(x, precision), round(y, precision));
56
+ };
57
+ const rotatePoint = (target, angle, center, name, precision = 2) => {
58
+ const vSrc = createVector(center, target, "vSrc", precision);
59
+ const vRotated = vSrc.rotate(angle, "vRotated");
60
+ return createPoint(add(center.x, vRotated.x).evaluate(), add(center.y, vRotated.y).evaluate(), name, precision);
61
+ };
62
+ const regularPolygonPoints = (iObj, segmentBase, nbSides) => {
63
+ const nodeApotheme = frac(segmentBase.getLength(), multiply(2, tan(frac(PiNode, nbSides))));
64
+ const vecAB = VectorConstructor.fromPoints(segmentBase.pointA, segmentBase.pointB);
65
+ const vecOrth = vecAB.getOrthogonal();
66
+ const vecOrthUnit = vecOrth.times(frac(1, vecOrth.getNorm()));
67
+ const pointCenter = vecOrthUnit
68
+ .times(nodeApotheme)
69
+ .getEndPoint(segmentBase.getMidpoint());
70
+ const angleBase = frac(multiply(2, PiNode), nbSides).evaluate();
71
+ const points = [...Array(nbSides).keys()].map((i) => {
72
+ return rotatePoint(segmentBase.pointA, i * angleBase, pointCenter, `P_${iObj}_${i}`, 5);
73
+ });
74
+ return points;
75
+ };
76
+ const regularPolygonGGBCommands = (iObj, coordsBase, nbSides, styles) => {
77
+ const pointA = new Point("A", coordsBase[0][0], coordsBase[0][1]);
78
+ const pointB = new Point("B", coordsBase[1][0], coordsBase[1][1]);
79
+ const segmentBase = new Segment(pointA, pointB);
80
+ const points = regularPolygonPoints(iObj, segmentBase, nbSides);
81
+ const segments = zip(points, arrayRotation(points, 1)).map(([p1, p2]) => new Segment(p1, p2));
82
+ const commands = [
83
+ //create points
84
+ ...points.flatMap((point) => {
85
+ return [
86
+ `${point.name} = ${point.toMathString()}`,
87
+ `SetVisibleInView(${point.name}, 1, false)`,
88
+ ];
89
+ }),
90
+ //create segments
91
+ ...segments.flatMap((segment, i) => [
92
+ ...segment.toGGBCommands(false, {
93
+ isFixed: true,
94
+ showLabel: false,
95
+ showLength: false,
96
+ style: styles[i][1] === 1 ? 2 : 0,
97
+ }),
98
+ `SetColor(${segment.ggbName}, "${colors[styles[i][0]]}")`,
99
+ ]),
100
+ ];
101
+ return commands;
102
+ };
103
+ const trianglePoints = (iObj, segmentBase, height) => {
104
+ const vecAB = VectorConstructor.fromPoints(segmentBase.pointA, segmentBase.pointB);
105
+ const vecOrth = vecAB.getOrthogonal();
106
+ const vecOrthUnit = vecOrth.times(frac(1, vecOrth.getNorm()));
107
+ const pointTop = vecOrthUnit
108
+ .times(height.toTree())
109
+ .getEndPoint(segmentBase.getMidpoint(), `P_${iObj}_2`);
110
+ const pointTopEvaluated = new Point(pointTop.name, pointTop.x.evaluate(), pointTop.y.evaluate());
111
+ const points = [segmentBase.pointA, segmentBase.pointB, pointTopEvaluated];
112
+ return points;
113
+ };
114
+ const triangleGGBCommands = (iObj, coordsBase, height, styles) => {
115
+ const pointA = new Point(`P_${iObj}_0`, coordsBase[0][0], coordsBase[0][1]);
116
+ const pointB = new Point(`P_${iObj}_1`, coordsBase[1][0], coordsBase[1][1]);
117
+ const segmentBase = new Segment(pointA, pointB);
118
+ const points = trianglePoints(iObj, segmentBase, height);
119
+ const segments = zip(points, arrayRotation(points, 1)).map(([p1, p2]) => new Segment(p1, p2));
120
+ const commands = [
121
+ //create points
122
+ ...points.flatMap((point) => {
123
+ return [
124
+ `${point.name} = ${point.toMathString()}`,
125
+ `SetVisibleInView(${point.name}, 1, false)`,
126
+ ];
127
+ }),
128
+ //create segments
129
+ ...segments.flatMap((segment, i) => [
130
+ ...segment.toGGBCommands(false, {
131
+ isFixed: true,
132
+ showLabel: false,
133
+ showLength: false,
134
+ style: styles[i][1] === 1 ? 2 : 0,
135
+ }),
136
+ `SetColor(${segment.ggbName}, "${colors[styles[i][0]]}")`,
137
+ ]),
138
+ ];
139
+ return commands;
140
+ };
141
+ const ggbCommandRectangularPrismPattern = (indexPattern, L, l, h) => {
142
+ switch (indexPattern) {
143
+ case 0:
144
+ {
145
+ return [
146
+ //top row
147
+ ...rectangleGGBCommands(0, [2 * L + h, 0], h, L, [
148
+ [2, 0],
149
+ [0, 0],
150
+ [2, 1],
151
+ [0, 0],
152
+ ]),
153
+ //mid row
154
+ ...rectangleGGBCommands(1, [0, -L], L, l, [
155
+ [0, 0],
156
+ [1, 1],
157
+ [0, 0],
158
+ [1, 0],
159
+ ]),
160
+ ...rectangleGGBCommands(2, [L, -L], h, l, [
161
+ [2, 0],
162
+ [1, 1],
163
+ [2, 0],
164
+ [1, 1],
165
+ ]),
166
+ ...rectangleGGBCommands(3, [L + h, -L], L, l, [
167
+ [0, 0],
168
+ [1, 1],
169
+ [0, 0],
170
+ [1, 1],
171
+ ]),
172
+ ...rectangleGGBCommands(4, [2 * L + h, -L], h, l, [
173
+ [2, 1],
174
+ [1, 0],
175
+ [2, 1],
176
+ [1, 1],
177
+ ]),
178
+ //bottom row
179
+ ...rectangleGGBCommands(5, [2 * L + h, -L - l], h, L, [
180
+ [2, 1],
181
+ [0, 0],
182
+ [2, 0],
183
+ [0, 0],
184
+ ]),
185
+ ];
186
+ }
187
+ break;
188
+ case 1:
189
+ {
190
+ return [
191
+ //top row
192
+ ...rectangleGGBCommands(0, [2 * L + h, 0], h, L, [
193
+ [2, 0],
194
+ [0, 0],
195
+ [2, 1],
196
+ [0, 0],
197
+ ]),
198
+ //mid row
199
+ ...rectangleGGBCommands(1, [0, -L], L, l, [
200
+ [0, 0],
201
+ [1, 1],
202
+ [0, 0],
203
+ [1, 0],
204
+ ]),
205
+ ...rectangleGGBCommands(2, [L, -L], h, l, [
206
+ [2, 0],
207
+ [1, 1],
208
+ [2, 0],
209
+ [1, 1],
210
+ ]),
211
+ ...rectangleGGBCommands(3, [L + h, -L], L, l, [
212
+ [0, 0],
213
+ [1, 1],
214
+ [0, 1],
215
+ [1, 1],
216
+ ]),
217
+ ...rectangleGGBCommands(4, [2 * L + h, -L], h, l, [
218
+ [2, 1],
219
+ [1, 0],
220
+ [2, 0],
221
+ [1, 1],
222
+ ]),
223
+ //bottom row
224
+ ...rectangleGGBCommands(5, [L + h, -L - l], L, h, [
225
+ [0, 1],
226
+ [2, 0],
227
+ [0, 0],
228
+ [2, 0],
229
+ ]),
230
+ ];
231
+ }
232
+ break;
233
+ case 2:
234
+ {
235
+ return [
236
+ //top row
237
+ ...rectangleGGBCommands(0, [2 * L + h, 0], h, L, [
238
+ [2, 0],
239
+ [0, 0],
240
+ [2, 1],
241
+ [0, 0],
242
+ ]),
243
+ //mid row
244
+ ...rectangleGGBCommands(1, [0, -L], L, l, [
245
+ [0, 0],
246
+ [1, 1],
247
+ [0, 0],
248
+ [1, 0],
249
+ ]),
250
+ ...rectangleGGBCommands(2, [L, -L], h, l, [
251
+ [2, 0],
252
+ [1, 1],
253
+ [2, 1],
254
+ [1, 1],
255
+ ]),
256
+ ...rectangleGGBCommands(3, [L + h, -L], L, l, [
257
+ [0, 0],
258
+ [1, 1],
259
+ [0, 0],
260
+ [1, 1],
261
+ ]),
262
+ ...rectangleGGBCommands(4, [2 * L + h, -L], h, l, [
263
+ [2, 1],
264
+ [1, 0],
265
+ [2, 0],
266
+ [1, 1],
267
+ ]),
268
+ //bottom row
269
+ ...rectangleGGBCommands(5, [L, -L - l], h, L, [
270
+ [2, 1],
271
+ [0, 0],
272
+ [2, 0],
273
+ [0, 0],
274
+ ]),
275
+ ];
276
+ }
277
+ break;
278
+ case 3:
279
+ {
280
+ return [
281
+ //top row
282
+ ...rectangleGGBCommands(0, [2 * L + h, 0], h, L, [
283
+ [2, 0],
284
+ [0, 0],
285
+ [2, 1],
286
+ [0, 0],
287
+ ]),
288
+ //mid row
289
+ ...rectangleGGBCommands(1, [0, -L], L, l, [
290
+ [0, 0],
291
+ [1, 1],
292
+ [0, 1],
293
+ [1, 0],
294
+ ]),
295
+ ...rectangleGGBCommands(2, [L, -L], h, l, [
296
+ [2, 0],
297
+ [1, 1],
298
+ [2, 0],
299
+ [1, 1],
300
+ ]),
301
+ ...rectangleGGBCommands(3, [L + h, -L], L, l, [
302
+ [0, 0],
303
+ [1, 1],
304
+ [0, 0],
305
+ [1, 1],
306
+ ]),
307
+ ...rectangleGGBCommands(4, [2 * L + h, -L], h, l, [
308
+ [2, 1],
309
+ [1, 0],
310
+ [2, 0],
311
+ [1, 1],
312
+ ]),
313
+ //bottom row
314
+ ...rectangleGGBCommands(5, [0, -L - l], L, h, [
315
+ [0, 1],
316
+ [2, 0],
317
+ [0, 0],
318
+ [2, 0],
319
+ ]),
320
+ ];
321
+ }
322
+ break;
323
+ case 4:
324
+ {
325
+ return [
326
+ //top row
327
+ ...rectangleGGBCommands(0, [L + h, -(L - h)], L, h, [
328
+ [0, 0],
329
+ [2, 0],
330
+ [0, 1],
331
+ [2, 0],
332
+ ]),
333
+ //mid row
334
+ ...rectangleGGBCommands(1, [0, -L], L, l, [
335
+ [0, 0],
336
+ [1, 1],
337
+ [0, 0],
338
+ [1, 0],
339
+ ]),
340
+ ...rectangleGGBCommands(2, [L, -L], h, l, [
341
+ [2, 0],
342
+ [1, 1],
343
+ [2, 0],
344
+ [1, 1],
345
+ ]),
346
+ ...rectangleGGBCommands(3, [L + h, -L], L, l, [
347
+ [0, 1],
348
+ [1, 1],
349
+ [0, 1],
350
+ [1, 1],
351
+ ]),
352
+ ...rectangleGGBCommands(4, [2 * L + h, -L], h, l, [
353
+ [2, 0],
354
+ [1, 0],
355
+ [2, 0],
356
+ [1, 1],
357
+ ]),
358
+ //bottom row
359
+ ...rectangleGGBCommands(5, [L + h, -L - l], L, h, [
360
+ [0, 1],
361
+ [2, 0],
362
+ [0, 0],
363
+ [2, 0],
364
+ ]),
365
+ ];
366
+ }
367
+ break;
368
+ case 5:
369
+ {
370
+ return [
371
+ //top row
372
+ ...rectangleGGBCommands(0, [L + h, -(L - h)], L, h, [
373
+ [0, 0],
374
+ [2, 0],
375
+ [0, 1],
376
+ [2, 0],
377
+ ]),
378
+ //mid row
379
+ ...rectangleGGBCommands(1, [0, -L], L, l, [
380
+ [0, 0],
381
+ [1, 1],
382
+ [0, 0],
383
+ [1, 0],
384
+ ]),
385
+ ...rectangleGGBCommands(2, [L, -L], h, l, [
386
+ [2, 0],
387
+ [1, 1],
388
+ [2, 0],
389
+ [1, 1],
390
+ ]),
391
+ ...rectangleGGBCommands(3, [L + h, -L], L, l, [
392
+ [0, 0],
393
+ [1, 1],
394
+ [0, 0],
395
+ [1, 1],
396
+ ]),
397
+ ...rectangleGGBCommands(4, [2 * L + h, -L], h, l, [
398
+ [2, 0],
399
+ [1, 0],
400
+ [2, 0],
401
+ [1, 1],
402
+ ]),
403
+ //bottom row
404
+ ...rectangleGGBCommands(5, [L, -L - l], h, L, [
405
+ [2, 1],
406
+ [0, 0],
407
+ [2, 0],
408
+ [0, 0],
409
+ ]),
410
+ ];
411
+ }
412
+ break;
413
+ case 6:
414
+ {
415
+ return [
416
+ //top row
417
+ ...rectangleGGBCommands(0, [2 * L + h, 0], h, L, [
418
+ [2, 0],
419
+ [0, 0],
420
+ [2, 1],
421
+ [0, 0],
422
+ ]),
423
+ //mid row
424
+ ...rectangleGGBCommands(1, [L, -L], h, l, [
425
+ [2, 0],
426
+ [1, 1],
427
+ [2, 0],
428
+ [1, 0],
429
+ ]),
430
+ ...rectangleGGBCommands(2, [L + h, -L], L, l, [
431
+ [0, 0],
432
+ [1, 1],
433
+ [0, 0],
434
+ [1, 1],
435
+ ]),
436
+ ...rectangleGGBCommands(3, [2 * L + h, -L], h, l, [
437
+ [2, 1],
438
+ [1, 0],
439
+ [2, 0],
440
+ [1, 1],
441
+ ]),
442
+ //bottom row
443
+ ...rectangleGGBCommands(4, [L - l, -L - l], l, L, [
444
+ [1, 0],
445
+ [0, 1],
446
+ [1, 0],
447
+ [0, 0],
448
+ ]),
449
+ ...rectangleGGBCommands(5, [L, -L - l], h, L, [
450
+ [2, 1],
451
+ [0, 0],
452
+ [2, 0],
453
+ [0, 1],
454
+ ]),
455
+ ];
456
+ }
457
+ break;
458
+ case 7:
459
+ {
460
+ return [
461
+ //top row
462
+ ...rectangleGGBCommands(0, [L + h, -(L - h)], L, h, [
463
+ [0, 0],
464
+ [2, 0],
465
+ [0, 1],
466
+ [2, 0],
467
+ ]),
468
+ //mid row
469
+ ...rectangleGGBCommands(1, [0, -L], L, l, [
470
+ [0, 0],
471
+ [1, 1],
472
+ [0, 0],
473
+ [1, 0],
474
+ ]),
475
+ ...rectangleGGBCommands(2, [L, -L], h, l, [
476
+ [2, 0],
477
+ [1, 1],
478
+ [2, 0],
479
+ [1, 1],
480
+ ]),
481
+ ...rectangleGGBCommands(3, [L + h, -L], L, l, [
482
+ [0, 1],
483
+ [1, 0],
484
+ [0, 1],
485
+ [1, 1],
486
+ ]),
487
+ //bottom row
488
+ ...rectangleGGBCommands(4, [L + h, -L - l], L, h, [
489
+ [0, 1],
490
+ [2, 1],
491
+ [0, 0],
492
+ [2, 0],
493
+ ]),
494
+ ...rectangleGGBCommands(5, [2 * L + h, -L - l], l, h, [
495
+ [1, 0],
496
+ [2, 0],
497
+ [1, 0],
498
+ [2, 1],
499
+ ]),
500
+ ];
501
+ }
502
+ break;
503
+ case 8:
504
+ {
505
+ return [
506
+ //top row
507
+ ...rectangleGGBCommands(0, [L + h, -(L - h)], L, h, [
508
+ [0, 0],
509
+ [2, 0],
510
+ [0, 1],
511
+ [2, 0],
512
+ ]),
513
+ //mid row
514
+ ...rectangleGGBCommands(1, [L, -L], h, l, [
515
+ [2, 0],
516
+ [1, 1],
517
+ [2, 1],
518
+ [1, 0],
519
+ ]),
520
+ ...rectangleGGBCommands(2, [L + h, -L], L, l, [
521
+ [0, 1],
522
+ [1, 1],
523
+ [0, 0],
524
+ [1, 1],
525
+ ]),
526
+ ...rectangleGGBCommands(3, [2 * L + h, -L], h, l, [
527
+ [2, 0],
528
+ [1, 0],
529
+ [2, 0],
530
+ [1, 1],
531
+ ]),
532
+ //bottom row
533
+ ...rectangleGGBCommands(4, [L - l, -L - l], l, L, [
534
+ [1, 0],
535
+ [0, 1],
536
+ [1, 0],
537
+ [0, 0],
538
+ ]),
539
+ ...rectangleGGBCommands(5, [L, -L - l], h, L, [
540
+ [2, 1],
541
+ [0, 0],
542
+ [2, 0],
543
+ [0, 1],
544
+ ]),
545
+ ];
546
+ }
547
+ break;
548
+ case 9:
549
+ {
550
+ return [
551
+ //top row
552
+ ...rectangleGGBCommands(0, [L + h, -(L - h)], L, h, [
553
+ [0, 0],
554
+ [2, 1],
555
+ [0, 1],
556
+ [2, 0],
557
+ ]),
558
+ ...rectangleGGBCommands(1, [2 * L + h, -(L - h)], l, h, [
559
+ [1, 0],
560
+ [2, 0],
561
+ [1, 0],
562
+ [2, 1],
563
+ ]),
564
+ //mid row
565
+ ...rectangleGGBCommands(2, [L, -L], h, l, [
566
+ [2, 0],
567
+ [1, 1],
568
+ [2, 1],
569
+ [1, 0],
570
+ ]),
571
+ ...rectangleGGBCommands(3, [L + h, -L], L, l, [
572
+ [0, 1],
573
+ [1, 0],
574
+ [0, 0],
575
+ [1, 1],
576
+ ]),
577
+ //bottom row
578
+ ...rectangleGGBCommands(4, [L - l, -L - l], l, L, [
579
+ [1, 0],
580
+ [0, 1],
581
+ [1, 0],
582
+ [0, 0],
583
+ ]),
584
+ ...rectangleGGBCommands(5, [L, -L - l], h, L, [
585
+ [2, 1],
586
+ [0, 0],
587
+ [2, 0],
588
+ [0, 1],
589
+ ]),
590
+ ];
591
+ }
592
+ break;
593
+ case 10:
594
+ {
595
+ return [
596
+ //top row
597
+ ...rectangleGGBCommands(0, [L + h, -(L - h)], L, h, [
598
+ [0, 0],
599
+ [2, 1],
600
+ [0, 1],
601
+ [2, 0],
602
+ ]),
603
+ ...rectangleGGBCommands(1, [2 * L + h, -(L - h)], l, h, [
604
+ [1, 0],
605
+ [2, 1],
606
+ [1, 0],
607
+ [2, 1],
608
+ ]),
609
+ ...rectangleGGBCommands(2, [2 * L + h + l, -(L - h)], L, h, [
610
+ [0, 0],
611
+ [2, 0],
612
+ [0, 0],
613
+ [2, 1],
614
+ ]),
615
+ //mid row
616
+ ...rectangleGGBCommands(3, [0, -L], L, l, [
617
+ [0, 0],
618
+ [1, 1],
619
+ [0, 0],
620
+ [1, 0],
621
+ ]),
622
+ ...rectangleGGBCommands(4, [L, -L], h, l, [
623
+ [2, 0],
624
+ [1, 1],
625
+ [2, 0],
626
+ [1, 1],
627
+ ]),
628
+ ...rectangleGGBCommands(5, [L + h, -L], L, l, [
629
+ [0, 1],
630
+ [1, 0],
631
+ [0, 0],
632
+ [1, 1],
633
+ ]),
634
+ //bottom row
635
+ //nothing
636
+ ];
637
+ }
638
+ break;
639
+ default:
640
+ throw new Error("Unsupported indexPattern: " + indexPattern);
641
+ }
642
+ };
643
+ const boundingCoordsRectangularPrismPattern = (indexPattern, L, l, h) => {
644
+ switch (indexPattern) {
645
+ case 0:
646
+ case 2:
647
+ return {
648
+ xMin: 0,
649
+ yMax: 0,
650
+ xMax: L + h + L + h,
651
+ yMin: -(L + l + L),
652
+ };
653
+ case 1:
654
+ case 3:
655
+ return {
656
+ xMin: 0,
657
+ yMax: 0,
658
+ xMax: L + h + L + h,
659
+ yMin: -(L + l + h),
660
+ };
661
+ case 4:
662
+ return {
663
+ xMin: 0,
664
+ yMax: -(L - h),
665
+ xMax: L + h + L + h,
666
+ yMin: -(L + l + h),
667
+ };
668
+ case 5:
669
+ return {
670
+ xMin: 0,
671
+ yMax: -(L - h),
672
+ xMax: L + h + L + h,
673
+ yMin: -(L + l + L),
674
+ };
675
+ case 6:
676
+ return {
677
+ xMin: L - l,
678
+ yMax: 0,
679
+ xMax: L + h + L + h,
680
+ yMin: -(L + l + L),
681
+ };
682
+ case 7:
683
+ return {
684
+ xMin: 0,
685
+ yMax: -(L - h),
686
+ xMax: L + h + L + l,
687
+ yMin: -(L + l + h),
688
+ };
689
+ case 8:
690
+ return {
691
+ xMin: L - l,
692
+ yMax: -(L - h),
693
+ xMax: L + h + L + h,
694
+ yMin: -(L + l + L),
695
+ };
696
+ case 9:
697
+ return {
698
+ xMin: L - l,
699
+ yMax: -(L - h),
700
+ xMax: L + h + L + l,
701
+ yMin: -(L + l + L),
702
+ };
703
+ case 10:
704
+ return {
705
+ xMin: 0,
706
+ yMax: -(L - h),
707
+ xMax: L + h + L + l + L,
708
+ yMin: -(L + l),
709
+ };
710
+ default:
711
+ throw new Error("Unsupported indexPattern: " + indexPattern);
712
+ }
713
+ };
714
+ const ggbCommandPrismFromRegularPolygonPattern = (
715
+ // indexPattern: number,
716
+ nbSides, l, h) => {
717
+ const ySpan = (() => {
718
+ const pointA = new Point("A", l, 0);
719
+ const pointB = new Point("B", 0, 0);
720
+ const segmentBase = new Segment(pointA, pointB);
721
+ const points = regularPolygonPoints(0, segmentBase, nbSides);
722
+ const ySpan = Math.max(...points.map((point) => point.y.evaluate()));
723
+ return ySpan;
724
+ })();
725
+ return [
726
+ //top row
727
+ ...regularPolygonGGBCommands(0, [
728
+ [l + l, -ySpan],
729
+ [l, -ySpan],
730
+ ], nbSides, [...[...Array(nbSides - 1).keys()].map(() => [0, 0]), [0, 1]]),
731
+ //mid row
732
+ ...rectangleGGBCommands(1, [0, -ySpan], l, h, [
733
+ [0, 0],
734
+ [1, 1],
735
+ [0, 0],
736
+ [1, 0],
737
+ ]),
738
+ ...rectangleGGBCommands(2, [l, -ySpan], l, h, [
739
+ [0, 1],
740
+ [1, 1],
741
+ [0, 0],
742
+ [1, 1],
743
+ ]),
744
+ ...[...Array(nbSides - 3).keys()]
745
+ .map((i) => i + 3)
746
+ .flatMap((i) => rectangleGGBCommands(i, [(i - 1) * l, -ySpan], l, h, [
747
+ [0, 0],
748
+ [1, 1],
749
+ [0, 0],
750
+ [1, 1],
751
+ ])),
752
+ ...rectangleGGBCommands(nbSides, [(nbSides - 1) * l, -ySpan], l, h, [
753
+ [0, 0],
754
+ [1, 0],
755
+ [0, 0],
756
+ [1, 1],
757
+ ]),
758
+ //bottom row
759
+ ...regularPolygonGGBCommands(nbSides + 1, [
760
+ [l, -ySpan - h],
761
+ [l + l, -ySpan - h],
762
+ ], nbSides, [...[...Array(nbSides - 1).keys()].map(() => [0, 0]), [0, 1]]),
763
+ ];
764
+ };
765
+ const boundingCoordsPrismFromRegularPolygonPattern = (
766
+ // indexPattern: number,
767
+ nbSides, l, h) => {
768
+ const ySpan = (() => {
769
+ const pointA = new Point("A", l, 0);
770
+ const pointB = new Point("B", 0, 0);
771
+ const segmentBase = new Segment(pointA, pointB);
772
+ const points = regularPolygonPoints(0, segmentBase, nbSides);
773
+ const ySpan = Math.max(...points.map((point) => point.y.evaluate()));
774
+ return ySpan;
775
+ })();
776
+ return {
777
+ xMin: 0,
778
+ yMax: 0,
779
+ xMax: nbSides * l,
780
+ yMin: -(2 * ySpan + h),
781
+ };
782
+ };
783
+ const ggbCommandPyramidFromRegularPolygonPattern = (
784
+ // indexPattern: number,
785
+ nbSides, l, h) => {
786
+ return [
787
+ //center
788
+ ...regularPolygonGGBCommands(0, [
789
+ [l + l, 0],
790
+ [l, 0],
791
+ ], nbSides, [...Array(nbSides).keys()].map(() => [0, 1])),
792
+ //ring
793
+ ...(() => {
794
+ const pointA = new Point("A", l + l, 0);
795
+ const pointB = new Point("B", l, 0);
796
+ const segmentBase = new Segment(pointA, pointB);
797
+ const points = regularPolygonPoints(0, segmentBase, nbSides);
798
+ const segments = zip(points, arrayRotation(points, 1)).map(([p1, p2]) => new Segment(p1, p2));
799
+ return segments.flatMap((segment, i) => {
800
+ const coordsBase = [segment.pointA, segment.pointB].map((point) => [
801
+ point.x.evaluate(),
802
+ point.y.evaluate(),
803
+ ]);
804
+ return triangleGGBCommands(i + 1, coordsBase, h, [
805
+ [0, 1],
806
+ [1, 0],
807
+ [1, 0],
808
+ ]);
809
+ });
810
+ })(),
811
+ ];
812
+ };
813
+ const boundingCoordsPyramidFromRegularPolygonPattern = (
814
+ // indexPattern: number,
815
+ nbSides, l, h) => {
816
+ //ugly
817
+ const pointA = new Point("A", l + l, 0);
818
+ const pointB = new Point("B", l, 0);
819
+ const segmentBase = new Segment(pointA, pointB);
820
+ const points = regularPolygonPoints(0, segmentBase, nbSides);
821
+ const segments = zip(points, arrayRotation(points, 1)).map(([p1, p2]) => new Segment(p1, p2));
822
+ const pointsTriangle = segments.flatMap((segment, i) => {
823
+ return trianglePoints(i + 1, segment, h);
824
+ });
825
+ const arrXSorted = pointsTriangle
826
+ .map((point) => point.x.evaluate())
827
+ .toSorted((x1, x2) => x1 - x2);
828
+ const arrYSorted = pointsTriangle
829
+ .map((point) => point.y.evaluate())
830
+ .toSorted((y1, y2) => y1 - y2);
831
+ return {
832
+ xMin: arrXSorted[0],
833
+ xMax: arrXSorted[arrXSorted.length - 1],
834
+ yMin: arrYSorted[0],
835
+ yMax: arrYSorted[arrYSorted.length - 1],
836
+ };
837
+ };
838
+ const ggbCommandCylinderPattern = (
839
+ // indexPattern: number,
840
+ l, h) => {
841
+ const w = 2 * PiNode.evaluate() * l;
842
+ return [
843
+ //top
844
+ `C_0 = Circle((${w / 2},${-l}),${l})`,
845
+ `SetColor(C_0, "${colors[0]}")`,
846
+ //mid
847
+ ...rectangleGGBCommands(1, [0, -l - l], w, h, [...Array(4).keys()].map((i) => (i % 2 === 0 ? [1, 0] : [2, 0]))),
848
+ //bottom
849
+ `C_2 = Circle((${w / 2},${-l - l - h - l}),${l})`,
850
+ `SetColor(C_2, "${colors[0]}")`,
851
+ ];
852
+ };
853
+ const boundingCoordsCylinderPattern = (
854
+ // indexPattern: number,
855
+ l, //radius
856
+ h) => {
857
+ return {
858
+ xMin: 0,
859
+ yMax: 0,
860
+ xMax: 2 * PiNode.evaluate() * l,
861
+ yMin: -(4 * l + h),
862
+ };
863
+ };
864
+ const ggbCommandConePattern = (
865
+ // indexPattern: number,
866
+ l, h) => {
867
+ const a = Math.sqrt(l ** 2 + h ** 2); //apothème du cône
868
+ const angleSector = (l / a) * 2 * PiNode.evaluate();
869
+ const angleRest = 2 * PiNode.evaluate() - angleSector;
870
+ const pointCSCenter = new Point("P_CS_center", l + l / Math.sqrt(2) + a / Math.sqrt(2), -(l + l / Math.sqrt(2) + a / Math.sqrt(2)));
871
+ const pointCSDiag = new Point("P_CS_diag", pointCSCenter.x.evaluate() + a / Math.sqrt(2), pointCSCenter.y.evaluate() - a / Math.sqrt(2));
872
+ const pointCS1 = rotatePoint(pointCSDiag, angleRest / 2, pointCSCenter, "P_CS1");
873
+ const pointCS2 = rotatePoint(pointCSDiag, -angleRest / 2, pointCSCenter, "P_CS2");
874
+ return [
875
+ //top
876
+ `C_0 = Circle((${l},${-l}),${l})`,
877
+ `SetColor(C_0, "${colors[0]}")`,
878
+ //mid
879
+ `CS_1 = CircularSector(${pointCSCenter.toMathString()}, ${pointCS1.toMathString()}, ${pointCS2.toMathString()})`,
880
+ `SetColor(C_0, "${colors[0]}")`,
881
+ ];
882
+ };
883
+ const boundingCoordsConePattern = (
884
+ // indexPattern: number,
885
+ l, //radius
886
+ h) => {
887
+ const a = Math.sqrt(l ** 2 + h ** 2); //apothème du cône
888
+ return {
889
+ xMin: 0,
890
+ yMax: 0,
891
+ xMax: l + l / Math.sqrt(2) + a / Math.sqrt(2) + a,
892
+ yMin: -(l + l / Math.sqrt(2) + a / Math.sqrt(2) + a),
893
+ };
894
+ };
895
+ const patternFamilies = [
896
+ {
897
+ str: "un cube",
898
+ patterns: [...Array(11).keys()].map((indexPattern) => {
899
+ return {
900
+ ggbCommandsFunc: (L, l, h) => ggbCommandRectangularPrismPattern(indexPattern, L, l, h),
901
+ boundingCoordsFunc: (L, l, h) => boundingCoordsRectangularPrismPattern(indexPattern, L, l, h),
902
+ };
903
+ }),
904
+ },
905
+ {
906
+ str: "un pavé droit",
907
+ patterns: [...Array(11).keys()].map((indexPattern) => {
908
+ return {
909
+ ggbCommandsFunc: (L, l, h) => ggbCommandRectangularPrismPattern(indexPattern, L, l, h),
910
+ boundingCoordsFunc: (L, l, h) => boundingCoordsRectangularPrismPattern(indexPattern, L, l, h),
911
+ };
912
+ }),
913
+ },
914
+ {
915
+ str: "un prisme droit de polygone régulier",
916
+ patterns: [...Array(1).keys()].map((_) => {
917
+ return {
918
+ ggbCommandsFunc: (nbSides, l, h) => ggbCommandPrismFromRegularPolygonPattern(
919
+ /*indexPattern,*/ nbSides, l, h),
920
+ boundingCoordsFunc: (nbSides, l, h) => boundingCoordsPrismFromRegularPolygonPattern(
921
+ /*indexPattern,*/ nbSides, l, h),
922
+ };
923
+ }),
924
+ },
925
+ {
926
+ str: "une pyramide régulière",
927
+ patterns: [...Array(1).keys()].map((_) => {
928
+ return {
929
+ ggbCommandsFunc: (nbSides, l, h) => ggbCommandPyramidFromRegularPolygonPattern(
930
+ /*indexPattern,*/ nbSides, l, h),
931
+ boundingCoordsFunc: (nbSides, l, h) => boundingCoordsPyramidFromRegularPolygonPattern(
932
+ /*indexPattern,*/ nbSides, l, h),
933
+ };
934
+ }),
935
+ },
936
+ {
937
+ str: "un cylindre",
938
+ patterns: [...Array(1).keys()].map((_) => {
939
+ return {
940
+ ggbCommandsFunc: (_, l, h) => ggbCommandCylinderPattern(/*indexPattern,*/ l, h),
941
+ boundingCoordsFunc: (_, l, h) => boundingCoordsCylinderPattern(/*indexPattern,*/ l, h),
942
+ };
943
+ }),
944
+ },
945
+ {
946
+ str: "un cône",
947
+ patterns: [...Array(1).keys()].map((_) => {
948
+ return {
949
+ ggbCommandsFunc: (_, l, h) => ggbCommandConePattern(/*indexPattern,*/ l, h),
950
+ boundingCoordsFunc: (_, l, h) => boundingCoordsConePattern(/*indexPattern,*/ l, h),
951
+ };
952
+ }),
953
+ },
954
+ ];
955
+ const getInstruction = () => {
956
+ return `De quel solide la figure ci-dessous est-elle le patron ?`;
957
+ };
958
+ const getAnswer = (identifiers) => {
959
+ const { indexFamily } = identifiers;
960
+ const pattern = patternFamilies[indexFamily];
961
+ return pattern.str;
962
+ };
963
+ const getHint = () => {
964
+ return `Les hachures indiquent les endroits où l'on plie le patron.
965
+ Il n'y a pas de languettes sur les patrons en mathématiques.`;
966
+ };
967
+ const getCorrection = (identifiers) => {
968
+ return `C'est le patron d'${getAnswer(identifiers)}.`;
969
+ };
970
+ const getGGBOptions = (identifiers) => {
971
+ const { indexFamily, indexPattern, L, l, h } = identifiers;
972
+ const patternFamily = patternFamilies[indexFamily];
973
+ const pattern = patternFamily.patterns[indexPattern];
974
+ const commands = [...pattern.ggbCommandsFunc(L, l, h)];
975
+ const ggb = new GeogebraConstructor({
976
+ commands,
977
+ hideAxes: true,
978
+ hideGrid: true,
979
+ });
980
+ return ggb.getOptions({
981
+ coords: ggb.getAdaptedCoords(pattern.boundingCoordsFunc(L, l, h)),
982
+ });
983
+ };
984
+ const getPropositions = (n, { answer, ...identifiers }) => {
985
+ const propositions = [];
986
+ addValidProp(propositions, answer, "raw");
987
+ let arrStrWrong;
988
+ const { indexFamily } = identifiers;
989
+ switch (indexFamily) {
990
+ //avoid multiple possible answers
991
+ case 0:
992
+ case 1:
993
+ {
994
+ arrStrWrong = ["une pyramide régulière", "un cylindre", "un cône"];
995
+ }
996
+ break;
997
+ default:
998
+ {
999
+ arrStrWrong = patternFamilies.map((patternFamily) => patternFamily.str);
1000
+ }
1001
+ break;
1002
+ }
1003
+ arrStrWrong.forEach((str) => {
1004
+ tryToAddWrongProp(propositions, str, "raw");
1005
+ });
1006
+ return shuffleProps(propositions, n);
1007
+ };
1008
+ const getRecognizeSolidFromSolidPatternQuestion = () => {
1009
+ const indexFamily = randint(0, patternFamilies.length);
1010
+ const patternFamily = patternFamilies[indexFamily];
1011
+ const indexPattern = randint(0, patternFamily.patterns.length);
1012
+ let L;
1013
+ let l;
1014
+ let h;
1015
+ switch (indexFamily) {
1016
+ case 0:
1017
+ {
1018
+ L = 5;
1019
+ l = 5;
1020
+ h = 5;
1021
+ }
1022
+ break;
1023
+ case 1:
1024
+ {
1025
+ [L, l, h] = randomMany([...Array(20).keys()].map((i) => i + 5), 3);
1026
+ }
1027
+ break;
1028
+ case 2:
1029
+ {
1030
+ //L is nbSides
1031
+ L = random([3, 5, 6, 7, 8]);
1032
+ [l, h] = randomMany([...Array(20).keys()].map((i) => i + 5), 2);
1033
+ }
1034
+ break;
1035
+ case 3:
1036
+ {
1037
+ //L is nbSides
1038
+ L = random([3, 5, 6, 7, 8]);
1039
+ l = random([...Array(20).keys()].map((i) => i + 5));
1040
+ const nodeApotheme = frac(l, multiply(2, tan(frac(PiNode, L))));
1041
+ const minHAsIntegerSharp = Math.ceil(nodeApotheme.evaluate());
1042
+ const minHAsIntegerForEye = Math.ceil(1.5 * minHAsIntegerSharp);
1043
+ h = randint(minHAsIntegerForEye, 2 * minHAsIntegerForEye);
1044
+ }
1045
+ break;
1046
+ case 4:
1047
+ case 5:
1048
+ {
1049
+ //L is useless
1050
+ L = 0;
1051
+ [l, h] = randomMany([...Array(20).keys()].map((i) => i + 5), 2);
1052
+ }
1053
+ break;
1054
+ default:
1055
+ throw new Error("Unsupported indexFamily: " + indexFamily);
1056
+ }
1057
+ const identifiers = { indexFamily, indexPattern, L, l, h };
1058
+ return getQuestionFromIdentifiers(identifiers);
1059
+ };
1060
+ const getQuestionFromIdentifiers = (identifiers) => {
1061
+ const question = {
1062
+ instruction: getInstruction(identifiers),
1063
+ answer: getAnswer(identifiers),
1064
+ hint: getHint(identifiers),
1065
+ correction: getCorrection(identifiers),
1066
+ ggbOptions: getGGBOptions(identifiers),
1067
+ keys: [],
1068
+ answerFormat: "raw",
1069
+ identifiers,
1070
+ };
1071
+ return question;
1072
+ };
1073
+ export const recognizeSolidFromSolidPattern = {
1074
+ id: "recognizeSolidFromSolidPattern",
1075
+ connector: "=",
1076
+ label: "Nommer un solide à partir de son patron",
1077
+ isSingleStep: true,
1078
+ generator: (nb) => getDistinctQuestions(getRecognizeSolidFromSolidPatternQuestion, nb),
1079
+ qcmTimer: 60,
1080
+ freeTimer: 60,
1081
+ getPropositions,
1082
+ subject: "Mathématiques",
1083
+ getQuestionFromIdentifiers,
1084
+ answerType: "QCU",
1085
+ getHint,
1086
+ getCorrection,
1087
+ hasHintAndCorrection: true,
1088
+ hasGeogebra: true,
1089
+ };