exercices/6e/6G11-1.js

import Exercice from '../Exercice.js'
import { mathalea2d } from '../../modules/2dGeneralites.js'
import { context } from '../../modules/context.js'
import { listeQuestionsToContenu, randint, lettreDepuisChiffre, numAlpha, combinaisonListes, shuffle } from '../../modules/outils.js'
import { point, tracePoint, rotation, labelPoint, homothetie, droite, grille, seyes, angle, codageSegment, codageAngleDroit, pointIntersectionDD, droiteParPointEtPerpendiculaire, pointSurDroite, milieu } from '../../modules/2d.js'
import Alea2iep from '../../modules/Alea2iep.js'
export const titre = 'Tracer des perpendiculaires'
export const dateDePublication = '09/10/2022'
/**
 * Fonction générale pour construire des perpendiculairs
 * @author Mickael Guironnet
 */

export const uuid = 'df825'
export const ref = '6G11-1'
export default class constructionPerpendiculaires extends Exercice {
//  'use strict'
  constructor () {
    super()
    this.titre = titre
    this.nbQuestions = 1
    this.nbCols = 1
    this.nbColsCorr = 1
    this.sup = 1
    this.sup2 = '1'
    this.typeExercice = 'IEP'
    this.spacing = (context.isHtml) ? 2 : 1
    this.besoinFormulaireNumerique = [
      'Type de cahier',
      3,
      ' 1 : Cahier à petits carreaux\n 2 : Cahier à gros carreaux (Seyes)\n 3 : Feuille blanche'
    ]
    this.besoinFormulaire2Texte = [
      'Type de question', [
        'Choix séparés par des tirets',
        '0 : Mélange',
        '1 : Orthocentre (intérieur du triangle)',
        '2 : Orthocentre (extérieur du triangle)',
        '3 : Centre du cercle circonscrit  (intérieur du triangle)',
        '4 : Centre du cercle circonscrit  (extérieur du triangle)'
      ].join('\n')
    ]
  }

