बिलियर्ड गेंदों की टक्कर


24

प्रभाव से ठीक पहले बिलियर्ड गेंदों की एक जोड़ी के 2-आयामी पदों और वेगों को देखते हुए, पूरी तरह से लोचदार टक्कर के बाद उनके वेगों की गणना करें । गेंदों को एक ही त्रिज्या, समान द्रव्यमान, समान घनत्व और कोई घर्षण के साथ आदर्श क्षेत्र (या समतुल्य: मंडलियों) के रूप में माना जाता है।

इनपुट 8 नंबर के होते हैं p0x,p0y,v0x,v0y,p1x,p1y,v1x,v1yजहां p0x,p0yपहली गेंद, का केंद्र है v0x,v0yइसकी गति, और इसी प्रकार p1x,p1y,v1x,v1yदूसरी ही गेंद के लिए। आप किसी भी क्रम में इनपुट स्वीकार करते हैं और एक 2x2x2 सरणी, या हो सकता है एक 2x2 सरणी के लिए के रूप में किसी भी सुविधाजनक तरीके से संरचित, जैसे कर सकते हैं pऔर दो लंबाई-2 के लिए सरणियों v0और v1। Xy जोड़े के बजाय जटिल संख्या (यदि आपकी भाषा उन्हें समर्थन करती है) लेना ठीक है। हालांकि, आपको कार्टेशियन के अलावा किसी समन्वय प्रणाली में इनपुट नहीं लेना चाहिए, अर्थात ध्रुवीय अनुमति नहीं है।

ध्यान दें कि एक बिलियर्ड बॉल की त्रिज्या बीच p0x,p0yऔर से आधी दूरी पर है p1x,p1y, इसलिए इसे इनपुट के स्पष्ट भाग के रूप में नहीं दिया गया है।

एक प्रोग्राम या फ़ंक्शन लिखें जो किसी भी सुविधाजनक कार्टेशियन प्रतिनिधित्व में 4 नंबर का आउटपुट या रिटर्न करता है: के टक्कर के बाद के मान v0x,v0y,v1x,v1y

टक्कर आरेख

एक संभव एल्गोरिथ्म है:

  • दोनों केंद्रों से होकर गुजरने वाली सामान्य रेखा को खोजें

  • स्पर्श रेखा को खोजें जो दो केंद्रों के बीच मध्य बिंदु से होकर गुजरती है और सामान्य रेखा के लंबवत है

  • समन्वय प्रणाली को बदलने v0x,v0yऔर v1x,v1yउनके स्पर्शरेखा और सामान्य घटकों v0t,v0nऔर में टूट जाते हैंv1t,v1n

  • के सामान्य घटकों की अदला-बदली करें v0और v1उनके मूर्त घटकों को संरक्षित करें

  • मूल समन्वय प्रणाली में वापस बदलें

परीक्षण (परिणाम 5 दशमलव स्थानों तक):

   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]

सबसे छोटी जीत। कोई खामियां नहीं।


धन्यवाद @Anush आरेख की पृष्ठभूमि के रंग को ठीक करने में मदद करने के लिए

जवाबों:


16

पायथन 3 , 67 66 बाइट्स, 53 बाइट्स

def f(p,v,q,w):p-=q;d=((v-w)/p).real*p;return v-d,w+d

इसे ऑनलाइन आज़माएं!

-1 बाइट थैंक्स टू @ngn

-13 बाइट्स @ @ नील को धन्यवाद

यह फ़ंक्शन fइनपुट के रूप में चार जटिल संख्या लेता है और दो जटिल संख्या देता है। अनलॉक्ड संस्करण को निम्नलिखित में दिखाया गया है।

Ungolfed

def elastic_collision_complex(p1, v1, p2, v2):
    p12 = p1 - p2
    d = ((v1 - v2) / p12).real * p12
    return v1 - d, v2 + d

इसे ऑनलाइन आज़माएं!

गणना सूत्र विकी पर 2D- वेक्टर सूत्र के आधार पर व्युत्पन्न होता है । चूंकि m1=m2 , इस सूत्र के सरल किया जा सकता

