# How to do the Geometry Wars gravity well effect

I'm not talking about the background grid here, I'm talking about the swirly particles going around the Gravity Wells! I've always liked the effect and decided it'd be a fun experiment to replicate it, I know GW uses Hooke's law all over the place, but I don't think the Particle-to-Well effect is done using springs, it looks like a distance-squared function.

Here is a video demonstrating the effect: http://www.youtube.com/watch?v=YgJe0YI18Fg

I can implement a spring or gravity effect on some particles just fine, that's easy. But I can't seem to get the effect to look similar to GWs effect. When I watch the effect in game it seems that the particles are emitted in bunches from the Well itself, they spiral outward around the center of the well, and eventually get flung outward, fall back towards the well, and repeat.

How would I make the particles spiral outward when spawned? How would I keep the particle bunches together when near the Well but spread away from each other when they're flung outward? How would I keep the particles so strongly attached to the Well?

EDIT:
https://dl.dropbox.com/u/49283213/gw.gif <- GIF of the particle path

I disabled the randomization within GW to make the particle effect easier to see, here's a minute video where you can see a blue-green drain sending out it's bunch of particles. The red particles are from the explosions that normally appear all over the place. Some observations I made from the video:

• The particles are emitted from the center (or near center) of the drain
• All particles are being forced into a clockwise motion around the center so some sort of tangential motion is being applied, you can easily see this when the red explosion particles get close to the drain.

From the video showed it just seems to be plain gravity to me. Most people think gravity makes things flying downwards, but looking at it from a more far away perspective it makes things fly in a elliptical or spiral kind of motion around the center. The particles are always accelerated towards the center, however fly beyond it until the gravity forces it to come back, again and again. Some particles fly so far that the gravity doesn't affect them so much anymore and end up burning out before changing their direction.

Each particle has a X and Y velocity, to which each frame the gravity is added to, depending on the angle and distance to the center. The gravity always adds velocity into the direction (angle) of the center.

So you have for the particle: position, velocity
For the gravity well you have: position, strength

From the positions you can calculate the angle between the particle and the gravity well. To calculate the angle you'll need the deltas between the two coordinates.

dx = particle.x - gravity.x; dy = particle.y - gravity.y
angle = atan2(dy, dx)


This angle is the angle of the velocity vector that needs to be added.

The amount of force that is applied depends on the distance. To be exact it decreases by the square of the distance. So if something is twice as far away only a fourth of force is applied. For the distance the deltas are required too.

distance = sqrt(dx*dx + dy*dy)
force = gravity.strength / distance*distance


Now you have the force and the angle you just need to apply them:

particle.velocity.x += force * sin(angle)
particle.velocity.y += force * cos(angle)

• your solution is quite similar to mine, but it uses atan, sin, cos, sqrt, ... so it might get very slow. it's better to avoid the atan/sin/cos part, see my post to se one (maybe not the best) do to it faster. Sep 30 '12 at 12:59
• It's not optimized so it's better understandable. Sep 30 '12 at 13:59
• you are right to do so, but i guess the answer is of much more use, especially for those not strong in cos/sin things, if you put the 'optimised' pseudo-code after the theorical explanation. Sep 30 '12 at 15:12
• I realize the code here is not optimized, but it appears that you can avoid the sqrt() call on the distance, since you immediately use it a moment later by squaring it. Jun 12 '14 at 7:31

it seems to me that what is drawn is segments, not points. So i guess the Well ejects a point of the circle, with a high speed and a speed vector tangent to the circle. And another point is thrown just after, which is linked to the first one to draw a segment. Then i think laws of physics (Newton) are applied with a strong gravity, which explains the speed decrease. So i guess you have to integrate on time to do this.

with : C the center of the well, R its radius.
P1 the point we're looking at
K being a 'big' constant that you choose with some trials (mass of the well).
vel0 is the initial velocity vector, tangential to the circle.
vel0 must be high(do trials too)
pos0 the initial position, on the circle, at time t0.
: d the distance beetween C and P1
: Vn the normed vector C P1

accx= - Vnx * K * 1 / square(d)   ; accy = - Vny * K * 1/square (d)
velx = accx*(t-t0) + vel0x   ;   vely = accy(t-t0) + vel0y
posx= (1/2)*accx*square(t-t0) + vel0x*(t-t0) + pos0x   ;
posy= (1/2)*accx*square(t-t0) + vel0y*(t-t0) + pos0y


Init : Most easy way to go to spawn a new point is to choose an angle A, then :

  pos0x= Cx +R *cos(A)  ; pos0y = Cy + R*sin(A)
vel0x = v0*sin(A)   vel0y =  - v0*cos(A)     v0= float constant.


update : for each iteration you have to compute :

d= square root( square(P1x-Cx)+square(P1y-Cy) )
Vnx= (P1x-Cx)/d   ;   Vny=(P1y-Cy)/d
acc (accx,accy) and finally pos (posx, posy)  as described above.


no need to compute speed.
maybe the game use some kind of friction, then the equation would be different.
notice that you use several times cos(A) and sin(A), so store them.

so if you spawn a lot of points linked two by two and at the same time you change initial angle A to have the segment source rotate around the well, you come pretty close from the solution i guess.

Edit : i think you should give a try to this without friction first, it might be ok. friction is a force which is proportionnal to speed, but having reversed vector direction. so the equation becomes :

    Acc = Gravity force + Friction Force.


with Friction Force = - constant * Vel. this i don't know how to integrate, so i would go for a step by step integration :

   Vel(t+dt) = vel(t) + acc(t)*dt,
pos(t+dt)= pos(t)+ vel(t)*dt.


there WILL be numerical stability issue, but since the life time of particules is short, this should not be an issue.

• What would have to change about the equation under the influence of friction? I have a couple solutions to that issue but I'm interested to hear yours. Sep 30 '12 at 11:45

I finally did it, a satisfactory replication of the particle behavior.

The effect IS a standard gravity effect with a twist, when the particles get within a certain range a force is applied on the tangent normal. this causes the particles to "orbit" in a rather unstable fashion. The particles in the processing sketch don't burn out, but at the apex of their orbit this is when they would burn out and another bunch would be released. Thanks all for your help, even if it didn't really provide me with any new information, it's highly appreciated that you'd put the time and effort you did into your answers. Thanks again!