কীভাবে অন্য একটি অবজেক্টের পরিধি বরাবর একটি বস্তু সরিয়ে নেওয়া যায়?


11

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

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

এখানে চিত্র বর্ণনা লিখুন


1
কি dএকটি রৈখিক দূরত্ব বা এটি একটি চাপ রয়েছে?
মাইকেলহাউস

এটি পিক্সেলের লিনিয়ার দূরত্ব
লুমিস

আপনি কী ভেক্টর এবং সেগুলি সম্পর্কে প্রাথমিক অপারেশনগুলির সাথে মোটেই পরিচিত?
প্যাট্রিক হিউজেস

@ পেট্রিক নো, আমি অনুমান করি আমাকে ভেক্টরগুলির বিষয়ে একটি কোর্স করতে হবে। যেহেতু এটি ফ্রেম বাই ফ্রেম অ্যানিমেশন তাই কোডটি দ্রুত এবং অনুকূলিত করা উচিত।
লুমিস

উত্তর:


8

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

ভাগ্যক্রমে, এর গাণিতিকটি তুলনামূলকভাবে সহজ। প্রথমত, আমরা আমাদের কেন্দ্রের অবস্থান থেকে আমাদের বর্তমান অবস্থানে আপেক্ষিক ভেক্টরটি খুঁজে পেতে পারি:

deltaX = oX-cX;
deltaY = oY-cY;

এবং একবার যখন আমাদের এই আপেক্ষিক ভেক্টরটি পাওয়া যায়, তারপরে আমরা এর বৃত্তের ব্যাসার্ধটি জানতে পেরে আমরা এর বৃত্তটির দৈর্ঘ্যটি খুঁজে বের করতে পারি:

radius = sqrt(deltaX*deltaX+deltaY*deltaY);

আরও কী, আমাদের আপেক্ষিক ভেক্টর থেকে আমরা সুনির্দিষ্ট কোণটি খুঁজে পেতে পারি যে সিএক্স থেকে অক্স পর্যন্ত রেখাটি রয়েছে:

curTheta = atan2(deltaX, deltaY);

এখন জিনিসগুলি কিছুটা জটিল হয়ে উঠছে। প্রথমত, বুঝতে হবে যে একটি বৃত্তের পরিধি - যা 2π এর কৌণিক পরিমাপযুক্ত একটি চাপের 'চাপ দৈর্ঘ্য' - 2πr। সাধারণভাবে, ব্যাসার্ধের বৃত্ত বরাবর একটি কৌণিক পরিমাপের সাথে একটি চাপের চাপের দৈর্ঘ্য মাত্র θr হয়। যদি আমরা আপনার চিত্রের ডিটি আর্ক দৈর্ঘ্য হিসাবে ব্যবহার করতে পারি এবং যেহেতু আমরা ব্যাসার্ধটি জানি, আমরা কেবল আলাদা করে আলাদা করে নতুন অবস্থানে নিয়ে যাওয়ার জন্য থিয়েটার পরিবর্তনটি খুঁজে পেতে পারি:

deltaTheta = d/radius; // treats d as a distance along the arc

যে ক্ষেত্রে ডিটির লিনিয়ার দূরত্ব হওয়া দরকার সেখানে জিনিসগুলি কিছুটা জটিল হয় তবে ভাগ্যক্রমে খুব বেশি কিছু হয় না। সেখানে ডি একটি আইসোসিল ত্রিভুজের একটি দিক রয়েছে যার অন্য দুটি দিকটি বৃত্তের ব্যাসার্ধ (যথাক্রমে সিএক্স / সিওয়াই থেকে ওএক্স / ওওয়াই এবং এক্স / এওয়াই) এবং এই সমদ্বীপীয় ত্রিভুজকে দ্বিখণ্ডিত করার ফলে দুটি করে সঠিক ত্রিভুজ পাওয়া যায় যার প্রত্যেকটিই এক পাশ হিসাবে d / 2 এবং অনুমিতি হিসাবে ব্যাসার্ধ রয়েছে; এর অর্থ এই যে আমাদের অর্ধেক কোণের সাইন (d / 2) / ব্যাসার্ধ এবং সুতরাং সম্পূর্ণ কোণটি এর দ্বিগুণ:

deltaTheta = 2*asin(d/(2*radius)); // treats d as a linear distance

