स्टैक ओवरफ्लो समुदाय की मदद से मैंने एक बहुत ही बुनियादी लेकिन मजेदार भौतिकी सिम्युलेटर लिखा है।
आप एक गेंद लॉन्च करने के लिए माउस को क्लिक करते हैं और खींचते हैं। यह चारों ओर उछल जाएगा और अंततः "मंजिल" पर रुक जाएगा।
मेरी अगली बड़ी विशेषता जो मैं जोड़ना चाहता हूं वह है बॉल टू बॉल टक्कर। गेंद की गति कुल्हाड़ी और y गति वेक्टर में टूट जाती है। मेरे पास गुरुत्वाकर्षण है (प्रत्येक चरण में y वेक्टर की छोटी कमी), मुझे घर्षण है (दोनों वैक्टर की छोटी कमी प्रत्येक दीवार से टकराती है)। गेंद ईमानदारी से आश्चर्यजनक रूप से चारों ओर घूमती है।
मुझे लगता है कि मेरे प्रश्न के दो भाग हैं:
- बॉल टू बॉल टकराव का पता लगाने का सबसे अच्छा तरीका क्या है?
क्या मेरे पास एक O (n ^ 2) लूप है जो प्रत्येक गेंद पर पुनरावृत्त करता है और यह देखने के लिए हर दूसरी गेंद की जांच करता है कि क्या यह त्रिज्या ओवरलैप है? - गेंद को गेंद से टकराने के लिए मैं किन समीकरणों का उपयोग करता हूं? भौतिकी 101
यह दो गेंदों की गति x / y वैक्टर को कैसे प्रभावित करता है? परिणामी दिशा दो गेंदों को किस दिशा में ले जाती है? मैं इसे प्रत्येक गेंद पर कैसे लागू करूं?
"दीवारों" की टक्कर का पता लगाने से निपटने और परिणामस्वरूप वेक्टर परिवर्तन आसान थे लेकिन मुझे गेंद-गेंद टकराव के साथ अधिक जटिलताएं दिखाई देती हैं। दीवारों के साथ मुझे बस उपयुक्त एक्स या वाई वेक्टर का नकारात्मक लेना था और इसे सही दिशा में जाना होगा। गेंदों के साथ मुझे नहीं लगता कि यह इस तरह है।
कुछ त्वरित स्पष्टीकरण: सादगी के लिए मैं अब के लिए एक पूरी तरह से लोचदार टकराव के साथ ठीक हूं, मेरी सभी गेंदों में अभी एक ही द्रव्यमान है, लेकिन मैं भविष्य में इसे बदल सकता हूं।
संपादित करें: संसाधन जिन्हें मैंने उपयोगी पाया है
वैक्टर के साथ 2d बॉल फिजिक्स: ट्रिगोनोमेट्री के बिना 2-डायमेंशनल कॉल्स। पीपीडी
2 डी बॉल टकराव का पता लगाने का उदाहरण: कोलिशन डिटेक्शन जोड़ना
सफलता!
मैं गेंद टकराव का पता लगाने और प्रतिक्रिया महान काम कर रहा है!
प्रासंगिक कोड:
टक्कर की पहचान हुई है:
for (int i = 0; i < ballCount; i++)
{
for (int j = i + 1; j < ballCount; j++)
{
if (balls[i].colliding(balls[j]))
{
balls[i].resolveCollision(balls[j]);
}
}
}
यह हर गेंद के बीच टकराव की जाँच करेगा, लेकिन निरर्थक जाँच छोड़ें (यदि आपको जाँचना है कि क्या गेंद 1 गेंद 2 से टकराती है तो आपको यह जाँचने की ज़रूरत नहीं है कि क्या गेंद 2 गेंद से टकराती है। साथ ही, यह अपने आप टकराव की जाँच कर लेती है )।
फिर, मेरी बॉल क्लास में मेरे टकराने () और सॉलोकेशन () तरीके हैं:
public boolean colliding(Ball ball)
{
float xd = position.getX() - ball.position.getX();
float yd = position.getY() - ball.position.getY();
float sumRadius = getRadius() + ball.getRadius();
float sqrRadius = sumRadius * sumRadius;
float distSqr = (xd * xd) + (yd * yd);
if (distSqr <= sqrRadius)
{
return true;
}
return false;
}
public void resolveCollision(Ball ball)
{
// get the mtd
Vector2d delta = (position.subtract(ball.position));
float d = delta.getLength();
// minimum translation distance to push balls apart after intersecting
Vector2d mtd = delta.multiply(((getRadius() + ball.getRadius())-d)/d);
// resolve intersection --
// inverse mass quantities
float im1 = 1 / getMass();
float im2 = 1 / ball.getMass();
// push-pull them apart based off their mass
position = position.add(mtd.multiply(im1 / (im1 + im2)));
ball.position = ball.position.subtract(mtd.multiply(im2 / (im1 + im2)));
// impact speed
Vector2d v = (this.velocity.subtract(ball.velocity));
float vn = v.dot(mtd.normalize());
// sphere intersecting but moving away from each other already
if (vn > 0.0f) return;
// collision impulse
float i = (-(1.0f + Constants.restitution) * vn) / (im1 + im2);
Vector2d impulse = mtd.normalize().multiply(i);
// change in momentum
this.velocity = this.velocity.add(impulse.multiply(im1));
ball.velocity = ball.velocity.subtract(impulse.multiply(im2));
}
स्रोत कोड: बॉल को बॉल कोलाइडर के लिए पूर्ण स्रोत।
अगर किसी के पास इस बुनियादी भौतिकी सिम्युलेटर को बेहतर बनाने के लिए कुछ सुझाव हैं तो मुझे बताएं! एक चीज़ जो मुझे अभी तक मिलनी है वह है कोणीय गति इसलिए गेंदें अधिक वास्तविक रूप से चलेंगी। कोई अन्य सुझाव? एक टिप्पणी छोड़ें!
Vector2d impulse = mtd.multiply(i);
मैं * सामान्यीकृत mtd वेक्टर होना चाहिए। कुछ इस तरह:Vector2d impulse = mtd.normalize().multiply(i);