नोट: निम्नलिखित सभी मानते हैं कि गेंद की सतह घर्षण रहित है (इसलिए यह अलग तरीके से घूमना या पलटना शुरू नहीं करेगा क्योंकि यह है)।
टक्कर के समय, गेंद कोने को छू रही होगी। जब ठोस ऑब्जेक्ट टकराते हैं, तो एक बल तथाकथित सतह के साथ-साथ टकराव के बिंदु पर सतह के लंबवत कार्य करेगा।
चूंकि यह एक गेंद है, सतह के लंबवत गेंद के केंद्र की ओर है। ठीक है, तो हम बल की दिशा जानते हैं, इसके परिमाण के बारे में क्या? एक लोचदार टकराव (और यह कि आयत हिल नहीं सकती) मानकर, गेंद को उसी वेग से पुनर्जन्म करना चाहिए जिसके साथ वह प्रभावित हुआ था।
चलो (nDx, nDy) टक्कर के बाद वेग हो, (oDx, oDy) टक्कर से पहले वेग, और टक्कर के बिंदु पर (x, y) गेंद की स्थिति। चलो आगे मान लें कि जिस कोने से गेंद टकराती है वह (0,0) है।
सूत्र के रूप में अपनी अंतर्दृष्टि व्यक्त करते हुए, हमारे पास:
(nDx, nDy) = (oDx, oDy) + c * (x, y)
length (nDx, nDy) = length (oDx, oDy)
जो इसके बराबर है:
nDx = oDx + c * x
nDy = oDy + c * y
nDx^2 + nDy^2 = oDx^2 + oDy^2
पिछले एक में पहले दो समीकरणों को प्रतिस्थापित करते हुए, हमें यह मिलता है:
(oDx + c * x)^2 + (oDy + c * y)^2 = oDx^2 + oDy^2
द्विपद वक्ष का उपयोग कर विस्तार
(a+b)^2 = a^2 + 2ab + b^2
पैदावार:
oDx^2 + 2 * oDx * c * x + (c * x) ^ 2 + oDy^2 + 2 * oDy * c * y + (c * y) ^ 2 = oDx^2 + oDy^2
2 * oDx * c * x + 2 * oDy * c * y + (c * x) ^ 2 + (c * y) ^ 2 = 0
(2 * oDx * x + 2 * oDy * y) * c + (x^2 + y^2) * c^2 = 0
इस द्विघात समीकरण के c
दो समाधान हैं, जिनमें से एक है। जाहिर है, यह वह समाधान नहीं है जिसमें हम रुचि रखते हैं, क्योंकि आम तौर पर टकराव के परिणामस्वरूप गेंद की दिशा बदल जाएगी। अन्य समाधान प्राप्त करने के लिए, हम दोनों पक्षों को c से विभाजित करते हैं और प्राप्त करते हैं:
(2 * oDx * x + 2 * oDy * y) + (x^2 + y^2) * c = 0
अर्थात्:
c = -(2 * oDx * x + 2 * oDy * y) / (x^2 + y^2)
संक्षेप में, हमारे पास है:
c = -(2 * oDx * x + 2 * oDy * y) / (x^2 + y^2)
nDx = oDx + c * x
nDy = oDy + c * y
संपादित करें : कोड में:
if (collision) {
float x = ballX - cornerX;
float y = ballY - cornerY;
float c = -2 * (ballDx * x + ballDy * y) / (x * x + y * y);
ballDx = ballDx + c * x;
ballDy = ballDy + c * y;
}
कुछ कार्यान्वयन के विचार: जब आप अनुकरण कदम के बाद गेंद की स्थिति के साथ (x, y) अनुमानित कर सकते हैं, तो यह सन्निकटन विक्षेपण के कोण को बदल देगा और इसलिए बहुत ध्यान देने योग्य होगा, इसलिए आपके सिमुलेशन चरणों को बहुत ठीक होने की आवश्यकता है (शायद ऐसा ही) गेंद प्रति चरण 1/20 से अधिक इसके डिमैटर पर नहीं चलती है)। अधिक सटीक समाधान के लिए, आप उस समय की गणना कर सकते हैं जब टक्कर होती है, और उस समय पर उस सिमुलेशन कदम को विभाजित करें, यानी टक्कर के बिंदु तक एक आंशिक कदम और शेष चरण के लिए एक और आंशिक कदम।
संपादन 2: प्रभाव के बिंदु को समझना
आज्ञा देना त्रिज्या, (x0, y0) स्थिति और (dx, डाई) सिमुलेशन कदम की शुरुआत में गेंद का वेग। सादगी के लिए, चलो आगे मान लेते हैं कि प्रश्न में कोने (0,0) पर स्थित है।
हम जानते है:
(x,y) = (x0, y0) + (dx, dy) * t
हम चाहते हैं
length(x,y) = r
अर्थात्
(x0 + dx * t) ^ 2 + (y0 + dy * t) ^ 2 = r^2
x0^2 + 2 * x0 * dx * t + dx^2 * t^2 + y0^2 + 2 * y0 * dy * t + dy^2 * t^2 = r ^ 2
(dx^2 + dy^2) * t^2 + (2 * x0 * dx + 2 * y0 * dy) * t + (x0^2 + y0^2 - r^2) = 0
\____ _____/ \____________ ___________/ \_______ ________/
\/ \/ \/
a b c
यह t में एक द्विघात समीकरण है। अगर इसका भेदभाव है
D = b^2 - 4 * a * c
नकारात्मक है, इसका कोई हल नहीं है, अर्थात गेंद अपने वर्तमान पाठ्यक्रम पर कभी भी कोने से नहीं टकराएगी। अन्यथा, इसके दो समाधान द्वारा दिए गए हैं
t1 = (-b - sqrt(D)) / (2 * a)
t2 = (-b + sqrt(D)) / (2 * a)
हम उस समय में रुचि रखते हैं जब टकराव शुरू हुआ, जो पहले का समय है t1
।
आपकी विधि बन जाएगी:
// compute a,b,c and D as given above
if (D >= 0) {
t = (-b - sqrt(D)) / (2 * a);
if (0 < t && t <= ts) {
// collision during this timestep!
x = x + t * dx;
y = y + t * dy;
ts = ts - t;
// change dx and dy using the deflection formula
}
}
x = x + ts * dx;
y = y + ts * dy;