exercices/6e/6G12-1.js

import Exercice from '../Exercice.js'
import { mathalea2d } from '../../modules/2dGeneralites.js'
import { context } from '../../modules/context.js'
import { listeQuestionsToContenu, randint, combinaisonListes, arrondi, texNombre, texteEnCouleur, numAlpha, stringNombre } from '../../modules/outils.js'
import { point, tracePoint, pointSurDroite, pointIntersectionDD, labelPoint, droite, droiteParPointEtParallele, droiteParPointEtPerpendiculaire, segment, rotation, codageAngleDroit, afficheCoteSegment, grille, seyes, longueur } from '../../modules/2d.js'
import Alea2iep from '../../modules/Alea2iep.js'
export const amcReady = true
export const amcType = 'AMCOpen' // type de question AMC
export const titre = 'Tracer des parallèles et des perpendiculaires'

/**
 * Fonction générale pour exercices de constructions de parallèles et perpendiculaires
 * références 6G11, 6G12 et 6G12-1
 * Animation de la correction ajoutée le 16/04/2021
 * @author Jean-Claude Lhote  (AMC par Eric Elter en septembre 2021, ES6 par Loïc Geeraerts
 */

export const uuid = 'd14bc'
export const ref = '6G12-1'
export default class ParalleleEtPerpendiculaires extends Exercice {
//  'use strict'
  constructor () {
    super()
    this.titre = titre
    this.nbQuestions = 1
    this.nbCols = 1
    this.nbColsCorr = 1
    this.sup = 1
    this.type = 3
    this.typeExercice = 'IEP'
    this.besoinFormulaire2CaseACocher = ['Avec auto-correction']
    this.sup2 = true

    this.besoinFormulaireNumerique = [
      'Type de cahier',
      3,
      ' 1 : Cahier à petits carreaux\n 2 : Cahier à gros carreaux (Seyes)\n 3 : Feuille blanche'
    ]
  }

