src added

This commit is contained in:
alequa 2021-04-10 21:13:20 +02:00
commit 03290feb3b
16 changed files with 711 additions and 0 deletions

12
GiocoPopolazioni.iml Normal file
View file

@ -0,0 +1,12 @@
<?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$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="core" level="project" />
</component>
</module>

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

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

View 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;
}
}

View 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;
}
}

View 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;
};
}

View 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
}

View 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);
// }
}

View 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;
}
}

View 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);
}
}
}
}
}

View 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>

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB