আমি কীভাবে একটি গোলক এবং একটি বিমানের মধ্যে সংঘর্ষের প্রতিক্রিয়া গণনা করব?


9

আমি একটি সাধারণ 3 ডি গেম তৈরি করার চেষ্টা করছি এবং খেলোয়াড়কে গেমের বিশ্বের সীমার মধ্যে সীমাবদ্ধ করা দরকার। খেলোয়াড় যখন বিশ্বের চারদিকে হিট হয় আমি চাই প্লেয়ারের জাহাজটি কিছুটা বাউন্স হয়ে যায়।

বাস্তবে আমি খেলোয়াড়কে একটি বাক্সের মধ্যে আটকে দেওয়ার চেষ্টা করছি এবং তাদের পাশ দিয়ে পালাতে বাধা দেব ...

আমি উত্স থেকে স্বাভাবিক এবং দূরত্ব সহ প্লেনের সংগ্রহ হিসাবে গেমওয়ার্ল্ডের সীমা নির্ধারণ করতে সক্ষম হয়েছি। খেলোয়াড়টির একটি গোলাকার সীমাবদ্ধ গোলক রয়েছে এবং এই ওয়েবসাইটটি অনুসরণ করে http://www.gamasutra.com/view/feature/3383/simple_intersection_tests_for_games.php আমি সংঘর্ষগুলি সনাক্ত করতে সক্ষম হয়েছি।

কোনও সংঘর্ষ শনাক্ত হওয়ার পরে এখন কী করা উচিত তা আমি এখন বেশ পুরোপুরি কাজ করতে পারি না। আমি পরিচালনা করতে পারি সেরাটি হ'ল প্লেয়ারটি বিমানটিতে আটকা পড়ে যাওয়া, সরাসরি তার মধ্য দিয়ে যাওয়া, বা সত্যিই দ্রুত হারে বার বার তাড়ানোর জন্য।

সাধারণ জ্ঞান আমাকে বলে যে আমাকে বিমানের প্রতিবিম্বিত কোণটি গণনা করতে হবে, তার সাধারণ ব্যবহার করে এবং এটি খেলোয়াড়ের বেগের সাথে প্রয়োগ করা উচিত, তবে আমি মনে করি যে প্রথমে আমার প্লেয়ারটি বিমানের মধ্য দিয়ে গেছে যা আমি যা করতে পারি না তা দেখার দরকার think কাজ করা।

উত্তর:


4

আপনাকে আপনার অবজেক্টে একটি প্রবণতা প্রয়োগ করতে হবে, যা এটির বেগের তাত্ক্ষণিক পরিবর্তন। বাস্তব বিশ্বে, একটি শক্তিশালী শক্তি খুব অল্প সময়ের ব্যবধানে অবজেক্টে প্রয়োগ করা হত, এর ত্বরণকে বিপরীত করে তোলে এবং এর গতিবেগ পরিবর্তন করতে পারে। তবে, যেহেতু আমরা একটি বিচ্ছিন্ন বিশ্বে কাজ করছি, তাই হঠাৎ দিকের এই পরিবর্তনটি অনুকরণ করতে আমাদের কিছুটা প্রতারণা করতে হবে। একটি গোলক এবং একটি বিমানের জন্য, এটি বেশ সোজা। সর্বাধিক প্রাথমিক সংঘর্ষের প্রতিক্রিয়াটি হল বিমানটির স্বাভাবিকের চারপাশে গোলকের গতিবেগ প্রতিফলিত করা এবং তারপরে ফলাফলটি হল গোলকের নতুন বেগ। সিউডো-কোডটি এরকম কিছু দেখায়:

reflected = 2 * plane.normal * (plane.normal * sphere.velocity)
sphere.velocity -= reflected

সেখান থেকে, আপনি তাপ বা ঘর্ষণে হারিয়ে যাওয়া শক্তির জন্য অ্যাকাউন্টে কিছু স্যাঁতস্যাঁতে (কিছু গুণফল, ০.৯ এর মতো করে) যোগ করতে পারেন। আপনি যদি কৌণিক বেগ জড়িত থাকতে চান (সম্ভবত আপনার গোলকটি ঘুরছে), তবে সমীকরণগুলি আরও জটিল হয়ে উঠবে।

আরও তথ্যের জন্য, আমি আপনাকে রিজিড বডি ডায়নামিক্সে ক্রিস হেকারের নিবন্ধগুলি উল্লেখ করব । আপনি যদি এর আগে ক্রিস হেককারের কথা না শুনে থাকেন তবে তিনি গেম ফিজিক্স এবং স্পোরের পদ্ধতিগত চরিত্র জেনারেশন এবং অ্যানিমেশন সম্পর্কে তাঁর কাজের জন্য সুপরিচিত।


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

ঠিক আছে এটি বেশিরভাগ কাজ করে বলে মনে হচ্ছে তবে এটি কিছুটা অদ্ভুত। আমি মনে করি আমি আমার কোডের ভুল পয়েন্টে এটি করছি। আমি কি আমার সমস্ত বস্তুর মধ্য দিয়ে লুপ করব এবং যদি সেগুলি স্থানান্তরিত করার আগে তারা সংঘর্ষে চলেছে (তারা পরের ফ্রেমটি কোথায় যাবে তার উপর ভিত্তি করে) বা তাদের স্থানান্তরিত করে এবং তারপরে সংঘর্ষের জন্য পরীক্ষা করা উচিত?
পিকু

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

