मैं वैक्टर का उपयोग करके यथार्थवादी कार आंदोलन बनाने के लिए देख रहा हूं


12

मैंने यह करने के लिए कैसे गॉगल किया है और यह पाया गया है http://www.helixsoft.nl/articles/circle/sincos.htm मुझे इस पर एक जाना पड़ा है, लेकिन अधिकांश कार्य जो दिखाए गए थे वे काम नहीं करते थे मुझे सिर्फ त्रुटियां मिलीं क्योंकि वे मौजूद नहीं थे। मैंने कॉस और पाप कार्यों को देखा है, लेकिन समझ में नहीं आता है कि उन्हें कैसे उपयोग किया जाए या वैक्टर का उपयोग करके कार आंदोलन को सही तरीके से कैसे काम किया जाए। मेरे पास कोई कोड नहीं है क्योंकि मुझे यकीन नहीं है कि मुझे क्या करना है।

किसी भी मदद की सराहना की है।

संपादित करें:

मेरे पास प्रतिबंध है कि मुझे अपने खेल के लिए TL इंजन का उपयोग करना चाहिए, मुझे किसी भी प्रकार के भौतिकी इंजन को जोड़ने की अनुमति नहीं है। इसे c ++ में प्रोग्राम किया जाना चाहिए। यहाँ एक नमूना है जो मुझे उस लिंक का पालन करने की कोशिश से मिला है जो मैंने प्रदान की गई लिंक में किया था।

if(myEngine->KeyHeld(Key_W))
    {
        length += carSpeedIncrement;
    }
    if(myEngine->KeyHeld(Key_S))
    {
        length -= carSpeedIncrement;
    }
    if(myEngine->KeyHeld(Key_A))
    {
        angle -= carSpeedIncrement;
    }
    if(myEngine->KeyHeld(Key_D))
    {
        angle += carSpeedIncrement;
    }

    carVolocityX = cos(angle);
    carVolocityZ = cos(angle);

    car->MoveX(carVolocityX * frameTime);
    car->MoveZ(carVolocityZ * frameTime);

: स्टीयरिंग व्यवहार के लिए इस साइट की जाँच करें red3d.com/cwr/steer
MichaelHouse

आपको "यथार्थवादी कार आंदोलन" को परिभाषित करने की आवश्यकता है
माईक सेमर

1
मुझे लगता है कि आपका कोण स्टीयरिंग व्हील से आता है, शायद। लंबाई आपके वेग की परिमाण होनी चाहिए। तो पिछले कोड स्निपेट की तर्ज पर कुछ हो सकता है: carVecloityX = length* cos(angle);, carVelocityZ = length *sin(angle);, इसके अलावा, कृपया बताएं कि आपके इनपुट है और कैसे कार व्यवहार करना चाहिए। अभी, इसे ग्राउंड प्लेन में चलना चाहिए, लेकिन फिर, यह बिल्कुल भी सामान्य नहीं है। वहाँ आपने अभी हमें एक कच्चे यूलर इंटीग्रेशन स्टेप बनाया है ..
टेओड्रॉन

जवाबों:


23

यह एक अच्छा कार आंदोलन बनाने के लिए कठिन नहीं है (लेकिन यह पोस्ट बहुत लंबी होगी)। कार को भौतिक रूप से गतिशील बनाने के लिए आपको कुछ बुनियादी ताकतों को "अनुकरण" करना होगा।

(सभी कोड नमूने स्यूडोकोड हैं।)

त्वरण

सबसे पहले, आपको स्पष्ट रूप से त्वरण की आवश्यकता होगी। निम्नलिखित पंक्ति के रूप में कुछ सरल होगा:

acceleration_vector = forward_vector * acceleration_input * acceleration_factor
  • forward_vector - कार के समान दिशा में एक वेक्टर इंगित करता है।
  • acceleration_input - इनपुट अंतराल में होना चाहिए [-1, 1]।
  • acceleration_factor - त्वरण का मान (पिक्सेल / सेकंड ^ 2, या जो भी आपकी इकाइयाँ हैं)।

स्टीयरिंग

स्टीयरिंग भी काफी सरल है। सिद्धांत रूप में, आप क्या करेंगे कार के आगे वेक्टर को घुमाने के लिए इसे किसी अन्य दिशा में इंगित करने के लिए।

steer_angle = steer_input * steer_factor
new_forward_vector = rotate_around_axis(forward_vector, up_vector, steer_angle)

