diff --git a/organism/src/main.cpp b/organism/src/main.cpp index c078de0..b219f0f 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -33,35 +33,46 @@ MatrixPanel_I2S_DMA *matrix = nullptr; -int start_x = 5; -int start_y = 5; -int end_x = 59; -int end_y = 27; - -int anchor_x = 16; -int anchor_y = 24; - -#define BLOB_POINTS 32 -#define BLOB_RADIUS 12 -typedef struct { - int x_coords[BLOB_POINTS]; - int y_coords[BLOB_POINTS]; -} Blob; - - #define NUM_AGENTS 64 #define AGENT_MOVE_DISTANCE 1 -#define AGENT_DROP_AMOUNT 100 +#define AGENT_DROP_AMOUNT 1 +#define AGENT_ANGLE 0.175 +#define NUM_ITERATIONS 1000 typedef struct { int x_position; int y_position; float heading; } SlimeAgent; -uint16_t attractant[PANEL_WIDTH][PANEL_HEIGHT] = {}; +uint8_t attractant[PANEL_WIDTH][PANEL_HEIGHT] = {}; +int iterations = 0; SlimeAgent agents[NUM_AGENTS]; -Blob blob; +void init_attractant() { + memset(attractant, (uint8_t) 0, sizeof attractant); + // draw a circle out of attractant + //for (int p = 0; p < 64; p++) { + // float angle = ((PI * 2) / 64) * p; + // int x = 31 + round(10 * sin(angle)); + // int y = 15 + round(10 * cos(angle)); + // attractant[x][y] = 15; + //} +} + +void init_agents() { + for(int a = 0; a < NUM_AGENTS; a++) { + float angle = ((PI * 2) / NUM_AGENTS) * a; + //agents[a].x_position = 31 + round(10*sin(angle)); + //agents[a].y_position = 15 + round(10*cos(angle)); + // agents[a].heading = ((PI * 2) / NUM_AGENTS) * ); + + agents[a].x_position = random(12, 52); + agents[a].y_position = random(12, 20); + agents[a].heading = (random(0, 100) / 100.0) * (PI*2); + } +} + + void setup(){ Serial.begin(BAUD_RATE); @@ -85,80 +96,51 @@ void setup(){ matrix->setBrightness8(64); matrix->fillScreenRGB888(0, 0, 0); - //for(int i = 0; i < BLOB_POINTS; i++) { - // //float angle = (360 / BLOB_POINTS) * (i+1); - // float angle = ((PI * 2) / BLOB_POINTS) * (i+1); - // blob.x_coords[i] = random(-6, 7) + 31 + round(BLOB_RADIUS * sin(angle)); - // blob.y_coords[i] = random(-2, 7) + 15 + round(BLOB_RADIUS * cos(angle)); - // //blob.x_coords[i] = random(0, 64); - // //blob.y_coords[i] = random(0, 32); - //} - for(int a = 0; a < NUM_AGENTS; a++) { - agents[a].x_position = random(12, 52); - agents[a].y_position = random(12, 20); - agents[a].heading = (random(0, 100) / 100.0) * (PI*2); - } - for(int x = 0; xdrawLine(x1, y1, x2, y2, matrix->color565(16, 16, 16)); - //matrix->drawLine(x2, y2, x3, y3, matrix->color565(16, 16, 16)); - - for (float percent = 0; percent < 1; percent += 0.01) { - int xa = interpolate(x1, x2, percent); - int ya = interpolate(y1, y2, percent); - int xb = interpolate(x2, x3, percent); - int yb = interpolate(y2, y3, percent); - //matrix->drawLine(xa, ya, xb, yb, matrix->color565(0, 128, 0)); - - int x = interpolate(xa, xb, percent); - int y = interpolate(ya, yb, percent); - - matrix->drawPixel(x, y, matrix->color565(106, 95, 219)); - } -} - - bool is_in_bounds(int x, int y) { return (x < PANEL_WIDTH) and (y < PANEL_HEIGHT) and (x >= 0) and (y >= 0); } +void draw_bg() { + int h_lines = round(PANEL_HEIGHT / 7); + int v_lines = round(PANEL_WIDTH / 7); + for(int v = 0; v <= v_lines; v++) { + matrix->drawFastVLine(v*7+2, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); + } + for(int h = 0; h <= h_lines; h++) { + matrix->drawFastHLine(0, 7*h + 1, PANEL_WIDTH, matrix->color565(41, 17, 76)); + } +} + +void draw_attractant() { + for(int x = 0; x 20) { + matrix->drawPixel(x, y, matrix->color565( + int((255.0 / 255.0) * attractant[x][y]), + int((80.0 / 255.0) * attractant[x][y]), + int((83.0 / 255.0) * attractant[x][y]) + ) + ); + } + } + } +} + void loop() { matrix ->flipDMABuffer(); //matrix->clearScreen(); matrix->fillScreenRGB888(15, 0, 10); - // draw grid - int h_lines = PANEL_HEIGHT / 7; - int v_lines = PANEL_WIDTH / 7; - for(int i = 0; i < PANEL_WIDTH; i++) { - if(i % 7 == 2) { - matrix->drawFastVLine(i, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); - } - } - for(int i = 0; i <= h_lines; i++) { - matrix->drawFastHLine(0, 7*i + 1, PANEL_WIDTH, matrix->color565(41, 17, 76)); - } - - for(int x = 0; xdrawPixel(x, y, attractant[x][y]); - } - } + // draw background and organism + draw_bg(); + draw_attractant(); for(int a = 0; a < NUM_AGENTS; a++) { - matrix->drawPixel(agents[a].x_position, agents[a].y_position, attractant[agents[a].x_position][agents[a].y_position]); + //matrix->drawPixel(agents[a].x_position, agents[a].y_position, matrix->color565(0, 0, attractant[agents[a].x_position][agents[a].y_position])); // motor step // check if agent can move forward float target_x = agents[a].x_position + cos(agents[a].heading) * AGENT_MOVE_DISTANCE; @@ -168,57 +150,39 @@ void loop() { if (is_in_bounds(move_x, move_y)) { agents[a].x_position = move_x; agents[a].y_position = move_y; - attractant[move_x][move_y] += AGENT_DROP_AMOUNT; + if (attractant[move_x][move_y] != 255) { + attractant[move_x][move_y] += AGENT_DROP_AMOUNT; + } } else { - agents[a].heading += (random(0,2) *2 -1 ) * (random(0, 30) / 100.0) * PI*2; + agents[a].heading += (random(-1,2) *2 - 1 ) * 30 / 100.0 * PI*2; } // sample step int front_x = round(agents[a].x_position + cos(agents[a].heading) * AGENT_MOVE_DISTANCE); int front_y = round(agents[a].y_position + sin(agents[a].heading) * AGENT_MOVE_DISTANCE); - int left_x = round(agents[a].x_position + cos(agents[a].heading - ((random(0,30) / 100.0) * (PI * 2)))); - int left_y = round(agents[a].y_position + cos(agents[a].heading - ((random(0,30) / 100.0) * (PI * 2)))); - int right_x = round(agents[a].x_position + cos(agents[a].heading + ((random(0,30) / 100.0) * (PI * 2)))); - int right_y = round(agents[a].y_position + cos(agents[a].heading + ((random(0,30) / 100.0) * (PI * 2)))); + int left_x = round(agents[a].x_position + cos(agents[a].heading - (AGENT_ANGLE * (PI * 2)))); + int left_y = round(agents[a].y_position + sin(agents[a].heading - (AGENT_ANGLE * (PI * 2)))); + int right_x = round(agents[a].x_position + cos(agents[a].heading + (AGENT_ANGLE * (PI * 2)))); + int right_y = round(agents[a].y_position + sin(agents[a].heading + (AGENT_ANGLE * (PI * 2)))); int front_value = attractant[front_x][front_y]; int left_value = attractant[left_x][left_y]; int right_value = attractant[right_x][right_y]; if (front_value > right_value and front_value > left_value) { ; } else if (front_value < right_value and front_value < left_value) { - agents[a].heading += (random(0, 2) * 2 - 1) * (random(0, 30) / 100.0) * (PI*2) ; + agents[a].heading += (random(0, 2) * 2 - 1) * (AGENT_ANGLE / 100.0) * (PI*2) ; } else if (left_value > right_value) { - agents[a].heading -= ((random(0,30) / 100.0) * (PI * 2)); + agents[a].heading -= AGENT_ANGLE * (PI * 2); } else { - agents[a].heading += ((random(0,30) / 100.0) * (PI * 2)); + agents[a].heading += AGENT_ANGLE * (PI * 2); } } - - //for(int i = 0; i < BLOB_POINTS; i+=2) { - // int end_offset = i + 2; - // if ( end_offset >= BLOB_POINTS) { - // end_offset = 0; - // } - // draw_bezier(blob.x_coords[i], - // blob.y_coords[i], - // blob.x_coords[i+1], - // blob.y_coords[i+1], - // blob.x_coords[end_offset], - // blob.y_coords[end_offset] - // ); - // matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(128, 128, 128)); - // blob.x_coords[i+1] += random(-1, 2); - // if (blob.x_coords[i+1] >= PANEL_WIDTH) { - // blob.x_coords[i+1] = PANEL_WIDTH - 1; - // } - // if (blob.x_coords[i+1] < 0) { - // blob.x_coords[i+1] = 0; - // } - // //blob.y_coords[i+1] += random(-1, 2); - // //matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(0, 0, 128)); - // //matrix->drawPixel(blob.x_coords[i+1], blob.y_coords[i+1], matrix->color565(128, 0, 0)); - // //matrix->drawPixel(blob.x_coords[end_offset], blob.y_coords[end_offset], matrix->color565(0, 0, 128)); - //} - delay(100); + delay(10); + iterations++; + if (iterations >= NUM_ITERATIONS) { + init_attractant(); + init_agents(); + iterations = 0; + } }