color[] silvertown_colors = {color(200, 0, 0), color(200, 200, 0), color(0, 200, 0), color(100, 100, 255), color(0, 0, 150)}; int grid_width = 100; int grid_height = 100; int scale = 2; int half_scale = scale/2; int seed_scale = 2; int last_clicked_i = -1; int last_clicked_j = -1; boolean updateMode = false; boolean SINGLE_STEP = false; boolean CONTINUOUS = true; int ruleSet = 0; int LIFE = 0; int SURFACE_TENSION = 1; int SPECIES = 2; int SILVERTOWN = 3; int DURRETT_MODEL1 = 4; int DURRETT_MODEL2 = 5; int DURRETT_MODEL3 = 6; int empty_cells = 0; int mature_cells = 0; int changed_cells = 0; float max_seeds = 0; int years = 0; int graph_height = 100; float[] R; float[] R_adjusted; float i_r_max=0; pArrayQueue[] pop_record; int pop_record_i = 0; int pop_record_step = 1; int pop_record_length = 1000; boolean saved_pop_record = false; void setup(){ size((int)(grid_width * scale) + 1, (int)(grid_height * scale) + 1 + graph_height); noStroke(); pop_record = new pArrayQueue[6]; for(int i = 0; i < pop_record.length; i++){ pop_record[i] = new pArrayQueue(300); } ruleSet = DURRETT_MODEL3; initD3AllThree(); rectMode(CORNER); neighborhoodSetA(5); } void draw(){ // background(0); noStroke(); if(updateMode == CONTINUOUS){ takeAStep(); } if(ruleSet == DURRETT_MODEL3){ int[] column; for(int i = 0; i < grid_width; i++){ column = durrett3_grid[i]; for(int j = 0; j < grid_height; j++){ if(column[j] != 0){ fill(durrett_colors[column[j]]); } else{ fill(0); } rect(i*scale, j*scale, scale, scale); } } } //draw_graph fill(0); noStroke(); rect(0, grid_height*scale, width, height); int record_length = pop_record[1].array.length; float gx_inc = (float)(width) / (float)(record_length); float gx = 0; float p_scale = graph_height; for(int s = 0; s < pop_record.length; s++){ gx = 0; for(int i = 0; i < record_length; i++){ if(ruleSet == DURRETT_MODEL2 || ruleSet == DURRETT_MODEL3){ if(s < silvertown_colors.length-1) stroke(silvertown_colors[s]); } else if(ruleSet == DURRETT_MODEL1 || ruleSet == SILVERTOWN){ if(s < silvertown_colors.length) stroke(silvertown_colors[s]); } point(gx, height - pop_record[s].get(i)/p_scale); gx += gx_inc; } } R = autoCorrelation(pop_record[1].array); R_adjusted = new float[R.length]; record_length = R.length; gx_inc = (float)(width) / (float)(record_length); gx = 0; float r_adjust = R[0]; float r_adjust_inc = (R[0] - R[R.length-1]) / R.length; stroke(0, 150, 0); float r_i = 0; float r_max = r_i; for(int i = 0; i < record_length; i++){ r_i = R[i] - r_adjust; r_i += (float)(R.length)-sq(float(abs(R.length/2 - i))); R_adjusted[i] = r_i; if(r_i > r_max && i > 20 && i < record_length - 20) { r_max = r_i; i_r_max = i; } //point(gx, height - 20 - r_i/10000000); gx += gx_inc; r_adjust -= r_adjust_inc; } stroke(0, 0, 150); line(i_r_max*gx_inc, height, i_r_max*gx_inc, height - graph_height); } void mouseReleased(){ updateMode = !updateMode; } void keyPressed(){ if(key == ' ') { updateMode = SINGLE_STEP; initD3AllThree(); } // tweaks to DURRETT_MODEL3 else if(key == 'v' || key == 'V'){ if(!d3_big_neighborhoods_dominate){ d3_big_neighborhoods_dominate = true; int[][] new_d3_n_x = { n0_x, n0_x, n1_x, n2_x }; // zero argument doesn't matter int[][] new_d3_n_y = { n0_y, n0_y, n1_y, n2_y }; // zero argument doesn't matter d3_n_x = new_d3_n_x; // zero argument doesn't matter d3_n_y = new_d3_n_y; // zero argument doesn't matter } else { d3_big_neighborhoods_dominate = false; int[][] new_d3_n_x = { n0_x, n2_x, n1_x, n0_x }; // zero argument doesn't matter int[][] new_d3_n_y = { n0_y, n2_y, n1_y, n0_y }; // zero argument doesn't matter d3_n_x = new_d3_n_x; // zero argument doesn't matter d3_n_y = new_d3_n_y; // zero argument doesn't matter } } } void takeAStep(){ if(ruleSet == DURRETT_MODEL3){ d3_occupy_vacancies(); d3_spread(); for(int j = 0; j < grid_height; j++){ for(int i = 0; i < grid_width; i++){ durrett3_grid[i][j] = durrett3_grid_new[i][j]; } } for(int i = 0; i < 4; i++){ int pop_insert = populationCount(durrett3_grid, i); pop_record[i].insert(pop_insert); } } } int populationCount(int[][] grid, int s){ int count = 0; for(int j = 0; j < grid_height; j++){ for(int i = 0; i < grid_width; i++){ if(grid[i][j] == s) count++; } } return count; } void neighborhoodSetA(int p){ // inverse relationship between neighborhood size and dominance makeNeighborhood( nrs[p][0], 0); makeNeighborhood( nrs[p][1], 1); makeNeighborhood( nrs[p][2], 2); d3_n_x = new int[][] {n0_x, n0_x, n1_x, n2_x}; // zero argument doesn't matter d3_n_y = new int[][] {n0_y, n0_y, n1_y, n2_y}; // zero argument doesn't matter } void neighborhoodSetB(int p){ makeNeighborhood( nrs[p][2], 0); makeNeighborhood( nrs[p][1], 1); makeNeighborhood( nrs[p][0], 2); d3_n_x = new int[][] {n0_x, n0_x, n1_x, n2_x}; // zero argument doesn't matter d3_n_y = new int[][] {n0_y, n0_y, n1_y, n2_y}; // zero argument doesn't matter }