Gravity free space simulator
- Posted by Lmailles <Lmailles at AOL.COM> May 07, 1998
- 730 views
OK all you game programmers, here is some real physics for you. Please feel free to chop and change, some credit would be nice. You'll want to put your own values in. At the moment it has the earth and the sun. As you know, the earth takes a year to go round the sun so it is not very exciting to watch. You will probably want to make things much closer and then change the SCALE constant. All the others are unchangeable (unless you're feeling like rewriting the laws of physics). The bit at the end where the objects are defined is complete gibberish. I'll explain. An object has the following properties : Mass Position (x,y) Speed (x,y) Bearing (This is the way in which you are pointing, which can be different from the way you are travelling) Engine type and thrust They are defined in a sequence as follows : eg {10000, {93e9,1e6}, {0,1}, {1/2*2*PI,{30000,1}}}, --ship {mass, {x_pos,y_pos}, {x_speed,y_speed}, {bearing, {thrust, thrust_type}}} where bearing is in radians. Thrust type is rocket or nuclear. Only 1 does anything. -----Code starts---- include graphics.e constant grav_const=6.67e-11,PI=3.1416, --ensures no spurious type check failures PLANET_DENSITY=5464.15, X=1,Y=2,MASS=1,POS=2,SPEED=3,BEARING=4, SCALE=1000000000 --metres per pixel constant LEFT=331, RIGHT=333, UP=328, DOWN=336 type angle(atom x) return x>=-PI and x<=PI end type type color(integer x) return x >= 0 and x <= 255 end type type coordinate(sequence c) return atom(c[1]) and atom(c[2]) end type type thrust(sequence t) --{max_power,type} type is 0,1,2 none,rocket,nuclear return atom(t[1]) and t[1]>=0 and integer(t[2]) end type type thing(sequence t) integer temp temp=sequence(t[3]) if temp then temp=atom(t[BEARING][1]) and angle(t[BEARING][1]) and thrust(t[BEARING][2]) end if return atom(t[MASS]) and t[MASS]>0 and coordinate(t[POS]) and coordinate(t[SPEED]) and temp --{mass,{x,y},{xspeed,yspeed},{bearing,{max_thrust,type}}} end type function force(atom mass1,atom mass2,atom distance) return mass1*mass2/power(distance,2)*grav_const end function function tidy_angle(atom a) if a>PI then a=tidy_angle(a-2*PI) elsif a<-PI then a=tidy_angle(a+2*PI) end if return a end function procedure draw(color colour, coordinate xy, atom mass) atom radius radius=power(mass/PLANET_DENSITY/(4/3)/PI,1/3)/SCALE if radius<.5 then pixel(colour,xy) else if radius>10 then radius=10 end if ellipse(colour,1, xy-radius, xy+radius) end if end procedure atom start start=time() procedure simulate(sequence things) sequence but_things, --optimised version of things for simpler processing speed,pos,bearing thing bthing atom accel,xaccel,yaccel,xdist,ydist,mass, dist,tim,othen integer leng,temp,times othen=time() leng=length(things) temp=0 while temp != 27 do while temp != 999 do temp=get_key()+1000 end while times=floor(temp/1000) temp=temp-times*1000 if find(temp,{32,LEFT,RIGHT,UP,DOWN}) then if temp=32 then start=start-(time()-othen)*100*times othen=othen-(time()-othen)*100*times elsif temp=LEFT then things[3][BEARING][1]=tidy_angle(things[3][BEARING][1]-PI/3*ti mes) elsif temp=RIGHT then things[3][BEARING][1]=tidy_angle(things[3][BEARING][1]+PI/3*ti mes) end if end if tim=othen-time() othen=time() position(1,1) printf(1,"%10d",sqrt(power(things[1][SPEED][X],2)+power(things[1][SPEE D][Y],2))/SCALE) printf(1,"%10d %10d",things[1][POS]/SCALE) puts(1,"\n") printf(1,"%10d",sqrt(power(things[2][SPEED][X],2)+power(things[2][SPEE D][Y],2))/SCALE) printf(1,"%10d %10d",things[2][POS]/SCALE) puts(1,"\n") printf(1,"%10d",sqrt(power(things[3][SPEED][X],2)+power(things[3][SPEE D][Y],2))/SCALE) printf(1,"%10d %10d",things[3][POS]/SCALE) --puts(1,"\n") position(1,70) printf(1,"Time %4.1d",time()-start) but_things={} for a=1 to leng do but_things=append(but_things,things[1..a-1]&things[a+1..leng]) end for for a=1 to leng do speed=things[a][SPEED] pos=things[a][POS] mass=things[a][MASS] bearing=things[a][BEARING] accel=bearing[2][1]/mass xaccel=accel*sin(bearing[1]) yaccel=accel*cos(bearing[1]) for b=1 to leng-1 do bthing=but_things[a][b] xdist=bthing[POS][X]-pos[X] ydist=bthing[POS][Y]-pos[Y] dist=sqrt(power(xdist,2)+power(ydist,2)) accel=force(mass,bthing[MASS],dist)*tim/mass xaccel=xaccel+accel*xdist/dist yaccel=yaccel+accel*ydist/dist end for things[a][SPEED][X] = speed[X] + xaccel things[a][SPEED][Y] = speed[Y] + yaccel things[a][POS][X] = pos[X] + things[a][SPEED][X]*tim things[a][POS][Y] = pos[Y] + things[a][SPEED][Y]*tim end for for a=1 to leng do draw(a,(things[a][POS]/SCALE+{320,240}),things[a][MASS]) end for end while end procedure integer temp temp=graphics_mode(18) simulate({ {6e30, {0,0}, {0,0}, {0,{0,0}}}, --sun {6e24, {93e9,0}, {0,2.07442e6}, {0,{0,0}}}, --inner planet {10000, {93e9,1e6}, {0,1}, {1/2*2*PI,{30000,1}}}, --ship {6e24, {3e11,0}, {0,1.15499e6}, {0,{0,0}}} --outer planet })