আমি কীভাবে মাধ্যাকর্ষণ বাস্তবায়ন করতে পারি? কোনও নির্দিষ্ট ভাষার জন্য নয়, কেবলমাত্র সিউডোকোড ...
আমি কীভাবে মাধ্যাকর্ষণ বাস্তবায়ন করতে পারি? কোনও নির্দিষ্ট ভাষার জন্য নয়, কেবলমাত্র সিউডোকোড ...
উত্তর:
অন্যরা যেমন মন্তব্যে উল্লেখ করেছেন, টেনপেনের উত্তরে বর্ণিত বুনিয়াদি ইউলার সংহতকরণ পদ্ধতিটি কয়েকটি সমস্যা ভোগ করে:
এমনকি সাধারণ গতির জন্য যেমন ধ্রুবক মহাকর্ষের অধীনে ব্যালিস্টিক জাম্পিংয়ের মতো এটি নিয়মতান্ত্রিক ত্রুটির পরিচয় দেয়।
ত্রুটিটি টাইমস্টেপের উপর নির্ভর করে, যার অর্থ টাইমস্টেপ পরিবর্তন করা অবজেক্ট ট্র্যাজেক্টরিগুলিকে একটি নিয়মতান্ত্রিক উপায়ে পরিবর্তন করে যা খেলাগুলি খেয়াল করতে পারে যদি গেমটি একটি চলক টাইমস্টেপ ব্যবহার করে। এমনকি স্থির পদার্থবিজ্ঞানের টাইমস্টেপযুক্ত গেমগুলির ক্ষেত্রেও, বিকাশের সময় টাইমস্টেপ পরিবর্তন করা গেমের পদার্থবিজ্ঞানের উপর প্রভাব ফেলতে পারে যেমন নির্দিষ্ট প্রদত্ত কোনও বাহিনী নিয়ে যে বস্তুটি যাত্রা করবে তার দূরত্ব সম্ভাব্যভাবে পূর্বের নকশা করা স্তরগুলি ভঙ্গ করে।
অন্তর্নিহিত পদার্থবিজ্ঞানের উচিত হলেও এটি শক্তি সংরক্ষণ করে না। বিশেষত, যে সমস্ত বস্তুগুলি অবিচ্ছিন্নভাবে দোলিত হওয়া উচিত (যেমন পেনডুলাম, ঝর্ণা, গ্রহ প্রদক্ষিণ গ্রহ ইত্যাদি) পুরো সিস্টেমটি বিচ্ছিন্ন না হওয়া পর্যন্ত অবিচ্ছিন্নভাবে শক্তি সঞ্চয় করতে পারে।
ভাগ্যক্রমে, প্রায় সাধারণ হিসাবে এমন কিছু দিয়ে অুলার সংহতকরণ প্রতিস্থাপন করা কঠিন নয় , তবুও এর মধ্যে কোনও সমস্যা নেই - বিশেষত, দ্বিতীয়-ক্রমের সিম্প্লেফিক ইন্টিগ্রেটার যেমন লিফফ্রোগ ইন্টিগ্রেশন বা ঘনিষ্ঠভাবে সম্পর্কিত বেগ ভার্টিট পদ্ধতি হিসাবে । বিশেষত, যেখানে বেসিক এলিউর ইন্টিগ্রেশন গতি এবং অবস্থান হিসাবে আপডেট করে:
ত্বরণ = বল (সময়, অবস্থান) / ভর; সময় + = টাইমস্টেপ; অবস্থান + = টাইমস্টেপ * বেগ; বেগ + = টাইমস্টেপ * ত্বরণ;
বেগ ভার্টিট পদ্ধতিটি এটির মতো করে:
ত্বরণ = বল (সময়, অবস্থান) / ভর; সময় + = টাইমস্টেপ; অবস্থান + = টাইমস্টেপ * ( বেগ + টাইমস্টেপ * ত্বরণ / 2) ; newAcceleration = বল (সময়, অবস্থান) / ভর; বেগ + = টাইমস্টেপ * ( ত্বরণ + নতুনচক্র) / 2 ;
আপনার যদি একাধিক ইন্টারঅ্যাক্টিং অবজেক্ট থাকে তবে আপনার বাহিনীটি পুনরায় গণনা করার এবং বেগগুলি আপডেট করার আগে তাদের সমস্ত অবস্থান আপডেট করা উচিত । নতুন ত্বরণ (গুলি) তারপরে পরবর্তী টাইমস্টেপে পজিশনগুলি আপডেট করতে ব্যবহার করা force()
যেতে পারে, যেমন এলারের পদ্ধতির মতো কল টাইমসটি টাইপস্টেপ থেকে এক (প্রতি বস্তু) তে নামিয়ে আনা হয়।
এছাড়াও, যদি ত্বরণটি স্বাভাবিকভাবে ধ্রুব থাকে (ব্যালিস্টিক জাম্পিংয়ের সময় মহাকর্ষের মতো) তবে আমরা উপরেরটিকে কেবল সহজ করতে পারি:
সময় + = টাইমস্টেপ; অবস্থান + = টাইমস্টেপ * ( বেগ + টাইমস্টেপ * ত্বরণ / 2) ; বেগ + = টাইমস্টেপ * ত্বরণ;
যেখানে মৌলিক ইউলার একীকরণের তুলনায় গা bold় মধ্যে অতিরিক্ত শব্দটি একমাত্র পরিবর্তন।
অয়লার একীকরণের সাথে তুলনা করে, বেগ ভার্টেল এবং লিপফ্রোগের পদ্ধতিগুলির বেশ কয়েকটি দুর্দান্ত বৈশিষ্ট্য রয়েছে:
ধ্রুবক ত্বরণের জন্য, তারা সঠিক ফলাফল দেয় (যাইহোক যাইহোক ভাসমান পয়েন্ট রাউন্ডফ ত্রুটি পর্যন্ত), মানে ব্যালিস্টিক জাম্প ট্র্যাজেটরিগুলি একইভাবে থাকে যদিও টাইমস্টেপ পরিবর্তন করা হয়।
তারা দ্বিতীয় ক্রম সংহতকারী, যার অর্থ, এমনকি বিভিন্ন ত্বরণের সাথেও, গড় সংহতকরণ ত্রুটি কেবল টাইমস্টেপের বর্গক্ষেত্রের সমানুপাতিক। এটি নির্ভুলতার সাথে আপস না করে বৃহত্তর টাইমস্টেপগুলি মঞ্জুরি দিতে পারে।
এইগুলি হল symplectic , যার মানে হল তারা শক্তি সঞ্চয় করে অন্তর্নিহিত পদার্থবিদ্যা (যতদিন timestep ধ্রুবক যেমন অন্তত) না। বিশেষত, এর অর্থ হ'ল গ্রহগুলি তাদের কক্ষপথ থেকে স্বতঃস্ফূর্তভাবে উড়ে যাওয়ার মতো জিনিসগুলি, বা ঝর্ণা সহ একে অপরের সাথে সংযুক্ত জিনিসগুলি ধীরে ধীরে আরও কিছুটা ঘুরে বেড়াচ্ছে যতক্ষণ না পুরো জিনিসটি ফুঁড়ে উঠছে।
তবুও বেগ ভার্টিট / লিপফ্রোগ পদ্ধতি বেসল ইউলার সংহত হিসাবে প্রায় সহজ এবং দ্রুত এবং চতুর্থ-ক্রম রঞ্জ-কোট্টা সংহতকরণের মতো বিকল্পগুলির তুলনায় অবশ্যই অনেক সহজ (যা সাধারণত খুব সুন্দর সংহতকারী হলেও পার্থক্যমূলক সম্পত্তিটির অভাব হয় এবং এর জন্য চারটি মূল্যায়নের প্রয়োজন হয়) এর force()
সময় পদক্ষেপ প্রতি ফাংশন)। সুতরাং, আমি দৃ strongly়তার সাথে তাদের যেকোন ধরণের গেম ফিজিক্স কোড লেখার জন্য তাদের সুপারিশ করব, এমনকি এটি যদি এক প্ল্যাটফর্ম থেকে অন্য প্ল্যাটফর্মে ঝাঁপ দেওয়ার মতোই সহজ।
সম্পাদনা করুন: যদিও বেগ ভার্টেল পদ্ধতিটির আনুষ্ঠানিক বিকাশ কেবল তখনই বৈধ যখন বাহিনী গতিবেগ থেকে স্বতন্ত্র থাকে, বাস্তবে আপনি বেগ মাত্রায় নির্ভর বাহিনী যেমন তরল ড্রাগের সাথেও ঠিক এটি ব্যবহার করতে পারেন । সেরা ফলাফলের জন্য, দ্বিতীয় কলটির জন্য নতুন বেগটি অনুমান করতে আপনার প্রাথমিক ত্বরণ মানটি ব্যবহার করা উচিত force()
:
ত্বরণ = বল (সময়, অবস্থান, বেগ) / ভর; সময় + = টাইমস্টেপ; অবস্থান + = টাইমস্টেপ * ( বেগ + টাইমস্টেপ * ত্বরণ / 2) ; বেগ + = টাইমস্টেপ * ত্বরণ; newAcceleration = বল (সময়, অবস্থান, বেগ) / ভর; বেগ + = টাইমস্টেপ * (নতুন ত্বরণ - ত্বরণ) / 2 ;
আমি বেগের ভারলেট পদ্ধতির এই নির্দিষ্ট বৈকল্পিকটির একটি নির্দিষ্ট নাম আছে কিনা তা আমি নিশ্চিত নই, তবে আমি এটি পরীক্ষা করেছি এবং এটি খুব ভালভাবে কাজ করে বলে মনে হচ্ছে। এটি মাথার অর্ডার রঞ্জে-কত্তার মতো যথাযথভাবে সঠিক নয় (এটি দ্বিতীয়-আদেশ পদ্ধতি থেকে যেমন প্রত্যাশা করা হয়েছিল) তবে এটি মধ্যবর্তী গতিবেগ অনুমান ব্যতিরেকে অয়লার বা নির্বোধ বেগ ভার্টেলের চেয়ে অনেক ভাল এবং এটি এখনও স্বাভাবিকের লক্ষণীয় সম্পত্তি ধরে রেখেছে রক্ষণশীল, অ-বেগ-নির্ভর শক্তিগুলির জন্য বেগ ভারলেট।
সম্পাদনা 2: একটি খুব অনুরূপ অ্যালগরিদম বর্ণনা করা হয়েছে যেমন গ্রুট অ্যান্ড ওয়ারেন ( জে। কেম। ফিজি। 1997) দ্বারা , যদিও, লাইনগুলির মধ্যে পড়ে এটি মনে হয় যে তারা অতিরিক্ত গতির জন্য কিছুটা নির্ভুলতার জন্য newAcceleration
অনুমিত বেগ ব্যবহার করে গণনা করা মূল্য সংরক্ষণ করে ত্যাগ করেছিল seems এবং acceleration
পরের টাইমস্টেপের জন্য এটি হিসাবে পুনরায় ব্যবহার করুন । তারা 0 ≤ λ ≤ 1 একটি পরামিতিও প্রবর্তন করে যা acceleration
প্রাথমিক বেগের অনুমানের সাথে গুণিত হয় ; কিছু কারণে, তারা সুপারিশ λ = 0.5, যদিও সব আমার পরীক্ষা যা প্রমাণ করে λ= 1 (যা আমি উপরে যা ব্যবহার করি তা কার্যকরভাবে) ত্বকের পুনঃব্যবহারের সাথে বা ব্যবহার ছাড়াই ভাল বা আরও ভাল কাজ করে। সম্ভবত এটির সাথে তাদের কিছু করার দরকার আছে যে তাদের বাহিনীতে স্টোকাস্টিক ব্রাউনিয়ান গতি উপাদান রয়েছে।
force(time, position, velocity)
আমার উত্তর উপরে শুধু "বল একটি বস্তুর উপর অভিনয় সাধারণভাবে সংক্ষেপে হয় position
এ চলন্ত velocity
এ time
"। সাধারণত, শক্তিটি বস্তুটি ফ্রিফলে রয়েছে বা শক্ত পৃষ্ঠে বসে আছে কিনা, আশেপাশের অন্য কোনও বস্তু এতে কোন শক্তি প্রয়োগ করছে কিনা, কোনও পৃষ্ঠের (ঘর্ষণ) এবং / বা তরল দিয়ে কত দ্রুত গতিতে চলেছে তার উপর নির্ভর করবে force বা গ্যাস (টানুন), ইত্যাদি
আপনার গেমের প্রতিটি আপডেট লুপ, এটি করুন:
if (collidingBelow())
gravity = 0;
else gravity = [insert gravity value here];
velocity.y += gravity;
উদাহরণস্বরূপ, প্লাটফর্মারটিতে, একবার আপনি যদি মহাকর্ষটি লাফিয়ে সক্রিয় হয়ে যান (সংঘর্ষের নীচে আপনার নীচে গ্রাউন্ড রয়েছে কি না তা আপনাকে জানায়) এবং একবার আপনি মাটিতে আঘাত করলে এটি অক্ষম হয়ে যায়।
এগুলি ছাড়াও, জাম্পগুলি বাস্তবায়নের জন্য, তারপর এটি করুন:
if (pressingJumpButton() && collidingBelow())
velocity.y = [insert jump speed here]; // the jump speed should be negative
এবং বেশ স্পষ্টতই, আপডেট লুপে আপনাকে নিজের অবস্থান আপডেট করতে হবে:
position += velocity;
একটি যথাযথ ফ্রেম-রেট স্বাধীন * নিউটোনীয় পদার্থবিজ্ঞানের একীকরণ:
Vector forces = 0.0f;
// gravity
forces += down * m_gravityConstant; // 9.8m/s/s on earth
// left/right movement
forces += right * m_movementConstant * controlInput; // where input is scaled -1..1
// add other forces in for taste - usual suspects include air resistence
// proportional to the square of velocity, against the direction of movement.
// this has the effect of capping max speed.
Vector acceleration = forces / m_massConstant;
m_velocity += acceleration * timeStep;
m_position += velocity * timeStep;
টুইক গ্র্যাভিটি কনস্ট্যান্ট, মুভমেন্টকন্সট্যান্ট এবং ম্যাসকনস্ট্যান্ট যতক্ষণ না এটি সঠিক মনে হয়। এটি একটি স্বজ্ঞাত জিনিস এবং দুর্দান্ত অনুভূতি পেতে কিছুটা সময় নিতে পারে।
নতুন গেমপ্লে যুক্ত করতে ফোর্স ভেক্টরটিকে প্রসারিত করা সহজ - উদাহরণস্বরূপ কাছের কোনও বিস্ফোরণ থেকে দূরে অথবা ব্ল্যাক হোলের দিকে কোনও বাহিনী যুক্ত করুন।
* সম্পাদনা করুন: সময়ের সাথে এই ফলাফলগুলি ভুল হবে, তবে আপনার বিশ্বস্ততা বা দক্ষতার জন্য এটি "যথেষ্ট ভাল" হতে পারে। আরও তথ্যের জন্য এই লিঙ্কটি দেখুন: http://lol.zoy.org/blog/2011/12/14/ বোঝার-- মোশন- ইন- গেমস ।
position += velocity * timestep
উপরের সাথে সহজেই ওলিউর সংহতকরণের সাথে সমস্যাগুলি সমাধান করতে পারেন position += (velocity - acceleration * timestep / 2) * timestep
( velocity - acceleration * timestep / 2
কেবলমাত্র পুরানো এবং নতুন বেগের গড় যেখানে রয়েছে)। বিশেষত, তাত্পর্য স্থির থাকলে এই সংহতকারী সঠিক ফলাফল দেয়, কারণ এটি সাধারণত মহাকর্ষের জন্য। ভিন্নতর ত্বরণের অধীনে আরও ভাল নির্ভুলতার জন্য, বেগ বেগের ভার্টিটেশন সংহতকরণের জন্য আপনি বেগ আপডেটে অনুরূপ সংশোধন যুক্ত করতে পারেন ।
আপনি যদি কিছুটা বড় স্কেলে মাধ্যাকর্ষণ বাস্তবায়ন করতে চান তবে আপনি প্রতিটি লুপে এই ধরণের গণনা ব্যবহার করতে পারেন:
for each object in the scene
for each other_object in the scene not equal to object
if object.mass * other_object.mass / object.distanceSquaredBetweenCenterOfMasses(other_object) < epsilon
abort the calculation for this pair
if object.mass is much, much bigger than other_object.mass
abort the calculation for this pair
force = gravitational_constant
* object.mass * other_object.mass
/ object.distanceSquaredBetweenCenterOfMasses(other_object)
object.addForceAtCenterOfMass(force * object.normalizedDirectionalVectorTo(other_object))
end for loop
end for loop
এমনকি আরও বড় (গ্যালাকটিক) স্কেলগুলির জন্য, একাকী মহাকর্ষই যদিও "আসল" গতি তৈরি করার পক্ষে যথেষ্ট নয়। নক্ষত্রের গতিবিদ্যার জন্য নাভিয়ার-স্টোকস সমীকরণ দ্বারা নির্ধারিত তারকা ব্যবস্থাগুলির মিথস্ক্রিয়া একটি তাত্পর্যপূর্ণ এবং অত্যন্ত দৃশ্যমান পরিমাণে, এবং আপনাকে আলোর সীমাবদ্ধ গতি রাখতে হবে - এবং এইভাবে মহাকর্ষ - এছাড়াও মনে রাখবেন।
ইলমারি করোনেন প্রদত্ত কোডটি প্রায় সঠিক, তবে কিছুটা সমস্যা রয়েছে। আপনি প্রকৃতপক্ষে টিকের জন্য 2 বার ত্বরণ গণনা করুন, এটি পাঠ্যপুস্তক সমীকরণ অনুসরণ করে না।
acceleration = force(time, position) / mass; // Here
time += timestep;
position += timestep * (velocity + timestep * acceleration / 2);
newAcceleration = force(time, position) / mass;
velocity += timestep * (acceleration + newAcceleration) / 2;
নিম্নলিখিত মোড সঠিক:
time += timestep;
position += timestep * (velocity + timestep * acceleration / 2);
oldAcceletation = acceleration; // Store it
acceleration = force(time, position) / mass;
velocity += timestep * (acceleration + oldAcceleration) / 2;
চিয়ার্স '
পেক্যান্টের উত্তরকর্তা ফ্রেমের সময়কে উপেক্ষা করেছেন এবং এটি আপনার পদার্থবিজ্ঞানের আচরণ সময়ে সময়ে পৃথক করে।
আপনি যদি খুব সাধারণ গেম করতে চলেছেন তবে আপনি নিজের তৈরি করতে পারেন নিজের সামান্য পদার্থবিজ্ঞান ইঞ্জিন - প্রতিটি চলমান বস্তুর জন্য ভর এবং সমস্ত ধরণের পদার্থবিজ্ঞানের পরামিতি নির্ধারণ করুন এবং সংঘর্ষ সনাক্তকরণ করুন, তারপরে প্রতিটি ফ্রেমের অবস্থান এবং বেগ আপডেট করুন। এই অগ্রগতি ত্বরান্বিত করার জন্য, আপনাকে সংঘর্ষের জালটি সহজ করতে হবে, সংঘর্ষ সনাক্তকরণের কলগুলি হ্রাস করতে হবে ইত্যাদি বেশিরভাগ ক্ষেত্রে এটি ব্যথা pain
পদার্থবিজ্ঞান ইঞ্জিন যেমন ফিজিক্স, ওডিই এবং বুলেট ব্যবহার করা ভাল। এগুলির যে কোনওটি আপনার পক্ষে স্থিতিশীল এবং যথেষ্ট দক্ষ হবে।