HEX
Server: Apache
System: Linux vps.mmtprep.com 4.18.0-477.21.1.el8_8.x86_64 #1 SMP Thu Aug 10 13:51:50 EDT 2023 x86_64
User: mmtprep (1001)
PHP: 8.1.34
Disabled: exec,passthru,shell_exec,system
Upload Files
File: /home/mmtprep/public_html/mathzen.mmtprep.com/assets/3d-a5FjzFK6.js.map
{"version":3,"file":"3d-a5FjzFK6.js","sources":["../../src/modules/3d.js"],"sourcesContent":["import { cross, dot, matrix, multiply, norm } from 'mathjs'\nimport { distancePointDroite, droite } from '../lib/2d/droites.js'\nimport { point, pointIntersectionDD, pointSurSegment, tracePoint } from '../lib/2d/points.js'\nimport { polygone, polygoneAvecNom, polyline, renommePolygone } from '../lib/2d/polygones.js'\nimport { longueur, norme, segment, vecteur } from '../lib/2d/segmentsVecteurs.js'\nimport { labelPoint } from '../lib/2d/textes.js'\nimport { translation } from '../lib/2d/transformations.js'\nimport { choisitLettresDifferentes } from '../lib/outils/aleatoires.js'\nimport { arrondi } from '../lib/outils/nombres.js'\nimport { assombrirOuEclaircir, colorToLatexOrHTML, fixeBordures, vide2d } from './2dGeneralites.js'\nimport { context } from './context.js'\n\nconst math = { matrix, multiply, norm, cross, dot }\n\n/*\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%% OBJET PARENT %%%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n*/\n\n/*\n * Classe parente de tous les objets de MathALEA2D\n *\n * @author Rémi Angot\n */\nlet numId = 0\n\nfunction ObjetMathalea2D () {\n  this.positionLabel = 'above'\n  this.isVisible = true\n  this.color = colorToLatexOrHTML('black')\n  this.style = '' // stroke-dasharray=\"4 3\" pour des hachures //stroke-width=\"2\" pour un trait plus épais\n  this.styleTikz = ''\n  this.epaisseur = 1\n  this.opacite = 1\n  this.pointilles = false\n  this.id = numId\n  numId++\n  if (context.isInEditor) context.objets2D.push(this)\n}\n\n/*\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%% OBJETS DE BASE %%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n*/\n\n/**\n * LE POINT\n *\n * @author Jean-Claude Lhote\n * Point de l'espace défini par ses trois coordonnées (Si deux sont données seulement, le point est dans le plan XY)\n * le paramètre visible définit si ce point est placé devant (par défaut) ou derrière une surface. Il sera utilisé pour définir la visibilité des arêtes qui en partent\n */\nclass Point3d {\n  constructor (x, y, z, visible, label, positionLabel) {\n    const alpha = context.anglePerspective * Math.PI / 180 // context.anglePerspective peut être changé globalement pour modifier la perspective\n    const rapport = context.coeffPerspective // idem pour context.coefficientPerspective qui est la réduction sur l'axe y.\n    const MT = math.matrix([[1, rapport * Math.cos(alpha), 0], [0, rapport * Math.sin(alpha), 1]]) // La matrice de projection 3d -> 2d\n    this.x = x\n    this.y = y\n    this.z = z\n    this.visible = visible\n    this.label = label\n    this.typeObjet = 'point3d'\n    const V = math.matrix([this.x, this.y, this.z])\n    const W = math.multiply(MT, V)\n    this.c2d = point(W._data[0], W._data[1], this.label, positionLabel)\n  }\n}\n\nexport function point3d (x, y, z = 0, visible = true, label = '', positionLabel = 'above left') {\n  return new Point3d(x, y, z, visible, label, positionLabel)\n}\n\n/**\n * LE VECTEUR\n *\n * @author Jean-Claude Lhote\n * le vecteur3d est sans doute l'objet le plus important de cette base d'objets\n * On les utilise dans tous les objets complexes et dans toutes les transformations\n * Ils servent notament à définir la direction des plans.\n *\n * 3 usages : vecteur3d(A,B) ou vecteur3d(x,y,z) ou vecteur3d(math.matrix([x,y,z]))\n * A et B sont deux objets de type Point3d\n * x,y et z sont trois nombres\n * la commande math.matrix([x,y,z]) crée une matrice colonne.\n *\n * L'objet créé est de type Vecteur3d\n * sa propriété p2d est un objet Vecteur (2 dimensions : c'est la projection du vecteur)\n * sa propriété this.representant(A) est le dessin du représentant d'origine A.\n * exemples :\n * let v = vecteur3d(3,5,1) -> définit un vecteur de composantes (3;5;1)\n * let w = vecteur(point3d(0,0,0),point3d(1,1,1)) -> définit un vecteur d'origine O et d'extrémité M(1;1;1)\n * let fleche = w.representant(point3d(5,0,0)) -> fleche est un objet 2d qui représente le vecteur w au point (5;0;0)\n */\nclass Vecteur3d {\n  constructor (...args) {\n    const alpha = context.anglePerspective * Math.PI / 180\n    const rapport = context.coeffPerspective\n    const MT = math.matrix([[1, rapport * Math.cos(alpha), 0], [0, rapport * Math.sin(alpha), 1]]) // ceci est la matrice de projection 3d -> 2d\n    if (args.length === 2) {\n      this.x = args[1].x - args[0].x\n      this.y = args[1].y - args[0].y\n      this.z = args[1].z - args[0].z\n    } else {\n      if (typeof (args[0]) === 'number') {\n        this.x = args[0]\n        this.y = args[1]\n        this.z = args[2]\n      } else if (args.length === 1) {\n        this.x = args[0]._data[0]\n        this.y = args[0]._data[1]\n        this.z = args[0]._data[2]\n      }\n    }\n    this.matrice = math.matrix([this.x, this.y, this.z]) // On exporte cette matrice colonne utile pour les calculs vectoriels qui seront effectués par math.js\n    this.norme = Math.sqrt(this.x ** 2 + this.y ** 2 + this.z ** 2) // la norme du vecteur\n    const W = math.multiply(MT, this.matrice) // voilà comment on obtient les composantes du projeté 2d du vecteur\n    this.c2d = vecteur(W._data[0], W._data[1]) // this.c2d est l'objet 2d qui représente l'objet 3d this\n    this.representant = function (A) { // méthode pour construire un représentant d'origine A (un point 3d)\n      const B = translation3d(A, this)\n      return vecteur(A.c2d, B.c2d).representant(A.c2d) // qui retourne un représentant de vecteur 2d (objet dessiné)\n    }\n  }\n}\n\nexport function vecteur3d (...args) { // A,B deux Point3d ou x,y,z les composantes du vecteur\n  return new Vecteur3d(...args)\n}\n\n/**\n * L'ARETE\n * @author Jean-Claude lhote\n * Une telle arête est définie par deux points\n * Si l'un des deux points n'est pas visible (propriété visible à false) alors l'arête aura aussi visible à false\n * sa propriété p2d est un segment en pointillé ou en trait plein suivant sa visibilité.\n */\nclass Arete3d {\n  constructor (point1, point2, color, visible) {\n    this.extremite1 = point1\n    this.extremite2 = point2\n    this.color = color\n    this.visible = visible\n    if (!point1.visible || !point2.visible || !this.visible) {\n      this.visible = false\n    } else {\n      this.visible = true\n    }\n    this.c2d = segment(point1.c2d, point2.c2d, this.color)\n    if (!this.visible) {\n      this.c2d.pointilles = 2\n    } else {\n      this.c2d.pointilles = false\n    }\n  }\n}\n\n// l'arête est visible par défaut sauf si p1 ou p2 sont invisibles\nexport function arete3d (p1, p2, color = 'black', visible = true) {\n  return new Arete3d(p1, p2, color, visible)\n}\n\n/**\n * LA DROITE\n *\n * @author Jean-claude Lhote\n * Droite de l'espace définie par point et vecteur directeur droite3d(A,v)\n * Droite de l'espace définie par 2 points droite3d(A,B)\n * Les droites servent principalement à définir des axes de rotation dans l'espace\n */\nclass Droite3d {\n  constructor (point3D, vecteur3D) {\n    if (vecteur3D.constructor === Vecteur3d) {\n      this.directeur = vecteur3D\n    } else if (vecteur3D.constructor === Point3d) {\n      this.directeur = vecteur3d(point3D, vecteur3D)\n    }\n    this.origine = point3D\n    const M = translation3d(this.origine, this.directeur)\n    this.point = M\n    this.c2d = droite(this.origine.c2d, M.c2d) // la droite correspndant à la projection de cette droite dans le plan Mathalea2d\n    this.c2d.isVisible = false\n  }\n}\n\nexport function droite3d (point3D, vecteur3D) {\n  return new Droite3d(point3D, vecteur3D)\n}\n\n/**\n * LE DEMI-CERCLE  - ANCIENNE FONCTION\n *\n *@author Jean-Claude Lhote\n * Le nom est trompeur, il s'agit le plus souvent d'une demi-ellipse représentant un cercle projeté\n * Utilisé pour représenter un cercle dont une moitié est visible mais pas l'autre.\n *\n * normal et rayon sont deux vecteurs 3d\n * normal est un vecteur normal au plan du cercle\n * rayon est le vecteur qui part du centre et qui joint la 1ere extremité visible.\n * cote est soit 'caché' soit 'visible' et déterminera dans quel sens on crée le demi-cercle.\n * Si cote='caché' alors on tourne dans le sens direct et le tracé est en pointillés\n * Si cote='visible' alors on tourne dans le sens indirect et le tracé est plein.\n *\n */\n\n/*\nexport function demicercle3d (centre, normal, rayon, cote, color, angledepart = context.anglePerspective) {\n  let signe; const M = []; const listepoints = []\n  if (cote === 'caché') {\n    signe = 1\n  } else {\n    signe = -1\n  }\n  const d = droite3d(centre, normal)\n  M.push(rotation3d(translation3d(centre, rayon), d, angledepart))\n  listepoints.push(M[0].c2d)\n\n  for (let i = 1; i < 19; i++) {\n    M.push(rotation3d(M[i - 1], d, 10 * signe))\n    listepoints.push(M[i].c2d)\n  }\n  const demiCercle = polyline(listepoints, color)\n  if (cote === 'caché') {\n    demiCercle.pointilles = 2\n    demiCercle.opacite = 0.3\n  }\n  return demiCercle\n}\n*/\n/**\n * Crée un demi-cercle\n * @param {Point3d} centre Centre du demi-cercle\n * @param {Vecteur3d} normal Vecteur normal au demi-cercle\n * @param {Vecteur3d} rayon Vecteur correspondant au rayon\n * @param {string} [sens = 'direct'] Sens de rotation pour créer le demi-cercle ('direct' ou 'indirect\")\n * @param {boolean} [estCache = false] Si false, alors le tracé est en trait plein, sinon le tracé est en pointillés\n * @param {string} [color = 'black'] Couleur du demi-cercle : du type 'blue' ou du type '#f15929'\n * @param {number} [angledepart = context.anglePerspective] Angle en degré entre le vecteur rayon depuis le centre et le point de début de tracé du demi-cercle\n * @example demicercle3d(A,n,v) // Crée un demi-cercle noir en trait plein de centre A, de vecteur normal v, dont le rayon correspond au vecteur v et le sens est direct\n * @example demicercle3d(A,n,v,'indirect',true,'red',0) // Crée un demi-cercle rouge en pointillés de centre A, de vecteur normal v, dont le rayon correspond au vecteur v, le sens est direct et l'angle de départ est 0°.\n * @author Eric Elter (d'après version précédente de Jean-Claude Lhote)\n * @return {demiCercle}\n */\nexport function demicercle3d (centre, normal, rayon, sens = 'direct', estCache = false, color = 'black', angledepart = context.anglePerspective) {\n  let signe\n  const M = []\n  const listepoints = []\n  const listePoints3d = []\n  if (sens === 'direct') {\n    signe = 1\n  } else {\n    signe = -1\n  }\n  const d = droite3d(centre, normal)\n  M.push(rotation3d(translation3d(centre, rayon), d, angledepart))\n  listePoints3d.push(M[0])\n  listepoints.push(M[0].c2d)\n\n  for (let i = 1; i < 19; i++) {\n    M.push(rotation3d(M[i - 1], d, 10 * signe))\n    listePoints3d.push(M[i])\n    listepoints.push(M[i].c2d)\n  }\n  const demiCercle = polyline(listepoints, color)\n  if (estCache) {\n    demiCercle.pointilles = 2\n    demiCercle.opacite = 0.9\n  }\n  return demiCercle\n}\n\n/**\n * L'ARC\n *\n *@author Mickael Guironnet\n * Le nom est trompeur, il s'agit le plus souvent d'un morceau d'ellipse représentant un arc projeté\n * Utilisé pour représenter un arc dont une moitié est visible mais pas l'autre.\n *\n * normal et rayon sont deux vecteurs 3d\n * normal est un vecteur normal au plan du cercle\n * rayon est le vecteur qui part du centre et qui joint la 1ere extremité visible.\n * cote est soit 'caché' soit 'visible'\n *\n */\nexport function arc3d (centre, normal, rayon, cote, color, angledepart, angledefin) {\n  const M = []\n  const listepoints = []\n  const d = droite3d(centre, normal)\n  M.push(rotation3d(translation3d(centre, rayon), d, angledepart))\n  listepoints.push(M[0].c2d)\n\n  const nbr = Math.floor((angledefin - angledepart) / 10)\n  for (let i = 1; i <= nbr; i++) {\n    M.push(rotation3d(M[i - 1], d, 10))\n    listepoints.push(M[i].c2d)\n  }\n  const arc = polyline(listepoints, color)\n  if (cote === 'caché') {\n    arc.pointilles = 2\n    arc.opacite = 0.3\n  }\n  return arc\n}\n\n/**\n * LE CERCLE\n *\n * @author Jean-Claude Lhote\n *\n * C'est la version entière du cercle : soit totalement visible, soit totalement caché.\n * visible est un booléen\n *\n */\nexport function cercle3d (centre, normal, rayon, visible = true, color = 'black', pointilles = false) {\n  const M = []\n  const listepoints = []\n  const listepoints3d = []\n  const d = droite3d(centre, normal)\n  M.push(rotation3d(translation3d(centre, rayon), d, context.anglePerspective))\n  listepoints3d.push(M[0])\n  listepoints.push(M[0].c2d)\n  for (let i = 1; i < 36; i++) {\n    M.push(rotation3d(M[i - 1], d, 10))\n    listepoints3d.push(M[i])\n    listepoints.push(M[i].c2d)\n  }\n  const C = polygone(listepoints, color)\n  C.isVisible = visible\n  if (pointilles) {\n    C.pointilles = 2\n  }\n  return [C, listepoints3d, listepoints]\n}\n\n/**\n * LE POLYGONE\n *\n * @author Jean-Claude Lhote\n * usages : polygone3d([A,B,C,...],color) ou polygone3d(A,B,C...) où A,B,C ... sont des point3d. color='black' par défaut.\n */\nclass Polygone3d {\n  constructor (...args) {\n    if (Array.isArray(args[0])) {\n      // Si le premier argument est un tableau\n      this.listePoints = args[0]\n      if (args[1]) {\n        this.color = args[1]\n      }\n    } else {\n      this.listePoints = args\n      this.color = 'black'\n    }\n    const segments3d = []\n    let A\n    const segments = []\n    A = this.listePoints[0]\n    this.listePoints2d = [A.c2d]\n    for (let i = 1; i < this.listePoints.length; i++) {\n      segments3d.push(arete3d(A, this.listePoints[i], this.color))\n      segments.push(segments3d[i - 1].c2d)\n      A = this.listePoints[i]\n      this.listePoints2d.push(A.c2d)\n    }\n    segments3d.push(arete3d(A, this.listePoints[0], this.color))\n    segments.push(segments3d[this.listePoints.length - 1].c2d)\n    this.aretes = segments3d\n    this.c2d = segments\n  }\n}\n\nexport function polygone3d (...args) {\n  return new Polygone3d(...args)\n}\n\n/*\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%% OBJETS COMPLEXES %%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n*/\n\n/**\n * LA SPHERE - ANCIENNE FONCTION\n *\n * @author Jean-Claude Lhote\n * Produit une sphère : choisir un nombre de parallèles impair pour avoir l'équateur. normal défini l'axe Nord-Sud.\n * rayon est le rayon de la sphère. l'équateur est dans le plan xy l'axe Nord-Sud est sur z\n * @param {Point3d} centre\n * @param {Number} rayon\n * @param {Number} nbParalleles\n * @param {Number} nbMeridiens\n * @param {string} color\n */\n\n/*\nfunction Sphere3d (centre, rayon, nbParalleles, nbMeridiens, color) {\n  ObjetMathalea2D.call(this, { })\n  this.centre = centre\n  this.rayon = vecteur3d(rayon, 0, 0)\n  this.normal = vecteur3d(0, 0, 1)\n  this.color = color\n  this.nbMeridiens = nbMeridiens\n  this.nbParalleles = nbParalleles\n  this.c2d = []; let c1; let c2; let c3; let c4; let C; let D\n  const prodvec = vecteur3d(math.cross(this.normal.matrice, this.rayon.matrice))\n  const rayon2 = vecteur3d(math.cross(this.rayon.matrice, math.multiply(prodvec.matrice, 1 / math.norm(prodvec.matrice))))\n  const R = rayon\n  const cote1 = 'caché'\n  const cote2 = 'visible'\n  for (let k = 0, rayon3; k < 1; k += 1 / (this.nbParalleles + 1)) {\n    C = point3d(centre.x, centre.y, centre.z + R * Math.sin(k * Math.PI / 2))\n    D = point3d(centre.x, centre.y, centre.z + R * Math.sin(-k * Math.PI / 2))\n    rayon3 = vecteur3d(R * Math.cos(k * Math.PI / 2), 0, 0)\n    c1 = demicercle3d(C, this.normal, rayon3, cote1, this.color, context.anglePerspective)\n    c2 = demicercle3d(C, this.normal, rayon3, cote2, this.color, context.anglePerspective)\n    c3 = demicercle3d(D, this.normal, rayon3, cote1, this.color, context.anglePerspective)\n    c4 = demicercle3d(D, this.normal, rayon3, cote2, this.color, context.anglePerspective)\n    this.c2d.push(c1, c2, c3, c4)\n  }\n  for (let k = 0, V; k < 181; k += 90 / this.nbMeridiens) {\n    V = rotationV3d(prodvec, this.normal, context.anglePerspective + k)\n    c1 = demicercle3d(this.centre, V, rayon2, cote2, this.color, 0)\n    c2 = demicercle3d(this.centre, V, rayon2, cote1, this.color, 0)\n    this.c2d.push(c1, c2)\n  }\n}\nexport function sphere3d (centre, rayon, nbParalleles, nbMeridiens, color = 'black') {\n  return new Sphere3d(centre, rayon, nbParalleles, nbMeridiens, color)\n}\n*/\n\n/**\n * Classe de la sphère\n * @param {Point3d} centre Centre de la sphère\n * @param {number} rayon Rayon de la sphère\n * @param {string} [colorEquateur = 'red'] Couleur de l'équateur : du type 'blue' ou du type '#f15929'\n * @param {string} [colorEnveloppe = 'blue'] Couleur de l'enveloppe de la sphère : du type 'blue' ou du type '#f15929'\n * @param {number} [nbParalleles = 0]  Le nombre de parallèles au total\n * @param {string} [colorParalleles = 'gray'] Couleur des parallèles de la sphère : du type 'blue' ou du type '#f15929'\n * @param {number} [nbMeridiens = 0]  Le nombre de méridiens au total\n * @param {string} [colorMeridiens = 'gray'] Couleur des méridiens de la sphère : du type 'blue' ou du type '#f15929'\n * @param {boolean} [affichageAxe = false] Permet (ou pas) l'affichage de l'axe de la sphère.\n * @param {string} [colorAxe = 'black'] Couleur de l'axe de la sphère : du type 'blue' ou du type '#f15929'\n * @param {number} inclinaison angle d'inclinaison de l'axe N-S\n * @property {Point3d} centre Centre de la sphère\n * @property {Vecteur3d} rayon Rayon de la sphère\n * @property {string} colorEquateur Couleur de l'équateur : du type 'blue' ou du type '#f15929'\n * @property {string} colorEnveloppe Couleur de l'enveloppe de la sphère : du type 'blue' ou du type '#f15929'\n * @property {number} nbParalleles Le nombre de parallèles au total\n * @property {string} colorParalleles Couleur des parallèles de la sphère : du type 'blue' ou du type '#f15929'\n * @property {number} nbMeridiens Le nombre de méridiens au total\n * @property {string} colorMeridiens Couleur des méridiens de la sphère : du type 'blue' ou du type '#f15929'\n * @property {boolean} affichageAxe Permet (ou pas) l'affichage de l'axe de la sphère.\n * @property {string} colorAxe Couleur de l'axe de la sphère : du type 'blue' ou du type '#f15929'\n * @property {Array} c2d Contient les commandes à tracer en 2d de cette fonction\n * @author Eric Elter (d'après version précédente de Jean-Claude Lhote)\n * @class\n */\nfunction Sphere3d (centre, rayon, colorEquateur = 'red', colorEnveloppe = 'blue', nbParalleles = 0, colorParalleles = 'gray', nbMeridiens = 0, colorMeridiens = 'gray', affichageAxe = false, colorAxe = 'black', inclinaison = 0) {\n  ObjetMathalea2D.call(this, {})\n  this.centre = centre\n  this.rayon = rayon\n  this.colorEquateur = colorEquateur\n  this.colorEnveloppe = colorEnveloppe\n  this.nbParalleles = nbParalleles\n  this.colorParalleles = colorParalleles\n  this.nbMeridiens = nbMeridiens\n  this.colorMeridiens = colorMeridiens\n  this.affichageAxe = affichageAxe\n  this.colorAxe = colorAxe\n  const droiteRot = droite3d(point3d(this.centre.x, this.centre.y, this.centre.z), vecteur3d(0, 1, 0))\n  const poleNord = rotation3d(\n    point3d(\n      this.centre.x,\n      this.centre.y,\n      this.centre.z + this.rayon,\n      true,\n      choisitLettresDifferentes(1, 'OQWX' + this.centre.label)[0],\n      'left'\n    ),\n    droiteRot,\n    inclinaison)\n  const poleSud = rotation3d(\n    point3d(\n      this.centre.x,\n      this.centre.y,\n      this.centre.z - this.rayon,\n      true,\n      choisitLettresDifferentes(1, 'OQWX' + this.centre.label + poleNord.label)[0],\n      'left'\n    ),\n    droiteRot,\n    inclinaison)\n  const nbParallelesDeConstruction = 36 // Ce nb de paralleles permet de construire l'enveloppe de la sphère (le \"cercle\" apparent de la sphère)\n  const divisionParalleles = this.nbParalleles !== 0 ? Math.round(2 * nbParallelesDeConstruction / this.nbParalleles) : 1\n  let unDesParalleles\n  let centreParallele\n  let rayonDuParallele\n  let normal\n  const paralleles = {\n    listePoints3d: [],\n    ptCachePremier: [],\n    indicePtCachePremier: [],\n    ptCacheDernier: [],\n    indicePtCacheDernier: []\n  }\n  const enveloppeSphere1 = []\n  let enveloppeSphere2 = []\n  let premierParallele = 100\n  let indicePremier\n  let indiceDernier\n  this.c2d = []\n\n  // Construction de tous les paralleles\n\n  // Construction du parallèle le plus proche du pôle nord\n  centreParallele = rotation3d(\n    point3d(\n      this.centre.x,\n      this.centre.y,\n      this.centre.z + this.rayon * Math.sin((nbParallelesDeConstruction - 1) / nbParallelesDeConstruction * Math.PI / 2)\n    ),\n    droiteRot,\n    inclinaison\n  )\n  rayonDuParallele = rotation3d(\n    vecteur3d(this.rayon * Math.cos((nbParallelesDeConstruction - 1) / nbParallelesDeConstruction * Math.PI / 2), 0, 0),\n    droiteRot,\n    inclinaison)\n  normal = rotation3d(\n    vecteur3d(0, 0, 1),\n    droiteRot,\n    inclinaison)\n  unDesParalleles = cercle3d(centreParallele, normal, rayonDuParallele)\n  paralleles.listePoints3d.push(unDesParalleles[1])\n  paralleles.ptCachePremier.push('')\n  paralleles.indicePtCachePremier.push('')\n  paralleles.ptCacheDernier.push('')\n  paralleles.indicePtCacheDernier.push('')\n\n  // Construction de tous les autres parallèles jusqu'au plus proche du pôle sud\n  for (let k = nbParallelesDeConstruction - 2, poly, j = 1; k > -nbParallelesDeConstruction; k -= 1) {\n    centreParallele = rotation3d(\n      point3d(\n        this.centre.x,\n        this.centre.y,\n        this.centre.z + this.rayon * Math.sin(k / nbParallelesDeConstruction * Math.PI / 2)\n      ),\n      droiteRot,\n      inclinaison)\n    rayonDuParallele = rotation3d(\n      vecteur3d(this.rayon * Math.cos(k / nbParallelesDeConstruction * Math.PI / 2), 0, 0),\n      droiteRot,\n      inclinaison)\n\n    normal = rotation3d(vecteur3d(0, 0, 1), droiteRot, inclinaison)\n    poly = polygone(unDesParalleles[2])\n    poly.isVisible = false\n    unDesParalleles = cercle3d(centreParallele, normal, rayonDuParallele, false)\n    paralleles.listePoints3d.push(unDesParalleles[1])\n    for (let ee = 0; ee < paralleles.listePoints3d[0].length; ee++) {\n      paralleles.listePoints3d[j][ee].isVisible = !(paralleles.listePoints3d[j][ee].c2d.estDansPolygone(poly))\n    }\n    paralleles.ptCachePremier.push('')\n    paralleles.indicePtCachePremier.push('')\n    paralleles.ptCacheDernier.push('')\n    paralleles.indicePtCacheDernier.push('')\n\n    for (let ee = 0, s, s1, d1, d2, jj, pt; ee < paralleles.listePoints3d[0].length; ee++) {\n      s = segment(paralleles.listePoints3d[j][ee].c2d, paralleles.listePoints3d[j][(ee + 1) % paralleles.listePoints3d[0].length].c2d)\n      s.isVisible = false\n      // Recherche du point d'intersection entre le parallèle actuel et le précédent.\n      if ((!paralleles.listePoints3d[j][ee].isVisible) && (paralleles.listePoints3d[j][(ee + 1) % paralleles.listePoints3d[0].length].isVisible)) {\n        jj = ee - 3\n        s1 = segment(paralleles.listePoints3d[j - 1][(paralleles.listePoints3d[0].length + jj) % paralleles.listePoints3d[0].length].c2d, paralleles.listePoints3d[j - 1][(paralleles.listePoints3d[0].length + jj - 1) % paralleles.listePoints3d[0].length].c2d)\n        s1.isVisible = false\n        // Le point d'intersection avec ce segment précis du parallèle actuel est avec l'un des 7 (nombre totalement empirique) segments les plus proches du parallèle précédent.\n        while (!s.estSecant(s1)) {\n          jj++\n          s1 = segment(paralleles.listePoints3d[j - 1][(paralleles.listePoints3d[0].length + jj) % paralleles.listePoints3d[0].length].c2d, paralleles.listePoints3d[j - 1][(paralleles.listePoints3d[0].length + jj - 1) % paralleles.listePoints3d[0].length].c2d)\n          s1.isVisible = false\n        }\n\n        // s étant secant avec s1, on mène plusieurs actions :\n        d1 = droite(paralleles.listePoints3d[j][ee].c2d, paralleles.listePoints3d[j][(ee + 1) % paralleles.listePoints3d[0].length].c2d)\n        d1.isVisible = false\n        d2 = droite(paralleles.listePoints3d[j - 1][(paralleles.listePoints3d[0].length + jj) % paralleles.listePoints3d[0].length].c2d, paralleles.listePoints3d[j - 1][(paralleles.listePoints3d[0].length + jj - 1) % paralleles.listePoints3d[0].length].c2d)\n        d2.isVisible = false\n        pt = pointIntersectionDD(d1, d2) // 1) Tout d'abord, ce point d'intersection est donc la frontière entre le visible et le caché et on l'enregistre comme élément de l'enveloppe de la sphère\n        enveloppeSphere1.push(pt)\n        //  2) Ensuite, si pt est le tout premier point d'intersection trouvé, on enregistre quel est le premier parallèle et quel est son indice\n        // Ces informmations serviront pour le tracé de l'enveloppe près du pôle Nord.\n        if (premierParallele >= j) {\n          premierParallele = j\n          indicePremier = jj % paralleles.listePoints3d[0].length\n        }\n        // 3) On note ce point pour le futur tracé du parallèle, si besoin\n        paralleles.ptCachePremier[j] = pt\n        paralleles.indicePtCachePremier[j] = ee\n      } else if ((paralleles.listePoints3d[j][ee].isVisible) && (!paralleles.listePoints3d[j][(ee + 1) % paralleles.listePoints3d[0].length].isVisible)) {\n        // Si le point précédent était l'entrée dans la partie cachée, alors celui-ci sera celui de l'entrée dans la partie visible (ou inversement)\n        // car pour chaque parallèle intersecté avec le précédent, il y a \"forcément\" deux points sauf tangence mais ce n'est pas un pb.\n        jj = ee - 3\n        s1 = segment(paralleles.listePoints3d[j - 1][(paralleles.listePoints3d[0].length + jj) % paralleles.listePoints3d[0].length].c2d, paralleles.listePoints3d[j - 1][(paralleles.listePoints3d[0].length + jj - 1) % paralleles.listePoints3d[0].length].c2d)\n        s1.isVisible = false\n        // On recherche le point d'intersection\n        while (!s.estSecant(s1)) {\n          jj++\n          s1 = segment(paralleles.listePoints3d[j - 1][(paralleles.listePoints3d[0].length + jj) % paralleles.listePoints3d[0].length].c2d, paralleles.listePoints3d[j - 1][(paralleles.listePoints3d[0].length + jj - 1) % paralleles.listePoints3d[0].length].c2d)\n          s1.isVisible = false\n        }\n        // s étant secant avec s1, on mène plusieurs actions :\n        d1 = droite(paralleles.listePoints3d[j][ee].c2d, paralleles.listePoints3d[j][(ee + 1) % paralleles.listePoints3d[0].length].c2d)\n        d1.isVisible = false\n        d2 = droite(paralleles.listePoints3d[j - 1][(paralleles.listePoints3d[0].length + jj) % paralleles.listePoints3d[0].length].c2d, paralleles.listePoints3d[j - 1][(paralleles.listePoints3d[0].length + jj - 1) % paralleles.listePoints3d[0].length].c2d)\n        d2.isVisible = false\n        pt = pointIntersectionDD(d1, d2)\n        // 1) Tout d'abord, ce point d'intersection est donc la frontière entre le visible et le caché et on l'enregistre comme élément de l'enveloppe de la sphère\n        enveloppeSphere2.push(pt)\n        // 2) Ensuite, si pt est le tout premier point d'intersection trouvé, on enregistre quel est le premier parallèle et quel est son indice\n        // Ces informmations serviront pour le tracé de l'enveloppe près du pôle Sud.\n        if (premierParallele >= j) {\n          premierParallele = j\n          indiceDernier = jj\n        }\n        // 3) On note ce point pour le futur tracé du parallèle, si besoin\n        paralleles.ptCacheDernier[j] = pt\n        paralleles.indicePtCacheDernier[j] = ee\n      }\n    }\n    j++\n  }\n\n  if (this.nbParalleles !== 0) {\n    let t = tracePoint(poleNord.c2d, this.colorParalleles)\n    t.style = 'o'\n    t.taille = 0.5\n    this.c2d.push(t)\n    t = tracePoint(poleSud.c2d, assombrirOuEclaircir(this.colorParalleles, 50))\n    t.style = 'o'\n    t.taille = 0.5\n    this.c2d.push(t)\n  }\n\n  // Construction des parallèles demandés\n  for (let k = nbParallelesDeConstruction, j = -1; k > -nbParallelesDeConstruction; k -= 1) {\n    const polyLineVisible = [] // Contient l'ensemble des points du parallèle contenus dans la partie visible\n    let polyLineCachee = [] // Idem pour la partie cachée.\n    if ((this.nbParalleles !== 0 || k === 0) && (k !== nbParallelesDeConstruction) && (k % divisionParalleles === 0)) { // k=0 : C'est l'équateur\n      for (let ee = 0; ee < paralleles.listePoints3d[0].length; ee++) {\n        if (paralleles.indicePtCachePremier[j] === ee) {\n          polyLineCachee.push(paralleles.ptCachePremier[j])\n        } else if (paralleles.indicePtCacheDernier[j] === ee) {\n          polyLineCachee.push(paralleles.ptCacheDernier[j])\n        } else {\n          // Tracé des pointilles ou pas des parallèles\n          if ((!paralleles.listePoints3d[j][ee].isVisible) && (!paralleles.listePoints3d[j][(ee + 1) % paralleles.listePoints3d[0].length].isVisible)) {\n            polyLineCachee.push(paralleles.listePoints3d[j][ee].c2d)\n          } else {\n            polyLineVisible.push(paralleles.listePoints3d[j][(ee + 1) % paralleles.listePoints3d[0].length].c2d)\n          }\n        }\n      }\n      if (k < 36 && k > -30) { // uniquement à bonne distance des pôles pour éviter les points trop proches\n        let securite = 0\n        if (polyLineCachee.length > 4) { // une précaution au cas où la liste de points est courte ça pourrait boucler à l'infini\n          while (securite < 10 && longueur(polyLineCachee[polyLineCachee.length - 1], polyLineCachee[0]) < 1) {\n            const dernierPoint = polyLineCachee.pop()\n            polyLineCachee = [point(dernierPoint.x, dernierPoint.y), ...polyLineCachee]\n            securite++\n          }\n        }\n        if (polyLineVisible.length > 4) {\n          while (securite < 20 && longueur(polyLineVisible[polyLineVisible.length - 1], polyLineVisible[0]) < 1) {\n            const premierPoint = polyLineVisible.shift()\n            polyLineVisible.push(point(premierPoint.x, premierPoint.y))\n            securite++\n          }\n        }\n      }\n      const ligneCachee = polyLineCachee.length > 0 ? polyline(...polyLineCachee) : null // parfois, il n'y a rien à cacher près du pôle nord\n      const ligneVisible = polyLineVisible.length > 0 ? polyline(...polyLineVisible) : null // et rien non plus à montrer près du pôle sud.\n      if (k === 0) { // là on est certain qu'il y a du monde à cacher et à montrer\n        ligneCachee.color = colorToLatexOrHTML(this.colorEquateur)\n        ligneCachee.epaisseur = 1.5\n        ligneVisible.color = colorToLatexOrHTML(this.colorEquateur)\n        ligneVisible.epaisseur = 1.5\n      } else {\n        if (ligneVisible) ligneVisible.color = colorToLatexOrHTML(this.colorParalleles)\n        if (ligneCachee) ligneCachee.color = colorToLatexOrHTML(this.colorParalleles)\n      }\n      if (ligneCachee) {\n        ligneCachee.pointilles = 4\n        ligneCachee.opacite = 0.5\n        this.c2d.push(ligneCachee)\n      }\n      if (ligneVisible) {\n        this.c2d.push(ligneVisible)\n      }\n    }\n    j++\n  }\n\n  // Construction des méridiens demandés\n  if (this.nbMeridiens !== 0) {\n    const divisionMeridiens = Math.round(36 / this.nbMeridiens)\n    for (let k = 0, s; k < 18; k += divisionMeridiens) {\n      const polyLineCachee1 = []\n      const polyLineVisible1 = []\n      const polyLineCachee2 = []\n      const polyLineVisible2 = []\n\n      for (let ee = 1; ee < paralleles.listePoints3d.length - 1; ee++) {\n        // Affichage des méridiens sans le dernier segment relié aux pôles\n        // s = segment(paralleles.listePoints3d[ee][k].c2d, paralleles.listePoints3d[(ee + 1) % paralleles.listePoints3d.length][k].c2d, this.colorMeridiens)\n        if ((!paralleles.listePoints3d[ee][k].isVisible) && (!paralleles.listePoints3d[(ee + 1) % paralleles.listePoints3d.length][k].isVisible)) {\n          //  s.pointilles = 4 // Laisser 4 car sinon les pointilles ne se voient dans les petits cercles\n          //  s.opacite = 0.5\n          polyLineCachee1.push(paralleles.listePoints3d[ee][k].c2d)\n        } else {\n          polyLineVisible1.push(paralleles.listePoints3d[ee][k].c2d)\n        }\n        // this.c2d.push(s)\n        // s = segment(paralleles.listePoints3d[ee][k + 18].c2d, paralleles.listePoints3d[(ee + 1) % paralleles.listePoints3d.length][k + 18].c2d, this.colorMeridiens)\n        if ((!paralleles.listePoints3d[ee][k + 18].isVisible) && (!paralleles.listePoints3d[(ee + 1) % paralleles.listePoints3d.length][k + 18].isVisible)) {\n          //   s.pointilles = 4 // Laisser 4 car sinon les pointilles ne se voient dans les petits cercles\n          //   s.opacite = 0.5\n          polyLineCachee2.push(paralleles.listePoints3d[ee][k + 18].c2d)\n        } else {\n          polyLineVisible2.push(paralleles.listePoints3d[ee][k + 18].c2d)\n        }\n      }\n      // Affichage de la partie reliée au pôle Nord\n      s = segment(poleNord.c2d, paralleles.listePoints3d[1][k].c2d, this.colorMeridiens)\n      this.c2d.push(s)\n      s = segment(paralleles.listePoints3d[1][k + 18].c2d, poleNord.c2d, this.colorMeridiens)\n      this.c2d.push(s)\n      // Affichage de la partie reliée au pôle Sud\n      s = segment(poleSud.c2d, paralleles.listePoints3d[paralleles.listePoints3d.length - 1][k].c2d, this.colorMeridiens)\n      if (!paralleles.listePoints3d[paralleles.listePoints3d.length - 1][0].isVisible) {\n        s.pointilles = 4 // Laisser 4 car sinon les pointilles ne se voient dans les petits cercles\n        s.opacite = 0.5\n      }\n      this.c2d.push(s)\n      s = segment(paralleles.listePoints3d[paralleles.listePoints3d.length - 1][k + 18].c2d, poleSud.c2d, this.colorMeridiens)\n      if (!paralleles.listePoints3d[paralleles.listePoints3d.length - 1][k].isVisible) {\n        s.pointilles = 4 // Laisser 4 car sinon les pointilles ne se voient dans les petits cercles\n        s.opacite = 0.5\n      }\n      this.c2d.push(s)\n\n      const ligneCachee1 = polyline(...polyLineCachee1)\n      const ligneVisible1 = polyline(...polyLineVisible1)\n      const ligneCachee2 = polyline(...polyLineCachee2)\n      const ligneVisible2 = polyline(...polyLineVisible2)\n      ligneCachee1.pointilles = 4\n      ligneCachee1.opacite = 0.5\n      ligneCachee2.pointilles = 4\n      ligneCachee2.opacite = 0.5\n\n      this.c2d.push(ligneCachee1, ligneVisible1, ligneCachee2, ligneVisible2)\n    }\n  }\n\n  // L'enveloppe finale contiendra les points de l'enveloppe 1 + les points de l'enveloppe 2 inversée (sinon le polygone serait croisé)\n  // A cela, il faut ajouter les points autour des pôles car les premiers parallèles ne s'intersectent pas forcément.\n  enveloppeSphere2 = enveloppeSphere2.reverse()\n  const enveloppeSphere = [...enveloppeSphere1]\n\n  // Pour trouver les points du cercle apparent près du pôle sud\n  // On va prendre les points du premier parallèle intersecté entre l'indice du premier point d'intersection et l'indice du dernier point d'intersection.\n  let ii = 1\n  while ((indiceDernier + paralleles.listePoints3d[0].length / 2 + ii) % paralleles.listePoints3d[0].length < (indicePremier + paralleles.listePoints3d[0].length / 2) % paralleles.listePoints3d[0].length) {\n    enveloppeSphere.push(paralleles.listePoints3d[2 * nbParallelesDeConstruction - 1 - premierParallele][(indiceDernier + paralleles.listePoints3d[0].length / 2 + ii) % paralleles.listePoints3d[0].length].c2d)\n    ii++\n  }\n  enveloppeSphere.push(...enveloppeSphere2)\n  // Pour trouver les points du cercle apparent près du pôle nord\n  // On va prendre les points du premier parallèle intersecté entre l'indice du premier point d'intersection et l'indice du dernier point d'intersection.\n  // La gestion des indices est plus compliquée car il arrive de repasser de 35 à 0 (36 modulo 36) d'où cette double gestion.\n\n  if (indiceDernier > indicePremier) {\n    ii = 1\n    while (indiceDernier + ii < indicePremier + paralleles.listePoints3d[0].length) {\n      enveloppeSphere.push(paralleles.listePoints3d[premierParallele][(indiceDernier + ii) % paralleles.listePoints3d[0].length].c2d)\n      ii++\n    }\n  } else {\n    ii = 1\n    while (indiceDernier + ii < indicePremier) {\n      enveloppeSphere.push(paralleles.listePoints3d[premierParallele][indiceDernier + ii].c2d)\n      ii++\n    }\n  }\n  const p = polygone(enveloppeSphere, this.colorEnveloppe)\n  p.epaisseur = 1.5\n\n  this.c2d.push(p)\n\n  if (this.affichageAxe) {\n    const l = longueur(poleNord.c2d, poleSud.c2d)\n    let ee = 1\n    const poly = polygone(enveloppeSphere)\n    // poly.isVisible = false\n    while (ee < 2 && pointSurSegment(poleNord.c2d, poleSud.c2d, ee * l).estDansPolygone(poly)) {\n      ee += 0.01\n    }\n\n    let s = segment(poleNord.c2d, pointSurSegment(poleNord.c2d, poleSud.c2d, Math.max(ee - 0.01, 1) * l), this.colorAxe)\n    s.pointilles = 2\n    this.c2d.push(s)\n    s = segment(poleSud.c2d, pointSurSegment(poleNord.c2d, poleSud.c2d, 1.1 * l), this.colorAxe)\n    this.c2d.push(s)\n    s = segment(poleNord.c2d, pointSurSegment(poleNord.c2d, poleSud.c2d, -0.1 * l), this.colorAxe)\n    this.c2d.push(s)\n  }\n}\n\n/**\n * Crée une sphère\n * @param {Point3d} centre Centre de la sphère\n * @param {Vecteur3d} rayon Vecteur correspondant au rayon de la sphère\n * @param {string} [colorEquateur = 'red'] Couleur de l'équateur : du type 'blue' ou du type '#f15929'\n * @param {string} [colorEnveloppe = 'blue'] Couleur de l'enveloppe de la sphère : du type 'blue' ou du type '#f15929'\n * @param {number} [nbParalleles = 0]  Le nombre de parallèles au total\n * @param {string} [colorParalleles = 'gray'] Couleur des parallèles de la sphère : du type 'blue' ou du type '#f15929'\n * @param {number} [nbMeridiens = 0]  Le nombre de méridiens au total\n * @param {string} [colorMeridiens = 'gray'] Couleur des méridiens de la sphère : du type 'blue' ou du type '#f15929'\n * @param {boolean} [affichageAxe = false] Permet (ou pas) l'affichage de l'axe de la sphère.\n * @param {string} [colorAxe = 'black'] Couleur de l'axe de la sphère : du type 'blue' ou du type '#f15929'\n * @param {number} inclinaison Angle d'inclinaison de l'axe N-S\n * @example sphere3d(A,v) // Crée une sphère de centre A et dont le rayon correspond au vecteur v, l'équateur rouge et l'enveloppe bleue\n * @example sphere3d(A,v,'green','pink') // Crée une sphère de centre A et dont le rayon correspond au vecteur v, l'équateur vert et l'enveloppe rose\n * @example sphere3d(A,v,'green','pink',18,'red') // Crée une sphère de centre A et dont le rayon correspond au vecteur v, l'équateur vert, l'enveloppe rose, avec 18 parallèles rouges\n * @example sphere3d(A,v,'green','pink',18,'red',36,'blue') // Crée une sphère de centre A et dont le rayon correspond au vecteur v, l'équateur vert, l'enveloppe rose, avec 18 parallèles rouges et 36 méridiens verts\n * @example sphere3d(A,v,'green','pink',18,'red',36,'blue',true,'#f15929') // Crée une sphère de centre A et dont le rayon correspond au vecteur v, l'équateur vert, l'enveloppe rose, avec 18 parallèles rouges, 36 méridiens verts et un axe affiché orange\n * @author Eric Elter (d'après version précédente de Jean-Claude Lhote)\n * @return {Sphere3d}\n */\nexport function sphere3d (centre, rayon, colorEquateur = 'red', colorEnveloppe = 'blue', nbParalleles = 0, colorParalleles = 'gray', nbMeridiens = 0, colorMeridiens = 'black', affichageAxe = false, colorAxe = 'black', inclinaison = 0) {\n  return new Sphere3d(centre, rayon, colorEquateur, colorEnveloppe, nbParalleles, colorParalleles, nbMeridiens, colorMeridiens, affichageAxe, colorAxe, inclinaison)\n}\n\n/**\n * LE CONE (jamais utilisé)\n *\n * @author Jean-Claude Lhote\n *\n * centrebase est le centre du disque de base\n * sommet est le sommet du cône\n * normal est un vecteur 3d normal au plan du disque (il détermine avec rayon de quel côté se trouve la partie visible)\n *\n */\n\n/*\nfunction Cone3d (centrebase, sommet, rayon, generatrices = 18) {\n  ObjetMathalea2D.call(this, { })\n  this.sommet = sommet\n  this.centrebase = centrebase\n  this.normal = vecteur3d(centrebase, sommet)\n  if (typeof (rayon) === 'number') {\n    this.rayon = vecteur3d(rayon, 0, 0)\n  } else {\n    this.rayon = rayon\n  }\n  this.c2d = []\n  let s, color1, color2\n  const prodvec = vecteur3d(math.cross(this.normal.matrice, this.rayon.matrice))\n  const prodscal = math.dot(prodvec.matrice, vecteur3d(0, 1, 0).matrice)\n  let cote1, cote2\n  if (prodscal > 0) {\n    cote1 = 'caché'\n    color1 = 'gray'\n    cote2 = 'visible'\n    color2 = 'black'\n  } else {\n    cote2 = 'caché'\n    cote1 = 'visible'\n    color1 = 'black'\n    color2 = 'gray'\n  }\n  const c1 = demicercle3d(this.centrebase, this.normal, this.rayon, cote1, color1)\n  const c2 = demicercle3d(this.centrebase, this.normal, this.rayon, cote2, color2)\n\n  for (let i = 0; i < c1.listePoints.length; i++) {\n    if (i % generatrices === 0) {\n      s = segment(this.sommet.c2d, c1.listePoints[i])\n      if (cote1 === 'caché') {\n        s.pointilles = 2\n        s.color = colorToLatexOrHTML('gray')\n      } else {\n        s.color = colorToLatexOrHTML('black')\n      }\n      this.c2d.push(s)\n    }\n  }\n  for (let i = 0; i < c2.listePoints.length; i++) {\n    if (i % generatrices === 0) {\n      s = segment(this.sommet.c2d, c2.listePoints[i])\n      if (cote2 === 'caché') {\n        s.pointilles = 2\n        s.color = colorToLatexOrHTML('gray')\n      } else {\n        s.color = colorToLatexOrHTML('black')\n      }\n      this.c2d.push(s)\n    }\n  }\n  this.c2d.push(c1, c2)\n}\nexport function cone3d (centre, sommet, rayon, generatrices = 18) {\n  return new Cone3d(centre, sommet, rayon, generatrices)\n}\n*/\n\n/**\n * Classe du cône\n * @param {Point3d} centre Centre de la base du cône\n * @param {Point3d} sommet Sommet du cône\n * @param {Vecteur3d} rayon Rayon de la base du cône\n * @param {string} [color = 'black'] Couleur des génératrices visibles et de la base du cône : du type 'blue' ou du type '#f15929'\n * @param {boolean} [affichageAxe = true] Permet (ou pas) l'affichage de l'axe du cône.\n * @param {string} [colorAxe = 'black'] Couleur de l'axe et du centre de la base du cône : du type 'blue' ou du type '#f15929'\n * @param {string} [colorCone = 'gray'] Couleur du cône : du type 'blue' ou du type '#f15929'\n * @property {Point3d} centre centre de la base du cône\n * @property {Point3d} sommet Sommet du cône\n * @property {Vecteur3d} rayon Rayon de la base du cône\n * @property {string} color Couleur des génératrices visibles et de la base du cône : du type 'blue' ou du type '#f15929'\n * @property {boolean} affichageAxe Permet (ou pas) l'affichage de l'axe du cône.\n * @property {string} colorAxe Couleur de l'axe et du centre de la base du cône : du type 'blue' ou du type '#f15929'\n * @property {string} colorCone Couleur du cône : du type 'blue' ou du type '#f15929'\n * @property {Array} c2d Contient les commandes à tracer en 2d de cette fonction\n * @author Eric Elter (d'après version précédente de Jean-Claude Lhote)\n * @class\n */\nfunction Cone3d (centre, sommet, rayon, color = 'black', affichageAxe = true, colorAxe = 'black', colorCone = 'gray') {\n  ObjetMathalea2D.call(this, {})\n  this.centre = centre\n  this.sommet = sommet\n  this.rayon = rayon\n  this.color = color\n  this.colorAxe = colorAxe\n  this.colorCone = colorCone\n\n  const pt1 = translation3d(this.centre, this.rayon)\n  const ptsBase = [pt1]\n  const nbSommets = 36\n  for (let ee = 1; ee < nbSommets; ee++) {\n    ptsBase.push(rotation3d(pt1, droite3d(this.centre, vecteur3d(this.sommet, this.centre)), ee * 360 / (nbSommets)))\n  }\n  const p = polygone3d(ptsBase, this.color)\n  // this.c2d = pyramide3d(p, this.sommet, this.color, this.centre, affichageAxe, this.colorAxe, false, true, this.colorCone).c2d\n  this.c2d = pyramide3d(p, this.sommet, this.color, this.centre, affichageAxe, this.colorAxe, false, true, this.colorCone).c2d\n}\n\n/**\n * Crée un cône\n * @param {Point3d} centre centre de la base du cône\n * @param {Point3d} sommet Sommet du cône\n * @param {Vecteur3d} rayon Rayon de la base du cône\n * @param {string} [color = 'black'] Couleur des génératrices visibles et de la base du cône : du type 'blue' ou du type '#f15929'\n * @param {boolean} [affichageAxe = true] Permet (ou pas) l'affichage de l'axe du cône.\n * @param {string} [colorAxe = 'black'] Couleur de l'axe et du centre de la base du cône : du type 'blue' ou du type '#f15929'\n * @param {string} [colorCone = 'gray'] Couleur du cône : du type 'blue' ou du type '#f15929'\n * @example cone3d(A,B,v) // Créé un cône de centre A, de sommet B et dont le rayon correspond au vecteur v\n * @example cone3d(A,B,v,'red') // Créé un cône de centre A, de sommet B et dont le rayon correspond au vecteur v, la couleur du cône en fil de fer est rouge\n * @example cone3d(A,B,v,'red',true,'green') // Créé un cône de centre A, de sommet B et dont le rayon correspond au vecteur v, la couleur du cône en fil de fer est rouge, l'axe est affiché en vert\n * @example cone3d(A,B,v,'red',true,'green','blue') // Créé un cône de centre A, de sommet B et dont le rayon correspond au vecteur v, la couleur du cône en fil de fer est rouge, l'axe est affiché en vert et la face externe du cône est bleue\n * @author Eric Elter\n * @return {Cone3d}\n */\nexport function cone3d (centre, sommet, rayon, color = 'black', affichageAxe = false, colorAxe = 'black', colorCone = 'gray') {\n  return new Cone3d(centre, sommet, rayon, color, affichageAxe, colorAxe, colorCone)\n}\n\n/**\n * Classe du cylindre : un cylindre de révolution défini par les centres de ses 2 bases\n * Permet en faisant varier les rayons des deux bases de créer des troncs de cônes (A VERIFIER)\n * @param {Point3d} centrebase1 Centre de la première base\n * @param {Point3d} centrebase2 Centre de la seconde base\n * @param {Vecteur3d} rayon1 Vecteur correspondant au rayon de la première base\n * @param {Vecteur3d} rayon2 Vecteur correspondant au rayon de la seconde base\n * @param {string} [color = 'black'] Couleur des \"bords\" du cylindre : du type 'blue' ou du type '#f15929'\n * @param {boolean} [affichageGeneratrices = true] Permet (ou pas) l'affichage de génératrices du cylindre\n * @param {boolean} [affichageCentreBases = false] Permet (ou pas) l'affichage des centres respectifs de chaque base\n * @param {boolean} [affichageAxe = false] Permet (ou pas) l'affichage de l'axe du cylindre\n * @param {string} [colorAxe = 'black'] Couleur de l'axe et des centres respectifs de chaque base du cylindre : du type 'blue' ou du type '#f15929'\n * @param {boolean} [cylindreColore = false] Permet (ou pas) de colorier le cylindre\n * @param {string} [colorCylindre = 'lightgray'] Couleur du cylindre (avec gestion intégrée de la nuance de couleurs): du type 'blue' ou du type '#f15929'\n * @property {Point3d} centrebase1 Centre de la première base\n * @property {Point3d} centrebase2 Centre de la seconde base\n * @property {Vecteur3d} rayon1 Vecteur correspondant au rayon de la première base\n * @property {Vecteur3d} rayon2 Vecteur correspondant au rayon de la seconde base\n * @property {string} color Couleur des \"bords\" du cylindre : du type 'blue' ou du type '#f15929'\n * @property {boolean} affichageGeneratrices Permet (ou pas) l'affichage de génératrices du cylindre\n * @property {boolean} affichageCentreBases Permet (ou pas) l'affichage des centres respectifs de chaque base\n * @property {boolean} affichageAxe Permet (ou pas) l'affichage de l'axe du cylindre\n * @property {string} colorAxe Couleur de l'axe et des centres respectifs de chaque base du cylindre : du type 'blue' ou du type '#f15929'\n * @property {boolean} cylindreColore Permet (ou pas) de colorier le cylindre\n * @property {string} colorCylindre Couleur du cylindre (avec gestion intégrée de la nuance de couleurs): du type 'blue' ou du type '#f15929'\n * @property {number} angleDepart Angle de rotation à partir duquel les demis-cercles formant la base sont tracés\n * @property {Points[]} pointsBase1 Liste des points formant la ligne de la base 1\n * @property {Points[]} pointsBase2 Liste des points formant la ligne de la base 2\n * @property {Array} c2d Contient les commandes à tracer en 2d de cette fonction\n * @author Jean-Claude Lhote (optimisé par Eric Elter)\n * @class\n */\nfunction Cylindre3d (centrebase1, centrebase2, rayon1, rayon2, color = 'black', affichageGeneratrices = true, affichageCentreBases = false, affichageAxe = false, colorAxe = 'black', cylindreColore = false, colorCylindre = 'lightgray') {\n  ObjetMathalea2D.call(this, {})\n  this.centrebase1 = centrebase1\n  this.centrebase2 = centrebase2\n  this.rayon1 = rayon1\n  this.rayon2 = rayon2\n  this.color = color\n  this.affichageGeneratrices = affichageGeneratrices\n  this.affichageCentreBases = affichageCentreBases\n  this.affichageAxe = affichageAxe\n  this.colorAxe = colorAxe\n  this.cylindreColore = cylindreColore\n  this.colorCylindre = colorCylindre\n  this.c2d = []\n  let s\n  this.normal = vecteur3d(this.centrebase1, this.centrebase2)\n  const prodvec = vecteur3d(math.cross(this.normal.matrice, this.rayon1.matrice))\n  const prodscal = math.dot(prodvec.matrice, vecteur3d(0, 1, 0).matrice)\n  let cote1, cote2\n  const centre1PlusBasQueCentre2 = this.centrebase1.c2d.y !== this.centrebase2.c2d.y ? this.centrebase1.c2d.y < this.centrebase2.c2d.y : (context.anglePerspective > 0)\n  if (prodscal * context.anglePerspective > 0) {\n    cote1 = centre1PlusBasQueCentre2 ? 'direct' : 'indirect'\n    cote2 = centre1PlusBasQueCentre2 ? 'indirect' : 'direct'\n  } else {\n    cote2 = centre1PlusBasQueCentre2 ? 'direct' : 'indirect'\n    cote1 = centre1PlusBasQueCentre2 ? 'indirect' : 'direct'\n  }\n  cote2 = (this.rayon1.x === 0 && this.rayon1.y === 0) ? 'indirect' : cote2\n  cote1 = (this.rayon1.x === 0 && this.rayon1.y === 0) ? 'direct' : cote1\n  // Cette partie permet de chercher le bon angle de départ pour le tracé des demi-bases\n  // Recherche du premier point visible sur la demi-base visible\n  let angleDepart = 0\n  let distanceMax = 0\n  const d = droite3d(this.centrebase1, this.normal)\n  let ptReference = rotation3d(translation3d(this.centrebase1, this.rayon1), d, angleDepart)\n  const secondPt = rotation3d(translation3d(this.centrebase1, this.rayon1), d, angleDepart + 1)\n  const sensRecherche = distancePointDroite(ptReference.c2d, d.c2d) < distancePointDroite(secondPt.c2d, d.c2d) ? 1 : -1\n  while ((distancePointDroite(ptReference.c2d, d.c2d) > distanceMax)) {\n    distanceMax = distancePointDroite(ptReference.c2d, d.c2d)\n    angleDepart = angleDepart + sensRecherche\n    ptReference = rotation3d(translation3d(this.centrebase1, this.rayon1), d, angleDepart)\n  }\n  angleDepart = angleDepart - sensRecherche\n  // angleDepart est donc l'angle qui permet d'avoir un tracé de demicercle3d idéal\n  this.angleDepart = angleDepart\n  // Description de chaque demi-base en position verticale\n  // c1 : cercle bas derrière\n  const c1 = demicercle3d(this.centrebase1, this.normal, this.rayon1, cote1, true, this.color, angleDepart)\n  // c3 : cercle haut derrière\n  const c3 = demicercle3d(this.centrebase2, this.normal, this.rayon2, cote1, false, this.color, angleDepart)\n  // c2 : cercle bas devant\n  const c2 = demicercle3d(this.centrebase1, this.normal, this.rayon1, cote2, false, this.color, angleDepart)\n  // c4 : cercle haut devant\n  const c4 = demicercle3d(this.centrebase2, this.normal, this.rayon2, cote2, false, this.color, angleDepart)\n  this.pointsBase1 = [...c1.listePoints, ...c2.listePoints]\n  this.pointsBase2 = [...c3.listePoints, ...c4.listePoints]\n  if (this.cylindreColore) {\n    let polygon = [...c4.listePoints]\n    for (let i = c2.listePoints.length - 1; i >= 0; i--) {\n      polygon.push(c2.listePoints[i])\n    }\n    const faceColoree = polygone(polygon, 'white')\n    faceColoree.couleurDeRemplissage = colorToLatexOrHTML(this.colorCylindre)\n    this.c2d.push(faceColoree)\n\n    polygon = [...c3.listePoints]\n    for (let i = c4.listePoints.length - 1; i >= 0; i--) {\n      polygon.push(c4.listePoints[i])\n    }\n    const baseColoree = polygone(polygon, 'white')\n    baseColoree.couleurDeRemplissage = colorToLatexOrHTML(assombrirOuEclaircir(this.colorCylindre, 25))\n    this.c2d.push(baseColoree)\n  }\n\n  if (this.affichageGeneratrices) {\n    for (let i = 1; i < c1.listePoints.length - 1; i += 2) {\n      s = segment(c3.listePoints[i], c1.listePoints[i], this.color)\n      s.pointilles = 2\n      s.opacite = 0.3\n      this.c2d.push(s)\n    }\n  }\n\n  s = segment(c4.listePoints[0], c2.listePoints[0], this.color)\n  this.c2d.push(s)\n\n  if (this.affichageGeneratrices) {\n    for (let i = 1; i < c2.listePoints.length - 1; i++) {\n      s = segment(c4.listePoints[i], c2.listePoints[i], this.color)\n      this.c2d.push(s)\n    }\n  }\n\n  s = segment(c4.listePoints[c2.listePoints.length - 1], c2.listePoints[c2.listePoints.length - 1], this.color)\n  this.c2d.push(s)\n\n  this.c2d.push(c1, c2, c3, c4)\n\n  if (this.affichageCentreBases) {\n    this.c2d.push(tracePoint(this.centrebase1.c2d, this.centrebase2.c2d, this.colorAxe))\n  }\n\n  if (this.affichageAxe) {\n    let distanceMin = 9999\n    const pt = c2.listePoints\n    let i = 0\n    while ((distancePointDroite(pt[i], d.c2d) < distanceMin)) {\n      distanceMin = distancePointDroite(pt[i], d.c2d)\n      i++\n    }\n    s = segment(this.centrebase2.c2d, pt[i - 1], this.colorAxe)\n    s.pointilles = 2\n    s.opacite = 0.7\n    this.c2d.push(s)\n    const v = vecteur(this.centrebase2.c2d, this.centrebase1.c2d)\n    s = segment(pt[i - 1], translation(pt[i - 1], vecteur(v.x / norme(v), v.y / norme(v))), this.colorAxe)\n    this.c2d.push(s)\n    s = segment(this.centrebase2.c2d, translation(translation(this.centrebase2.c2d, vecteur(pt[i - 1], this.centrebase1.c2d)), vecteur(-v.x / norme(v), -v.y / norme(v))), this.colorAxe)\n    this.c2d.push(s)\n  }\n}\n\n/**\n * Crée un cylindre de révolution défini par les centres de ses 2 bases\n * Permet en faisant varier les rayons des deux bases de créer des troncs de cônes (A VERIFIER)\n * @param {Point3d} centrebase1 Centre de la première base\n * @param {Point3d} centrebase2 Centre de la seconde base\n * @param {Vecteur3d} rayon1 Vecteur correspondant au rayon de la première base\n * @param {Vecteur3d} rayon2 Vecteur correspondant au rayon de la seconde base\n * @param {string} [color = 'black'] Couleur des \"bords\" du cylindre : du type 'blue' ou du type '#f15929'\n * @param {boolean} [affichageGeneratrices = true] Permet (ou pas) l'affichage de génératrices du cylindre\n * @param {boolean} [affichageCentreBases = false] Permet (ou pas) l'affichage des centres respectifs de chaque base\n * @param {boolean} [affichageAxe = false] Permet (ou pas) l'affichage de l'axe du cylindre\n * @param {string} [colorAxe = 'black'] Couleur de l'axe et des centres respectifs de chaque base du cylindre : du type 'blue' ou du type '#f15929'\n * @param {boolean} [cylindreColore = false] Permet (ou pas) de colorier le cylindre\n * @param {string} [colorCylindre = 'lightgray'] Couleur du cylindre (avec gestion intégrée de la nuance de couleurs): du type 'blue' ou du type '#f15929'\n * @example cylindre3d(A, B, v, v, 'blue')\n * // Retourne un cylindre à bords bleus dont les bases ont pour centre respectif A et B et le rayon est donné par le vecteur v.\n * @example cylindre3d(A, B, v, v, 'green', false, true, true, 'red', true, 'lightblue')\n * // Retourne un cylindre à bords verts dont les bases ont pour centre respectif A et B et le rayon est donné par le vecteur v.\n * // Les génératrices sont invisibles, les centres et axe sont visibles et rouges, le cylindre est coloré en bleu.\n * @author Jean-Claude Lhote (optimisé par Eric Elter)\n * @return {Cylindre3d}\n */\nexport function cylindre3d (centrebase1, centrebase2, rayon, rayon2, color = 'black', affichageGeneratrices = true, affichageCentreBases = false, affichageAxe = false, colorAxe = 'black', cylindreColore = false, colorCylindre = 'lightgray') {\n  return new Cylindre3d(centrebase1, centrebase2, rayon, rayon2, color, affichageGeneratrices, affichageCentreBases, affichageAxe, colorAxe, cylindreColore, colorCylindre)\n}\n\n/**\n * LE PRISME - ANCIENNE FONCTION\n *\n * @author Jean-Claude Lhote\n * Crée un prisme à partir du base Polygone3d et d'un vecteur3d d'extrusion (on peut faire des prismes droits ou non droits)\n */\n\n/* class Prisme3d {\n  constructor (base, vecteur, color) {\n    ObjetMathalea2D.call(this, { })\n\n    this.color = color\n    base.color = colorToLatexOrHTML(this.color)\n    this.base1 = base\n    this.base2 = translation3d(base, vecteur)\n    this.base2.color = this.base1.color\n    this.c2d = []; let s\n    for (let i = 0; i < this.base1.listePoints.length; i++) {\n      this.c2d.push(this.base1.c2d[i])\n    }\n    for (let i = 0; i < this.base2.listePoints.length; i++) {\n      this.c2d.push(this.base2.c2d[i])\n    }\n    for (let i = 0; i < this.base1.listePoints.length; i++) {\n      s = arete3d(this.base1.listePoints[i], this.base2.listePoints[i], this.color)\n      this.c2d.push(s.c2d)\n    }\n  }\n}\n\nexport function prisme3d (base, vecteur, color = 'black') {\n  return new Prisme3d(base, vecteur, color)\n} */\n\n/**\n * Classe du prisme droit\n * Ce prisme droit est optimisé dans son tracé des arêtes cachées pour des bases dans le plan (xOy) et son vecteur normal selon (Oz)\n * Pour d'autres usages, il faut approfondir la fonction mais laissé en l'état car justement pas d'autre usage demandé.\n * @param {Polygone3d} base Une des deux bases du prisme droit\n * @param {Vecteur3d} vecteur Vecteur normal à la base dont la norme indique la hauteur du prisme droit.\n * @param {string} [color = 'black'] Couleur des arêtes du prisme droit : du type 'blue' ou du type '#f15929'\n * @param {boolean} [affichageNom = false] Permet (ou pas) l'affichage du nom des sommets du prisme.\n * @property {Polygone3d} base1 La base entièrement visible du prisme droit\n * @property {Vecteur3d} vecteur Vecteur normal à la base dont la norme indique la hauteur du prisme droit.\n * @property {string} [color = 'black'] Couleur des arêtes du prisme droit : du type 'blue' ou du type '#f15929'\n * @property {boolean} [affichageNom = false] Permet (ou pas) l'affichage du nom des sommets du prisme.\n * @property {Array} c2d Contient les commandes à tracer en 2d de cette fonction\n * @property {string} nom Nom du prisme\n * @author Eric Elter (d'après version précédente de Jean-Claude Lhote)\n * @class\n */\nclass Prisme3d {\n  constructor (base, vecteur, color, affichageNom = false) {\n    ObjetMathalea2D.call(this, {})\n    this.affichageNom = affichageNom\n    this.color = color\n    base.color = colorToLatexOrHTML(this.color)\n    this.vecteur = vecteur\n    this.base1 = this.vecteur.z >= 1 ? base : translation3d(base, vecteur3d(this.vecteur.x, this.vecteur.y, -this.vecteur.z))\n    this.base2 = this.vecteur.z < 1 ? base : translation3d(base, this.vecteur)\n    this.base2.color = this.base1.color\n    this.c2d = []\n    let s\n    // On trace this.base1 (toujours visible)\n    for (let i = 0; i < this.base1.listePoints.length; i++) {\n      this.c2d.push(this.base1.c2d[i])\n    }\n    // On cherche les sommets cachés de this.base2\n    let toutesLesAretesSontVisibles = true\n    for (let i = 0; i < this.base1.listePoints.length; i++) {\n      const areteVisibleOuPas = pointSurSegment(this.base1.listePoints[i].c2d, this.base2.listePoints[i].c2d, longueur(this.base1.listePoints[i].c2d, this.base2.listePoints[i].c2d) / 50).estDansPolygone(polygone(this.base1.listePoints2d))\n      this.base2.listePoints[i].visible = !areteVisibleOuPas\n      toutesLesAretesSontVisibles = !areteVisibleOuPas & toutesLesAretesSontVisibles\n    }\n    // On trace les arêtes de this.base2\n    for (let i = 0; i < this.base2.listePoints.length; i++) {\n      s = arete3d(this.base2.listePoints[i], this.base2.listePoints[i + 1 === this.base2.listePoints.length ? 0 : i + 1], this.color)\n      if (toutesLesAretesSontVisibles) { // Cas particulier où aucun sommet de this.base2 n'est caché (cas de certains tétraèdres)\n        let areteVisibleOuPas = true\n        for (let ee = 0; ee < this.base1.listePoints.length; ee++) {\n          const areteLiaison = segment(this.base1.listePoints[ee].c2d, this.base2.listePoints[ee].c2d)\n          areteVisibleOuPas = areteVisibleOuPas && (areteLiaison.estSecant(s.c2d))\n        }\n        s = arete3d(this.base2.listePoints[i], this.base2.listePoints[i + 1 === this.base2.listePoints.length ? 0 : i + 1], this.color, !areteVisibleOuPas)\n      }\n      this.c2d.push(s.c2d)\n    }\n    // On trace les arêtes de liaison entre les bases\n    for (let i = 0; i < this.base1.listePoints.length; i++) {\n      s = arete3d(this.base1.listePoints[i], this.base2.listePoints[i], this.color)\n      this.c2d.push(s.c2d)\n    }\n\n    if (this.affichageNom) {\n      let p = polygone(this.base1.listePoints2d)\n      const nomBase1 = choisitLettresDifferentes(this.base1.listePoints.length, 'OQWX')\n      renommePolygone(p, nomBase1)\n      for (let ee = 0; ee < this.base1.listePoints2d.length; ee++) {\n        this.base1.listePoints2d[ee].positionLabel = 'above'\n      }\n      this.c2d.push(labelPoint(...p.listePoints))\n      p = polygone(this.base2.listePoints2d)\n      const nomBase2 = choisitLettresDifferentes(this.base1.listePoints.length, 'OQWX' + nomBase1)\n      renommePolygone(p, nomBase2)\n      for (let ee = 0; ee < this.base2.listePoints2d.length; ee++) {\n        this.base2.listePoints2d[ee].positionLabel = 'below'\n      }\n      this.c2d.push(labelPoint(...p.listePoints))\n      this.nom = nomBase1 + nomBase2\n    }\n  }\n}\n\n/**\n * Crée un prisme droit\n * Ce prisme droit est optimisé dans son tracé des arêtes cachées pour des bases dans le plan (xOy) et son vecteur normal selon (Oz)\n * Pour d'autres usages, il faut approfondir la fonction mais laissé en l'état car justement pas d'autre usage demandé.\n * @param {Polygone3d} base Une des deux bases du prisme droit\n * @param {Vecteur3d} vecteur Vecteur normal à la base dont la norme indique la hauteur du prisme droit.\n * @param {string} [color = 'black'] Couleur des arêtes du prisme droit : du type 'blue' ou du type '#f15929'\n * @param {boolean} [affichageNom = false] Permet (ou pas) l'affichage du nom des sommets du prisme.\n * @example prisme3d(p, v)\n * // Retourne un prisme droit de base p dont un vecteur normal à la base est v.\n * @example prisme3d(p, v, 'blue', true)\n * // Retourne un prisme droit de base p dont un vecteur normal à la base est v, de couleur V et dont les sommets sont nommés\n * @author Eric Elter (d'après version précédente de Jean-Claude Lhote)\n * @return {Prisme3d}\n */\nexport function prisme3d (base, vecteur, color = 'black', affichageNom = false) {\n  return new Prisme3d(base, vecteur, color, affichageNom)\n}\n\n/**\n * La pyramide  - ANCIENNE FONCTION\n *\n * @author Jean-Claude Lhote\n * Crée une pyramide à partir d'une base Polygone3d et d'un sommet\n */\n\n/*\nclass Pyramide3d {\n  constructor (base, sommet, color) {\n    ObjetMathalea2D.call(this, { })\n\n    this.color = color\n    base.color = colorToLatexOrHTML(color)\n    this.base = base\n    this.aretes = []\n    this.sommet = sommet\n    this.c2d = []; let s\n    for (let i = 0; i < this.base.listePoints.length; i++) {\n      s = this.base.c2d[i]\n      if (this.base.listePoints[i].visible) {\n        s.pointilles = false\n      } else {\n        s.pointilles = 2\n      }\n      this.c2d.push(s)\n    }\n    for (let i = 0; i < this.base.listePoints.length; i++) {\n      s = arete3d(this.base.listePoints[i], this.sommet, this.color, true)\n      if (this.base.listePoints[i].visible) {\n        s.c2d.pointilles = false\n      } else {\n        s.c2d.pointilles = 2\n      }\n      this.c2d.push(s.c2d)\n    }\n  }\n}\n\nexport function pyramide3d (base, vecteur, color = 'black') {\n  return new Pyramide3d(base, vecteur, color)\n}\n*/\n\n/**\n * Classe de la pyramide\n * (optimisée au niveau des pointillés pour une base sur le plan xOy et un sommet plus haut ou plus bas que la base)\n * @param {Polygone3d} base Base de la pyramide\n * @param {Point3d} sommet Sommet de la pyramide\n * @param {string} [color = 'black'] Couleur des arêtes du prisme droit : du type 'blue' ou du type '#f15929'\n * @param {Point3d} [centre] Centre de la pyramide... Entraine l'affichage de ce centre\n * @param {boolean} [affichageAxe = false] Permet (ou pas) l'affichage de l'axe de la pyramide. Ne fonctionne que si centre est défini.\n * @param {string} [colorAxe = 'black'] Couleur de l'axe et du centre de la base de la pyramide : du type 'blue' ou du type '#f15929'\n * @param {boolean} [affichageNom = false] Permet (ou pas) l'affichage du nom des sommets de la pyramide.\n * @param {boolean} [estCone = false] Permet (ou pas) de considérer la pyramide comme un cône... dans le cas où la base est un disque.\n * @param {string} [colorCone = 'gray'] Couleur du cône : du type 'blue' ou du type '#f15929'\n * @property {Polygone3d} base Base de la pyramide\n * @property {Point3d} sommet Sommet de la pyramide\n * @property {string} color Couleur des arêtes de la pyramide : du type 'blue' ou du type '#f15929'\n * @property {Point3d} centre Centre de la pyramide... Entraine l'affichage de ce centre\n * @property {boolean} affichageAxe Permet (ou pas) l'affichage de l'axe de la pyramide. Ne fonctionne que si centre est défini.\n * @property {string} colorAxe Couleur de l'axe et du centre de la base de la pyramide : du type 'blue' ou du type '#f15929'\n * @property {boolean} affichageNom Permet (ou pas) l'affichage du nom des sommets de la pyramide.\n * @property {string} nom Nom de la pyramide (si affichageNom = true)\n * @property {string} colorCone Couleur du cône : du type 'blue' ou du type '#f15929'\n * @property {arete3d[]} aretesSommet Ce tableau contient les arêtes liant le sommet de la pyramide aux sommets de la base\n * @property {Array} c2d Contient les commandes à tracer en 2d de cette fonction\n * @author Eric Elter (d'après version précédente de Jean-Claude Lhote)\n * @class\n */\nclass Pyramide3d {\n  constructor (base, sommet, color, centre, affichageAxe = false, colorAxe = 'black', affichageNom = false, estCone = false, colorCone = 'gray') {\n    ObjetMathalea2D.call(this, {})\n\n    base.color = colorToLatexOrHTML(color)\n    this.base = base\n    this.sommet = sommet\n    this.color = color\n    this.centre = centre\n    this.affichageAxe = affichageAxe\n    this.colorAxe = colorAxe\n    this.affichageNom = affichageNom\n    this.estCone = estCone\n    this.colorCone = colorCone\n    this.c2d = []\n    this.nom = ''\n    let s\n\n    // Stockage de toutes les arêtes issues du sommet\n    this.aretesSommet = []\n\n    for (let i = 0; i < this.base.listePoints.length; i++) {\n      s = arete3d(this.base.listePoints[i], this.sommet, this.color, true)\n      // s.c2d.isVisible = false\n      this.aretesSommet.push(s)\n    }\n\n    // Stockage de toutes les arêtes de la base\n    const aretesBase = []\n    for (let i = 0; i < this.base.listePoints.length; i++) {\n      s = arete3d(this.base.listePoints[i], this.base.listePoints[(i + 1) % this.base.listePoints.length], this.color, true)\n      aretesBase.push(s)\n    }\n\n    // Recherche des sommets arrières (donc toutes les arêtes issues de ce point sont cachées)\n    let sommetCache = false\n    let sommetCacheAvant\n    const angleReference = [0, 0]\n    const sommetGeneratriceCone = []\n\n    for (let i = 0; i < this.base.listePoints.length; i++) {\n      sommetCacheAvant = sommetCache\n      sommetCache = false\n      for (let j = 1; j < this.base.listePoints.length - 1; j++) {\n        const poly = polygone([this.sommet.c2d, this.base.listePoints[(i + j) % this.base.listePoints.length].c2d, this.base.listePoints[(i + j + 1) % this.base.listePoints.length].c2d])\n        poly.isVisible = false\n        sommetCache = sommetCache || this.base.listePoints[i].c2d.estDansPolygone(poly)\n      }\n      if (this.estCone && sommetCacheAvant !== sommetCache && i !== 0) {\n        if (sommetCache) sommetGeneratriceCone.push(this.aretesSommet[(this.aretesSommet.length + i - 1) % this.aretesSommet.length])\n        else sommetGeneratriceCone.push(this.aretesSommet[i])\n        if (sommetCache) angleReference[1] = i\n        else angleReference[0] = i\n      }\n      if (sommetCache) {\n        if (sommet.z > this.base.listePoints[0].z) { // Si le sommet est au-dessus de la base\n          this.aretesSommet[i].visible = false\n          this.aretesSommet[i].c2d.pointilles = 2\n          aretesBase[i].c2d.pointilles = 2\n          aretesBase[(this.base.listePoints.length + i - 1) % this.base.listePoints.length].c2d.pointilles = 2\n        }\n      }\n    }\n\n    if (this.estCone && angleReference[1] <= angleReference[0]) {\n      angleReference[1] += this.base.listePoints.length\n    }\n\n    if (this.estCone && sommetGeneratriceCone.length === 1) {\n      sommetGeneratriceCone.push(this.aretesSommet[this.aretesSommet.length - 1])\n      angleReference[1] = this.aretesSommet.length - 1\n    }\n    if (this.estCone) {\n      const premierPlan = [this.sommet.c2d]\n      for (let i = angleReference[0]; i < angleReference[1]; i++) {\n        premierPlan.push(this.base.listePoints[i % this.base.listePoints.length].c2d)\n      // ok\n      }\n      const faceAv = polygone(premierPlan, this.colorCone)\n      faceAv.couleurDeRemplissage = colorToLatexOrHTML(this.colorCone)\n      this.c2d.push(faceAv)\n    }\n\n    if (!this.estCone) {\n      let longueurSegment\n      if (this.sommet.z > this.base.listePoints[0].z) { // Si le sommet est au-dessus de la base\n        // Recherche de l'arête cachée possible issue de deux sommets non cachés.\n        for (let i = 0; i < this.base.listePoints.length; i++) {\n          sommetCache = false\n          longueurSegment = longueur(this.base.listePoints[i].c2d, this.base.listePoints[(i + 1) % this.base.listePoints.length].c2d)\n          s = segment(pointSurSegment(this.base.listePoints[i].c2d, this.base.listePoints[(i + 1) % this.base.listePoints.length].c2d, longueurSegment / 20), pointSurSegment(this.base.listePoints[i].c2d, this.base.listePoints[(i + 1) % this.base.listePoints.length].c2d, 19 * longueurSegment / 20))\n          s.isVisible = false\n          for (let j = 0; j < this.aretesSommet.length; j++) {\n            sommetCache = sommetCache || s.estSecant(this.aretesSommet[j].c2d)\n          }\n          if (sommetCache) aretesBase[i].c2d.pointilles = 2\n        }\n      } else { // Si le sommet est en-dessous de la base\n        for (let i = 0; i < this.base.listePoints.length; i++) {\n          longueurSegment = longueur(this.base.listePoints[i].c2d, this.sommet.c2d)\n          s = segment(pointSurSegment(this.base.listePoints[i].c2d, this.sommet.c2d, longueurSegment / 20), this.sommet.c2d)\n          s.isVisible = false\n          let j = 0\n          while (j < aretesBase.length && !s.estSecant(aretesBase[j].c2d)) {\n            j++\n          }\n          if (j < aretesBase.length) this.aretesSommet[i].c2d.pointilles = 2\n        }\n      }\n      for (let i = 0; i < this.base.listePoints.length; i++) {\n        this.c2d.push(this.aretesSommet[i].c2d)\n      }\n    } else {\n      for (let i = 0; i < sommetGeneratriceCone.length; i++) {\n        this.c2d.push(sommetGeneratriceCone[i].c2d)\n      }\n    }\n\n    for (let i = 0; i < this.base.listePoints.length; i++) {\n      this.c2d.push(aretesBase[i].c2d)\n    }\n\n    if (this.centre !== undefined && this.centre.constructor === Point3d) {\n      this.c2d.push(tracePoint(this.centre.c2d, this.colorAxe))\n      if (this.centre.label === '') this.centre.label = choisitLettresDifferentes(1, 'OQWX')[0]\n      this.c2d.push(labelPoint(this.centre.c2d))\n\n      if (this.affichageAxe) { // Axe affiché que si centre précisé\n        if (this.sommet.z > 0) {\n          let intersectionTrouvee = false\n          let ee = 0\n          // Recherche du point d'intersection visuelle entre l'axe et une arête visible de la base\n          while (!intersectionTrouvee && ee < aretesBase.length) {\n            s = aretesBase[ee].c2d\n            if (s.pointilles !== 2) { // L'arête coupée doit être visible\n              const d1 = droite(this.centre.c2d, this.sommet.c2d)\n              d1.isVisible = false\n              intersectionTrouvee = s.estSecant(d1)\n            }\n            ee++\n          }\n          if (intersectionTrouvee) {\n            ee--\n            const d1 = droite(this.base.listePoints[ee].c2d, this.base.listePoints[(ee + 1) % this.base.listePoints.length].c2d)\n            d1.isVisible = false\n            const d2 = droite(this.centre.c2d, this.sommet.c2d)\n            d2.isVisible = false\n            const ptBase = pointIntersectionDD(d1, d2)\n            s = segment(ptBase, this.sommet.c2d, this.colorAxe)\n            s.pointilles = 2\n            this.c2d.push(s)\n            s = segment(ptBase, translation(ptBase, vecteur(this.centre.c2d, ptBase)), this.colorAxe)\n            this.c2d.push(s)\n            s = segment(this.sommet.c2d, translation(this.sommet.c2d, vecteur(ptBase, this.centre.c2d)), this.colorAxe)\n            this.c2d.push(s)\n          }\n        } else {\n          s = segment(this.centre.c2d, this.sommet.c2d, this.colorAxe)\n          s.pointilles = 2\n          this.c2d.push(s)\n          const v = vecteur(this.centre.c2d, this.sommet.c2d)\n          const L = longueur(this.base.listePoints[0].c2d, this.centre.c2d)\n          const h = 2 * norme(v)\n          s = segment(this.sommet.c2d, translation(this.sommet.c2d, vecteur(L * v.x / h, L * v.y / h)), this.colorAxe)\n          this.c2d.push(s)\n          s = segment(this.centre.c2d, translation(this.centre.c2d, vecteur(-L * v.x / h, -L * v.y / h)), this.colorAxe)\n          this.c2d.push(s)\n        }\n      }\n    }\n\n    if (this.affichageNom) {\n      const p = polygone(this.base.listePoints2d)\n      p.isVisible = false\n      if (this.centre.label === '' || this.centre.label === this.sommet.label) this.sommet.label = choisitLettresDifferentes(1, 'OQWX')[0]\n      const nomBase = choisitLettresDifferentes(this.base.listePoints.length, 'OQWX' + this.sommet.label + this.centre.label)\n      renommePolygone(p, nomBase)\n      for (let ee = 0; ee < this.base.listePoints2d.length; ee++) {\n        this.base.listePoints2d[ee].positionLabel = this.sommet.z > 0 ? 'below' : 'above'\n      }\n      this.c2d.push(labelPoint(...p.listePoints))\n      this.c2d.push(labelPoint(this.sommet))\n      this.nom = nomBase.join('') + this.sommet.label\n    }\n  }\n}\n\n/**\n * Crée une pyramide\n * @param {Polygone3d} base Base de la pyramide\n * @param {Point3d} sommet Sommet de la pyramide\n * @param {string} [color = 'black'] Couleur des arêtes de la pyramide : du type 'blue' ou du type '#f15929'\n * @param {Point3d} [centre] Centre de la pyramide... Entraine l'affichage de ce centre\n * @param {boolean} [affichageAxe = false] Permet (ou pas) l'affichage de l'axe de la pyramide. Ne fonctionne que si centre est défini.\n * @param {string} [colorAxe = 'black'] Couleur de l'axe et du centre de la base de la pyramide : du type 'blue' ou du type '#f15929'\n * @param {boolean} [affichageNom = false] Permet (ou pas) l'affichage du nom des sommets de la pyramide.\n * @param {boolean} [estCone = false] Permet (ou pas) de considérer la pyramide comme un cône\n * @param {string} [colorCone = 'gray'] Couleur du cône : du type 'blue' ou du type '#f15929'\n * @author Eric Elter (d'après version précédente de Jean-Claude Lhote)\n * @example pyramide3d(p,A) // Créé une pyramide de base p et de sommet A\n * @example pyramide3d(p,A,'red') // Créé une pyramide de base p et de sommet A et dont les arêtes sont rouges\n * @example pyramide3d(p,A,'red',B) // Créé une pyramide de base p et de sommet A et dont les arêtes sont rouges, le centre affiché est B\n * @example pyramide3d(p,A,'red',B,true,'green') // Créé une pyramide de base p et de sommet A et dont les arêtes sont rouges, le centre affiché est B, l'axe affiché est vert\n * @example pyramide3d(p,A,'red',B,true,'green',true) // Créé une pyramide de base p et de sommet A et dont les arêtes sont rouges, le centre affiché est B, l'axe affiché est vert, les sommets sont nommés\n * @example pyramide3d(c,A,'red',B,true,'green',false,true) // Créé un CONE de cercle c et de sommet A et dont les \"arêtes\" sont rouges, le centre affiché est B, l'axe affiché est vert\n * @example pyramide3d(c,A,'red',B,true,'green',false,true,'blue') // Créé un CONE de cercle c et de sommet A et dont les \"arêtes\" sont rouges, le centre affiché est B, l'axe affiché est vert et le cône est peint en vert\n * @return {Pyramide3d}\n */\nexport function pyramide3d (base, sommet, color = 'black', centre, affichageAxe = false, colorAxe = 'black', affichageNom = false, estCone = false, colorCone = 'gray') {\n  return new Pyramide3d(base, sommet, color, centre, affichageAxe, colorAxe, affichageNom, estCone, colorCone)\n}\n\n/**\n * La pyramide tronquée\n *\n * @author Jean-Claude Lhote\n * Crée une pyramide à partir d'une base Polygone3d d'un sommet et d'un coefficient compris entre 0 et 1\n * un coefficient de 0.5 coupera la pyramide à mi-hauteur (valeur par défaut).\n */\nclass PyramideTronquee3d {\n  constructor (base, sommet, coeff = 0.5, color = 'black') {\n    ObjetMathalea2D.call(this, {})\n\n    this.color = color\n    base.color = colorToLatexOrHTML(color)\n    this.base = base\n    this.coeff = coeff\n    this.aretes = []\n    this.sommet = sommet\n    this.c2d = []\n    const sommetsBase2 = []\n    for (let i = 0, pointSection; i < this.base.listePoints.length; i++) {\n      pointSection = homothetie3d(sommet, base.listePoints[i], coeff)\n      pointSection.visible = true\n      sommetsBase2.push(pointSection)\n    }\n    this.base2 = polygone3d(...sommetsBase2)\n    this.c2d.push(...this.base.c2d)\n    for (let i = 0; i < base.listePoints.length; i++) {\n      this.aretes.push(arete3d(base.listePoints[i], this.base2.listePoints[i], this.color, base.listePoints[i].visible))\n      this.c2d.push(this.aretes[i].c2d)\n    }\n    this.c2d.push(...this.base2.c2d)\n  }\n}\n\nexport function pyramideTronquee3d (base, sommet, coeff = 0.5, color = 'black') {\n  return new PyramideTronquee3d(base, sommet, coeff, color)\n}\n\n/**\n * Classe du cube : construit le cube d'arète c dont le sommet en bas à gauche a les coordonnées x,y,z\n * (la face avant est dans le plan xz, la face de droite est toujours visible, la face de haut ou du bas est visible selon context.anglePerspective)\n * @param {number} x Abscisse du sommet du cube en bas à gauche\n * @param {number} y Ordonnée du sommet du cube en bas à gauche\n * @param {number} x Altitude du sommet du cube en bas à gauche\n * @param {number} c Longueur de l'arête du cube\n * @param {string} [color = 'black'] Couleur des arêtes du cube : du type 'blue' ou du type '#f15929'\n * @param {string} [colorAV = 'lightgray'] Couleur de la face avant du cube : du type 'blue' ou du type '#f15929'\n * @param {string} [colorHautouBas = 'white'] Couleur de la face visible du dessus (ou du dessous) du cube : du type 'blue' ou du type '#f15929'\n * @param {string} [colorDr = 'darkgray'] Couleur de la face de droite (toujours visible) du cube : du type 'blue' ou du type '#f15929'\n * @param {boolean} [aretesCachee = true] Si true, les arêtes cachées sont visibles.\n * @param {boolean} [affichageNom = false] Si true, le nom des sommets est affiché\n * @param {string[]} [nom = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']] Nom du cube\n * @property {boolean} affichageNom Si true, le nom des sommets est affiché\n * @property {Point3d[]} sommets Tableau contenant les sommets du cube\n * @property {Array} c2d Contient les commandes à tracer en 2d de cette fonction\n * @author Jean-Claude Lhote (Amendée par Eric Elter)\n * @class\n */\nclass Cube3d {\n  constructor (x, y, z, c, color = 'black', colorAV = 'lightgray', colorHautouBas = 'white', colorDr = 'darkgray', aretesCachee = true, affichageNom = false, nom = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']) {\n    ObjetMathalea2D.call(this, {})\n    this.affichageNom = affichageNom\n    const A = point3d(x, y, z)\n    A.c2d.nom = nom[0]\n    const vx = vecteur3d(c, 0, 0)\n    const vy = vecteur3d(0, c, 0)\n    const vz = vecteur3d(0, 0, c)\n    const B = translation3d(A, vx)\n    B.c2d.nom = nom[1]\n    const C = translation3d(B, vz)\n    C.c2d.nom = nom[2]\n    const D = translation3d(A, vz)\n    D.c2d.nom = nom[3]\n    let pointsFace = [A.c2d, B.c2d, C.c2d, D.c2d]\n    const faceAV = this.affichageNom ? polygoneAvecNom(...pointsFace) : polygone(pointsFace, color)\n    if (this.affichageNom) faceAV[0].color = colorToLatexOrHTML(color)\n    const E = translation3d(A, vy)\n    E.c2d.nom = nom[4]\n    const F = translation3d(E, vx)\n    F.c2d.nom = nom[5]\n    const G = translation3d(F, vz)\n    G.c2d.nom = nom[6]\n    const H = translation3d(D, vy)\n    H.c2d.nom = nom[7]\n    pointsFace = [E.c2d, F.c2d, G.c2d, H.c2d]\n    const faceArr = this.affichageNom ? polygoneAvecNom(...pointsFace) : vide2d()\n\n    const faceDr = polygone([B.c2d, F.c2d, G.c2d, C.c2d], color)\n    let faceVisibleHautOuBas, areteCachee3, areteCachee2, areteCachee1\n    if (context.anglePerspective > 0) {\n      faceVisibleHautOuBas = polygone([D.c2d, C.c2d, G.c2d, H.c2d], color) // Cette face est en fonction de context.anglePerspective\n      areteCachee1 = segment(E.c2d, H.c2d, color)\n      areteCachee2 = segment(E.c2d, F.c2d, color)\n      areteCachee3 = segment(E.c2d, A.c2d, color)\n    } else {\n      faceVisibleHautOuBas = polygone([A.c2d, B.c2d, F.c2d, E.c2d], color)\n      areteCachee1 = segment(E.c2d, H.c2d, color)\n      areteCachee2 = segment(D.c2d, H.c2d, color)\n      areteCachee3 = segment(G.c2d, H.c2d, color)\n    }\n    areteCachee1.pointilles = 2\n    areteCachee2.pointilles = 2\n    areteCachee3.pointilles = 2\n\n    this.sommets = [A, B, C, D, E, F, G, H]\n    // Les 8 sommets sont indispensables pour pouvoir les utiliser ensuite.\n\n    if (aretesCachee) {\n      faceAV.couleurDeRemplissage = colorToLatexOrHTML(colorAV)\n      faceVisibleHautOuBas.couleurDeRemplissage = colorToLatexOrHTML(colorHautouBas)\n      faceDr.couleurDeRemplissage = colorToLatexOrHTML(colorDr)\n      this.c2d = [faceAV.length === 2 ? faceAV[0] : faceAV, faceAV.length === 2 ? faceAV[1] : vide2d(), faceDr, faceVisibleHautOuBas]\n    } else {\n      this.c2d = [faceAV.length === 2 ? faceAV[0] : faceAV, faceAV.length === 2 ? faceAV[1] : vide2d(), faceDr, faceVisibleHautOuBas, faceArr.length === 2 ? faceArr[1] : vide2d(), areteCachee1, areteCachee2, areteCachee3]\n    }\n  }\n}\n\n/**\n * Crée un cube d'arète c dont le sommet en bas à gauche a les coordonnées x,y,z\n * (la face avant est dans le plan xz, la face de droite est toujours visible, la face de haut ou du bas est visible selon context.anglePerspective)\n * @param {number} x Abscisse du sommet du cube en bas à gauche\n * @param {number} y Ordonnée du sommet du cube en bas à gauche\n * @param {number} x Altitude du sommet du cube en bas à gauche\n * @param {number} c Longueur de l'arête du cube\n * @param {string} [color = 'black'] Couleur des arêtes du cube : du type 'blue' ou du type '#f15929'\n * @param {string} [colorAV = 'lightgray'] Couleur de la face avant du cube : du type 'blue' ou du type '#f15929'\n * @param {string} [colorHautouBas = 'white'] Couleur de la face visible du dessus (ou du dessous) du cube : du type 'blue' ou du type '#f15929'\n * @param {string} [colorDr = 'darkgray'] Couleur de la face de droite (toujours visible) du cube : du type 'blue' ou du type '#f15929'\n * @param {boolean} [aretesCachee = true] Si true, les arêtes cachées sont visibles.\n * @param {boolean} [affichageNom = false] Si true, le nom des sommets est affiché\n * @param {string[]} [nom = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']] Nom du cube\n * @example cube(0,0,0,10)\n * // Construit un cube noir d'arête 10 dont le sommet en bas à gauche est l'origine du repère et dont les faces visibles sont colorées aux couleurs par défaut.\n * // Les arêtes cachées sont visibles et le cube ne porte pas de nom.\n * @example cube(0,0,0,10,'red','','','',false)\n * // Construit un cube rouge d'arête 10 dont le sommet en bas à gauche est l'origine du repère et dont aucune face n'est coloriée.\n * // Les arêtes cachées sont invisibles et le cube ne porte pas de nom.\n * @example cube(0,0,0,10,'#f15929','','','',trie,true)\n * // Construit un cube orange d'arête 10 dont le sommet en bas à gauche est l'origine du repère et dont aucune face n'est coloriée.\n * // Les arêtes cachées sont visibles et le cube s'appelle ABCDEFGH.\n * @author Jean-Claude Lhote (Amendée par Eric Elter)\n * @return {Cube3d}\n */\nexport function cube3d (x, y, z, c, color = 'black', colorAV = 'lightgray', colorHautouBas = 'white', colorDr = 'darkgray', aretesCachee = true, affichageNom = false, nom = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']) {\n  return new Cube3d(x, y, z, c, color, colorAV, colorHautouBas, colorDr, aretesCachee, affichageNom, nom)\n}\n\n/**\n * @author Jean-Claude Lhote\n * Créer une barre de l cubes de c de côté à partir du point (x,y,z)\n * La barre est positionnée suivant l'axe x\n */\nclass Barre3d {\n  constructor (x, y, z, c, l, color = 'black') {\n    ObjetMathalea2D.call(this, {})\n    let B, C, D, E, F, G, H, faceAv, faceTop\n    this.c2d = []\n    const vx = vecteur3d(c, 0, 0)\n    const vy = vecteur3d(0, c, 0)\n    const vz = vecteur3d(0, 0, c)\n    let A = point3d(x, y, z)\n\n    for (let i = 0; i < l; i++) {\n      B = translation3d(A, vx)\n      C = translation3d(B, vz)\n      D = translation3d(A, vz)\n      E = translation3d(A, vy)\n      F = translation3d(E, vx)\n      G = translation3d(F, vz)\n      H = translation3d(D, vy)\n      faceAv = polygone([A.c2d, B.c2d, C.c2d, D.c2d], color)\n      faceTop = polygone([D.c2d, C.c2d, G.c2d, H.c2d], color)\n      faceAv.couleurDeRemplissage = colorToLatexOrHTML('lightgray')\n      faceTop.couleurDeRemplissage = colorToLatexOrHTML('white')\n      this.c2d.push(faceAv, faceTop)\n      A = translation3d(A, vx)\n    }\n    const faceD = polygone([B.c2d, F.c2d, G.c2d, C.c2d], color)\n    faceD.couleurDeRemplissage = colorToLatexOrHTML('darkgray')\n    this.c2d.push(faceD)\n  }\n}\n\nexport function barre3d (x, y, z, c, l, color = 'black') {\n  return new Barre3d(x, y, z, c, l, color)\n}\n\n/**\n * @author Jean-Claude Lhote\n * Crée une plaque de cubes de côtés c de dimensions l suivant x et p suivant y\n */\nclass Plaque3d {\n  constructor (x, y, z, c, l, p, color = 'black') {\n    ObjetMathalea2D.call(this, {})\n    let A, B, C, D, F, G, H, faceAv, faceTop, faceD\n    this.c2d = []\n    const vx = vecteur3d(c, 0, 0)\n    const vy = vecteur3d(0, c, 0)\n    const vz = vecteur3d(0, 0, c)\n\n    for (let i = 0; i < l; i++) {\n      for (let j = 0; j < p; j++) {\n        A = point3d(x + i * c, y + j * c, z)\n        B = translation3d(A, vx)\n        C = translation3d(B, vz)\n        D = translation3d(A, vz)\n        F = translation3d(B, vy)\n        G = translation3d(F, vz)\n        H = translation3d(D, vy)\n        if (j === 0) {\n          faceAv = polygone([A.c2d, B.c2d, C.c2d, D.c2d], color)\n          faceAv.couleurDeRemplissage = colorToLatexOrHTML('lightgray')\n          this.c2d.push(faceAv)\n        }\n        if (i === l - 1) {\n          faceD = polygone([B.c2d, F.c2d, G.c2d, C.c2d], color)\n          faceD.couleurDeRemplissage = colorToLatexOrHTML('darkgray')\n          this.c2d.push(faceD)\n        }\n        faceTop = polygone([D.c2d, C.c2d, G.c2d, H.c2d], color)\n        faceTop.couleurDeRemplissage = colorToLatexOrHTML('white')\n        this.c2d.push(faceTop)\n      }\n    }\n  }\n}\n\nexport function plaque3d (x, y, z, c, l, p, color = 'black') {\n  return new Plaque3d(x, y, z, c, l, p, color)\n}\n\nclass PaveLPH3d {\n  constructor (x, y, z, c, l, p, h, color = 'black') {\n    ObjetMathalea2D.call(this, {})\n    let A, B, C, D, F, G, H, faceAv, faceTop, faceD\n    this.c2d = []\n    const vx = vecteur3d(c, 0, 0)\n    const vy = vecteur3d(0, c, 0)\n    const vz = vecteur3d(0, 0, c)\n\n    for (let i = 0; i < l; i++) {\n      for (let j = 0; j < p; j++) {\n        for (let k = 0; k < h; k++) {\n          A = point3d(x + i * c, y + j * c, z + k * c)\n          B = translation3d(A, vx)\n          C = translation3d(B, vz)\n          D = translation3d(A, vz)\n          F = translation3d(B, vy)\n          G = translation3d(F, vz)\n          H = translation3d(D, vy)\n          if (j === 0) {\n            faceAv = polygone([A.c2d, B.c2d, C.c2d, D.c2d], color)\n            faceAv.couleurDeRemplissage = colorToLatexOrHTML('lightgray')\n            this.c2d.push(faceAv)\n          }\n          if (i === l - 1) {\n            faceD = polygone([B.c2d, F.c2d, G.c2d, C.c2d], color)\n            faceD.couleurDeRemplissage = colorToLatexOrHTML('darkgray')\n            this.c2d.push(faceD)\n          }\n          if (k === h - 1) {\n            faceTop = polygone([D.c2d, C.c2d, G.c2d, H.c2d], color)\n            faceTop.couleurDeRemplissage = colorToLatexOrHTML('white')\n            this.c2d.push(faceTop)\n          }\n        }\n      }\n    }\n  }\n}\n\n/**\n *\n * @param {number} x coordonnées du sommet en bas à gauche\n * @param {number} y\n * @param {number} z\n * @param {number} c longueur de l'unité\n * @param {number} p profondeur\n * @param {number} l longueur\n * @param {number} h hauteur\n * @param {*} color couleur\n * @returns {object}\n */\nexport function paveLPH3d (x, y, z, c, l, p, h, color = 'black') {\n  return new PaveLPH3d(x, y, z, c, l, p, h, color)\n}\n\n/**\n * @author Erwan Duplessis et Jean-Claude Lhote\n * Attention !\n * Cette Classe définit un objet cube dans une représentation en perspective axonométrique paramétrée par alpha et beta\n * et non pas context.anglePerspective (contrairement à l'objet cube3d ci-dessus ou l'objet pave3d ci-dessous)\n * Il ne s'agit pas à proprement parler d'un objet 3d, c'est un objet 2d avec sa méthode svg() et sa méthode tikz()\n * Utilisée par exemple dans 6G43\n */\nclass Cube {\n  constructor (x, y, z, alpha, beta, colorD, colorT, colorG) {\n    ObjetMathalea2D.call(this, {})\n    this.x = x\n    this.y = y\n    this.z = z\n    this.alpha = alpha\n    this.beta = beta\n    this.colorD = colorToLatexOrHTML(colorD)\n    this.colorG = colorToLatexOrHTML(colorG)\n    this.colorT = colorToLatexOrHTML(colorT)\n\n    this.lstPoints = []\n    this.lstPolygone = []\n\n    function proj (x, y, z, alpha, beta) {\n      const cosa = Math.cos(alpha * Math.PI / 180)\n      const sina = Math.sin(alpha * Math.PI / 180)\n      const cosb = Math.cos(beta * Math.PI / 180)\n      const sinb = Math.sin(beta * Math.PI / 180)\n      return point(cosa * x - sina * y, -sina * sinb * x - cosa * sinb * y + cosb * z)\n    }\n\n    this.lstPoints.push(proj(this.x, this.y, this.z, this.alpha, this.beta)) // point 0 en bas\n    this.lstPoints.push(proj(this.x + 1, this.y, this.z, this.alpha, this.beta)) // point 1\n    this.lstPoints.push(proj(this.x + 1, this.y, this.z + 1, this.alpha, this.beta)) // point 2\n    this.lstPoints.push(proj(this.x, this.y, this.z + 1, this.alpha, this.beta)) // point 3\n    this.lstPoints.push(proj(this.x + 1, this.y + 1, this.z + 1, this.alpha, this.beta)) // point 4\n    this.lstPoints.push(proj(this.x, this.y + 1, this.z + 1, this.alpha, this.beta)) // point 5\n    this.lstPoints.push(proj(this.x, this.y + 1, this.z, this.alpha, this.beta)) // point 6\n    let p\n    p = polygone([this.lstPoints[0], this.lstPoints[1], this.lstPoints[2], this.lstPoints[3]], 'black')\n    p.opaciteDeRemplissage = 1\n    p.couleurDeRemplissage = this.colorD\n    this.lstPolygone.push(p)\n    p = polygone([this.lstPoints[2], this.lstPoints[4], this.lstPoints[5], this.lstPoints[3]], 'black')\n    p.couleurDeRemplissage = this.colorG\n    p.opaciteDeRemplissage = 1\n    this.lstPolygone.push(p)\n    p = polygone([this.lstPoints[3], this.lstPoints[5], this.lstPoints[6], this.lstPoints[0]], 'black')\n    p.couleurDeRemplissage = this.colorT\n    p.opaciteDeRemplissage = 1\n    this.lstPolygone.push(p)\n    this.c2d = this.lstPolygone\n  }\n}\n\nexport function cube (x = 0, y = 0, z = 0, alpha = 45, beta = -35, {\n  colorD = 'green',\n  colorT = 'white',\n  colorG = 'gray'\n} = {}) {\n  return new Cube(x, y, z, alpha, beta, colorD, colorG, colorT)\n}\n\n/**\n * Classe du pavé : construit le pavé ABCDEFGH dont les arêtes [AB],[AD] et [AE] délimitent 3 faces adjacentes.\n * La gestion des arêtes cachées est prise en compte et n'est pas forcément E.\n * En travaillant sur le signe de context.anglePerspective et sur celui de la hauteur (B.z), on peut avoir une vision de haut, de bas, de gauche, de droite comme dans l'exercice....\n * @param {Point3d} A Sommet du pavé droit\n * @param {Point3d} B Sommet du pavé droit\n * @param {Point3d} D Sommet du pavé droit\n * @param {Point3d} E Sommet du pavé droit\n * @param {boolean} [affichageNom = false] Permet (ou pas) l'affichage du nom des sommets du pavé droit.\n * @param {string} [nom = 'ABCDEFGH'] Nom du pavé droit\n * @property {Point3d[]} sommets Tableau contenant les sommets du pavé droit\n * @property {string} color Couleur des arêtes du pavé droit : du type 'blue' ou du type '#f15929'\n * @property {Polygone3d} base Base ABFE du pavé droit\n * @property {Vecteur3d} hauteur Vecteur AD\n * @property {Arete3d} aretes Tableau contenant les arêtes du pavé droit\n * @property {Array} c2d Contient les commandes à tracer en 2d de cette fonction\n * @author Jean-Claude Lhote (optimisé par Eric Elter)\n * @class\n */\nclass Pave3d {\n  constructor (A, B, D, E, color = 'black', affichageNom = false, nom = 'ABCDEFGH') {\n    ObjetMathalea2D.call(this, {})\n    this.affichageNom = affichageNom\n    const v1 = vecteur3d(A, B)\n    const v2 = vecteur3d(A, E)\n    const C = translation3d(D, v1)\n    const H = translation3d(D, v2)\n    const G = translation3d(C, v2)\n    const F = translation3d(B, v2)\n\n    // Determination du point caché\n    function distanceMoyenne4points (pt) {\n      const dist1 = longueur(pt.c2d, A.c2d, 5)\n      const dist2 = longueur(pt.c2d, B.c2d, 5)\n      const dist3 = longueur(pt.c2d, C.c2d, 5)\n      const dist4 = longueur(pt.c2d, D.c2d, 5)\n      return arrondi((dist1 + dist2 + dist3 + dist4) / 4, 5)\n    }\n\n    E.visible = !E.c2d.estDansQuadrilatere(A.c2d, B.c2d, C.c2d, D.c2d)\n    F.visible = !F.c2d.estDansQuadrilatere(A.c2d, B.c2d, C.c2d, D.c2d)\n    G.visible = !G.c2d.estDansQuadrilatere(A.c2d, B.c2d, C.c2d, D.c2d)\n    H.visible = !H.c2d.estDansQuadrilatere(A.c2d, B.c2d, C.c2d, D.c2d)\n    if (E.visible && F.visible && G.visible && H.visible) {\n      const minimum = Math.min(distanceMoyenne4points(E), distanceMoyenne4points(F), distanceMoyenne4points(G), distanceMoyenne4points(H))\n      E.visible = minimum !== distanceMoyenne4points(E)\n      F.visible = minimum !== distanceMoyenne4points(F)\n      G.visible = minimum !== distanceMoyenne4points(G)\n      H.visible = minimum !== distanceMoyenne4points(H)\n    }\n    // Fin de determination du point caché\n\n    this.sommets = [A, B, C, D, E, F, G, H]\n    this.color = color\n    this.base = polygone3d([A, B, F, E])\n    this.hauteur = vecteur3d(A, D)\n    this.c2d = []\n    this.aretes = [arete3d(A, B, color), arete3d(A, D, color), arete3d(A, E, color), arete3d(C, B, color), arete3d(F, B, color), arete3d(C, D, color), arete3d(C, G, color), arete3d(F, G, color), arete3d(F, E, color), arete3d(H, G, color), arete3d(H, E, color), arete3d(H, D, color)]\n    for (const arete of this.aretes) {\n      this.c2d.push(arete.c2d)\n    }\n    if (this.affichageNom) {\n      let pointsFace = [A.c2d, B.c2d, C.c2d, D.c2d]\n      A.c2d.nom = nom[0]\n      B.c2d.nom = nom[1]\n      C.c2d.nom = nom[2]\n      D.c2d.nom = nom[3]\n      E.c2d.nom = nom[4]\n      F.c2d.nom = nom[5]\n      G.c2d.nom = nom[6]\n      H.c2d.nom = nom[7]\n\n      const faceAV = polygoneAvecNom(...pointsFace, context.isHtml ? 0.5 : 1.5)\n      pointsFace = [E.c2d, F.c2d, G.c2d, H.c2d]\n      const faceArr = polygoneAvecNom(...pointsFace, context.isHtml ? 0.5 : 1.5)\n      this.c2d.push(faceAV[1], faceArr[1])\n    }\n  }\n}\n\n/**\n * Construit le pavé ABCDEFGH dont les arêtes [AB],[AD] et [AE] délimitent 3 faces adjacentes.\n * La gestion des arêtes cachées est prise en compte et n'est pas forcément E.\n * En travaillant sur le signe de context.anglePerspective et sur celui de la hauteur (B.z), on peut avoir une vision de haut, de bas, de gauche, de droite comme dans l'exercice....\n * @param {Point3d} A Sommet du pavé droit\n * @param {Point3d} B Sommet du pavé droit\n * @param {Point3d} D Sommet du pavé droit\n * @param {Point3d} E Sommet du pavé droit\n * @param {boolean} [affichageNom = false] Permet (ou pas) l'affichage du nom des sommets du pavé droit.\n * @param {string} [nom = 'ABCDEFGH'] Nom du pavé droit\n * @example pave(A,B,D,E) // Créé un pavé noir sans nom\n * @example pave(A,B,D,E,'blue') // Créé un pavé bleu sans nom\n * @example pave(A,B,D,E,'red',true,'MNOPQRST') // Créé un pavé rouge dont les sommets sont nommés M, N, O, P, Q, R, S et T\n * @author Jean-Claude Lhote (optimisé par Eric Elter)\n * @return {Pave3d}\n */\nexport function pave3d (A, B, D, E, color = 'black', affichageNom = false, nom = 'ABCDEFGH') {\n  return new Pave3d(A, B, D, E, color, affichageNom, nom)\n}\n\n/*\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%%%%%%%%%%%%%% TRANSFORMATIONS%%%%%%%%%%%\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n*/\n\n/**\n * LA ROTATION VECTORIELLE\n *\n * @author Jean-Claude Lhote\n * Cette rotation se distingue de la rotation d'axe (d) par le fait qu'on tourne autour d'une droite vectorielle\n * Elle sert à faire tourner des vecteurs essentiellement.\n * Si on l'utilise sur un point, alors il tournera autour d'une droite passant par l'origine.\n *\n * @param {*} point3D pour l'instant, cette fonction ne fait tourner qu'un point3d ou un vecteur3d\n * @param {*} vecteur3D vecteur directeur de l'axe de rotation (l'axe passe par l'origine, pour tourner autour d'une droite particulière on utilise rotation3d())\n * @param {*} angle Angle de rotation\n */\nexport function rotationV3d (point3D, vecteur3D, angle) { // point = ce qu'on fait tourner (Point3d) ; vecteur = directeur de l'axe de rotation [x,y,z] et angle de rotation en degrés\n  let V, p2\n  const norme = math.norm(vecteur3D.matrice)\n  const unitaire = math.multiply(vecteur3D.matrice, 1 / norme)\n  const u = unitaire._data[0]\n  const v = unitaire._data[1]\n  const w = unitaire._data[2]\n  const c = Math.cos(angle * Math.PI / 180)\n  const s = Math.sin(angle * Math.PI / 180)\n  const k = 1 - c\n  const matrice = math.matrix([[u * u * k + c, u * v * k - w * s, u * w * k + v * s], [u * v * k + w * s, v * v * k + c, v * w * k - u * s], [u * w * k - v * s, v * w * k + u * s, w * w * k + c]])\n  if (point3D.constructor === Point3d) {\n    V = math.matrix([point3D.x, point3D.y, point3D.z])\n    p2 = math.multiply(matrice, V)\n    return point3d(p2._data[0], p2._data[1], p2._data[2])\n  } else if (point3D.constructor === Vecteur3d) {\n    V = point3D\n    p2 = math.multiply(matrice, V.matrice)\n    return vecteur3d(p2._data[0], p2._data[1], p2._data[2])\n  }\n}\n\n/**\n * LA ROTATION D'AXE UNE DROITE\n *\n * @author Jean-Claude Lhote\n *\n * @param {Point3d} point3D Pour l'instant on ne fait tourner qu'un point3d\n * Remarque : ça n'a aucun sens de faire tourner un vecteur autour d'une droite particulière, on utilise la rotation vectorielle pour ça.\n * @param {Droite3d} droite3D Axe de rotation\n * @param {Number} angle Angle de rotation\n * @param {string} color couleur du polygone créé. si non précisé la couleur sera celle du polygone argument\n */\nexport function rotation3d (point3D, droite3D, angle, color) {\n  const directeur = droite3D.directeur\n  const origine = droite3D.origine\n  const p = []\n  if (point3D.constructor === Point3d) {\n    const V = vecteur3d(origine, point3d(0, 0, 0))\n    const W = vecteur3d(point3d(0, 0, 0), origine)\n    const M = translation3d(point3D, V)\n    const N = rotationV3d(M, directeur, angle)\n    return translation3d(N, W)\n  } else if (point3D.constructor === Vecteur3d) {\n    return rotationV3d(point3D, directeur, angle)\n  } else if (point3D.constructor === Polygone3d) {\n    for (let i = 0; i < point3D.listePoints.length; i++) {\n      p.push(rotation3d(point3D.listePoints[i], droite3D, angle))\n    }\n    if (typeof (color) !== 'undefined') {\n      return polygone3d(p, color)\n    } else {\n      return polygone3d(p, point3D.color)\n    }\n  }\n}\n\n/**\n * @author Jean-Claude Lhote\n * Crée une flèche en arc de cercle pour montrer un sens de rotation autour d'un axe 3d\n * cette flèche est dessinée dans le plan orthogonal à l'axe qui passe par l'origine de l'axe\n * le rayon est ici un vecteur 3d qui permet de fixer le point de départ de la flèche par translation de l'origine de l'axe\n * l'angle définit l'arc formé par la flèche\n * son sens est définit par le vecteur directeur de l'axe (changer le signe de chaque composante de ce vecteur pour changer le sens de rotation)\n */\nfunction SensDeRotation3d (axe, rayon, angle, epaisseur, color) {\n  ObjetMathalea2D.call(this, {})\n  this.epaisseur = epaisseur\n  this.color = color\n  this.c2d = []\n  let M\n  let N\n  let s\n  M = translation3d(axe.origine, rayon)\n  for (let i = 0; i < angle; i += 5) {\n    N = rotation3d(M, axe, 5)\n    s = segment(M.c2d, N.c2d, this.color)\n    s.epaisseur = this.epaisseur\n    this.c2d.push(s)\n    M = N\n  }\n  N = rotation3d(M, axe, 5)\n  s = segment(M.c2d, N.c2d, this.color)\n  s.epaisseur = this.epaisseur\n  this.c2d.push(s)\n  const d = droite3d(N, axe.directeur)\n  const A = rotation3d(M, d, 30)\n  const B = rotation3d(M, d, -30)\n  s = segment(N.c2d, A.c2d, this.color)\n  s.epaisseur = this.epaisseur\n  this.c2d.push(s)\n  s = segment(N.c2d, B.c2d, this.color)\n  s.epaisseur = this.epaisseur\n  this.c2d.push(s)\n}\n\nexport function sensDeRotation3d (axe, rayon, angle, epaisseur, color) {\n  return new SensDeRotation3d(axe, rayon, angle, epaisseur, color)\n}\n\n/**\n * LA TRANSLATION\n *\n * @author Jean-Claude Lhote\n * @param {Point3d} point3D Pour l'instant on ne translate qu'un point3d ou un polygone3d\n * @param {Vecteur3d} vecteur3D\n */\nexport function translation3d (point3D, vecteur3D) {\n  if (point3D.constructor === Point3d) {\n    const x = point3D.x + vecteur3D.x\n    const y = point3D.y + vecteur3D.y\n    const z = point3D.z + vecteur3D.z\n    return point3d(x, y, z)\n  } else if (point3D.constructor === Polygone3d) {\n    const p = []\n    for (let i = 0; i < point3D.listePoints.length; i++) {\n      p.push(translation3d(point3D.listePoints[i], vecteur3D))\n    }\n    return polygone3d(p, point3D.color)\n  }\n}\n\n/**\n * L'homothetie\n * @author Jean-Claude Lhote\n * La même chose qu'ne 2d, mais en 3d...\n * Pour les points3d les polygones ou les vecteurs (multiplication scalaire par rapport)\n */\nexport function homothetie3d (point3D, centre, rapport, color) {\n  let V\n  const p = []\n  if (point3D.constructor === Point3d) {\n    V = vecteur3d(centre, point3D)\n    V.x *= rapport\n    V.y *= rapport\n    V.z *= rapport\n    return translation3d(centre, V)\n  } else if (point3D.constructor === Vecteur3d) {\n    V = vecteur3d(point3D.x, point3D.y, point3D.z)\n    V.x *= rapport\n    V.y *= rapport\n    V.z *= rapport\n    return V\n  } else if (point3D.constructor === Polygone3d) {\n    for (let i = 0; i < point3D.listePoints.length; i++) {\n      p.push(homothetie3d(point3D.listePoints[i], centre, rapport, color))\n    }\n    if (typeof (color) !== 'undefined') {\n      return polygone3d(p, color)\n    } else {\n      return polygone3d(p, point3D.color)\n    }\n  }\n}\n\nexport class CodageAngleDroit3D extends ObjetMathalea2D {\n  constructor (A, B, C, color = 'black', taille = 1) {\n    super()\n    const BA = vecteur3d(B, A)\n    const BC = vecteur3d(B, C)\n    const k1 = BA.norme\n    const k2 = BC.norme\n    const M1 = homothetie3d(A, B, taille * 0.5 / k1)\n    const M3 = homothetie3d(C, B, taille * 0.5 / k2)\n    const BM1 = vecteur3d(B, M1)\n    const BM3 = vecteur3d(B, M3)\n    const x = B.x + BM1.x + BM3.x\n    const y = B.y + BM1.y + BM3.y\n    const z = B.z + BM1.z + BM3.z\n    const M2 = point3d(x, y, z)\n    const M1M2 = arete3d(M1, M2, color)\n    const M2M3 = arete3d(M2, M3, color)\n    const bordures = fixeBordures([M1M2.c2d, M2M3.c2d])\n    this.bordures = [bordures.xmin, bordures.ymin, bordures.xmax, bordures.ymax]\n    this.svg = function (coeff) {\n      return M1M2.c2d.svg(coeff) + M2M3.c2d.svg(coeff)\n    }\n    this.tikz = function () {\n      return M1M2.c2d.tikz() + M2M3.c2d.tikz()\n    }\n  }\n}\n"],"names":["math","matrix","multiply","norm","cross","dot","numId","ObjetMathalea2D","colorToLatexOrHTML","context","Point3d","x","y","z","visible","label","positionLabel","alpha","rapport","MT","V","W","point","point3d","Vecteur3d","args","vecteur","A","B","translation3d","vecteur3d","Arete3d","point1","point2","color","segment","arete3d","p1","p2","Droite3d","point3D","vecteur3D","M","droite","droite3d","demicercle3d","centre","normal","rayon","sens","estCache","angledepart","signe","listepoints","d","rotation3d","i","demiCercle","polyline","arc3d","cote","angledefin","nbr","arc","cercle3d","pointilles","listepoints3d","C","polygone","Polygone3d","segments3d","segments","polygone3d","Sphere3d","colorEquateur","colorEnveloppe","nbParalleles","colorParalleles","nbMeridiens","colorMeridiens","affichageAxe","colorAxe","inclinaison","droiteRot","poleNord","choisitLettresDifferentes","poleSud","nbParallelesDeConstruction","divisionParalleles","unDesParalleles","centreParallele","rayonDuParallele","paralleles","enveloppeSphere1","enveloppeSphere2","premierParallele","indicePremier","indiceDernier","k","poly","j","ee","s","s1","d1","d2","jj","pt","pointIntersectionDD","t","tracePoint","assombrirOuEclaircir","polyLineVisible","polyLineCachee","securite","longueur","dernierPoint","premierPoint","ligneCachee","ligneVisible","divisionMeridiens","polyLineCachee1","polyLineVisible1","polyLineCachee2","polyLineVisible2","ligneCachee1","ligneVisible1","ligneCachee2","ligneVisible2","enveloppeSphere","ii","p","l","pointSurSegment","sphere3d","Cone3d","sommet","colorCone","pt1","ptsBase","nbSommets","pyramide3d","cone3d","Cylindre3d","centrebase1","centrebase2","rayon1","rayon2","affichageGeneratrices","affichageCentreBases","cylindreColore","colorCylindre","prodvec","prodscal","cote1","cote2","centre1PlusBasQueCentre2","angleDepart","distanceMax","ptReference","secondPt","sensRecherche","distancePointDroite","c1","c3","c2","c4","polygon","faceColoree","baseColoree","distanceMin","v","translation","norme","cylindre3d","Prisme3d","base","affichageNom","toutesLesAretesSontVisibles","areteVisibleOuPas","areteLiaison","nomBase1","renommePolygone","labelPoint","nomBase2","prisme3d","Pyramide3d","estCone","aretesBase","sommetCache","sommetCacheAvant","angleReference","sommetGeneratriceCone","premierPlan","faceAv","longueurSegment","intersectionTrouvee","ptBase","L","h","nomBase","PyramideTronquee3d","coeff","sommetsBase2","pointSection","homothetie3d","pyramideTronquee3d","Cube3d","colorAV","colorHautouBas","colorDr","aretesCachee","nom","vx","vy","vz","D","pointsFace","faceAV","polygoneAvecNom","E","F","G","H","faceArr","vide2d","faceDr","faceVisibleHautOuBas","areteCachee3","areteCachee2","areteCachee1","cube3d","c","Barre3d","faceTop","faceD","barre3d","Plaque3d","plaque3d","PaveLPH3d","paveLPH3d","Cube","beta","colorD","colorT","colorG","proj","cosa","sina","cosb","sinb","cube","Pave3d","v1","v2","distanceMoyenne4points","dist1","dist2","dist3","dist4","arrondi","minimum","arete","pave3d","rotationV3d","angle","unitaire","u","w","matrice","droite3D","directeur","origine","N","SensDeRotation3d","axe","epaisseur","sensDeRotation3d","CodageAngleDroit3D","taille","BA","BC","k1","k2","M1","M3","BM1","BM3","M2","M1M2","M2M3","bordures","fixeBordures"],"mappings":"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"}