math-exercises 3.0.159 → 3.0.161
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/exercise.d.ts +12 -0
- package/lib/exercises/exercise.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/equation/solveByFactorizingWithIdRmq3.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/equation/solveByFactorizingWithIdRmq3.js +1 -2
- package/lib/exercises/math/functions/basics/inverseImageFunctionGeogebra.d.ts.map +1 -1
- package/lib/exercises/math/functions/basics/inverseImageFunctionGeogebra.js +43 -0
- package/lib/exercises/math/functions/trinoms/factoForm/index.d.ts +1 -0
- package/lib/exercises/math/functions/trinoms/factoForm/index.d.ts.map +1 -1
- package/lib/exercises/math/functions/trinoms/factoForm/index.js +1 -0
- package/lib/exercises/math/functions/trinoms/factoForm/trinomDevelopFactorizedForm.d.ts +13 -0
- package/lib/exercises/math/functions/trinoms/factoForm/trinomDevelopFactorizedForm.d.ts.map +1 -0
- package/lib/exercises/math/functions/trinoms/factoForm/trinomDevelopFactorizedForm.js +147 -0
- package/lib/exercises/math/functions/trinoms/roots/niceRootsFromDevForm.d.ts.map +1 -1
- package/lib/exercises/math/functions/trinoms/roots/niceRootsFromDevForm.js +96 -0
- package/lib/exercises/math/functions/trinoms/roots/rootsFromDevForm.d.ts.map +1 -1
- package/lib/exercises/math/functions/trinoms/roots/rootsFromDevForm.js +95 -1
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/devFormFromSummitAndPoint.d.ts +9 -0
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/devFormFromSummitAndPoint.d.ts.map +1 -0
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/devFormFromSummitAndPoint.js +173 -0
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/index.d.ts +2 -0
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/index.d.ts.map +1 -1
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/index.js +2 -0
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/summitAbscissFromRoots.js +1 -1
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/summitAbscissFromSymetricPoints.d.ts +9 -0
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/summitAbscissFromSymetricPoints.d.ts.map +1 -0
- package/lib/exercises/math/functions/trinoms/summitAndCanonical/summitAbscissFromSymetricPoints.js +97 -0
- package/lib/exercises/math/geometry/circles/circleCanonicalEquationFromDevEquation.d.ts +10 -0
- package/lib/exercises/math/geometry/circles/circleCanonicalEquationFromDevEquation.d.ts.map +1 -0
- package/lib/exercises/math/geometry/circles/circleCanonicalEquationFromDevEquation.js +174 -0
- package/lib/exercises/math/geometry/circles/circleCenterAndRadiusFromEquation.d.ts +12 -0
- package/lib/exercises/math/geometry/circles/circleCenterAndRadiusFromEquation.d.ts.map +1 -0
- package/lib/exercises/math/geometry/circles/circleCenterAndRadiusFromEquation.js +161 -0
- package/lib/exercises/math/geometry/circles/circleEquationFromDiameter.d.ts +9 -0
- package/lib/exercises/math/geometry/circles/circleEquationFromDiameter.d.ts.map +1 -0
- package/lib/exercises/math/geometry/circles/circleEquationFromDiameter.js +145 -0
- package/lib/exercises/math/geometry/circles/circleEquationFromPointAndRadius.d.ts +13 -0
- package/lib/exercises/math/geometry/circles/circleEquationFromPointAndRadius.d.ts.map +1 -0
- package/lib/exercises/math/geometry/circles/circleEquationFromPointAndRadius.js +181 -0
- package/lib/exercises/math/geometry/circles/circleRadiusOrCenterFromDevEquation.d.ts +11 -0
- package/lib/exercises/math/geometry/circles/circleRadiusOrCenterFromDevEquation.d.ts.map +1 -0
- package/lib/exercises/math/geometry/circles/circleRadiusOrCenterFromDevEquation.js +191 -0
- package/lib/exercises/math/geometry/circles/index.d.ts +5 -0
- package/lib/exercises/math/geometry/circles/index.d.ts.map +1 -1
- package/lib/exercises/math/geometry/circles/index.js +5 -0
- package/lib/exercises/math/geometry/circles/isPointOnCircleFromCartesianEquation.js +1 -1
- package/lib/exercises/math/geometry/lines/cartesianEquationOfTriangleHeight.d.ts +10 -0
- package/lib/exercises/math/geometry/lines/cartesianEquationOfTriangleHeight.d.ts.map +1 -0
- package/lib/exercises/math/geometry/lines/cartesianEquationOfTriangleHeight.js +181 -0
- package/lib/exercises/math/geometry/lines/cartesianEquationToReduced.d.ts +4 -1
- package/lib/exercises/math/geometry/lines/cartesianEquationToReduced.d.ts.map +1 -1
- package/lib/exercises/math/geometry/lines/cartesianEquationToReduced.js +23 -3
- package/lib/exercises/math/geometry/lines/index.d.ts +1 -0
- package/lib/exercises/math/geometry/lines/index.d.ts.map +1 -1
- package/lib/exercises/math/geometry/lines/index.js +1 -0
- package/lib/exercises/math/geometry/vectors/scalarProduct/scalarProductIdentities.js +1 -1
- package/lib/exercises/math/probaStat/independancy/isIndependantFromDefinition.js +1 -1
- package/lib/exercises/math/probaStat/randomVariable/findValueForFairRandomVariable.js +1 -1
- package/lib/exercises/math/probaStat/randomVariable/findValueToMatchRandomVariableAverage.js +1 -1
- package/lib/exercises/math/probaStat/stats1var/compareSeriesDispersion.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/stats1var/compareSeriesDispersion.js +11 -6
- package/lib/exercises/vea/pointVEA.d.ts +2 -0
- package/lib/exercises/vea/pointVEA.d.ts.map +1 -0
- package/lib/exercises/vea/pointVEA.js +7 -0
- package/lib/index.d.ts +41 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/math/geometry/circle.d.ts +6 -0
- package/lib/math/geometry/circle.d.ts.map +1 -1
- package/lib/math/geometry/circle.js +16 -0
- package/lib/math/geometry/point.d.ts +1 -1
- package/lib/math/geometry/point.d.ts.map +1 -1
- package/lib/math/geometry/point.js +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { addValidProp, shuffleProps, propWhile, tryToAddWrongProp, GeneratorOptionType, GeneratorOptionTarget, } from "../../../../exercises/exercise.js";
|
|
2
|
+
import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
|
|
3
|
+
import { pointVEA } from "../../../../exercises/vea/pointVEA.js";
|
|
4
|
+
import { sqrtVEA } from "../../../../exercises/vea/sqrtVEA.js";
|
|
5
|
+
import { CircleConstructor } from "../../../../math/geometry/circle.js";
|
|
6
|
+
import { Point, PointConstructor } from "../../../../math/geometry/point.js";
|
|
7
|
+
import { SquareRootConstructor } from "../../../../math/numbers/reals/real.js";
|
|
8
|
+
import { randint } from "../../../../math/utils/random/randint.js";
|
|
9
|
+
import { opposite } from "../../../../tree/nodes/functions/oppositeNode.js";
|
|
10
|
+
import { sqrt } from "../../../../tree/nodes/functions/sqrtNode.js";
|
|
11
|
+
import { reifyAlgebraic } from "../../../../tree/nodes/nodeConstructor.js";
|
|
12
|
+
import { square } from "../../../../tree/nodes/operators/powerNode.js";
|
|
13
|
+
import { substract } from "../../../../tree/nodes/operators/substractNode.js";
|
|
14
|
+
import { coinFlip } from "../../../../utils/alea/coinFlip.js";
|
|
15
|
+
import { handleVEAError } from "../../../../utils/errors/handleVEAError.js";
|
|
16
|
+
const getPropositions = (n, { answer, isAskingRadius }) => {
|
|
17
|
+
const propositions = [];
|
|
18
|
+
addValidProp(propositions, answer);
|
|
19
|
+
propWhile(propositions, n, () => {
|
|
20
|
+
if (isAskingRadius)
|
|
21
|
+
tryToAddWrongProp(propositions, coinFlip()
|
|
22
|
+
? randint(1, 10) + ""
|
|
23
|
+
: SquareRootConstructor.randomIrreductible(20).toTex());
|
|
24
|
+
else
|
|
25
|
+
tryToAddWrongProp(propositions, PointConstructor.random("A").toCoords());
|
|
26
|
+
});
|
|
27
|
+
return shuffleProps(propositions, n);
|
|
28
|
+
};
|
|
29
|
+
const getAnswer = (identifiers) => {
|
|
30
|
+
const { equationIds, isAskingRadius } = identifiers;
|
|
31
|
+
const equation = reifyAlgebraic(equationIds);
|
|
32
|
+
console.log(equation.toTex());
|
|
33
|
+
if (isAskingRadius)
|
|
34
|
+
return sqrt(equation.rightChild).simplify().toTex();
|
|
35
|
+
const left = equation.leftChild;
|
|
36
|
+
const xNode = left.leftChild;
|
|
37
|
+
const abscisse = opposite(xNode.leftChild.toDetailedEvaluation({ x: (0).toTree() })).simplify();
|
|
38
|
+
const yNode = left.rightChild;
|
|
39
|
+
const ordonnee = opposite(yNode.leftChild.toDetailedEvaluation({ y: (0).toTree() })).simplify();
|
|
40
|
+
return new Point("O", abscisse, ordonnee).toCoords();
|
|
41
|
+
};
|
|
42
|
+
const getInstruction = (identifiers) => {
|
|
43
|
+
const { equationIds, isAskingRadius } = identifiers;
|
|
44
|
+
const equation = reifyAlgebraic(equationIds);
|
|
45
|
+
return `Soit $\\mathcal{C}$ le cercle dont une équation cartésienne est :
|
|
46
|
+
|
|
47
|
+
$$
|
|
48
|
+
${equation.toTex()}
|
|
49
|
+
$$
|
|
50
|
+
|
|
51
|
+
${isAskingRadius
|
|
52
|
+
? "Quel est le rayon de $\\mathcal{C}$ ?"
|
|
53
|
+
: "Quelles sont les coordonnées du centre de $\\mathcal{C}$ ?"}`;
|
|
54
|
+
};
|
|
55
|
+
const getHint = () => {
|
|
56
|
+
return `Si $A(x_A;y_A)$ est le centre d'un cercle $\\mathcal{C}$ de rayon $R$, alors une équation cartésienne de $\\mathcal{C}$ est :
|
|
57
|
+
|
|
58
|
+
$$
|
|
59
|
+
(x-x_A)^2+(y-y_A)^2 = R^2
|
|
60
|
+
$$`;
|
|
61
|
+
};
|
|
62
|
+
const getCorrection = (identifiers) => {
|
|
63
|
+
const { isAskingRadius, equationIds } = identifiers;
|
|
64
|
+
const radius = getAnswer({ equationIds, isAskingRadius: true });
|
|
65
|
+
const coords = getAnswer({ equationIds, isAskingRadius: false });
|
|
66
|
+
const coordsTrimed = coords
|
|
67
|
+
.replaceAll("\\left", "")
|
|
68
|
+
.replaceAll("\\right", "")
|
|
69
|
+
.replaceAll("(", "")
|
|
70
|
+
.replaceAll(")", "");
|
|
71
|
+
const abscisse = coordsTrimed.split(";")[0].unfrenchify();
|
|
72
|
+
const ordonnee = coordsTrimed.split(";")[1].unfrenchify();
|
|
73
|
+
return `Si $A(x_A;y_A)$ est le centre d'un cercle $\\mathcal{C}$ de rayon $R$, alors une équation cartésienne de $R$ est :
|
|
74
|
+
|
|
75
|
+
$$
|
|
76
|
+
(x-x_A)^2+(y-y_A)^2 = R^2
|
|
77
|
+
$$
|
|
78
|
+
|
|
79
|
+
Ici, on peut donc réécrire l'équation pour faire apparaître les coordonnées du centre et le rayon :
|
|
80
|
+
|
|
81
|
+
$$
|
|
82
|
+
(${substract("x", abscisse).toTex()})^2 + (${substract("y", ordonnee).toTex()})^2 = ${square(radius).toTex()}
|
|
83
|
+
$$
|
|
84
|
+
|
|
85
|
+
${isAskingRadius
|
|
86
|
+
? `Le rayon de $\\mathcal{C}$ est donc $${radius}$.`
|
|
87
|
+
: `Les coordonnées du centre de $\\mathcal{C}$ sont donc $${coords}$.`}`;
|
|
88
|
+
};
|
|
89
|
+
const getKeys = () => {
|
|
90
|
+
return ["semicolon"];
|
|
91
|
+
};
|
|
92
|
+
const isAnswerValid = (ans, { answer, isAskingRadius }) => {
|
|
93
|
+
try {
|
|
94
|
+
if (isAskingRadius)
|
|
95
|
+
return sqrtVEA(ans, answer);
|
|
96
|
+
else {
|
|
97
|
+
return pointVEA(ans, answer);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
return handleVEAError(err);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const getCircleCenterAndRadiusFromEquationQuestion = (opts) => {
|
|
105
|
+
const isAskingRadius = opts?.askedParameter === "Rayon"
|
|
106
|
+
? true
|
|
107
|
+
: opts?.askedParameter === "Coordonnées du centre"
|
|
108
|
+
? false
|
|
109
|
+
: coinFlip();
|
|
110
|
+
const center = PointConstructor.random("O");
|
|
111
|
+
const radius = coinFlip()
|
|
112
|
+
? randint(1, 10).toTree()
|
|
113
|
+
: SquareRootConstructor.randomIrreductible(20).toTree();
|
|
114
|
+
const eq = CircleConstructor.cartesianEquation(center, radius);
|
|
115
|
+
console.log("rad ", radius.toTex(), "eq ", eq.toTex());
|
|
116
|
+
const identifiers = {
|
|
117
|
+
isAskingRadius,
|
|
118
|
+
equationIds: eq.toIdentifiers(),
|
|
119
|
+
};
|
|
120
|
+
return getQuestionFromIdentifiers(identifiers);
|
|
121
|
+
};
|
|
122
|
+
const getQuestionFromIdentifiers = (identifiers) => {
|
|
123
|
+
return {
|
|
124
|
+
answer: getAnswer(identifiers),
|
|
125
|
+
instruction: getInstruction(identifiers),
|
|
126
|
+
keys: getKeys(identifiers),
|
|
127
|
+
answerFormat: "tex",
|
|
128
|
+
identifiers,
|
|
129
|
+
hint: getHint(identifiers),
|
|
130
|
+
correction: getCorrection(identifiers),
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
const options = [
|
|
134
|
+
{
|
|
135
|
+
id: "askedParameter",
|
|
136
|
+
label: "Paramètre demandé",
|
|
137
|
+
target: GeneratorOptionTarget.generation,
|
|
138
|
+
type: GeneratorOptionType.select,
|
|
139
|
+
values: ["Rayon", "Coordonnées du centre", "L'un ou l'autre aléatoirement"],
|
|
140
|
+
defaultValue: "L'un ou l'autre aléatoirement",
|
|
141
|
+
},
|
|
142
|
+
];
|
|
143
|
+
export const circleCenterAndRadiusFromEquation = {
|
|
144
|
+
id: "circleCenterAndRadiusFromEquation",
|
|
145
|
+
connector: "=",
|
|
146
|
+
label: "Déterminer le centre ou le rayon d'un cercle dans son équation canonique",
|
|
147
|
+
isSingleStep: true,
|
|
148
|
+
generator: (nb, opts) => getDistinctQuestions(() => getCircleCenterAndRadiusFromEquationQuestion(opts), nb),
|
|
149
|
+
qcmTimer: 60,
|
|
150
|
+
freeTimer: 60,
|
|
151
|
+
getPropositions,
|
|
152
|
+
isAnswerValid,
|
|
153
|
+
subject: "Mathématiques",
|
|
154
|
+
getInstruction,
|
|
155
|
+
getHint,
|
|
156
|
+
getCorrection,
|
|
157
|
+
getAnswer,
|
|
158
|
+
getQuestionFromIdentifiers,
|
|
159
|
+
hasHintAndCorrection: true,
|
|
160
|
+
options,
|
|
161
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Exercise } from "../../../../exercises/exercise.js";
|
|
2
|
+
import { PointIdentifiers } from "../../../../math/geometry/point.js";
|
|
3
|
+
type Identifiers = {
|
|
4
|
+
AIds: PointIdentifiers;
|
|
5
|
+
BIds: PointIdentifiers;
|
|
6
|
+
};
|
|
7
|
+
export declare const circleEquationFromDiameter: Exercise<Identifiers>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=circleEquationFromDiameter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circleEquationFromDiameter.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/circles/circleEquationFromDiameter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAEL,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAStC,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,gBAAgB,CAAC;CACxB,CAAC;AA+JF,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,WAAW,CAmB5D,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { addValidProp, shuffleProps, propWhile, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
|
|
2
|
+
import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
|
|
3
|
+
import { PointConstructor, } from "../../../../math/geometry/point.js";
|
|
4
|
+
import { Vector } from "../../../../math/geometry/vector.js";
|
|
5
|
+
import { equal } from "../../../../tree/nodes/equations/equalNode.js";
|
|
6
|
+
import { substract } from "../../../../tree/nodes/operators/substractNode.js";
|
|
7
|
+
import { parseAlgebraic } from "../../../../tree/parsers/latexParser.js";
|
|
8
|
+
import { doWhile } from "../../../../utils/doWhile.js";
|
|
9
|
+
import { handleVEAError } from "../../../../utils/errors/handleVEAError.js";
|
|
10
|
+
import { alignTex } from "../../../../utils/latex/alignTex.js";
|
|
11
|
+
const getPropositions = (n, { answer }) => {
|
|
12
|
+
const propositions = [];
|
|
13
|
+
addValidProp(propositions, answer);
|
|
14
|
+
propWhile(propositions, n, () => {
|
|
15
|
+
const [A, B] = PointConstructor.randomDifferent(2, {});
|
|
16
|
+
tryToAddWrongProp(propositions, getAnswer({
|
|
17
|
+
AIds: A.toIdentifiers(),
|
|
18
|
+
BIds: B.toIdentifiers(),
|
|
19
|
+
}));
|
|
20
|
+
});
|
|
21
|
+
return shuffleProps(propositions, n);
|
|
22
|
+
};
|
|
23
|
+
const getAnswerNode = (identifiers) => {
|
|
24
|
+
// const { AIds, BIds } = identifiers;
|
|
25
|
+
// const A = PointConstructor.fromIdentifiers(AIds);
|
|
26
|
+
// const B = PointConstructor.fromIdentifiers(BIds);
|
|
27
|
+
// const center = A.midpoint(B).simplify();
|
|
28
|
+
// const radius = frac(A.distanceToNode(B), 2).simplify();
|
|
29
|
+
// return CircleConstructor.cartesianEquation(center, radius);
|
|
30
|
+
const { AIds, BIds } = identifiers;
|
|
31
|
+
const A = PointConstructor.fromIdentifiers(AIds);
|
|
32
|
+
const B = PointConstructor.fromIdentifiers(BIds);
|
|
33
|
+
const AM = new Vector("AM", substract("x", A.x), substract("y", A.y)).simplify();
|
|
34
|
+
const BM = new Vector("BM", substract("x", B.x), substract("y", B.y)).simplify();
|
|
35
|
+
return equal(AM.scalarProduct(BM)
|
|
36
|
+
.simplify({ forbidFactorize: true, towardsDistribute: true })
|
|
37
|
+
.toTex(), 0);
|
|
38
|
+
};
|
|
39
|
+
const getAnswer = (identifiers) => {
|
|
40
|
+
return getAnswerNode(identifiers).toTex();
|
|
41
|
+
};
|
|
42
|
+
const getInstruction = (identifiers) => {
|
|
43
|
+
const { AIds, BIds } = identifiers;
|
|
44
|
+
const A = PointConstructor.fromIdentifiers(AIds);
|
|
45
|
+
const B = PointConstructor.fromIdentifiers(BIds);
|
|
46
|
+
return `Soit $\\mathcal{C}$ le cercle de diamètre $[AB]$, avec $${A.toTexWithCoords()}$ et $${B.toTexWithCoords()}$.
|
|
47
|
+
|
|
48
|
+
Donner une équation cartésienne du cercle $\\mathcal{C}$.`;
|
|
49
|
+
};
|
|
50
|
+
const getHint = () => {
|
|
51
|
+
return `Si $[AB]$ est le diamètre d'un cercle $\\mathcal{C}$, alors tout point de $C$ est tel que $ABC$ est un triangle rectangle en $C$.
|
|
52
|
+
|
|
53
|
+
Cela signifie donc qu'un point $C(x;y)$ est sur le cercle $\\mathcal{C}$ si et seulement si les vecteurs $\\overrightarrow{AC}$ et $\\overrightarrow{BC}$ sont orthogonaux.`;
|
|
54
|
+
};
|
|
55
|
+
const getCorrection = (identifiers) => {
|
|
56
|
+
const { AIds, BIds } = identifiers;
|
|
57
|
+
const A = PointConstructor.fromIdentifiers(AIds);
|
|
58
|
+
const B = PointConstructor.fromIdentifiers(BIds);
|
|
59
|
+
const AM = new Vector("AM", substract("x", A.x), substract("y", A.y)).simplify();
|
|
60
|
+
const BM = new Vector("BM", substract("x", B.x), substract("y", B.y)).simplify();
|
|
61
|
+
// const center = A.midpoint(B).simplify();
|
|
62
|
+
// const radius = frac(A.distanceToNode(B), 2).simplify();
|
|
63
|
+
// const canoEq = CircleConstructor.cartesianEquation(center, radius).toTex();
|
|
64
|
+
return `On considère un point $M(x;y)$.
|
|
65
|
+
|
|
66
|
+
Le point $M$ appartient à $\\mathcal{C}$ si seulement si le triangle $ABM$ est rectangle en $M$, c'est à dire si $\\overrightarrow{AM}$ et $\\overrightarrow{BM}$ sont orthogonaux.
|
|
67
|
+
|
|
68
|
+
Donc le point $M$ appartient à $\\mathcal{C}$ si et seulement si :
|
|
69
|
+
|
|
70
|
+
${alignTex([
|
|
71
|
+
["", "\\overrightarrow{AM}\\cdot \\overrightarrow{BM}=0"],
|
|
72
|
+
["\\iff", `${AM.scalarProduct(BM).toTex()} = 0`],
|
|
73
|
+
[
|
|
74
|
+
"\\iff",
|
|
75
|
+
`${AM.scalarProduct(BM)
|
|
76
|
+
.simplify({ forbidFactorize: true, towardsDistribute: true })
|
|
77
|
+
.toTex()} = 0`,
|
|
78
|
+
],
|
|
79
|
+
])}
|
|
80
|
+
|
|
81
|
+
Une équation cartésienne du cercle $\\mathcal{C}$ est donc :
|
|
82
|
+
|
|
83
|
+
$$
|
|
84
|
+
${getAnswer(identifiers)}
|
|
85
|
+
$$`;
|
|
86
|
+
};
|
|
87
|
+
const getKeys = () => {
|
|
88
|
+
return ["x", "y", "equal"];
|
|
89
|
+
};
|
|
90
|
+
const isAnswerValid = (ans, { answer: _answer, ...identifiers }) => {
|
|
91
|
+
try {
|
|
92
|
+
const split = ans.split("=");
|
|
93
|
+
if (split.length !== 2)
|
|
94
|
+
return false;
|
|
95
|
+
const left = parseAlgebraic(split[0]);
|
|
96
|
+
const right = parseAlgebraic(split[1]);
|
|
97
|
+
const studentEq = substract(left, right).simplify({
|
|
98
|
+
towardsDistribute: true,
|
|
99
|
+
forbidFactorize: true,
|
|
100
|
+
});
|
|
101
|
+
const ansNodeDev = getAnswerNode(identifiers).leftChild;
|
|
102
|
+
return studentEq.toTex() === ansNodeDev.toTex();
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
return handleVEAError(err);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const getCircleEquationFromDiameterQuestion = () => {
|
|
109
|
+
const A = PointConstructor.random("A");
|
|
110
|
+
const B = doWhile(() => PointConstructor.random("B"), (p) => p.equals(A));
|
|
111
|
+
const identifiers = {
|
|
112
|
+
AIds: A.toIdentifiers(),
|
|
113
|
+
BIds: B.toIdentifiers(),
|
|
114
|
+
};
|
|
115
|
+
return getQuestionFromIdentifiers(identifiers);
|
|
116
|
+
};
|
|
117
|
+
const getQuestionFromIdentifiers = (identifiers) => {
|
|
118
|
+
return {
|
|
119
|
+
answer: getAnswer(identifiers),
|
|
120
|
+
instruction: getInstruction(identifiers),
|
|
121
|
+
keys: getKeys(identifiers),
|
|
122
|
+
answerFormat: "tex",
|
|
123
|
+
identifiers,
|
|
124
|
+
hint: getHint(identifiers),
|
|
125
|
+
correction: getCorrection(identifiers),
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
export const circleEquationFromDiameter = {
|
|
129
|
+
id: "circleEquationFromDiameter",
|
|
130
|
+
connector: "\\iff",
|
|
131
|
+
label: "Déterminer une équation cartésienne d'un cercle en connaissant son diamètre",
|
|
132
|
+
isSingleStep: true,
|
|
133
|
+
generator: (nb, opts) => getDistinctQuestions(() => getCircleEquationFromDiameterQuestion(opts), nb),
|
|
134
|
+
qcmTimer: 60,
|
|
135
|
+
freeTimer: 60,
|
|
136
|
+
getPropositions,
|
|
137
|
+
isAnswerValid,
|
|
138
|
+
subject: "Mathématiques",
|
|
139
|
+
getInstruction,
|
|
140
|
+
getHint,
|
|
141
|
+
getCorrection,
|
|
142
|
+
getAnswer,
|
|
143
|
+
getQuestionFromIdentifiers,
|
|
144
|
+
hasHintAndCorrection: true,
|
|
145
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Exercise } from "../../../../exercises/exercise.js";
|
|
2
|
+
import { PointIdentifiers } from "../../../../math/geometry/point.js";
|
|
3
|
+
import { NodeIdentifiers } from "../../../../tree/nodes/nodeConstructor.js";
|
|
4
|
+
type Identifiers = {
|
|
5
|
+
centerIds: PointIdentifiers;
|
|
6
|
+
radiusIds: NodeIdentifiers;
|
|
7
|
+
};
|
|
8
|
+
type Options = {
|
|
9
|
+
equationType: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const circleEquationFromPointAndRadius: Exercise<Identifiers, Options>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=circleEquationFromPointAndRadius.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circleEquationFromPointAndRadius.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/circles/circleEquationFromPointAndRadius.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAkBT,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAEL,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAItC,OAAO,EACL,eAAe,EAEhB,MAAM,qCAAqC,CAAC;AAQ7C,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,SAAS,EAAE,eAAe,CAAC;CAC5B,CAAC;AAwMF,KAAK,OAAO,GAAG;IACb,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAYF,eAAO,MAAM,gCAAgC,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAwBzE,CAAC"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { addValidProp, shuffleProps, propWhile, GeneratorOptionTarget, GeneratorOptionType, tryToAddWrongProp, } from "../../../../exercises/exercise.js";
|
|
2
|
+
import { getDistinctQuestions } from "../../../../exercises/utils/getDistinctQuestions.js";
|
|
3
|
+
import { PointConstructor, } from "../../../../math/geometry/point.js";
|
|
4
|
+
import { SquareRootConstructor } from "../../../../math/numbers/reals/real.js";
|
|
5
|
+
import { randint } from "../../../../math/utils/random/randint.js";
|
|
6
|
+
import { equal } from "../../../../tree/nodes/equations/equalNode.js";
|
|
7
|
+
import { reifyAlgebraic, } from "../../../../tree/nodes/nodeConstructor.js";
|
|
8
|
+
import { add } from "../../../../tree/nodes/operators/addNode.js";
|
|
9
|
+
import { square } from "../../../../tree/nodes/operators/powerNode.js";
|
|
10
|
+
import { substract } from "../../../../tree/nodes/operators/substractNode.js";
|
|
11
|
+
import { parseAlgebraic } from "../../../../tree/parsers/latexParser.js";
|
|
12
|
+
import { coinFlip } from "../../../../utils/alea/coinFlip.js";
|
|
13
|
+
import { handleVEAError } from "../../../../utils/errors/handleVEAError.js";
|
|
14
|
+
const getPropositions = (n, { answer }, opts) => {
|
|
15
|
+
const propositions = [];
|
|
16
|
+
addValidProp(propositions, answer);
|
|
17
|
+
propWhile(propositions, n, () => {
|
|
18
|
+
const radiusIds = randint(1, 10).toTree().toIdentifiers();
|
|
19
|
+
const centerIds = PointConstructor.random("O").toIdentifiers();
|
|
20
|
+
tryToAddWrongProp(propositions, getAnswer({
|
|
21
|
+
centerIds,
|
|
22
|
+
radiusIds,
|
|
23
|
+
}, opts));
|
|
24
|
+
});
|
|
25
|
+
return shuffleProps(propositions, n);
|
|
26
|
+
};
|
|
27
|
+
const getAnnswerNode = (identifiers, opts) => {
|
|
28
|
+
const { centerIds, radiusIds } = identifiers;
|
|
29
|
+
const center = PointConstructor.fromIdentifiers(centerIds);
|
|
30
|
+
const radius = reifyAlgebraic(radiusIds);
|
|
31
|
+
const radiusSquared = square(radius).simplify();
|
|
32
|
+
const isDev = opts?.equationType === "Développée";
|
|
33
|
+
if (isDev) {
|
|
34
|
+
return equal(substract(add(square(substract("x", center.x).simplify()), square(substract("y", center.y).simplify())), radiusSquared).simplify({ towardsDistribute: true, forbidFactorize: true }), "0");
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
return equal(add(square(substract("x", center.x).simplify()), square(substract("y", center.y).simplify())), square(radius).simplify());
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const getAnswer = (identifiers, opts) => {
|
|
41
|
+
return getAnnswerNode(identifiers, opts).toTex();
|
|
42
|
+
};
|
|
43
|
+
const getInstruction = (identifiers, opts) => {
|
|
44
|
+
const { centerIds, radiusIds } = identifiers;
|
|
45
|
+
const center = PointConstructor.fromIdentifiers(centerIds);
|
|
46
|
+
const radius = reifyAlgebraic(radiusIds);
|
|
47
|
+
return `Le cercle $\\mathcal{C}$ a pour centre $${center.toTexWithCoords()}$ et pour rayon $${radius.toTex()}$.
|
|
48
|
+
|
|
49
|
+
Donner une équation cartésienne du cercle $\\mathcal{C}$${opts?.equationType === "Développée" ? " **sous forme développée**" : ""}.`;
|
|
50
|
+
};
|
|
51
|
+
const getHint = () => {
|
|
52
|
+
return `Si $A(x_A;y_A)$ est le centre d'un cercle $\\mathcal{C}$ de rayon $R$, alors une équation cartésienne de $R$ est :
|
|
53
|
+
|
|
54
|
+
$$
|
|
55
|
+
(x-x_A)^2+(y-y_A)^2 = R^2
|
|
56
|
+
$$`;
|
|
57
|
+
};
|
|
58
|
+
const getCorrection = (identifiers, opts) => {
|
|
59
|
+
const { centerIds, radiusIds } = identifiers;
|
|
60
|
+
const center = PointConstructor.fromIdentifiers(centerIds);
|
|
61
|
+
const radius = reifyAlgebraic(radiusIds);
|
|
62
|
+
const radiusSquared = square(radius).simplify();
|
|
63
|
+
return `Si $A(x_A;y_A)$ est le centre d'un cercle $\\mathcal{C}$ de rayon $R$, alors une équation cartésienne de $R$ est :
|
|
64
|
+
|
|
65
|
+
$$
|
|
66
|
+
(x-x_A)^2+(y-y_A)^2 = R^2
|
|
67
|
+
$$
|
|
68
|
+
|
|
69
|
+
Ici, une équation cartésienne de $\\mathcal{C}$ est donc :
|
|
70
|
+
|
|
71
|
+
$$
|
|
72
|
+
(${substract("x", center.x).simplify().toTex()})^2 + (${substract("y", center.y)
|
|
73
|
+
.simplify()
|
|
74
|
+
.toTex()})^2 = ${square(radius).simplify().toTex()}
|
|
75
|
+
$$
|
|
76
|
+
|
|
77
|
+
${opts?.equationType === "Développée"
|
|
78
|
+
? `Il suffit alors de développer en utilisant des identités remarquables :
|
|
79
|
+
|
|
80
|
+
$$
|
|
81
|
+
${square(substract("x", center.x))
|
|
82
|
+
.simplify({
|
|
83
|
+
towardsDistribute: true,
|
|
84
|
+
forbidFactorize: true,
|
|
85
|
+
})
|
|
86
|
+
.toTex()} + ${square(substract("y", center.y))
|
|
87
|
+
.simplify({
|
|
88
|
+
towardsDistribute: true,
|
|
89
|
+
forbidFactorize: true,
|
|
90
|
+
})
|
|
91
|
+
.toTex()} = ${radiusSquared.toTex()}
|
|
92
|
+
$$
|
|
93
|
+
|
|
94
|
+
$$
|
|
95
|
+
${substract(add(square(substract("x", center.x).simplify({
|
|
96
|
+
towardsDistribute: true,
|
|
97
|
+
forbidFactorize: true,
|
|
98
|
+
})), square(substract("y", center.y).simplify({
|
|
99
|
+
towardsDistribute: true,
|
|
100
|
+
forbidFactorize: true,
|
|
101
|
+
}))), radiusSquared)
|
|
102
|
+
.simplify({ towardsDistribute: true, forbidFactorize: true })
|
|
103
|
+
.toTex()} = 0
|
|
104
|
+
$$
|
|
105
|
+
`
|
|
106
|
+
: ``}`;
|
|
107
|
+
};
|
|
108
|
+
const getKeys = () => {
|
|
109
|
+
return ["x", "y", "equal"];
|
|
110
|
+
};
|
|
111
|
+
const isAnswerValid = (ans, { answer: _answer, ...identifiers }) => {
|
|
112
|
+
try {
|
|
113
|
+
const split = ans.split("=");
|
|
114
|
+
if (split.length !== 2)
|
|
115
|
+
return false;
|
|
116
|
+
const left = parseAlgebraic(split[0]);
|
|
117
|
+
const right = parseAlgebraic(split[1]);
|
|
118
|
+
const studentEq = substract(left, right).simplify({
|
|
119
|
+
towardsDistribute: true,
|
|
120
|
+
forbidFactorize: true,
|
|
121
|
+
});
|
|
122
|
+
const ansNodeDev = getAnnswerNode(identifiers, {
|
|
123
|
+
equationType: "Développée",
|
|
124
|
+
}).leftChild;
|
|
125
|
+
return studentEq.toTex() === ansNodeDev.toTex();
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
return handleVEAError(err);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
const getCircleEquationFromPointAndRadisuQuestion = (opts) => {
|
|
132
|
+
const center = PointConstructor.random("O");
|
|
133
|
+
const radius = coinFlip()
|
|
134
|
+
? randint(1, 10).toTree()
|
|
135
|
+
: SquareRootConstructor.randomIrreductible(20).toTree();
|
|
136
|
+
const identifiers = {
|
|
137
|
+
centerIds: center.toIdentifiers(),
|
|
138
|
+
radiusIds: radius.toIdentifiers(),
|
|
139
|
+
};
|
|
140
|
+
return getQuestionFromIdentifiers(identifiers, opts);
|
|
141
|
+
};
|
|
142
|
+
const getQuestionFromIdentifiers = (identifiers, opts) => {
|
|
143
|
+
return {
|
|
144
|
+
answer: getAnswer(identifiers, opts),
|
|
145
|
+
instruction: getInstruction(identifiers, opts),
|
|
146
|
+
keys: getKeys(identifiers),
|
|
147
|
+
answerFormat: "tex",
|
|
148
|
+
identifiers,
|
|
149
|
+
hint: getHint(identifiers, opts),
|
|
150
|
+
correction: getCorrection(identifiers, opts),
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
const options = [
|
|
154
|
+
{
|
|
155
|
+
id: "equationType",
|
|
156
|
+
label: "Forme de l'équation attendue",
|
|
157
|
+
target: GeneratorOptionTarget.answer,
|
|
158
|
+
type: GeneratorOptionType.select,
|
|
159
|
+
values: ["Canonique", "Développée"],
|
|
160
|
+
defaultValue: "Canonique",
|
|
161
|
+
},
|
|
162
|
+
];
|
|
163
|
+
export const circleEquationFromPointAndRadius = {
|
|
164
|
+
id: "circleEquationFromPointAndRadius",
|
|
165
|
+
connector: "\\iff",
|
|
166
|
+
label: "Déterminer l'équation cartésienne d'un cercle en connaissant son centre et son rayon",
|
|
167
|
+
isSingleStep: true,
|
|
168
|
+
generator: (nb, opts) => getDistinctQuestions(() => getCircleEquationFromPointAndRadisuQuestion(opts), nb),
|
|
169
|
+
qcmTimer: 60,
|
|
170
|
+
freeTimer: 60,
|
|
171
|
+
getPropositions,
|
|
172
|
+
isAnswerValid,
|
|
173
|
+
subject: "Mathématiques",
|
|
174
|
+
getInstruction,
|
|
175
|
+
getHint,
|
|
176
|
+
getCorrection,
|
|
177
|
+
getAnswer,
|
|
178
|
+
getQuestionFromIdentifiers,
|
|
179
|
+
hasHintAndCorrection: true,
|
|
180
|
+
options,
|
|
181
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Exercise } from "../../../../exercises/exercise.js";
|
|
2
|
+
import { NodeIdentifiers } from "../../../../tree/nodes/nodeConstructor.js";
|
|
3
|
+
type Identifiers = {
|
|
4
|
+
aIds: NodeIdentifiers;
|
|
5
|
+
bIds: NodeIdentifiers;
|
|
6
|
+
cIds: NodeIdentifiers;
|
|
7
|
+
isAskingRadius: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare const circleRadiusOrCenterFromDevEquation: Exercise<Identifiers>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=circleRadiusOrCenterFromDevEquation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circleRadiusOrCenterFromDevEquation.d.ts","sourceRoot":"","sources":["../../../../../src/exercises/math/geometry/circles/circleRadiusOrCenterFromDevEquation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EAeT,MAAM,6BAA6B,CAAC;AAQrC,OAAO,EACL,eAAe,EAEhB,MAAM,qCAAqC,CAAC;AAU7C,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,eAAe,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AA0MF,eAAO,MAAM,mCAAmC,EAAE,QAAQ,CAAC,WAAW,CAsBrE,CAAC"}
|