আমি ভেক্টরগুলি ব্যবহার করে বাস্তববাদী গাড়ি চলাচল তৈরি করতে চাই


12

আমি কীভাবে এটি করব এবং এই http://www.helixsoft.nl/articles/circle/sincos.htm এ আমি খুঁজে পেয়েছি তবে বেশিরভাগ ফাংশন যা দেখানো হয়েছিল তা কাজ করে নি আমি কেবল ত্রুটি পেয়েছি কারণ তাদের অস্তিত্ব ছিল না। আমি কোস এবং পাপ ফাংশনগুলির দিকে নজর রেখেছি তবে কীভাবে সেগুলি ব্যবহার করব বা কীভাবে ভেক্টরগুলি ব্যবহার করে গাড়ি চলাচল করতে হবে তা বুঝতে পারি না। আমার কোনও কোড নেই কারণ আমি কী করব তা নিশ্চিত নই।

কোন সাহায্য প্রশংসা করা হয়।

সম্পাদনা করুন:

আমার বিধিনিষেধ আছে যে আমাকে আমার গেমের জন্য টিএল ইঞ্জিন অবশ্যই ব্যবহার করতে হবে, আমাকে কোনও ধরণের পদার্থবিজ্ঞান ইঞ্জিন যুক্ত করার অনুমতি নেই। এটি অবশ্যই সি ++ এ প্রোগ্রাম করা উচিত। আমার দেওয়া লিঙ্কটিতে যা করা হয়েছিল তা অনুসরণ করার চেষ্টা করে আমি কী পেয়েছি তার একটি নমুনা এখানে is

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

নোট বন্ধ হচ্ছে

আমি উল্লেখ করেছি যে আপনি স্টিয়ারিংয়ে কীভাবে লার্পিং প্রয়োগ করবেন; আমি মনে করি ত্বরণের জন্য এবং সম্ভবত স্টিয়ার এঙ্গলের জন্য আপনার একই জিনিসটি করার প্রয়োজন হতে পারে (আপনাকে পূর্বের ফ্রেম থেকে তাদের মানগুলি সংরক্ষণ করতে হবে এবং এটি থেকে lerp করতে হবে)। এছাড়াও গাড়ীর সাথে সম্পর্কিত সমস্ত ভেক্টরগুলির (এগিয়ে, ডান, উপরে) দৈর্ঘ্য 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))

বাহ, এটি একটি দুর্দান্ত উত্তর!
ezolotko

0

আপনার প্রশ্নটি বিচার করে, আমি ধরে নিচ্ছি আপনি প্রোগ্রামিংয়ে তুলনামূলকভাবে নতুন (যা একটি-ঠিক বিটিডব্লু!)। আমি বিদ্যমান ফ্রেমওয়ার্কগুলি ব্যবহার করার পরামর্শ দেব কারণ বাস্তবের গাড়ি সিমুলেশন সঠিকভাবে পদার্থবিজ্ঞানের অন্যতম কঠিন দিক।

আপনি 2 ডি / 3 ডি নিষেধাজ্ঞাগুলি উল্লেখ করেন নি তাই আমি এগিয়ে যেতে পরামর্শ দিচ্ছি যে আপনি হাভোক এসডিকে ডাউনলোড করুন (অ-বাণিজ্যিক ব্যবহারের জন্য নিখরচায়) এবং একটি সরল ডেমো আপ এবং চালিয়ে যাবেন (তাদের আসলে ডেমো রয়েছে যা বাক্সের বাইরে চলে গেছে [পান আপনার সিস্টেমে সংকলিত, সমস্ত কোড রয়েছে], এটি সংকলন করার জন্য আপনাকে কিছু করার দরকার নেই ... কেবলমাত্র প্রকল্পটি খুলুন এবং বিল্ডটি হিট করুন)।

একবার আপনি গাড়ী পদার্থবিজ্ঞানের পর্দার পিছনে কিছু ধারণা পেয়েছেন (যদিও আপনি পদার্থবিজ্ঞানের প্রকৃত বাস্তবায়ন দেখতে পাবেন না, এটি লুকানো আছে, আপনি ইন্টারফেসগুলি দেখতে পাবেন), আমি বিশ্বাস করি আপনি আরও ভাল অবস্থানে থাকবেন আপনার নিজের থেকে শুরু করার সময় এটি সঠিকভাবে পেতে।

