Sperm Demo (Iris version)
Paul Andrew Olbrich
po0o+ at andrew.cmu.edu
Wed Apr 3 08:03:37 AEST 1991
Try this!
-------
/*
glsperm.c
Drew Olbrich, February 1991
Compile with:
cc -O sperm.c -o sperm -lgl_s -lm
*/
#include <stdio.h>
#include <math.h>
#include "gl.h"
#include "device.h"
typedef double POINT[2];
typedef double VECTOR[2];
#define VEC_DOT(x, y) (x[0]*y[0] + x[1]*y[1])
#define VEC_LEN(x) (sqrt(x[0]*x[0] + x[1]*x[1]))
#define VEC_SET(x, a, b) x[0] = a, x[1] = b
#define VEC_COPY(y, x) y[0] = x[0], y[1] = x[1]
#define VEC_NEG(x) x[0] = -x[0], x[1] = -x[1]
#define VEC_ADD(z, x, y) z[0] = x[0] + y[0], z[1] = x[1] + y[1]
#define VEC_SUB(z, x, y) z[0] = x[0] - y[0], z[1] = x[1] - y[1]
#define VEC_MULT(x, a) x[0] *= a, x[1] *= a
#define VEC_DIV(x, a) x[0] /= a, x[1] /= a
#define VEC_ADDS(z, x, a, y) z[0] = x[0] + (a)*y[0], z[1] = x[1] + (a)*y[1]
#define VEC_NORM(x) { double l = VEC_LEN(x); VEC_DIV(x, l); }
#define COUNT 200
#define WIN_X 1280
#define WIN_Y 1024
typedef struct {
POINT x;
VECTOR v;
double sine, cosine;
double vel;
} SPERM;
SPERM sperm[COUNT];
double rad_scale = 3.5;
int index = 0;
double frand()
{
return (rand() % 16384)/16384.0;
}
init_display()
{
ginit();
prefsize(WIN_X, WIN_Y);
prefposition(0, WIN_X - 1, 0, WIN_Y - 1);
foreground();
winopen("sperm");
doublebuffer();
linewidth(3);
gconfig();
}
init_sperm()
{
int i;
double angle;
for (i = 0; i < COUNT; i++)
{
sperm[i].x[0] = frand()*WIN_X;
sperm[i].x[1] = frand()*WIN_Y;
VEC_SET(sperm[i].v, 0.0, 0.0);
angle = frand()*10.0 + 5.0;
sperm[i].sine = sin(angle*M_PI/180.0);
sperm[i].cosine = cos(angle*M_PI/180.0);
sperm[i].vel = frand()*4.0 + 4.0;
}
}
dynamics()
{
int i;
VECTOR w, old_w;
POINT p;
double r, dot, temp;
int org_x, org_y;
VECTOR origin, mouse;
int x1, y1, x2, y2;
VECTOR target;
getorigin(&org_x, &org_y);
VEC_SET(origin, (double) org_x, (double) org_y);
mouse[0] = getvaluator(MOUSEX);
mouse[1] = getvaluator(MOUSEY);
VEC_SUB(mouse, mouse, origin);
for (i = 0; i < COUNT; i++)
{
x1 = (int) sperm[i].x[0];
y1 = (int) sperm[i].x[1];
VEC_COPY(target, mouse);
VEC_SUB(w, sperm[i].x, target);
VEC_NORM(w);
VEC_COPY(old_w, w);
w[0] = old_w[0]*sperm[i].cosine - old_w[1]*sperm[i].sine;
w[1] = old_w[1]*sperm[i].cosine + old_w[0]*sperm[i].sine;
VEC_ADDS(p, target, rad_scale*(160.0 - sperm[i].vel*20.0), w);
VEC_SUB(w, p, sperm[i].x);
VEC_NORM(w);
VEC_ADDS(sperm[i].v, sperm[i].v, 1.0, w);
VEC_NORM(sperm[i].v);
VEC_MULT(sperm[i].v, sperm[i].vel);
VEC_ADD(sperm[i].x, sperm[i].x, sperm[i].v);
x2 = (int) sperm[i].x[0];
y2 = (int) sperm[i].x[1];
color(BLACK);
move2i(x1, y1);
draw2i(x2, y2);
}
}
main_loop()
{
while (!getbutton(RIGHTMOUSE))
{
color(WHITE);
clear();
dynamics();
swapbuffers();
}
}
main()
{
init_display();
init_sperm();
main_loop();
gexit();
}
More information about the Comp.sys.sgi
mailing list