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