Compte tenu des positions et des vitesses bidimensionnelles d'une paire de boules de billard juste avant l'impact, calculez leurs vitesses après une collision parfaitement élastique . Les boules sont supposées être des sphères idéales (ou de manière équivalente: des cercles) avec le même rayon, la même masse, une densité uniforme et sans frottement.
L'entrée se compose de 8 chiffres: p0x,p0y,v0x,v0y,p1x,p1y,v1x,v1y
où p0x,p0y
est le centre de la première balle, v0x,v0y
sa vitesse, et de même p1x,p1y,v1x,v1y
pour la deuxième balle. Vous pouvez accepter des entrées dans n'importe quel ordre et structurées de n'importe quelle manière pratique, par exemple en tant que tableau 2x2x2, ou peut-être un tableau 2x2 pour p
et deux tableaux de longueur 2 pour v0
et v1
. Il est également possible de prendre des nombres complexes (si votre langue les prend en charge) au lieu de paires xy. Cependant, vous ne devez pas prendre d'entrée dans un système de coordonnées autre que cartésien, c'est-à-dire que la polaire n'est pas autorisée.
Notez que le rayon d'une boule de billard est la moitié de la distance entre p0x,p0y
et p1x,p1y
, donc il n'est pas donné comme une partie explicite de l'entrée.
Écrivez un programme ou une fonction qui génère ou renvoie 4 nombres dans n'importe quelle représentation cartésienne pratique: les valeurs post-collision de v0x,v0y,v1x,v1y
.
Un algorithme possible est:
trouver la ligne normale qui passe par les deux centres
trouver la ligne tangente qui passe par le milieu entre les deux centres et qui est perpendiculaire à la ligne normale
changer le système de coordonnées et décomposer
v0x,v0y
etv1x,v1y
en leurs composants tangentiels et normauxv0t,v0n
etv1t,v1n
permuter les composants normaux de
v0
etv1
, en préservant leurs composants tangentielsrevenir au système de coordonnées d'origine
Tests (résultats arrondis à 5 décimales):
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]
Victoires les plus courtes. Pas de failles.
merci @Anush d'avoir aidé à corriger la couleur d'arrière-plan du diagramme
r=p-q
parp-=q
et utilisez davantagep
au lieu der
, comme dans la réponse js de NeilJavaScript (Node.js) ,
9088 octetsEssayez-le en ligne! Le lien inclut une suite de tests. Explication:
q,r
sont réutilisés comme vecteur de différence entre les centres, etu
est le carré de sa longueur.v
est la différence entre les produits scalaires deo,p
ets,t
avecq,r
, toutv/u
comme le facteur d'échelle pourq,r
lequel donne la quantité de vitesse transférée deo,p
às,t
. Edit: sauvé 2 octets grâce à @Arnauld.la source
Perl 6 ,
75646361 octets11 octets économisés en passant de
map
àfor
, dispensant de la nécessité de mettre les choses en variables intermédiaires pour lesmap
voir.1 octet enregistré en passant
($^a-$^c)².&{$_/abs}
à($^a-$^c).&{$_/.conj}
.2 octets enregistrés grâce à @nwellnhof.
Essayez-le en ligne!
Explication
Lorsque le message d'origine a dit que l'entrée pouvait être des nombres complexes, il était trop difficile de résister ... Cela prend donc 4 nombres complexes (position 1, vitesse 1, position 2, vitesse 2) et renvoie les vitesses sous forme de nombres complexes.
Le programme utilise exactement le même algorithme que celui décrit dans l'OP. Cependant, avec des nombres complexes, c'est assez simple. Tout d'abord, notons que le nombre complexeré= p1- p0 points de la première balle à la seconde. Donc, si nous divisons toutes les vitesses par elle, la direction normale coïncide soudainement avec l'axe réel et la direction tangente avec l'axe imaginaire. (Cela perturbe les grandeurs mais nous ne nous en soucions pas.)
Maintenant, nous devons changer les parties normales (c'est-à-dire réelles) des vitessesv0/ d et v1/ d et après cela, multipliez-le par ré again to make the normal (and the velocities) point in the correct direction (and to unmess the magnitudes). So we need to calculate
v′0v′1=d(Rv1d+iIv0d),=d(Rv0d+iIv1d)
(where R = real part, I = imaginary part). Let's shuffle the first one a bit (using ⋆ for complex conjugation):
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)).
The result for v′1 can be obtained just by switching v0↔v1 . All that does is changing a sign:
v′1=12[v0+v1+dd⋆(v⋆0−v⋆1)].
And that's it. All the program does is just this calculation, golfed a bit.
la source
($^a-$^c)
(and only inside a lambda that normalizes this number), the second acts on($b-$d)
. So they can't really be reconciled. I could make a function that would just call.conj
, but that would only add bytes (because I heavily use the$_
variable, which has the nice property that you can call methods on it without specifying it:.conj
instead of$_.conj
).Jelly, 16 bytes
Try it online!
A dyadic link taking as its left argument a list of the initial positions
[[p0x, p0y], [p1x, p1y]]
and its right argument the initial velocities[[v0x, v0y], [v1x, v2y]]
. Returns a list of the final velocities[[v0x', v0y'], [v1x', v2y']]
Based on the algorithm used by @Neil’s JavaScript answer so be sure to upvote that one too!
la source
C (gcc),
140132 bytesTry it online!
Basically a port of @Neil's JavaScript answer, but then @ceilingcat shaved off 8 bytes by cleverly reusing
m
andn
to store temporaries.la source
Python 2,
9792 bytesTry it online!
Modified version of Neil's approach.
la source
C (gcc),
7772 bytesTry it online!
Based on the python implementation of @Joel
la source
APL (Dyalog Classic), 21 bytes
Try it online!
based on @Joel's answer
in: 2x2 complex matrix, out: complex pair
la source