Hice una simulación en C++ con la ley de Newton y la probé comparando las posiciones de los planetas con la posición de la calculadora del sistema solar Don Cross (que convertí de JavaScript a C++)
http://cosinekitty.com/solar_system.html
Lo que hago es cada paso de tiempo (generalmente 1 segundo, pero el paso de 0,2 segundos es muy similar al paso de 10 segundos):
Como puede ver, algunos planetas tienen pequeñas desviaciones y otros más grandes, por lo que mi pregunta es: ¿Puede ser exacto el de Newton? o la calculadora del sistema solar Don Cross no lo es? ¿O hay materia negra en esa región? ¿O qué más?
void CGravitator::CalcAceleration(double timeseconds){
unsigned int i,j,iend;
if (sunStatic)iend=m_np-1;
else iend=m_np;
for (i = 0; i < iend; i++) {
m_planetas[i].aceleration.set(0,0,0);
CVector3 totalGravitationalForce;
// Loop through all bodies in the universe to calculate their gravitational pull on the object (TODO: Ignore very far away objects for better performance)
for (j = 0; j < m_np; j++) {
if (i == j) continue; // No need to calculate the gravitational pull of a body on itself as it will always be 0.
double distancia =CVector3::Distancia(m_planetas[i].pos,m_planetas[j].pos);
double force = KGNEWTON * m_planetas[i].masa * m_planetas[j].masa / pow(distancia, 2);
CVector3 forceDirection = CVector3::Normalize(m_planetas[j].pos - m_planetas[i].pos);
totalGravitationalForce += forceDirection * force;
}
CVector3 incspeed = totalGravitationalForce / m_planetas[i].masa ;
m_planetas[i].aceleration += incspeed * timeseconds;
}
Necesitas usar un mejor método numérico. El método de Euler es notoriamente malo para la mecánica orbital porque los errores numéricos siempre se acumulan. En particular, el método de Euler no conserva la energía, por lo que obtienes órbitas que mágicamente ganan energía y se salen de control.
Necesita usar algo como el método Verlet o algún otro integrador simpléctico.
Además de las deficiencias del método numérico señaladas en la otra respuesta, la simulación de la órbita de Mercurio debe tener en cuenta la gravitación de Júpiter, así como los efectos relativistas. Esto solo explica una pequeña fracción de la desviación, pero debe tenerse en cuenta cuando el método numérico mejore.
Aparentemente, la precesión del perihelio de Mercurio debido a la atracción de Júpiter y los efectos relativistas es de aproximadamente 574 segundos de arco en un siglo, o 1,57E-2 segundos de arco/día. Con una circunferencia orbital de aproximadamente 3,6E8 km y un arcosegundo de 1,296E-6 de vuelta, eso equivale a aproximadamente 4,3 km, o 43 km en 10 días.
Si bien la diferencia en la posición del perihelio no se traduce directamente en una diferencia de ubicación, debería dar una idea del efecto.
El error vino de las fuentes de datos. Ahora reemplacé a NAIF cspice.lib y descargué un archivo SPK general solo para los planetas, y el error es realmente pequeño sin otros cuerpos de gravedad como asteroides y cometas. Es realmente simple usar solo 2 funciones (furnsh_c y spkezr_c), una inclusión y una lib.
Codificado con vc6 ++ pure win 32. Ejecuté makeall.bat desde Spice descomprimido (no pude hacerlo funcionar en MFC)
También el paso de tiempo puede ser cualquier fracción de segundos para que Spice y Newton estén sincronizados. Así que Newton me dice que no hay materia negra.
Estos son los resultados sin la gravedad de asteroides y cometas durante 10 días y sin correcciones en cpsice spkezr_c
error de distancia en KM newton (Verlet) desde el
tiempo de especias = 864000.250
MERCURY BARYCENTER = 5.511496277969209e+002
SATURN BARYCENTER = 8.535731413118873e+001
VENUS BARYCENTER = 2.701394194074592e+002
URANUS BARYCENTER = 8.651056255887706e+001
EARTH = 9.664941717935676e+001
NEPTUNE BARYCENTER = 8.654038466254323e+001
MOON = 1.208560265740111e+002
MARS BARYCENTER = 5.954829440293592e+001
PLUTO BARYCENTER = 8.661640570487361e+001
JUPITER BARYCENTER = 8.256645190275238e+001
TOTAL ERROR DISTANCE = 1.525933904320919e+003
Time Ini GREGORIAN = 2000 ENE 01 12:00:00.000
Time End GREGORIAN 0.20:05 = 201 ENE 02:00
PM 2 Anillo
PM 2 Anillo
jkej
nick t
luis alberto
luis alberto
Arturo
ilmari karonen
m_planetas[i].masa
. Cancele esos. (Y cambie "fuerza" en los nombres de sus variables a "aceleración".) #2 Primero (presumiblemente) está sacando una raíz cuadrada adentroCVector3::Distancia
y luego elevando al cuadrado la distancia. Cancele esos también. Y #3 sí, evita la integración de Euler. Y #4, incluya su código de actualización de posición y velocidad real en su pregunta; es posible que tenga errores o inexactitudes numéricas que afecten sus resultados.david blanco
negro mate
RBarryYoung
PM 2 Anillo
PM 2 Anillo
david hamen
ilmari karonen
m_planetas[i].aceleration
, ya que no han publicado el resto, pero el valor que almacenan en ese vector no es una aceleración. (incspeed
es una aceleración, al menos suponiendo quetotalGravitationalForce
sea una fuerza, pero luego se multiplica por un intervalo de tiempo).qmecanico
luis alberto
luis alberto