Orbital calculations are insane, please help

Hi, I’ve been stuck on this for more than months. I have a planet, using the wiki gravity script. I have been trying to find a way to spawn an object somewhere within the gravity range of the planet, and then apply a force perpendicular to the gravity well, creating sufficient velocity so that the object maintains a fairly circular orbit. I can tweak the multiplier value for a given distance between the planet and object until it works, but I need this to work wherever the object happens to spawn. The following attempt will run OK at “long range” but when the object spawns close to the planet it has way too much velocity.

//calculate current gravity pull then apply offset velocity to counter the fall
Vector3 offset = transform.position - myGravityWell.transform.position;
Vector3 theForce = offset / offset.sqrMagnitude * myGravityWell.rigidbody.mass;
//point the "satellite" at the gravity well
transform.LookAt(myGravityWell.transform.position, Vector3.forward);
//apply orbital force
transform.rigidbody.AddRelativeForce(theForce.sqrMagnitude*600, 0,0);

I’m not asking anyone to hand over their algorithms, but just pointing out how goofy wrong my approach is might be helpful. I find the use of sqrMagnitude to be baffling at best. If it matters, my particular project keeps all objects at zero on the z plane, with a top down view of the solar system.

Why go to all that trouble if all you want is a steady orbit? Why not just use transform.RotateAround() with the center of the planet as your rotation target and Vector3.up as the rotation axis?

Good question. I’ve used that compromise so far. I wanted to allow the user to apply force to these objects to stabilize or change their orbits. It’s just a direction that the game can’t really go without either swapping back and forth between custom orbit solutions like that, which are very limited, and the physics engine… or figuring out what seemed like a fairly straight forward math problem until I started trying to solve it :wink:

It certainly is a fun one. To simplify it, here’s the calculation for the acceleration towards the center of the planet:

acceleration = velocity-squared / radius

So, if you know how fast you’re accelerating towards the planet and the distance between the center of the planet and the object, the speed at which it must move perpendicular to it is:

The square root of (acceleration * radius)

You shall be remembered in lore as one of the true greats. It’s going to take me some time to work that out. I’ll post the results. Thanks so much.

I hate to admit it, but I can’t make sense of GargerathSunman’s help. I might have made too many mistakes in my question. First, I failed to mention this is all happening in one frame, during the object’s instantiation. Then there is theForce (a vector3) which I put in the X position of AddRelativeForce, which should be a float. Derp! Here’s what I’ve been using, that works, but only works if I spawn the satellite in the same place ever time. Fail.

	void Start() {
		//calculate gravity pull then apply offset velocity to counter the fall
		Vector3 offset = transform.position - myGravityWell.transform.position;
		Vector3 theForce = offset / offset.sqrMagnitude * myGravityWell.rigidbody.mass;

		//point the satellite at the planet, then apply a one-time force perpendicular to the planet's direction
		transform.LookAt(myGravityWell.transform.position, Vector3.forward);
		transform.rigidbody.AddRelativeForce(theForce.magnitude*100, 0, 0);
	}

I know that theForce is the exact same value that gravity is pulling (except gravity does so every frame instead of just once) So it stands to reason, that multiplying this value for it’s one-time use should get me close, and it does, but I’m still missing something because as soon as I move the satellite closer to the planet, the 100 from AddRelativeForce(theForce.magnitude*100, 0, 0) is now too high. It’s like I need to multiply theForce by ANOTHER graduated value based on the gravity calculation. I’m still very stumped thru no fault of GargerathSunman.

You shouldn’t be doing this by adding force, but by setting initial velocity. The adding of force also needs to take mass into account, and its results aren’t as easy to control as velocity shifts. Here’s a translated result, assuming that you never want to rotate around the Z or X Axis. (Note: Have an empty child object inside the rotating object that is linked to the variable “looker”)

var looker : Transform;
var myPlanet : Transform;

var gravityPull : float;

function Start()
{
   looker.LookAt(myPlanet);
   rigidbody.velocity = looker.right * Mathf.Sqrt(gravityPull * Vector3.Distance(transform.position, myPlanet.position);
}

Roughly right, but you’ll have to replace the variables with your real ones.

P.S. Will only work if you use true exponential gravity.

I know this sounds hyper-gratuitous, but I really can’t thank you enough for taking the time. I just got it to work… perfectly, with your last explanation. Thank you!

If you want to see your good deed in action, here it is. Any asteroids that spawn within the gravity wells are in perfect orbit. I’m so excited I can’t stand it. You really have no idea how long that has plagued me. This version of the project is very not ready for prime-time, I’m hoping no one clicks the link :wink: It lacks any internal explanation or help, so: Left-click and hold inside the center white circle to thrust your ship. mouse wheel zooms in and out. Space bar is booster/brake. Right-click “targets” objects. The tiny diamond are the asteroids, and if they start out in a gravity well they are beautiful little angels in perfect orbits!
Web version