{v1=v1dvv2=v2+dv

चलो x12=x1x2 और v12=v1v2 , हमारे पास है

dv=v12,x12x122x12=Re(v12x12¯)x12x12¯x12=Re(v12x12¯x12x12¯)x12=Re(v12x12)x12

Ungolfed कार्यक्रम में, p12, v1 - v2, dके अनुरूप x12 , y12 , और dv , क्रमशः।


1
बहुत बढ़िया! यह दृष्टिकोण रामलीला के 'पर्ल 6' उत्तर से भिन्न दिखता है जो जटिल संख्याओं का भी उपयोग करता है। अगर आप की जगह आप एक बाइट को बचा सकता है r=p-qके साथ p-=qऔर आगे उपयोग pके बजाय rमें की तरह, नील के js जवाब
NGN

1
। मैंने फार्मूला में लिखा था कि पर्ल 6 गोल्फ के लिए अच्छा था, और जोएल ने संभवतः एक का इस्तेमाल किया जो पायथन के लिए बेहतर था। वैसे भी, मुझे नहीं लगता था कि कोई और स्वतंत्र रूप से जटिल संख्याओं का उपयोग करके समाधान के साथ आएगा। बहुत बढ़िया!
रामलीज

3
अच्छा है, लेकिन अगर आप प्रश्न में एल्गोरिथ्म का उपयोग करते हैं तो यह केवल 53 बाइट्स लेगा ...
नील

1
@ नील आपके संकेत के लिए धन्यवाद। गणना अब बहुत सरल है।
जोएल

3
मैं वास्तव में आपके सभी महान समाधान और विस्तृत स्पष्टीकरण पसंद कर रहा हूं!
xnor

11

जावास्क्रिप्ट (Node.js) , 90 88 बाइट्स

(m,n,o,p,q,r,s,t,u=(q-=m)*q+(r-=n)*r,v=o*q+p*r-s*q-t*r)=>[o-(q*=v/u),p-(v*=r/u),s+q,t+v]

इसे ऑनलाइन आज़माएं! लिंक में परीक्षण सूट शामिल है। स्पष्टीकरण: q,rकेंद्रों के बीच अंतर वेक्टर के रूप में पुनर्निर्मित किया जाता है, और uइसकी लंबाई का वर्ग है। और इसके साथ vडॉट उत्पादों में अंतर है , इसलिए इसके लिए स्केलिंग कारक है , जिससे स्थानांतरित किए गए वेग की मात्रा मिलती हैo,ps,tq,rv/uq,ro,ps,t. Edit: Saved 2 bytes thanks to @Arnauld.


मुझे उम्मीद नहीं थी कि कोई इतनी जल्दी इतनी अच्छी तरह से एल्गोरिथ्म को सरल बना देगा! यहाँ आपके समाधान का एक दृश्य है (
अरनुलड

@ng गलत लिंक?
नील

@ नील गिलतब की पाइपलाइन लॉग का कहना है कि यह होना चाहिए। Ctrl + F5? तीर लाल गेंद को नियंत्रित करते हैं। पारी में तेजी। फ़ायरफ़ॉक्स और क्रोमियम में परीक्षण किया गया। चेतावनी: ध्वनि।
ngn

@ng आह, अब काम कर, धन्यवाद! (मुझे पहले एक 404 मिला था। इसके अलावा, मैं एक निजी टैब का उपयोग कर रहा था, इसलिए मुझे डिफ़ॉल्ट रूप से कोई आवाज़ नहीं थी, हालांकि मुझे यह घुसपैठ नहीं लगा था। और मैं क्षुद्रग्रहों पर बेकार हूं, अन्यथा मैं एक "शूट के लिए पूछूंगा" "कुंजी ...)
नील

8

पर्ल 6 ,75 64 63 61 बाइट्स

11 बाइट्स से स्विच द्वारा बचाया mapकरने के लिए for, मध्यवर्ती चर में के लिए चीजों को डाल करने के लिए की आवश्यकता के साथ वितरण mapको देखने के लिए।

1 बाइट बदलकर बचाया ($^a-$^c)².&{$_/abs}करने के लिए ($^a-$^c).&{$_/.conj}

2 बाइट्स ने @nwellnhof को धन्यवाद दिया।

{(.($^b+$^d,{$_/.conj}($^a-$^c)*($b-$d).conj)/2 for *-*,*+*)}

इसे ऑनलाइन आज़माएं!


व्याख्या

जब मूल पोस्ट ने कहा कि इनपुट जटिल संख्याएं हो सकती हैं, तो प्रतिरोध करना बहुत कठिन था ... इसलिए यह 4 जटिल संख्याएं (स्थिति 1, वेग 1, स्थिति 2, वेग 2) लेता है और जटिल संख्याओं के रूप में वेग लौटाता है।

कार्यक्रम ओपी में वर्णित के अनुसार सिर्फ एक ही एल्गोरिथ्म का उपयोग करता है। हालांकि, जटिल संख्याओं के साथ, यह काफी सरल है। सबसे पहले, आइए ध्यान दें कि जटिल संख्या=पी1-पी0पहली गेंद से दूसरी गेंद तक अंक। इसलिए यदि हम इसके द्वारा सभी वेगों को विभाजित करते हैं, तो सामान्य दिशा अचानक वास्तविक अक्ष और काल्पनिक अक्ष के साथ स्पर्शरेखा दिशा से मेल खाती है। (यह परिमाण को गड़बड़ करता है लेकिन हमें परवाह नहीं है।)

अब, हमें वेगों के सामान्य (अर्थात वास्तविक) भागों को स्विच करने की आवश्यकता है v0/ तथा v1/, और उसके बाद, इसे गुणा करें again to make the normal (and the velocities) point in the correct direction (and to unmess the magnitudes). So we need to calculate

v0=d(v1d+iv0d),v1=d(v0d+iv1d)
(where = real part, = imaginary part). Let's shuffle the first one a bit (using for complex conjugation):
v0=d(v1d+iv0d)=d[12(v1d+v1d)+12(v0dv0d)]= =d2(v0+v1dv0v1d)=12(v0+v1dd(v0v1)).
The result for v1 can be obtained just by switching v0v1. All that does is changing a sign:
v1=12[v0+v1+dd(v0v1)].

And that's it. All the program does is just this calculation, golfed a bit.


very cool!­­­­­
ngn

I don't know much about Perl, but I think you could merge the two conjugate computations into one to save some bytes.
Joel

1
@Joel — Sadly, I'm pretty sure I can't. The first conjugate is acting on ($^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).
Ramillies

@Ramillies Thanks for the explanation.
Joel

How is the δ's magnitude relevant? You're just dividing by δ, switching the real components, and then multiplying by δ again.
Neil

3

Jelly, 16 bytes

_/×ḋ÷²S¥_/ʋ¥N,$+

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!


3

C (gcc), 140 132 bytes

f(m,n,o,p,q,r,s,t,a)float*a,m,n,o,p,q,r,s,t;{q-=m;r-=n;m=q*q+r*r,n=o*q+p*r-s*q-t*r;q*=n/m;*a++=o-q;n*=r/m;*a++=p-n;*a++=s+q;*a=t+n;}

Try it online!

Basically a port of @Neil's JavaScript answer, but then @ceilingcat shaved off 8 bytes by cleverly reusing m and n to store temporaries.




हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.