I was recently struck by the idea that everything in the universe is bound by gravity on a grand (Planets, stars) and minute (Atoms, molecules) scale, so I figured I'd do a little test on simulating gravity in Gmod.
I started off with a bunch of randomly-generated planets and a "sun" which dragged the planets towards it gradually (killing any that got too close), however I noticed that this didn't produce anything like the orbits we see in normal solar systems. However, I did discover by accident when I shifted the origin point of the sun (The E2 chip) that the planets spontaneously acquired a regular circular orbit.
So my next attempt was focused more on roaming particles, with each every element moving and pulling on and being pulled by every other element. How strongly each element was pulled depended of course on the density of the other element. So denser elements could very easily draw in less-dense elements, or very gradually pull together with other dense elements. ("Elements" here refers purely to a simulated object, not actual periodic elements of stars or such)
The way gravity works in this simulator is by directional velocity. Each element starts with an initial velocity, and then each other element pulls the element towards itself by an amount determined based on the element's density and distance by adding the subsequent vector to the element's velocity. As the simulator runs, the elements each move according to their new velocities, causing their directional pulls and positions to change, resulting in some rather surprising displays.
In this simple simulator, I've seen systems occur that resembled binary star systems, that look like ordinary one-star solar systems (As little elements whizz around a dense element), and even different elements pulling together to form a stronger collective gravity well, potentially forming heavier (periodic) elements or stars and black holes, depending on how you interpret the simulation.
And now, the code:
@name Gravity simulator
@persist Units U Base:vector RV
@persist Gr G State Slimit Dist
if(first()){
gSetGroup("atoms")
gDeleteAll()
U=1
Units=10 #Number of units to simulate
Slimit=75 #Speed limit of all units
Base=entity():pos() #Starting point for generation
Dist=1 #Gravity weaken over distance?
RV=1 #Randomised initial velocity
#If disabled, begins travelling from base point
}
if(U<=Units){interval(1000)}
else{runOnTick(1)}
M=0
#Unit generation
while(U<=Units & M<=10){
#Initial position
Vec=randvec()*random(0,1000)
Vec+=Base
#Initial Velocity
if(RV){
Vel=randvec()*random(0,Slimit)
}
else{
Vel=(Base-Vec):normalized()*min(Slimit,Vec:length())
}
gSetVec(U,Vel)
#Density
Den=round(random(0,255))
holoCreate(U,Vec,vec(1,1,1)*2)
holoModel(U,"hqicosphere2")
holoColor(U,vec(1,1,1)*Den)
holoAng(U,Vel:toAngle())
holoEntity(U):setTrails(5,5,10,"trails/plasma",vec(0,1,1)*255,255)
M++,U++
}
#Gravity function
if(tickClk()){
Une=holoEntity(Gr)
Vel=gGetVec(Gr)
Mass=Une:getColor():x()
Vec=Une:pos()
while(G<=Units & M<=30){
Ent=holoEntity(G)
if(G!=Gr & Ent){
Pos=Ent:pos()
Dis=Vec:distance(Pos)
#Gravity elements
Den=Ent:getAlpha() #Density
Rel=(Une:pos()-Pos):normalized() #Relative direction
Vel-=(Rel*(Den/Mass))*(Dist ? (1-min(Dis/700,1)) : 1)
gSetVec(Gr,Vel:normalized()*min(Vel:length(),Slimit))
#Heat
if(Dis<=100){
D=1-(Dis/100)
Hot=vec(1,1,0)*D
#holoColor(Gr,Une:getColor()+Hot)
}
}
M++,G++
}
if(G>=Units){
NP=Une:pos()+Vel
holoPos(Gr,NP)
holoAng(Gr,Vel:toAngle())
Gr=(Gr>=Units ? 1 : Gr+1)
G=0
}
}
Thursday, 28 January 2010
Subscribe to:
Post Comments (Atom)

No comments:
Post a Comment