  nouvelleVersion () {
    const typesDeQuestionsDisponibles = [this.type] // Le choix 1 ou 2 ou 3 : 1=perpendiculaires, 2=parallèles, 3=des perpendiculaires et des paralèlles
    const listeTypeDeQuestions = combinaisonListes(
      typesDeQuestionsDisponibles,
      this.nbQuestions
    )
    this.listeQuestions = [] // Liste de questions
    this.listeCorrections = [] // Liste de questions corrigées
    this.autoCorrection = []
    let Xmin; let Xmax; let Ymin; let Ymax; const ppc = 20; let sc
    let anim

    let A
    let B
    let C
    let D
    let xE
    let E
    let F
    let CC
    let DD
    let EE
    let d
    let s1
    let s2
    let enonce
    let correction
    let dB
    let dC
    let dD
    let dE
    let g
    let lC
    let lD
    let lE
    let cB
    let cC
    let cD
    let cE
    let cF
    let cG
    let FF
    let BB
    let carreaux
    let k
    const objetsEnonce = []
    const objetsCorrection = []

    let p
    for (
      let i = 0, texte, cpt = 0;
      i < this.nbQuestions && cpt < 50;

    ) {
      anim = new Alea2iep()
      anim.equerreZoom(150)
      objetsEnonce.length = 0
      objetsCorrection.length = 0
      correction = ''
      if (this.sup === 2) { k = 0.8 } else { k = 0.5 }
      if (this.sup === 3) { this.sup2 = false } // Pour obliger à enlever l'auto-correction sur papier blanc, car elle est alors impossible. Pb néanmoins avec la case à cocher qui ni bouge pas (Pb soulevé dans le Slack)
      switch (listeTypeDeQuestions[i]) {
        case 1:
          A = point(0, 0, 'A', 'above left')
          B = point(10, randint(-4, 4, [-1, 0, 1]), 'B', 'above right')
          d = droite(A, B)
          d.isVisible = true
          C = point(randint(2, 3), randint(3, 4), 'C', 'above left')
          D = point(randint(7, 8), randint(-7, -6), 'D')
          dB = droiteParPointEtPerpendiculaire(B, d)
          xE = 11
          E = pointSurDroite(dB, 11, 'E', 'left')
          while (!Number.isInteger(E.y)) {
            xE++
            E = pointSurDroite(dB, xE, 'E', 'left')
          }
          F = point(E.x, B.y)
          s1 = segment(B, F, 'red')
          s1.epaisseur = 2
          s1.pointilles = 5
          s2 = segment(F, E, 'blue')
          s2.epaisseur = 2
          s2.pointilles = 5
          dC = droiteParPointEtPerpendiculaire(C, d)
          dD = droiteParPointEtPerpendiculaire(D, d)
          BB = rotation(A, B, 90)
          CC = pointIntersectionDD(dC, d, 'M', 'below right')
          DD = pointIntersectionDD(dD, d, 'N', 'above left')
          lC = arrondi(longueur(CC, A) * k, 1)
          lD = arrondi(longueur(DD, A) * k, 1)
          cB = codageAngleDroit(A, B, BB)
          cC = codageAngleDroit(C, CC, B)
          cD = codageAngleDroit(D, DD, B)
          if (this.sup2) {
            objetsCorrection.push(s1,
              s2,
              dC,
              dD,
              dB,
              cB,
              cC,
              cD,
              d,
              tracePoint(A, B, C, D, E, CC, DD),
              labelPoint(A, B, C, D, E, CC, DD),
              afficheCoteSegment(
                segment(A, CC),
              `${stringNombre(lC)} cm`,
              0.5,
              'red',
              1,
              0.5,
              'red'
              ),
              afficheCoteSegment(
                segment(A, DD),
              `${stringNombre(lD)} cm`,
              -0.5,
              'red',
              1,
              -0.5,
              'red'
              )
            )
          } else {
            objetsCorrection.push(dC,
              dD,
              dB,
              cB,
              cC,
              cD,
              d,
              tracePoint(A, B, C, D, E, CC, DD),
              labelPoint(A, B, C, D, E, CC, DD)
            )
          }
          objetsEnonce.push(
            tracePoint(A, B, C, D),
            labelPoint(A, B, C, D),
            d
          )
          if (context.isHtml) enonce = numAlpha(0) + ' Reproduire la figure ci-dessous.<br>'
          else enonce = numAlpha(0) + ' Utiliser un crayon à papier afin de pouvoir gommer si besoin.<br>'
          enonce +=
          numAlpha(1) +
          ' Tracer la droite perpendiculaire à $(AB)$ passant par $B$.<br>'
          enonce +=
          numAlpha(2) +
          ' Tracer la droite perpendiculaire à $(AB)$ passant par $C$ et nommer $M$ le point d\'intersection de cette droite avec la droite $(AB)$.<br>'
          enonce +=
          numAlpha(3) +
          ' Tracer la droite perpendiculaire à $(AB)$ passant par $D$ et nommer $N$ le point d\'intersection de cette droite avec la droite $(AB)$.<br>'
          if (this.sup2) {
            enonce +=
          numAlpha(4) +
          ' Mesurer ensuite les distances $AM$ et $AN$. Pour l\'auto-correction comparer ces mesures avec celles données dans la correction<br>'

            correction = `<br>$AM \\approx ${texNombre(
          lC
        )}$ cm et $AN \\approx ${texNombre(lD)}$ cm.<br>`
            correction += 'Pour la perpendiculaire en $B$, contrôle la position du point $E$.<br>'
          }
          Xmin = Math.floor(Math.min(A.x, B.x, C.x, D.x, E.x, CC.x, DD.x) - 1)
          Xmax = Math.ceil(Math.max(A.x, B.x, C.x, D.x, E.x, CC.x, DD.x) + 1)
          Ymin = Math.floor(Math.min(A.y, B.y, C.y, D.y, E.y, CC.y, DD.y) - 1)
          Ymax = Math.ceil(Math.max(A.y, B.y, C.y, D.y, E.y, CC.y, DD.y) + 1)
          anim.recadre(Xmin - 3, Ymax)
          anim.pointsCreer(A, B, C, D)
          anim.regleDroite(A, B)
          anim.perpendiculaireRegleEquerre2points3epoint(A, B, B)
          anim.perpendiculaireRegleEquerre2points3epoint(A, B, C)
          anim.perpendiculaireRegleEquerre2points3epoint(A, B, D)
          break
        case 2:
          A = point(2, 0, 'A', 'below left')
          B = point(12, randint(-4, 4, 0), 'B')
          d = droite(A, B)
          d.isVisible = true
          C = point(0, randint(3, 4), 'C', 'above')
          D = point(randint(7, 8), randint(-7, -6), 'D', 'below right')
          E = point(randint(4, 5), randint(5, 6), 'E', 'below right')
          F = point(2, -3, 'F', 'left')

          dE = droiteParPointEtParallele(E, d)
          dC = droiteParPointEtParallele(C, d)
          dD = droiteParPointEtParallele(D, d)
          p = droite(A, F)
          p.isVisible = true
          CC = pointIntersectionDD(dC, p, 'M', 'above left')
          DD = pointIntersectionDD(dD, p, 'N', 'above left')
          EE = pointIntersectionDD(dE, p, 'O', 'above left')
          lC = arrondi(longueur(CC, A) * k, 1)
          lD = arrondi(longueur(DD, A) * k, 1)
          lE = arrondi(longueur(EE, A) * k, 1)
          if (this.sup2) {
            objetsCorrection.push(dC, dD, dE, d, p, tracePoint(A, B, C, D, E, F), labelPoint(A, B, C, D, E, F, CC, DD, EE), afficheCoteSegment(segment(A, CC), `${stringNombre(lC)} cm`, 0.2, 'red', 1, 0.5, 'red'), afficheCoteSegment(segment(DD, A), `${stringNombre(lD)} cm`, -0.2, 'green', 1, -0.5, 'green'), afficheCoteSegment(segment(A, EE), `${stringNombre(lE)} cm`, -0.2, 'blue', 1, -0.5, 'blue'))
          } else {
            objetsCorrection.push(dC, dD, dE, d, p, tracePoint(A, B, C, D, E, F), labelPoint(A, B, C, D, E, F, CC, DD, EE))
          }
          objetsEnonce.push(tracePoint(A, B, C, D, E, F), labelPoint(A, B, C, D, E, F), d, p)

          if (context.isHtml) enonce = numAlpha(0) + ' Reproduire la figure ci-dessous.<br>'
          else enonce = numAlpha(0) + ' Utiliser un crayon à papier afin de pouvoir gommer si besoin.<br>'
          enonce += numAlpha(1) + ' Tracer la droite parallèle à $(AB)$ passant par $C$ et nommer $M$, le point d\'intersection de cette droite avec la droite $(AF)$.<br>'
          enonce += numAlpha(2) + ' Tracer la droite parallèle à $(AB)$ passant par $D$ et nommer $N$, le point d\'intersection de cette droite avec la droite $(AF)$.<br>'
          enonce += numAlpha(3) + ' Tracer la droite parallèle à $(AB)$ passant par $E$ et nommer $O$, le point d\'intersection de cette droite avec la droite $(AF)$.<br>'
          if (this.sup2) {
            enonce += numAlpha(4) + ' Mesurer les distances $AM$, $AN$ et $AO$. Pour l\'auto-correction, comparer ces mesures avec celles données par  l\'ordinateur dans la correction.<br>'

            correction = `<br>$AM \\approx ${texNombre(
          lC
        )}$ cm, $AN \\approx ${texNombre(
          lD
        )}$ cm et $AO \\approx${texNombre(
          lE
        )}$ cm.<br>`
          }
          Xmin = Math.floor(Math.min(A.x, B.x, C.x, D.x, E.x, F.x, EE.x, CC.x, DD.x) - 1)
          Xmax = Math.ceil(Math.max(A.x, B.x, C.x, D.x, E.x, F.x, EE.x, CC.x, DD.x) + 1)
          Ymin = Math.floor(Math.min(A.y, B.y, C.y, D.y, E.y, F.y, EE.y, CC.y, DD.y) - 1)
          Ymax = Math.ceil(Math.max(A.y, B.y, C.y, D.y, E.y, F.y, EE.y, CC.y, DD.y) + 1)
          anim.recadre(Xmin - 3, Ymax)
          anim.pointsCreer(A, B, C, D, E)
          anim.regleDroite(A, B)
          anim.paralleleRegleEquerre2points3epoint(A, B, C)
          anim.paralleleRegleEquerre2points3epoint(A, B, D)
          anim.paralleleRegleEquerre2points3epoint(A, B, E)

          break
        case 3:
          A = point(0, 0, 'A', 'above left')
          B = point(10, randint(-4, 4, [-1, 0, 1]), 'B', 'above right')
          d = droite(A, B)
          d.isVisible = true
          C = point(randint(2, 3), randint(3, 4), 'C', 'above left')
          D = point(randint(7, 8), randint(-7, -6), 'D')
          dB = droiteParPointEtPerpendiculaire(B, d)
          xE = 11
          E = pointSurDroite(dB, 11, 'E', 'left')
          while (!Number.isInteger(E.y)) {
            xE++
            E = pointSurDroite(dB, xE, 'E', 'left')
          }
          F = point(E.x, B.y)
          dE = droiteParPointEtParallele(E, d)
          dD = droiteParPointEtParallele(D, d)
          dC = droiteParPointEtPerpendiculaire(C, d)
          BB = rotation(A, B, 90)
          CC = pointIntersectionDD(dC, d, 'M', 'below right')
          DD = pointIntersectionDD(dD, dB, 'N', 'above left')
          EE = pointIntersectionDD(dC, dE, 'O', 'above left')
          FF = pointIntersectionDD(dD, dC)

          lC = arrondi(longueur(CC, A) * k, 1)
          lD = arrondi(longueur(DD, A) * k, 1)
          lE = arrondi(longueur(EE, A) * k, 1)
          cB = codageAngleDroit(A, B, BB)
          cC = codageAngleDroit(C, CC, B)
          cD = codageAngleDroit(D, DD, B, 'red')
          cE = codageAngleDroit(B, E, EE, 'red')
          cF = codageAngleDroit(C, EE, E, 'red')
          cG = codageAngleDroit(C, FF, D, 'red')
          if (this.sup2) {
            objetsCorrection.push(dC, dD, dB, dE, cB, cC, cD, cE, cF, cG, d, tracePoint(A, B, C, D, E, CC, DD, EE), labelPoint(A, B, C, D, E, CC, DD, EE), afficheCoteSegment(
              segment(A, CC),
          `${stringNombre(lC)} cm`,
          0.5,
          'red',
          1,
          0.5,
          'red'
            ),
            afficheCoteSegment(
              segment(A, DD),
            `${stringNombre(lD)} cm`,
            0,
            'blue',
            1,
            -0.5,
            'blue'
            ),
            afficheCoteSegment(
              segment(A, EE),
            `${stringNombre(lE)} cm`,
            0,
            'green',
            1,
            -0.5,
            'green'
            ))
          } else {
            objetsCorrection.push(dC, dD, dB, dE, cB, cC, cD, cE, cF, cG, d, tracePoint(A, B, C, D, E, CC, DD, EE), labelPoint(A, B, C, D, E, CC, DD, EE))
          }
          objetsEnonce.push(tracePoint(A, B, C, D, E), labelPoint(A, B, C, D, E), d)
          if (context.isHtml) enonce = numAlpha(0) + ' Reproduire la figure ci-dessous.<br>'
          else enonce = numAlpha(0) + ' Utiliser un crayon à papier afin de pouvoir gommer si besoin.<br>'
          enonce += numAlpha(1) + ' Tracer la droite perpendiculaire à $(AB)$ passant par $B$.<br>'
          enonce += numAlpha(2) + ' Tracer la droite perpendiculaire à $(AB)$ passant par $C$ et nomme $M$, le point d\'intersection de cette droite avec la droite $(AB)$.<br>'
          enonce += numAlpha(3) + ' Tracer la droite parallèle à $(AB)$ passant par $D$ et nomme $N$, le point d\'intersection de cette droite avec la droite $(BE)$.<br>'
          enonce += numAlpha(4) + ' Tracer la droite parallèle à $(AB)$ passant par $E$ et nomme $O$, le point d\'intersection de cette droite avec la droite $(CM)$.<br>'
          if (this.sup2) {
            enonce += numAlpha(5) + ' Mesurer les distances $AM$, $AN$ et $AO$. Pour l\'auto-correction, comparer ces mesures avec celles données par  l\'ordinateur dans la correction.<br>'

            correction += `<br>$AM \\approx ${texNombre(
          lC
        )}$ cm, $AN \\approx ${texNombre(
          lD
        )}$ cm et $AO \\approx${texNombre(
          lE
        )}$ cm.<br>`
          }
          correction += `Les angles droits en rouge se justifient par la propriété :<br> ${texteEnCouleur('Si deux droites sont parallèles, alors toute droite perpendiculaire à l\'une est aussi perpendiculaire à l\'autre', 'red')}.<br>`
          correction += 'Vérifier les angles droits à l\'équerre.<br>'
          Xmin = Math.floor(Math.min(A.x, B.x, C.x, D.x, E.x, F.x, EE.x, CC.x, DD.x) - 1)
          Xmax = Math.ceil(Math.max(A.x, B.x, C.x, D.x, E.x, F.x, EE.x, CC.x, DD.x) + 1)
          Ymin = Math.floor(Math.min(A.y, B.y, C.y, D.y, E.y, F.y, EE.y, CC.y, DD.y) - 1)
          Ymax = Math.ceil(Math.max(A.y, B.y, C.y, D.y, E.y, F.y, EE.y, CC.y, DD.y) + 1)
          anim.recadre(Xmin - 3, Ymax)
          anim.pointsCreer(A, B, C, D, E)
          anim.regleDroite(A, B)
          anim.perpendiculaireRegleEquerre2points3epoint(A, B, B)
          anim.perpendiculaireRegleEquerre2points3epoint(A, B, C)
          anim.paralleleRegleEquerre2points3epoint(A, B, D)
          anim.paralleleRegleEquerre2points3epoint(A, B, E)

          break
      }
      if (this.sup < 3) g = grille(Xmin, Ymin, Xmax, Ymax, 'gray', 0.7)
      else g = ''
      if (parseInt(this.sup) === 2) {
        sc = 0.8
        carreaux = seyes(Xmin, Ymin, Xmax, Ymax)
      } else {
        sc = 0.5
        carreaux = ''
      }
      objetsEnonce.push(g, carreaux)
      objetsCorrection.push(g, carreaux)

      enonce += '<br>' + mathalea2d(
        {
          xmin: Xmin,
          ymin: Ymin,
          xmax: Xmax,
          ymax: Ymax,
          pixelsParCm: ppc,
          scale: sc
        },
        objetsEnonce
      )
      correction += mathalea2d(
        {
          xmin: Xmin,
          ymin: Ymin,
          xmax: Xmax,
          ymax: Ymax,
          pixelsParCm: ppc,
          scale: sc
        },
        objetsCorrection
      )
      /** ********************** AMC Open *****************************/
      this.autoCorrection[i] = {}
      this.autoCorrection[i].options = { ordered: false }
      this.autoCorrection[i].enonce = enonce + '<br>'
      this.autoCorrection[i].propositions = [
        {
          texte: correction,
          statut: 3,
          sanscadre: true
        }
      ]
      // this.autoCorrection = [{ enonce: enonce + '<br>', propositions: [{ texte: correction, statut: 3, sanscadre: true }] }]
      /****************************************************/
      correction += anim.htmlBouton(this.numeroExercice, i)
      if (this.listeQuestions.indexOf(texte) === -1) {
      // Si la question n'a jamais été posée, on en crée une autre
        this.listeQuestions.push(enonce + '<br>')
        this.listeCorrections.push(correction + '<br>')
        i++
      }
      cpt++
    }

    listeQuestionsToContenu(this)
  }
}