¿Por qué los objetos en una simulación de gravedad experimentan grandes aceleraciones repentinas?

Estoy tratando de crear un programa simple que simule la gravedad. La idea es que tengo un sol central y varios planetas que puedo crear con un gesto de deslizamiento en la pantalla, y uso el deslizamiento inicial para proporcionar a los planetas una velocidad inicial.

Después de algún tiempo, el planeta finalmente comenzará a moverse alrededor del sol de acuerdo con la ley de Newton.

Mi enfoque actual es: en cualquier momento calculo el valor de la fuerza gravitacional que el sol ejerce sobre el planeta ( METRO pag es la masa del planeta y METRO s es la masa del sol):

F = GRAMO METRO pag METRO s r 2

Entonces encuentro el valor de aceleración para el planeta con

A = F METRO pag

Entonces encuentro el ángulo, θ , de la línea que une el centro del planeta con el centro del sol.

A continuación, creo un vector de aceleración a lo largo de esa línea creando su componente x y ay:

A X = A porque θ A y = A pecado θ

En la siguiente iteración utilizo este vector de aceleración y el tiempo transcurrido desde la iteración anterior para calcular la velocidad del planeta y luego su posición. Entonces todo se repite.

El principal problema con este enfoque es que tan pronto como el planeta alcanza una distancia cercana a cero del sol, obtiene una tremenda aceleración y en la siguiente iteración simplemente está demasiado lejos del sol y sigue moviéndose en línea recta. justo fuera de la pantalla, que por supuesto no es lo que espero de la gravedad. Tenga en cuenta que todavía no tengo detección de colisión, por lo que esperaría que el planeta permaneciera inmóvil en el centro del sol.

Mi intuición me grita que debería usar algún tipo de integración para la aceleración, de modo que cada aceleración que pierda entre una iteración y la siguiente se tenga en cuenta y mi planeta deje de escapar de la gravedad, así que recuperé mis libros de matemáticas y física y probé. para resolver esto por mí mismo, pero sin suerte.

Si lo hice bien, el problema es que mi aceleración es una función de la distancia, por lo que no puedo integrarla para obtener la posición del planeta, porque eso requeriría una aceleración en función del tiempo. ¿Tengo razón? ¿Cuál es la solución correcta para esto?

Mi respuesta a otra pregunta podría ser útil.
Además, NBabel alberga un conjunto norte -códigos de cuerpo escritos en varios lenguajes populares (Fortran, C, C++, Python, etc.); tal vez le interese revisar esos códigos.
He borrado algunos comentarios fuera de tema. Un recordatorio para todos que los comentarios son para solicitar aclaraciones y sugerir mejoras a la publicación y, de forma temporal, señalar recursos relacionados. ¡Definitivamente no por responder la pregunta!
algo como este documento resolverá su problema.
También observé este fenómeno recientemente con simulación de gravedad. El ajuste más básico quizás sea calcular la acción gravitatoria, ya que sería medio paso de tiempo antes del tiempo de aplicación. Esto significa que el error de cuantización tiene la misma probabilidad de ralentizar los objetos que de acelerarlos. Esto puede estar relacionado con "Integración Verlet"
Recomiendo que antes de usar soluciones más complejas, no se permita que la distancia (r) entre el sol y el planeta llegue a cero. La distancia más pequeña debe ser el radio del sol (R) + una distancia "razonable" (d) que evitará la colisión del planeta con el sol. Si quieres permitir la colisión, prueba el cálculo de la distancia y si es 0 o negativo, "choca" el planeta con una explosión proporcional al tamaño del planeta.

Respuestas (5)

