◆ Portail Antalaha

Annuaire › Code ouvert

Maison 3D pour une agence immobilière

tutorial · Voir le site ↗
Connectez-vous pour copier ce site

Code publié par son auteur, en lecture seule. « Copier dans mon espace » crée un nouveau site à vous (non publié) que vous pouvez modifier librement.

js/arbre.js · 4.4 Ko

/* ==========================================================================
 * js/arbre.js — UN ARBRE (type flamboyant) À GÉNÉRER PAR FONCTION
 * --------------------------------------------------------------------------
 * Maison.creerArbre(parent, options) fabrique un arbre complet :
 *   - un tronc (Zdog.Cylinder) ;
 *   - un feuillage fait de grosses « boules » vertes ;
 *   - quelques fleurs rouges sur le feuillage.
 *
 * ASTUCE ZDOG : un Zdog.Shape SANS path est un point. Avec un `stroke`
 * (épaisseur) très grand, ce point devient une SPHÈRE visible. L'épaisseur
 * du trait est le DIAMÈTRE de la sphère.
 *
 * Les positions des boules sont tirées au hasard, mais avec un hasard
 * REPRODUCTIBLE (Maison.generateurAleatoire) : mêmes paramètres = même arbre.
 *
 * Dépend de : Zdog, Maison.COULEURS, Maison.generateurAleatoire.
 * ========================================================================== */

(function () {
  'use strict';

  var TAU = Zdog.TAU;

  /**
   * Construit un arbre.
   *
   * @param {Zdog.Anchor} parent Où l'accrocher (le « monde »).
   * @param {Object} [options]
   * @param {number} [options.x=0]         Position sur x.
   * @param {number} [options.z=0]         Position sur z.
   * @param {number} [options.hauteur=40]  Hauteur du tronc.
   * @param {number} [options.graine=7]    Graine du hasard (change la forme).
   * @param {number} [options.boules=7]    Nombre de boules de feuillage.
   * @returns {Zdog.Group} Le groupe contenant tout l'arbre.
   */
  function creerArbre(parent, options) {
    var o = options || {};
    var hauteur = o.hauteur || 40;
    var nbBoules = o.boules || 7;
    var C = Maison.COULEURS;
    var hasard = Maison.generateurAleatoire(o.graine || 7);

    // Un Group avec updateSort: true trie ses enfants du plus loin au plus
    // proche : le feuillage se superpose correctement quand on tourne.
    var arbre = new Zdog.Group({
      addTo: parent,
      translate: { x: o.x || 0, z: o.z || 0 },
      updateSort: true,
    });

    // 1) LE TRONC ----------------------------------------------------------
    // Un Cylinder est « couché » le long de l'axe z par défaut. On le tourne
    // de TAU/4 autour de x pour le dresser le long de y.
    // Son origine est le MILIEU de sa longueur : on le monte de hauteur/2.
    new Zdog.Cylinder({
      addTo: arbre,
      diameter: 9,
      length: hauteur,
      translate: { y: -hauteur / 2 },
      rotate: { x: TAU / 4 },
      stroke: false,
      color: C.tronc,
      backface: C.tronc,            // couleur de l'autre extrémité
    });

    // 2) LE FEUILLAGE ------------------------------------------------------
    // On place les boules autour d'un centre situé au-dessus du tronc.
    var centreY = -hauteur - 14;
    var boules = [];

    for (var i = 0; i < nbBoules; i++) {
      var rayon = 14 + hasard() * 8;                  // diamètre aléatoire : entre 28 et 44
      var position = {
        x: (hasard() - 0.5) * 36,                     // un peu à gauche ou à droite
        y: centreY + (hasard() - 0.5) * 22,           // un peu plus haut ou plus bas
        z: (hasard() - 0.5) * 36,                     // un peu devant ou derrière
      };
      boules.push({ position: position, rayon: rayon });

      new Zdog.Shape({
        addTo: arbre,
        translate: position,
        stroke: rayon * 2,                            // le trait épais = diamètre de la sphère
        color: C.feuillage[i % C.feuillage.length],   // on alterne les 4 verts (% = reste)
      });
    }

    // 3) LES FLEURS --------------------------------------------------------
    // On choisit une boule au hasard, puis un point sur sa surface (direction
    // aléatoire × rayon) et on y pose une petite sphère rouge.
    for (var f = 0; f < 10; f++) {
      var b = boules[Math.floor(hasard() * boules.length)];
      var angleH = hasard() * TAU;                    // angle autour de l'axe vertical
      var angleV = (hasard() - 0.5) * TAU / 2;        // angle de haut en bas
      new Zdog.Shape({
        addTo: arbre,
        translate: {
          x: b.position.x + Math.cos(angleH) * Math.cos(angleV) * b.rayon,
          y: b.position.y + Math.sin(angleV) * b.rayon,
          z: b.position.z + Math.sin(angleH) * Math.cos(angleV) * b.rayon,
        },
        stroke: 5,
        color: C.fleur,
      });
    }

    return arbre;
  }

  Maison.creerArbre = creerArbre;
})();