Compare commits
No commits in common. "b34644733d857c8e26540af950735556f4297ff2" and "03290feb3b9017f4ec520855709364aaa25dc982" have entirely different histories.
b34644733d
...
03290feb3b
|
@ -7,6 +7,6 @@
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="library" name="core" level="application" />
|
<orderEntry type="library" name="core" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
|
@ -1,3 +0,0 @@
|
||||||
Manifest-Version: 1.0
|
|
||||||
Main-Class: Predator
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
Manifest-Version: 1.0
|
|
||||||
Main-Class: Predator
|
|
||||||
|
|
Before Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 7 KiB |
Before Width: | Height: | Size: 5.3 KiB |
|
@ -1,3 +0,0 @@
|
||||||
Manifest-Version: 1.0
|
|
||||||
Main-Class: Predator
|
|
||||||
|
|
Before Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 7 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 16 KiB |
|
@ -1,3 +1,3 @@
|
||||||
Manifest-Version: 1.0
|
Manifest-Version: 1.0
|
||||||
Main-Class: Predator
|
Main-Class: main.java.com.lotkavolterra.PopulationModel
|
||||||
|
|
||||||
|
|
1003
src/Predator.java
|
@ -1,22 +0,0 @@
|
||||||
import processing.core.PApplet;
|
|
||||||
import processing.core.PShape;
|
|
||||||
|
|
||||||
public class ProcessingTest extends PApplet{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void settings() {
|
|
||||||
size(200, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw() {
|
|
||||||
background(0);
|
|
||||||
fill(255, 0, 0);
|
|
||||||
ellipse(100, 100, 100, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main (String... args) {
|
|
||||||
ProcessingTest pt = new ProcessingTest();
|
|
||||||
PApplet.runSketch(new String[]{"ProcessingTest"}, pt);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
public class Structs {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package com.company;
|
|
||||||
|
|
||||||
public class Main {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
// write your code here
|
|
||||||
}
|
|
||||||
}
|
|
30
src/main/java/com/lotkavolterra/Bar.java
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package main.java.com.lotkavolterra;
|
||||||
|
|
||||||
|
public class Bar extends Structs {
|
||||||
|
float x; // top left corner x position
|
||||||
|
float y; // top left corner y position
|
||||||
|
float w; // width of button
|
||||||
|
float h; // height of button
|
||||||
|
float my_fill; // Fill the box till
|
||||||
|
|
||||||
|
Bar( float xpos, float ypos, float widthB, float heightB) {
|
||||||
|
x = xpos;
|
||||||
|
y = ypos;
|
||||||
|
w = widthB;
|
||||||
|
h = heightB;
|
||||||
|
my_fill=x;
|
||||||
|
}
|
||||||
|
|
||||||
|
double get_value() {
|
||||||
|
return my_fill/w;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean MouseIsOver( float mouseX, float mouseY) {
|
||||||
|
if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
|
||||||
|
my_fill=mouseX - x;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
26
src/main/java/com/lotkavolterra/Button.java
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package main.java.com.lotkavolterra;
|
||||||
|
|
||||||
|
import processing.core.PApplet;
|
||||||
|
|
||||||
|
class Button extends PApplet {
|
||||||
|
String label;
|
||||||
|
float x; // top left corner x position
|
||||||
|
float y; // top left corner y position
|
||||||
|
float w; // width of button
|
||||||
|
float h; // height of button
|
||||||
|
|
||||||
|
Button(String labelB, float xpos, float ypos, float widthB, float heightB) {
|
||||||
|
label = labelB;
|
||||||
|
x = xpos;
|
||||||
|
y = ypos;
|
||||||
|
w = widthB;
|
||||||
|
h = heightB;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean MouseIsOver(float mouseX, float mouseY) {
|
||||||
|
if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
16
src/main/java/com/lotkavolterra/Densities.java
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package main.java.com.lotkavolterra;
|
||||||
|
|
||||||
|
public class Densities {
|
||||||
|
double rabbits;
|
||||||
|
double foxes;
|
||||||
|
double desert;
|
||||||
|
double grass;
|
||||||
|
Densities (double rabbits, double foxes,double desert, double grass)
|
||||||
|
{
|
||||||
|
this.rabbits=rabbits;
|
||||||
|
this.foxes=foxes;
|
||||||
|
this.desert=desert;
|
||||||
|
this.grass=grass;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
163
src/main/java/com/lotkavolterra/Graphs.java
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
package main.java.com.lotkavolterra;
|
||||||
|
|
||||||
|
import processing.core.PApplet;
|
||||||
|
import processing.core.PConstants;
|
||||||
|
import processing.core.PImage;
|
||||||
|
|
||||||
|
public class Graphs extends Structs {
|
||||||
|
|
||||||
|
public int WIDTH = 1900;
|
||||||
|
public int HEIGHT = 1000;
|
||||||
|
|
||||||
|
public PImage[] images_g = new PImage[5];
|
||||||
|
public Structs.Box[] colors = new Structs.Box[5];
|
||||||
|
public int PIC_SIZE = 80;
|
||||||
|
public int TRACES = 40;
|
||||||
|
public int[] counter = new int[5];
|
||||||
|
public int[][] traces = new int[N_AGENTS][TRACES];
|
||||||
|
|
||||||
|
String[] myFileArray = {"main/resources/pictures/fox.jpg", "main/resources/pictures/rabbit.jpg", "main/resources/pictures/grass.jpeg", "main/resources/pictures/soil.jpg", "main/resources/pictures/road.jpeg"}; // picture names,, add more
|
||||||
|
String[] myNames = {"fox", "rabbit", "grass", "desert"}; // picture names,, add more
|
||||||
|
|
||||||
|
public void set_traces(Densities d){
|
||||||
|
for (int i = 0; i < TRACES; i += 1) {
|
||||||
|
traces[FOX][i] = (int) d.foxes;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < TRACES; i += 1) {
|
||||||
|
traces[RABBIT][i] = (int) d.rabbits;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < TRACES; i += 1) {
|
||||||
|
traces[GRASS][i] = (int) d.grass;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < TRACES; i += 1) {
|
||||||
|
traces[DESERT][i] = (int) d.desert;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load_image(){
|
||||||
|
PImage im ;
|
||||||
|
PImage im_g;
|
||||||
|
for (int x=0; x < 5; x++ ) {
|
||||||
|
im = loadImage(myFileArray[x]);
|
||||||
|
im.resize(SIZE, SIZE);
|
||||||
|
images[x] = im;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x=0; x < 5; x++ ) {
|
||||||
|
im_g = loadImage(myFileArray[x]);
|
||||||
|
im_g.resize(PIC_SIZE, PIC_SIZE);
|
||||||
|
images_g[x] = im_g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// count the number of agents from the boxes
|
||||||
|
public void count_boxes(){
|
||||||
|
for (int n=0; n<5; n++) {
|
||||||
|
counter[n] = 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < nn; i++) {
|
||||||
|
counter[boxes[i].type] +=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Visualizations: update_traces creates the fading effect on the plots
|
||||||
|
public void update_traces(){
|
||||||
|
count_boxes();
|
||||||
|
for (int j = 0; j < 4; j += 1) {
|
||||||
|
if (TRACES - 1 >= 0) {
|
||||||
|
System.arraycopy(traces[j], 1, traces[j], 0, TRACES - 1);
|
||||||
|
traces[j][TRACES-1] = counter[j];
|
||||||
|
} else {
|
||||||
|
traces[j][TRACES-1] = counter[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void arrow(int x1, int y1, int x2, int y2) {
|
||||||
|
|
||||||
|
strokeWeight(3);
|
||||||
|
line(x1, y1, x2, y2);
|
||||||
|
pushMatrix();
|
||||||
|
translate(x2, y2);
|
||||||
|
float a = atan2(x1-x2, y2-y1);
|
||||||
|
rotate(a);
|
||||||
|
strokeWeight(3);
|
||||||
|
line(0, 0, -10, -10);
|
||||||
|
line(0, 0, 10, -10);
|
||||||
|
popMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw_box(Bar bar) {
|
||||||
|
fill(218);
|
||||||
|
stroke(141);
|
||||||
|
rect(bar.x,bar.y, bar.w, bar.h, 10);
|
||||||
|
fill(0);
|
||||||
|
rect(bar.x,bar.y, bar.my_fill, bar.h, 10);
|
||||||
|
}
|
||||||
|
public void draw_button(Button button) {
|
||||||
|
fill(218);
|
||||||
|
stroke(141);
|
||||||
|
rect(button.x, button.y, button.w, button.h, 10);
|
||||||
|
textAlign(CENTER, CENTER);
|
||||||
|
fill(0);
|
||||||
|
text(button.label, button.x + (button.w / 2), button.y + (button.h / 2));
|
||||||
|
}
|
||||||
|
public void draw_slider(Slider slider) {
|
||||||
|
stroke(0);
|
||||||
|
line(slider.x, slider.y, slider.x+ slider.w, slider.y );
|
||||||
|
circle(slider.w0+slider.x, slider.y, PIC_SIZE/2);
|
||||||
|
textAlign(CENTER, CENTER);
|
||||||
|
fill(0);
|
||||||
|
text(slider.label, slider.x + (slider.w / 2), slider.y + (PIC_SIZE / 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Make the plots on the right side
|
||||||
|
public void plot_traces() {
|
||||||
|
float mean;
|
||||||
|
strokeWeight(3);
|
||||||
|
textSize(30);
|
||||||
|
textAlign(LEFT);
|
||||||
|
stroke(182,22,63);
|
||||||
|
|
||||||
|
// Upper plot with phase space
|
||||||
|
text("Volpi", WIDTH/2 + 2*PIC_SIZE, 2*PIC_SIZE );
|
||||||
|
arrow(WIDTH/2 + 2* PIC_SIZE, HEIGHT/2, WIDTH/2 + 2*PIC_SIZE, 2*PIC_SIZE);
|
||||||
|
stroke(4,54,84);
|
||||||
|
arrow(WIDTH/2 + 2* PIC_SIZE, HEIGHT/2, WIDTH *3/4, HEIGHT/2);
|
||||||
|
text("Conigli", WIDTH*3/4, HEIGHT/2 );
|
||||||
|
for (int i = 0; i < TRACES-1; i += 1) {
|
||||||
|
stroke(0, i*255/TRACES);
|
||||||
|
if (traces[RABBIT][i] > 0) {
|
||||||
|
line(WIDTH/2+ 2*PIC_SIZE +WIDTH/2 *traces[RABBIT][i]/nn,
|
||||||
|
HEIGHT/2 *(nn-traces[FOX][i])/nn,
|
||||||
|
WIDTH/2+ 2*PIC_SIZE + WIDTH/2 *traces[RABBIT][i+1]/nn ,
|
||||||
|
HEIGHT/2*(nn-traces[FOX][i + 1])/nn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lower plot with pop densities
|
||||||
|
for (int j = 0; j < 4; j += 1) {
|
||||||
|
mean = 0;
|
||||||
|
for (int i = 0; i < TRACES-1; i += 1) {
|
||||||
|
mean += traces[j][i];
|
||||||
|
}
|
||||||
|
mean /= TRACES;
|
||||||
|
if (j==GRASS) {stroke(77,137,99);}
|
||||||
|
else if (j==FOX) {stroke(182,22,63);}
|
||||||
|
else if (j==DESERT) {stroke(244,148,0);}
|
||||||
|
else if (j==RABBIT) {stroke(4,54,84);}
|
||||||
|
|
||||||
|
strokeWeight((float) 2.5);
|
||||||
|
for (int i = 0; i < TRACES-1; i += 1) {
|
||||||
|
if (traces[j][i] > 0) {
|
||||||
|
line(HEIGHT + 200 +i*15,
|
||||||
|
HEIGHT/2 +PIC_SIZE +(10 * PIC_SIZE * (traces[j][i] )/nn),
|
||||||
|
HEIGHT + 200 +i*15+15,
|
||||||
|
HEIGHT/2+ +PIC_SIZE +(10 * PIC_SIZE * (traces[j][i + 1])/nn));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialization
|
||||||
|
|
||||||
|
}
|
271
src/main/java/com/lotkavolterra/PopulationModel.java
Normal file
|
@ -0,0 +1,271 @@
|
||||||
|
package main.java.com.lotkavolterra;
|
||||||
|
|
||||||
|
import processing.core.PFont;
|
||||||
|
import processing.core.PApplet;
|
||||||
|
|
||||||
|
public class PopulationModel extends Graphs {
|
||||||
|
|
||||||
|
// Distributions
|
||||||
|
Densities densities = new Densities(0.,0.,0.5,0.5);
|
||||||
|
Bar fox_bar;
|
||||||
|
Bar rabbit_bar;
|
||||||
|
Button start;
|
||||||
|
Button restart;
|
||||||
|
Slider speed;
|
||||||
|
|
||||||
|
|
||||||
|
// visualization
|
||||||
|
|
||||||
|
|
||||||
|
PFont f;
|
||||||
|
int box = -1 ;
|
||||||
|
double time = 0;
|
||||||
|
boolean INIT_TODO = true;
|
||||||
|
boolean RUN_SIMULATION = false;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void settings() {
|
||||||
|
size(WIDTH, HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
SIZE =HEIGHT/n_boxes;
|
||||||
|
set_traces(densities);
|
||||||
|
load_image();
|
||||||
|
f = createFont("Arial",16,true);
|
||||||
|
for (int t = 0; t < 4; t += 1) {
|
||||||
|
colors[t] = new Structs.Box(SIZE*n_boxes+PIC_SIZE*2*(t+1), PIC_SIZE/2, t, PIC_SIZE);
|
||||||
|
} // for
|
||||||
|
strokeWeight(3);
|
||||||
|
fox_bar = new Bar(WIDTH * 1 / 4, HEIGHT * 1 / 2, WIDTH / 2, PIC_SIZE);
|
||||||
|
rabbit_bar = new Bar(WIDTH * 1 / 4, HEIGHT * 1 / 2 +100, WIDTH / 2, PIC_SIZE);
|
||||||
|
start = new Button("Start", WIDTH * 3/4-100, HEIGHT * 3/4, WIDTH/4, PIC_SIZE);
|
||||||
|
speed = new Slider("Speed", WIDTH* 85/100, HEIGHT* 3/10, WIDTH*1/10);
|
||||||
|
restart = new Button("Restart", WIDTH* 85/100, (float)(HEIGHT* 3/10 + PIC_SIZE), WIDTH*1/10, PIC_SIZE);
|
||||||
|
} // setup()
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw() {
|
||||||
|
if (INIT_TODO){
|
||||||
|
background(255);
|
||||||
|
fill(0);
|
||||||
|
stroke(0);
|
||||||
|
textSize(40);
|
||||||
|
textAlign(CENTER);
|
||||||
|
text("Scegli la percentuale di volpi e conigli", WIDTH/2, HEIGHT/2 -200);
|
||||||
|
image(images_g[1], WIDTH*1/4 - PIC_SIZE -5 , HEIGHT*1/2 +100);
|
||||||
|
image(images_g[0], WIDTH*1/4 - PIC_SIZE -5, HEIGHT*1/2 );
|
||||||
|
draw_box(fox_bar);
|
||||||
|
draw_box(rabbit_bar);
|
||||||
|
draw_button(start);
|
||||||
|
if (mousePressed){
|
||||||
|
fox_bar.MouseIsOver(mouseX, mouseY);
|
||||||
|
rabbit_bar.MouseIsOver(mouseX, mouseY);
|
||||||
|
if (start.MouseIsOver(mouseX, mouseY)){
|
||||||
|
INIT_TODO = false;
|
||||||
|
densities.foxes= fox_bar.get_value();
|
||||||
|
densities.rabbits= rabbit_bar.get_value();
|
||||||
|
println(densities.desert, densities.foxes, densities.grass, densities.rabbits);
|
||||||
|
initialize();
|
||||||
|
println(densities.foxes, densities.rabbits);
|
||||||
|
println(counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
mousePressed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (keyPressed == true) {
|
||||||
|
if (key == 'q' || key == 'Q') {
|
||||||
|
background(0);
|
||||||
|
INIT_TODO = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
time += 5*speed.get_speed();
|
||||||
|
delay(20);
|
||||||
|
if (mousePressed) {
|
||||||
|
box = get_clicked_box(mouseX, mouseY);
|
||||||
|
if (box > -1) boxes[box].type = ROAD;
|
||||||
|
speed.MouseIsOver(mouseX, mouseY);
|
||||||
|
if (restart.MouseIsOver(mouseX, mouseY)) {INIT_TODO = true;}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time >10)
|
||||||
|
{
|
||||||
|
time=0;
|
||||||
|
update_grid();
|
||||||
|
update_traces();
|
||||||
|
}
|
||||||
|
background(255);
|
||||||
|
draw_slider(speed);
|
||||||
|
draw_button(restart);
|
||||||
|
|
||||||
|
|
||||||
|
plot_traces();
|
||||||
|
for (int k = 0; k < 4; k++) {
|
||||||
|
colors[k].make_borders();
|
||||||
|
image(images_g[k],SIZE*n_boxes+PIC_SIZE*2*(k+1), PIC_SIZE/2);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < nn; i++) {
|
||||||
|
boxes[i].display(boxes[i].type);
|
||||||
|
} // for
|
||||||
|
|
||||||
|
// print("size");
|
||||||
|
// print(boxes[0].x);
|
||||||
|
// print(boxes[0].x+boxes[0].w);
|
||||||
|
}
|
||||||
|
} // draw()
|
||||||
|
|
||||||
|
// ===============================================================
|
||||||
|
|
||||||
|
private void normalize_densities(Densities d) {
|
||||||
|
d.rabbits = d.rabbits/2;
|
||||||
|
d.foxes = d.foxes/2;
|
||||||
|
d.desert = 0.25;
|
||||||
|
d.grass = 0.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int weighted_type(Densities d) {
|
||||||
|
float r = random(0, 1);
|
||||||
|
if (r < d.foxes) {
|
||||||
|
return FOX;
|
||||||
|
} else if (r < d.rabbits + d.foxes) {
|
||||||
|
return RABBIT;
|
||||||
|
} else if (r < d.rabbits + d.foxes + d.grass) {
|
||||||
|
return GRASS;
|
||||||
|
} else {
|
||||||
|
return DESERT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialize() {
|
||||||
|
normalize_densities(densities);
|
||||||
|
int k=0;
|
||||||
|
for (int j = 0; j < n_boxes; j += 1) {
|
||||||
|
// run over the ys
|
||||||
|
for (int i = 0; i < n_boxes; i += 1) {
|
||||||
|
int type = weighted_type(densities);
|
||||||
|
boxes[k] = new Structs.Box(i * SIZE, j * SIZE, type);
|
||||||
|
neighs[k] = new Structs.Neighbours(i, j);
|
||||||
|
k++;
|
||||||
|
} // for
|
||||||
|
} // for
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===============================================================
|
||||||
|
// Evolution algorithm
|
||||||
|
private void update_grid(){
|
||||||
|
|
||||||
|
int k =0;
|
||||||
|
//for each box evolve by the rules
|
||||||
|
//run over xs and ys
|
||||||
|
boolean starve;
|
||||||
|
for (int j = 0; j < n_boxes; j += 1) {
|
||||||
|
for (int i = 0; i < n_boxes; i += 1) {
|
||||||
|
// run over the ys
|
||||||
|
// death conditions
|
||||||
|
// fox dies if no rabbits
|
||||||
|
if (boxes[k].type == ROAD) {
|
||||||
|
boxes[k].next = ROAD;
|
||||||
|
}
|
||||||
|
if (boxes[k].type == FOX) {
|
||||||
|
starve = true;
|
||||||
|
for (int n = 0; n < neighs[k].surround.length; n++) {
|
||||||
|
if (boxes[neighs[k].surround[n]].type == RABBIT) {
|
||||||
|
// there is AT LEAST a rabbit, no starvation
|
||||||
|
starve = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (boxes[neighs[k].surround[n]].type == DESERT) {
|
||||||
|
// there is AT LEAST a desert, starvation
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (starve) {boxes[k].next = DESERT;}
|
||||||
|
}
|
||||||
|
// rabbit dies if no grass
|
||||||
|
if (boxes[k].type == RABBIT) {
|
||||||
|
starve = true;
|
||||||
|
for (int n = 0; n < neighs[k].surround.length; n++) {
|
||||||
|
if (boxes[neighs[k].surround[n]].type == GRASS) {
|
||||||
|
// there is AT LEAST a grass, no starvation
|
||||||
|
starve = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (starve) {boxes[k].next = DESERT;}
|
||||||
|
}
|
||||||
|
// birth conditions
|
||||||
|
// fox is born eating rabbit
|
||||||
|
if (boxes[k].type == RABBIT) {
|
||||||
|
for (int n = 0; n < neighs[k].surround.length; n++) {
|
||||||
|
if (boxes[neighs[k].surround[n]].type == FOX) {
|
||||||
|
boxes[k].next = FOX;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// rabbit is born eating grass
|
||||||
|
if (boxes[k].type == GRASS) {
|
||||||
|
for (int n = 0; n < neighs[k].surround.length; n++) {
|
||||||
|
if (boxes[neighs[k].surround[n]].type == RABBIT) {
|
||||||
|
boxes[k].next = RABBIT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// grass grows where desert
|
||||||
|
if (boxes[k].type == DESERT) {
|
||||||
|
for (int n = 0; n < neighs[k].surround.length; n++) {
|
||||||
|
if (boxes[neighs[k].surround[n]].type == GRASS) {
|
||||||
|
boxes[k].next = GRASS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
k = 0;
|
||||||
|
for (int j = 0; j < n_boxes; j += 1) {
|
||||||
|
// run over the ys
|
||||||
|
for (int i = 0; i < n_boxes; i += 1) {
|
||||||
|
boxes[k].type = boxes[k].next;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int get_clicked_box(int x, int y){
|
||||||
|
int box =-1;
|
||||||
|
for (int i = 0; i < nn; i += n_boxes) {
|
||||||
|
if (boxes[i].y < y && y < +boxes[i].yend) {
|
||||||
|
for (int j = 0; j < n_boxes; j += 1) {
|
||||||
|
if (boxes[j+i].x < x && x < + boxes[j+i].xend){
|
||||||
|
box = j+i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return box;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main (String... args) {
|
||||||
|
PopulationModel pt = new PopulationModel();
|
||||||
|
runSketch(new String[]{"PopulationModel"}, pt);
|
||||||
|
}
|
||||||
|
// public static void main(String[] passedArgs) {
|
||||||
|
// String[] appletArgs = new String[] { "PopulationModel" };
|
||||||
|
// PApplet.main(appletArgs);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
28
src/main/java/com/lotkavolterra/Slider.java
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
package main.java.com.lotkavolterra;
|
||||||
|
|
||||||
|
public class Slider extends Graphs {
|
||||||
|
float x; // top left corner x position
|
||||||
|
float y; // top left corner y position
|
||||||
|
float w; // width of button
|
||||||
|
String label;
|
||||||
|
float w0; // Fill the box till
|
||||||
|
|
||||||
|
Slider(String mylabel, float xpos, float ypos, float widthB) {
|
||||||
|
x = xpos;
|
||||||
|
y = ypos;
|
||||||
|
w = widthB;
|
||||||
|
label = mylabel;
|
||||||
|
w0=0;
|
||||||
|
}
|
||||||
|
float get_speed(){
|
||||||
|
return w0/w;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean MouseIsOver( float mouseX, float mouseY) {
|
||||||
|
if (mouseX > x && mouseX < (x + w) && mouseY > y-PIC_SIZE/2 && mouseY < (y + PIC_SIZE/2)) {
|
||||||
|
w0=mouseX - x;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
133
src/main/java/com/lotkavolterra/Structs.java
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
package main.java.com.lotkavolterra;
|
||||||
|
|
||||||
|
import processing.core.PApplet;
|
||||||
|
import processing.core.PImage;
|
||||||
|
|
||||||
|
public class Structs extends PApplet {
|
||||||
|
|
||||||
|
int n_boxes = 30;
|
||||||
|
|
||||||
|
int FOX = 0;
|
||||||
|
int RABBIT = 1;
|
||||||
|
int GRASS = 2;
|
||||||
|
int DESERT = 3;
|
||||||
|
int ROAD = 4;
|
||||||
|
int N_AGENTS = 4;
|
||||||
|
|
||||||
|
PImage[] images = new PImage[5];
|
||||||
|
|
||||||
|
int SIZE = -1;
|
||||||
|
boolean DIAGONAL = false;
|
||||||
|
|
||||||
|
int nn = n_boxes *n_boxes;
|
||||||
|
Box [] boxes = new Box[nn];
|
||||||
|
Neighbours [] neighs = new Neighbours[nn] ;
|
||||||
|
|
||||||
|
class Box {
|
||||||
|
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float xend;
|
||||||
|
float yend;
|
||||||
|
|
||||||
|
float w=SIZE;
|
||||||
|
float h=SIZE;
|
||||||
|
|
||||||
|
int type;
|
||||||
|
int next;
|
||||||
|
|
||||||
|
|
||||||
|
// constr
|
||||||
|
|
||||||
|
Box ( float x, float y, int type, int size) {
|
||||||
|
this.x=x;
|
||||||
|
this.y=y;
|
||||||
|
this.w = size;
|
||||||
|
this.h = size;
|
||||||
|
this.xend=x+size;
|
||||||
|
this.yend=y+size;
|
||||||
|
this.type =type;
|
||||||
|
this.next =type;
|
||||||
|
} // constr
|
||||||
|
Box ( float x, float y, int type) {
|
||||||
|
this.x=x;
|
||||||
|
this.y=y;
|
||||||
|
this.type =type;
|
||||||
|
this.next =type;
|
||||||
|
this.xend=x+this.w;
|
||||||
|
this.yend=y+this.h;
|
||||||
|
} // constr
|
||||||
|
|
||||||
|
void make_borders() {
|
||||||
|
int j = type;
|
||||||
|
if (j==GRASS) {stroke(77,137,99);}
|
||||||
|
else if (j==FOX) {stroke(182,22,63);}
|
||||||
|
else if (j==DESERT) {stroke(244,148,0);}
|
||||||
|
else if (j==RABBIT) {stroke(4,54,84);}
|
||||||
|
strokeWeight(10);
|
||||||
|
rect(x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void display(int n) {
|
||||||
|
image(images[n], x, y);
|
||||||
|
}
|
||||||
|
} // class
|
||||||
|
|
||||||
|
class Neighbours {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int [] surround;
|
||||||
|
|
||||||
|
Neighbours( int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
if (DIAGONAL) {
|
||||||
|
int N = 8;
|
||||||
|
int[] xs= new int[N];
|
||||||
|
int[] ys= new int[N];
|
||||||
|
|
||||||
|
ys[0] = (n_boxes + y-1)%n_boxes;
|
||||||
|
ys[1] = ys[0];
|
||||||
|
ys[2] = ys[0];
|
||||||
|
ys[3] = y; ys[4] = y;
|
||||||
|
ys[5] = (y+1)%n_boxes;
|
||||||
|
ys[6] = ys[5];
|
||||||
|
ys[7] = ys[5];
|
||||||
|
|
||||||
|
xs[0] = (n_boxes + x-1)%n_boxes;
|
||||||
|
xs[1] = x;
|
||||||
|
xs[2] = (x+1) %n_boxes;
|
||||||
|
xs[3] = xs[0]; xs[4] =xs[2];
|
||||||
|
xs[5] = xs[0];
|
||||||
|
xs[6] = x;
|
||||||
|
xs[7] = xs[2];
|
||||||
|
|
||||||
|
this.surround = new int[N];
|
||||||
|
|
||||||
|
for (int i=0; i<N; i++){
|
||||||
|
surround[i] = xs[i]+ys[i]*n_boxes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
int N = 4;
|
||||||
|
int[] xs= new int[N];
|
||||||
|
int[] ys= new int[N];
|
||||||
|
this.surround = new int[N];
|
||||||
|
|
||||||
|
ys[0] = (n_boxes + y-1)%n_boxes;
|
||||||
|
ys[1] = y;
|
||||||
|
ys[2] = y;
|
||||||
|
ys[3] = (y+1)%n_boxes;
|
||||||
|
xs[0] = x;
|
||||||
|
xs[1] = (n_boxes + x-1)%n_boxes;
|
||||||
|
xs[2] = (x+1) %n_boxes;
|
||||||
|
xs[3] = x;
|
||||||
|
for (int i=0; i<N; i++){
|
||||||
|
surround[i] = xs[i]+(ys[i]*n_boxes);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
src/main/java/com/lotkavolterra/vodkalaterra.iml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
18
src/main/resources/logback.xml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||||
|
|
||||||
|
<Pattern>
|
||||||
|
%-5level %logger{36} - %msg%n
|
||||||
|
</Pattern>
|
||||||
|
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="debug">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
BIN
src/main/resources/pictures/fox.jpg
Normal file
After Width: | Height: | Size: 132 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
BIN
src/main/resources/pictures/rabbit.jpg
Normal file
After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
BIN
src/main/resources/pictures/soil.jpg
Normal file
After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 7 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 7 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 16 KiB |
|
@ -1,494 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
String[] myFileArray = {"pictures/fox.jpeg", "pictures/rabbit.jpeg", "pictures/grass.jpeg", "pictures/desert.jpeg", "pictures/road.jpeg"}; // picture names,, add more
|
|
||||||
String[] myNames = {"fox", "rabbit", "grass", "desert"}; // picture names,, add more
|
|
||||||
|
|
||||||
int n_boxes = 30;
|
|
||||||
int nn = n_boxes *n_boxes;
|
|
||||||
boolean DIAGONAL = false;
|
|
||||||
Box [] boxes = new Box[nn];
|
|
||||||
Neighbours [] neighs = new Neighbours[nn] ;
|
|
||||||
|
|
||||||
// Distributions
|
|
||||||
double rabbits= 0.3;
|
|
||||||
double foxes = 0.3;
|
|
||||||
double desert = 0.15;
|
|
||||||
double grass = 0.15;
|
|
||||||
|
|
||||||
// Elements
|
|
||||||
int FOX = 0;
|
|
||||||
int RABBIT = 1;
|
|
||||||
int GRASS = 2;
|
|
||||||
int DESERT = 3;
|
|
||||||
int ROAD = 4;
|
|
||||||
|
|
||||||
int N_AGENTS = 4;
|
|
||||||
|
|
||||||
// visualization
|
|
||||||
PImage[] images = new PImage[5];
|
|
||||||
PImage[] images_g = new PImage[5];
|
|
||||||
Box [] colors = new Box[5];
|
|
||||||
int WIDTH = 1900;
|
|
||||||
int HEIGHT = 1000;
|
|
||||||
int SIZE = 50;
|
|
||||||
int PIC_SIZE = 80;
|
|
||||||
int TRACES = 40;
|
|
||||||
PFont f;
|
|
||||||
int[] counter = new int[5];
|
|
||||||
int[][] traces = new int[N_AGENTS][TRACES];
|
|
||||||
int box = -1 ;
|
|
||||||
int time = 0;
|
|
||||||
boolean INIT_TODO = true;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void settings() {
|
|
||||||
size(WIDTH, HEIGHT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
|
|
||||||
SIZE = HEIGHT/n_boxes;
|
|
||||||
set_traces();
|
|
||||||
load_image();
|
|
||||||
f = createFont("Arial",16,true);
|
|
||||||
|
|
||||||
for (int t = 0; t < 4; t += 1) {
|
|
||||||
colors[t] = new Box(SIZE*n_boxes+PIC_SIZE*2*(t+1), PIC_SIZE/2, t, PIC_SIZE);
|
|
||||||
} // for
|
|
||||||
} // setup()
|
|
||||||
|
|
||||||
private void initialize() {
|
|
||||||
get_values();
|
|
||||||
normalize_densities();
|
|
||||||
int k=0;
|
|
||||||
for (int j = 0; j < n_boxes; j += 1) {
|
|
||||||
// run over the ys
|
|
||||||
for (int i = 0; i < n_boxes; i += 1) {
|
|
||||||
int type = weighted_type();
|
|
||||||
boxes[k] = new Box(i * SIZE, j * SIZE, type);
|
|
||||||
neighs[k] = new Neighbours(i, j);
|
|
||||||
k++;
|
|
||||||
} // for
|
|
||||||
} // for
|
|
||||||
}
|
|
||||||
private void get_values(){
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private int weighted_type(){
|
|
||||||
float r = random(0,1);
|
|
||||||
if (r < foxes) { return FOX;}
|
|
||||||
else if (r < rabbits+foxes) {return RABBIT;}
|
|
||||||
else if (r < rabbits+foxes+grass) {return GRASS;}
|
|
||||||
else {return DESERT;}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw() {
|
|
||||||
if (INIT_TODO){
|
|
||||||
background(255);
|
|
||||||
fill(255);
|
|
||||||
stroke(0);
|
|
||||||
textSize(60);
|
|
||||||
rect(WIDTH*1/4 ,HEIGHT*1/2,WIDTH/2, PIC_SIZE);
|
|
||||||
fill(0);
|
|
||||||
textAlign(CENTER);
|
|
||||||
text("Scegli la percentuale di volpi e conigli", WIDTH/2, HEIGHT/2 -100);
|
|
||||||
image(images_g[1], WIDTH*1/4 -2 - PIC_SIZE, HEIGHT*1/2 );
|
|
||||||
image(images_g[0], WIDTH*3/4 +2, HEIGHT*1/2 );
|
|
||||||
if (mousePressed){
|
|
||||||
INIT_TODO = false;
|
|
||||||
rect(WIDTH*1/4,HEIGHT*1/2,mouseX -WIDTH/4, PIC_SIZE);
|
|
||||||
rabbits = (float) (mouseX - WIDTH *1/4);
|
|
||||||
rabbits /= WIDTH/2;
|
|
||||||
print(rabbits);
|
|
||||||
print("\n");
|
|
||||||
initialize();
|
|
||||||
mousePressed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (keyPressed == true) {
|
|
||||||
if (key == 'b' || key == 'B') {
|
|
||||||
background(0);
|
|
||||||
INIT_TODO = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delay(20);
|
|
||||||
time += 1;
|
|
||||||
if (mousePressed) {
|
|
||||||
box = get_clicked_box(mouseX, mouseY);
|
|
||||||
if (box > -1) boxes[box].type = ROAD;
|
|
||||||
print("the box", box, " ");
|
|
||||||
print("\n");
|
|
||||||
}
|
|
||||||
if (time > 4) {
|
|
||||||
time = 0;
|
|
||||||
update_grid();
|
|
||||||
update_traces();
|
|
||||||
}
|
|
||||||
background(255);
|
|
||||||
|
|
||||||
|
|
||||||
plot_traces();
|
|
||||||
for (int k = 0; k < 4; k++) {
|
|
||||||
colors[k].make_borders();
|
|
||||||
image(images_g[k],SIZE*n_boxes+PIC_SIZE*2*(k+1), PIC_SIZE/2);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < nn; i++) {
|
|
||||||
boxes[i].display(boxes[i].type);
|
|
||||||
} // for
|
|
||||||
|
|
||||||
// print("size");
|
|
||||||
// print(boxes[0].x);
|
|
||||||
// print(boxes[0].x+boxes[0].w);
|
|
||||||
}
|
|
||||||
} // draw()
|
|
||||||
|
|
||||||
// ===============================================================
|
|
||||||
|
|
||||||
// Initialization
|
|
||||||
private void normalize_densities() {
|
|
||||||
double total = 0.5 / (rabbits + foxes);
|
|
||||||
rabbits *= total;
|
|
||||||
foxes *= total;
|
|
||||||
desert = 0.25;
|
|
||||||
grass = 0.25;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void set_traces(){
|
|
||||||
for (int i = 0; i < TRACES; i += 1) {
|
|
||||||
traces[FOX][i] = (int) foxes;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < TRACES; i += 1) {
|
|
||||||
traces[RABBIT][i] = (int) rabbits;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < TRACES; i += 1) {
|
|
||||||
traces[GRASS][i] = (int) grass;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < TRACES; i += 1) {
|
|
||||||
traces[DESERT][i] = (int) desert;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void load_image(){
|
|
||||||
PImage im ;
|
|
||||||
PImage im_g;
|
|
||||||
for (int x=0; x < 5; x++ ) {
|
|
||||||
im = loadImage(myFileArray[x]);
|
|
||||||
im.resize(SIZE, SIZE);
|
|
||||||
images[x] = im;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int x=0; x < 5; x++ ) {
|
|
||||||
im_g = loadImage(myFileArray[x]);
|
|
||||||
im_g.resize(PIC_SIZE, PIC_SIZE);
|
|
||||||
images_g[x] = im_g;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// count the number of agents from the boxes
|
|
||||||
private void count_boxes(){
|
|
||||||
for (int n=0; n<5; n++) {
|
|
||||||
counter[n] = 0;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < nn; i++) {
|
|
||||||
counter[boxes[i].type] +=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Visualizations: update_traces creates the fading effect on the plots
|
|
||||||
private void update_traces(){
|
|
||||||
count_boxes();
|
|
||||||
for (int j = 0; j < 4; j += 1) {
|
|
||||||
if (TRACES - 1 >= 0) {
|
|
||||||
System.arraycopy(traces[j], 1, traces[j], 0, TRACES - 1);
|
|
||||||
traces[j][TRACES-1] = counter[j];
|
|
||||||
} else {
|
|
||||||
traces[j][TRACES-1] = counter[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void arrow(int x1, int y1, int x2, int y2) {
|
|
||||||
line(x1, y1, x2, y2);
|
|
||||||
pushMatrix();
|
|
||||||
translate(x2, y2);
|
|
||||||
float a = atan2(x1-x2, y2-y1);
|
|
||||||
rotate(a);
|
|
||||||
line(0, 0, -10, -10);
|
|
||||||
line(0, 0, 10, -10);
|
|
||||||
popMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the plots on the right side
|
|
||||||
private void plot_traces() {
|
|
||||||
float mean;
|
|
||||||
strokeWeight((float) 2.5);
|
|
||||||
textSize(20);
|
|
||||||
textAlign(LEFT);
|
|
||||||
stroke(182,22,63);
|
|
||||||
|
|
||||||
// Upper plot with phase space
|
|
||||||
text("Volpi", WIDTH/2 + 2*PIC_SIZE, 2*PIC_SIZE );
|
|
||||||
arrow(WIDTH/2 + 2* PIC_SIZE, HEIGHT/2, WIDTH/2 + 2*PIC_SIZE, 2*PIC_SIZE);
|
|
||||||
stroke(4,54,84);
|
|
||||||
arrow(WIDTH/2 + 2* PIC_SIZE, HEIGHT/2, WIDTH- 2*PIC_SIZE, HEIGHT/2);
|
|
||||||
text("Conigli", WIDTH - 2*PIC_SIZE + 5, HEIGHT/2 );
|
|
||||||
stroke(0);
|
|
||||||
for (int i = 0; i < TRACES-1; i += 1) {
|
|
||||||
if (traces[RABBIT][i] > 0) {
|
|
||||||
line(WIDTH/2+ 2*PIC_SIZE +WIDTH/2 *traces[RABBIT][i]/nn,
|
|
||||||
HEIGHT/2 *(nn-traces[FOX][i])/nn,
|
|
||||||
WIDTH/2+ 2*PIC_SIZE + WIDTH/2 *traces[RABBIT][i+1]/nn ,
|
|
||||||
HEIGHT/2*(nn-traces[FOX][i + 1])/nn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lower plot with pop densities
|
|
||||||
for (int j = 0; j < 4; j += 1) {
|
|
||||||
mean = 0;
|
|
||||||
for (int i = 0; i < TRACES-1; i += 1) {
|
|
||||||
mean += traces[j][i];
|
|
||||||
}
|
|
||||||
mean /= TRACES;
|
|
||||||
if (j==GRASS) {stroke(77,137,99);}
|
|
||||||
else if (j==FOX) {stroke(182,22,63);}
|
|
||||||
else if (j==DESERT) {stroke(244,148,0);}
|
|
||||||
else if (j==RABBIT) {stroke(4,54,84);}
|
|
||||||
|
|
||||||
strokeWeight((float) 2.5);
|
|
||||||
for (int i = 0; i < TRACES-1; i += 1) {
|
|
||||||
if (traces[j][i] > 0) {
|
|
||||||
line(HEIGHT + 200 +i*15,
|
|
||||||
HEIGHT/2 +PIC_SIZE +(10 * PIC_SIZE * (traces[j][i] )/nn),
|
|
||||||
HEIGHT + 200 +i*15+15,
|
|
||||||
HEIGHT/2+ +PIC_SIZE +(10 * PIC_SIZE * (traces[j][i + 1])/nn));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Evolution algorithm
|
|
||||||
private void update_grid(){
|
|
||||||
|
|
||||||
int k =0;
|
|
||||||
//for each box evolve by the rules
|
|
||||||
//run over xs and ys
|
|
||||||
boolean starve;
|
|
||||||
for (int j = 0; j < n_boxes; j += 1) {
|
|
||||||
for (int i = 0; i < n_boxes; i += 1) {
|
|
||||||
// run over the ys
|
|
||||||
// death conditions
|
|
||||||
// fox dies if no rabbits
|
|
||||||
if (boxes[k].type == ROAD) {
|
|
||||||
boxes[k].next = ROAD;
|
|
||||||
}
|
|
||||||
if (boxes[k].type == FOX) {
|
|
||||||
starve = true;
|
|
||||||
for (int n = 0; n < neighs[k].surround.length; n++) {
|
|
||||||
if (boxes[neighs[k].surround[n]].type == RABBIT) {
|
|
||||||
// there is AT LEAST a rabbit, no starvation
|
|
||||||
starve = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (boxes[neighs[k].surround[n]].type == DESERT) {
|
|
||||||
// there is AT LEAST a desert, starvation
|
|
||||||
// break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (starve) {boxes[k].next = DESERT;}
|
|
||||||
}
|
|
||||||
// rabbit dies if no grass
|
|
||||||
if (boxes[k].type == RABBIT) {
|
|
||||||
starve = true;
|
|
||||||
for (int n = 0; n < neighs[k].surround.length; n++) {
|
|
||||||
if (boxes[neighs[k].surround[n]].type == GRASS) {
|
|
||||||
// there is AT LEAST a grass, no starvation
|
|
||||||
starve = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (starve) {boxes[k].next = DESERT;}
|
|
||||||
}
|
|
||||||
// birth conditions
|
|
||||||
// fox is born eating rabbit
|
|
||||||
if (boxes[k].type == RABBIT) {
|
|
||||||
for (int n = 0; n < neighs[k].surround.length; n++) {
|
|
||||||
if (boxes[neighs[k].surround[n]].type == FOX) {
|
|
||||||
boxes[k].next = FOX;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// rabbit is born eating grass
|
|
||||||
if (boxes[k].type == GRASS) {
|
|
||||||
for (int n = 0; n < neighs[k].surround.length; n++) {
|
|
||||||
if (boxes[neighs[k].surround[n]].type == RABBIT) {
|
|
||||||
boxes[k].next = RABBIT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// grass grows where desert
|
|
||||||
if (boxes[k].type == DESERT) {
|
|
||||||
for (int n = 0; n < neighs[k].surround.length; n++) {
|
|
||||||
if (boxes[neighs[k].surround[n]].type == GRASS) {
|
|
||||||
boxes[k].next = GRASS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
k = 0;
|
|
||||||
for (int j = 0; j < n_boxes; j += 1) {
|
|
||||||
// run over the ys
|
|
||||||
for (int i = 0; i < n_boxes; i += 1) {
|
|
||||||
boxes[k].type = boxes[k].next;
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int get_clicked_box(int x, int y){
|
|
||||||
int box =-1;
|
|
||||||
for (int i = 0; i < nn; i += n_boxes) {
|
|
||||||
if (boxes[i].y < y && y < +boxes[i].yend) {
|
|
||||||
print(i);
|
|
||||||
for (int j = 0; j < n_boxes; j += 1) {
|
|
||||||
if (boxes[j+i].x < x && x < + boxes[j+i].xend){
|
|
||||||
box = j+i;
|
|
||||||
print(boxes[j+i].y, " ", y, " ", boxes[j+i].yend, i, " ");
|
|
||||||
print(boxes[j+i].x, " ", x, " ", boxes[j+i].xend, i, " ");
|
|
||||||
print("\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return box;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class Box {
|
|
||||||
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float xend;
|
|
||||||
float yend;
|
|
||||||
|
|
||||||
float w=SIZE;
|
|
||||||
float h=SIZE;
|
|
||||||
|
|
||||||
int type;
|
|
||||||
int next;
|
|
||||||
|
|
||||||
|
|
||||||
// constr
|
|
||||||
|
|
||||||
Box ( float x, float y, int type, int size) {
|
|
||||||
this.x=x;
|
|
||||||
this.y=y;
|
|
||||||
this.w = size;
|
|
||||||
this.h = size;
|
|
||||||
this.xend=x+size;
|
|
||||||
this.yend=y+size;
|
|
||||||
this.type =type;
|
|
||||||
this.next =type;
|
|
||||||
} // constr
|
|
||||||
Box ( float x, float y, int type) {
|
|
||||||
this.x=x;
|
|
||||||
this.y=y;
|
|
||||||
this.type =type;
|
|
||||||
this.next =type;
|
|
||||||
this.xend=x+this.w;
|
|
||||||
this.yend=y+this.h;
|
|
||||||
} // constr
|
|
||||||
|
|
||||||
void make_borders() {
|
|
||||||
int j = type;
|
|
||||||
if (j==GRASS) {stroke(77,137,99);}
|
|
||||||
else if (j==FOX) {stroke(182,22,63);}
|
|
||||||
else if (j==DESERT) {stroke(244,148,0);}
|
|
||||||
else if (j==RABBIT) {stroke(4,54,84);}
|
|
||||||
strokeWeight(10);
|
|
||||||
rect(x, y, w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
void display(int n) {
|
|
||||||
image(images[n], x, y);
|
|
||||||
}
|
|
||||||
} // class
|
|
||||||
|
|
||||||
class Neighbours {
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int [] surround;
|
|
||||||
|
|
||||||
Neighbours( int x, int y) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
if (DIAGONAL) {
|
|
||||||
int N = 8;
|
|
||||||
int[] xs= new int[N];
|
|
||||||
int[] ys= new int[N];
|
|
||||||
|
|
||||||
ys[0] = (n_boxes + y-1)%n_boxes;
|
|
||||||
ys[1] = ys[0];
|
|
||||||
ys[2] = ys[0];
|
|
||||||
ys[3] = y; ys[4] = y;
|
|
||||||
ys[5] = (y+1)%n_boxes;
|
|
||||||
ys[6] = ys[5];
|
|
||||||
ys[7] = ys[5];
|
|
||||||
|
|
||||||
xs[0] = (n_boxes + x-1)%n_boxes;
|
|
||||||
xs[1] = x;
|
|
||||||
xs[2] = (x+1) %n_boxes;
|
|
||||||
xs[3] = xs[0]; xs[4] =xs[2];
|
|
||||||
xs[5] = xs[0];
|
|
||||||
xs[6] = x;
|
|
||||||
xs[7] = xs[2];
|
|
||||||
|
|
||||||
this.surround = new int[N];
|
|
||||||
|
|
||||||
for (int i=0; i<N; i++){
|
|
||||||
surround[i] = xs[i]+ys[i]*n_boxes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
int N = 4;
|
|
||||||
int[] xs= new int[N];
|
|
||||||
int[] ys= new int[N];
|
|
||||||
this.surround = new int[N];
|
|
||||||
|
|
||||||
ys[0] = (n_boxes + y-1)%n_boxes;
|
|
||||||
ys[1] = y;
|
|
||||||
ys[2] = y;
|
|
||||||
ys[3] = (y+1)%n_boxes;
|
|
||||||
xs[0] = x;
|
|
||||||
xs[1] = (n_boxes + x-1)%n_boxes;
|
|
||||||
xs[2] = (x+1) %n_boxes;
|
|
||||||
xs[3] = x;
|
|
||||||
// print("\n##");
|
|
||||||
for (int i=0; i<N; i++){
|
|
||||||
surround[i] = xs[i]+(ys[i]*n_boxes);
|
|
||||||
}
|
|
||||||
// print("\n##\n");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|