Si realmente desea un simulador de gravitación general (es decir, uno que maneje más de dos cuerpos), existen métodos para reducir el error involucrado en la simulación, pero no existen métodos para eliminar el error. A continuación se presentan algunos enfoques: ninguno de estos enfoques es perfecto, ya que existe un equilibrio entre la precisión física, la programación y la velocidad computacional, y la reducción del comportamiento de escape.

  1. Pasos de tiempo adaptables: cuando su partícula experimenta grandes cambios en la aceleración (es decir, cuando se mueve rápido cerca de un cuerpo masivo), puede reducir el paso de tiempo d t por lo que está "saltando" menos tiempo. Esto aumentará la precisión física de la simulación, pero también la ralentizará (y la ralentizará de manera desigual), por lo que no es un buen enfoque si desea que se vea bien en tiempo real.

  2. Hard spheres: convierte tus masas en esferas duras que rebotan entre sí. Esto reducirá la acumulación de errores, ya que las masas no se acercarán tanto entre sí. Esto puede aumentar la precisión física de la simulación, a menos que objete los planetas que rebotan como pelotas de goma (lo cual es una objeción justa, supongo; también podría hacerlos esferas inelásticas, lo que probablemente sea más preciso para los planetas).

  3. Límite de velocidad: simplemente puede programar un límite de velocidad estricto para limitar el comportamiento de escape. Cada vez que la velocidad exceda el límite de velocidad, cambie el tamaño de la magnitud de la velocidad de nuevo al límite de velocidad. Esto no es muy preciso físicamente y podría resultar en un comportamiento extraño, pero es fácil de programar y reducirá el escape de sus masas.

  4. Conservación de energía: en cada paso de tiempo, calcule la cantidad total de energía gravitacional y cinética que tienen todas las masas. En cada paso de tiempo, si la cantidad total de energía ha cambiado, ajuste artificialmente las velocidades de las masas para que la cantidad total de energía permanezca igual. Esto tampoco es perfectamente preciso, pero mantiene la fidelidad con una ley física y reducirá el comportamiento de escape.

Si desea ayuda para comprender la implementación de uno de estos métodos, puedo explicarlo con más detalle.

Sí, estaba pensando en la solución 2 y 3, pero el punto es que me gustaría evitar este tipo de trucos, estoy usando esta simulación para mejorar mis conocimientos de cálculo y estoy bastante seguro de que hay una manera de resolver el problema. usándolo Gracias de cualquier manera. Y la solución 4 es realmente interesante.
Las esferas inelásticas son en realidad más fáciles de implementar: reemplace los dos cuerpos originales con uno nuevo, sumando las masas y sumando los momentos, dividiendo el momento total por la nueva masa para obtener una nueva velocidad.

Brionus ha tocado la clave: pasos de tiempo adaptables. Cuando comience a obtener grandes aceleraciones, reduzca el tamaño de sus incrementos de tiempo. Además, cuando no estés acelerando mucho, aumenta el tamaño.

Una forma bastante estándar de hacer esto es calcular el cambio de posición en un paso. Luego corte el paso por la mitad y, comenzando desde el mismo punto de partida, calcule 2 pasos de posición sucesivos. Compare los dos cambios de posición finales, y si difieren por algún factor predeterminado (digamos 10^-6), reemplace el paso de tiempo original con el paso más pequeño y haga el cálculo nuevamente. Si los dos pasos coinciden estrechamente, intente un cálculo con un paso de tiempo el doble del original.

Esto requiere muchos cálculos adicionales, pero produce una simulación que no es ni demasiado precisa ni lo suficientemente precisa. Para las simulaciones orbitales, los grandes pasos de tiempo utilizados durante las trayectorias de baja gravedad compensarán con creces el tiempo de cálculo adicional.

EDITAR: en respuesta a la solicitud de "el enfoque de cálculo":

El enfoque de cálculo que utilizó funcionará para un simulador realmente simple, pero ignora las interacciones entre los cuerpos que no son solares, además de suponer que el sol central no se mueve. Para manejar esto, utilice un enfoque más generalizado. Almacene los valores (x,y,z) (Vx,Vy,Vz) y (Mx,My,Mz) para sus cuerpos en matrices indexadas de la misma manera. Entonces, las atracciones gravitatorias entre dos cuerpos cualesquiera se calcularán simplemente como (Fx,Fy,Fz), donde

