[C#] 2D elliptical Orbit - Non incrementing Variable
So I'm having an issue with the variable T in this code, for some reason it is not being incremented and I just cannot figure out why. For those wondering this is to be used for elliptical orbit in a 2D environment. For more precise numbers I should be using doubles however I'm unaware of how to cast as doubles within unity. All attempts have failed. More interested in resolving Angle. I apologize in advance for any issues with reading. Will be here all day if more details are needed.
public class Orbit : MonoBehaviour
{
private int minD; // min orbital distance of this object from it's parent or barycenter
private int maxD; // max orbital distance of this object from it's parent or barycenter
private int massObj; // mass of this object
private int massTar; // mass of the orbital parent, (mass of other star if binary star pair)
private float G = 0.0000000000667408f; // Gravitational Constant
private float AU = 149597870700f; // Meters
private float c = 299792458f; // Meters/Second
private float a; // Semi-Major Axis
private float b; // Semi-Minor Axis
private float P; // Period, overwritten by period, if period is non-zero
private float e; // Eccentricity, zero means a circular orbit
private float M; // Mean Anomaly
private float t; // Current world time
private float E; // Eccentric anomaly
private float o;
// Use this for initialization
void Start()
{
minD = 5;
maxD = 50;
massObj = 100;
massTar = 100;
a = (minD + maxD) / 2;
b = Mathf.Sqrt(minD * maxD);
P = Mathf.Sqrt((4 * Mathf.Pow(Mathf.PI, 2) / (G * (massObj + massTar))) * Mathf.Pow(a, 3));
e = (maxD - minD) / (maxD + minD);
}
// Update is called once per frame
void Update()
{
t = Time.time;
o = t % P; /* time on orbit */
float M = 2 * Mathf.PI / P * t;
float E = M;
for (float k = 0; k < 10; k++) { E = M + e * Mathf.Sin(E); }
float r = a * (1 - e * Mathf.Cos(E)); /* current radius */
float T = Mathf.Acos((a * Mathf.Cos(E) - a * e) / r); /* current angle */
if (o > (P / 2)) { T = -T; } // This lets us resolve the OTHER half of the orbit
Debug.Log("Period: " + P);
Debug.Log("Orbit: " + o);
Debug.Log("Radius: " + r);
Debug.Log("Angle: " + T); // This is always zero! Gah!
Debug.Log("Time: " + t);
transform.position = new Vector3(r, 0, 0);
transform.RotateAround(transform.parent.position, Vector3.forward, T / Mathf.Deg2Rad * Time.deltatime);
}
}
Answer by BMRX · Feb 23, 2016 at 08:19 PM
Wow I'm silly.
massObj = 100;
massTar = 100;
Is too small of a value;
massObj = Mathf.Pow(10, 24) * 5972;
massTar = Mathf.Pow(10, 30) * 1.989f;
Is a more realistic value. (If you're interested massObj is the mass of Earth, and massTar is the mass of Sol).
Thanks for stopping by! hopefully this helps someone.
sounds like you knocked it! nice work.
some $$anonymous$$or comments -
i'd make $$anonymous$$D and maxD floats. Ditto the two masses. There's no reason to have them ints.
i doubt you'll get much benefit from converting to doubles. in some cases doubles will definitely help, but this algorithm appears to be deter$$anonymous$$istic. ie, you don't need to know the state at time T-dT in order to calculate the state at time T. in other words, your state is calculated each Update() as a function of constants and the current time. So you're not accumulating error. Which is good. And since you're not accumulating error, the precision of floats is pretty good.
i don't know if you're planning to have multiple bodies in the system, but if so it seems like you're lacking a "phase" constant for each body ? eg, if you had two earths in the same orbit but 180º out of phase, all the parameters for each would be identical, except for a phase value.
Huh I was certain I replied to you, weird.
Anyways to re-iterate :P
This is still very WIP and I'm quite new to thinking at this level, so a phase constant does sound like a good idea however seeing as this is going to be used for procedural generation of star systems I've decided that two bodies in the same orbit just will not happen for ease of $$anonymous$$d. $$anonymous$$aybe someday I'll go back to change it but at the moment for a 4X game I'm already going above and beyond what is needed.
Answer by Riderfan · Feb 23, 2016 at 08:25 PM
To cast a double (or anything else) use;
double x = (double)(500.3344 * 0.00000045);
This will return whatever that math works out as to x which was declared a double. You can also use;
double x = system.Convert.ToDouble(someintvalue);
but I prefer the first choice.
Something to keep in mind that is that very little has to do with 'C# within unity'. You're writing code in C#. Whatever math functions and data types you have available to you in C# are available to you in C#. It doesn't matter that Unity is involved in someway. A double is a double is a double.
Fair enough, and I've now (using your suggestion) trying converting all of this to doubles. The issue now is that Vector3's don't seem to like using doubles. I haven't looked into a resolution for that yet....
I have also found that with using $$anonymous$$athf.[whatever] I in fact needed to change to System.$$anonymous$$ath.[whatever] because for whatever reason I cannot include System.$$anonymous$$ath at the top.
Thank you for your answer I appreciate it.
EDIT/ I found this thread that has custom scripts for use of Double Precision in Vector3's very handy. http://forum.unity3d.com/threads/double-precision-vector3.190713/
Your answer
Follow this Question
Related Questions
converting degrees per second into speed 1 Answer
Why aint my gameObject(the one i aplied the script) moving? 1 Answer
Help in C# rotatearound is not around center object 0 Answers
Problems with camera orbiting the player based on mouse input (C#) 0 Answers
Standalone build rotation shuddering with input button 0 Answers