organism #3
@ -33,35 +33,46 @@
|
|||||||
|
|
||||||
MatrixPanel_I2S_DMA *matrix = nullptr;
|
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 NUM_AGENTS 64
|
||||||
#define AGENT_MOVE_DISTANCE 1
|
#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 {
|
typedef struct {
|
||||||
int x_position;
|
int x_position;
|
||||||
int y_position;
|
int y_position;
|
||||||
float heading;
|
float heading;
|
||||||
} SlimeAgent;
|
} SlimeAgent;
|
||||||
|
|
||||||
uint16_t attractant[PANEL_WIDTH][PANEL_HEIGHT] = {};
|
uint8_t attractant[PANEL_WIDTH][PANEL_HEIGHT] = {};
|
||||||
|
int iterations = 0;
|
||||||
SlimeAgent agents[NUM_AGENTS];
|
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(){
|
void setup(){
|
||||||
Serial.begin(BAUD_RATE);
|
Serial.begin(BAUD_RATE);
|
||||||
@ -85,80 +96,51 @@ void setup(){
|
|||||||
matrix->setBrightness8(64);
|
matrix->setBrightness8(64);
|
||||||
matrix->fillScreenRGB888(0, 0, 0);
|
matrix->fillScreenRGB888(0, 0, 0);
|
||||||
|
|
||||||
//for(int i = 0; i < BLOB_POINTS; i++) {
|
init_agents();
|
||||||
// //float angle = (360 / BLOB_POINTS) * (i+1);
|
init_attractant();
|
||||||
// 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; x<PANEL_WIDTH; x++) {
|
|
||||||
for(int y = 0; y<PANEL_HEIGHT; y++){
|
|
||||||
attractant[x][y] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int interpolate(int from, int to, float percent) {
|
|
||||||
int difference = to - from;
|
|
||||||
return from + ( difference * percent );
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_bezier(int x1, int y1, int x2, int y2, int x3, int y3) {
|
|
||||||
// draw lines to p2
|
|
||||||
//matrix->drawLine(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) {
|
bool is_in_bounds(int x, int y) {
|
||||||
return (x < PANEL_WIDTH) and (y < PANEL_HEIGHT) and (x >= 0) and (y >= 0);
|
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<PANEL_WIDTH; x++) {
|
||||||
|
for(int y = 0; y<PANEL_HEIGHT; y++){
|
||||||
|
if (attractant[x][y] > 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() {
|
void loop() {
|
||||||
matrix ->flipDMABuffer();
|
matrix ->flipDMABuffer();
|
||||||
//matrix->clearScreen();
|
//matrix->clearScreen();
|
||||||
matrix->fillScreenRGB888(15, 0, 10);
|
matrix->fillScreenRGB888(15, 0, 10);
|
||||||
// draw grid
|
|
||||||
|
|
||||||
int h_lines = PANEL_HEIGHT / 7;
|
// draw background and organism
|
||||||
int v_lines = PANEL_WIDTH / 7;
|
draw_bg();
|
||||||
for(int i = 0; i < PANEL_WIDTH; i++) {
|
draw_attractant();
|
||||||
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; x<PANEL_WIDTH; x++) {
|
|
||||||
for(int y = 0; y<PANEL_HEIGHT; y++){
|
|
||||||
matrix->drawPixel(x, y, attractant[x][y]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int a = 0; a < NUM_AGENTS; a++) {
|
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
|
// motor step
|
||||||
// check if agent can move forward
|
// check if agent can move forward
|
||||||
float target_x = agents[a].x_position + cos(agents[a].heading) * AGENT_MOVE_DISTANCE;
|
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)) {
|
if (is_in_bounds(move_x, move_y)) {
|
||||||
agents[a].x_position = move_x;
|
agents[a].x_position = move_x;
|
||||||
agents[a].y_position = move_y;
|
agents[a].y_position = move_y;
|
||||||
|
if (attractant[move_x][move_y] != 255) {
|
||||||
attractant[move_x][move_y] += AGENT_DROP_AMOUNT;
|
attractant[move_x][move_y] += AGENT_DROP_AMOUNT;
|
||||||
|
}
|
||||||
} else {
|
} 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
|
// sample step
|
||||||
int front_x = round(agents[a].x_position + cos(agents[a].heading) * AGENT_MOVE_DISTANCE);
|
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 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_x = round(agents[a].x_position + cos(agents[a].heading - (AGENT_ANGLE * (PI * 2))));
|
||||||
int left_y = round(agents[a].y_position + cos(agents[a].heading - ((random(0,30) / 100.0) * (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 + ((random(0,30) / 100.0) * (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 + cos(agents[a].heading + ((random(0,30) / 100.0) * (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 front_value = attractant[front_x][front_y];
|
||||||
int left_value = attractant[left_x][left_y];
|
int left_value = attractant[left_x][left_y];
|
||||||
int right_value = attractant[right_x][right_y];
|
int right_value = attractant[right_x][right_y];
|
||||||
if (front_value > right_value and front_value > left_value) {
|
if (front_value > right_value and front_value > left_value) {
|
||||||
;
|
;
|
||||||
} else 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) {
|
} else if (left_value > right_value) {
|
||||||
agents[a].heading -= ((random(0,30) / 100.0) * (PI * 2));
|
agents[a].heading -= AGENT_ANGLE * (PI * 2);
|
||||||
} else {
|
} else {
|
||||||
agents[a].heading += ((random(0,30) / 100.0) * (PI * 2));
|
agents[a].heading += AGENT_ANGLE * (PI * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delay(10);
|
||||||
//for(int i = 0; i < BLOB_POINTS; i+=2) {
|
iterations++;
|
||||||
// int end_offset = i + 2;
|
if (iterations >= NUM_ITERATIONS) {
|
||||||
// if ( end_offset >= BLOB_POINTS) {
|
init_attractant();
|
||||||
// end_offset = 0;
|
init_agents();
|
||||||
// }
|
iterations = 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user