আমিও খুব বেশিদিন আগে একই জাতীয় প্রশ্ন জিজ্ঞাসা করেছি । সেগুলির লিঙ্কগুলি পাশাপাশি সহায়তা করতে পারে। এবং এখানে অন্য লিঙ্ক


আপনার সম্পাদনাটি দেখার পরে মনে হচ্ছে আপনি গণনাকৃত কোণগুলির উপর নির্ভর করে কেবল গাড়ির গতিবেগ পরিবর্তন করতে দেখছেন (এটি বাস্তবিক বিটিডব্লিউ নয়, তাই এটি প্রতিফলিত করার জন্য আপনার মূল প্রশ্নটি পরিবর্তন করা উচিত)। যদি কোণগুলি প্রশ্নের অংশ হয় (যে আপনি পরিবর্তন করতে পারবেন না) এবং আপনাকে নতুন বেগ গণনা করতে কোণগুলি ব্যবহার করতে হয়, তবে @ টিওড্রন মন্তব্যগুলিতে কী রেখেছেন তা দিয়ে যান।

অন্য উপায় হ'ল কেবল ভেক্টর ব্যবহার করা। ভেক্টর ব্যবহার করে একাধিক পদ্ধতি রয়েছে, আমি একটি উপস্থাপন করতে যাচ্ছি।

একটি বেগ হ'ল দিক * মাত্রা (যেখানে পরিধিটি গতি এবং দিকটি একটি স্বাভাবিক ভেক্টর)। গাড়ির বর্তমান গতি এবং দিক গণনা করুন। দিকটি ধরুন এবং এর জন্য একটি ভেক্টর যুক্ত করুন (আসুন এটি কল করুন D') এটির জন্য এটি লম্ব। এটি গাড়ির গতিবেগ পরিবর্তন করবে। আশেপাশে কোন কোণ নেই (যদিও আপনি লম্ব ভেক্টরের দৈর্ঘ্য নির্ধারণ করতে কোণ ব্যবহার করতে পারেন যা আপনি কারণ হয়ে উঠতে পারেন [নীচে দেখুন])

কীভাবে গণনা করবেনD' : লম্ব লম্বা ভেক্টরটি সন্ধান করতে, মূল বেগের দিকটি ধরুন, স্ক্রিনের দিকে আসার দিক ভেক্টরটি দিয়ে এটি ক্রস করুন যেখানে আপনি ভেক্টরগুলিকে ক্রম করুন যাতে লম্ব লম্বা ভেক্টরের দিক নির্ধারণ করে। তারপরে কিছু ঘুরিয়ে ফ্যাক্টর সহ এই পেরিপিকুলার ফ্যাক্টরটিকে একাধিক করুন যা নির্ধারণ করে যে গাড়িটি কত দ্রুত গাড়ি ঘুরছে।


আমি চাইব তবে আমার কোনও পদার্থবিজ্ঞানের ইঞ্জিন ব্যবহার করার অনুমতি নেই, গেমটি থ্রিডি এবং আমার যে পরিবর্তন করতে হবে তা হ'ল এক্স এবং জেড ভেক্টরগুলি কেবল তাদের কী তা নিয়ে কাজ করা দরকার।
বোবথেম্যাক

@ ববথেম্যাক: এটি কি হোমওয়ার্কের প্রশ্ন? যদি হ্যাঁ, আপনার প্রতিবন্ধকতাগুলি নির্দেশ করতে আপনার প্রশ্নটি সম্পাদনা করুন এবং সম্ভবত কিছু প্রাসঙ্গিক কোড পোস্ট করুন যাতে আমাদের তৈরির জন্য কিছু থাকে। বিটিডব্লিউ, শেষ লিঙ্কটি আপনি কার্যকারিতা বোঝার ক্ষেত্রে যা খুঁজছেন তা হতে পারে।
সমুরসার

আপনার অনুরোধ করা তথ্য আমি যুক্ত করেছি এবং প্রদত্ত লিঙ্কগুলিতে সন্ধান করেছি কিন্তু এখনও তা বুঝতে পারি না।
bobthemac

@ ববথেম্যাক: আমার সম্পাদনা দেখুন
সমুরসা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.