Dadas las posiciones bidimensionales y las velocidades de un par de bolas de billar justo antes del impacto, calcule sus velocidades después de una colisión perfectamente elástica . Se supone que las bolas son esferas ideales (o equivalente: círculos) con el mismo radio, la misma masa, densidad uniforme y sin fricción.
La entrada consta de 8 números: p0x,p0y,v0x,v0y,p1x,p1y,v1x,v1y
dónde p0x,p0y
está el centro de la primera bola, v0x,v0y
su velocidad y de manera similar p1x,p1y,v1x,v1y
para la segunda bola. Puede aceptar entradas en cualquier orden y estructuradas de cualquier manera conveniente, por ejemplo, como una matriz de 2x2x2, o tal vez una matriz de 2x2 para p
y dos matrices de longitud 2 para v0
y v1
. También está bien tomar números complejos (si su idioma los admite) en lugar de pares xy. Sin embargo, no debe tomar datos en un sistema de coordenadas que no sea cartesiano, es decir, no se permite polar.
Tenga en cuenta que el radio de una bola de billar es la mitad de la distancia entre p0x,p0y
y p1x,p1y
, por lo que no se proporciona como una parte explícita de la entrada.
Escriba un programa o función que genere o devuelva 4 números en cualquier representación cartesiana conveniente: los valores posteriores a la colisión de v0x,v0y,v1x,v1y
.
Un posible algoritmo es:
encuentra la línea normal que pasa por ambos centros
encuentre la línea tangente que pasa por el punto medio entre los dos centros y es perpendicular a la línea normal
cambiar el sistema de coordenadas y descomponer
v0x,v0y
yv1x,v1y
en sus componentes tangenciales y normalesv0t,v0n
yv1t,v1n
intercambiar los componentes normales de
v0
yv1
, preservando sus componentes tangencialescambiar de nuevo al sistema de coordenadas original
Pruebas (resultados redondeados a 5 decimales):
p0x p0y v0x v0y p1x p1y v1x v1y -> v0x' v0y' v1x' v1y'
[-34.5,-81.8, 34.7,-76.1, 96.2,-25.2, 59.2,-93.3] [ 49.05873, -69.88191, 44.84127, -99.51809]
[ 36.9, 77.7,-13.6,-80.8, -7.4, 34.4, 15.1,-71.8] [ 5.57641, -62.05647, -4.07641, -90.54353]
[-51.0, 17.6, 46.1,-80.1, 68.6, 54.0,-35.1,-73.9] [ -26.48927,-102.19239, 37.48927, -51.80761]
[-21.1,-52.6,-77.7, 91.5, 46.0, 94.1, 83.8, 93.7] [ -48.92598, 154.40834, 55.02598, 30.79166]
[ 91.3, -5.3, 72.6, 89.0, 97.8, 50.5, 36.2, 85.7] [ 71.73343, 81.56080, 37.06657, 93.13920]
[-79.9, 54.9, 92.5,-40.7,-20.8,-46.9,-16.4, -0.9] [ 47.76727, 36.35232, 28.33273, -77.95232]
[ 29.1, 80.7, 76.9,-85.1,-29.3,-49.5,-29.0,-13.0] [ 86.08581, -64.62067, -38.18581, -33.47933]
[ 97.7,-89.0, 72.5, 12.4, 77.8,-88.2, 31.5,-34.0] [ 33.42847, 13.97071, 70.57153, -35.57071]
[-22.2, 22.6,-61.3, 87.1, 67.0, 57.6,-15.3,-23.1] [ -58.90816, 88.03850, -17.69184, -24.03850]
[-95.4, 15.0, 5.3, 39.5,-54.7,-28.5, -0.7, 0.8] [ 21.80656, 21.85786, -17.20656, 18.44214]
[ 84.0,-26.8,-98.6,-85.6,-90.1, 30.9,-48.1, 37.2] [ -89.76828, -88.52700, -56.93172, 40.12700]
[ 57.8, 90.4, 53.2,-74.1, 76.4,-94.4,-68.1,-69.3] [ 51.50525, -57.26181, -66.40525, -86.13819]
[ 92.9, 69.8,-31.3, 72.6,-49.1,-78.8,-62.3,-81.6] [-123.11680, -23.48435, 29.51680, 14.48435]
[-10.3,-84.5,-93.5,-95.6, 35.0, 22.6, 44.8, 75.5] [ -11.12485, 99.15449, -37.57515,-119.25449]
[ -3.9, 55.8,-83.3, 9.1, -2.7,-95.6, 37.7,-47.8] [ -82.84144, -48.75541, 37.24144, 10.05541]
[-76.5,-88.4,-76.7,-49.9, 84.5, 38.0, 4.2, 18.4] [ 6.52461, 15.43907, -79.02461, -46.93907]
[ 64.2,-19.3, 67.2, 45.4,-27.1,-28.7, 64.7, -4.3] [ 59.66292, 44.62400, 72.23708, -3.52400]
[ 9.8, 70.7,-66.2, 63.0,-58.7, 59.5, 83.7,-10.6] [ 68.07646, 84.95469, -50.57646, -32.55469]
[ 62.9, 46.4, 85.0, 87.4, 36.3,-29.0,-63.0,-56.3] [ 23.53487, -86.82822, -1.53487, 117.92822]
[ -5.5, 35.6, 17.6,-54.3, -2.2, 66.8,-15.2, 11.8] [ 24.15112, 7.63786, -21.75112, -50.13786]
Las victorias más cortas. No hay escapatorias.
gracias @Anush por ayudar a arreglar el color de fondo del diagrama
r=p-q
conp-=q
y uso posteriorp
en lugar der
, como en la respuesta de Neil JSJavaScript (Node.js) ,
9088 bytesPruébalo en línea! El enlace incluye un conjunto de pruebas. Explicación:
q,r
se reutilizan como el vector de diferencia entre los centros, yu
es el cuadrado de su longitud.v
es la diferencia en los productos punto deo,p
ys,t
conq,r
, también lov/u
es el factor de escalaq,r
que da la cantidad de velocidad transferida deo,p
as,t
. Editar: Guardado 2 bytes gracias a @Arnauld.fuente
Perl 6 ,
75646361 bytes11 bytes guardados al cambiar de
map
afor
, prescindiendo de la necesidad de poner cosas en variables intermedias para que lasmap
vea.1 byte guardado al cambiar
($^a-$^c)².&{$_/abs}
a($^a-$^c).&{$_/.conj}
.2 bytes guardados gracias a @nwellnhof.
Pruébalo en línea!
Explicación
Cuando la publicación original decía que la entrada podía ser números complejos, era demasiado difícil de resistir ... Entonces, esto toma 4 números complejos (posición 1, velocidad 1, posición 2, velocidad 2) y devuelve las velocidades como números complejos.
El programa utiliza el mismo algoritmo que se describe en el OP. Sin embargo, con números complejos, eso es bastante simple. Primero, observemos que el número complejo puntos desde la primera bola hasta la segunda. Entonces, si dividimos todas las velocidades por él, la dirección normal de repente coincide con el eje real y la dirección tangente con el eje imaginario. (Esto arruina las magnitudes pero no nos importa).re= p1- p0 0
Ahora, necesitamos cambiar las partes normales (es decir, reales) de las velocidades y , y luego, multiplicarlo por nuevamente para hacer que el punto normal (y las velocidades) apunten en la dirección correcta (y hacia Desate las magnitudes). Por lo tanto, debemos calcular (donde = real parte, = parte imaginaria). Mezclemos el primero un poco (usando para conjugación compleja):v0 0/ d v1/ d re v′0v′1=d(Rv1d+iIv0d),=d(Rv0d+iIv1d) R I ⋆ v′0=d(Rv1d+iIv0d)=d[12(v1d+v⋆1d⋆)+12(v0d−v⋆0d⋆)]= =d2(v0+v1d−v⋆0−v⋆1d⋆)=12(v0+v1−dd⋆(v⋆0−v⋆1)).
El resultado para se puede obtener simplemente cambiando . Todo lo que hace es cambiar un signo:
v′1 v0↔v1 v′1=12[v0+v1+dd⋆(v⋆0−v⋆1)].
Y eso es. Todo lo que el programa hace es solo este cálculo, un poco de golf.
fuente
($^a-$^c)
(y solo dentro de una lambda que normaliza este número), el segundo actúa($b-$d)
. Por lo tanto, realmente no se pueden reconciliar. Podría hacer una función que simplemente llamara.conj
, pero que solo agregaría bytes (porque uso mucho la$_
variable, que tiene la buena propiedad de que puede llamar métodos sin especificarla: en.conj
lugar de$_.conj
).Jalea , 16 bytes
Pruébalo en línea!
Un enlace diádico que toma como argumento izquierdo una lista de las posiciones iniciales
[[p0x, p0y], [p1x, p1y]]
y su argumento derecho las velocidades iniciales[[v0x, v0y], [v1x, v2y]]
. Devuelve una lista de las velocidades finales.[[v0x', v0y'], [v1x', v2y']]
Según el algoritmo utilizado por la respuesta de JavaScript de @ Neil, ¡ asegúrese de votar ese también!
fuente
C (gcc) ,
140132 bytesPruébalo en línea!
Básicamente, un puerto de la respuesta JavaScript de @ Neil, pero luego @ceilingcat redujo 8 bytes reutilizando inteligentemente
m
yn
almacenando temporarios.fuente
Python 2 ,
9792 bytesPruébalo en línea!
Versión modificada del enfoque de Neil.
fuente
C (gcc) ,
7772 bytesPruébalo en línea!
Basado en la implementación de Python de @Joel
fuente
APL (Dyalog Classic) , 21 bytes
Pruébalo en línea!
basado en la respuesta de @ Joel
entrada: matriz compleja 2x2, salida: par complejo
fuente