Hola a todos. ¡Ya tenemos simulador! Con su panel de control y todo.
Lo he subido aquí para que podáis jugar con él:
https://force-field-particles-simulator.vercel.app/Aquí está el código fuente:
https://github.com/danielthetechie/force-field-particles-simulator/tree/main/srcLos ficheros más relevantes (donde está contenida la física del programa) son
Universe.js y
Particle.js.
También es apta para tierrahuequistas como nuestro amigo DCM, ya que se puede configurar para que la distancia inicial de todas las partículas con respecto del origen sea igual al radio del universo (como en el gif de arriba), esto es, que no haya partículas en el interior de la esfera. El único inconveniente es que no tiene un final feliz para DCM, sino que el final es el que predijo Richard unos cuantos mensajes más atrás:
Con la suficiente cantidad de tiempo quedará una sola partícula, pero que sin importar el número inicial de estas nunca se forma una estructura hueca, así funciona la naturaleza
Explico algunas opciones que quizá no sean demasiado claras al principio:
- Constante de fuerza: por defecto es \( -1 \), con signo negativo para crear una fuerza de atracción, pero se puede poner positivo para que la fuerza sea de repulsión. A más magnitud, más intensa será la fuerza, ya sea en un sentido u otro. Si la constante es \( 0 \) y la velocidad inicial de las partículas también la dejáis a \( 0 \), pues... nada, pasamos a un universo aburrido y estático.
- Las opciones con un % se calculan con respecto al valor máximo de la opción de arriba. Por ejemplo, si el radio del universo es \( 600 \) unidades y se escoge como distancia mínima al centro el valor \( 50 \), no es que sean 50 unidades, sino que es el \( 50\% \) de \( 600 \), es decir, \( 300 \) unidades. (Esto lo hice así para evitar que se pueda elegir valores mínimos superiores a los máximos y evitar errores.)
- La opción "Aumentar tamaño de las partículas compuestas" se refiere a que cuando dos partículas chocan (el choque siempre es inelástico, no hay rebotes), si ésta está activada el radio de la partícula resultante aumenta (lo hace de forma un poco artificial, eso sí, y lo hace sumando un 10% del radio de la partícula más pequeña al radio de la partícula más grande). Si desactiváis la opción, el radio de la partícula resultante será igual al de la partícula más grande antes del choque, y como efecto secundario veréis órbitas que duran más tiempo antes de que las partículas se absorban entre ellas.
- En la info de abajo, la "velocidad media del sistema" se refiere al cálculo de hacer el promedio de las velocidades instantáneas de todas las partículas en todos sus ejes. Es una manera de medir la evolución del sistema: al final del todo, la velocidad de la partícula que queda acaba siendo constante. Y si elegís que la constante de fuerza sea positiva (o sea, que la fuerza sea repulsiva), veréis que al cabo de un rato la velocidad media del sistema se va estabilizando a medida que las partículas se van alejando y disminuye la fuerza entre ellas.
- Para mover la cámara, mantened el botón derecho del ratón apretado y ésta rotará. Para desplazaros, lo mismo pero con click izquierdo. Para aumentar o disminuir el zoom, usad la rueda del ratón.
- Al inicio todas las partículas son rojas, pero cuando chocan, las partículas resultantes son de color verde para distinguirlas mejor de las originales.
Ahora respondo a Richard en particular:
Primero que nada gracias , estoy muy contento con que la idea haya colado y te haya motivado a programarlo.
Gracias a ti por el algoritmo.
De hecho, si te parece bien, me gustaría hacerte una mención de agradecimiento en el futuro Readme del proyecto. Le quiero añadir una opción para cambiar de idioma, algunas opciones más, pulir cosas y compartirlo con más gente.
Además ...Wow, quien pudiera jugar con cosas así, he hecho cosas más pobres visualmente, pero cuando lo pusiste a rotar en el espacio e hiciste zoom, quedé alucinado.
He usado una librería de Javascript llamada Three, que es para hacer gráficos en 3D, no es difícil de aprender y seguro que tú como ingeniero podrías sacarle mucho más provecho que yo.
hay como una concentración de partículas al centro que puede ser a causa de la perspectiva o a la propia distribución aleatoria que por tener mas espesor la esfera en el centro habrá mas partículas sobre esa línea de visión, por las dudas revisa si esta bien la aleatoriedad.
Al final lo he intentado solucionar de dos maneras:
1) Reemplazando la función por defecto para generar números aleatorios por una criptográfica que se supone que añade más aleatoriedad (en el fichero
math.js puedes ver la función getRandomNumber original, que la he dejado comentada, por su reemplazo, inmediatamente más abajo).
2) Añadiendo la opción "distancia mínima al centro del universo" explicada más arriba.
no se si será la escala pero veo grandes en tamaño a las partículas respecto del diámetro de la esfera contenedora, agrandar \( R \) o bajar \( r_i \) sería un consejo, pero quizá se pierda definición cuando todo se aglomere en el centro a lo largo del tiempo
Sí, creo que en el primer GIF que mostré usé un radio bastante pequeño (quizá 100 o 200 unidades, ahora no recuerdo), pero ahora se puede ajustar hasta las 3000 unidades. Si quieres más, dímelo.
La idea de fondo de la simulación funciona bien cuando el número de partículas $$n$$ es muy elevado para un $$R$$ grande, pero se ralentiza el cálculo entre posición y posición, además se tarda mas en aglutinar todo, si aumentas n quizá te convenga primero calcular todas la posiciones para cada tiempo, guardarlas en una base de datos y luego solo ejecuta la parte visual, donde se ven las trayectorias usando los datos y no calculándolos en el mismo tiempo de ejecución...
Es una manera ingeniosa, pero no sé hasta qué punto viable desde el punto de vista de la memoria, ya que habría que guardar una matriz de números bastante tocha en la base de datos para cada frame que durara la animación, y a cada ejecución del programa con diferentes parámetros quizá habría que esperar un rato hasta tener la base de datos repoblada. Aunque es cierto que una vez hecho esto, podrías correr la animación con un \( n \) mucho más alto de manera fluida.
Ahora mismo los cálculos se realizan a cada frame, se asignan los resultados a las variables de las partículas, se desplazan de forma acorde con dichos valores y vuelta a empezar en el siguiente frame. Según he leído en la documentación de la librería, no se procede a la animación del siguiente frame hasta que no estén todos los cálculos terminados.
En mi ordenador (que no es gran cosa, un laptop con un procesador Intel i3 6006U), la animación va fluida hasta los \( 600 \) - \( 700 \) partículas, a partir de ahí ya empieza a sufrir. Pero eso solo pasa al principio, ya que a medida que se van produciendo los choques y las partículas se van uniendo, voy borrando todas las referencias de las partículas iniciales para liberar memoria, así que aunque se empiece con un número relativamente alto de partículas, la animación acabará siendo más fluida con el tiempo.
El número máximo de partículas lo he limitado a \( 1000 \), pero otra vez, si quieres más dímelo y lo subo.
Se podría comenzar la simulación dándole una velocidad, dirección y sentido inicial a cada partícula
Esto ya se puede ajustar también en las opciones.
Por defecto las partículas empiezan sin velocidad, pero se puede ajustar.
por cierto habría que poder visualizar un corte de la esfera en un determinado momento, para ver si es hueca o no... quizá sea mucho pedir
Si te refieres a parar la animación en un determinado momento, es fácil de hacer. Pronto le pondré un botón para poder pausar la animación y que se pueda mover la cámara para poder ver con detalle el estado del universo en un determinado momento.
por más evidencia que presentes el fanatismo será superior
Sí, hay que admitir que contra un fanático que quiere serlo no hay nada que hacer desde la razón, pero programar esto y leer el hilo ha sido divertido: una cosa no quita la otra.
Siento la tardanza, por temas de trabajo no he podido dedicarle tanto tiempo estos días.