circular gravity

Started by
10 comments, last by Bacterius 12 years ago
Hi,

I'm making a game where you walk around a circle, its 2D and the circle is going to be a planet, its kind of like Angry Birds in Space in terms of gravity. At the moment I am rotating my objects to align with the gravity vector which is pointing in to the centre of the planet. This is fine for objects on the planet but then I want to have a rocket ship that leaves the planet so I don't want to set the rotation of the ship to be inline with the planet as I will need to rotate the ship to steer. I'm sure there are also other situations where I will want to rotate objects away from this set rotation.

At the moment I use this function to apply gravity to objects which is a member of my GameObject base class -


public void ApplyGravity(Vector2 planetPosition, float gravityForce, float deltaTime)
{
Vector2 gravity = m_position - planetPosition;
if (gravity.LengthSquared() != 0)
{
gravity.Normalize();
}

gravity *= gravityForce;
// Apply gravity to velocity
m_velocity -= gravity * deltaTime;
// Adjust rotation of object to stick to circle
Vector2 normalisedGravity = gravity;
normalisedGravity.Normalize();
float desiredRotation = (float)Math.Atan2(gravity.Y, gravity.X);

m_rotation = desiredRotation;
m_rotation += MathHelper.ToRadians(90);
}


So just a bit of advice would be nice,

Should I keep it like this for objects on the planet which will want to be rotated to snap to the circle in most cases and then have specific states where the objects are allowed to rotate?

Or is there something I'm missing, maybe some sort of rotational gravity force that is applied to objects to attempt to align them with the planet but still allow some movement if there is a strong enough force in the opposing direction?

Any advice is appreciated, if you would like more info or my explanation was rubbish then just say,

Thanks.

"To know the road ahead, ask those coming back."

Advertisement
Can't really help you, but I'm curious about one thing. Why do you declare normalisedGravity, if you never use it? Just normalising it doesn't seem to justify it's existense :P
Why do you need to rotate objects to apply gravity? You just need to find the gravity force vector from the object's center of mass to the planet's center of mass (which is just the normalized line between the object and the planet, scaled by the gravity force) and add that to the object's current forces. The point of using vectors instead of angles is that you do not, in fact, need to rotate anything - vector algebra does everything for you.

So you have one gravity force which is exerted on objects at all times, and one reaction force from the planet's surface (of equal and opposite force) to prevent objects which are on the surface from sinking into the ground. Then for your rocket, you just give it a force outwards of the planet which is greater than the gravity force, thus the rocket's net force will be away from the planet, i.e. the rocket will rise slowly and gain speed (if it remains at constant acceleration).

Then to steer the rocket you just change the rocket's acceleration vector (thus modifying the direction of the force applied on it), which will cause it to turn in that direction. You may need angles *here* by breaking down the rocket's velocity (NOT acceleration) vector into two components, finding which angle the rocket is going at, and modifying the angle to steer accordingly.

Besides if you start hacking in fixes to account for buggy gravity, your game will probably end up with unrealistic physics. You really want to do everything properly here because bad gravity is extremely noticeable - as an example players can sense something is wrong when their character takes 50 milliseconds too much to land to the ground after jumping, so imagine how obvious it would be with a rocket.

If you want physics that work like in real life (or at least bear some resemblance to that) you need to implement Newtonian physics into your game. It's not very hard but there are some gotchas.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

Thanks for the replies


Can't really help you, but I'm curious about one thing. Why do you declare normalisedGravity, if you never use it? Just normalising it doesn't seem to justify it's existense tongue.png

Yeah I know, sorry, I just copied and pasted the code from my project, I think I was messing around with different things, that should have been excluded for this example.

@Bacterius
- thank you, I understand what you are saying and I think what you are describing is what I had originally, the reason why things are rotated is so they stick the circumference of the circle, for example when the player character is on the planet and you press left or right you travel around the circle so he needs to rotate as he goes round, what you describe doesn't seem to take this into consideration, do you have any ideas about how I might achieve this effect?

"To know the road ahead, ask those coming back."

