Outils pour utilisateurs

Outils du site


figure_de_lichtenberg

Figures de Lichtenberg

Illustration

Théorie

Simulation

Résultat

Processing

ArrayList<Marcheur> arbre;
ArrayList<Marcheur> marcheurs;
int nombreMarcheurs = 2000;
int rangMax = 0;
 
 
void setup() {
  size(1600, 1000);
  arbre = new ArrayList<Marcheur>();
  arbre.add(new Marcheur(width / 2, height));
  marcheurs = new ArrayList<Marcheur>();
  for (int i = 0; i < nombreMarcheurs; i++) {
    marcheurs.add(new Marcheur());
  }
}
 
void draw() {
  background(0);
  for (int i = marcheurs.size() - 1; i >= 0; i--) {
    Marcheur m = marcheurs.get(i);
    m.rafraichir();
    //m.afficher(rangMax);
    for (int j = 0; j < arbre.size(); j++) {
      Marcheur ma = arbre.get(j);
      if (m.position.dist(ma.position) < (2 * ma.rayon - 4)) {
        if (m.position.y < ma.position.y) {
          marcheurs.remove(m);
          m.rayon = ma.rayon * 0.97;
          m.rang = ma.rang + 1;
          m.parent = ma;
          if (m.rang > rangMax) {
            rangMax = m.rang;
          }
          arbre.add(m);
          break;
        } else {
          m.position = haut();
        }
      }
    }
  }
  for (int i = arbre.size() - 1; i >= 0; i--) {
    Marcheur ma = arbre.get(i);
    ma.afficher(rangMax);
  }
  if (marcheurs.size() == 0) {
    affichageArbre();
    println(rangMax);
    saveFrame("images/DLA-######.png");
    noLoop();
  }
}
 
void affichageArbre() {
  background(0);
  for (int j = 1; j < arbre.size(); j++) {
    Marcheur ma1 = arbre.get(j);
    Marcheur ma2 = ma1.parent;
    stroke(255);
    strokeWeight(ma2.rayon / 3.5);
    line(ma1.position.x, ma1.position.y, ma2.position.x, ma2.position.y);
  }
}
 
class Marcheur {
  PVector position; 
  Marcheur parent;
  float rayon;
  int rang;
 
  Marcheur() {
    position = haut();
    rayon = 15;
    rang = 0;
  }
 
  Marcheur(int x, int y) {
    position = new PVector(x, y);
    rayon = 30;
    rang = 0;
  }
 
  void rafraichir() {
    PVector vitesse = PVector.random2D().setMag(30);
    position.add(vitesse);
    position.x = constrain(position.x, 0, width);
    position.y = constrain(position.y, 0, height);
  }
 
  void afficher(int r) {
    noStroke();
    int teinte = (int)map(rang, 0, r, 255, 10);
    fill(teinte);
    ellipse(position.x, position.y, 2 * rayon, 2 * rayon);
  }
}
 
PVector pourtour() {
  int a = (int)random(3);
  if (a == 0) {
    float r = random(width);
    return new PVector(r, 0);
  } else if (a == 1) {
    float t = random(height);
    return new PVector(0, t);
  } else {
    float u = random(width);
    return new PVector(width, u);
  }
}
 
PVector haut() {
  float r = random(width);
  return new PVector(r, 0);
}
 
float distSq(PVector a, PVector b) {
  float dx = b.x - a.x;
  float dy = b.y - a.y;
  return dx * dx + dy * dy;
}

Processing 3D

Voici le code avec exportation .png et .stl :

import java.io.*;
import peasy.PeasyCam;
 
PeasyCam cam;
File repertoire;
 
 
ArrayList<Marcheur> arbre;
ArrayList<Marcheur> marcheurs;
int nombreMarcheurs = 1000;
int limite = 800;
int rangMax = 0;
 
public void settings() {
  size(1000, 1000, P3D);
  arbre = new ArrayList<Marcheur>();
  arbre.add(new Marcheur(0, 0, 0, limite));
  marcheurs = new ArrayList<Marcheur>();
  for (int i = 0; i < nombreMarcheurs; i++) {
    marcheurs.add(new Marcheur(limite));
  }
}
 
public void setup() {
  cam = new PeasyCam(this, 400);
    repertoire = new File(sketchPath());
 
}
 
