Gravity hole: Objects moving near a hole, shifts its projection towards the hole

I’m just curious.

You know that golf holes in any games that “attracts, or sucks, balls into/towards the hole” game mechanic?

I find games in space, such as Angry Birds Space on Android produces some zones in which objects spins around the planet when interacting with gravity, intriguing with gravity involved. Like how black holes interact with objects, how gravity distorts the original velocity vector of an object towards the center, etc.

I’m curious about:

  • What is the name for the “gravity hole” game mechanic? (Depicted as such in the picture.) I would like to know the most generic name, so I can find it easily on Google.
  • How it was done exactly? Does one rotate the dot product of (the normalized vector from center of hole to point of collision) and (speed vector of any object within range of the gravity hole) towards the center of the hole?

It’s Gravitational Physics.

The effect? Nope, not rotating for the most part. It’s more a build up of velocities based on the acceleration imparted by objects on objects. You’re not really ‘rotating’ anything (Of course, due to the way that most objects function in these circumstances a rotation does occur, however that’s a side-effect, not a cause).

Basically, you do something like: dv = g * mass / distance^2. Then you can figure out the ‘components’ of it by doing dx = sin(angle) * dv, dy = cos(angle) * dv. These are then added to the object’s velocity vector. Rotation happens, to a small extent due to the fact that gravity doesn’t affect the entire object at the same amount. This tends to be very negligible, instead more of it comes from the forces of drag/other atmospheric/friction based considerations.

In your image the ‘Yellow’ zone is really just the point at which the dv formula actually starts to apply a change in velocity that is noticeable (Due to the distance^2, far away objects are relatively unaffected), however the objects still feel them.

Increase the speed of the object toward the whole. The magnitude of the speed increases as the object gets closer.

If you’ve got vertical and horizontal speeds, find out their components and magnitude with sin and cos based on the distance between the hole and the object (magnitude of speed).

I don’t know if this phenomenon has a specific name for games. Ideally you don’t have to rotate anything since it’s a centripetal force, i.e, it happens automatically.

I thought the entire process can be done by vector calculations, instead of using sines, cosines, and angles.

It’s trippy, but I guess my curiosity is fulfilled.

The only problem left is the search term that allows me to search around on Google. I see that, other than using physics to describe it, there aren’t anything on Google that points me to a few Java examples.

You can do it with vectors too. Just add the gravity vector to the objects displacement vector.

The gravity vector which direction is towards the “gravity hole” and the magnitude is based on the distance between the “gravity hole” and the object.

See: http://www.youtube.com/watch?v=xp6ibuI8UuQ

What you are looking for can be done with springs. Google spring physics and Hooke’s law and it should take you in the right direction. It shouldn’t be too hard to inplement if you’ve got a good physics engine as a base.

Spring force (approximately) increases linearly with distance while gravity decreases quadratically with distance.

Yes, but the example tom_mai78101 is using is a golf game, as he states is “´attracts, or sucks, balls into/towards the hole´ game mechanic”. When an object is in the yellow zone you let a spring force work on the object. It the force of the object is weaker than the spring it will “magnetise” itself to the center, else it will just change the objects course as it enters and leaves the yellow zone. I might not be gravity, but I belive it´s an relatively easy solution to the problem. Why wouldn´t this work?

Note that it’s not just any golf games. It could be any space themed games.

By continuing this discussion further, I would like to try taking such a challenge and be able to get this mock Java code up on here:

public void suckIntoHole(Ball b, Hole h){
		//Note that (x,y) for Ball and Hole are given at the top left corner.
		float ballRadius = b.diameter /2;
		float holeRadius = 16;
		//Give the correct difference of the two objects' position.
		float dx = b.position[0] - h.x + (ballRadius + holeRadius);
		float dy = b.position[1] - h.y + (ballRadius + holeRadius);
		//Find the angle of the line of collision
		double angle = Math.atan2(dx, dy);
		//Change the angle of the speed vector to the line of collision.
		double lx = b.speed[0]*Math.cos(angle)-b.speed[1]*Math.sin(angle);
		double ly = b.speed[1]*Math.cos(angle)+b.speed[0]*Math.sin(angle);
		//Set the new speeds to the current speed.
		b.speed[0] = (float) lx;
		b.speed[1] = (float) ly;
		//And then set the new position on the line of collision to the object's position.
		b.position[0] = (float)(lx*Math.cos(-angle)-ly*Math.sin(-angle));
		b.position[1] = (float)(ly*Math.cos(-angle)+lx*Math.sin(-angle));
	}

My hypothesis is like this:

But in practice, the ball went awkward… And didn’t quite bend around the hole like I expected.

I don’t really understand that graph :o

I made a little sample applet. All I do is add the speed vector to the position vector.

The “hard” part is figuring out the x and y components of the pull. Which you can do with sin and cos on the magnitude of the pull. You get the angle needed by the angle between the objects. I wasn’t bothered I simply took the delta of the objects positions and added a fraction of that to the speed.

[applet archive=gravity.jar class=com.jonjava.Apple.class width=320 height=180]

left and right click to add particles, middle click (wheel) to make a massive immovable.

Hmm… the [applet] tag doesn’t work.

It is an interesting insight. I guess I went ahead and thought things out differently than I expected.