F norte = Δ norte Δ X 2 + Δ y 2 + Δ z 2 GRAMO METRO a METRO b Δ X 2 + Δ y 2 + Δ z 2
Calcule cada componente por separado e integre por separado para obtener nuevas velocidades y posiciones. También tenga en cuenta que tendrá que calcular norte ( norte 1 ) valores para N cuerpos (incluido el sol), pero ese cuerpo A tira del cuerpo B exactamente con la misma fuerza con la que el cuerpo B tira del cuerpo A, por lo que solo necesita hacer el cálculo numérico de la mitad del total aparente, aunque tendrá que ser tenga cuidado de invertir el signo para obtener la otra mitad de los valores correctos. (La razón por la que es norte ( norte 1 ) en vez de norte 2 es que no calculas la atracción de un cuerpo sobre sí mismo).

Para un simulador simple, puede usar la integración de Euler. Dada la fuerza sobre un cuerpo y su masa, para una muy pequeña Δ t puedes decir

Δ V = F Δ t METRO
y cuando conoce tanto la velocidad original V como el cambio de velocidad, el cambio de posición Δ PAG es
Δ PAG = ( V + Δ V ) Δ t

Para escalas de tiempo cortas y muy pequeñas Δ t esto funcionará, pero fundamentalmente está tratando de aproximarse a una curva irregular con segmentos rectos y, a la larga, verá errores grandes y crecientes. Entonces, durante períodos más largos, querrá ingresar a algoritmos más sofisticados. Como ha comentado zeldridge, Runge-Kutta es una alternativa muy conocida.

SEGUNDA EDICIÓN: Además, cuando actualice sus valores, realice cada conjunto de cálculos en función de las mismas condiciones originales para todos los cuerpos. Es decir, si está calculando Vnuevo y Pnuevo para el cuerpo A, no calcule los resultados para el cuerpo B usando el Pnuevo actualizado para el cuerpo A. Calcule una matriz completamente nueva de valores V y P, luego reemplace los valores antiguos como un bloque .

Los comentarios no son para una discusión extensa; esta conversación se ha movido a chat .

Si no está interesado en una simulación completa de n cuerpos y acepta una en la que el sol es mucho más masivo que todos los planetas, puede simplificar mucho las cosas. Tenemos una solución analítica para el problema de los dos cuerpos, por lo que puede aplicar la gravedad del sol de esa manera. Para cada planeta, dada su posición y velocidad, puede calcular su momento angular y energía, y luego obtener la órbita. Esto le permite calcular la ubicación del planeta al final del paso de tiempo ignorando las atracciones de todos los planetas. En orden cero, has terminado, porque ignoras las interacciones planeta-planeta. Si desea aplicar las interacciones planeta-planeta, puede calcular la fuerza sobre el planeta i de todos los demás planetas y aplicar la aceleración durante todo el paso de tiempo. Como la fuerza es mucho menor que la gravedad del sol, el cambio de posición será pequeño. Esto mantendrá sus errores mucho más pequeños, aproximadamente como la proporción de las fuerzas en el planeta de los otros planetas a la fuerza del sol. Luego puede aplicar los pasos de tiempo adaptables y la conservación de energía que sugieren los otros respondedores.

Esta publicación de Physics.SE analiza las posiciones parametrizadas de los cuerpos en órbita.

Un enfoque de programación diferente en una animación paso a paso es asignar variables de posición y momento a cada uno de los objetos. En términos de programación, tenemos el nombre del objeto, la masa, la ubicación x/y/z y el momento px/py/pz. Entre cada marco, para cada objeto, primero calcule su distancia a cualquier otro objeto y calcule la fuerza gravitatoria sobre ese objeto según la ley de fuerza inversa de Newton; segundo, agregue la fuerza al impulso; finalmente, agregue el impulso a la ubicación (px=px+forcex, x=x+px).

