rileyjshaw / terra

:space_invader: JS library for simple biological simulations and cellular automata
http://rileyjshaw.com/terra/
MIT License
610 stars 46 forks source link

Added "render" method #8

Closed johnhenry closed 9 years ago

johnhenry commented 10 years ago

The render method is similar to the to the animate method, except is has two callbacks -- one that's executed after each iteration in addition to the one executed at the end. In addition, on each iteration, the method is passed an object representing the simulation at that stage, with "canvas" and "grid" properties, so the simulations don't have to be in real time and you can look at the data later or all at once rather than in individual frames. At the end of the iteration, the final callback is passed an array of all objects representing all stages. My motivation behind this to study 1-dimensional cellular automata (Wolfram) which is generally done by running the simulation over multiple steps and looking at them all at once. The following code, based on the Game Of Life demo, works in the way I had have intended (that is, if my update is merged).

Math.seedrandom();
var CellularAutomata = new terra.Terrarium(100, 1, undefined, undefined, undefined, true);
terra.creatureFactory.register({
  type: 'CA',
  colorFn: function () { return this.alive ? this.color + ',1' : '0,0,0,0'; },
  wait: function () {},
  isDead: function () { return false; },
  queue: function (neighbors) {
    var surrounding = _.filter(neighbors, function (spot) {
      return spot.creature.alive;
    }).length;
    this.alive = surrounding > 1 && this.alive;
    return false;
  }
}, function () {
  this.alive = Math.random() < 0.80;
});
CellularAutomata.populate([['CA', 100]]);
CellularAutomata.render(25,
function(frame){
    document.body.appendChild(frame.canvas);//Attach Iteration to DOM
    document.body.appendChild(document.createElement("br"));
},function(){
    alert("Simulation Complete!")
});
rileyjshaw commented 10 years ago

Fantastic!

@johnhenry I'm going to spend some time thinking about this one. I love the idea and I think the name render is perfect, but I'm still not sure if saving a new canvas element for each step of the simulation is necessary. For the 1d case, we could just draw the step onto a row of a single canvas at each step. For the 2d case it's trickier; I've been considering how best to do this for a while.

This is a great step forward. I also really like how you're thinking about the library! It's a good goal to be less tied to the animation aspect and more data-driven... that way people can use this for whatever they want (pre-rendering, analysis...), not just making pretty animations :+1:

rileyjshaw commented 10 years ago

The pull request contains both of your commits (fixing default cellSize && adding render)... would you mind stripping the first one out so that it's only the render commit?

Also, a nitpick:

this.supress = false;

doesn't appear to be necessary.

I've added some build instructions in README.md if you need!

johnhenry commented 9 years ago

Sorry, I completely forgot about this. It looks like you've made a lot of progress since, so I'll just go ahead and close this.