// Le premier import et l'utilisation de iepLoadPromise est à commenter pour que le build:dicos fonctionne dans la v3
import iepLoadPromise from 'instrumenpoche'
import { angleOriente, droite, homothetie, longueur, milieu, norme, point, pointAdistance, pointSurSegment, rotation, segment, translation, translation2Points, vecteur } from './2d.js'
import { context } from './context.js'
import { bissectriceAuCompas, cercleCirconscrit, hauteur, mediane, mediatriceAuCompas, mediatriceRegleEquerre } from './iepMacros/droitesRemarquables.js'
import { paralleleAuCompas, paralleleAuCompasAvecDescription, paralleleRegleEquerre2points3epoint, paralleleRegleEquerreDroitePointAvecDescription, perpendiculaireCompasPoint, perpendiculaireCompasPointSurLaDroite, perpendiculaireRegleEquerre2points3epoint, perpendiculaireRegleEquerreDroitePoint, perpendiculaireRegleEquerrePointSurLaDroite } from './iepMacros/parallelesEtPerpendiculaires.js'
import { parallelogramme2sommetsConsecutifsCentre, parallelogramme3sommetsConsecutifs, parallelogrammeAngleCentre, partageSegment } from './iepMacros/parallelogrammes.js'
import { carre1point1longueur } from './iepMacros/quadrilateres.js'
import { demiTourPoint, demiTourPolygone, homothetiePoint, homothetiePolygone, rotationPoint, rotationPolygone, symetrieAxialePoint, symetrieAxialePolygone, translationPoint, translationPolygone } from './iepMacros/transformations.js'
import { triangle1longueur2angles, triangle2longueurs1angle, triangle3longueurs, triangleEquilateral, triangleEquilateral2Sommets, triangleRectangle2Cotes, triangleRectangleCoteHypotenuse } from './iepMacros/triangles.js'
const store = {}
export class StoreIep {
static getXml (id) {
return store[id]
}
static saveXml (id, xml) {
store[id] = xml
}
}
/*
* Classe parente de tous les objets Alea2iep
*
* @author Rémi Angot
*/
export default class Alea2iep {
constructor () {
this.idIEP = 0 // Identifiant pour les tracés
this.idHTML = 0 // Identifiant pour les div et le svg
this.tempo = 5 // Pause par défaut après une instruction
this.vitesse = 10 // Vitesse par défaut pour les déplacements d'instruments
this.couleur = 'blue' // Couleur par défaut
this.couleurCompas = 'forestgreen'
this.couleurTexte = 'black'
this.couleurPoint = 'black' // Couleur du nom des points
this.couleurCodage = '#f15929'
this.couleurTraitsDeConstruction = 'gray'
this.epaisseur = 2
this.epaisseurTraitsDeConstruction = 1
this.pointilles = false
this.liste_script = [] // Liste des instructions xml mise à jour par les méthodes
this.translationX = 0
this.translationY = 10 // Par défaut l'angle en haut à gauche est le point de coordonnées (0,10)
// Garde en mémoire les coordonnées extrêmes des objets créés
this.xMin = 0
this.yMin = 0
this.xMax = 0
this.yMax = 0
// Sauvegarde de l'état des instruments
this.regle = {
visibilite: false,
position: point(0, 0),
angle: 0,
longueur: 15,
zoom: 100
}
this.crayon = {
visibilite: false,
position: point(0, 0),
angle: 0,
zoom: 100
}
this.equerre = {
visibilite: false,
position: point(0, 0),
angle: 0,
zoom: 100
}
this.requerre = {
visibilite: false,
position: point(0, 0),
angle: 0,
zoom: 100
}
this.rapporteur = {
visibilite: false,
position: point(0, 0),
angle: 0,
rayon: 5.2,
zoom: 100
}
this.compas = {
visibilite: false,
position: point(0, 0),
angle: 0,
orientation: 'droite',
ecartement: 0,
leve: false,
zoom: 100
}
this.xml = ''
}
/** **** Fin du constructeur */
// Transforme les coordonnées MathALEA2D en coordonnées pour le XML d'IEP
x (A) {
const x = Math.round((A.x + this.translationX) * 30)
if (A.x > this.xMax) {
this.xMax = A.x
}
if (A.x < this.xMin) {
this.xMin = A.x
}
return x
}
y (A) {
const y = Math.round((-A.y + this.translationY) * 30)
if (A.y < this.yMin) {
this.yMin = A.y
}
if (A.y > this.yMax) {
this.yMax = A.y
}
return y
}
/**
* Renvoie le script xml
*
*/
script () {
if (this.xml.length > 1) {
return this.xml
} else {
let codeXML = '<?xml version="1.0" encoding="UTF-8"?>\n'
codeXML += '<INSTRUMENPOCHE version="2">\n'
codeXML += this.liste_script.join('\n')
codeXML += '\n</INSTRUMENPOCHE>'
return codeXML
}
}
/**
* Renvoie le code HTML de l'animation
* Il est important de spécifier le numéro de l'exercice et de la question pour avoir un identifiant unique sur la page
* @param {int} numeroExercice - Numéro de l'exercice
* @param {int} i - Numéro de la question
*/
html (id1, id2 = 0) {
if (context.versionMathalea === 3) {
if (context.isHtml) {
const id = `IEP_${id1}_${id2}`
StoreIep.saveXml(id, this.script())
const codeHTML = `<alea-instrumenpoche id=${id}>`
return codeHTML
}
return ''
} else {
if (context.isHtml) {
const id = `IEP_${id1}_${id2}`
window.listeScriptsIep[id] = this.script() // On ajoute le script
const codeHTML = `<div id="IEPContainer${id}" ></div>`
window.listeAnimationsIepACharger.push(id)
return codeHTML
}
return ''
}
}
/**
* Créé un bouton qui permettra d'afficher ou masquer l'animation
* Il est important de spécifier le numéro de l'exercice et de la question pour avoir un identifiant unique sur la page
* @param {int} numeroExercice - Numéro de l'exercice
* @param {int} i - Numéro de la question
* @return Code HTML avec le bouton qui affiche ou masque un div avec l'animation
*/
htmlBouton (id1, id2 = '') {
if (context.versionMathalea === 3) {
if (context.isHtml) {
const id = `IEP_${id1}_${id2}`
StoreIep.saveXml(id, this.script())
const codeHTML = `<alea-buttoninstrumenpoche id=${id}>`
return codeHTML
}
return ''
} else {
if (context.isHtml) {
const id = `IEP_${id1}_${id2}`
window.listeScriptsIep[id] = this.script() // On ajoute le script
const codeHTML = `<br><button class="ui mini compact button" id="btnAnimation${id}" onclick="toggleVisibilityIEP('${id}')" style="margin-top:20px"><i class="large play circle outline icon"></i>Voir animation</button>
<div id="IEPContainer${id}" style="display: none;" ></div>`
if (!window.toggleVisibilityIEP) {
window.toggleVisibilityIEP = function (id) {
const element = document.getElementById(`IEPContainer${id}`)
const elementBtn = document.getElementById(`btnAnimation${id}`)
const xml = window.listeScriptsIep[id]
if (element.style.display === 'none') {
element.style.display = 'block'
element.style.marginTop = '30px'
// On ajoute une regle css max-width pour éviter le débordement
element.style.maxWidth = '95%'
elementBtn.innerHTML = '<i class="large stop circle outline icon"></i>Masquer animation'
iepLoadPromise(element, xml, { zoom: true, autostart: true }).then(iepApp => {
// la figure est chargée
// On surcharge la propriété CSS min-width après que la promesse ait été satisfaite sinon ça marche pas !
element.style.minWidth = '90%'
}).catch(error => { console.log(error) })
} else {
element.style.display = 'none'
elementBtn.innerHTML = '<i class="large play circle outline icon"></i>Voir animation'
}
}
}
return codeHTML
} else {
return ''
}
}
}
/**
**************************
*** FONCTIONS COMMUNES ***
**************************
*/
/**
*
* Permet de déplacer le repère utilisé pour l'animation en précisant les bornes xmin et ymax
* @param {int} xmin
* @param {int} ymax
*/
recadre (xmin, ymax) {
this.translationX = 1 - xmin
this.translationY = ymax + 3
}
/**
*
* @param {int} width
* @param {int} height
*/
taille (width, height) {
this.liste_script.push(`<viewBox width="${width}" height="${height}" />`)
}
/**
*
* @param {string} objet - 'regle', 'equerre', 'requerre, 'compas', 'rapporteur' ou 'crayon'
* @param {point} A - Point (0, 0) par défaut
* @param {objet} options - { tempo : 10 }
*/
montrer (objet, A, { tempo = this.tempo, vitesse = this.vitesse } = {}) {
if (!this[objet].visibilite || this[objet].position !== A) { // On ajoute une ligne xml que si l'objet est caché ou doit apparaitre à un autre endroit
let codeXML = ''
let A1
if (typeof A === 'undefined') { // A1 est une copie de A ou (0,0) si A n'est pas défini
A1 = this[objet].position
} else {
A1 = A
}
if (this[objet].visibilite) { // S'il est déjà visible, montrer devient un déplacer
this.deplacer(objet, A1, { tempo, vitesse })
} else {
codeXML = `<action objet="${objet}" mouvement="montrer" abscisse="${this.x(A1)}" ordonnee="${this.y(A1)}" tempo="${tempo}" />`
this[objet].visibilite = true
}
this[objet].position = A1
this.liste_script.push(codeXML)
}
}
/**
*
* @param {point} A
* @param {objet} options
*/
regleMontrer (A, options) {
this.montrer('regle', A, options)
}
/**
*
* @param {point} A
* @param {objet} options
*/
crayonMontrer (A, options) {
this.montrer('crayon', A, options)
}
/**
*
* @param {point} A
* @param {objet} options
*/
equerreMontrer (A, options) {
this.montrer('equerre', A, options)
}
/**
*
* @param {point} A
* @param {objet} options
*/
requerreMontrer (A, options) {
this.montrer('requerre', A, options)
}
/**
*
* @param {point} A
* @param {objet} options
*/
compasMontrer (A, options) {
this.montrer('compas', A, options)
}
/**
*
* @param {point} A
* @param {objet} options
*/
rapporteurMontrer (A, options) {
this.montrer('rapporteur', A, options)
}
/**
*
* @param {string} objet - 'regle', 'equerre', 'requerre, 'compas', 'rapporteur' ou 'crayon'
* @param {objet} param1
*/
masquer (objet, { tempo = this.tempo } = {}) {
if (this[objet].visibilite) { // On ajoute une ligne xml que si l'objet est visible
const codeXML = `<action objet="${objet}" mouvement="masquer" tempo="${tempo}" />`
this[objet].visibilite = false
this.liste_script.push(codeXML)
}
}
/**
*
* @param {objet} options
*/
regleMasquer (options) {
this.masquer('regle', options)
}
/**
*
* @param {objet} options
*/
crayonMasquer (options) {
this.masquer('crayon', options)
}
/**
*
* @param {objet} options
*/
equerreMasquer (options) {
this.masquer('equerre', options)
}
/**
*
* @param {objet} options
*/
requerreMasquer (options) {
this.masquer('requerre', options)
}
/**
*
* @param {objet} options
*/
compasMasquer (options) {
this.masquer('compas', options)
}
/**
*
* @param {objet} options
*/
rapporteurMasquer (options) {
this.masquer('rapporteur', options)
}
/**
*
* @param {string} objet - 'regle', 'equerre', 'requerre, 'compas', 'rapporteur' ou 'crayon'
* @param {point} A
* @param {objet} options
*/
deplacer (objet, A, { tempo = this.tempo, vitesse = this.vitesse } = {}) {
if (this[objet].position !== A) { // On n'ajoute une commande xml que s'il y a vraiment un déplacement
const codeXML = `<action objet="${objet}" mouvement="translation" abscisse="${this.x(A)}" ordonnee="${this.y(A)}" tempo="${tempo}" vitesse="${vitesse}" />`
this[objet].position = A
this.liste_script.push(codeXML)
}
}
/**
*
* @param {point} A
* @param {objet} options
*/
regleDeplacer (A, options) {
this.deplacer('regle', A, options)
}
/**
*
* @param {point} A
* @param {objet} options
*/
texteDeplacer (id, A, { tempo = this.tempo, vitesse = this.vitesse } = {}) {
const codeXML = `<action objet="texte" id="${id}" mouvement="translation" abscisse="${this.x(A)}" ordonnee="${this.y(A)}" tempo="${tempo}" vitesse="${vitesse}" />`
this.liste_script.push(codeXML)
}
/**
*
* @param {point} A
* @param {objet} options
*/
crayonDeplacer (A, options) {
this.deplacer('crayon', A, options)
}
/**
*
* @param {point} A
* @param {objet} options
*/
equerreDeplacer (A, options) {
this.deplacer('equerre', A, options)
}
/**
*
* @param {point} A
* @param {objet} options
*/
requerreDeplacer (A, options) {
this.deplacer('requerre', A, options)
}
/**
*
* @param {point} A
* @param {objet} options
*/
compasDeplacer (A, options) {
this.deplacer('compas', A, options)
}
/**
*
* @param {point} A
* @param {objet} options
*/
rapporteurDeplacer (A, options) {
this.deplacer('rapporteur', A, options)
}
/**
*
* @param {string} objet - 'regle', 'equerre', 'requerre, 'compas', 'rapporteur' ou 'crayon'
* @param {int} angle
* @param {objet} options
*/
rotation (objet, a, { tempo = this.tempo, sens = Math.round(this.vitesse / 2) } = {}) {
let angle
if (a.typeObjet === 'point') {
const d = droite(this[objet].position, a)
angle = d.angleAvecHorizontale
} else {
angle = a
}
if (this[objet].angle !== a) { // Si la rotation est inutile, on ne la fait pas
// Les angles de MathALEA2D et de IEP sont opposés !!!!!
const codeXML = `<action objet="${objet}" mouvement="rotation" angle="${-1 * angle}" tempo="${tempo}" sens="${sens}" />`
this[objet].angle = angle
if (typeof angle === 'number' && isFinite(angle)) {
this.liste_script.push(codeXML)
} else {
console.log('Angle de rotation non défini pour l\'objet .', objet)
}
}
}
/**
*
* @param {int} angle
* @param {objet} options
*/
regleRotation (angle, options) {
this.rotation('regle', angle, options)
}
/**
*
* @param {int} angle
* @param {objet} options
*/
crayonRotation (angle, options) {
this.rotation('crayon', angle, options)
}
/**
*
* @param {int} angle
* @param {objet} options
*/
equerreRotation (angle, options) {
this.rotation('equerre', angle, options)
}
/**
*
* @param {int} angle
* @param {objet} options
*/
requerreRotation (angle, options) {
this.rotation('requerre', angle, options)
}
/**
*
* @param {int} angle
* @param {objet} options
*/
compasRotation (angle, options) {
this.rotation('compas', angle, options)
}
/**
*
* @param {int} angle
* @param {objet} options
*/
rapporteurRotation (angle, options) {
this.rotation('rapporteur', angle, options)
}
/**
* @param {string} objet - 'regle', 'equerre', 'requerre, 'compas' ou 'rapporteur'
* @param {int} pourcentage 200 pour doubler la taille
* @param {objet} options tempo = 0 par défaut
*/
zoom (objet, echelle, { tempo = 0 } = {}) {
this[objet].zoom = echelle
this.liste_script.push(`<action echelle="${echelle}" mouvement="zoom" objet="${objet}" tempo="${tempo}" />`)
}
/**
*
* @param {int} pourcentage 200 pour doubler la taille
* @param {objet} options tempo = 0 par défaut
*/
regleZoom (echelle, options) {
this.zoom('regle', echelle, options)
this.regle.longueur = this.regle.longueur * echelle / 100
}
/**
*
* @param {int} pourcentage 200 pour doubler la taille
* @param {objet} options tempo = 0 par défaut
*/
equerreZoom (echelle, options) {
this.zoom('equerre', echelle, options)
}
/**
*
* @param {int} pourcentage 200 pour doubler la taille
* @param {objet} options tempo = 0 par défaut
*/
requerreZoom (echelle, options) {
this.zoom('requerre', echelle, options)
}
/**
*
* @param {int} pourcentage 200 pour doubler la taille
* @param {objet} options tempo = 0 par défaut
*/
rapporteurZoom (echelle, options) {
this.zoom('rapporteur', echelle, options)
}
/**
*
* @param {int} pourcentage 200 pour doubler la taille
* @param {objet} options tempo = 0 par défaut
*/
compasZoom (echelle, options) {
this.zoom('compas', echelle, options)
}
/**
**************************
********* POINT **********
**************************
*/
/**
* Crééer un point avec la croix pour le situer et son nom en bas à droite par défaut. L'id sera sauvegardé dans l'objet point. S'il n'est pas défini alors on prend le premier entier disponible.
* @param {point} A
* @param {objet} options { label: A.nom, tempo: this.tempo, couleur: this.couleurPoint, couleurLabel: this.couleurTexte, id }
*
*/
pointCreer (A, { dx = 0.1, dy, label = A.nom, tempo = this.tempo, couleur = this.couleurPoint, couleurLabel = this.couleurTexte, id } = {}) {
if (typeof id !== 'undefined') {
A.id = id
} else {
this.idIEP++
A.id = this.idIEP
}
let codeXML
if (label) {
codeXML = `<action abscisse="${this.x(A)}" ordonnee="${this.y(A)}" couleur="${couleur}" id="${A.id}" mouvement="creer" objet="point" tempo="${tempo}"/>`
// codeXML += `\n<action couleur="${couleurLabel}" nom="${label}" id="${this.idIEP}" mouvement="nommer" objet="point" tempo="${tempo}" />`
const M = point(A.x, A.y)
if (typeof dx !== 'undefined') {
M.x += dx
}
if (typeof dy !== 'undefined') {
M.y += dy
}
this.textePoint(`$${label}$`, M, { tempo: 0, couleur: couleurLabel })
} else {
codeXML = `<action abscisse="${this.x(A)}" ordonnee="${this.y(A)}" couleur="${couleur}" id="${A.id}" mouvement="creer" objet="point" tempo="${tempo}" />`
}
this.liste_script.push(codeXML)
}
/**
* Création de plusieurs points
* Le dernier argument peut être une option qui sera appliquée à tous les points
*
* @param {...points} points Points séparés par des virgules
*/
pointsCreer (...args) {
if (args[args.length - 1].typeObjet === 'point') {
for (const point of args) {
this.pointCreer(point, { tempo: 0 })
}
} else {
const options = args[args.length - 1]
const enleveDernier = arr => arr.slice(0, -1)
for (const point of enleveDernier(args)) {
this.pointCreer(point, options)
}
}
}
/**
* Masquer un point
* @param {point} A
* @param {objet} options Défaut : { tempo: 0 }
*/
pointMasquer (...args) {
const enleveDernier = arr => arr.slice(0, -1)
if (args[args.length - 1].typeObjet === 'point') {
for (const point of args) {
this.liste_script.push(`<action id="${point.id}" mouvement="masquer" objet="point" tempo="0" />`)
}
} else {
if (args[args.length - 1].tempo !== undefined) {
const tempo = args[args.length - 1].tempo
for (const point of enleveDernier(args)) {
this.liste_script.push(`<action id="${point.id}" mouvement="masquer" objet="point" tempo="${tempo}" />`)
}
} else {
for (const point of enleveDernier(args)) {
this.liste_script.push(`<action id="${point.id}" mouvement="masquer" objet="point" tempo="0" />`)
}
}
}
}
/**
* Montrer un point qui aurait été caché
* @param {point} A
* @param {objet} options Défaut ; { tempo : this.tempo }
*/
pointMontrer (A, { tempo = this.tempo } = {}) {
this.liste_script.push(`<action id="${A.id}" mouvement="montrer" objet="point" tempo="${tempo}" />`)
}
/**
* Anime la translation d'un point
* @param {point} A
* @param {int} x Abscisse du point d'arrivée
* @param {int} y Ordonnée du point d'arrivée
* @param {objet} options Défaut : { tempo: this.tempo, vitesse: this.vitesse }
*/
pointDeplacer (A, x, y, { tempo = this.tempo, vitesse = this.vitesse } = {}) {
const B = point(x, y)
this.liste_script.push(`<action abscisse="${this.x(B)}" ordonnee="${this.y(B)}" id="${A.id}" mouvement="translation" objet="point" tempo="${tempo}" vitesse="${vitesse}" />`)
}
/**
* Ajoute un label au point
* @param {point} A
* @param {string} nom
* @param {objet} options dx pour le déplacement vertical du nom du point, dy pour le déplacemetn horizontal, couleur: this.couleurPoint, tempo: this.tempo
*/
pointNommer (A, nom, { dx, dy, couleur = this.couleurPoint, tempo = this.tempo } = {}) {
// const coordonneesTexte = ''
const M = point(A.x, A.y)
if (typeof dx !== 'undefined') {
M.x += dx
}
if (typeof dy !== 'undefined') {
M.y += dy
}
this.textePoint(`$${nom}$`, M, { tempo, couleur })
// this.liste_script.push(`<action couleur="${couleur}" nom="${nom}" id="${A.id}" mouvement="nommer" objet="point" tempo="${tempo}" ${coordonneesTexte} />`)
}
/**
**************************
********* COMPAS *********
**************************
*/
/**
* Change l'orientation du compas. Par défaut, elle est vers la droite. L'orientation courante du compas est sauvegardée dans this.compas.orientation
* @param {objet} options Défaut : { tempo: this.tempo}
*/
compasRetourner ({ tempo = this.tempo } = {}) {
const codeXML = `<action mouvement="retourner" objet="compas" tempo="${tempo}" />`
if (this.compas.orientation === 'droite') {
this.compas.orientation = 'gauche'
} else {
this.compas.orientation = 'droite'
}
this.liste_script.push(codeXML)
}
/**
*
* @param {int} longueur écartement en cm
* @param {objet} options Défaut : { tempo: this.tempo, vitesse: this.vitesse }
*/
compasEcarter (l, { tempo = this.tempo, vitesse = this.vitesse } = {}) {
const codeXML = `<action ecart="${l * 30}" mouvement="ecarter" objet="compas" tempo="${tempo}" vitesse="${vitesse}" />`
this.compas.ecartement = l
this.liste_script.push(codeXML)
}
/**
* Fais apparaitre la règle à l'horizontale, met le compas vertical et écarte le compas le long de la règle pour lire son écartement
* @param {int} longueur
* @param {*} options Défaut : { tempo: this.tempo, vitesse: this.vitesse, sens : this.vitesse / 2 }
*/
compasEcarterAvecRegle (l, { tempo = this.tempo, vitesse = this.vitesse, sens = this.vitesse / 2 } = {}) {
this.regleRotation(0, { tempo: 0, sens })
this.regleMontrer(this.compas.position, { tempo: 0 })
this.regleDeplacer(this.compas.position, { tempo: 0, vitesse })
this.compasMontrer()
this.compasRotation(0, { tempo: 0, sens })
this.compasEcarter(l, { tempo, vitesse, sens })
}
/**
*
* @param {point} A Pointe du compas
* @param {point} B Mine du compas
* @param {objet} options Défaut : { tempo: this.tempo, vitesse: this.vitesse, sens : this.vitesse / 2 }
*/
compasEcarter2Points (A, B, { tempo = this.tempo, vitesse = this.vitesse, sens = this.vitesse / 2 } = {}) {
this.compasMontrer(A)
this.compasDeplacer(A, { tempo, vitesse })
const s = segment(A, B)
s.isVisible = false
const angle = s.angleAvecHorizontale
this.compasRotation(angle, { tempo, sens })
this.compasEcarter(longueur(A, B), { tempo, vitesse })
}
/**
* Remettre le compas en position standard. Son état est sauvegardé dans le booléen this.compas.leve.
* @param {objet} options Défaut : { tempo: this.tempo }
*/
compasLever ({ tempo = this.tempo } = {}) {
if (!this.compas.leve) { // On ne fait rien si le compas est déjà levé
const codeXML = `<action mouvement="lever" objet="compas" tempo="${tempo} />`
this.compas.leve = true
this.liste_script.push(codeXML)
}
}
/**
* Voir le compas en vue de dessus avant qu'il trace un arc de cercle
* @param {objet} options Défaut : { tempo: this.tempo }
*/
compasCoucher ({ tempo = this.tempo } = {}) {
if (this.compas.leve) { // On ne fait rien si le compas est déjà levé
const codeXML = `<action mouvement="coucher" objet="compas" tempo="${tempo}" />`
this.compas.leve = false
this.liste_script.push(codeXML)
}
}
/**
* Trace un arc de cercle en gardant l'écartement et le centre actuel. L'angle de départ sera choisi pour être le plus proche de l'angle actuel
* @param {int} angle1
* @param {int} angle2
* @param {objet} options Défaut : { tempo: this.tempo, sens: this.vitesse / 2, epaisseur: this.epaisseur, couleur: this.couleurCompas, pointilles: this.pointilles }
* @return {id}
*/
compasTracerArc2Angles (angle1, angle2, { tempo = this.tempo, sens = Math.round(this.vitesse / 2), epaisseur = this.epaisseur, couleur = this.couleurCompas, pointilles = this.pointilles } = {}) {
const pointillesTexte = pointilles ? 'pointille="tiret"' : ''
this.idIEP += 1
if (Math.abs(this.compas.angle - angle1) > Math.abs(this.compas.angle - angle2)) { // On cherche à commencer par le point le plus proche de la position courante du compas
[angle1, angle2] = [angle2, angle1]
}
let codeXML = `<action sens="${sens}" angle="${-angle1}" mouvement="rotation" objet="compas" tempo="${tempo}" />\n`
codeXML += '<action mouvement="lever" objet="compas" />\n'
codeXML += `<action sens="${sens}" angle="${-angle1}" mouvement="rotation" objet="compas" />\n`
let sensTexte
if (angle2 > angle1) {
sensTexte = sens
} else {
sensTexte = -1 * sens
}
codeXML += `<action couleur="${couleur}" epaisseur="${epaisseur}" sens="${sensTexte}" debut="${-angle1}" fin="${-angle2}" mouvement="tracer" objet="compas" ${pointillesTexte} id="${this.idIEP}" />\n`
codeXML += `<action mouvement="coucher" objet="compas" tempo="${tempo}"/>`
this.compas.angle = angle2
this.liste_script.push(codeXML)
return this.idIEP
}
/**
* Trace un arc de cercle autour d'un point. La longueur de l'arc est déterminée par l'option delta en degré qui est ajoutée de part et d'autre du point
* @param {point} centre
* @param {point} point
* @param {objet} options Défaut : { delta: 10, tempo: this.tempo, sens: this.vitesse / 2, epaisseur: this.epaisseur, couleur: this.couleurCompas, pointilles: this.pointilles }
* @return {id}
*/
compasTracerArcCentrePoint (centre, point, { delta = 10, tempo = this.tempo, vitesse = this.vitesse, sens = Math.round(this.vitesse / 2), epaisseur = this.epaisseur, couleur = this.couleurCompas, pointilles = this.pointilles } = {}) {
this.compasMontrer()
this.compasDeplacer(centre, { tempo, vitesse })
const s = segment(centre, point)
s.visibility = false
const angle1 = s.angleAvecHorizontale - delta
const angle2 = s.angleAvecHorizontale + delta
if ((Math.abs(this.compas.ecartement - longueur(this.compas.position, point))) > 0.1) {
this.compasEcarter(longueur(centre, point), { tempo, vitesse })
}
return this.compasTracerArc2Angles(angle1, angle2, { tempo, vitesse, epaisseur, sens, couleur, pointilles })
}
/**
*
* @param {point} centre
* @param {point} point Point de départ du tracé du cercle
* @param {objet} options Défaut : { tempo: this.tempo, sens: this.vitesse / 2, epaisseur: this.epaisseur, couleur: this.couleurCompas, pointilles: this.pointilles }
*/
compasCercleCentrePoint (centre, point, { tempo = this.tempo, couleur = this.couleur, vitesse = this.vitesse, sens = Math.round(this.vitesse / 2), epaisseur = this.epaisseur, pointilles = this.pointilles } = {}) {
this.compasEcarter2Points(centre, point, { vitesse, tempo })
const d = droite(centre, point)
const angle1 = d.angleAvecHorizontale
this.compasTracerArc2Angles(angle1, angle1 + 360, { tempo, vitesse, sens, epaisseur, couleur, pointilles })
}
/**
**************************
******** REQUERRE ********
**************************
*/
/**
*
* @param {int} déplacement en nombre de cm (le déplacement peut être positif ou négatif)
* @param {*} options Défaut : { tempo: this.tempo, vitesse: this.vitesse }
*/
requerreGlisserEquerre (a, { tempo = this.tempo, vitesse = this.vitesse } = {}) {
this.liste_script.push(`<action abscisse="${a * 30}" mouvement="glisser" objet="requerre" tempo="${tempo}" vitesse="${vitesse}" />`)
}
/**
**************************
******* RAPPORTEUR *******
**************************
*/
// Non pris en charge par le lecteur JS
// this.rapporteurCirculaire = function (tempo=this.tempo) {
// // this.liste_script.push(`<action mouvement="circulaire" objet="rapporteur" tempo="${tempo}"/>`)
// }
// this.rapporteurSemiCirculaire = function (tempo=this.tempo) {
// // this.liste_script.push(`<action mouvement="semicirculaire" objet="rapporteur" tempo="${tempo}"/>`)
// }
/**
* Montre ou masque les graduations du rapporteur
* @param {point} A
* @param {string} nom
* @param {objet} options Défaut : { tempo: this.tempo }
*/
// rapporteurGraduations ()
/**
* Masque la graduation externe du rapporteur (laisse l'autre graduation visible)
* @param {objet} options Défaut : { tempo: this.tempo }
*/
rapporteurMasquerGraduationsExterieures ({ tempo = this.tempo } = {}) {
this.liste_script.push(`<action mouvement="masquer_nombres" objet="rapporteur" tempo="${tempo}"/>`)
}
/**
* Montre la graduation extérieure si elle avait été précédemment cachée
* @param {objet} options Défaut : { tempo: this.tempo }
*/
rapporteurMontrerGraduationsExterieures ({ tempo = this.tempo } = {}) {
this.liste_script.push(`<action mouvement="montrer_nombres" objet="rapporteur" tempo="${tempo}"/>`)
}
/**
* Masque la graduation interne du rapporteur (laisse l'autre graduation visible)
* @param {objet} options Défaut : { tempo: this.tempo }
*/
rapporteurMasquerGraduationsInterieures ({ tempo = this.tempo } = {}) {
this.liste_script.push(`<action mouvement="vide" objet="rapporteur" tempo="${tempo}"/>`)
}
/**
* Montre la graduation interne si elle avait été précédemment cachée
* @param {objet} options Défaut : { tempo: this.tempo }
*/
rapporteurMontrerGraduationsInterieures ({ tempo = this.tempo } = {}) {
this.liste_script.push(`<action mouvement="graduations" objet="rapporteur" tempo="${tempo}"/>`)
}
/**
* Met le rapporteur en position avec le centre en A et le 0 de droite alogné avec le point B
* @param {point} A
* @param {point} B
* @param {objet} options Défaut : { tempo: this.tempo, vitesse: this.vitesse, sens : this.vitesse / 2 }
*/
rapporteurDeplacerRotation2Points (A, B, { tempo = this.tempo, vitesse = this.vitesse, sens = Math.round(this.vitesse / 2) } = {}) {
const d = droite(A, B)
d.isVisible = false
this.rapporteurMontrer()
this.rapporteurDeplacer(A, { tempo, vitesse })
this.rapporteurRotation(d.angleAvecHorizontale, { tempo, vitesse, sens })
}
/**
* Fais une petite marque (couleur et épaisseur d'un trait de construction) sur une graduation du rapporteur
* @param {int} angle
* @param {objet} options Défaut : { tempo: this.tempo, vitesse: this.vitesse, couleur: this.couleurTraitsDeConstruction, epaisseur: this.epaisseurTraitsDeConstruction }
*/
rapporteurCrayonMarqueAngle (angle, { tempo = this.tempo, vitesse = this.vitesse, couleur = this.couleurTraitsDeConstruction, epaisseur = this.epaisseurTraitsDeConstruction } = {}) {
const O = this.rapporteur.position
const distanceBord = this.rapporteur.rayon * this.rapporteur.zoom / 100
const M = pointAdistance(O, distanceBord, angle + this.rapporteur.angle)
const N = pointAdistance(O, distanceBord + 0.3, angle + this.rapporteur.angle)
this.crayonMontrer()
this.crayonDeplacer(M, { tempo, vitesse })
this.tracer(N, { tempo, vitesse, couleur, epaisseur })
}
/**
* Le crayon va faire une marque sur la graduation du rapporteur, le rapporteur va se cacher et on trace une demi-droite dont on peut choisir la "longueur" (par défaut 90% de celle de la règle)
* @param {point} A Centre du rapporteur
* @param {point} B Point avec lequel le 0 de droite sera aligné
* @param {int} angle
* @param {objet} options { longueur: 0.9 * this.regle.longueur, couleur: this.couleur, tempo: this.tempo, vitesse: this.vitesse, sens : this.vitesse / 2, epaisseur: this.epaisseur, pointilles: this.pointilles }
*/
rapporteurTracerDemiDroiteAngle (A, B, angle, { longueur = 0.9 * this.regle.longueur, couleur = this.couleur, tempo = this.tempo, vitesse = this.vitesse, sens = Math.round(this.vitesse / 2), epaisseur = this.epaisseur, pointilles = this.pointilles } = {}) {
if (angle > 0) {
this.rapporteurDeplacerRotation2Points(A, B, { tempo, vitesse, sens })
this.rapporteurCrayonMarqueAngle(angle, { tempo, vitesse, sens })
} else {
const B2 = rotation(B, A, 180)
this.rapporteurDeplacerRotation2Points(A, B2, { tempo, vitesse, sens })
this.rapporteurCrayonMarqueAngle(180 - Math.abs(angle), { tempo, vitesse, sens })
}
const d = droite(A, B)
d.isVisible = false
const M = pointAdistance(A, this.rapporteur.rayon * this.rapporteur.zoom / 100, d.angleAvecHorizontale + angle)
this.rapporteurMasquer({ tempo })
this.regleDemiDroiteOriginePoint(A, M, { longueur, couleur, tempo, vitesse, sens, epaisseur, pointilles })
}
/**
**************************
********* REGLE **********
**************************
*/
/**
* Masquer les graduations sur la règle
* @param {objet} options Défaut : { tempo: this.tempo }
*/
regleMasquerGraduations ({ tempo = this.tempo } = {}) {
this.liste_script.push(`<action mouvement="vide" objet="regle" tempo="${tempo}"/>`)
}
/**
* Montrer les graduations sur la règle si elles avaient été masquées
* @param {objet} options Défaut : { tempo: this.tempo }
*/
regleMontrerGraduations ({ tempo = this.tempo } = {}) {
this.liste_script.push(`<action mouvement="graduations" objet="regle" tempo="${tempo}"/>`)
}
/**
* Modifie la taille de la règle
* @param {int} longueur
* @param {objet} options Défaut : { tempo: this.tempo }
*/
regleModifierLongueur (longueur = 20, { tempo = this.tempo } = {}) {
this.regle.longueur = longueur
this.liste_script.push(`<action mouvement="modifier_longueur" objet="regle" longueur="${longueur}" tempo="${tempo}"/>`)
}
/**
* Trace une demi-droite d'origine O passant par A (ou en direction de A si les points sont trop éloignés)
* @param {point} O Origine
* @param {point} A Direction
* @param {objet} options Défaut {longueur: this.regle.longueur, tempo : this.tempo, vitesse: this.vitesse, sens: this.vitesse / 2}
*/
regleDemiDroiteOriginePoint (O, A, options = {}) {
if (!options.longueur) {
options.longueur = this.regle.longueur
}
const M = pointSurSegment(O, A, options.longueur)
this.regleSegment(O, M, options)
}
/**
* Trace une droite passanrt par les points A et B
* @param {point} A
* @param {point} B
* @param {objet} options Défaut {longueur: this.regle.longueur, tempo : this.tempo, vitesse: this.vitesse, sens: this.vitesse / 2}
*/
regleDroite (A, B, options = {}) {
if (!options.longueur) {
options.longueur = this.regle.longueur
}
const M = homothetie(B, A, (-options.longueur * 0.5 + longueur(A, B) * 0.5) / longueur(A, B))
const N = homothetie(A, B, (-options.longueur * 0.5 + longueur(A, B) * 0.5) / longueur(A, B))
if (this.x(A) <= this.x(B)) {
this.regleMontrer(M)
this.regleRotation(N, options)
this.regleSegment(M, N, options)
} else {
this.regleMontrer(N)
this.regleRotation(M, options)
this.regleSegment(N, M, options)
}
}
/**
* Avec la règle, on prolonge le segment de l cm du coté de la 2e extrémité si l est positif sinon du côté de la première extrémité
* @param {point} A
* @param {point} B
* @param {objet} options Défaut {longueur: 3, tempo: this.tempo, vitesse: this.vitesse, sens: this.vitesse / 2}
*/
regleProlongerSegment (A, B, options = {}) {
if (!options.longueur) {
options.longueur = this.regle.longueur - 3
}
if (options.longueur > 0) {
const B1 = pointSurSegment(B, A, 3)
const B2 = pointSurSegment(B, A, -options.longueur)
this.regleSegment(B1, B2, options)
} else {
const A1 = pointSurSegment(A, B, 3)
const A2 = pointSurSegment(A, B, options.longueur)
this.regleSegment(A1, A2, options)
}
}
/**
**************************
********* TRAITS *********
**************************
*/
/**
* Le crayon trace un trait de sa position courante jusqu'au point B
* @param {point} B
* @param {objet} options Défaut { tempo: this.tempo, vitesse: this.vitesse, epaisseur: this.epaisseur, couleur: this.couleur, pointilles: this.pointilles, vecteur: false }
* @return {id} id utilisée pour le tracé
*/
tracer (B, { tempo = this.tempo, vitesse = this.vitesse, epaisseur = this.epaisseur, couleur = this.couleur, pointilles = this.pointilles, vecteur = false } = {}) {
const pointillesTexte = pointilles ? 'pointille="tiret"' : ''
const vecteurTexte = vecteur ? 'style="vecteur"' : ''
this.idIEP += 1
const codeXML = `<action abscisse="${this.x(B)}" ordonnee="${this.y(B)}" epaisseur="${epaisseur}" couleur="${couleur}" mouvement="tracer" objet="crayon" tempo="${tempo}" vitesse="${vitesse}" ${pointillesTexte} ${vecteurTexte} id="${this.idIEP}" />`
this.crayon.position = B
this.liste_script.push(codeXML)
return this.idIEP
}
/**
* Trace au crayon le segment [AB]
* @param {point} A Première extrémité
* @param {point} B Deuxième extrémité
* @param {*} options
* @return {id} id utilisée pour le tracé
*/
trait (A, B, options = {}) {
this.crayonDeplacer(A, options)
return this.tracer(B, options)
}
/**
* Trace au crayon le segment [AB] sans tempo et avec une vitesse multipliée par 1 000
* @param {point} A Première extrémité
* @param {point} B Deuxième extrémité
* @param {*} options
* @return {id} id utilisée pour le tracé
*/
traitRapide (A, B, options = {}) {
options.tempo = 0
options.vitesse = 10000
this.crayonDeplacer(A, options)
return this.tracer(B, options)
}
/**
* Masque le trait d'id fourni
* @param {int} id
* @param {objet} options Défaut : { tempo: 0, vitesse: 200 }
*/
traitMasquer (id, { tempo = 0, vitesse = 200 } = {}) {
this.liste_script.push(`<action mouvement="masquer" objet="trait" id="${id}" vitesse="${vitesse}" />`)
}
/**
*
* @param {segment/point} Segment à tracer ou première extrémité
* @param {objet/point} options ou deuxième extrémité
* @param {objet} options si les deux premiers arguments étaient des points
* @returns {id} identifiant utilisé pour le trait
*/
regleSegment (arg1, arg2, arg3) {
let A, B, options, id
if (arg1.typeObjet === 'segment') {
A = arg1.extremite1
B = arg1.extremite2
options = arg2
} else {
A = arg1
B = arg2
options = arg3
}
if (A.x <= B.x) { // Toujours avoir la règle de gauche à droite
this.regleMontrer(A, options)
this.regleRotation(B, options)
} else {
this.regleMontrer(B, options)
this.regleRotation(A, options)
}
if (longueur(this.crayon.position, A) < longueur(this.crayon.position, B)) { // Le crayon ira au point le plus proche
this.crayonMontrer(A, options)
id = this.tracer(B, options)
} else {
this.crayonMontrer(B, options)
id = this.tracer(A, options)
}
return id
}
/**
* Trace un polygone avec les options par défaut que l'on ne peut pas changer ici
* @param {...points} sommets du polygonne séparés par des virgules
*/
polygoneTracer (...sommets) {
for (let i = 0; i < sommets.length - 1; i++) {
this.regleSegment(sommets[i], sommets[i + 1])
}
this.regleSegment(sommets[sommets.length - 1], sommets[0])
}
/**
* Trace un polygone avec traitRapide()
* @param {...points} sommets du polygonne séparés par des virgules
*/
polygoneRapide (...sommets) {
for (let i = 0; i < sommets.length - 1; i++) {
this.traitRapide(sommets[i], sommets[i + 1])
}
this.traitRapide(sommets[sommets.length - 1], sommets[0])
}
/**
**************************
********* TEXTE **********
**************************
*/
/**
* Ecris un texte collé au point. On peut choisir un fond, un cadre, l'opacité du fond, la police...
* @param {string} texte
* @param {point} A
* @param {objet} options Défaut : { tempo: this.tempo, police: false, couleur: this.couleurTexte, couleurFond, opaciteFond, couleurCadre, epaisseurCadre, marge, margeGauche, margeDroite, margeHaut, margeBas }
* @return {id}
*/
textePoint (texte, A, { tempo = this.tempo, police = false, couleur = this.couleurTexte, taille, couleurFond, opaciteFond, couleurCadre, epaisseurCadre, marge, margeGauche, margeDroite, margeHaut, margeBas } = {}) {
this.idIEP++
const policeTexte = police ? `police="${police}"` : ''
let options = ''
if (typeof couleurFond !== 'undefined') {
options += ` couleur_fond="${couleurFond}"`
}
if (typeof opaciteFond !== 'undefined') {
options += ` opacite_fond="${opaciteFond}"`
}
if (typeof couleurCadre !== 'undefined') {
options += ` couleur_cadre="${couleurCadre}"`
}
if (typeof epaisseurCadre !== 'undefined') {
options += ` epaisseur_cadre="${epaisseurCadre}"`
}
if (typeof marge !== 'undefined') {
options += ` marge="${marge}"`
}
if (typeof margeGauche !== 'undefined') {
options += ` marge_gauche="${margeGauche}"`
}
if (typeof margeDroite !== 'undefined') {
options += ` marge_droite="${margeDroite}"`
}
if (typeof margeBas !== 'undefined') {
options += ` marge_bas="${margeBas}"`
}
if (typeof margeHaut !== 'undefined') {
options += ` marge_haut="${margeHaut}"`
}
if (typeof taille !== 'undefined') {
options += ` taille="${taille}"`
}
let codeXML = `<action abscisse="${this.x(A)}" ordonnee="${this.y(A)}" id="${this.idIEP}" mouvement="creer" objet="texte" />`
codeXML += `\n<action ${policeTexte} couleur="${couleur}" texte="${texte}" id="${this.idIEP}" mouvement="ecrire" objet="texte" ${options} tempo="${tempo}" />`
this.liste_script.push(codeXML)
return this.idIEP
}
/**
* Ecris un texte collé au point de coordonnées (x,y). On peut choisir un fond, un cadre, l'opacité du fond, la police...
* @param {string} texte
* @param {int} x Abscisse du coin en haut à gauche
* @param {int} y Ordonnée du coin en haut à gauche
* @param {objet} options Défaut : { tempo: this.tempo, police: false, couleur: this.couleurTexte, couleurFond, opaciteFond, couleurCadre, epaisseurCadre, marge, margeGauche, margeDroite, margeHaut, margeBas }
*/
textePosition (texte, x, y, options) {
const A = point(x, y)
return this.textePoint(texte, A, options)
}
longueurSegment (A, B, dy, options) {
const l = longueur(A, B)
const v = vecteur(A, B)
const w = vecteur(-v.y * dy / norme(v), v.x * dy / norme(v))
const ancrage = translation(translation(pointSurSegment(A, B, l / 2 - 0.7), w), vecteur(0, 1))
return this.textePoint(`${l} cm`, ancrage, options)
}
mesureAngle (A, O, B) {
const a = angleOriente(A, O, B)
const C = translation(homothetie(rotation(A, O, a / 2), O, 1.3 / longueur(O, A)), vecteur(-0.2, 0.5))
return this.textePoint(Math.abs(a) + '°', C)
}
/**
* Masque le trait d'id fourni
* @param {array} id
* @param {objet} options Défaut : { tempo: 0 }
*/
texteMasquer (...args) {
const enleveDernier = arr => arr.slice(0, -1)
if (Number.isNaN(args[args.length - 1])) {
if (args[args.length - 1].tempo !== undefined) {
const tempo = args[args.length - 1].tempo
for (const texte of enleveDernier(args)) {
this.liste_script.push(`<action mouvement="masquer" objet="texte" id="${texte}" tempo="${tempo}" />`)
}
} else {
for (const texte of enleveDernier(args)) {
this.liste_script.push(`<action mouvement="masquer" objet="texte" id="${texte}" tempo="0" />`)
}
}
} else {
for (const texte of args) {
this.liste_script.push(`<action mouvement="masquer" objet="texte" id="${texte}" tempo="0" />`)
}
}
}
/**
* Change la couleur d'un texte déjà créé dont on donne l'id retourné par this.textePoint ou this.textePosition
* Nécessité de redonner le texte car on réécrit le texte dans une autre couleur.
* @param {string} texte
* @param {number} id
* @param {string} couleur
*/
texteChangeCouleur (texte, id, couleur) {
this.liste_script.push(`\n<action couleur="${couleur}" texte="${texte}" id="${id}" mouvement="ecrire" objet="texte" />`)
}
/**
* Met l'animation en pause forçant l'utilisateur à appuyer sur lecture pour voir la suite
*/
pause () {
this.liste_script.push('<action mouvement="pause" />')
}
/**
**************************
******* CODAGES **********
**************************
*/
/**
*
* @param {segment/point} Segment à coder ou première extrémité
* @param {objet/point} options ou deuxième extrémité
* @param {objet} options si les deux premiers arguments étaient des points. Défaut : { tempo: this.tempo, couleur: this.couleurCodage, codage: '//', }
* @return {id}
*/
segmentCodage (arg1, arg2 = {}, arg3 = {}) {
let s
let options = {}
if (arg1.typeObjet === 'segment') {
s = arg1
options = arg2
} else {
s = segment(arg1, arg2)
options = { ...arg3 }
}
if (options.tempo === undefined) {
options.tempo = this.tempo
}
if (options.couleur === undefined) {
options.couleur = this.couleurCodage
}
if (options.codage === undefined) {
options.codage = '\\'
}
this.idIEP++
const id = this.idIEP
const M = milieu(s.extremite1, s.extremite2)
const codeXML = `<action abscisse="${this.x(M)}" ordonnee="${this.y(M)}" forme="${options.codage}" couleur="${options.couleur}" id="${id}" tempo="${options.tempo}" mouvement="creer" objet="longueur" />`
this.liste_script.push(codeXML)
return id
}
/**
*
* @param {int} id Identifiant du codage
* @param {objet} options Défaut : { tempo: this.tempo }
*/
segmentCodageMasquer (id, { tempo = this.tempo } = {}) {
this.liste_script.push(`<action id="${id}" mouvement="masquer" objet="longueur" tempo="${tempo}" />`)
}
/**
*
* @param {int} id Identifiant du codage
* @param {objet} options Défaut : { tempo: this.tempo }
*/
segmentCodageMontrer (id, { tempo = this.tempo } = {}) {
this.liste_script.push(`<action id="${id}" mouvement="montrer" objet="longueur" tempo="${tempo}" />`)
}
/**
* Trace le petit carré au crayon
* @param {point} A Point sur un côté de l'angle
* @param {point} B Sommet de l'angle
* @param {point} C Point sur un côté de l'angle
* @param {objet} options Défaut : {longueur : 0.3, couleur: this.couleurCodage}
* @return {array} [idTrait1, idTrait2]
*/
codageAngleDroit (A, B, C, options = {}) {
this.crayonMontrer()
if (options.longueur === undefined) {
options.longueur = 0.3
}
if (options.couleur === undefined) {
options.couleur = this.couleurCodage
}
const C1 = pointSurSegment(B, C, options.longueur)
const A1 = pointSurSegment(B, A, options.longueur)
const M = translation2Points(A1, B, C1)
const options1 = { ...options } // On recopie options pour ouvoir en changer le tempo du premier tracé
options1.tempo = 0
const trait1 = this.trait(C1, M, options1)
const trait2 = this.trait(M, A1, options)
return [trait1, trait2]
}
/**
* Masque le codage d'un angle droit
* @param {int} id Identifiant du codage d'un angle droit
* @param {objet} options Défaut { tempo: 0 }
*/
codageAngleDroitMasquer (id, { tempo = 0 } = {}) {
this.traitMasquer(id[0], { tempo })
this.traitMasquer(id[1], { tempo })
}
/**
* Code un angle. L'option codage peut être "simple", "/", "//", "///", "O"
* "double", "double/", "double//", "double///", "doubleO"
* "triple", "triple/", "triple//", "triple///", "tripleO"
* "plein", "plein/", "plein//", "plein///", "pleinO"
* @param {point} A Point sur un côté de l'angle
* @param {point} B Sommet de l'angle
* @param {point} C Point sur un côté de l'angle
* @param {objet} options Défaut : { rayon : 1, couleur: this.couleurCodage, codage: 'plein'}
* @return {id} L'identifiant correspond à l'identifiant des 3 points de l'angle séparés par _
*/
angleCodage (B, A, C, { couleur = this.couleurCodage, codage = 'plein', rayon = 1, tempo = this.tempo } = {}) {
const id = B.id + '_' + A.id + '_' + C.id
const d1 = droite(A, B)
const d2 = droite(A, C)
d1.isVisible = false
d2.isVisible = false
const angle1 = -d1.angleAvecHorizontale
const angle2 = -d2.angleAvecHorizontale
const codeXML = `<action abscisse="${this.x(A)}" ordonnee="${this.y(A)}" rayon="${rayon * 30}" angle1="${angle1}" angle2="${angle2}" forme="${codage}" couleur="${couleur}" id="${id}" tempo="${tempo}" mouvement="creer" objet="angle" />`
this.liste_script.push(codeXML)
return id
}
/**
* Masque un codage préalablement créé
* @param {point} A
* @param {point} B
* @param {point} C
* @param {objet} options Défaut { tempo: 0 }
*/
angleCodageMasquer (B, A, C, { tempo = 0 } = {}) {
const id = B.id + '_' + A.id + '_' + C.id
this.liste_script.push(`<action id="${id}" mouvement="masquer" objet="angle" tempo="${tempo}" />`)
}
/**
* Montre un codage préalablement créé
* @param {point} A
* @param {point} B
* @param {point} C
* @param {objet} options Défaut { tempo: 0 }
*/
angleCodageMontrer (B, A, C, { tempo = 0 } = {}) {
const id = B.id + '_' + A.id + '_' + C.id
this.liste_script.push(`<action id="${id}" mouvement="montrer" objet="angle" tempo="${tempo}" />`)
}
/**
* Affiche une image (donnée par son URL) au point A
* @param {string} url
* @returns {id}
*/
image (url, A = point(0, 0)) {
this.idIEP++
let codeXML
codeXML = `<action id="${this.idIEP}" url="${url}" mouvement="chargement" objet="image" />`
codeXML += `\n<action abscisse="${this.x(A)}" ordonnee="${this.y(A)}" id="${this.idIEP}" mouvement="translation" objet="image" vitesse="100000" />`
this.liste_script.push(codeXML)
return this.idIEP
}
}
Alea2iep.prototype.symetrieAxialePoint = symetrieAxialePoint
Alea2iep.prototype.parallelogramme3sommetsConsecutifs = parallelogramme3sommetsConsecutifs
Alea2iep.prototype.parallelogramme2sommetsConsecutifsCentre = parallelogramme2sommetsConsecutifsCentre
Alea2iep.prototype.parallelogrammeAngleCentre = parallelogrammeAngleCentre
Alea2iep.prototype.partageSegment = partageSegment
Alea2iep.prototype.paralleleRegleEquerre2points3epoint = paralleleRegleEquerre2points3epoint
Alea2iep.prototype.paralleleRegleEquerre2points3epoint = paralleleRegleEquerre2points3epoint
Alea2iep.prototype.perpendiculaireRegleEquerre2points3epoint = perpendiculaireRegleEquerre2points3epoint
Alea2iep.prototype.perpendiculaireRegleEquerreDroitePoint = perpendiculaireRegleEquerreDroitePoint
Alea2iep.prototype.perpendiculaireRegleEquerrePointSurLaDroite = perpendiculaireRegleEquerrePointSurLaDroite
Alea2iep.prototype.perpendiculaireCompasPointSurLaDroite = perpendiculaireCompasPointSurLaDroite
Alea2iep.prototype.perpendiculaireCompasPoint = perpendiculaireCompasPoint
Alea2iep.prototype.paralleleRegleEquerreDroitePointAvecDescription = paralleleRegleEquerreDroitePointAvecDescription
Alea2iep.prototype.paralleleAuCompasAvecDescription = paralleleAuCompasAvecDescription
Alea2iep.prototype.paralleleAuCompas = paralleleAuCompas
Alea2iep.prototype.mediatriceAuCompas = mediatriceAuCompas
Alea2iep.prototype.mediatriceRegleEquerre = mediatriceRegleEquerre
Alea2iep.prototype.hauteur = hauteur
Alea2iep.prototype.mediane = mediane
Alea2iep.prototype.bissectriceAuCompas = bissectriceAuCompas
Alea2iep.prototype.cercleCirconscrit = cercleCirconscrit
Alea2iep.prototype.triangle3longueurs = triangle3longueurs
Alea2iep.prototype.triangleRectangleCoteHypotenuse = triangleRectangleCoteHypotenuse
Alea2iep.prototype.triangleRectangle2Cotes = triangleRectangle2Cotes
Alea2iep.prototype.triangle1longueur2angles = triangle1longueur2angles
Alea2iep.prototype.triangle2longueurs1angle = triangle2longueurs1angle
Alea2iep.prototype.triangleEquilateral2Sommets = triangleEquilateral2Sommets
Alea2iep.prototype.triangleEquilateral = triangleEquilateral
Alea2iep.prototype.carre1point1longueur = carre1point1longueur
Alea2iep.prototype.rotationPoint = rotationPoint
Alea2iep.prototype.translationPoint = translationPoint
Alea2iep.prototype.demiTourPoint = demiTourPoint
Alea2iep.prototype.homothetiePoint = homothetiePoint
Alea2iep.prototype.rotationPolygone = rotationPolygone
Alea2iep.prototype.symetrieAxialePolygone = symetrieAxialePolygone
Alea2iep.prototype.translationPolygone = translationPolygone
Alea2iep.prototype.demiTourPolygone = demiTourPolygone
Alea2iep.prototype.homothetiePolygone = homothetiePolygone