Browse Source

src added

alequa 3 years ago
commit
03290feb3b

+ 12 - 0
GiocoPopolazioni.iml

@@ -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 - 0
src/META-INF/MANIFEST.MF

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

+ 30 - 0
src/main/java/com/lotkavolterra/Bar.java

@@ -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 - 0
src/main/java/com/lotkavolterra/Button.java

@@ -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 - 0
src/main/java/com/lotkavolterra/Densities.java

@@ -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 - 0
src/main/java/com/lotkavolterra/Graphs.java

@@ -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 - 0
src/main/java/com/lotkavolterra/PopulationModel.java

@@ -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 - 0
src/main/java/com/lotkavolterra/Slider.java

@@ -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 - 0
src/main/java/com/lotkavolterra/Structs.java

@@ -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 - 0
src/main/java/com/lotkavolterra/vodkalaterra.iml

@@ -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 - 0
src/main/resources/logback.xml

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


BIN
src/main/resources/pictures/grass.jpeg


BIN
src/main/resources/pictures/rabbit.jpg


BIN
src/main/resources/pictures/road.jpeg


BIN
src/main/resources/pictures/soil.jpg