public void draw() {
  lights();
  scale(1);
  rotateX(PI/2);
  background(0);
  for (int i = marcheurs.size() - 1; i >= 0; i--) {
    Marcheur m = marcheurs.get(i);
    m.rafraichir();
    //m.afficher(1);
    for (int j = 0; j < arbre.size(); j++) {
      Marcheur ma = arbre.get(j);
      if (dist3DSq(m.position, ma.position) < (4 * ma.rayon * ma.rayon)) {
        if (m.position.z > ma.position.z) {
          marcheurs.remove(m);
          m.rayon = ma.rayon * 0.97;
          m.rang = ma.rang + 1;
          m.parent = ma;
          if (m.rang > rangMax) {
            rangMax = m.rang;
          }
          arbre.add(m);
          break;
        } else {
          m.position = pourtour(limite);
        }
      }
    }
  }
  affichageArbre(arbre);
  if (marcheurs.size() == 0) {
    println(rangMax);
  }
}
 
void affichageArbre(ArrayList<Marcheur> a) {
  background(0);
  for (int j = 1; j < a.size(); j++) {
    Marcheur ma1 = a.get(j);
    Marcheur ma2 = ma1.parent;
    stroke(255);
    strokeWeight(ma2.rayon / 3.5);
    line(ma1.position.x, ma1.position.y, ma1.position.z, ma2.position.x, ma2.position.y, ma2.position.z);
  }
}
 
void keyPressed() {
  if (key == ' ') {
    saveFrame("images/DLA3D-######.png");
  }
  if (key == 'e') {
    exporterSTL(arbre);
  }
}
 
void exporterSTL(ArrayList<Marcheur> a) {
  String ligne = "[";
    for (int j = 1; j < a.size(); j++) {
      if (j != 1) {
        ligne += ",";
      }
      Marcheur ma1 = a.get(j);
      Marcheur ma2 = ma1.parent;
      String p1 = "[" + ma1.position.x + "," + ma1.position.y + "," + ma1.position.z + "]";
      String p2 = "[" + ma2.position.x + "," + ma2.position.y + "," + ma2.position.z + "]";
      ligne += "[[" + p1 + "," + ma1.rayon / 3.5 + "]," + "[" + p2 + "," + ma2.rayon / 3.5 + "]]";
    }
    ligne += "]";
    println(ligne);
    String[] cmd = {"/Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD", 
      "-o", 
      "Arbre.stl", 
      "-D", 
      "u = " + ligne, 
      "Arbre.scad"};
 
    Process p;
    try {
      p = Runtime.getRuntime().exec(cmd, new String[0], repertoire);
      p.waitFor();
      float error = p.exitValue();
      println("Erreur = " + error);
    } 
    catch (InterruptedException e) {
      e.printStackTrace();
    } 
    catch (IOException e) {
      e.printStackTrace();
    }
}
 
class Marcheur {
  PVector position; 
  Marcheur parent;
  float rayon;
  int rang;
  int limite;
 
  Marcheur(int l) {
    limite = l;
    position = pourtour(limite);
    rayon = 15;
    rang = 0;
  }
 
  Marcheur(int x, int y, int z, int l) {
    limite = l;
    position = new PVector(x, y, z);
    rayon = 30;
    rang = 1;
  }
 
  void rafraichir() {
    PVector vitesse = PVector.random3D().setMag(30);
    position.add(vitesse);
    position.setMag(constrain(position.mag(), 0, limite));
  }
 
  void afficher(int r) {
    noStroke();
    int teinte = (int)map(rang, 0, r, 255, 10);
    fill(teinte);
    pushMatrix();
    translate(position.x, position.y, position.z);
    sphere( 2 * rayon);
    popMatrix();
  }
}
 
PVector pourtour(int l) {
  PVector v = PVector.random3D().setMag(l);
  v.z = abs(v.z);
  return v;
}
 
float dist3DSq(PVector a, PVector b) {
  float dx = b.x - a.x;
  float dy = b.y - a.y;
  float dz = b.z - a.z;
  return dx * dx + dy * dy + dz * dz;
}

Pour la partie OpenSACD de l'exportation .stl :

$fn = 15;
 
u = [[[[10, 10, 10], 30], [[30, 20, 40], 20]], [[[30, 20, 40], 20], [[60, 30, 45], 10]]];
 
for (i = [0:len(u) - 1]) {
    element(u[i]);
}
 
module element(e) {
    a = e[0];
    b = e[1];
    hull() {
        translate(a[0]) sphere(d = a[1]);
        translate(b[0]) sphere(d = b[1]);
    }
}

Code

Heightmap

Agrégation limitée par la diffusion (DLA)

figure_de_lichtenberg.txt · Dernière modification: 2019/11/24 10:13 par Mushussu