@ পিকু এবং এটি করার জন্য আমরা অতীতের যে সময় সংঘর্ষের ঘটনাটি ঘটেছে (টিওআই / প্রভাবের সময় বলা হয়) তা খুঁজে বের করি। একবার আমাদের কাছে আসার পরে আমরা বস্তুর গতিটি এটি আবার সরিয়ে নিতে ( distance = speed * timeসাধারণত ত্রুটি এড়ানোর জন্য অতিরিক্ত ক্ষুদ্র দূরত্ব সহ) ব্যবহার করতে পারি এবং তারপরে সংঘর্ষের ফলাফল কী হবে তার বেগটি আপডেট করতে পারি।
জোনাথন ডিকিনসন

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

1

এফ = মা, বা একটি = এফ / এম। গোলক এবং বিমানের মধ্যে সংঘর্ষের পয়েন্ট গণনা করুন। এটি সাধারণত গোলকের কেন্দ্র - স্বাভাবিক * ব্যাসার্ধ। আপনি যদি আরও নির্ভুলতা চান, তাহলে গোলকটি বিমানটি কত দূরত্বে প্রবেশ করেছে তা গণনা করুন এবং আপনার গণনাটি সামঞ্জস্য করুন। এটি অবশ্যই মূলত alচ্ছিক, যদি না আপনি সত্যিই সঠিক পদার্থবিজ্ঞান চান। এখন স্বাভাবিকের সাথে আপেক্ষিক বেগ গণনা করুন। স্ট্যাটিক প্লেনের জন্য এটি: ভলিবল ডট এন। তারপরে ভোলডটনকে -1 দ্বারা গুণিত করুন এবং ভর দিয়ে গুণ করুন। পদার্থবিজ্ঞানে এই পর্যায়ে আপনি পুনঃস্থাপনের গুণাগুণ (বাউন্স ফ্যাক্টর) দ্বারা এটিও গুন করবেন। এই স্কেলারটিকে এন দ্বারা গুণ করুন এবং আপনার শক্তি রয়েছে।

ভবলটি সামঞ্জস্য করার সময়, বলটিকে আবার ভর দিয়ে ভাগ করুন এবং আপনার চূড়ান্ত ত্বরণ হবে, সুতরাং এটি কেবল বেগটিতে যুক্ত করুন এবং আপনার চূড়ান্ত পোস্টের সংঘর্ষের বেগ হবে।

vec3 Vrel = Ball.getVelocity();
float vDotN = Vrel.Dot(CollisionNormal);
vec3 F = -(1.0f+Ball.getRestitution())*vDotN;
F*=Ball.getMass();
Ball.accelerate(F/Ball.getMass());

এই পদ্ধতিটি সংঘর্ষের প্রতিক্রিয়ার সূত্রগুলির সাথে সঠিক। আপনি যদি আরও বেশি নির্ভুলতা চান তবে আপনি ঘর্ষণটি অ্যাকাউন্টে নিতে চাইবেন, যার ফলে বলটি স্পিন হয়ে যাবে, তবে আমি জানি না যে আপনি আপনার খেলায় এটি চান কিনা। আপনি যদি করেন তবে এইভাবে আপনি স্পর্শকাতত্ত্ব শক্তি গণনা করুন:

vec3 Ft = -(Ball.getvelocity()+(vDotN*CollisionNormal));
Ft*=Ball.getKineticFriction()+Wall.getKineticFriction(); //you could fudge these numbers
Ft*=Ball.getMass();
vec3 vec2Centre = Ball.getPosition()-ContactPoint;
vec3 Torque = cross(vec2Centre,Ft);
Ball.AngularAccelerate(Torque/Ball.getMomentofInertia(glm::normalize(Torque)));

কোনও রৈখিক প্রভাব প্রয়োগ করার আগে ফিটটি গণনা করার বিষয়টি নিশ্চিত করুন, বা ঘর্ষণটি সঠিক হবে না।


লাইন না করা উচিত 3 হতে: vec3 F = -CollisionNormal * (1.0f+Ball.getRestitution())*vDotN;?
শীতল শাহ

হ্যাঁ, আমি সেই অংশটি মিস করেছি। এটা ইশারা জন্য ধন্যবাদ।
আয়ান ইয়ং

0

আমি আপনাকে প্রথমে বিমান থেকে দূরত্ব গণনা করার পরামর্শ দেব; এবং তারপরে যখন দূরত্ব <= ব্যাসার্ধের সাথে সংঘর্ষের প্রতিক্রিয়া ঘটে।

তারপরে আপনি দূরত্ব গণনা করতে এটি পরিবর্তন করতে পারেন এবং যদি দূরত্বটি এর চেয়ে কম হয় তবে ব্যাসার্ধের (যার অর্থ বস্তুটি ওভারল্যাপ করে চলেছে) বলগুলি স্থান পরিবর্তন করে এবং তার পরে সংঘর্ষের প্রতিক্রিয়াটি সম্পাদন করা হয়।

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