jeudi 3 décembre 2020

how to generate random points in a circle (fractal trees)

I am making a tree with space-colonization algorithm in javascript. (with p5.js) I followed the tutorial of https://www.youtube.com/watch?v=kKT0v3qhIQY&ab_channel=TheCodingTrain

or in C# http://www.jgallant.com/procedurally-generating-trees-with-space-colonization-algorithm-in-xna/

I want to make a customized area (in this case a circle) where the leaves are generated randomly. in Leaf.js I try to include some calculations how the leaves get the random Chordinates within the circle.

So there is sketch.js , leaf.js, branch.js, tree.js

//leaf.js
function Leaf() {
      function getChord(){
        var r = 150;
        var angle = random(0, 2 * PI);
        var xChord =  2*r + sqrt(r) * cos(angle);
        var yChord =  r + sqrt(r) * sin(angle);
        return (createVector(xChord, yChord));
      }

      this.pos = getChord();
      this.reached = false;

      // // var t = 2 * PI * random(0,1);
      // // var r = sqrt(random(0,1));
      // // var x = r * cos(t);
      // // var y = r * sin(t); 

      // // this.pos = createVector(x, y);
      // this.reached = false;
  
    this.show = function() {
      fill(58, 126, 34);
      noStroke();
      ellipse(this.pos.x, this.pos.y, 4, 4);
    };
  }
//branch.js

function Branch(parent, pos, dir) {
  this.pos = pos;
  this.parent = parent;
  this.dir = dir;
  this.origDir = this.dir.copy();
  this.count = 0;
  this.len = 3;

  this.reset = function() {
    this.dir = this.origDir.copy();
    this.count = 0;
  };

  this.next = function() {
    var nextDir = p5.Vector.mult(this.dir, this.len);
    var nextPos = p5.Vector.add(this.pos, nextDir);
    var nextBranch = new Branch(this, nextPos, this.dir.copy());
    return nextBranch;
  };

  this.show = function() {
    if (parent != null) {
      stroke(151, 53, 48);
      strokeWeight(1);
      line(this.pos.x, this.pos.y, this.parent.pos.x, this.parent.pos.y);
    }
  };
}

And then in tree.js I push every leaf into leaves.

//tree.js

function Tree() {
  this.leaves = [];
  this.branches = [];

  for (var i = 0; i < 1500; i++) {
    this.leaves.push(new Leaf());
  }
  var pos = createVector(width / 2, height);
  var dir = createVector(0, -1);
  var root = new Branch(null, pos, dir);
  this.branches.push(root);
  var current = root;
  var found = false;
  while (!found) {
    for (var i = 0; i < this.leaves.length; i++) {
      var d = p5.Vector.dist(current.pos, this.leaves[i].pos);
      if (d < max_dist) {
        found = true;
      }
    }
    if (!found) {
      var branch = current.next();
      current = branch;
      this.branches.push(current);
    }
  }

  this.grow = function() {
    for (var i = 0; i < this.leaves.length; i++) {
      var leaf = this.leaves[i];
      var closestBranch = null;
      var record = max_dist;
      for (var j = 0; j < this.branches.length; j++) {
        var branch = this.branches[j];
        var d = p5.Vector.dist(leaf.pos, branch.pos);
        if (d < min_dist) {
          leaf.reached = true;
          closestBranch = null;
          break;
        } else if (d < record) {
          closestBranch = branch;
          record = d;
        }
      }

      if (closestBranch != null) {
        var newDir = p5.Vector.sub(leaf.pos, closestBranch.pos);
        newDir.normalize();
        closestBranch.dir.add(newDir);
        closestBranch.count++;
      }
    }

    for (var i = this.leaves.length - 1; i >= 0; i--) {
      if (this.leaves[i].reached) {
        this.leaves.splice(i, 1);
      }
    }

    for (var i = this.branches.length - 1; i >= 0; i--) {
      var branch = this.branches[i];
      if (branch.count > 0) {
        branch.dir.div(branch.count + 1);
        this.branches.push(branch.next());
        branch.reset();
      }
    }
  };

  this.show = function() {
    for (var i = 0; i < this.leaves.length; i++) {
      this.leaves[i].show();
    }

    for (var i = 0; i < this.branches.length; i++) {
      this.branches[i].show();
    }
  };
}
//sketch.js
var tree;
var max_dist = 30;
var min_dist = 10;

function setup() {
  createCanvas(600, 600);
  tree = new Tree();
}

function draw() {
  background(111, 149, 231);
  tree.show();
  tree.grow();
}

Some how in the function getChord I think there is an infinite loop or having trouble getting the random value? Because it is not loading at all... It works when I change this.pos = getChord(); to this.pos = createVector(random(width),random(height-100);

Does anyone know how to solve this? Or how to write codes to make an area of circle where the leaves can be generated? Thank you!




Aucun commentaire:

Enregistrer un commentaire