Why not use the actual equation for gravity. 0f36df929ac9d711a8ba8c5658c3bfee.png,(courtesy of Wikipedia) Since F=ma you can solve for the acceleration of each object by solving for the force and then dividing by the mass of the object being moved. I wrote this code and never ended up even testing it out so there are without a doubt some trig errors and general logic mistakes but you may use this as an outline.

public void accelerateDueToGravityAtAPoint(BaseObject object1,BaseObject object2)
{
float dist = object1.getPosition().dist(object2.getPosition());
float force = (float) (GRAVITATIONAL_CONSTANT *((object1.getMass()+ object2.getMass()) / Math.pow(dist,2)));

if(object1.isStatic() == false)
{
float angle = (float) Math.atan(
(object1.getPosition().y-object2.getPosition().y)/
(object1.getPosition().x-object2.getPosition().x));

object1.setAcceleration(new Vector2(
(float)(force/object1.getMass()*Math.cos(angle)), //x component of the acceleration f/m
(float)(force/object1.getMass()*Math.sin(angle))));//y component of the acceleration f/m
}
if(object2.isStatic() == false)
{
float angle = (float) Math.atan(
(object2.getPosition().y-object1.getPosition().y)/
(object2.getPosition().x-object1.getPosition().x));

object2.setAcceleration(new Vector2(
(float)(force/object2.getMass()*Math.cos(angle)),
(float)(force/object2.getMass()*Math.sin(angle))));
}
}
final float GRAVITATIONAL_CONSTANT = 0.00012f;


If you want your objects to rotate around their center of mass due to the force of gravity pulling them you could look at torque caused on the objects.

t =rfsin(o) // since there is no torque arm just is a constant like 1 or so for r
t = Ia //I is rotational inetia and a is rotational acceleration
Ia = rfsin(o)
a = (rfsin(o)/I

you can calculate intertia I as either a disk or a spere if you want(google rotational inertia it isn't complicated)

Then just update the objects angular velocity basted on the angular acceleration
and update your objects angular position based on that.
- thank you, I understand what you are saying and I think what you are describing is what I had originally, the reason why things are rotated is so they stick the circumference of the circle, for example when the player character is on the planet and you press left or right you travel around the circle so he needs to rotate as he goes round, what you describe doesn't seem to take this into consideration, do you have any ideas about how I might achieve this effect?[/quote]
It does, actually. When you walk around on the circle, the "movement" force acting on the object is broken down into X and Y components, which are not cancelled equally by the gravity force as it's not in the same direction. The result is the object sticks to the surface of the planet (constrained by the normal force and the gravity force) while still being able to move on that surface because of the unequal cancelling.

But it is a bit tricky to implement, I agree. Especially when you get into time steps and all that stuff.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

I misread part of your post, if you want to ineract with the object thats walking around then you could break down the force into x and y components then add the x and y force components currently acting upon the object before solving for its current acceleration. Could you eleborate on the current system you are using to maneuver your character around ( whether it be velocity vectors or just adding a constant the the postion vector every itteration or whatever else you're doing)?
Thank you both for the replies, looks like some really good info here and now I think about it a bit I think I am approaching this problem from the wrong angle, I don't have much time now but I will look through what you have said more carefully tomorrow and try to implement some more accurate gravity into my game.

@GameGeazer - at the moment I'm doing some slightly dodgy calculations where I move the man along the vector perpendicular to the gravity vector by adding a force in that direction to the man's velocity, the gravity force then also applied to his velocity which makes him stick to the planet. I then ensure he stays at least the radius amount away from the circle centre. The sprite is then drawn by rotating it by the rotation amount using the ApplyGravity function I specified in the original post.

I would post an image of what it looks like at the moment but I'm not too sure how, can I do it through this forum or do I need to upload it through a different site and link the url?

Thanks

"To know the road ahead, ask those coming back."

Using a polar coordinate system for the physics should simply things a lot.
I think what you need to do it is "align" the object with the normal at the point on circumference of the planet. You need to map your object's rotation to normal's vector.

If the planet is always a circle, normal will be just be the opp of gravitation vector at that point.

One way to do this is to get angle between normal vector and the XY.. get the angle ans set this as rotation..

This topic is closed to new replies.

Advertisement