2010-07-12 14 views
5

मुझे एक एल्गोरिदम बनाने की ज़रूरत है जो पता चलता है कि दो गोलाकार कब टकराते हैं, और, जिस दिशा में टक्कर के बाद कोई तत्काल होगा।क्षेत्र - क्षेत्र टकराव का पता लगाने -> प्रतिक्रिया

मान लें, जब आप पूल टेबल में अपनी टेबल खोलते हैं, तो सभी गेंदें एक दूसरे से "यादृच्छिक रूप से" टकरा रही हैं।

तो, कोड स्वयं लिखना शुरू करने से पहले, मैं सोच रहा था कि वहां पहले से ही इसका कार्यान्वयन हो रहा है या नहीं।

अग्रिम में Thx!

Cyas.-

+0

सबसे मुश्किल हिस्सा स्पिन है ... –

+0

मुझे स्पिन के बारे में परवाह नहीं है, मुझे केवल कॉलिशन और "फ्लैट प्रतिक्रियाएं" की आवश्यकता है। – Artemix

+0

दिशा केंद्रों को जोड़ने वाली रेखा के साथ ही दिशा है। – Mau

उत्तर

7

आप यहाँ एक अच्छा ट्यूटोरियल पा सकते हैं: Link

+0

यकीन है कि यह आदमी, thx होगा। लेकिन, मुझे 3 डी टकराव की आवश्यकता नहीं है, मेरा मतलब है सर्कल - सर्कल कॉलिशन वास्तव में, गोलाकार नहीं है: पी मेरा बुरा। – Artemix

+0

@ आर्टिमिक्स: यदि आप उस पृष्ठ को देखते हैं, तो ऐसा लगता है कि 2 डी में समझाया जा रहा है! अच्छे लेख के लिए +1। –

+0

हां, मैंने देखा कि। – Artemix

7

टक्कर हिस्सा आसान है। जांचें कि गोलाकार केंद्रों के बीच की दूरी उनके त्रिज्या के योग से कम है या नहीं।

बाउंस के लिए, आपको वेग की मात्रा को स्वैप करने की आवश्यकता है जो गोलाकारों की टकराव के लिए लंबवत कुल वेग में योगदान देता है।

struct Vec3 { 
    double x, y, z; 
} 

Vec3 minus(const Vec3& v1, const Vec3& v2) { 
    Vec3 r; 
    r.x = v1.x - v2.x; 
    r.y = v1.y - v2.y; 
    r.z = v1.z - v2.z; 
    return r; 
} 

double dotProduct(const Vec3& v1, const Vec3& v2) { 
    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z; 
} 

Vec3 scale(const Vec3& v, double a) { 
    Vec3 r; 
    r.x = v.x * a; 
    r.y = v.y * a; 
    r.z = v.z * a; 
    return r; 
} 

Vec3 projectUonV(const Vec3& u, const Vec3& v) { 
    Vec3 r; 
    r = scale(v, dotProduct(u, v)/dotProduct(v, v)); 
    return r; 
} 

int distanceSquared(const Vec3& v1, const Vec3& v2) { 
    Vec3 delta = minus(v2, v1); 
    return dotProduct(delta, delta); 
} 

struct Sphere { 
    Vec3 position; 
    Vec3 velocity; 
    int radius; 
} 

bool doesItCollide(const Sphere& s1, const Sphere& s2) { 
    int rSquared = s1.radius + s2.radius; 
    rSquared *= rSquared; 
    return distanceSquared(s1.position, s2.position) < rSquared; 
} 

void performCollision(Sphere& s1, Sphere& s2) { 
    Vec3 nv1; // new velocity for sphere 1 
    Vec3 nv2; // new velocity for sphere 2 
    // this can probably be optimised a bit, but it basically swaps the velocity amounts 
    // that are perpendicular to the surface of the collistion. 
    // If the spheres had different masses, then u would need to scale the amounts of 
    // velocities exchanged inversely proportional to their masses. 
    nv1 = s1.velocity; 
    nv1 += projectUonV(s2.velocity, minus(s2.position, s1.position)); 
    nv1 -= projectUonV(s1.velocity, minus(s1.position, s2.position)); 
    nv2 = s2.velocity; 
    nv2 += projectUonV(s1.velocity, minus(s2.position, s1.position)); 
    nv2 -= projectUonV(s2.velocity, minus(s1.position, s2.position)); 
    s1.velocity = nv1; 
    s2.velocity = nv2; 
} 

संपादित करें (अपने सभी क्षेत्रों मान लिया जाये कि बराबर बड़े पैमाने पर, यह अलग आम जनता का एक संयोजन के लिए अलग अलग हो जाएगा): यदि आप अधिक सटीकता की जरूरत है, तो एक टक्कर पर आप की गणना करना चाहिए कितनी दूर दोनों टकराने क्षेत्रों स्थानांतरित करने के लिए पीछे की ओर ताकि वे एक दूसरे को छूएं, फिर प्रदर्शन टकराव समारोह को ट्रिगर करें। यह बीमा करेगा बीमा कोण अधिक सटीक होगा।

+0

बहुत अच्छा काम करता है - लेकिन मुझे लगता है कि कोई समस्या है: मैं 10 गेंदों (कोई ओवरलैपिंग) से शुरू करता हूं, जहां केवल एक ही वेग होता है - थोड़ी देर के बाद और बहुत सारे उछालते हुए वे सभी आगे बढ़ रहे हैं। अंतराल पर मैं सभी वेगों को जोड़ता हूं (abs (x) + abs (y)) - अगर मैंने शुरुआत की, तो 8 कहें, यह तेजी से बढ़ता है (जिसे संरक्षण कानूनों में से एक का उल्लंघन करना चाहिए?) लेकिन थोड़ी देर के बाद बढ़ता बंद हो जाता है, बस लगभग 20 में उतार-चढ़ाव करता है .. मैं उलझन में हूं और सुनिश्चित नहीं हूं कि मुझे होना चाहिए .. (नोट: टक्कर के बाद पता चला है कि मैं पहले गेंद को पीछे की ओर ले जाता हूं, मिनटों तक, जब तक वे प्रदर्शन को कॉल करने से पहले ओवरलैप नहीं करते हैं) – T4NK3R

+0

प्रत्येक के लिए संक्षेप में प्रयास करें (वर्ग (vx^2 + vy^2))। – clinux

संबंधित मुद्दे