Charles.Forsyth20060303a828770d19 years agoHistory
2180 lines · 37.5 KB · Brainfuck
RawDownload
##	initially generated by c2l# implement Collide; include "draw.m";	draw: Draw;	Display, Image: import draw; Collide: module{	init: fn(nil: ref Draw->Context, argl: list of string);}; include "sys.m";	sys: Sys;include "tk.m";	tk: Tk;	Toplevel: import tk;include "tkclient.m";	tkclient: Tkclient;include "math.m";	maths: Math;include "rand.m";	rand: Rand;include "daytime.m";	daytime: Daytime;include "bufio.m";include "arg.m";	arg: Arg;include "math/polyhedra.m";	polyhedra: Polyhedra; init(ctxt: ref Draw->Context, argl: list of string){	sys = load Sys Sys->PATH;	draw = load Draw Draw->PATH;	tk = load Tk Tk->PATH;	tkclient = load Tkclient Tkclient->PATH;	maths = load Math Math->PATH;	rand = load Rand Rand->PATH;	arg = load Arg Arg->PATH;	daytime = load Daytime Daytime->PATH;	main(ctxt, argl);} π: con Math->Pi;∞: con real (1<<30);ε: con 0.001;√2: con 1.4142135623730950488016887242096980785696718753769486732; M1: con 1.0;M2: con 1.0;E: con 1.0;	# coefficient of restitution/elasticity COLLIDE, REFLECT: con 1<<iota; MAXX, MAXY: con 512; RDisp: ref Draw->Image;black, white, red: ref Draw->Image;display: ref Draw->Display;toplev: ref Toplevel; Vector: adt{	x: real;	y: real;	z: real;}; Line: adt{	a: Vector;	d: Vector;		# normalized}; Plane: adt{	id: int;	n: Vector;		# normalized	d: real;	min: Vector;	max: Vector;	far: Vector;	v: array of Vector;}; Object: adt{	id: int;	poly: ref Polyhedra->Polyhedron;	# if any	c: ref Draw->Image;		#  colour 	cb: ref Draw->Image;	#  border colour	l: ref Line;				#  initial point and direction 	p: Vector;				#  current position	rp: Vector;			# position after reflection	cp: Vector;			# any collision point	rt: real;				# time to reflection	ct: real;				# time to collision	plane: ref Plane;		# reflecting off	pmask: int;			# plane mask	obj: cyclic ref Object;	# colliding with	v: real;				#  speed	ω: real;				# speed of rotation	roll: real;				# roll	pitch: real;			# pitch	yaw: real;				# yaw	todo: int;				# work to do}; planes: list of ref Plane; V0: con Vector(real 0, real 0, real 0);VZ: con Vector(0.0, 0.0, 1.0); far: Vector; DOCIRCLE: con 1;POLY, FILLPOLY, CIRCLE, FILLCIRCLE, ELLIPSE, FILLELLIPSE: con iota; ##  final object is centred on (0, 0, -objd)#  viewer is at origin looking along (0 0 -1)#  maxx, maxy: int; SCRW: con 320;	#  screen widthSCRH: con 240;		# screen height frac := 0.5;	# % of screen for cubefront := 0.5;	# % of cube in front of screenhpar := 0.0;	# horizontal parallaxfov := -1.0;	# field of view : 0 for parallel projection, -1 for unspecifiedobjd := 500.0;	# eye to middle of cubecubd := 100.0;	# half side of cubeicubd: real;	# half side of inner cubeicubd2: real;	# square of aboveeyed := 32.0;	# half eye to eyetrkd := 5.0;	# side/diameter of objecttrkd2: real;	# square of aboverpy := 0;roll := 0.0;		# zpitch := 0.0;	# yyaw := 0.0;	# x scrd, objD, scrD: real;	# screen distanceleft := 0;		# left or right eyesx, sy, sz: real;	#  screen scale factors sf: real;		#  perspective scale factor fbpar: real;	#  -1 for front of cube, 1 for backvf := 1.0;		# current velocity factor cmin, cmax: Vector;	# cube extents #  special transformation matrix without roll, pitch, yaw #  this is needed so that spheres can be drawn as circles mod0 := array[4] of array of real; stereo := 0;	# stereopsis SPHERE, ELLIPSOID, CUBE, POLYHEDRON: con iota;surr := CUBE;	# surround poly := 0;		# show polyhedraflat: int;		# objects in one planeprojx: int;		# strange projection # ellipse parametersef: Vector = (1.0, 0.8, 1.0);e2: Vector; # objectsnobjs: int;objs: array of ref Object;me: ref Object; # circle drawingNC: con 72;cost, sint: array of real; # polyhedrapolys: ref Polyhedra->Polyhedron;npolys: int;polyh: ref Polyhedra->Polyhedron; rgba(r: int, g: int, b: int, α: int): ref Image{	c := draw->setalpha((r<<24)|(g<<16)|(b<<8), α);	return display.newimage(((0, 0), (1, 1)), display.image.chans, 1, c);} random(a: int, b: int): int{	return a+rand->rand(b-a+1);} urand(): real{	M: con 1000;	return real random(0, M)/real M;} randomr(a: real, b: real): real{	return a+urand()*(b-a);} randomc(): ref Image{	r, g, b: int; 	do{		r = random(0, 255);		g = random(0, 255);		b = random(0, 255);	}while(r+g+b < 384);	return rgba(r, g, b, 255);} randomv(a: real, b: real): Vector{	x := randomr(a, b);	y := randomr(a, b);	if(flat)		return (x, y, (a+b)/2.0);	return (x, y, randomr(a, b));} randomd(): Vector{	M: con 1000.0;	v := randomv(-M, M);	while(vlen(v) == 0.0)		v = randomv(-M, M);	return vnorm(v);} randomp(min: real, max: real): Vector{	case(surr){		SPHERE =>			return vmul(randomd(), max*maths->sqrt(urand()));		ELLIPSOID =>			return vmul(randomd(), max*vmin(ef)*maths->sqrt(urand()));		CUBE =>			return randomv(min, max);		* =>			v := randomv(min, max);			while(outside3(v, cmin, cmax))				v = randomv(min, max);			return v;	}} det(a: real, b: real, c: real, d: real): real{	return a*d-b*c;} simeq(a: real, b: real, c: real, d: real, e: real, f: real): (real, real){	de := det(a, b, c, d);	return (det(e, b, f, d)/de, det(a, e, c, f)/de);} cksimeq(a: real, b: real, c: real, d: real, e: real, f: real): (int, real, real){	ade := de := det(a, b, c, d);	if(ade < 0.0)		ade = -ade;	if(ade < ε)		return (0, 0.0, 0.0);	return (1, det(e, b, f, d)/de, det(a, e, c, f)/de);} ostring(o: ref Object): string{	return lstring(o.l) + "+" + vstring(o.p) + "+" + string o.v;} pstring(p: ref Plane): string{	return vstring(p.n) + "=" + string p.d;} lstring(l: ref Line): string{	return vstring(l.a) + "->" + vstring(l.d);} vstring(v: Vector): string{	return "(" + string v.x + " " + string v.y + " " + string v.z + ")";} vpt(x: real, y: real, z: real): Vector{	p: Vector; 	p.x = x;	p.y = y;	p.z = z;	return p;} vdot(v1: Vector, v2: Vector): real{	return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z;} vcross(v1: Vector, v2: Vector): Vector{	v: Vector; 	v.x = v1.y*v2.z-v1.z*v2.y;	v.y = v1.z*v2.x-v1.x*v2.z;	v.z = v1.x*v2.y-v1.y*v2.x;	return v;} vadd(v1: Vector, v2: Vector): Vector{	v: Vector; 	v.x = v1.x+v2.x;	v.y = v1.y+v2.y;	v.z = v1.z+v2.z;	return v;} vsub(v1: Vector, v2: Vector): Vector{	v: Vector; 	v.x = v1.x-v2.x;	v.y = v1.y-v2.y;	v.z = v1.z-v2.z;	return v;} vmul(v1: Vector, s: real): Vector{	v: Vector; 	v.x = s*v1.x;	v.y = s*v1.y;	v.z = s*v1.z;	return v;} vdiv(v1: Vector, s: real): Vector{	v: Vector; 	v.x = v1.x/s;	v.y = v1.y/s;	v.z = v1.z/s;	return v;} vlen(v: Vector): real{	return maths->sqrt(vdot(v, v));} vlen2(v: Vector): (real, real){	d2 := vdot(v, v);	d := maths->sqrt(d2);	return (d, d2);} vnorm(v: Vector): Vector{	d := maths->sqrt(vdot(v, v));	if(d == 0.0)		return v;	return vmul(v, real 1/d);} vnorm2(v: Vector): (real, Vector){	d := maths->sqrt(vdot(v, v));	if(d == 0.0)		return (0.0, VZ);	return (d, vmul(v, real 1/d));} clip(x: real, d: real): real{	if(x < -d)		x = -d;	if(x > d)		x = d;	return x;} vclip(v: Vector, d: real): Vector{	c: Vector; 	c.x = clip(v.x, d);	c.y = clip(v.y, d);	c.z = clip(v.z, d);	return c;} vout(v1: Vector, v2: Vector): int{	v := vsub(v2, v1);	return v.x < 0.0 || v.y < 0.0 || v.z < 0.0;} vmin(v: Vector): real{	m := v.x;	if(v.y < m)		m = v.y;	if(v.z < m)		m = v.z;	return m;} vvmul(v1: Vector, v2: Vector): Vector{	v: Vector; 	v.x = v1.x*v2.x;	v.y = v1.y*v2.y;	v.z = v1.z*v2.z;	return v;} vvdiv(v1: Vector, v2: Vector): Vector{	v: Vector; 	v.x = v1.x/v2.x;	v.y = v1.y/v2.y;	v.z = v1.z/v2.z;	return v;} vmuldiv(v1: Vector, v2: Vector, v3: Vector): real{	return vdot(vvdiv(v1, v3), v2);} newp(id: int, a: real, b: real, c: real, d: real, m: real, v: array of Vector){	p := ref Plane;	p.id = id;	p.n = (a, b, c);	p.d = d;	m += ε;	p.min = (-m, -m, -m);	p.max = (+m, +m, +m);	p.v = v;	if(v != nil){		p.min = (∞, ∞, ∞);		p.max = (-∞, -∞, -∞);		for(i := 0; i < len v; i++){			vtx := v[i];			if(vtx.x < p.min.x)				p.min.x = vtx.x;			if(vtx.y < p.min.y)				p.min.y = vtx.y;			if(vtx.z < p.min.z)				p.min.z = vtx.z;			if(vtx.x > p.max.x)				p.max.x = vtx.x;			if(vtx.y > p.max.y)				p.max.y = vtx.y;			if(vtx.z > p.max.z)				p.max.z = vtx.z;		}		(x, y, z) := p.far = vmul(p.max, 2.0);		if(a != 0.0)			p.far.x = (d-b*y-c*z)/a;		else if(b != 0.0)			p.far.y = (d-c*z-a*x)/b;		else if(c != 0.0)			p.far.z = (d-a*x-b*y)/c;		else			fatal("null plane");	}	planes = p :: planes;} pinit(){	case(surr){		SPHERE or		ELLIPSOID =>			newp(0, 0.0, 0.0, 1.0, ∞, ∞, nil);		CUBE =>			newp(0, 1.0, 0.0, 0.0, -icubd, icubd, nil);			newp(1, 1.0, 0.0, 0.0, +icubd, icubd, nil);			newp(2, 0.0, 1.0, 0.0, -icubd, icubd, nil);			newp(3, 0.0, 1.0, 0.0, +icubd, icubd, nil);			newp(4, 0.0, 0.0, 1.0, -icubd, icubd, nil);			newp(5, 0.0, 0.0, 1.0, +icubd, icubd, nil);

Lines 1–500 of 2180.