Puede obtener muy buenas animaciones con este método, donde la precisión solo está limitada por la precisión de los cálculos, la frecuencia de los cálculos y la posición inicial/momento de cada uno de los objetos. Puede encontrar un ejemplo de este método en http://www.animatedphysics.com/planets/Moon_Orbit.htm

WRT su problema "El principal problema con este enfoque es que tan pronto como el planeta alcanza una distancia cercana a cero del sol, obtiene una tremenda aceleración y en la siguiente iteración simplemente está demasiado lejos del sol y simplemente sigue moviéndose una línea recta, directamente fuera de la pantalla". Este es un problema muy importante. Si permite que un objeto se acerque arbitrariamente a un segundo objeto, la fuerza entre los objetos será arbitrariamente grande (por lo tanto, el objeto salta repentinamente fuera del campo de visión como experimentó) sin importar cuán pequeños sean los intervalos de tiempo que use.

Creo que sería muy esclarecedor si @Brionius pudiera ampliar su opción 4.

Basado en el modelo físico que está adoptando (que solo el "sol" ejerce fuerza gravitatoria sobre los "planetas" y que ignoramos los efectos gravitacionales de los planetas sobre el sol o entre sí), que sin duda es un comienzo bastante decente punto (sin mencionar lo suficientemente bueno para Kepler en nuestro propio sistema solar), hay dos puntos principales para darse cuenta:

1) ¡HAY órbitas legítimas (o, más correctamente, llamémoslas trayectorias) en las que el planeta no está unido al sol! Es decir, el planeta, en lugar de moverse en un camino que permanece cerca del sol y gira periódicamente alrededor de él, puede, en total consistencia con las leyes de Newton, ser puesto en un curso que lo saque del sistema solar, para nunca regresar ( y esto puede ocurrir incluso después de que el planeta hace un primer paso cercano al sol, lo que podría llevar a creer que iba a orbitar). Dadas las velocidades iniciales arbitrarias de los planetas, tampoco debemos esperar que estas trayectorias sean raras o inusuales, aunque es posible que no sean las que le interesan. Resolver las leyes del movimiento de Newton junto con su ley de la gravedad nos dice que la trayectoria del planeta será de tres tipos: elíptica, parabólica o hiperbólica. Sólo las primeras de ellas, las trayectorias elípticas, son cerradas o acotadas. Ahora bien, es muy posible, incluso probable, que las trayectorias "fuera de control" que observa realmente se deban a los artefactos numéricos de un algoritmo de simulación insuficientemente preciso, pero probablemente le convendría confirmar que esto es cierto como primer paso verificando que las velocidades iniciales que está asignando a los planetas son lo suficientemente pequeñas como para que no coloquen al planeta en una trayectoria parabólica o hiperbólica. Si desea descartar por completo tales trayectorias, como parece que lo hace, sería inteligente escribir su código de tal manera que evite que el usuario elija las velocidades iniciales que conducirían a ellas. La prueba es fácil; solo exige eso que las trayectorias "fuera de control" que observa realmente se deben a los artefactos numéricos de un algoritmo de simulación insuficientemente preciso, pero probablemente le convendría confirmar que esto es cierto como primer paso comprobando que las velocidades iniciales que está asignando a los planetas son lo suficientemente pequeños como para no poner al planeta en una trayectoria parabólica o hiperbólica. Si desea descartar por completo tales trayectorias, como parece que lo hace, sería inteligente escribir su código de tal manera que evite que el usuario elija las velocidades iniciales que conducirían a ellas. La prueba es fácil; solo exige eso que las trayectorias "fuera de control" que observa realmente se deben a los artefactos numéricos de un algoritmo de simulación insuficientemente preciso, pero probablemente le convendría confirmar que esto es cierto como primer paso comprobando que las velocidades iniciales que está asignando a los planetas son lo suficientemente pequeños como para no poner al planeta en una trayectoria parabólica o hiperbólica. Si desea descartar por completo tales trayectorias, como parece que lo hace, sería inteligente escribir su código de tal manera que evite que el usuario elija las velocidades iniciales que conducirían a ellas. La prueba es fácil; solo exige eso pero probablemente le convendría confirmar que esto es cierto como un primer paso verificando que las velocidades iniciales que está asignando a los planetas son lo suficientemente pequeñas como para que no coloquen al planeta en una trayectoria parabólica o hiperbólica. Si desea descartar por completo tales trayectorias, como parece que lo hace, sería inteligente escribir su código de tal manera que evite que el usuario elija las velocidades iniciales que conducirían a ellas. La prueba es fácil; solo exige eso pero probablemente le convendría confirmar que esto es cierto como un primer paso verificando que las velocidades iniciales que está asignando a los planetas son lo suficientemente pequeñas como para que no coloquen al planeta en una trayectoria parabólica o hiperbólica. Si desea descartar por completo tales trayectorias, como parece que lo hace, sería inteligente escribir su código de tal manera que evite que el usuario elija las velocidades iniciales que conducirían a ellas. La prueba es fácil; solo exige eso La prueba es fácil; solo exige eso La prueba es fácil; solo exige eso v 2 < GRAMO METRO / r , dónde v es la velocidad total inicial del planeta y r es la distancia sol-planeta en el momento en que se mide esa velocidad inicial. Es posible que desee ir un paso más allá y exigir que la excentricidad de todas las órbitas elípticas sea lo suficientemente pequeña como para que el planeta no salga de la pantalla (como podría ser, por ejemplo, para un objeto similar al cometa Halley que, aunque unido a nuestro sol, varía su distancia al sol por un factor de 70 durante su período orbital de 76 años). Al exigir que a 1 2 r v 2 GRAMO METRO , el llamado "semi-eje mayor" de la órbita, es más pequeño que la distancia desde el sol hasta el borde de la pantalla, puede estar seguro de que los planetas que salen de la pantalla nunca regresarán y representan parabólicos /trayectorias hiperbólicas, o si éstas han sido excluidas, artefactos numéricos.

