Be a Supporter!

Trying to simulate gravity (AS3)

  • 374 Views
  • 6 Replies
New Topic Respond to this Topic
TheHiddenBlade
TheHiddenBlade
  • Member since: Nov. 30, 2012
  • Offline.
Forum Stats
Member
Level 01
Blank Slate
Trying to simulate gravity (AS3) 2013-05-10 11:39:22 Reply

So I'm working on a program that's trying to simulate universal gravitation ((mass of one body * mass of another body)/distance between them^2). I've got collision worked out, movement is done by adding XSpeed and YSpeed to the X and Y coordinates of the player body (the only one that moves in the sim). The other five bodies, planets, are stationary, and all pull the player body simultaneously according to the above formula.

Only, I can't seem to get the actual formula to apply well. It's spazzing out, and I can't seem to figure out why. I think part of it is that when the player body is on an axis with one of the bodies, the formula divides by zero and the player body warps the hell away.

stage.addEventListener(Event.ENTER_FRAME, accelPlayer)
function accelPlayer(e:Event):void{
	if(Mode==true){
		p1.x += playerXSpeed/pm
		p1.y += playerYSpeed/pm
	}
	if((dist1>(pr+b1r)) && (dist2>(pr+b2r)) && (dist3>(pr+b3r)) && (dist4>(pr+b4r)) && (dist5>(pr+b5r))){
		Mode=true
		playerXSpeed =(b1m*pm/(dist1X*dist1X))+(b2m*pm/(dist2X*dist2X))+(b3m*pm/(dist3X*dist3X))+(b4m*pm/(dist4X*dist4X))+(b5m*pm/(dist5X*dist5X))
		playerYSpeed =(b1m*pm/(dist1X*dist1X))+(b2m*pm/(dist2X*dist2X))+(b3m*pm/(dist3X*dist3X))+(b4m*pm/(dist4X*dist4X))+(b5m*pm/(dist5X*dist5X))
		//I think the problem is that when it's on an X or Y Coord with one of the bodies, it divides by zero and warps the fuck away
	}
	else if(dist1<=(pr+b1r) || dist2<=(pr+b2r) || dist3<=(pr+b3r) || dist4<=(pr+b4r) || dist5<=(pr+b5r)){
		Mode = false
	}
}

Key:
p1 is the player body's sprite.
pr is the player body's radius
pm is the player body's mass.
b#r is the radius of that body.
b#m is the mass of that body.
dist#X is the distance between that body and the player body on the X coordinate, vice versa for Y.
Mode is the boolean that determines collision; it starts true, becomes false and stops motion when there's a collision.

Note: The registration points for each sprite are at their centers. Each dist variable is positive when the player coord is greater than the respective body's coord (so, dist1X is positive when player is to the right of body1).

Also note: the radii are generated randomly when the program is run, and the masses are computed accordingly.

Basically, that should make the vectored movement of the player body equal to the sum of all the forces applied to it by the five planetary bodies. Only, nothing works, I don't know how to avoid division by zero. Any help would be tremendously appreciated :)


If life gives you lemons, find someone whose life gave them vodka, and have a party.

MSGhero
MSGhero
  • Member since: Dec. 15, 2010
  • Offline.
Forum Stats
Supporter
Level 16
Game Developer
Response to Trying to simulate gravity (AS3) 2013-05-10 12:27:10 Reply

I thought this was gonna be a boring Mario gravity question.

First of all, you could stick each planet in an array and loop through that instead of having 5 checks. Changing the number of planets would be significantly easier. You'd just add the result of each iteration to a temporary velocity var, and then use that once the loop is over.

Second, you should use x*x + y*y as your radius in the denominator so that being on top of each other is the only breaking case. Sqrt to get r. x/r times the resulting force is the x component of the force, and same goes for y. That way, you have a non-infinity number as the force, and 0/r times that would be zero if they're at the same x or y.

TheHiddenBlade
TheHiddenBlade
  • Member since: Nov. 30, 2012
  • Offline.
Forum Stats
Member
Level 01
Blank Slate
Response to Trying to simulate gravity (AS3) 2013-05-13 11:46:50 Reply

First of all, you could stick each planet in an array and loop through that instead of having 5 checks. Changing the number of planets would be significantly easier. You'd just add the result of each iteration to a temporary velocity var, and then use that once the loop is over.

I'm not wholly familiar with arrays. I've been learning the basics, like adding and subtracting and sorting, but that sounds a bit over my head. Not familiar with temporary vars, either :/