हालाँकि, आप यहाँ एक जटिलता का सामना कर सकते हैं। यदि आपका इनपुट कीबोर्ड के माध्यम से है, तो इसका मूल्य -1 या 1 होगा, जिसका अर्थ है कि आपकी कार तुरंत बदल जाएगी। आप इसे एक बहुत ही सरल रैखिक प्रक्षेप (लेरिंग) का उपयोग करके ठीक कर सकते हैं:

 amount = time_since_last_frame * steer_lerp_factor
 forward_vector = lerp(forward_vector, new_forward_vector, amount)

राशि इस तरह के समय पर निर्भर होनी चाहिए कि आपका आंदोलन आपके फ्रेम दर पर निर्भर न हो। यह राशि [0, 1] के बीच होनी चाहिए और यह जितनी छोटी होगी, पुराने और नए वैक्टर के बीच संक्रमण उतना ही कम होगा।

(इस बिंदु पर आप पाएंगे कि कार खड़ी रहेगी भले ही वह खड़ी हो। इसे रोकने के लिए, गुणा steer_angleकरके current_speed / max_speed, जहाँ max_speedआपके द्वारा परिभाषित किया गया है।)

चलती

अब हम त्वरण लागू करेंगे और कार को उसके वेग, त्वरण और स्टीयरिंग के आधार पर निश्चित संख्या में पिक्सेल ले जाएँगे। हम कार की गति को भी सीमित करना चाहते हैं, ताकि यह अनंत तेजी से आगे बढ़ न जाए।

current_speed = velocity_vector.norm()
if (current_speed < max_speed)
{
    velocity_vector += acceleration_vector * time_since_last_frame
}

position_vector += velocity_vector * time_since_last_frame

आपकी कार अब फिसलने लगी है

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

आपको पार्श्व वेग को कम करने की आवश्यकता होगी। इसे पूरी तरह से कम न करके आप कार को बहती हुई भी बना सकते हैं।

 lateral_velocity = right_vector * dot(velocity_vector, right_vector)
 lateral_friction = -lateral_velocity * lateral_friction_factor 

चूँकि हम घर्षण के बारे में बात कर रहे हैं, आप एक बल (घर्षण का) भी चाहते हैं जो आपके वेग को कम कर दे, जैसे कि जब आप तेजी को रोकते हैं, तो आपकी कार अंततः बंद हो जाएगी।

 backwards_friction = -velocity_vector * backwards_friction_factor

कार को स्थानांतरित करने के लिए आपका कोड अब इस तरह दिखना चाहिए:

// Friction should be calculated before you apply the acceleration
lateral_velocity = right_vector * dot(velocity_vector, right_vector)
lateral_friction = -lateral_velocity * lateral_friction_factor
backwards_friction = -velocity_vector * backwards_friction_factor
velocity_vector += (backwards_friction + lateral_friction) * time_since_last_frame


current_speed = velocity_vector.norm()
if (current_speed < max_speed)
{ 
    velocity_vector += acceleration_vector * time_since_last_frame
}

position_vector += velocity_vector * time_since_last_frame

नोट बंद करना

मैंने उल्लेख किया कि आपको स्टीयरिंग पर लेरिंग कैसे लागू करना चाहिए; मुझे लगता है कि आपको त्वरण के लिए एक ही काम करने की आवश्यकता हो सकती है और संभवतः स्टीयर कोण के लिए भी (आपको पिछले फ्रेम से उनके मूल्यों को संग्रहीत करना होगा और उसी से एलआरपी करना होगा)। कार के सापेक्ष सभी वैक्टर (आगे, दाएं, ऊपर) की लंबाई 1 होनी चाहिए।

इसके अलावा, घर्षण थोड़ा अधिक जटिल है जितना मैंने यहां दिखाया है। आपको हमेशा यह सुनिश्चित करना चाहिए कि इसकी लंबाई कार स्टॉप बनाने के लिए आवश्यक त्वरण से अधिक नहीं है (अन्यथा घर्षण कार को विपरीत दिशा में ले जाएगा)। तो आपके पास कुछ ऐसा होना चाहिए:

dt = time_since_last_frame
backwards_friction.resize(min(backwards_friction.norm(), velocity_vector.norm() / dt))
lateral_friction.resize(min(lateral_friction.norm(), lateral_velocity.norm() / dt))

वाह, यह बहुत अच्छा जवाब है!
ईज़ोलोटको

0

आपके प्रश्न से निर्णय लेते हुए, मैं आपको प्रोग्रामिंग के लिए अपेक्षाकृत नया मानने जा रहा हूं (जो कि एक ठीक-ठीक btw है!)। मैं मौजूदा फ्रेमवर्क का उपयोग करने का सुझाव दूंगा क्योंकि यथार्थवादी कार सिमुलेशन सही होने के लिए भौतिकी के सबसे कठिन पहलुओं में से एक है।

