#include #include #include #include #include #include #include "neutronlib.h" int bumpsig = 0; struct sphere { double x; // x position double y; // y position double r; // radius can also be z position for depth double m; // mass double v; // movement vector amplitude total double vx; // and in x direction normalized double vy; // and in y direction normalized double vxt; // unnormalized x movement vector double vyt; // unnormalized y movement vector double rad; // movement vector direction int hue; // color double trans; // degree of transparency int bumpc; // Bump control int id; int bumper; // id of the last bumper void shovec(void) { // Show the direction vector double a = x, b = y, xx = 0, ln = r + (r * v); while(xx++ < ln){ putpixel(a, b, hue); a += vx; b += vy; } } void Circle(double radius){ double inc = 1.0 / (radius * trans); // Amount of transparency double circle = 0; while(circle < 2 * PI){ putpixel(x + cos(circle) * radius, y + sin(circle) * radius, hue); circle += inc; } } void show(void){ double xx = 0, savehue = hue, savetrans = trans; while(xx++ < r){ // Save the color and transparency Circle(xx); hue += 0x010101; trans += .01; } hue = savehue; // Restore color and transparency trans = savetrans; } void getrad(void){ // Get radian from movement vectors rad = acos(vx / vxt * vyt); if(vx > 0){ rad = 2 * PI - rad; } rad += PI / 2; } void move(void){ // Move along the radian and bounce off walls if(x + r > maxx){ rad = PI - rad; x = maxx - r; } if(x - r < minx){ rad = PI - rad; x = minx + r; } if(y + r > maxy){ rad = 2 * PI - rad; y = maxy - r; } if(y - r < miny){ rad = 2 * PI - rad; y = miny + r; } vx = cos(rad); // Get movement vectors from radian vy = sin(rad); vxt = vx * v; vyt = vy * v; x += vxt; // Move along movement vectors y += vyt; } void init(void){ x = rand() % (maxx - 100); y = rand() % (maxy - 100); r = rand() % 100 + 10; m = r * r; rad = rand() % 7; hue = rand() % 0xffffff; v = rand() % 10 + .5; trans = .1; bumper = -1; } void getv(void){ v = sqrt(vxt * vxt + vyt * vyt); // Set movement vectors vx = vxt / v; vy = vyt / v; } void bump(sphere & sp){ double dx = x - sp.x; double dy = y - sp.y; double sr = r + sp.r; if(dx * dx + dy * dy > sr * sr){ if(bumper == sp.id){ bumper = -1; sp.bumper = -1; } // Lose last bumper return; // No bump exit } if(bumper == sp.id){ vx *= 1.50; return; } double dc = sqrt(dx * dx + dy * dy); // Distance between centers double nx = dx / dc; double ny = dy / dc; // Calculate change in double a1 = vxt * nx + vyt * ny; // momentum and use that double a2 = sp.vxt * nx + sp.vyt * ny; // to get new radians and double op = (2 * (a1 - a2)) / (m + sp.m); // velocities for a bounce vxt = vxt - op * sp.m * nx; // true to physics. vyt = vyt - op * sp.m * ny; sp.vxt = sp.vxt + op * m * nx; sp.vyt = sp.vyt + op * m * ny; getv(); sp.getv(); getrad(); // Get new radians sp.getrad(); if(sp.hue > 0){ hue = sp.hue; } if(sp.r > 20){ sp.hue = color; } if(bumpc < 20){ bumpc ++; } if(bumpc == 19){ hue = 0xff0000; } if(sp.bumpc == 19){ sp.hue = 0x0000ff; } if(bumpc > 19){ bumpc = 0; color = rand() % 0xffffff; } if(bumper < 0 || sp.bumper < 0){ bumper = sp.id; sp.bumper = id; } } }; int main(int argc, char **argv) { char c; int x, y, x1, y1, c2, chunk = 0; maxx = 1920; maxy = 1100; int spqty = 100; int vis = 2; time_t seconds; seconds = time (NULL); unsigned int sec = seconds; srand(sec); sphere sp[spqty]; for(x = 0; x < spqty; x++){ sp[x].init(); sp[x].id = x; } double xx, cosrad; int ofst, sfst; init_screen(maxx, maxy); color = sec % 0xffffff; ColorFill(color, maxx, maxy); while(1){ ColorFill(color, maxx, maxy); for(x = 0; x < vis; x ++){ sp[x].shovec(); sp[x].show(); sp[x].move(); for(y = x + 1; y < vis; y++) { sp[y].bump(sp[x]); } } c = keystroke(); if(c == 'q') break; if(c == 'w') SDL_Delay(10000); if(c == 'm' && vis < spqty) vis ++; if(c == 'l' && vis > 1) vis --; if(c == 'v'){ color = rand() % 0xffffff; } if(c == 'n'){ color = 0x000000; } if(c == '1'){ vis = 1; } if(c == 'b'){ for(x = 0; x < vis; x++) sp[x].hue = 0xffffff; } if(c == 'u'){ for(x = 0; x < vis; x++) sp[x].hue += 0x010101; } if(c == 'i'){ seconds = time (NULL); sec = seconds; srand(sec); for(x = 0; x < spqty; x++) sp[x].init(); } if(c == 't'){ seconds = time (NULL); sec = seconds % 0xffffff; for(x = 0; x < spqty; x ++){ sp[x].hue = seconds; } } SDL_UpdateRect(screen, minx, miny, maxx, maxy); if(bumpsig == 1){ SDL_Delay(5000); bumpsig = 0; } SDL_Delay(10); } SDL_Quit(); }