/* meow @-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-@ | | * * | | * * | | * * | | *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* */ #include #include #include #include #include // read #include // read #include // read const int RED=1; const int GREEN=2; const int YELLOW=3; const int BLUE=4; const int PURPLE=5; const int CYAN=6; // Width and height of universe. int WIDTH = 1600, HEIGHT = 840; /*----------------------------------------------------------------------------- Want to create *-----*-----* Masses with forces between them. In this case I guess the masses are connected by springs. They're Allowed free movement when less than the spring distance but feel a force when beyond it relative to the spring tension. Should make for an interesting simulation. Two data structures. Masses and springs. Springs connect to masses. and vice versa. A spring can only connect to two masses but a mass might connect to 0 or more springs. -----------------------------------------------------------------------------*/ typedef struct { int id; double y, x; // position double m; // mass double j, i; // velocity int color; // color double ly, lx; // last position } mass; typedef struct { mass *a, *b; // The two masses this spring connects. double length, // The length of the spring that a force begins to be felt. tension; // The strength of said force. } spring; // Scanned character map int charMapHeight=0; char *charMapRows[1024]; int massesCount=0; mass masses[1024]; int springsCount=0; spring springs[1024]; //----------------------------------------------------------------------------- double square (double i) { return i * i; } // Render a mass. void plot (mass *m) { printf ("[%d;%dH[0;3%dm ", ((int)m->ly)%HEIGHT, ((int)m->lx*1+WIDTH/WIDTH)%WIDTH, m->color); printf ("[%d;%dH[1;3%dm*", ((int)m->y)%HEIGHT, ((int)m->x*1+WIDTH/WIDTH)%WIDTH, m->color); m->ly = m->y; m->lx = m->x; } // Updates mass' position according to its velocity. void momentum (mass *m) { if (m->m >= 1000000) return; m->y += m->j; m->x += m->i; // Deal with drag. if (m->j < 0.0) m->j += 0.000020; else m->j -= 0.000020; if (m->i < 0.0) m->i += 0.000020; else m->i -= 0.000020; } // Given a spring, update its masses momentum. void pull (spring *s) { mass *a = s->a, *b = s->b; double ang, // Angle between two points. y, // Y force direction x, // X force direction d; // Force distance // Compute component and cartesian distance between two points. y = a->y - b->y; x = a->x - b->x; d = sqrt(y*y + x*x); a->j += 0.001; b->j += 0.001; // If spring being pulled, apply equal and opposite force to masses. if (d > s->length) { a->j -= y*square(d-s->length) * s->tension; a->i -= x*square(d-s->length) * s->tension; b->j += y*square(d-s->length) * s->tension; b->i += x*square(d-s->length) * s->tension; } else if (d < s->length) { a->j += y*square(d-s->length) * s->tension * 5; a->i += x*square(d-s->length) * s->tension * 5; b->j -= y*square(d-s->length) * s->tension * 5; b->i -= x*square(d-s->length) * s->tension * 5; } } /* Scan file into character field. */ int scan (void) { FILE *f; char buff[1024]={0}, done=0; f = fopen("rubber.c", "r"); fscanf(f, "/*%[^\n]%*c", buff); /* Skip initial comment line. */ printf ("[%s]\n", buff); while (!done) { /* Scan line and deal with an empty one. */ if (0 == fscanf(f, "%[^\n]%*c", buff)) fgetc(f), *buff=0; if (!strncmp(buff, "*/", 2)) done++; else { charMapRows[charMapHeight] = (char*)strdup(buff); printf ("%3d[%s]\n", charMapHeight, charMapRows[charMapHeight]); charMapHeight++; } } return 0; } /* Scan field for masses. */ int findMasses (void) { int y, x, c=0; for (y=0; y victim->y) victim = masses+i; } else { victim = masses+i; //printf ("*"); } } } return victim; } mass *findRight (int y, int x) { int i; mass *victim=NULL; for (i=0; i= x) { if (victim) { if (masses[i].x < victim->x) victim = masses+i; } else { victim = masses+i; //printf ("*"); } } } return victim; } mass *findLeft (int y, int x) { int i; mass *victim=NULL; for (i=0; i victim->x) victim = masses+i; } else { victim = masses+i; //printf ("*"); } } } return victim; } mass *findDown (int y, int x) { int i; mass *victim=NULL; for (i=0; i= y) { if (victim) { if (masses[i].y < victim->y) { victim = masses+i; //printf ("*"); } } else { victim = masses+i; //printf ("*"); } } } return victim; } void incrementMassMomentum (mass *mass, float j, float i) { if (mass) { mass->j += j; mass->i += i; //printf ("\n%s: %f %f", __func__, j, i); } else printf ("\n%s: No mass to increase momentum of.", __func__); } int findForces (void) { int y, x; for (y=0; y') incrementMassMomentum(findRight(y,x), 0, .1); else if (charMapRows[y][x]=='v')incrementMassMomentum(findDown(y, x), .1, 0); else if (charMapRows[y][x]=='<')incrementMassMomentum(findLeft(y, x), 0,-.1); else if (charMapRows[y][x]=='^')incrementMassMomentum(findUp(y, x) ,-.1, 0); } } } /* Find springs in field and connect two closest masses. */ int findSprings (void) { mass *a, *b; int y, x; for (y=0; yid, (springs[i].b)->id, springs[i].length, springs[i].tension); } int main (void) { int m; scan(); findMasses(); findForces(); findSprings(); debugDumpMasses(); setbuf(stdout,0); printf ("[?25l"); for (;;) { for (m=0; m