आपने 2D / 3D प्रतिबंधों का उल्लेख नहीं किया है, इसलिए मैं आगे बढ़ने जा रहा हूं और आपको सुझाव दूंगा कि आप हॉक एसडीके (गैर-व्यावसायिक उपयोग के लिए मुफ्त) डाउनलोड करें और एक साधारण डेमो प्राप्त करें और चलाएं (वे वास्तव में डेमो हैं जो बॉक्स से बाहर निकलते हैं [मिलते हैं] आपके सिस्टम पर संकलित, सभी कोड है], आपको इसे संकलित करने के लिए कुछ भी करने की ज़रूरत नहीं है ... बस परियोजना खोलें और बिल्ड बनाएं)।

एक बार जब आप कार भौतिकी के पर्दे के पहलुओं के पीछे कुछ विचार रखते हैं (हालांकि आप भौतिकी के वास्तविक कार्यान्वयन को नहीं देखेंगे, जो छिपा हुआ है, तो आपको इंटरफेस देखने को मिलेगा), मेरा मानना ​​है कि आप बेहतर स्थिति में होंगे जब आप अपने दम पर शुरू करते हैं, तो इसे ठीक करने के लिए।

मैंने भी कुछ समय पहले ऐसा ही सवाल पूछा था। वहाँ के लिंक भी मदद कर सकते हैं। और यहाँ एक और लिंक है


अपने संपादन को देखने के बाद, ऐसा लगता है कि आप गणना किए गए कोणों के आधार पर बस कार के वेग को बदलना चाहते हैं (जो कि वास्तविक btw नहीं है, इसलिए आपको उस प्रतिबिंबित करने के लिए मूल प्रश्न को बदलना चाहिए)। यदि कोण प्रश्न का हिस्सा है (जिसे आप बदल नहीं सकते हैं) और नए वेग की गणना करने के लिए आपको कोणों का उपयोग करना होगा, तो टिप्पणी में @teodron के साथ जाएं।

एक अन्य तरीका केवल वैक्टर का उपयोग करना है। वैक्टर का उपयोग करते हुए कई दृष्टिकोण हैं, मैं एक प्रस्तुत करने जा रहा हूं।

एक वेग दिशा है * परिमाण (जहां परिमाण गति और दिशा एक सामान्य वेक्टर है)। कार की वर्तमान गति और दिशा की गणना करें। दिशा लें और इसमें एक वेक्टर जोड़ें (इसे कॉल करें D') जो इसे लंबवत है। इससे कार का वेग बदल जाएगा। किसी भी कोण के साथ गड़बड़ करने के लिए (यद्यपि आप लंब वेक्टर की लंबाई निर्धारित करने के लिए कोण का उपयोग कर सकते हैं जो आप कारक हो सकते हैं [नीचे देखें])

गणना कैसे करेंD' : लंबवत वेक्टर को खोजने के लिए, मूल वेग की दिशा लें, इसे स्क्रीन की ओर आने वाली दिशा वेक्टर से पार करें, जहां आप वेक्टर को दिशा निर्धारित करते हुए वैक्टर को पार करते हैं। फिर कुछ मोड़ कारक के साथ कई इस लंबवत कारक जो यह निर्धारित करता है कि कार कितनी तेजी से मोड़ रही है।


मुझे लेकिन मुझे भौतिकी इंजन का उपयोग करने की अनुमति नहीं है, खेल 3 डी है और मुझे जो कुछ भी बदलने की आवश्यकता है वह है एक्स और जेड वैक्टर मैं बस उन्हें बाहर काम करने की आवश्यकता है जो वे हैं।
ब्रेमहेमैक

@ ब्रेमहेमेक: क्या यह एक होमवर्क सवाल है? यदि हाँ, तो अपने प्रश्न को संपादित करें जो आपके पास प्रतिबंध है और शायद कुछ प्रासंगिक कोड पोस्ट करें ताकि हमारे पास कुछ बनाने के लिए हो। Btw, अंतिम लिंक हो सकता है कि आप कार्यक्षमता को समझने के संदर्भ में क्या देख रहे हैं।
समोरसा

मैंने आपके द्वारा अनुरोधित जानकारी को जोड़ दिया है और प्रदान किए गए लिंक को देखा है लेकिन फिर भी यह समझ में नहीं आता है।
बवहेमेक

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