2) Quizás más importante, porque tiene el potencial de mejorar en gran medida la simplicidad, la precisión y la eficiencia de su código, es que las leyes de Newton, bajo sus suposiciones físicas, son completamente solucionables , lo que significa que no hay necesidad de simular la física ( !). Se llama el problema de los dos cuerpos (a pesar de que hay múltiples planetas, asumimos que no interactúan entre sí, por lo que el camino de cada planeta está completamente determinado por sus interacciones con exactamente otro objeto, el sol), y es esencialmente el cálculo que hizo Kepler para mostrar que los planetas se mueven en órbitas elípticas. Es algo complicado anotar el X y y posiciones en función del tiempo dada una posición inicial arbitraria y la velocidad del planeta, por lo que no lo haré aquí, pero el artículo de Wikipedia sobre "órbitas de Kepler", y los enlaces que contiene, proporcionan todas las ecuaciones que uno necesitaría masajear para obtener el resultado deseado (tenga en cuenta que allí se supone que tomamos la dirección del perihelio/afelio de la órbita para alinearla con uno de los ejes de coordenadas, y sería necesario realizar un cambio de base para recuperar el resultado más general). De hecho, soy un empleado de Wolfram Alpha y me sorprende que no tengamos los resultados paramétricos para X y y en función del tiempo para el problema de Kepler disponible en nuestro sitio web. ¡Pero trabajaré para rectificar eso en el futuro y actualizaré mi respuesta aquí si lo hago! Baste decir, sin embargo, que si no le importan las interacciones interplanetarias, simular las leyes de Newton definitivamente no es la forma correcta de abordar este problema, y ​​cosas como los pasos de tiempo adaptativos, aunque funcionarían, serían exageración masiva.