লক্ষ্য করুন কীভাবে আপনি যদি এই সূত্রটি থেকে অসিনটি নিয়ে যান এবং 2 টি বাতিল করেন, তবে এটি শেষ সূত্রের মতো হবে; এটি একই বলেছে যে পাপের (x) এক্স এর ছোট মানগুলির জন্য প্রায় x, যা একটি দরকারী অনুমান হিসাবে জানতে।

এখন আমরা কেবল যুক্ত বা বিয়োগ করে নতুন কোণটি খুঁজে পেতে পারি:

newTheta = curTheta+deltaTheta; // This will take you to aX, aY. For bX/bY, use curTheta-deltaTheta

আমাদের কাছে নতুন কোণটি আসার পরে আমরা আমাদের আপডেট হওয়া আপেক্ষিক ভেক্টরটি খুঁজতে কিছু বেসিক ট্রিগ ব্যবহার করতে পারি:

newDeltaX = radius*cos(newTheta);
newDeltaY = radius*sin(newTheta);

এবং আমাদের কেন্দ্রের অবস্থান এবং আমাদের আপেক্ষিক ভেক্টর থেকে আমরা (অবশেষে) লক্ষ্য বিন্দুটি খুঁজে পেতে পারি:

aX = cX+newDeltaX;
aY = cY+newDeltaY;

এখন, এই সমস্তগুলির সাথে, সচেতন হওয়ার জন্য কয়েকটি বড় সাবধানবাণী রয়েছে। একটির জন্য, আপনি লক্ষ্য করবেন যে এই গণিতটি বেশিরভাগ ভাসমান-পয়েন্ট এবং বাস্তবে এটি প্রায় হতে হবে; একটি লুপে আপডেট করার জন্য এই পদ্ধতিটি ব্যবহার করার চেষ্টা করা এবং প্রতিটি ধাপে পূর্ণসংখ্যার মানগুলিতে ফিরে আসার জন্য এটি প্রথমে শুরু না হওয়ার জন্য আপনার বৃত্তটি বন্ধ না করা (প্রতিটি বার লুপের চারদিকে যাওয়ার সময় অভ্যন্তরীণ বা বাহ্যিকভাবে ছড়িয়ে পড়ে) করা সবকিছু থেকে পারে it জায়গা! (যদি আপনার ডি খুব ছোট হয়, তবে আপনি আবিষ্কার করতে পারেন যে এক্স / এওয়াই বা বিএক্স / বিওয়াইয়ের বৃত্তাকার সংস্করণগুলি ঠিক যেখানে আপনার প্রারম্ভিক অবস্থান oX / oY ছিল are) অন্যটির জন্য, এটি খুব ব্যয়বহুল, বিশেষত এটি যা চেষ্টা করছে তার জন্য কাজ কর; সাধারণভাবে, যদি আপনি জানেন যে আপনার চরিত্রটি একটি বিজ্ঞপ্তি চাপরে চলেছে, আপনার পুরো আর্কটি আগে থেকেই পরিকল্পনা করা উচিত এবং নাফ্রেম থেকে ফ্রেমে এটি এটিকে টিক দিন, যেহেতু এখানে বেশিরভাগ ব্যয়বহুল গণনাগুলি ব্যয় হ্রাস করার জন্য সম্মুখ-লোড হতে পারে। ব্যয়গুলি ছাঁটাই করার আরও একটি ভাল উপায়, আপনি যদি সত্যিই এভাবে বর্ধিতভাবে আপডেট করতে চান তবে প্রথম স্থানে ট্রিগ ব্যবহার না করা; যদি ডিটি ছোট হয় এবং আপনার এটি সঠিক হওয়ার দরকার নেই তবে কেবল খুব কাছাকাছি থাকে, তবে আপনি আপনার কেন্দ্রের দিকে ভেক্টরের সাথে দৈর্ঘ্যের ডি / ওএক্স / ওওয়াইয়ের সাথে ভের্টোর যুক্ত করে একটি 'ট্রিক' করতে পারেন (নোট করুন যে একটি ভেক্টর অরথোগোনাল থেকে (ডিএক্স, ডিওয়াই) প্রদত্ত (-dY, dX)) এবং তারপরে এটি ডান দৈর্ঘ্যে সঙ্কুচিত করুন। আমি এই কোডটি এতদূর ধাপে ধাপে ব্যাখ্যা করব না, তবে আশা করি আপনি এ পর্যন্ত যা দেখেছেন তা প্রদত্ত বোধগম্য হবে। নোট করুন যে আমরা নতুন ব-দ্বীপ ভেক্টরকে শেষ ধাপে অন্তর্নিহিতভাবে 'সঙ্কুচিত' করেছি,

