math-exercises 3.0.156 → 3.0.157
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/lib/exercises/math/calcul/proportionality/proportionalityTableCoefficient.js +1 -1
- package/lib/exercises/math/calculLitteral/equation/factorizeEquation.d.ts +4 -1
- package/lib/exercises/math/calculLitteral/equation/factorizeEquation.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/equation/factorizeEquation.js +148 -31
- package/lib/exercises/math/calculLitteral/equation/multiplicationEquation.d.ts +4 -1
- package/lib/exercises/math/calculLitteral/equation/multiplicationEquation.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/equation/multiplicationEquation.js +124 -44
- package/lib/exercises/math/dataRepresentations/halfPieChartCommenting.d.ts.map +1 -1
- package/lib/exercises/math/dataRepresentations/halfPieChartCommenting.js +4 -1
- package/lib/exercises/math/functions/affines/drawAffineFromPointAndLeadingCoeff.d.ts.map +1 -1
- package/lib/exercises/math/functions/affines/drawAffineFromPointAndLeadingCoeff.js +5 -4
- package/lib/exercises/math/functions/linear/linearFromExercise.d.ts.map +1 -1
- package/lib/exercises/math/functions/linear/linearFromExercise.js +4 -3
- package/lib/exercises/math/geometry/euclidian/pinSegmentFromRotation.js +1 -1
- package/lib/exercises/math/geometry/euclidian/recognizeHomothetyCenter.d.ts.map +1 -1
- package/lib/exercises/math/geometry/euclidian/recognizeHomothetyCenter.js +4 -5
- package/lib/exercises/math/geometry/euclidianConstructions/placeHomothetyCenter.js +4 -4
- package/lib/exercises/math/geometry/perimeters/circleCircumference.d.ts.map +1 -1
- package/lib/exercises/math/geometry/perimeters/circleCircumference.js +5 -3
- package/lib/exercises/math/geometry/volumes/parallelepipedVolume.d.ts.map +1 -1
- package/lib/exercises/math/geometry/volumes/parallelepipedVolume.js +18 -5
- package/lib/exercises/math/geometry/volumes/volumeOfPyramidWithSquareOrRectBase.d.ts.map +1 -1
- package/lib/exercises/math/geometry/volumes/volumeOfPyramidWithSquareOrRectBase.js +45 -21
- package/lib/exercises/math/geometry/volumes/volumeOfPyramidWithTriangleBase.d.ts.map +1 -1
- package/lib/exercises/math/geometry/volumes/volumeOfPyramidWithTriangleBase.js +33 -12
- package/lib/exercises/math/geometry/volumes/volumeOfPyramidWithTriangleRectBase.d.ts.map +1 -1
- package/lib/exercises/math/geometry/volumes/volumeOfPyramidWithTriangleRectBase.js +38 -15
- package/lib/exercises/math/percent/findTVA.d.ts.map +1 -1
- package/lib/exercises/math/percent/findTVA.js +17 -11
- package/lib/exercises/math/percent/populationEffectifFromSubPopulation.js +1 -1
- package/lib/exercises/math/probaStat/basicProbas/index.d.ts +1 -0
- package/lib/exercises/math/probaStat/basicProbas/index.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/basicProbas/index.js +1 -1
- package/lib/exercises/math/probaStat/basicProbas/pickEquiprobableSituations.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/basicProbas/pickEquiprobableSituations.js +114 -20
- package/lib/exercises/math/probaStat/basicProbas/pickEquiprobableTo.js +2 -2
- package/lib/exercises/math/probaStat/stats1var/etendueTable.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/stats1var/etendueTable.js +5 -1
- package/lib/exercises/math/probaStat/stats1var/medianWithList.js +1 -1
- package/lib/exercises/math/probaStat/stats1var/medianWithTable.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/stats1var/medianWithTable.js +19 -5
- package/lib/exercises/math/probaStat/stats1var/plausibilityOfAverage.js +1 -1
- package/lib/exercises/math/probaStat/twoStepExperiments/headsOrTailsTwiceOutcomes.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/twoStepExperiments/headsOrTailsTwiceOutcomes.js +34 -29
- package/lib/exercises/math/probaStat/twoStepExperiments/headsOrTailsTwiceProbas.js +3 -3
- package/lib/exercises/math/probaStat/twoStepExperiments/numberPoolTwiceProbas.js +2 -2
- package/lib/exercises/math/probaStat/twoStepExperiments/twoStepExperimentProbas.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/twoStepExperiments/twoStepExperimentProbas.js +18 -10
- package/lib/exercises/math/spaceGeometry/solids/recognizeSolidFromSolidPattern.js +1 -1
- package/lib/exercises/math/spaceGeometry/sphere/index.d.ts +2 -0
- package/lib/exercises/math/spaceGeometry/sphere/index.d.ts.map +1 -1
- package/lib/exercises/math/spaceGeometry/sphere/index.js +3 -1
- package/lib/exercises/math/spaceGeometry/sphere/pinPointLatLon.2d.d.ts +12 -0
- package/lib/exercises/math/spaceGeometry/sphere/pinPointLatLon.2d.d.ts.map +1 -0
- package/lib/exercises/math/spaceGeometry/sphere/pinPointLatLon.2d.js +205 -0
- package/lib/exercises/math/spaceGeometry/sphere/sphereLatLonReading.2d.d.ts +13 -0
- package/lib/exercises/math/spaceGeometry/sphere/sphereLatLonReading.2d.d.ts.map +1 -0
- package/lib/exercises/math/spaceGeometry/sphere/sphereLatLonReading.2d.js +215 -0
- package/lib/exercises/math/spaceGeometry/sphere/sphereLatLonReading.3d.d.ts +14 -0
- package/lib/exercises/math/spaceGeometry/sphere/sphereLatLonReading.3d.d.ts.map +1 -0
- package/lib/exercises/math/spaceGeometry/sphere/sphereLatLonReading.3d.js +390 -0
- package/lib/exercises/math/trigonometry/trigonometrySideCalcul.js +1 -1
- package/lib/exercises/vea/setVEA.d.ts.map +1 -1
- package/lib/exercises/vea/setVEA.js +4 -0
- package/lib/index.d.ts +24 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/utils/arrays/dichoFilter.d.ts +2 -0
- package/lib/utils/arrays/dichoFilter.d.ts.map +1 -0
- package/lib/utils/arrays/dichoFilter.js +11 -0
- package/package.json +1 -1
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { toolBarConstructor } from "../../../../exercises/utils/geogebra/toolBarConstructor.js";
|
|
2
|
+
import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
|
|
3
|
+
import { greenMain, red } from "../../../../geogebra/colors.js";
|
|
4
|
+
import { GeogebraConstructor } from "../../../../geogebra/geogebraConstructor.js";
|
|
5
|
+
import { ggbPointToCoords } from "../../../../geogebra/parsers/ggbPointToCoords.js";
|
|
6
|
+
import { parseGGBPoints } from "../../../../geogebra/parsers/parseGGBPoints.js";
|
|
7
|
+
import { Point, PointConstructor, } from "../../../../math/geometry/point.js";
|
|
8
|
+
import { cos } from "../../../../tree/nodes/functions/cosNode.js";
|
|
9
|
+
import { sin } from "../../../../tree/nodes/functions/sinNode.js";
|
|
10
|
+
import { PiNode } from "../../../../tree/nodes/numbers/piNode.js";
|
|
11
|
+
import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
|
|
12
|
+
import { multiply } from "../../../../tree/nodes/operators/multiplyNode.js";
|
|
13
|
+
import { random, randomMany } from "../../../../utils/alea/random.js";
|
|
14
|
+
import { getCartesiansProducts } from "../../../../utils/arrays/cartesianProducts.js";
|
|
15
|
+
const earthGlobe2DGGBCommands = () => {
|
|
16
|
+
const [pointN, pointS, pointE, pointO] = [
|
|
17
|
+
["N", [0, 1]],
|
|
18
|
+
["S", [0, -1]],
|
|
19
|
+
["E", [1, 0]],
|
|
20
|
+
["O", [-1, 0]],
|
|
21
|
+
].map(([pointName, [x, y]]) => new Point(pointName, x, y));
|
|
22
|
+
return [
|
|
23
|
+
//Greenwich and equator
|
|
24
|
+
...[pointN, pointS, pointE, pointO].flatMap((point) => point.toGGBCommand({
|
|
25
|
+
isFixed: true,
|
|
26
|
+
showLabel: true,
|
|
27
|
+
color: "#000000",
|
|
28
|
+
size: 2,
|
|
29
|
+
})),
|
|
30
|
+
`Seg_greenwich = Segment(S,N)`,
|
|
31
|
+
`SetColor(Seg_greenwich,"${greenMain}")`,
|
|
32
|
+
`Seg_equator = Segment(O,E)`,
|
|
33
|
+
`SetColor(Seg_equator,"${red}")`,
|
|
34
|
+
//labels
|
|
35
|
+
`Lbl_greenwich = Text(RotateText("\\tiny Greenwich", 90°), (-0.05, 0.62), true, true, 0, 0)`,
|
|
36
|
+
`Lbl_equator = Text("\\tiny Équateur", (0.62, 0), true, true, 0, 0)`,
|
|
37
|
+
`Lbl_15_greenwich = Text("\\tiny 15", (0.27, -0.05), true, true, 0, 0)`,
|
|
38
|
+
`SetFixed(Lbl_15_greenwich, true, false)`,
|
|
39
|
+
`Lbl_15_equator = Text("\\tiny 15", (-0.07, 0.27), true, true, 0, 0)`,
|
|
40
|
+
`SetFixed(Lbl_15_equator, true, false)`,
|
|
41
|
+
//curves
|
|
42
|
+
`l1 = Sequence(x² / sin²(λ) + y² = 1, λ, 0, π / 2, π / 12)`,
|
|
43
|
+
`SetColor(l1, "#AAAAAA")`,
|
|
44
|
+
`SetFilling(l1, 0)`,
|
|
45
|
+
`l2 = Sequence(If(x² + sin²(α) ≤ 1, sin(α)), α, (-π) / 2, π / 2, π / 12)`,
|
|
46
|
+
`SetColor(l2,"#AAAAAA")`,
|
|
47
|
+
`SetFilling(l2, 0)`,
|
|
48
|
+
];
|
|
49
|
+
};
|
|
50
|
+
const xyPointForLatLonPoint = (latlonPoint) => {
|
|
51
|
+
const { x: lat, y: lon } = latlonPoint;
|
|
52
|
+
const toRadians = frac(PiNode, 180);
|
|
53
|
+
const phi = multiply(lat, toRadians);
|
|
54
|
+
const lambda = multiply(lon, toRadians);
|
|
55
|
+
const x = multiply(cos(phi), sin(lambda));
|
|
56
|
+
const y = sin(phi);
|
|
57
|
+
return new Point("S", x, y);
|
|
58
|
+
};
|
|
59
|
+
const getStrLatitude = (angleInDegrees) => {
|
|
60
|
+
if (angleInDegrees % 90 === 0) {
|
|
61
|
+
return `${angleInDegrees.frenchify()}°`;
|
|
62
|
+
}
|
|
63
|
+
else if (angleInDegrees < 0) {
|
|
64
|
+
return `${(-angleInDegrees).frenchify()}°S`;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return `${angleInDegrees.frenchify()}°N`;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const getStrLongitude = (angleInDegrees) => {
|
|
71
|
+
if (angleInDegrees % 180 === 0) {
|
|
72
|
+
return `${angleInDegrees.frenchify()}°`;
|
|
73
|
+
}
|
|
74
|
+
else if (angleInDegrees < 0) {
|
|
75
|
+
return `${(-angleInDegrees).frenchify()}°O`;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
return `${angleInDegrees.frenchify()}°E`;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
const getAnswerPoint = (identifiers) => {
|
|
82
|
+
const { namePointTarget, pointsDict } = identifiers;
|
|
83
|
+
const pointDst = PointConstructor.fromIdentifiers(pointsDict[namePointTarget]["2d"]);
|
|
84
|
+
return pointDst;
|
|
85
|
+
};
|
|
86
|
+
const getGGBAnswer = (identifiers) => {
|
|
87
|
+
const { namePointTarget, pointsDict } = identifiers;
|
|
88
|
+
const pointDst = PointConstructor.fromIdentifiers(pointsDict[namePointTarget]["2d"]);
|
|
89
|
+
return [`${pointDst.toMathString()}`];
|
|
90
|
+
};
|
|
91
|
+
const getInstruction = (identifiers) => {
|
|
92
|
+
const { namePointTarget, pointsDict } = identifiers;
|
|
93
|
+
const latLonPoint = PointConstructor.fromIdentifiers(pointsDict[namePointTarget].latLon);
|
|
94
|
+
const [lat, lon] = [latLonPoint.x.evaluate(), latLonPoint.y.evaluate()];
|
|
95
|
+
return `Placer le point $A$ de coordonnées $(${getStrLatitude(lat)};${getStrLongitude(lon)})$ sur la figure ci-dessous.`;
|
|
96
|
+
};
|
|
97
|
+
const getHint = () => {
|
|
98
|
+
return `Pour déterminer la latitude, on utlise les parallèles.
|
|
99
|
+
Pour déterminer la longitude, on utilise les méridiens.`;
|
|
100
|
+
};
|
|
101
|
+
const getCorrection = () => {
|
|
102
|
+
return `La latitude donne la position Nord/Sud.
|
|
103
|
+
La longitude donne la position Est/Ouest.`;
|
|
104
|
+
};
|
|
105
|
+
const getCorrectionGGBOptions = (identifiers) => {
|
|
106
|
+
const { pointsDict } = identifiers;
|
|
107
|
+
const xyPoints = Object.values(pointsDict)
|
|
108
|
+
.map((pointMiniDict) => pointMiniDict["2d"])
|
|
109
|
+
.map((pointIds) => PointConstructor.fromIdentifiers(pointIds));
|
|
110
|
+
const commands = [
|
|
111
|
+
...earthGlobe2DGGBCommands(),
|
|
112
|
+
...xyPoints.flatMap((point) => point.toGGBCommand({
|
|
113
|
+
isFixed: true,
|
|
114
|
+
showLabel: true,
|
|
115
|
+
size: 2,
|
|
116
|
+
color: greenMain,
|
|
117
|
+
})),
|
|
118
|
+
];
|
|
119
|
+
const ggb = new GeogebraConstructor({
|
|
120
|
+
commands,
|
|
121
|
+
hideAxes: true,
|
|
122
|
+
hideGrid: true,
|
|
123
|
+
});
|
|
124
|
+
return ggb.getOptions({
|
|
125
|
+
coords: [-1.1, 1.1, -1.1, 1.1],
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
const getStudentGGBOptions = () => {
|
|
129
|
+
const commands = [...earthGlobe2DGGBCommands()];
|
|
130
|
+
const studentGgb = new GeogebraConstructor({
|
|
131
|
+
customToolBar: toolBarConstructor({
|
|
132
|
+
point: true,
|
|
133
|
+
}),
|
|
134
|
+
commands,
|
|
135
|
+
hideAxes: true,
|
|
136
|
+
hideGrid: true,
|
|
137
|
+
});
|
|
138
|
+
return studentGgb.getOptions({
|
|
139
|
+
coords: [-1.1, 1.1, -1.1, 1.1],
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
const isGGBAnswerValid = (ans, { ggbAnswer, ...identifiers }) => {
|
|
143
|
+
const isPointValid = () => {
|
|
144
|
+
const points = parseGGBPoints(ans)
|
|
145
|
+
.map((p) => ggbPointToCoords(p))
|
|
146
|
+
.map((coords, i) => new Point(`K_${i}`, coords.x, coords.y));
|
|
147
|
+
const answerPoint = getAnswerPoint(identifiers);
|
|
148
|
+
return points.some((point) => point.distanceTo(answerPoint) < 0.1);
|
|
149
|
+
};
|
|
150
|
+
return isPointValid();
|
|
151
|
+
};
|
|
152
|
+
const getPinPointLatLon2dQuestion = () => {
|
|
153
|
+
const letters = ["A"];
|
|
154
|
+
const arrLat = [...Array(9).keys()].map((i) => (i - 4) * 15);
|
|
155
|
+
const arrLon = [...Array(9).keys()].map((i) => (i - 4) * 15);
|
|
156
|
+
//we need student to figure out the correct mapping
|
|
157
|
+
const arrLatLon = getCartesiansProducts([arrLat, arrLon]).filter(([lat, lon]) => lat !== lon && -lat !== lon);
|
|
158
|
+
const pickedLatLon = randomMany(arrLatLon, letters.length);
|
|
159
|
+
const pointsDict = letters.reduce((acc, letter, i) => {
|
|
160
|
+
const [lat, lon] = pickedLatLon[i];
|
|
161
|
+
const latLonPoint = new Point(`${letter}`, lat, lon);
|
|
162
|
+
const xyPoint = xyPointForLatLonPoint(latLonPoint);
|
|
163
|
+
xyPoint.name = letter;
|
|
164
|
+
acc[letter] = {
|
|
165
|
+
latLon: latLonPoint.toIdentifiers(),
|
|
166
|
+
"2d": xyPoint.toIdentifiers(),
|
|
167
|
+
};
|
|
168
|
+
return acc;
|
|
169
|
+
}, {});
|
|
170
|
+
const namePointTarget = random(Object.keys(pointsDict));
|
|
171
|
+
const identifiers = {
|
|
172
|
+
pointsDict,
|
|
173
|
+
namePointTarget,
|
|
174
|
+
};
|
|
175
|
+
return getQuestionFromIdentifiers(identifiers);
|
|
176
|
+
};
|
|
177
|
+
const getQuestionFromIdentifiers = (identifiers) => {
|
|
178
|
+
const question = {
|
|
179
|
+
identifiers,
|
|
180
|
+
instruction: getInstruction(identifiers),
|
|
181
|
+
ggbAnswer: getGGBAnswer(identifiers),
|
|
182
|
+
hint: getHint(identifiers),
|
|
183
|
+
correction: getCorrection(identifiers),
|
|
184
|
+
studentGgbOptions: getStudentGGBOptions(identifiers),
|
|
185
|
+
correctionGgbOptions: getCorrectionGGBOptions(identifiers),
|
|
186
|
+
};
|
|
187
|
+
return question;
|
|
188
|
+
};
|
|
189
|
+
export const pinPointLatLon2d = {
|
|
190
|
+
id: "pinPointLatLon2d",
|
|
191
|
+
label: "Placer un point à partir de sa latitude et de sa longitude",
|
|
192
|
+
isSingleStep: true,
|
|
193
|
+
generator: (nb, opts) => getDistinctQuestions(() => getPinPointLatLon2dQuestion(opts), nb),
|
|
194
|
+
qcmTimer: 60,
|
|
195
|
+
freeTimer: 60,
|
|
196
|
+
getGGBAnswer,
|
|
197
|
+
getStudentGGBOptions,
|
|
198
|
+
isGGBAnswerValid,
|
|
199
|
+
getHint,
|
|
200
|
+
getCorrection,
|
|
201
|
+
hasHintAndCorrection: true,
|
|
202
|
+
subject: "Mathématiques",
|
|
203
|
+
getQuestionFromIdentifiers,
|
|
204
|
+
answerType: "GGB",
|
|
205
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Exercise } from "../../../../exercises/exercise.js";
|
|
2
|
+
import { PointIdentifiers } from "../../../../math/geometry/point.js";
|
|
3
|
+
type Identifiers = {
|
|
4
|
+
pointData: {
|
|
5
|
+
latLon: PointIdentifiers;
|
|
6
|
+
"2d": PointIdentifiers;
|
|
7
|
+
};
|
|
8
|
+
isLatitude: boolean;
|
|
9
|
+
namePointTarget: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const sphereLatLonReading2d: Exercise<Identifiers>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=sphereLatLonReading.2d.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sphereLatLonReading.2d.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/spaceGeometry/sphere/sphereLatLonReading.2d.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAgBT,MAAM,6BAA6B,CAAC;AAIrC,OAAO,EAGL,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAuFtC,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE;QACT,MAAM,EAAE,gBAAgB,CAAC;QACzB,IAAI,EAAE,gBAAgB,CAAC;KACxB,CAAC;IAEF,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AA+KF,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,WAAW,CAgBvD,CAAC"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { addValidProp, shuffleProps, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
|
|
2
|
+
import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
|
|
3
|
+
import { greenMain, red } from "../../../../geogebra/colors.js";
|
|
4
|
+
import { GeogebraConstructor } from "../../../../geogebra/geogebraConstructor.js";
|
|
5
|
+
import { Point, PointConstructor, } from "../../../../math/geometry/point.js";
|
|
6
|
+
import { cos } from "../../../../tree/nodes/functions/cosNode.js";
|
|
7
|
+
import { sin } from "../../../../tree/nodes/functions/sinNode.js";
|
|
8
|
+
import { PiNode } from "../../../../tree/nodes/numbers/piNode.js";
|
|
9
|
+
import { frac } from "../../../../tree/nodes/operators/fractionNode.js";
|
|
10
|
+
import { multiply } from "../../../../tree/nodes/operators/multiplyNode.js";
|
|
11
|
+
import { coinFlip } from "../../../../utils/alea/coinFlip.js";
|
|
12
|
+
import { random, randomMany } from "../../../../utils/alea/random.js";
|
|
13
|
+
import { getCartesiansProducts } from "../../../../utils/arrays/cartesianProducts.js";
|
|
14
|
+
const earthGlobe2DGGBCommands = () => {
|
|
15
|
+
const [pointN, pointS, pointE, pointO] = [
|
|
16
|
+
["N", [0, 1]],
|
|
17
|
+
["S", [0, -1]],
|
|
18
|
+
["E", [1, 0]],
|
|
19
|
+
["O", [-1, 0]],
|
|
20
|
+
].map(([pointName, [x, y]]) => new Point(pointName, x, y));
|
|
21
|
+
return [
|
|
22
|
+
//Greenwich and equator
|
|
23
|
+
...[pointN, pointS, pointE, pointO].flatMap((point) => point.toGGBCommand({
|
|
24
|
+
isFixed: true,
|
|
25
|
+
showLabel: true,
|
|
26
|
+
color: "#000000",
|
|
27
|
+
size: 2,
|
|
28
|
+
})),
|
|
29
|
+
`Seg_greenwich = Segment(S,N)`,
|
|
30
|
+
`SetColor(Seg_greenwich,"${greenMain}")`,
|
|
31
|
+
`SetFixed(Seg_greenwich, true, false)`,
|
|
32
|
+
`Seg_equator = Segment(O,E)`,
|
|
33
|
+
`SetFixed(Seg_equator, true, false)`,
|
|
34
|
+
`SetColor(Seg_equator,"${red}")`,
|
|
35
|
+
//labels
|
|
36
|
+
`Lbl_greenwich = Text(RotateText("\\tiny Greenwich", 90°), (-0.05, 0.62), true, true, 0, 0)`,
|
|
37
|
+
`Lbl_equator = Text("\\tiny Équateur", (0.62, 0), true, true, 0, 0)`,
|
|
38
|
+
`Lbl_15_greenwich = Text("\\tiny 15", (0.27, -0.05), true, true, 0, 0)`,
|
|
39
|
+
`SetFixed(Lbl_15_greenwich, true, false)`,
|
|
40
|
+
`Lbl_15_equator = Text("\\tiny 15", (-0.07, 0.27), true, true, 0, 0)`,
|
|
41
|
+
`SetFixed(Lbl_15_equator, true, false)`,
|
|
42
|
+
//curves
|
|
43
|
+
`l1 = Sequence(x² / sin²(λ) + y² = 1, λ, 0, π / 2, π / 12)`,
|
|
44
|
+
`SetColor(l1, "#AAAAAA")`,
|
|
45
|
+
`SetFilling(l1, 0)`,
|
|
46
|
+
`l2 = Sequence(If(x² + sin²(α) ≤ 1, sin(α)), α, (-π) / 2, π / 2, π / 12)`,
|
|
47
|
+
`SetColor(l2,"#AAAAAA")`,
|
|
48
|
+
`SetFilling(l2, 0)`,
|
|
49
|
+
];
|
|
50
|
+
};
|
|
51
|
+
const xyPointForLatLonPoint = (latlonPoint) => {
|
|
52
|
+
const { x: lat, y: lon } = latlonPoint;
|
|
53
|
+
const toRadians = frac(PiNode, 180);
|
|
54
|
+
const phi = multiply(lat, toRadians);
|
|
55
|
+
const lambda = multiply(lon, toRadians);
|
|
56
|
+
const x = multiply(cos(phi), sin(lambda));
|
|
57
|
+
const y = sin(phi);
|
|
58
|
+
return new Point("S", x, y);
|
|
59
|
+
};
|
|
60
|
+
const getStrLatitude = (angleInDegrees) => {
|
|
61
|
+
if (angleInDegrees % 90 === 0) {
|
|
62
|
+
return `${angleInDegrees.frenchify()}°`;
|
|
63
|
+
}
|
|
64
|
+
else if (angleInDegrees < 0) {
|
|
65
|
+
return `${(-angleInDegrees).frenchify()}°S`;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
return `${angleInDegrees.frenchify()}°N`;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const getStrLongitude = (angleInDegrees) => {
|
|
72
|
+
if (angleInDegrees % 180 === 0) {
|
|
73
|
+
return `${angleInDegrees.frenchify()}°`;
|
|
74
|
+
}
|
|
75
|
+
else if (angleInDegrees < 0) {
|
|
76
|
+
return `${(-angleInDegrees).frenchify()}°O`;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
return `${angleInDegrees.frenchify()}°E`;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const getPropositions = (n, { answer, ...identifiers }) => {
|
|
83
|
+
const { pointData, isLatitude } = identifiers;
|
|
84
|
+
const propositions = [];
|
|
85
|
+
const latLonPoints = PointConstructor.fromIdentifiers(pointData.latLon);
|
|
86
|
+
if (isLatitude) {
|
|
87
|
+
addValidProp(propositions, getStrLatitude(latLonPoints.x.evaluate()));
|
|
88
|
+
tryToAddWrongProp(propositions, getStrLongitude(latLonPoints.y.evaluate()));
|
|
89
|
+
//wrongSign
|
|
90
|
+
tryToAddWrongProp(propositions, getStrLatitude(-latLonPoints.x.evaluate()));
|
|
91
|
+
//madness
|
|
92
|
+
tryToAddWrongProp(propositions, getStrLatitude(latLonPoints.y.evaluate()));
|
|
93
|
+
tryToAddWrongProp(propositions, getStrLatitude(-latLonPoints.y.evaluate()));
|
|
94
|
+
tryToAddWrongProp(propositions, getStrLongitude(latLonPoints.x.evaluate()));
|
|
95
|
+
tryToAddWrongProp(propositions, getStrLongitude(-latLonPoints.x.evaluate()));
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
addValidProp(propositions, getStrLongitude(latLonPoints.y.evaluate()));
|
|
99
|
+
tryToAddWrongProp(propositions, getStrLatitude(latLonPoints.x.evaluate()));
|
|
100
|
+
//wrongSign
|
|
101
|
+
tryToAddWrongProp(propositions, getStrLongitude(-latLonPoints.y.evaluate()));
|
|
102
|
+
//madness
|
|
103
|
+
tryToAddWrongProp(propositions, getStrLongitude(latLonPoints.x.evaluate()));
|
|
104
|
+
tryToAddWrongProp(propositions, getStrLongitude(-latLonPoints.x.evaluate()));
|
|
105
|
+
tryToAddWrongProp(propositions, getStrLatitude(latLonPoints.y.evaluate()));
|
|
106
|
+
tryToAddWrongProp(propositions, getStrLatitude(-latLonPoints.y.evaluate()));
|
|
107
|
+
}
|
|
108
|
+
return shuffleProps(propositions, n);
|
|
109
|
+
};
|
|
110
|
+
const getAnswer = (identifiers) => {
|
|
111
|
+
const { pointData, isLatitude } = identifiers;
|
|
112
|
+
const latLonPoints = PointConstructor.fromIdentifiers(pointData.latLon);
|
|
113
|
+
if (isLatitude) {
|
|
114
|
+
return getStrLatitude(latLonPoints.x.evaluate());
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
return getStrLongitude(latLonPoints.y.evaluate());
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const getInstruction = (identifiers) => {
|
|
121
|
+
const { isLatitude, namePointTarget } = identifiers;
|
|
122
|
+
return `Quelle est la ${isLatitude ? "latitude" : "longitude"} du point $${namePointTarget}$ sur la figure ci-dessous ?`;
|
|
123
|
+
};
|
|
124
|
+
const getHint = () => {
|
|
125
|
+
return `Pour déterminer la latitude, on utlise les parallèles.
|
|
126
|
+
Pour déterminer la longitude, on utilise les méridiens.`;
|
|
127
|
+
};
|
|
128
|
+
const getCorrection = (identifiers) => {
|
|
129
|
+
const { isLatitude, namePointTarget } = identifiers;
|
|
130
|
+
const answer = getAnswer(identifiers);
|
|
131
|
+
return `La latitude donne la position Nord/Sud.
|
|
132
|
+
La longitude donne la position Est/Ouest.
|
|
133
|
+
La ${isLatitude ? "latitude" : "longitude"} du point $${namePointTarget}$ est donc $${answer}$.`;
|
|
134
|
+
};
|
|
135
|
+
const getGGBOptions = (identifiers) => {
|
|
136
|
+
const { pointData } = identifiers;
|
|
137
|
+
const xyPoint = PointConstructor.fromIdentifiers(pointData["2d"]);
|
|
138
|
+
const commands = [
|
|
139
|
+
...earthGlobe2DGGBCommands(),
|
|
140
|
+
...xyPoint.toGGBCommand({ isFixed: true, showLabel: true }),
|
|
141
|
+
];
|
|
142
|
+
const ggb = new GeogebraConstructor({
|
|
143
|
+
commands,
|
|
144
|
+
hideAxes: true,
|
|
145
|
+
hideGrid: true,
|
|
146
|
+
});
|
|
147
|
+
return ggb.getOptions({
|
|
148
|
+
coords: [-1.1, 1.1, -1.1, 1.1],
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
const getKeys = () => {
|
|
152
|
+
return ["degree", "N", "O", "S", "E"];
|
|
153
|
+
};
|
|
154
|
+
const isAnswerValid = (ans, { answer }) => {
|
|
155
|
+
console.log("ans", ans);
|
|
156
|
+
console.log("answer", answer);
|
|
157
|
+
const ansRefined = ans.replace("^{\\circ}", "°");
|
|
158
|
+
return ansRefined === answer;
|
|
159
|
+
};
|
|
160
|
+
const getSphereLatLonReading2dQuestion = () => {
|
|
161
|
+
const isLatitude = coinFlip();
|
|
162
|
+
const letters = ["A", "B", "C", "D"];
|
|
163
|
+
const arrLat = [...Array(9).keys()].map((i) => (i - 4) * 15);
|
|
164
|
+
const arrLon = [...Array(9).keys()].map((i) => (i - 4) * 15);
|
|
165
|
+
//we need student to figure out the correct mapping
|
|
166
|
+
const arrLatLon = getCartesiansProducts([arrLat, arrLon]).filter(([lat, lon]) => lat !== lon && -lat !== lon);
|
|
167
|
+
const pickedLatLon = randomMany(arrLatLon, letters.length);
|
|
168
|
+
const pointsDict = letters.reduce((acc, letter, i) => {
|
|
169
|
+
const [lat, lon] = pickedLatLon[i];
|
|
170
|
+
const latLonPoint = new Point(`${letter}`, lat, lon);
|
|
171
|
+
const xyPoint = xyPointForLatLonPoint(latLonPoint);
|
|
172
|
+
xyPoint.name = letter;
|
|
173
|
+
acc[letter] = {
|
|
174
|
+
latLon: latLonPoint.toIdentifiers(),
|
|
175
|
+
"2d": xyPoint.toIdentifiers(),
|
|
176
|
+
};
|
|
177
|
+
return acc;
|
|
178
|
+
}, {});
|
|
179
|
+
const namePointTarget = random(Object.keys(pointsDict));
|
|
180
|
+
const identifiers = {
|
|
181
|
+
isLatitude,
|
|
182
|
+
pointData: pointsDict[namePointTarget],
|
|
183
|
+
namePointTarget,
|
|
184
|
+
};
|
|
185
|
+
return getQuestionFromIdentifiers(identifiers);
|
|
186
|
+
};
|
|
187
|
+
const getQuestionFromIdentifiers = (identifiers) => {
|
|
188
|
+
const question = {
|
|
189
|
+
answer: getAnswer(identifiers),
|
|
190
|
+
instruction: getInstruction(identifiers),
|
|
191
|
+
keys: getKeys(identifiers),
|
|
192
|
+
answerFormat: "tex",
|
|
193
|
+
identifiers,
|
|
194
|
+
hint: getHint(identifiers),
|
|
195
|
+
correction: getCorrection(identifiers),
|
|
196
|
+
ggbOptions: getGGBOptions(identifiers),
|
|
197
|
+
};
|
|
198
|
+
return question;
|
|
199
|
+
};
|
|
200
|
+
export const sphereLatLonReading2d = {
|
|
201
|
+
id: "sphereLatLonReading2d",
|
|
202
|
+
label: "Donner la latitude/longitude d'un point sur une sphère ($2$D)",
|
|
203
|
+
isSingleStep: true,
|
|
204
|
+
generator: (nb, opts) => getDistinctQuestions(() => getSphereLatLonReading2dQuestion(opts), nb),
|
|
205
|
+
qcmTimer: 60,
|
|
206
|
+
freeTimer: 60,
|
|
207
|
+
getPropositions,
|
|
208
|
+
isAnswerValid,
|
|
209
|
+
getHint,
|
|
210
|
+
getCorrection,
|
|
211
|
+
hasHintAndCorrection: true,
|
|
212
|
+
subject: "Mathématiques",
|
|
213
|
+
hasGeogebra: true,
|
|
214
|
+
getQuestionFromIdentifiers,
|
|
215
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Exercise } from "../../../../exercises/exercise.js";
|
|
2
|
+
import { PointIdentifiers } from "../../../../math/geometry/point.js";
|
|
3
|
+
import { SpacePointIdentifiers } from "../../../../math/geometry/spacePoint.js";
|
|
4
|
+
type Identifiers = {
|
|
5
|
+
pointsDict: Record<string, {
|
|
6
|
+
latLon: PointIdentifiers;
|
|
7
|
+
"3d": SpacePointIdentifiers;
|
|
8
|
+
}>;
|
|
9
|
+
isLatitude: boolean;
|
|
10
|
+
namePointTarget: string;
|
|
11
|
+
};
|
|
12
|
+
export declare const sphereLatLonReading: Exercise<Identifiers>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=sphereLatLonReading.3d.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sphereLatLonReading.3d.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/spaceGeometry/sphere/sphereLatLonReading.3d.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAgBT,MAAM,6BAA6B,CAAC;AAIrC,OAAO,EAGL,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAGL,qBAAqB,EACtB,MAAM,mCAAmC,CAAC;AAwO3C,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,MAAM,CAChB,MAAM,EACN;QACE,MAAM,EAAE,gBAAgB,CAAC;QACzB,IAAI,EAAE,qBAAqB,CAAC;KAC7B,CACF,CAAC;IACF,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAwMF,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,WAAW,CAgBrD,CAAC"}
|