Very intresting applet.
The problem with your implementation is (I fist didn’t know you are able to right-click on it to make things appear), that if you create a lot of object on one position, then wait for it to drive off, the more far away you put new “particles” the faster they move to the gravitation center.

So to put it in an easier sentence: The farer away your particles are from each other, the stronger the gravity is between them.

That’s totally logical. You used the fraction of the delta vector and added that one to the position. So when does this vector get larger? Of course when the total delta is getting bigger.

I increase the speed with the difference in distance towards every other particle. Actually, yeah, the further away the faster the speed is increased :o

I noticed something as soon as I try the implementation. The balls will eventually go towards the hole, but very slowly, while it’s bouncing around and around the hole.

I tried tweaking it, so that if the ball gets closer and closer to the hole, the speed increases. I realized that if I were to hit the balls affected by the gravity pull with my cue ball, the balls ignore their current position and continues to move around, despite my cue balls changing their positions directly.

This behavior isn’t what I wanted, and they seemed to be off by many factors. I’ve been tweaking it until I fell asleep on the keyboard, so I must’ve been thinking too hard on this problem.

Here’s the current tweaked code:

public void gravityPull(Hole h){
		double dx = (this.position[0] - h.x);
		double dy = (this.position[1] - h.y);
		dx *= 0.00000001;
		dy *= 0.00000001;
		this.speed[0] += (float) 0.9 * dx - 1;
		this.speed[1] += (float) 0.9 * dy - 1;
	}

EDIT:

Actually, I’m adding buffers to this. If we look at this one-dimensionally, for example, on the X axis, we could see that the values tend to increase/decrease around the targeted X value (where the hole is located on the X axis). The values go up and down, as show here.

What I’m doing is to try to make it so that when the ball goes past the targeted X value, and slow down, just like the red graph shown above.

I thought that if I give the Dx and Dy values a bit more intensity, it will work. But that is not the case.

Well the “correct” way of calculating the pull’s strength is from Newtons:

Where r is the distance between them ( this is not the same as taking the difference between the objects x and y position )

http://t1.gstatic.com/images?q=tbn:ANd9GcQIGDBcbF-FE44IleBfkiGwifep5tOEteK36sWa3_IqmxrJASYz

This is where you use pythagoras famous “a^2 + b^2 = c^2” and conclude that the distance is

http://t1.gstatic.com/images?q=tbn:ANd9GcS26hYJkC3EAVJaiWZVjLo0dKz7lz9r3n3aJZh7q2Ly6jVJZIMo

Once you have the distance you can insert it to the

for r.

G is the gravitational constant ( change this to determine how fast/slow you want the gravitation to be ).

m1 and m2 are the masses of the objects. The larger the mass, the bigger it pulls.

Once you have the magnitude/strength of the pull (using

) you then have to split it to its horizontal ( x ) and vertical ( y ) components. Then add it to the speed vectors.

[EDIT]: Actually I’ll update my applet to incorporate this. My lazy delta x and y positions just confuses everyone.

[Updated]: controls: left and right click to add particles, middle click (wheel) to make a massive immovable.

The last problem I noticed immediately is my inability to split the gravity push/pull force into X and Y vectors on the Cartesian coordinates.

Line of pseudo-code process:


final double G;

//......

deltaX = a.position[0] - b.position[0];
deltaY = a.position[1] - b.position[1];
distance = Math.hypot(deltaX, deltaY);
angle = Math.atan2(deltaX, deltaY);

//We set both the mass to 1
force = G * a.mass * b.mass / (distance * distance);

//I suck at separating a singularity vector into 2 perpendicular vectors.
x = force * Math.cos(angle);
y = force * Math.sin(angle);

God forbids me to get a good job. sigh

Anyway, I’ll check your source codes and will update my own version of integration tomorrow. 11:25PM, signing out.

Sounds like you’re wanting to simulate something like a gravity well, where an object is caught in the gravity field of a larger more massive object and is pulled inwards. Jonjava above does a good job of explaining the physics involved, i’d like to try and take it a tiny bit further.

Once you calculate the force due to gravity on the smaller object, F, i think its useful to use this to calculate the acceleration on the object, since F = mass x acceleration, and work with acceleration instead of F alone. This way you can just use the acceleration value to update the velocity, then use the new velocity value to update the x and y position co-ordinates of the object.

If you call m1 the mass of the larger more massive object, and m2 as the mass of the smaller orbiting object, then the acceleration of m2 is found by the following…

http://www.bahill.net/fma2.jpg

If m1 is much larger than m2, then the above shows that you can effectively drop the value of m2 from the calculation of acceleration due to gravity on m2.

Once you have the acceleration, you find it’s horizontal and vertical components. You’ve already nailed that in your code above using trig and the angle.

In each frame just keep adding the horizontal and vertical components of the acceleration to the horizontal and vertical components of the object’s velocity, and in turn add these velocity components to the x and y position co-ordinates of the object to simulate the effect of gravity, though rather roughly. A more accurate simulation would include higher order integration factors to accommodate the effects of a variable acceleration rate.

If you’re having bother splitting a vector into its horizontal and vertical components, check out the applet I knocked up to help visualise this at the link below. Click the mouse left button and drag it around the screen to see a vector and its horizontal and vertical components.

http://www.bahill.net/myApplet.html

Hope all that makes sense and is of some help to you,

cheers,

Bahill