|
|
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 |
}
|