Second, you should use x*x + y*y as your radius in the denominator so that being on top of each other is the only breaking case. Sqrt to get r. x/r times the resulting force is the x component of the force, and same goes for y. That way, you have a non-infinity number as the force, and 0/r times that would be zero if they're at the same x or y.

Sqrt(x^2 + y^2) would give me the hypotenuse, which I've already got as var dist1 for dist1X and dist1Y. Putting dist1X/dist1, however, gives a reciprocal, so the force decreases as distance increases. Basically, if I would disregard mass, the player body would accelerate towards the body farthest from it, which is just wrong. I can't reciprocate that, either, because then I'm dividing by zero (again).


If life gives you lemons, find someone whose life gave them vodka, and have a party.

MSGhero
MSGhero
  • Member since: Dec. 15, 2010
  • Offline.
Forum Stats
Supporter
Level 16
Game Developer
Response to Trying to simulate gravity (AS3) 2013-05-13 12:44:43 Reply

An array is one of the basics you need to learn, so you might as well learn it now. A temporary variable is just a variable.

Dist1X/dist1 gives you the fraction of the force in the x direction. Multiply that by the force to get the x force. It's just trig but skipping angles and sin/cos. The force is supposed to decrease with distance: that's why the r*r is in the denominator. The rest of your logic doesn't really make sense...you have to account for any negative signs in dist1x to see if it goes left or right.

"Don't think about it too much, just let the math give you the answer." - one of my teachers

Diki
Diki
  • Member since: Jan. 31, 2004
  • Offline.
Forum Stats
Moderator
Level 13
Programmer
Response to Trying to simulate gravity (AS3) 2013-05-13 13:11:55 Reply

At 5/13/13 11:46 AM, TheHiddenBlade wrote: I'm not wholly familiar with arrays. I've been learning the basics, like adding and subtracting and sorting

How did you learn sorting without learning arrays?
You should really look into them though. They're not complicated and are incredibly useful.

At 5/13/13 11:46 AM, TheHiddenBlade wrote: Sqrt(x^2 + y^2) would give me the hypotenuse

You're not actually using the ^ operator, are you?

In AS3, and pretty much any other language, the ^ operator doesn't perform exponent-based math; the operator is used for an XOR (exclusive-or) bitwise operation. If you want to raise a number to a power you need to use the Math.pow function.

TheHiddenBlade
TheHiddenBlade
  • Member since: Nov. 30, 2012
  • Offline.
Forum Stats
Member
Level 01
Blank Slate
Response to Trying to simulate gravity (AS3) 2013-05-17 11:44:51 Reply

How did you learn sorting without learning arrays?
You should really look into them though. They're not complicated and are incredibly useful.

I mean, I know arrays. I know sorting, nesting, etc. I'm just not sure how to have a program change the number of items in an array (number of planets) or run X number of iterations through them. I guess my problem was I was never taught packages.

You're not actually using the ^ operator, are you?

And no, of course not, I know my Math functions.

:Dist1X/dist1 gives you the fraction of the force in the x direction. Multiply that by the force to get the x force. It's just trig but skipping angles and sin/cos. The force is supposed to decrease with distance: that's why the r*r is in the denominator. The rest of your logic doesn't really make sense...you have to account for any negative signs in dist1x to see if it goes left or right.
I don't think you're understanding (or maybe I'm not) but what you're defining as "r" is the hypotenuse of the triangle, right? that's my var dist1...

dist1 = Math.sqrt(Math.pow((dist1X),2)+Math.pow((dist1Y),2))

...as such, dist1 is never negative, etc.
The force, meanwhile, is playerXForce, which directly influences the player.x coordinate, but I don't actually have the force without this math. So all I need is a formula that will take the distance on the axis and the distance total (hypotenuse), plug them into the universal gravitation formula (disregarding mass, I can deal with that myself), and not divide by zero when the p1.x = b1.x.

I'm sorry if I'm being confusing, this has just been twisting my brain into an awful knot.


If life gives you lemons, find someone whose life gave them vodka, and have a party.

MSGhero
MSGhero
  • Member since: Dec. 15, 2010
  • Offline.
Forum Stats
Supporter
Level 16
Game Developer
Response to Trying to simulate gravity (AS3) 2013-05-17 12:07:46 Reply

Delete playerXforce. Calculate the total force, ignoring direction (GMm/r^2). Multiply that total force by dist1x/dist. That is your x force due to planet 1. You can't possibly divide by zero this way unless the planets are on top of each other.