deltaX = oX-cX; deltaY = oY-cY;
radius = sqrt(deltaX*deltaX+deltaY*deltaY);
orthoX = -deltaY*d/radius;
orthoY = deltaX*d/radius;
newDeltaX = deltaX+orthoX; newDeltaY = deltaY+orthoY;
newLength = sqrt(newDeltaX*newDeltaX+newDeltaY*newDeltaY);
aX = cX+newDeltaX*radius/newLength; aY = cY+newDeltaY*radius/newLength;

1
স্টিভেন আমি মনে করি আমি প্রায় অনুমানের চেষ্টা করতে যাচ্ছি কারণ এটি ঠিক এমন একটি খেলা যেখানে সুনির্দিষ্ট চেয়ে প্রাকৃতিক এবং আকর্ষণীয় বোধ করা আরও গুরুত্বপূর্ণ। গতি বিষয়। এই দীর্ঘ এবং ভাল টিউটোরিয়াল জন্য আপনাকে ধন্যবাদ!
লুমিস

বাহ, স্টিভেন আপনার অনুমানের স্বপ্নের মতো কাজ করছে! আপনি আমাকে কীভাবে আপনার কোডটি বিএক্স, বিवाय পেতে পরিবর্তন করবেন তা বলতে পারেন। আপনার অরথোগোনাল ধারণাটি সম্পর্কে আমি এখনও পরিষ্কার নই ...
লুমিস

2
নিশ্চিত! আপনি সত্যিকার অর্থে কোনও সময়ে ভেক্টর গণিতটি বুঝতে চাইবেন এবং আপনি যদি সন্দেহ করেন যে এটি আমার দ্বিতীয় প্রকৃতি হবে; বিএক্স / বিওয়াই পেতে আপনাকে কেবল 'অন্যদিকে' যেতে হবে - অন্য কথায়, (বিশেষ) অর্থোগোনাল ভেক্টর যুক্ত করার পরিবর্তে কেবল এটি বিয়োগ করুন। উপরের কোডটির ক্ষেত্রে, এটি হবে 'newDeltaX = ডেল্টাএক্স-অরথক্স; newDeltaY = deltaY-orthoY; ', এর পরে newLength এর একই গণনা এবং তারপরে' bX = cX + newDeltaX ব্যাসার্ধ / newLength; bY = cY + newDeltaY ব্যাসার্ধ / newLength; '।
স্টিভেন স্টাডনিকি

মূলত, এই কোডটি বিএডিএস / বিওয়াই (এক্স / এওয়াইর পরিবর্তে পরিবর্তে) এর পরিবর্তে নিউডেল্টাক্স / নিউডেল্টাওয়াকে নির্দেশ করবে, তারপরে আপনাকে এক্স / এওয়াই পেতে ঠিক তেমন ফিট করতে এবং কেন্দ্রে যুক্ত করতে ট্রিম করে।
স্টিভেন স্টাডনিকি

9

আপনার ইতিমধ্যে দুটি দিক ব্যবহার করে একটি ত্রিভুজ তৈরি করুন (একটি দিক 'গ' থেকে 'ও', অন্যটি 'ও' থেকে 'এ') এবং তৃতীয় দিকটি 'ক' থেকে 'সি' পর্যন্ত যাবে। 'ক' এখনও ঠিক কোথায় আছে তা আপনি জানেন না, আপাতত কল্পনা করুন যে এখানে একটি পয়েন্ট আছে। 'D' পাশের বিপরীত কোণের কোণটি গণনা করতে আপনার ত্রিকোণমিতি লাগবে। আপনার পক্ষের দৈর্ঘ্য সি <-> ও ও সি <-> এ রয়েছে কারণ তারা উভয়ই বৃত্তের ব্যাসার্ধ।

