Blame onefile/stars-smooth.c

261920
261920
#include <math.h></math.h>
261920
#include <string.h></string.h>
261920
#include <helianthus.h></helianthus.h>
261920
261920
261920
#define MAXCOUNT 10000
261920
#define SPEED    1
261920
#define SPS      500
261920
#define PERSP    0.5
261920
261920
261920
typedef struct Star {
261920
  double x, y, z;
261920
  double px, py;
261920
  int visible;
261920
} Star;
261920
261920
Star stars[MAXCOUNT];
261920
double step;
261920
double mx, my;
261920
261920
261920
Framebuffer buffer;
261920
Animation anim;
261920
261920
261920
void update(double dt) {
261920
  double dz = SPEED*dt;
261920
  double sx =  mx*dz*PERSP;
261920
  double sy = -my*dz*PERSP;
261920
  int j = 0, count = 0;
261920
  for(int i = 0; i < MAXCOUNT; ++i) {
261920
    if (stars[i].visible) {
261920
      double x = stars[i].x - sx*stars[i].z;
261920
      double y = stars[i].y - sy*stars[i].z;
261920
      double z = stars[i].z + sx*stars[i].x + sy*stars[i].y;
261920
      stars[i].x = x;
261920
      stars[i].y = y;
261920
      stars[i].z = z - dz;
261920
    } else {
261920
      j = i;
261920
      ++count;
261920
    }
261920
  }
261920
261920
  step += SPS*dt;
261920
  if (count > (int)step) count = (int)step;
261920
  step -= (int)step;
261920
  for(int i = 0; i < count; ++i) {
261920
    while(stars[j].visible) j = (j+1)%MAXCOUNT;
261920
    stars[j].px = 2*randomFloat() - 1;
261920
    stars[j].py = 2*randomFloat() - 1;
261920
    stars[j].z = 1 - randomFloat()*dz;
261920
    stars[j].x = stars[j].px * stars[j].z / PERSP;
261920
    stars[j].y = stars[j].py * stars[j].z / PERSP;
261920
    stars[j].visible = TRUE;
261920
  }
261920
}
261920
261920
261920
void init() {
261920
  background(COLOR_BLACK);
261920
  buffer = createFramebuffer(windowGetWidth(), windowGetHeight());
261920
  anim = createAnimationFromFramebuffer(buffer);
261920
}
261920
261920
261920
void draw() {
261920
  double w = windowGetWidth();
261920
  double h = windowGetHeight();
261920
  double s = 0.5*(w > h ? w : h);
261920
261920
  saveState();
261920
  noStroke();
261920
  target(buffer);
261920
  update(windowGetFrameTime());
261920
261920
  fill(colorByRGBA(0, 0, 0, 0.25));
261920
  rect(0, 0, w, h);
261920
261920
  saveState();
261920
  translate(w/2, h/2);
261920
  zoom(s);
261920
  mx = mouseTransformedX();
261920
  my = mouseTransformedY();
261920
  stroke(COLOR_WHITE);
261920
  double dz = 0.01;
261920
  for(int i = 0; i < MAXCOUNT; ++i) {
261920
    if (stars[i].visible) {
261920
      double z = stars[i].z > dz ? stars[i].z : dz;
261920
      double x = stars[i].x/z*PERSP;
261920
      double y = stars[i].y/z*PERSP;
261920
      double r = 0.25/s/z;
261920
      strokeWidth(r);
261920
261920
      line(stars[i].px, stars[i].py, x, y);
261920
      stars[i].px = x;
261920
      stars[i].py = y;
261920
      stars[i].visible = stars[i].z > dz && fabs(x)-r < 1 && fabs(y)-r < 1;
261920
    }
261920
  }
261920
  restoreState();
261920
261920
  noTarget(buffer);
261920
  fill(COLOR_WHITE);
261920
  rectTextured(anim, 0, 0, w, h);
261920
261920
  restoreState();
261920
}
261920
261920
261920
int main() {
261920
  windowSetSize(1024, 768);
261920
  windowSetVariableFrameRate();
261920
  windowSetInit(&init);
261920
  windowSetDraw(&draw);
261920
  windowRun();
261920
}