  nouvelleVersion () {
    this.listeQuestions = [] // Liste de questions
    this.listeCorrections = [] // Liste de questions corrigées
    this.autoCorrection = []

    let listeTypeDeQuestions = []
    if (!this.sup2) { // Si aucune liste n'est saisie ou mélange demandé
      listeTypeDeQuestions = combinaisonListes([1, 2, 3, 4], this.nbQuestions)
    } else {
      const quests = this.sup2.split('-')// Sinon on créé un tableau à partir des valeurs séparées par des -
      for (let i = 0; i < quests.length; i++) {
        const choixtp = parseInt(quests[i])
        if (choixtp >= 1 && choixtp <= 4) {
          listeTypeDeQuestions.push(choixtp)
        }
      }
      if (listeTypeDeQuestions.length === 0) { listeTypeDeQuestions = [1, 2] }
      listeTypeDeQuestions = combinaisonListes(listeTypeDeQuestions, this.nbQuestions)
    }

    for (let i = 0, texte, typesDeQuestions, cpt = 0; i < this.nbQuestions && cpt < 50; cpt++) {
      typesDeQuestions = listeTypeDeQuestions[i]
      const anim = new Alea2iep()
      const objetsEnonce = []
      const objetsCorrection = []
      const indLettre = randint(1, 15)
      const A = point(0, 0, lettreDepuisChiffre(indLettre), 'above left')
      let B = point(20, randint(-4, 0, [-1, 0, 1]), lettreDepuisChiffre(indLettre + 1), 'above right')

      let ang1, ang2, ang3
      switch (typesDeQuestions) {
        case 1:
        case 3: {
          // triangle avec des angles aigus
          ang1 = randint(30, 80)
          ang2 = randint(30, 80)
          ang3 = 180 - ang1 - ang2
          let k = 0
          while (ang3 > 90 & k < 30) {
            const r = randint(1, 10)
            if (ang1 + r < 90) {
              ang1 = ang1 + r
              ang3 = ang3 - r
            } else if (ang2 + r < 90) {
              ang2 = ang2 + r
              ang3 = ang3 - r
            }
            k++
          }
          break
        }
        case 2:
        case 4: {
          // triangle avec un angle obtus
          ang1 = 90 + randint(10, 30)
          ang2 = randint(30, 50)
          ang3 = 180 - ang1 - ang2
          const angle = shuffle([ang1, ang2])
          ang1 = angle[0]
          ang2 = angle[1]
          B.x = 10
          break
        }
      }
      const dAB = droite(A, B)
      const C1 = rotation(B, A, ang1)
      const C2 = rotation(A, B, -1 * ang2)
      const CC = pointIntersectionDD(droite(A, C1), droite(B, C2))
      let C = point(Math.floor(CC.x), Math.floor(CC.y), lettreDepuisChiffre(indLettre + 2), 'above left')

      const ag1 = angle(B, A, C)
      const ag2 = angle(C, B, A)
      const ag3 = angle(A, C, B)

      if ((typesDeQuestions === 1 || typesDeQuestions === 3) && (ag1 > 85 || ag2 > 85 || ag3 > 85)) {
        continue
      }

      const dAC = droite(A, C)
      const dBC = droite(B, C)
      let hC, hB, hA, ortho
      switch (typesDeQuestions) {
        case 1:
        case 2:
          hC = droiteParPointEtPerpendiculaire(C, dAB, '', 'blue')
          hB = droiteParPointEtPerpendiculaire(B, dAC, '', 'green')
          hA = droiteParPointEtPerpendiculaire(A, dBC, '', 'red')
          ortho = pointIntersectionDD(hC, hB)
          break
        case 3:
        case 4:
          hC = droiteParPointEtPerpendiculaire(milieu(A, B), dAB, '', 'blue')
          hB = droiteParPointEtPerpendiculaire(milieu(A, C), dAC, '', 'green')
          hA = droiteParPointEtPerpendiculaire(milieu(B, C), dBC, '', 'red')
          ortho = pointIntersectionDD(hC, hB)
          break
      }

      const Xmin = Math.floor(Math.min(A.x, B.x, C.x, ortho.x) - 1)
      const Xmax = Math.ceil(Math.max(A.x, B.x, C.x, ortho.x) + 1)
      const Ymin = Math.floor(Math.min(A.y, B.y, C.y, ortho.y) - 1)
      const Ymax = Math.ceil(Math.max(A.y, B.y, C.y, ortho.y) + 1)
      context.fenetreMathalea2d = [Xmin, Ymin, Xmax, Ymax]

      let pHc = pointIntersectionDD(droite(point(Xmin, Ymin), point(Xmax, Ymin)), hC, '(d_1)', 'above left')
      if (pHc && pHc.x >= Xmin && pHc.x <= Xmax) {
        // intersection avec le cadran du bas
        // pHc.x - Xmin > Xmax - pHc.x ? pHc.x = pHc.x - 0.5 : pHc.x = pHc.x + 0.5
        pHc.y = pHc.y + 0.5
      } else {
        // pas d'intersection
        pHc = pointSurDroite(hC, Xmin, '(d_1)', 'above left')
        // pHc.x = pHc.x - 1
      }
      let pHb = pointIntersectionDD(droite(point(Xmin, Ymin), point(Xmin, Ymax)), hB, '(d_2)', 'below right')
      if (pHb && pHb.y <= Ymax && pHb.y >= Ymin) {
        // intersection avec le cadran de gauche
        pHb.x = pHb.x + 0.5
      } else {
        pHb = pointIntersectionDD(droite(point(Xmin, Ymax), point(Xmax, Ymax)), hB, '(d_2)', 'below left')
        if (pHb && pHb.x <= Xmax && pHb.x >= Xmin) {
          // intersection avec le cadran d'en haut
          pHb.y = pHb.y - 0.5
        }
      }
      let pHa = pointIntersectionDD(droite(point(Xmax, Ymin), point(Xmax, Ymax)), hA, '(d_3)', 'above left')
      if (pHa && pHa.y <= Ymax && pHa.y >= Ymin) {
        // intersection avec le cadran de droite
        pHa.x = pHa.x - 0.5
      } else {
        pHa = pointIntersectionDD(droite(point(Xmin, Ymax), point(Xmax, Ymax)), hA, '(d_3)', 'below right')
        if (pHa && pHa.x <= Xmax && pHa.x >= Xmin) {
          // intersection avec le cadran d'en haut
          pHa.y = pHa.y - 0.5
        }
      }
      const T = tracePoint(A, B, C)
      T.tailleTikz = 0.3
      objetsCorrection.push(T, labelPoint(A, B, C), labelPoint(pHc, 'blue'), labelPoint(pHb, 'green'), labelPoint(pHa, 'red'), dAB, dAC, dBC, hA, hB, hC)
      if (typesDeQuestions === 1 || typesDeQuestions === 2) {
        objetsCorrection.push(codageAngleDroit(B, pointIntersectionDD(hC, dAB), C), codageAngleDroit(C, pointIntersectionDD(hA, dBC), A), codageAngleDroit(B, pointIntersectionDD(hB, dAC), C))
      } else {
        objetsCorrection.push(codageSegment(B, milieu(B, C), '|||'), codageSegment(milieu(B, C), C, '|||'), codageSegment(A, milieu(A, C), '||'), codageSegment(milieu(A, C), C, '||'), codageSegment(B, milieu(A, B), '|'), codageSegment(milieu(A, B), A, '|'), codageAngleDroit(B, milieu(A, B), ortho), codageAngleDroit(C, milieu(B, C), ortho), codageAngleDroit(C, milieu(A, C), ortho))
      }
      objetsEnonce.push(T, labelPoint(A, B, C))
      let correction = ''
      let enonce = ''
      let questind = 0
      if (context.isHtml) enonce += numAlpha(questind++) + ' Reproduire la figure ci-dessous.<br>'
      if (typesDeQuestions === 1 || typesDeQuestions === 2) {
        enonce +=
          numAlpha(questind++) +
          `Tracer $(${A.nom}${B.nom})$, $(${A.nom}${C.nom})$ et $(${B.nom}${C.nom})$.<br>`
        enonce +=
          numAlpha(questind++) +
          `Tracer la droite $(d_1)$ perpendiculaire à $(${A.nom}${B.nom})$ passant par $${C.nom}$.<br>`
        enonce +=
          numAlpha(questind++) +
          `Tracer la droite $(d_2)$ perpendiculaire à $(${A.nom}${C.nom})$ passant par $${B.nom}$.<br>`
        enonce +=
          numAlpha(questind++) +
          `Tracer la droite $(d_3)$ perpendiculaire à $(${B.nom}${C.nom})$ passant par $${A.nom}$.<br>`
        // enonce +=
        //   numAlpha(questind++) +
        //   'Tracer le point d\'intersection des droites $(d_1)$, $(d_2)$ et $(d_3)$.<br>'
      } else {
        enonce +=
          numAlpha(questind++) +
          `Tracer $(${A.nom}${B.nom})$, $(${A.nom}${C.nom})$ et $(${B.nom}${C.nom})$.<br>`
        enonce +=
          numAlpha(questind++) +
          `Placer le milieu de $[${A.nom}${B.nom}]$.<br>`
        enonce +=
          numAlpha(questind++) +
          `Tracer la droite $(d_1)$ perpendiculaire à $(${A.nom}${B.nom})$ passant par le milieu de $[${A.nom}${B.nom}]$.<br>`
        enonce +=
          numAlpha(questind++) +
          `Placer le milieu de $[${A.nom}${C.nom}]$.<br>`
        enonce +=
          numAlpha(questind++) +
          `Tracer la droite $(d_2)$ perpendiculaire à $(${A.nom}${C.nom})$ passant par le milieu de $[${A.nom}${C.nom}]$.<br>`
        enonce +=
          numAlpha(questind++) +
          `Placer le milieu de $[${B.nom}${C.nom}]$.<br>`
        enonce +=
          numAlpha(questind++) +
          `Tracer la droite $(d_3)$ perpendiculaire à $(${B.nom}${C.nom})$ passant par le milieu de $[${B.nom}${C.nom}]$.<br>`
        // enonce +=
        //   numAlpha(questind++) +
        //   'Tracer le point d\'intersection des droites $(d_1)$, $(d_2)$ et $(d_3)$.<br>'
      }
      anim.taille((Xmax - Xmin + 5) * 30, (Ymax - Ymin + 5) * 30)
      anim.recadre(Xmin - 3, Ymax)
      B = homothetie(A, B, 0.5, 'B', 'above right')
      C = homothetie(A, C, 0.5, 'C', 'above right')
      pHc = homothetie(A, pHc, 0.5)
      pHb = homothetie(A, pHb, 0.5)
      pHa = homothetie(A, pHa, 0.5)
      ortho = homothetie(A, ortho, 0.5)
      anim.pointsCreer(A, B, C)
      anim.regleModifierLongueur(20)
      anim.equerreZoom(200)
      anim.regleDroite(A, B, { couleur: 'blue' })
      anim.regleDroite(A, C, { couleur: 'blue' })
      anim.regleDroite(B, C, { couleur: 'blue' })
      anim.regleMasquer()
      if (typesDeQuestions === 1 || typesDeQuestions === 2) {
        anim.perpendiculaireRegleEquerreDroitePoint(droite(A, B), C)
        anim.textePosition('$(d_1)$', pHc.x, pHc.y)
        anim.perpendiculaireRegleEquerreDroitePoint(droite(A, C), B)
        anim.textePosition('$(d_2)$', pHb.x, pHb.y)
        anim.perpendiculaireRegleEquerreDroitePoint(droite(B, C), A)
        anim.textePosition('$(d_3)$', pHa.x, pHa.y)
      } else {
        anim.perpendiculaireRegleEquerreDroitePoint(droite(A, B), milieu(A, B))
        anim.textePosition('$(d_1)$', pHc.x, pHc.y)
        anim.perpendiculaireRegleEquerreDroitePoint(droite(A, C), milieu(A, C))
        anim.textePosition('$(d_2)$', pHb.x, pHb.y)
        anim.perpendiculaireRegleEquerreDroitePoint(droite(B, C), milieu(B, C))
        anim.textePosition('$(d_3)$', pHa.x, pHa.y)
      }
      anim.pointCreer(ortho)
      let g, sc, carreaux
      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)
      const ppc = 20
      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
      )

      /****************************************************/
      correction += anim.htmlBouton(this.numeroExercice, i)
      if (context.isHtml) correction += '<br><br>Remarque : les droites $(d_1)$, $(d_2)$ et $(d_3)$ ont un seul point d\'intersection. On dit qu\'elles sont concourantes.'
      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++
      }
    }

    listeQuestionsToContenu(this)
  }
}