menu

Populating a grid

Initialising the model itself

To initialise your grid, simply use:
    let config = { ncol:100, nrow:100, title="MyModel", ... }
    sim = new Simulation(config)
followed by
    sim.makeGridmodel("modelname")

Initialise the grid points with numbers

If your model is simple, you can simply represent different "species" or "individuals" as integer numbers (1,2,3,...,n). Similarly, you may want to represent resource concentrations with simple floating point numbers (0.02,1.29,482.1). To do so (after you have made your GridModel), use either:
    initialGrid(@Gridmodel, statename, default_value, 1st_value, 1st_fraction, 2nd_value, 2nd_fraction, ...)
    OR
    initialSpot(@Gridmodel, statename, number, spotsize, x, y)

Use cases:

  • In cheater.html: set species '1', '2', and '3', to 33% occupancy each
    sim.initialGrid(sim.cheater, 'species', 0, 1, 0.33, 2, 0.33, 3, 0.33)
  • In petridish.html: inoculate the middle of the grid with 'alive' cells
    sim.initialSpot(sim.cells, 'alive', 1, 2, sim.cells.nr / 2, sim.cells.nc / 2)
  • In tutorial_colony.html: give all grid points the same value (using the default value)
    sim.initialGrid(sim.growth,'external_resources',1000.0)

Populating the grid points with custom individuals

If your model is a bit more complex, you may want to first define what your individuals look like. To do this, there are two functions analogous to the ones above, but which you can pass a configuration-object with many more options.

First, define your individual(s):
    let individuals = [{alive:1, age:1, name: 'Cacatoo'},{alive:1, age:20, name: 'Cash'}]
And then call the functions "populateSpot" or "populateGrid":
    populateGrid(@Gridmodel, individuals, frequencies)
    OR
    populateSpot(@Gridmodel, individuals, frequencies, size, x, y)

Use cases:

  • In cooperation.html: populate with 'cooperators' and 'cheaters'
    let init_individuals = [{alive:1, helping_rate: helper_rate_cooperator}, {alive:1,helping_rate: helper_rate_cheater}]
    sim.populateSpot(sim.coop, init_individuals, [0.5,0.5], 100, config.ncol/2, config.nrow/2)
  • In tutorial_colony.html: populate with species with different uptake rates
    let species = [{species:1,uptake_rate:0.5,internal_resources:1}, {species:2,uptake_rate:5.0,internal_resources:1}, {species:3,uptake_rate:50.0,internal_resources:1}]
    sim.populateSpot(sim.growth, species, [0.33,0.33,0.33], 15, config.ncol/2, config.nrow/2)

Populating the grid points with PNGs

You can use PNG images to initialize your grid with spatial patterns. There are two options for mapping image colors to grid states:

1. Range-based Color Mapping

Map color ranges to different states in your model:

const rangeStateMapping = [
    { rMin: 0, rMax: 100, gMin: 0, gMax: 100, bMin: 100, bMax: 255, state: 'S' }, // Blues shades → Susceptible
    { rMin: 100, rMax: 255, gMin: 0, gMax: 100, bMin: 0, bMax: 100, state: 'I' }, // Reds shades → Infected
    { rMin: 200, rMax: 255, gMin: 200, gMax: 255, bMin: 200, bMax: 255, state: 'R' } // Light shades → Resistant
];

sim.loadPNGToGrid("image.png", rangeStateMapping, "modelName", "stateProperty", callback);

2. Exact Color Matching

Match specific RGB values to states (useful for simple on/off patterns):

const exactStateMapping = {
    "255,255,255,255": 'X' // White pixels become X to be "excluded" areas (e.g. if you have a topological map)
};

sim.loadPNGToGrid("image.png", exactStateMapping, "modelName", "stateProperty", callback);

Key Considerations:

  • Range-based is better for initialising from complex images
  • Exact matching works well for simple patterns or Cacatoo-derived images
  • Make sure to call any initialization functions after image loading by using the callback function

Example use case:

Manually setting the grid points

If you want even more freedom, it's probably best to loop over all the grid points and set them yourself. Here's an example of that, from "spirals.html":

    for (let i = 0; i < sim.spirals.nc; i++) // i are columns
      for (let j = 0; j < sim.spirals.nr; j++) // j are rows
           sim.spirals.grid[i][j]['colour'] = Math.ceil(sim.rng.genrand_real1() * n_species)


or another example from "ode_turing.html":

    for (let i = 0; i < sim.turing.nc; i++) // i are columns
       for (let j = 0; j < sim.turing.nr; j++) // j are rows
            sim.turing.grid[i][j].turingeq.state = [1 + sim.rng.genrand_real1(), 1]

Populating a flock

Initialising the model itself

To initialise a new simulation:
    let config = { ncol:100, nrow:100, title="MyModel", ... }
    sim = new Simulation(config)
and then initialise a flockmodel:
    let flockconfig = {num_boids: 100, width: 100, height: 200 }
    sim.makeFlockmodel("modelname", flockconfig)

Default boids

If you specified 'num_boids', there are already boids in your model. If you added flocking rules in the flockconfig, they will start flocking out of the box!
If you want to initialise the boids yourself, either use 'populatespot':
populateSpot(25,sim.nr/2,sim.nc/2,10)
This creates 25 boids in the center of the simulation in a radius of 10. Alternatively, push some 'boids' array like this:

for(let i=0;i<25;i++) {
  boid = {}
  boid.png = "my_image.png"
  boid.position.x = sim.rng.random()*20   // random number 0 to 20
  boid.position.y = sim.rng.random()*30  // random number 0 to 30
  boid.velocity.x = sim.rng.random()*2-1  // random number -1 to 1
  boid.velocity.y = sim.rng.random()*2-1  // random number -1 to 1
  boid.total_energy = 10
  sim.modelname.boids.push(boid)
}