#include <u.h>
#include <libc.h>
#include <bio.h>
#include <draw.h>
#include "galaxy.h"
Vector o, gv;
double
d = 100, drand,
sz = 25, szrand,
v, vrand,
av, avrand;
int new, c = 1;
void quadcalc(Body*, QB, double){}
Image *randcol(void){ return nil; }
void
usage(void)
{
fprint(2, "Usage: %s [-d dist[±r]]\n\t[-s size[±r]] [-v vel[±r]]\n\t[-av angvel[±r]] [-gv xdir,ydir]\n\t[-o xoff,yoff] [-f file]\n\t[-sq] [-i] size\n", argv0);
exits("usage");
}
Vector
polar(double ang, double mag)
{
Vector v;
v.x = cos(ang)*mag;
v.y = sin(ang)*mag;
return v;
}
Vector
getvec(char *str)
{
Vector v;
v.x = strtod(str, &str);
if(*str != ',')
usage();
v.y = strtod(str+1, nil);
return v;
}
double
getvals(char *str, double *rand)
{
Rune r;
double val;
int i;
val = strtod(str, &str);
i = chartorune(&r, str);
if(r == L'±')
*rand = strtod(str+i, nil);
else
*rand = 0;
return val;
}
#define RAND(r) ((r)*(frand()*2 - 1))
void
mkbodies(double lim)
{
Body *b;
Vector p;
double x, y;
for(x = -lim/2; x < lim/2; x += d)
for(y = -lim/2; y < lim/2; y += d) {
p.x = x + RAND(drand);
p.y = y + RAND(drand);
if(c)
if(hypot(p.x, p.y) > lim/2)
continue;
b = body();
b->Vector = p;
b->v = polar(frand()*π2, v+RAND(vrand));
b->v.x += gv.x - p.y*(av + RAND(avrand))/1000;
b->v.y += gv.y + p.x*(av + RAND(avrand))/1000;
b->size = sz + RAND(szrand);
}
}
void
main(int argc, char **argv)
{
static Biobuf bout;
Body *b;
double lim;
int fd;
char *a;
srand(truerand());
fmtinstall('B', Bfmt);
glxyinit();
ARGBEGIN {
case 'f':
fd = open(EARGF(usage()), OREAD);
if(fd < 0)
sysfatal("Could not open file %s: %r", *argv);
readglxy(fd);
close(fd);
break;
case 'i':
readglxy(0);
break;
case 's':
a = EARGF(usage());
switch(a[0]) {
case 'q':
if(a[1] != '\0')
usage();
c = 0;
break;
default:
sz = getvals(a, &szrand);
break;
}
break;
case 'a':
a = EARGF(usage());
if(a[0] != 'v' || a[1] != '\0')
usage();
argc--;
argv++;
av = getvals(*argv, &avrand);
break;
case 'g':
a = EARGF(usage());
if(a[0] != 'v' || a[1] != '\0')
usage();
argc--;
argv++;
gv = getvec(*argv);
break;
case 'v':
v = getvals(EARGF(usage()), &vrand);
break;
case 'o':
o = getvec(EARGF(usage()));
break;
case 'd':
d = getvals(EARGF(usage()), &drand);
break;
} ARGEND
if(argc != 1)
usage();
new = glxy.nb;
lim = strtod(*argv, nil);
mkbodies(lim);
Binit(&bout, 1, OWRITE);
for(b = glxy.a; b < glxy.a + new; b++)
Bprint(&bout, "%B\n", b);
for(b = glxy.a+new; b < glxy.a+glxy.nb; b++) {
b->x += o.x;
b->y += o.y;
Bprint(&bout, "%B\n", b);
}
Bterm(&bout);
exits(nil);
}