এখন এই ত্রিভুজের তিনটি বাহুর দৈর্ঘ্য আপনি এখনও দেখতে পাচ্ছেন না, আপনি ত্রিভুজের 'd' পাশের বিপরীত কোণটি নির্ধারণ করতে পারবেন। আপনার প্রয়োজন হলে এসএসএসের (সাইড-সাইড-সাইড) সূত্রটি এখানে রয়েছে: http://www.teacherschoice.com.au/math_library/trigonometry/solve_trig_sss.htm

এসএসএস সূত্রটি ব্যবহার করে আপনার কাছে কোণ রয়েছে (যা আমরা 'জে' ডাকব) যা 'ডি' পাশের বিপরীত। সুতরাং, এখন আমরা গণনা করতে পারি (ax, aY)।

// This is the angle from 'c' to 'o'
float angle = Math.atan2(oY - cY, oX - cX)

// Add the angle we calculated earlier.
angle += j;

Vector2 a = new Vector2( radius * Math.cos(angle), radius * Math.sin(angle) );

আপনি যে কোণগুলি গণনা করছেন তা সর্বদা রেডিয়ানে থাকে তা নিশ্চিত করুন।

যদি আপনাকে বৃত্তের ব্যাসার্ধ গণনা করতে হয় তবে আপনি ভেক্টর বিয়োগফল ব্যবহার করতে পারেন, বিন্দু 'ও' থেকে 'সি' বিয়োগ করতে পারেন, তারপরে ফলাফল ভেক্টরের দৈর্ঘ্য পান।

float lengthSquared = ( inVect.x * inVect.x
                      + inVect.y * inVect.y
                      + inVect.z * inVect.z );

float radius = Math.sqrt(lengthSquared);

আমি বিশ্বাস করি এরকম কিছু করা উচিত। আমি জাভা জানি না, তাই আমি ঠিক সিনট্যাক্স নিয়ে অনুমান করেছি।

Byte56এই ত্রিভুজটি দেখতে কেমন হতে পারে তা চিত্রিত করার জন্য এখানে ব্যবহারকারীর দেওয়া চিত্রটি এখানে দেওয়া হয়েছে : cao ত্রিভুজ


1
আমি একটি উত্তর দিচ্ছিলাম, কিন্তু এটি এটি। আপনার চিত্রের আমি :) প্রণীত ব্যবহার করতে চলেছেন স্বাগত i.imgur.com/UUBgM.png
MichaelHouse

@ বাইট 56: ধন্যবাদ, উদাহরণ দেওয়ার জন্য আমার কাছে কোনও চিত্র সম্পাদক নেইল নেই।
নিক ফস্টার

দ্রষ্টব্যটিও গুণতে হবে; পূর্ণ এসএসএস গণনার চেয়ে জে পাওয়ার আরও সোজা উপায় থাকতে হবে, যেহেতু আমাদের কাছে একটি আইসোসিল ত্রিভুজ রয়েছে।)
স্টিভেন স্টাডনিকি

হ্যাঁ, এটা আমার কাছেও সহজ বলে মনে হচ্ছে! অ্যান্ড্রয়েডের ভেক্টর 2 নেই তাই আমি অনুমান করি যে আমি কেবল মানগুলি আলাদাভাবে ব্যবহার করতে পারি। আকর্ষণীয়ভাবে আমি এখানে ভেক্টর 2 শ্রেণি অ্যানড্রইডের জন্য ম্যানুয়ালি তৈরি করতে পেয়েছি: কোড. google.com/p/beginning-android-games-2/source/browse/trunk/…
লুমিস

(সঠিক রৈখিক দূরত্ব খুঁজে পেতে আমি আমার নিজের উত্তরটি টুইট করেছি - সেখানে ডেল্টা থেইটারার দ্বিতীয় গণনা, 2 * আসিন (ডি / (2 * ব্যাসার্ধ)) হিসাবে আপনি এখানে জে কীভাবে পাবেন))
স্টিভেন স্টাডনিকি

3

2জেক্ট 2 এর চারপাশে ঘোরানোর জন্য সম্ভবত চেষ্টা করুন:

float angle = 0; //init angle

//call in an update
obj2.x = (obj1.x -= r*cos(angle));
obj2.y = (obj1.y += r*sin(angle));
angle-=0.5;

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

1
লুইস, কীভাবে কোনও বিন্দুর চারপাশে কোনও কক্ষপথকে প্রদক্ষিণ করবেন তা দেখানোর জন্য ধন্যবাদ। এটি কার্যকর হতে পারে ...
লুমিস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.