math-exercises 3.0.29 → 3.0.31
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/arithmetics/euclideanDivision.js +2 -2
- package/lib/exercises/math/calcul/fractions/fractionSquare.d.ts.map +1 -1
- package/lib/exercises/math/calcul/fractions/fractionSquare.js +4 -0
- package/lib/exercises/math/calcul/fractions/fractionsProduct.d.ts.map +1 -1
- package/lib/exercises/math/calcul/fractions/fractionsProduct.js +4 -2
- package/lib/exercises/math/calcul/fractions/fractionsSubstraction.d.ts +11 -0
- package/lib/exercises/math/calcul/fractions/fractionsSubstraction.d.ts.map +1 -0
- package/lib/exercises/math/calcul/fractions/fractionsSubstraction.js +106 -0
- package/lib/exercises/math/calcul/fractions/fractionsSumsPrimeDenominators.js +1 -1
- package/lib/exercises/math/calcul/fractions/fractionsSumsSameDenominators.js +1 -1
- package/lib/exercises/math/calcul/fractions/index.d.ts +1 -0
- package/lib/exercises/math/calcul/fractions/index.d.ts.map +1 -1
- package/lib/exercises/math/calcul/fractions/index.js +1 -0
- package/lib/exercises/math/calcul/fractions/periodicWritingToFraction.js +1 -1
- package/lib/exercises/math/calcul/fractions/simplifyFraction.d.ts.map +1 -1
- package/lib/exercises/math/calcul/fractions/simplifyFraction.js +19 -10
- package/lib/exercises/math/calcul/proportionality/proportionalityTable.d.ts.map +1 -1
- package/lib/exercises/math/calcul/proportionality/proportionalityTable.js +23 -7
- package/lib/exercises/math/calcul/proportionality/rectangleSideAfterReduction.d.ts.map +1 -1
- package/lib/exercises/math/calcul/proportionality/rectangleSideAfterReduction.js +4 -0
- package/lib/exercises/math/calcul/sign/signFromAx.d.ts.map +1 -1
- package/lib/exercises/math/calcul/sign/signFromAx.js +4 -0
- package/lib/exercises/math/calculLitteral/distributivity/allIdentities.js +3 -3
- package/lib/exercises/math/calculLitteral/distributivity/doubleDistri.d.ts +8 -0
- package/lib/exercises/math/calculLitteral/distributivity/doubleDistri.d.ts.map +1 -0
- package/lib/exercises/math/calculLitteral/distributivity/doubleDistri.js +155 -0
- package/lib/exercises/math/calculLitteral/distributivity/idRmq1.d.ts +11 -0
- package/lib/exercises/math/calculLitteral/distributivity/idRmq1.d.ts.map +1 -0
- package/lib/exercises/math/calculLitteral/distributivity/idRmq1.js +147 -0
- package/lib/exercises/math/calculLitteral/distributivity/idRmq2.d.ts +11 -0
- package/lib/exercises/math/calculLitteral/distributivity/idRmq2.d.ts.map +1 -0
- package/lib/exercises/math/calculLitteral/distributivity/idRmq2.js +150 -0
- package/lib/exercises/math/calculLitteral/distributivity/idRmq3.d.ts +11 -0
- package/lib/exercises/math/calculLitteral/distributivity/idRmq3.d.ts.map +1 -0
- package/lib/exercises/math/calculLitteral/distributivity/idRmq3.js +143 -0
- package/lib/exercises/math/calculLitteral/distributivity/index.d.ts +5 -5
- package/lib/exercises/math/calculLitteral/distributivity/index.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/distributivity/index.js +5 -5
- package/lib/exercises/math/calculLitteral/distributivity/simpleDistri.d.ts +9 -0
- package/lib/exercises/math/calculLitteral/distributivity/simpleDistri.d.ts.map +1 -0
- package/lib/exercises/math/calculLitteral/distributivity/simpleDistri.js +116 -0
- package/lib/exercises/math/calculLitteral/distributivity/simpleDistriXCoeff.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/distributivity/simpleDistriXCoeff.js +1 -0
- package/lib/exercises/math/calculLitteral/equation/equa1.d.ts +11 -0
- package/lib/exercises/math/calculLitteral/equation/equa1.d.ts.map +1 -0
- package/lib/exercises/math/calculLitteral/equation/equa1.js +111 -0
- package/lib/exercises/math/calculLitteral/equation/equa2.d.ts +17 -0
- package/lib/exercises/math/calculLitteral/equation/equa2.d.ts.map +1 -0
- package/lib/exercises/math/calculLitteral/equation/equa2.js +164 -0
- package/lib/exercises/math/calculLitteral/equation/equa3.d.ts +12 -0
- package/lib/exercises/math/calculLitteral/equation/equa3.d.ts.map +1 -0
- package/lib/exercises/math/calculLitteral/equation/equa3.js +113 -0
- package/lib/exercises/math/calculLitteral/equation/equa4.d.ts +13 -0
- package/lib/exercises/math/calculLitteral/equation/equa4.d.ts.map +1 -0
- package/lib/exercises/math/calculLitteral/equation/equa4.js +106 -0
- package/lib/exercises/math/calculLitteral/equation/index.d.ts +4 -4
- package/lib/exercises/math/calculLitteral/equation/index.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/equation/index.js +4 -4
- package/lib/exercises/math/calculLitteral/simplifying/reduceExpression.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/simplifying/reduceExpression.js +5 -1
- package/lib/exercises/math/calculLitteral/simplifying/valuateExpression.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/simplifying/valuateExpression.js +4 -0
- package/lib/exercises/math/dataRepresentations/functionGraphReading.d.ts.map +1 -1
- package/lib/exercises/math/dataRepresentations/functionGraphReading.js +4 -0
- package/lib/exercises/math/dataRepresentations/pieChartReading.d.ts.map +1 -1
- package/lib/exercises/math/dataRepresentations/pieChartReading.js +4 -0
- package/lib/exercises/math/derivation/derivative/expDerivativeOne.d.ts.map +1 -1
- package/lib/exercises/math/derivation/derivative/expDerivativeOne.js +0 -6
- package/lib/exercises/math/derivation/derivative/powerFunctionDerivative.d.ts.map +1 -1
- package/lib/exercises/math/derivation/derivative/powerFunctionDerivative.js +30 -0
- package/lib/exercises/math/functions/affines/leadingCoefficient.d.ts.map +1 -1
- package/lib/exercises/math/functions/affines/leadingCoefficient.js +26 -11
- package/lib/exercises/math/functions/logarithm/logSimplifiying.js +1 -1
- package/lib/exercises/math/geometry/areas/rightTriangleArea.d.ts +1 -1
- package/lib/exercises/math/geometry/areas/rightTriangleArea.d.ts.map +1 -1
- package/lib/exercises/math/geometry/areas/rightTriangleArea.js +1 -1
- package/lib/exercises/math/geometry/areas/triangleArea.d.ts +1 -1
- package/lib/exercises/math/geometry/areas/triangleArea.d.ts.map +1 -1
- package/lib/exercises/math/geometry/areas/triangleArea.js +1 -1
- package/lib/exercises/math/geometry/euclidian/pythagoreOrThales.d.ts.map +1 -1
- package/lib/exercises/math/geometry/euclidian/pythagoreOrThales.js +6 -2
- package/lib/exercises/math/geometry/index.d.ts +1 -0
- package/lib/exercises/math/geometry/index.d.ts.map +1 -1
- package/lib/exercises/math/geometry/index.js +1 -1
- package/lib/exercises/math/geometry/lines/linesRelativePositions.d.ts.map +1 -1
- package/lib/exercises/math/geometry/lines/linesRelativePositions.js +4 -0
- package/lib/exercises/math/geometry/pythagore/pythagore.d.ts +1 -1
- package/lib/exercises/math/geometry/pythagore/pythagore.d.ts.map +1 -1
- package/lib/exercises/math/geometry/pythagore/pythagore.js +1 -1
- package/lib/exercises/math/geometry/pythagore/pythagoreCalcul.d.ts +1 -1
- package/lib/exercises/math/geometry/pythagore/pythagoreCalcul.d.ts.map +1 -1
- package/lib/exercises/math/geometry/pythagore/pythagoreCalcul.js +1 -1
- package/lib/exercises/math/geometry/quadrilaterals/quadrilateralRecognition.d.ts +4 -4
- package/lib/exercises/math/geometry/quadrilaterals/quadrilateralRecognition.d.ts.map +1 -1
- package/lib/exercises/math/geometry/quadrilaterals/quadrilateralRecognition.js +4 -4
- package/lib/exercises/math/geometry/thales/thales.d.ts +1 -1
- package/lib/exercises/math/geometry/thales/thales.d.ts.map +1 -1
- package/lib/exercises/math/geometry/thales/thales.js +1 -1
- package/lib/exercises/math/geometry/thales/thalesCalcul.d.ts +1 -1
- package/lib/exercises/math/geometry/thales/thalesCalcul.d.ts.map +1 -1
- package/lib/exercises/math/geometry/thales/thalesCalcul.js +1 -1
- package/lib/exercises/math/geometry/triangles/index.d.ts +1 -1
- package/lib/exercises/math/geometry/triangles/index.d.ts.map +1 -1
- package/lib/exercises/math/geometry/triangles/index.js +2 -1
- package/lib/exercises/math/geometry/triangles/triangleNature.d.ts +9 -0
- package/lib/exercises/math/geometry/triangles/triangleNature.d.ts.map +1 -0
- package/lib/exercises/math/geometry/triangles/triangleNature.js +121 -0
- package/lib/exercises/math/geometry/triangles/triangleThirdAngleValue.d.ts +9 -0
- package/lib/exercises/math/geometry/triangles/triangleThirdAngleValue.d.ts.map +1 -0
- package/lib/exercises/math/geometry/triangles/triangleThirdAngleValue.js +134 -0
- package/lib/exercises/math/geometry/vectors/scalarProduct/scalarProductViaNorms.d.ts +1 -1
- package/lib/exercises/math/geometry/vectors/scalarProduct/scalarProductViaNorms.d.ts.map +1 -1
- package/lib/exercises/math/geometry/vectors/scalarProduct/scalarProductViaNorms.js +1 -1
- package/lib/exercises/math/percent/findRightCalculForPriceEvolution.d.ts +10 -0
- package/lib/exercises/math/percent/findRightCalculForPriceEvolution.d.ts.map +1 -0
- package/lib/exercises/math/percent/findRightCalculForPriceEvolution.js +117 -0
- package/lib/exercises/math/percent/index.d.ts +1 -1
- package/lib/exercises/math/percent/index.d.ts.map +1 -1
- package/lib/exercises/math/percent/index.js +1 -1
- package/lib/exercises/math/percent/percentToDecimal.js +2 -2
- package/lib/exercises/math/powers/powersOfTenToDecimal.d.ts.map +1 -1
- package/lib/exercises/math/powers/powersOfTenToDecimal.js +4 -0
- package/lib/exercises/math/powers/powersProduct.d.ts.map +1 -1
- package/lib/exercises/math/powers/powersProduct.js +10 -14
- package/lib/exercises/math/probaStat/stats1var/choseReasoningForIndicator.d.ts.map +1 -1
- package/lib/exercises/math/probaStat/stats1var/choseReasoningForIndicator.js +4 -0
- package/lib/exercises/math/spaceGeometry/basis/spaceCoordinatesInPrism.d.ts.map +1 -1
- package/lib/exercises/math/spaceGeometry/basis/spaceCoordinatesInPrism.js +4 -0
- package/lib/exercises/math/squareRoots/simpifySquareRoot.js +1 -1
- package/lib/exercises/math/squareRoots/squareRootsProducts.js +1 -1
- package/lib/exercises/math/trigonometry/trigonometry.d.ts +1 -1
- package/lib/exercises/math/trigonometry/trigonometry.d.ts.map +1 -1
- package/lib/exercises/math/trigonometry/trigonometry.js +1 -1
- package/lib/exercises/math/trigonometry/trigonometryAngleCalcul.d.ts +1 -1
- package/lib/exercises/math/trigonometry/trigonometryAngleCalcul.d.ts.map +1 -1
- package/lib/exercises/math/trigonometry/trigonometryAngleCalcul.js +1 -1
- package/lib/exercises/math/trigonometry/trigonometrySideCalcul.d.ts +1 -1
- package/lib/exercises/math/trigonometry/trigonometrySideCalcul.d.ts.map +1 -1
- package/lib/exercises/math/trigonometry/trigonometrySideCalcul.js +2 -2
- package/lib/exercises/pc/index.d.ts +4 -4
- package/lib/exercises/pc/index.d.ts.map +1 -1
- package/lib/exercises/pc/index.js +4 -4
- package/lib/index.d.ts +23 -15
- package/lib/index.d.ts.map +1 -1
- package/lib/math/geometry/angle.d.ts +6 -0
- package/lib/math/geometry/angle.d.ts.map +1 -1
- package/lib/math/geometry/angle.js +20 -7
- package/lib/math/geometry/quadrilaterals/parallelogram.d.ts +23 -0
- package/lib/math/geometry/quadrilaterals/parallelogram.d.ts.map +1 -0
- package/lib/math/geometry/quadrilaterals/parallelogram.js +65 -0
- package/lib/math/geometry/quadrilaterals/quadrilateral.d.ts +15 -0
- package/lib/math/geometry/quadrilaterals/quadrilateral.d.ts.map +1 -0
- package/lib/math/geometry/quadrilaterals/quadrilateral.js +38 -0
- package/lib/math/geometry/quadrilaterals/rectangle.d.ts +24 -0
- package/lib/math/geometry/quadrilaterals/rectangle.d.ts.map +1 -0
- package/lib/math/geometry/quadrilaterals/rectangle.js +59 -0
- package/lib/math/geometry/quadrilaterals/rhombus.d.ts +19 -0
- package/lib/math/geometry/quadrilaterals/rhombus.d.ts.map +1 -0
- package/lib/math/geometry/quadrilaterals/rhombus.js +41 -0
- package/lib/math/geometry/quadrilaterals/square.d.ts +22 -0
- package/lib/math/geometry/quadrilaterals/square.d.ts.map +1 -0
- package/lib/math/geometry/quadrilaterals/square.js +38 -0
- package/lib/math/geometry/triangles/equilateralTriangle.d.ts +21 -0
- package/lib/math/geometry/triangles/equilateralTriangle.d.ts.map +1 -0
- package/lib/math/geometry/triangles/equilateralTriangle.js +52 -0
- package/lib/math/geometry/triangles/isoceleTriangle.d.ts +23 -0
- package/lib/math/geometry/triangles/isoceleTriangle.d.ts.map +1 -0
- package/lib/math/geometry/triangles/isoceleTriangle.js +66 -0
- package/lib/math/geometry/triangles/rightTriangle.d.ts +31 -0
- package/lib/math/geometry/triangles/rightTriangle.d.ts.map +1 -0
- package/lib/math/geometry/triangles/rightTriangle.js +108 -0
- package/lib/math/geometry/triangles/triangle.d.ts +68 -0
- package/lib/math/geometry/triangles/triangle.d.ts.map +1 -0
- package/lib/math/geometry/triangles/triangle.js +240 -0
- package/package.json +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { randfloat } from "../../../math/utils/random/randfloat.js";
|
|
2
|
+
import { round } from "../../../math/utils/round.js";
|
|
3
|
+
import { reifyAlgebraic } from "../../../tree/nodes/nodeConstructor.js";
|
|
4
|
+
import { Point, PointConstructor } from "../point.js";
|
|
5
|
+
import { Triangle, TriangleConstructor, } from "./triangle.js";
|
|
6
|
+
export class EquilateralTriangleConstructor {
|
|
7
|
+
static fromIdentifiers(identifiers) {
|
|
8
|
+
return new EquilateralTriangle(identifiers.points.map((p) => PointConstructor.fromIdentifiers(p)), {
|
|
9
|
+
anglesRadianValues: identifiers.props?.anglesRadianValues?.map((n) => reifyAlgebraic(n)),
|
|
10
|
+
anglesDegreeValues: identifiers.props?.anglesDegreeValues?.map((n) => reifyAlgebraic(n)),
|
|
11
|
+
sidesLengths: identifiers.props?.sidesLengths?.map((n) => n ? reifyAlgebraic(n) : undefined),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
static randomNiceSides({ names = ["A", "B", "C"], randomName = false, intSides = false, minAngle = 0, }) {
|
|
15
|
+
let vertices = [];
|
|
16
|
+
if (randomName)
|
|
17
|
+
vertices = TriangleConstructor.randomName();
|
|
18
|
+
else
|
|
19
|
+
vertices = names;
|
|
20
|
+
let A;
|
|
21
|
+
let B;
|
|
22
|
+
let C;
|
|
23
|
+
const origin = new Point("O", (0).toTree(), (0).toTree());
|
|
24
|
+
const angle = randfloat(0, 2 * Math.PI);
|
|
25
|
+
const midSide = randfloat(3, 8, 1);
|
|
26
|
+
C = new Point(vertices[2], midSide.toTree(), (0).toTree()).rotate(angle, origin);
|
|
27
|
+
B = new Point(vertices[1], (-midSide).toTree(), (0).toTree()).rotate(angle, origin);
|
|
28
|
+
const height = Math.sqrt(3) * midSide;
|
|
29
|
+
A = new Point(vertices[0], (0).toTree(), height.toTree()).rotate(angle, origin);
|
|
30
|
+
return new Triangle([A, B, C], {
|
|
31
|
+
sidesLengths: [
|
|
32
|
+
round(B.distanceTo(C), intSides ? 0 : 1).toTree(),
|
|
33
|
+
round(A.distanceTo(C), intSides ? 0 : 1).toTree(),
|
|
34
|
+
round(A.distanceTo(B), intSides ? 0 : 1).toTree(),
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export class EquilateralTriangle extends Triangle {
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
*/
|
|
43
|
+
constructor(points, props) {
|
|
44
|
+
super(points, props);
|
|
45
|
+
if (Math.abs(points[0].distanceTo(points[1]) - points[0].distanceTo(points[2])) > 0.001 ||
|
|
46
|
+
Math.abs(points[1].distanceTo(points[2]) - points[1].distanceTo(points[0])) > 0.001)
|
|
47
|
+
throw new Error("Not an equilateral triangle");
|
|
48
|
+
}
|
|
49
|
+
drawSidesDecoration() {
|
|
50
|
+
this.commands.push(`SetDecoration(${this.sides[1].ggbName}, 2)`, `SetDecoration(${this.sides[2].ggbName}, 2)`, `SetDecoration(${this.sides[0].ggbName}, 2)`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Point } from "../point.js";
|
|
2
|
+
import { Triangle, TriangleIdentifiers, TriangleProps } from "./triangle.js";
|
|
3
|
+
export declare abstract class IsoceleTriangleConstructor {
|
|
4
|
+
static fromIdentifiers(identifiers: TriangleIdentifiers): IsoceleTriangle;
|
|
5
|
+
static randomNiceSides({ names, randomName, intSides, minAngle, }: {
|
|
6
|
+
names?: string[] | undefined;
|
|
7
|
+
randomName?: boolean | undefined;
|
|
8
|
+
intSides?: boolean | undefined;
|
|
9
|
+
minAngle?: number | undefined;
|
|
10
|
+
}): Triangle;
|
|
11
|
+
}
|
|
12
|
+
type IsoceleTriangleProps = {} & TriangleProps;
|
|
13
|
+
export declare class IsoceleTriangle extends Triangle {
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param points points[0] est le sommet principal
|
|
17
|
+
* sides[0] est la base
|
|
18
|
+
*/
|
|
19
|
+
constructor(points: Point[], props?: IsoceleTriangleProps);
|
|
20
|
+
drawSidesDecoration(): void;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=isoceleTriangle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isoceleTriangle.d.ts","sourceRoot":"","sources":["../../../../src/math/geometry/triangles/isoceleTriangle.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,EAAoB,MAAM,aAAa,CAAC;AACtD,OAAO,EACL,QAAQ,EAER,mBAAmB,EACnB,aAAa,EACd,MAAM,eAAe,CAAC;AAEvB,8BAAsB,0BAA0B;IAC9C,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,mBAAmB,GAAG,eAAe;IAgBzE,MAAM,CAAC,eAAe,CAAC,EACrB,KAAuB,EACvB,UAAkB,EAClB,QAAgB,EAChB,QAAY,GACb;;;;;KAAA,GAAG,QAAQ;CA8Cb;AAED,KAAK,oBAAoB,GAAG,EAAE,GAAG,aAAa,CAAC;AAC/C,qBAAa,eAAgB,SAAQ,QAAQ;IAC3C;;;;OAIG;gBACS,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,CAAC,EAAE,oBAAoB;IAUzD,mBAAmB,IAAI,IAAI;CAM5B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { randfloat } from "../../../math/utils/random/randfloat.js";
|
|
2
|
+
import { round } from "../../../math/utils/round.js";
|
|
3
|
+
import { reifyAlgebraic } from "../../../tree/nodes/nodeConstructor.js";
|
|
4
|
+
import { Angle } from "../angle.js";
|
|
5
|
+
import { Point, PointConstructor } from "../point.js";
|
|
6
|
+
import { Triangle, TriangleConstructor, } from "./triangle.js";
|
|
7
|
+
export class IsoceleTriangleConstructor {
|
|
8
|
+
static fromIdentifiers(identifiers) {
|
|
9
|
+
return new IsoceleTriangle(identifiers.points.map((p) => PointConstructor.fromIdentifiers(p)), {
|
|
10
|
+
anglesRadianValues: identifiers.props?.anglesRadianValues?.map((n) => reifyAlgebraic(n)),
|
|
11
|
+
anglesDegreeValues: identifiers.props?.anglesDegreeValues?.map((n) => reifyAlgebraic(n)),
|
|
12
|
+
sidesLengths: identifiers.props?.sidesLengths?.map((n) => n ? reifyAlgebraic(n) : undefined),
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
static randomNiceSides({ names = ["A", "B", "C"], randomName = false, intSides = false, minAngle = 0, }) {
|
|
16
|
+
let vertices = [];
|
|
17
|
+
if (randomName)
|
|
18
|
+
vertices = TriangleConstructor.randomName();
|
|
19
|
+
else
|
|
20
|
+
vertices = names;
|
|
21
|
+
let A;
|
|
22
|
+
let B;
|
|
23
|
+
let C;
|
|
24
|
+
const anglesAreNice = () => {
|
|
25
|
+
const values = [
|
|
26
|
+
new Angle([C, B, A]).evaluate(),
|
|
27
|
+
new Angle([A, C, B]).evaluate(),
|
|
28
|
+
new Angle([B, A, C]).evaluate(),
|
|
29
|
+
];
|
|
30
|
+
if (minAngle)
|
|
31
|
+
return values.every((v) => v > minAngle && v < 180 - minAngle);
|
|
32
|
+
return values.every((v) => v > 20 && v < 110);
|
|
33
|
+
};
|
|
34
|
+
do {
|
|
35
|
+
const origin = new Point("O", (0).toTree(), (0).toTree());
|
|
36
|
+
const angle = randfloat(0, 2 * Math.PI);
|
|
37
|
+
const midBase = randfloat(3, 8, 1);
|
|
38
|
+
const height = randfloat(3, 8, 1, [2 * midBase]);
|
|
39
|
+
C = new Point(vertices[2], midBase.toTree(), (0).toTree()).rotate(angle, origin);
|
|
40
|
+
B = new Point(vertices[1], (-midBase).toTree(), (0).toTree()).rotate(angle, origin);
|
|
41
|
+
A = new Point(vertices[0], (0).toTree(), height.toTree()).rotate(angle, origin);
|
|
42
|
+
} while (!anglesAreNice());
|
|
43
|
+
return new Triangle([A, B, C], {
|
|
44
|
+
sidesLengths: [
|
|
45
|
+
round(B.distanceTo(C), intSides ? 0 : 1).toTree(),
|
|
46
|
+
round(A.distanceTo(C), intSides ? 0 : 1).toTree(),
|
|
47
|
+
round(A.distanceTo(B), intSides ? 0 : 1).toTree(),
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export class IsoceleTriangle extends Triangle {
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
* @param points points[0] est le sommet principal
|
|
56
|
+
* sides[0] est la base
|
|
57
|
+
*/
|
|
58
|
+
constructor(points, props) {
|
|
59
|
+
super(points, props);
|
|
60
|
+
if (Math.abs(points[0].distanceTo(points[1]) - points[0].distanceTo(points[2])) > 0.001)
|
|
61
|
+
throw new Error("Not an isocele triangle");
|
|
62
|
+
}
|
|
63
|
+
drawSidesDecoration() {
|
|
64
|
+
this.commands.push(`SetDecoration(${this.sides[1].ggbName}, 2)`, `SetDecoration(${this.sides[2].ggbName}, 2)`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Angle } from "../angle.js";
|
|
2
|
+
import { Point } from "../point.js";
|
|
3
|
+
import { Triangle, TriangleIdentifiers, TriangleProps } from "./triangle.js";
|
|
4
|
+
export declare abstract class RightTriangleConstructor {
|
|
5
|
+
static randomNiceSides({ names, randomName, }: {
|
|
6
|
+
names?: string[] | undefined;
|
|
7
|
+
randomName?: boolean | undefined;
|
|
8
|
+
}): RightTriangle;
|
|
9
|
+
static randomNiceAngles({ names, randomName, niceSideIndex, }: {
|
|
10
|
+
names?: string[];
|
|
11
|
+
randomName?: boolean;
|
|
12
|
+
niceSideIndex?: number;
|
|
13
|
+
}): RightTriangle;
|
|
14
|
+
static fromIdentifiers(identifiers: TriangleIdentifiers): RightTriangle;
|
|
15
|
+
}
|
|
16
|
+
type RightTriangleProps = {} & TriangleProps;
|
|
17
|
+
export declare class RightTriangle extends Triangle {
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param points points[0] is right angle
|
|
21
|
+
* sides[0] is the hypotenuse (side "A" = "BC")
|
|
22
|
+
* angles[0] is angle A (90°)
|
|
23
|
+
*/
|
|
24
|
+
constructor(points: Point[], props?: RightTriangleProps);
|
|
25
|
+
getRightAngle(): Angle;
|
|
26
|
+
getPythagorianTex(): string;
|
|
27
|
+
getOppositeSide(summitIndex: number): import("../segment.js").Segment;
|
|
28
|
+
getAdjacentSide(summitIndex: number): import("../segment.js").Segment;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=rightTriangle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rightTriangle.d.ts","sourceRoot":"","sources":["../../../../src/math/geometry/triangles/rightTriangle.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,KAAK,EAAoB,MAAM,aAAa,CAAC;AACtD,OAAO,EACL,QAAQ,EAER,mBAAmB,EACnB,aAAa,EACd,MAAM,eAAe,CAAC;AAEvB,8BAAsB,wBAAwB;IAC5C,MAAM,CAAC,eAAe,CAAC,EACrB,KAAuB,EACvB,UAAkB,GACnB;;;KAAA,GAAG,aAAa;IAqCjB,MAAM,CAAC,gBAAgB,CAAC,EACtB,KAAuB,EACvB,UAAkB,EAClB,aAAyB,GAC1B,EAAE;QACD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB;IA0CD,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,mBAAmB;CAaxD;AAED,KAAK,kBAAkB,GAAG,EAAE,GAAG,aAAa,CAAC;AAC7C,qBAAa,aAAc,SAAQ,QAAQ;IACzC;;;;;OAKG;gBACS,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,CAAC,EAAE,kBAAkB;IAKvD,aAAa,IAAI,KAAK;IAMtB,iBAAiB;IAIjB,eAAe,CAAC,WAAW,EAAE,MAAM;IAInC,eAAe,CAAC,WAAW,EAAE,MAAM;CAKpC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { reifyAlgebraic } from "../../../tree/nodes/nodeConstructor.js";
|
|
2
|
+
import { random } from "../../../utils/alea/random.js";
|
|
3
|
+
import { pythagoricianTripletsNiceAngles, } from "../../utils/geometry/pythagoricianTriplets.js";
|
|
4
|
+
import { randfloat } from "../../utils/random/randfloat.js";
|
|
5
|
+
import { randint } from "../../utils/random/randint.js";
|
|
6
|
+
import { round } from "../../utils/round.js";
|
|
7
|
+
import { Point, PointConstructor } from "../point.js";
|
|
8
|
+
import { Triangle, TriangleConstructor, } from "./triangle.js";
|
|
9
|
+
export class RightTriangleConstructor {
|
|
10
|
+
static randomNiceSides({ names = ["A", "B", "C"], randomName = false, }) {
|
|
11
|
+
let vertices = [];
|
|
12
|
+
if (randomName)
|
|
13
|
+
vertices = TriangleConstructor.randomName();
|
|
14
|
+
else
|
|
15
|
+
vertices = names;
|
|
16
|
+
const triplet = random(pythagoricianTripletsNiceAngles);
|
|
17
|
+
// const triplet = pythagoricianTriplets[0];
|
|
18
|
+
const coeff = random([1, 2, 0.1, 0.2, 0.25, 0.4, 0.5, 0.75, 0.8]);
|
|
19
|
+
let [ac, ab, bc] = triplet.map((e) => round(e * coeff, 4));
|
|
20
|
+
// const angles = [
|
|
21
|
+
// frac(PiNode, 2),
|
|
22
|
+
// frac(multiply(round(Math.asin(ac / bc), 2), PiNode), 180),
|
|
23
|
+
// frac(multiply(round(Math.asin(ab / bc), 2), PiNode), 180),
|
|
24
|
+
// ];
|
|
25
|
+
const angle = randfloat(0, 2 * Math.PI);
|
|
26
|
+
//on construit [AC] sur (Ox) de milieu O et de taille 2*xRand
|
|
27
|
+
//puis [AB] perpendiculaire à (AB) de taille yRand
|
|
28
|
+
//puis on rotate
|
|
29
|
+
const midAc = ac / 2;
|
|
30
|
+
const origin = new Point("O", (0).toTree(), (0).toTree());
|
|
31
|
+
const A = new Point(vertices[0], (-midAc).toTree(), (0).toTree()).rotate(angle, origin);
|
|
32
|
+
const C = new Point(vertices[2], midAc.toTree(), (0).toTree()).rotate(angle, origin);
|
|
33
|
+
const B = new Point(vertices[1], (-midAc).toTree(), ab.toTree()).rotate(angle, origin);
|
|
34
|
+
return new RightTriangle([A, B, C], {
|
|
35
|
+
sidesLengths: [bc.toTree(), ac.toTree(), ab.toTree()],
|
|
36
|
+
// anglesRadianValues: angles,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
static randomNiceAngles({ names = ["A", "B", "C"], randomName = false, niceSideIndex = undefined, }) {
|
|
40
|
+
let vertices = [];
|
|
41
|
+
if (randomName)
|
|
42
|
+
vertices = TriangleConstructor.randomName();
|
|
43
|
+
else
|
|
44
|
+
vertices = names;
|
|
45
|
+
const angleB = randfloat(20, 60, 1);
|
|
46
|
+
const angleC = round(90 - angleB, 1);
|
|
47
|
+
const angles = [90, angleB, angleC];
|
|
48
|
+
//a / sin(A) = b/sin(B) = c/sin(C)
|
|
49
|
+
const niceSide = niceSideIndex !== undefined ? niceSideIndex : randint(0, 3);
|
|
50
|
+
const sideLenght = randfloat(1, 20, 1);
|
|
51
|
+
const sidesLenghts = angles.map((angle, index) => index === niceSideIndex
|
|
52
|
+
? sideLenght
|
|
53
|
+
: (Math.sin((angle * Math.PI) / 180) * sideLenght) /
|
|
54
|
+
Math.sin((angles[niceSide] * Math.PI) / 180));
|
|
55
|
+
const angle = randfloat(0, 2 * Math.PI);
|
|
56
|
+
//on construit [AC] sur (Ox) de milieu O et de taille 2*xRand
|
|
57
|
+
//puis [AB] perpendiculaire à (AB) de taille yRand
|
|
58
|
+
//puis on rotate
|
|
59
|
+
const midAc = sidesLenghts[1] / 2;
|
|
60
|
+
const origin = new Point("O", (0).toTree(), (0).toTree());
|
|
61
|
+
const A = new Point(vertices[0], (-midAc).toTree(), (0).toTree()).rotate(angle, origin);
|
|
62
|
+
const C = new Point(vertices[2], midAc.toTree(), (0).toTree()).rotate(angle, origin);
|
|
63
|
+
const B = new Point(vertices[1], (-midAc).toTree(), sidesLenghts[2].toTree()).rotate(angle, origin);
|
|
64
|
+
return new RightTriangle([A, B, C], {
|
|
65
|
+
sidesLengths: sidesLenghts.map((s) => s.toTree()),
|
|
66
|
+
anglesDegreeValues: angles.map((a) => a.toTree()),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
static fromIdentifiers(identifiers) {
|
|
70
|
+
return new RightTriangle(identifiers.points.map((p) => PointConstructor.fromIdentifiers(p)), {
|
|
71
|
+
anglesRadianValues: identifiers.props?.anglesRadianValues?.map((n) => reifyAlgebraic(n)),
|
|
72
|
+
sidesLengths: identifiers.props?.sidesLengths?.map((n) => n ? reifyAlgebraic(n) : undefined),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export class RightTriangle extends Triangle {
|
|
77
|
+
/**
|
|
78
|
+
*
|
|
79
|
+
* @param points points[0] is right angle
|
|
80
|
+
* sides[0] is the hypotenuse (side "A" = "BC")
|
|
81
|
+
* angles[0] is angle A (90°)
|
|
82
|
+
*/
|
|
83
|
+
constructor(points, props) {
|
|
84
|
+
super(points, props);
|
|
85
|
+
if (!this.isRight())
|
|
86
|
+
throw new Error("Not a right triangle");
|
|
87
|
+
this.commands.push(...this.angles[0].toCommands());
|
|
88
|
+
}
|
|
89
|
+
getRightAngle() {
|
|
90
|
+
const angle = this.angles.find((a) => a.isRight());
|
|
91
|
+
if (!angle)
|
|
92
|
+
throw new Error("Not a right triangle");
|
|
93
|
+
return angle;
|
|
94
|
+
}
|
|
95
|
+
getPythagorianTex() {
|
|
96
|
+
return `${this.sides[0].toInsideName()}^2=${this.sides[1].toInsideName()}^2+${this.sides[2].toInsideName()}^2`;
|
|
97
|
+
}
|
|
98
|
+
getOppositeSide(summitIndex) {
|
|
99
|
+
if (summitIndex === 0)
|
|
100
|
+
throw Error("Right angle has no opposite side");
|
|
101
|
+
return this.sides[summitIndex];
|
|
102
|
+
}
|
|
103
|
+
getAdjacentSide(summitIndex) {
|
|
104
|
+
if (summitIndex === 0)
|
|
105
|
+
throw Error("Right angle has no adjacent side");
|
|
106
|
+
return this.sides[3 - summitIndex];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Point, PointIdentifiers } from "../point.js";
|
|
2
|
+
import { Segment } from "../segment.js";
|
|
3
|
+
import { Angle } from "../angle.js";
|
|
4
|
+
import { AlgebraicNode } from "../../../tree/nodes/algebraicNode.js";
|
|
5
|
+
import { NodeIdentifiers } from "../../../tree/nodes/nodeConstructor.js";
|
|
6
|
+
export type TriangleIdentifiers = {
|
|
7
|
+
points: PointIdentifiers[];
|
|
8
|
+
props?: TrianglePropsIdentifiers;
|
|
9
|
+
};
|
|
10
|
+
export declare abstract class TriangleConstructor {
|
|
11
|
+
static fromIdentifiers(identifiers: TriangleIdentifiers): Triangle;
|
|
12
|
+
static randomNiceSides({ names, randomName, intSides, minAngle, }: {
|
|
13
|
+
names?: string[] | undefined;
|
|
14
|
+
randomName?: boolean | undefined;
|
|
15
|
+
intSides?: boolean | undefined;
|
|
16
|
+
minAngle?: number | undefined;
|
|
17
|
+
}): Triangle;
|
|
18
|
+
static randomName(): string[];
|
|
19
|
+
}
|
|
20
|
+
export type TrianglePropsIdentifiers = {
|
|
21
|
+
sidesLengths?: (NodeIdentifiers | undefined)[];
|
|
22
|
+
anglesRadianValues?: NodeIdentifiers[];
|
|
23
|
+
anglesDegreeValues?: NodeIdentifiers[];
|
|
24
|
+
};
|
|
25
|
+
export type TriangleProps = {
|
|
26
|
+
roundSidesTo?: number;
|
|
27
|
+
sidesLengths?: (AlgebraicNode | undefined)[];
|
|
28
|
+
anglesRadianValues?: AlgebraicNode[];
|
|
29
|
+
anglesDegreeValues?: AlgebraicNode[];
|
|
30
|
+
};
|
|
31
|
+
export declare class Triangle {
|
|
32
|
+
angles: Angle[];
|
|
33
|
+
points: Point[];
|
|
34
|
+
sides: Segment[];
|
|
35
|
+
commands: string[];
|
|
36
|
+
name: string;
|
|
37
|
+
props?: TriangleProps;
|
|
38
|
+
constructor(points: Point[], props?: TriangleProps);
|
|
39
|
+
toIdentifiers(): TriangleIdentifiers;
|
|
40
|
+
getPerimeter(): number;
|
|
41
|
+
getArea(): number;
|
|
42
|
+
isRight(): Boolean;
|
|
43
|
+
isEquilateral(): Boolean;
|
|
44
|
+
isIsosceles(): Boolean;
|
|
45
|
+
isScalene(): boolean;
|
|
46
|
+
highlightSide(index: number, opts: {
|
|
47
|
+
color?: string;
|
|
48
|
+
caption?: string;
|
|
49
|
+
}): void;
|
|
50
|
+
highlightAngle(index: number, opts?: {
|
|
51
|
+
color?: string;
|
|
52
|
+
showValue?: boolean;
|
|
53
|
+
}): void;
|
|
54
|
+
showSidesLength(hiddenSides?: number[]): void;
|
|
55
|
+
getHeight(summitIndex: number, opts?: {
|
|
56
|
+
footName?: string;
|
|
57
|
+
}): Segment;
|
|
58
|
+
drawHeight(summitIndex: number, opts?: {
|
|
59
|
+
footName?: string;
|
|
60
|
+
footPoint?: Point;
|
|
61
|
+
}): void;
|
|
62
|
+
generateCoords(): number[];
|
|
63
|
+
drawAngles(hidden: number[], opts?: {
|
|
64
|
+
fitCaption: boolean;
|
|
65
|
+
color?: string;
|
|
66
|
+
}): void;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=triangle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triangle.d.ts","sourceRoot":"","sources":["../../../../src/math/geometry/triangles/triangle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAoB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAExE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAKpC,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAClE,OAAO,EAEL,eAAe,EAEhB,MAAM,qCAAqC,CAAC;AAG7C,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,wBAAwB,CAAC;CAClC,CAAC;AAEF,8BAAsB,mBAAmB;IACvC,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,mBAAmB,GAAG,QAAQ;IAgBlE,MAAM,CAAC,eAAe,CAAC,EACrB,KAAuB,EACvB,UAAkB,EAClB,QAAgB,EAChB,QAAY,GACb;;;;;KAAA,GAAG,QAAQ;IA+CZ,MAAM,CAAC,UAAU;CAQlB;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,YAAY,CAAC,EAAE,CAAC,eAAe,GAAG,SAAS,CAAC,EAAE,CAAC;IAC/C,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC;IACvC,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC;CACxC,CAAC;AACF,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,CAAC,aAAa,GAAG,SAAS,CAAC,EAAE,CAAC;IAC7C,kBAAkB,CAAC,EAAE,aAAa,EAAE,CAAC;IACrC,kBAAkB,CAAC,EAAE,aAAa,EAAE,CAAC;CACtC,CAAC;AACF,qBAAa,QAAQ;IACnB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,aAAa,CAAC;gBACV,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,CAAC,EAAE,aAAa;IA0ClD,aAAa,IAAI,mBAAmB;IAepC,YAAY,IAAI,MAAM;IAItB,OAAO,IAAI,MAAM;IASjB,OAAO,IAAI,OAAO;IAIlB,aAAa,IAAI,OAAO;IAMxB,WAAW,IAAI,OAAO;IAUtB,SAAS,IAAI,OAAO;IASpB,aAAa,CACX,KAAK,EAAE,MAAM,EACb,IAAI,EAAE;QACJ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB;IAcH,cAAc,CACZ,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;QACL,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB;IAKH,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE;IAQtC,SAAS,CACP,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;IAYH,UAAU,CACR,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,SAAS,CAAC,EAAE,KAAK,CAAC;KACnB;IAoCH,cAAc,IAAI,MAAM,EAAE;IAkB1B,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;CAgB5E"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { Point, PointConstructor } from "../point.js";
|
|
2
|
+
import { randomLetter } from "../../../utils/strings/randomLetter.js";
|
|
3
|
+
import { Segment } from "../segment.js";
|
|
4
|
+
import { Angle } from "../angle.js";
|
|
5
|
+
import { arrayRotation } from "../../../utils/arrays/rotation.js";
|
|
6
|
+
import { round } from "../../utils/round.js";
|
|
7
|
+
import { randfloat } from "../../utils/random/randfloat.js";
|
|
8
|
+
import { LineConstructor } from "../line.js";
|
|
9
|
+
import { reifyAlgebraic, } from "../../../tree/nodes/nodeConstructor.js";
|
|
10
|
+
import { randint } from "../../utils/random/randint.js";
|
|
11
|
+
export class TriangleConstructor {
|
|
12
|
+
static fromIdentifiers(identifiers) {
|
|
13
|
+
return new Triangle(identifiers.points.map((p) => PointConstructor.fromIdentifiers(p)), {
|
|
14
|
+
anglesRadianValues: identifiers.props?.anglesRadianValues?.map((n) => reifyAlgebraic(n)),
|
|
15
|
+
anglesDegreeValues: identifiers.props?.anglesDegreeValues?.map((n) => reifyAlgebraic(n)),
|
|
16
|
+
sidesLengths: identifiers.props?.sidesLengths?.map((n) => n ? reifyAlgebraic(n) : undefined),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
static randomNiceSides({ names = ["A", "B", "C"], randomName = false, intSides = false, minAngle = 0, }) {
|
|
20
|
+
let vertices = [];
|
|
21
|
+
if (randomName)
|
|
22
|
+
vertices = TriangleConstructor.randomName();
|
|
23
|
+
else
|
|
24
|
+
vertices = names;
|
|
25
|
+
let A;
|
|
26
|
+
let B;
|
|
27
|
+
let C;
|
|
28
|
+
const anglesAreNice = () => {
|
|
29
|
+
const values = [
|
|
30
|
+
new Angle([C, B, A]).evaluate(),
|
|
31
|
+
new Angle([A, C, B]).evaluate(),
|
|
32
|
+
new Angle([B, A, C]).evaluate(),
|
|
33
|
+
];
|
|
34
|
+
if (minAngle)
|
|
35
|
+
return values.every((v) => v > minAngle && v < 180 - minAngle);
|
|
36
|
+
return values.every((v) => v > 20 && v < 110);
|
|
37
|
+
};
|
|
38
|
+
do {
|
|
39
|
+
const angle = randfloat(0, 2 * Math.PI);
|
|
40
|
+
const addAngle = randfloat(Math.PI / 4, (3 * Math.PI) / 4);
|
|
41
|
+
//on construit [AC] sur (Ox) de milieu O et de taille 2*xRand
|
|
42
|
+
//puis [AB] sur (Ox) qu'on rotate
|
|
43
|
+
const xRand = intSides ? randint(5, 9) : randfloat(5, 8, 1);
|
|
44
|
+
const xRand2 = intSides ? randint(-5, 5) : randfloat(-5, 5, 1);
|
|
45
|
+
const origin = new Point("O", (0).toTree(), (0).toTree());
|
|
46
|
+
const startA = new Point(vertices[0], (-xRand).toTree(), (0).toTree());
|
|
47
|
+
A = startA.rotate(angle, origin);
|
|
48
|
+
C = new Point(vertices[2], xRand.toTree(), (0).toTree()).rotate(angle, origin);
|
|
49
|
+
B = new Point(vertices[1], (-xRand + xRand2).toTree(), (0).toTree()).rotate(angle + addAngle, startA);
|
|
50
|
+
} while (!anglesAreNice());
|
|
51
|
+
return new Triangle([A, B, C], {
|
|
52
|
+
sidesLengths: [
|
|
53
|
+
round(B.distanceTo(C), intSides ? 0 : 1).toTree(),
|
|
54
|
+
round(A.distanceTo(C), intSides ? 0 : 1).toTree(),
|
|
55
|
+
round(A.distanceTo(B), intSides ? 0 : 1).toTree(),
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
static randomName() {
|
|
60
|
+
const startVertix = randomLetter(true, ["Y", "Z"]);
|
|
61
|
+
return [
|
|
62
|
+
startVertix,
|
|
63
|
+
String.fromCharCode(startVertix.charCodeAt(0) + 1),
|
|
64
|
+
String.fromCharCode(startVertix.charCodeAt(0) + 2),
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export class Triangle {
|
|
69
|
+
angles;
|
|
70
|
+
points;
|
|
71
|
+
sides;
|
|
72
|
+
commands;
|
|
73
|
+
name;
|
|
74
|
+
props;
|
|
75
|
+
constructor(points, props) {
|
|
76
|
+
if (points.length !== 3)
|
|
77
|
+
throw new Error("Triangle must have 3 points");
|
|
78
|
+
this.props = props;
|
|
79
|
+
this.name = points.map((p) => p.name).join("");
|
|
80
|
+
this.points = points;
|
|
81
|
+
const anglePoints = [points[0], points[2], points[1]];
|
|
82
|
+
this.angles = [
|
|
83
|
+
new Angle(arrayRotation(anglePoints, 2), {
|
|
84
|
+
radianValueNode: props?.anglesRadianValues?.[0],
|
|
85
|
+
degreeValueNode: props?.anglesDegreeValues?.[0],
|
|
86
|
+
}),
|
|
87
|
+
new Angle(anglePoints, {
|
|
88
|
+
radianValueNode: props?.anglesRadianValues?.[1],
|
|
89
|
+
degreeValueNode: props?.anglesDegreeValues?.[1],
|
|
90
|
+
}),
|
|
91
|
+
new Angle(arrayRotation(anglePoints, 1), {
|
|
92
|
+
radianValueNode: props?.anglesRadianValues?.[2],
|
|
93
|
+
degreeValueNode: props?.anglesDegreeValues?.[2],
|
|
94
|
+
}),
|
|
95
|
+
];
|
|
96
|
+
this.sides = [
|
|
97
|
+
new Segment(points[1], points[2], {
|
|
98
|
+
lengthNode: props?.sidesLengths?.[0],
|
|
99
|
+
}),
|
|
100
|
+
new Segment(points[0], points[2], {
|
|
101
|
+
lengthNode: props?.sidesLengths?.[1],
|
|
102
|
+
}),
|
|
103
|
+
new Segment(points[0], points[1], {
|
|
104
|
+
lengthNode: props?.sidesLengths?.[2],
|
|
105
|
+
}),
|
|
106
|
+
];
|
|
107
|
+
this.commands = [
|
|
108
|
+
...points.flatMap((p) => p.toGGBCommand({
|
|
109
|
+
isFixed: true,
|
|
110
|
+
showLabel: true,
|
|
111
|
+
})),
|
|
112
|
+
...this.sides.flatMap((s) => s.toGGBCommands(false)),
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
toIdentifiers() {
|
|
116
|
+
return {
|
|
117
|
+
points: this.points.map((point) => point.toIdentifiers()),
|
|
118
|
+
props: {
|
|
119
|
+
anglesRadianValues: this.props?.anglesRadianValues?.map((n) => n.toIdentifiers()),
|
|
120
|
+
anglesDegreeValues: this.props?.anglesDegreeValues?.map((n) => n.toIdentifiers()),
|
|
121
|
+
sidesLengths: this.props?.sidesLengths?.map((n) => n?.toIdentifiers()),
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
getPerimeter() {
|
|
126
|
+
return this.sides.reduce((acc, curr) => acc + curr.getLength(), 0);
|
|
127
|
+
}
|
|
128
|
+
getArea() {
|
|
129
|
+
const s = this.getPerimeter() / 2;
|
|
130
|
+
const lengths = this.sides.map((s) => s.getLength());
|
|
131
|
+
return round(Math.sqrt(s * (s - lengths[0]) * (s - lengths[1]) * (s - lengths[2])), 6);
|
|
132
|
+
}
|
|
133
|
+
isRight() {
|
|
134
|
+
return this.angles.some((a) => a.isRight());
|
|
135
|
+
}
|
|
136
|
+
isEquilateral() {
|
|
137
|
+
const lengths = this.sides.map((s) => s.getLength());
|
|
138
|
+
return lengths[0] === lengths[1] && lengths[1] === lengths[2];
|
|
139
|
+
}
|
|
140
|
+
isIsosceles() {
|
|
141
|
+
const lengths = this.sides.map((s) => s.getLength());
|
|
142
|
+
return (lengths[0] === lengths[1] ||
|
|
143
|
+
lengths[1] === lengths[2] ||
|
|
144
|
+
lengths[0] === lengths[2]);
|
|
145
|
+
}
|
|
146
|
+
isScalene() {
|
|
147
|
+
const lengths = this.sides.map((s) => s.getLength());
|
|
148
|
+
return (lengths[0] !== lengths[1] &&
|
|
149
|
+
lengths[1] !== lengths[2] &&
|
|
150
|
+
lengths[0] !== lengths[2]);
|
|
151
|
+
}
|
|
152
|
+
highlightSide(index, opts) {
|
|
153
|
+
const side = this.sides[index];
|
|
154
|
+
if (opts.color)
|
|
155
|
+
this.commands.push(`SetColor(${side.ggbName}, "${opts.color}")`);
|
|
156
|
+
if (opts.caption) {
|
|
157
|
+
this.commands.push(...side.getFitCaptionCommands({
|
|
158
|
+
text: opts.caption,
|
|
159
|
+
color: opts.color,
|
|
160
|
+
}));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
highlightAngle(index, opts) {
|
|
164
|
+
this.commands.push(...this.angles[index].toCommands(opts));
|
|
165
|
+
}
|
|
166
|
+
showSidesLength(hiddenSides) {
|
|
167
|
+
this.commands.push(...this.sides
|
|
168
|
+
.filter((s, i) => !hiddenSides?.includes(i))
|
|
169
|
+
.flatMap((s) => s.getFitCaptionCommands()));
|
|
170
|
+
}
|
|
171
|
+
getHeight(summitIndex, opts) {
|
|
172
|
+
const base = LineConstructor.fromSegment(this.sides[summitIndex]);
|
|
173
|
+
const perp = base.getPerpendicular(this.points[summitIndex]);
|
|
174
|
+
const foot = perp.intersect(base, opts?.footName);
|
|
175
|
+
while (this.name.includes(foot.name)) {
|
|
176
|
+
foot.name = randomLetter(true);
|
|
177
|
+
}
|
|
178
|
+
const segmentHeight = new Segment(this.points[summitIndex], foot);
|
|
179
|
+
return segmentHeight;
|
|
180
|
+
}
|
|
181
|
+
drawHeight(summitIndex, opts) {
|
|
182
|
+
let height;
|
|
183
|
+
let foot;
|
|
184
|
+
if (opts?.footPoint) {
|
|
185
|
+
foot = opts.footPoint;
|
|
186
|
+
height = new Segment(this.points[summitIndex], foot);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
height = this.getHeight(summitIndex, opts);
|
|
190
|
+
foot = height.pointB;
|
|
191
|
+
}
|
|
192
|
+
const angle = new Angle([
|
|
193
|
+
this.points[summitIndex],
|
|
194
|
+
foot,
|
|
195
|
+
this.points[(summitIndex + 1) % 3],
|
|
196
|
+
]);
|
|
197
|
+
this.commands.push(...foot.toGGBCommand(), ...height.toGGBCommands(false, { style: 2 }), ...angle.toCommands());
|
|
198
|
+
if (!this.sides[summitIndex].includes(foot)) {
|
|
199
|
+
const distancesToSideSummits = [
|
|
200
|
+
this.sides[summitIndex].pointA,
|
|
201
|
+
this.sides[summitIndex].pointB,
|
|
202
|
+
].map((p) => p.distanceTo(foot));
|
|
203
|
+
const closestPoint = distancesToSideSummits[0] < distancesToSideSummits[1]
|
|
204
|
+
? this.sides[summitIndex].pointA
|
|
205
|
+
: this.sides[summitIndex].pointB;
|
|
206
|
+
const prolongement = new Segment(closestPoint, foot);
|
|
207
|
+
this.commands.push(...prolongement.toGGBCommands(false, { style: 2 }));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
generateCoords() {
|
|
211
|
+
const coords = this.points.map((p) => [p.x.evaluate(), p.y.evaluate()]);
|
|
212
|
+
const [x1, y1, x2, y2, x3, y3] = coords.flatMap((p) => p);
|
|
213
|
+
const [xMin, xMax, yMin, yMax] = [
|
|
214
|
+
Math.min(x1, x2, x3),
|
|
215
|
+
Math.max(x1, x2, x3),
|
|
216
|
+
Math.min(y1, y2, y3),
|
|
217
|
+
Math.max(y1, y2, y3),
|
|
218
|
+
];
|
|
219
|
+
const xDelta = Math.abs(xMax - xMin);
|
|
220
|
+
const yDelta = Math.abs(yMax - yMin);
|
|
221
|
+
return [
|
|
222
|
+
xMin - 0.1 * xDelta,
|
|
223
|
+
xMax + 0.1 * xDelta,
|
|
224
|
+
yMin - 0.1 * yDelta,
|
|
225
|
+
yMax + 0.1 * yDelta,
|
|
226
|
+
];
|
|
227
|
+
}
|
|
228
|
+
drawAngles(hidden, opts) {
|
|
229
|
+
this.angles.forEach((a, i) => {
|
|
230
|
+
if (!hidden.includes(i)) {
|
|
231
|
+
this.commands.push(...a.toCommands({ showValue: false, color: opts?.color }));
|
|
232
|
+
if (opts?.fitCaption)
|
|
233
|
+
this.commands.push(...a.getFitCaptionCommands({
|
|
234
|
+
size: "scriptsize",
|
|
235
|
+
color: opts?.color,
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|