I wrote a little program to use Newton's Law of Universal Gravitation to animate 3 planets orbiting a central star, but I have run into a problem. Here is the code that I used to create the program (I apologise about the messyness):
orbit1 = NDSolve[{
x''[t] == (-(6.672*10^-11) (7*10^17) x[t])/(x[t]^2 + y[t]^2 + z[t]^2)^(3/2),
y''[t] == (-(6.672*10^-11) (7*10^17) y[t])/(x[t]^2 + y[t]^2 + z[t]^2)^(3/2),
z''[t] == (-(6.672*10^-11) (7*10^17) z[t])/(x[t]^2 + y[t]^2 + z[t]^2)^(3/2),
x[0] == 1000, y[0] == 1000, z[0] == 1000,
x'[0] == 0, y'[0] == -100, z'[0] == 0}, {x[t], y[t], z[t]}, {t, 0, 1000}];
orbit2 = NDSolve[{
x''[t] == (-(6.672*10^-11) (7*10^17) x[t])/(x[t]^2 + y[t]^2 + z[t]^2)^(3/2),
y''[t] == (-(6.672*10^-11) (7*10^17) y[t])/(x[t]^2 + y[t]^2 + z[t]^2)^(3/2),
z''[t] == (-(6.672*10^-11) (7*10^17) z[t])/(x[t]^2 + y[t]^2 + z[t]^2)^(3/2),
x[0] == 500, y[0] == -1000, z[0] == -1000,
x'[0] == -110, y'[0] == 100, z'[0] == 0}, {x[t], y[t], z[t]}, {t, 0, 1000}];
orbit3 = NDSolve[{
x''[t] == (-(6.672*10^-11) (7*10^17) x[t])/(x[t]^2 + y[t]^2 + z[t]^2)^(3/2),
y''[t] == (-(6.672*10^-11) (7*10^17) y[t])/(x[t]^2 + y[t]^2 + z[t]^2)^(3/2),
z''[t] == (-(6.672*10^-11) (7*10^17) z[t])/(x[t]^2 + y[t]^2 + z[t]^2)^(3/2),
x[0] == 0, y[0] == 100, z[0] == 500,
x'[0] == 350, y'[0] == -100, z'[0] == 0}, {x[t], y[t], z[t]}, {t, 0, 1000}];
orbitplotunion =
Animate[Show[{ParametricPlot3D[{{x[t], y[t], z[t]} /.
orbit1, {x[t], y[t], z[t]} /. orbit2, {x[t], y[t], z[t]} /.
orbit3}, {t, 0, a},
PlotRange -> {{-1600, 1600}, {-1600, 1600}, {-1600, 1600}},
AxesLabel -> {x, y, z}],
Graphics3D[{Yellow, Sphere[{0, 0, 0}, 100], Green,
Sphere[{x[t], y[t], z[t]} /. orbit1 /. t -> a, 50], Blue,
Sphere[{x[t], y[t], z[t]} /. orbit2 /. t -> a, 50], Purple,
Sphere[{x[t], y[t], z[t]} /. orbit3 /. t -> a, 50]}]}], {a, 0,
Infinity, 0.1}]
As you can see, there is one orbit calculation for each planet, and these are then animated.
Now, my first problem has to do with NDSolve[]
and its calculation from t = 0
to t = 1000
, which means that the animation will break once t = 1000
is hit.
Is there a way to allow the animation to go on indefinitely, instead of having to reset it once t = 1000
comes along?
Secondly, the planets and their trailing lines start out orbiting the star perfectly in the beginning, but over time, the trailing lines of each planet become more and more jagged, until eventually the animation looks horrible.
Here is what the orbits look like in the beginning:
And this is what they look like some time later:
If anyone knows how to solve the jagged line problem (maybe by editing the amount of trailing line that is allowed, so that it doesn't redraw over itself continually) and knows how to make the animation continue indefinitely, I would love to know.
Regards,
Alex
EDIT:
After looking at the $n$-body wiki page, I thought I'd give it a go and start out small with a simple Earth-Sun simulation, and if that worked, then move my way up to $3,4,5,\dots$ bodies as well. Unfortunately, as expected, I seem to have run into a problem almost immediately. Here is the code that I am currently using:
G = 6.672*10^-11;
m1 = 5.972*10^24; (* mass of Earth *)
m2 = 1.989*10^30; (* mass of Sun *)
orbitearthsun = NDSolve[{
x1''[t] == -((G (m2) (x1[t] - x2[t]))/Abs[x1[t] - x2[t]]^3),
y1''[t] == -((G (m2) (y1[t] - y2[t]))/Abs[y1[t] - y2[t]]^3),
x2''[t] == -((G (m1) (x2[t] - x1[t]))/Abs[x2[t] - x1[t]]^3),
y2''[t] == -((G (m1) (y2[t] - y1[t]))/Abs[y2[t] - y1[t]]^3),
x1[0] == 1000, x2[0] == 0, x1'[0] == 100, x2'[0] == 0,
y1[0] == 1000, y2[0] == 0, y1'[0] == 100, y2'[0] == 0},
{x1[t], x2[t], y1[t], y2[t]}, {t, 0, 1000}]
NDSolve::ndsz: At t == 3.049010336028579`*^-6, step size is effectively zero;
singularity or stiff system suspected. >>
Does this occur because the denominator of each term becomes zero as they collide?
PerformanceGoal -> "Quality"
... $\endgroup$ParametricPlot3D
isn't sampling the function finely enough when you go to large values ofa
. Try using something like{t, Max[0, a-50], a}
as the parameter range for the plot. The 50 determines the length of the trail. $\endgroup$