Compare commits

...

No commits in common. "03290feb3b9017f4ec520855709364aaa25dc982" and "b34644733d857c8e26540af950735556f4297ff2" have entirely different histories.

55 changed files with 1541 additions and 698 deletions

3
META-INF/MANIFEST.MF Normal file
View file

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: Predator

View file

@ -7,6 +7,6 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="core" level="project" />
<orderEntry type="library" name="core" level="application" />
</component>
</module>

Binary file not shown.

View file

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: Predator

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

View file

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: Predator

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -1,3 +1,3 @@
Manifest-Version: 1.0
Main-Class: main.java.com.lotkavolterra.PopulationModel
Main-Class: Predator

1003
src/Predator.java Normal file

File diff suppressed because it is too large Load diff

22
src/ProcessingTest.java Normal file
View file

@ -0,0 +1,22 @@
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);
}
}

3
src/Structs.java Normal file
View file

@ -0,0 +1,3 @@
public class Structs {
}

View file

@ -0,0 +1,8 @@
package com.company;
public class Main {
public static void main(String[] args) {
// write your code here
}
}

View file

@ -1,30 +0,0 @@
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;
}
}

View file

@ -1,26 +0,0 @@
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;
}
}

View file

@ -1,16 +0,0 @@
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;
};
}

View file

@ -1,163 +0,0 @@
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
}

View file

@ -1,271 +0,0 @@
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);
// }
}

View file

@ -1,28 +0,0 @@
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;
}
}

View file

@ -1,133 +0,0 @@
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);
}
}
}
}
}

View file

@ -1,11 +0,0 @@
<?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>

View file

@ -1,18 +0,0 @@
<?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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

BIN
src/pictures/desert.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
src/pictures/fox.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

BIN
src/pictures/grass.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
src/pictures/rabbit.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
src/pictures/road.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -0,0 +1,494 @@
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");
}
}
}
//