স্যাট এর সাথে যোগাযোগের স্থানটি সন্ধান করা হচ্ছে


12

পৃথকীকরণ অক্ষের উপপাদ্য (স্যাট) ন্যূনতম অনুবাদ ভেক্টর, অর্থাৎ, সংক্ষিপ্ততম ভেক্টর যা দুটি সংঘর্ষের বস্তুকে পৃথক করতে পারে তা নির্ধারণ করা সহজ করে তোলে। যাইহোক, আমার যা দরকার তা হ'ল ভেক্টর যা অনুপ্রবেশকারী বস্তুটি চলন্ত (যেমন যোগাযোগের বিন্দু) বরাবর বস্তুগুলি পৃথক করে।

আমি স্পষ্ট করতে সাহায্য করার জন্য একটি ছবি আঁকলাম। একটি বাক্স রয়েছে, পূর্ব থেকে পরবর্তী অবস্থানের দিকে চলে। এর পরে অবস্থানে এটি ধূসর বহুভুজকে ছেদ করে। স্যাট সহজেই এমটিভি ফিরিয়ে দিতে পারে, এটিই লাল ভেক্টর। আমি নীল ভেক্টর গণনা করতে চাই

স্যাট চিত্র

আমার বর্তমান দ্রবণটি নীল ভেক্টরের দৈর্ঘ্য নির্দিষ্ট সীমাতে না জানা পর্যন্ত পজিশনের আগে এবং পরে উভয়ের মধ্যে বাইনারি অনুসন্ধান করে। এটি কাজ করে তবে আকারের সংঘর্ষের জন্য প্রতিটি লুপকে পুনরায় গণনা করা দরকার বলে এটি একটি ব্যয়বহুল গণনা।

যোগাযোগের পয়েন্ট ভেক্টরটি খুঁজে পাওয়ার কোনও সহজ এবং / বা আরও কার্যকর উপায় আছে কি?


1
আপনি কি স্যাট ব্যবহার বন্ধ করে দিয়েছেন? এমপিআর (মিনকোভস্কি পোর্টাল সংশোধন) এর মতো অ্যালগরিদম সরাসরি যোগাযোগ বহুগুণে খুঁজে পেতে পারেন। স্যাট এবং জিজেকে দিয়ে যোগাযোগের পয়েন্টগুলি গণনা করার জন্য আপনার একটি পৃথক অ্যালগরিদম প্রয়োজন।
শান মিডলডিচ

উত্তর:


6

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

ভাগ্যক্রমে, অক্ষ পরীক্ষা পৃথক করা আপনাকে এখানে সহায়তা করতে পারে! রন লেভিনের সৌজন্যে অ্যালগরিদমের বর্ণনা এখানে রয়েছে :

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

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

অ্যালগরিদমের জন্য এখানে কিছু রুক্ষ এবং সম্পূর্ণ যাচাইকৃত সিউডোকোড দেওয়া হল:

t_min := +∞
t_max := -∞
foreach axis in potential_separating_axes
    a_min := +∞
    a_max := -∞
    foreach vertex in a.vertices
        a_min = min(a_min, vertex · axis)
        a_max = max(a_max, vertex · axis)
    b_min := +∞
    b_max := -∞
    foreach vertex in b.vertices
        b_min = min(b_min, vertex · axis)
        b_max = max(b_max, vertex · axis)
    v := b.velocity · axis
    if v > 0 then
        if a_max < b_min then
            return no_intersection
        else if (a_min < b_min < a_max) or (b_min < a_min < b_max) then
            t_min = min(t_min, (a_max - b_min) / v)
            t_max = max(t_max, 0)
        else
            t_min = min(t_min, (a_max - b_min) / v)
            t_max = max(t_max, (a_min - b_max) / v)
    else if v < 0 then
        // repeat the above case with a and b swapped
    else if v = 0 then
        if a_min < b_max and b_min < a_max then
            t_min = min(t_min, 0)
            t_max = max(t_max, 0)
        else
            return no_intersection
if t_max < t_min then
    // advance b by b.velocity * t_max
    return intersection
else
    return no_intersection

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

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


2
এটি সবই দুর্দান্ত, তবে যোগাযোগের বহুগুণ গণনা সম্পর্কে প্রশ্নের সরাসরি উত্তর দেয়নি। এছাড়াও, যদি আমি এটি সঠিকভাবে বুঝতে পারি তবে এই উত্তরটি কেবল রৈখিক বেগ নিয়ে কাজ করে, এবং তাই ঘোরানো অবজেক্টগুলিকে সমর্থন করতে পারে না; নিশ্চিত নয় যে প্রশ্নকারী জিজ্ঞাসাবাদী তা চায় কিনা।
শান মিডলডিচ

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

2

আপনি বহুভুজ ক্লিপিং ব্যবহার করতে চান। ছবিগুলির সাথে এটি সর্বোত্তমভাবে ব্যাখ্যা করা হয়েছে, যা আমার নেই তবে এই লোকটি করেছে, তাই আমি তাকে এটি ব্যাখ্যা করতে দেব।

http://www.codezealot.org/archives/394

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

মনে রাখবেন যে আপনার ছবি একটি ছোট সমস্যা চিত্রিত করেছে: আপনি যে নীল ভেক্টরের জন্য জিজ্ঞাসা করছেন তা কোনও শারীরিক সিমুলেশনে পাওয়া যাবে না, কারণ বাক্সটি যে আঘাত করবে তা আসলে তা নয়। বক্সটি নীচের দিকের বাম দিকের কোণে somewhereালু অন্য কোথাও আঘাত করবে যেহেতু কোণার একটি ছোট্ট অংশটি প্রবেশ করে।

অনুপ্রবেশ গভীরতা তুলনামূলকভাবে ছোট হবে, এবং অনুপ্রবেশের স্বাভাবিক বরাবর boxাল থেকে বাক্সটি বাইরে ধাক্কা দিয়ে বাক্সটি "সঠিক" অবস্থানে যথেষ্ট পরিমাণে বন্ধ করে দেবে, বিশেষত যদি বাক্সটি বাউন্স করতে চলেছে, গন্ডগোল করবে especially , বা পরে যাই হোক না কেন স্লাইড।


আপনি কি জানেন যে স্যাট ব্যবহার করে সেই "নীল ভেক্টর" (গতিবেগের ভেক্টর বরাবর আকৃতিটিকে পিছনের দিকে ধাকানোর জন্য প্রয়োজনীয়) গণনা করার কোনও উপায় আছে কিনা?
তারা

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

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

@ ডিউডসন: সর্বনিম্ন অনুপ্রবেশের প্রান্ত / অক্ষটি অবশ্যই প্রথম যোগাযোগের প্রান্ত নয়, সুতরাং স্যাট এখানে কীভাবে সহায়তা করে তা আমি এখনও দেখতে পাই না। আমি এই বিষয়ে কোনওভাবেই বিশেষজ্ঞ নই তাই আমি স্বীকার করি যে আমি ঠিক ভুল হতে পারি। :)
শান মিডলডিচ

যথাযথভাবে। এই কারণেই এটি নিশ্চিত কিনা আমি নিশ্চিত নই। যদিও এটি বোঝাবে যে সামুগীর উত্তরটি কেবল ভুল। তবে যাইহোক সাহায্যের জন্য ধন্যবাদ! : ডি
তারা তারা

0

কেবল ম্যাট ভেক্টরকে দিক ভেক্টরের দিকে প্রজেক্ট করুন। অনুপ্রবেশ ক্ষতিপূরণ জন্য ফলাফল ভেক্টরকে দিকনির্দেশক ভেক্টরে যুক্ত করা যেতে পারে। স্যাটটি করার সময় আপনি অক্ষের মতো এটিও একইভাবে প্রজেক্ট করুন। এটি বস্তুকে ঠিক এমন অবস্থানে সেট করে যা এটি অন্য বস্তুর সাথে স্পর্শ করে। ভাসমান পয়েন্ট সমস্যার সাথে লড়াই করতে একটি ছোট অ্যাপসিলন যুক্ত করুন।


1
"ম্যাট ভেক্টর"? আপনার মানে "এমটিভি"?
তারা

0

আমার উত্তরে বেশ কয়েকটি ক্যাভেট রয়েছে, যে আমি প্রথমে বেরিয়ে যাব: এটি কেবল ঘোরানো নয় সীমানা বাক্সগুলির সাথে সম্পর্কিত। এটি ধরে নেওয়া হয়েছে যে আপনি টানেলিং সংক্রান্ত সমস্যাগুলি বোঝার চেষ্টা করছেন , অর্থাত্ উচ্চ গতিতে চলমান বস্তুর কারণে সৃষ্ট সমস্যাগুলি।

আপনি একবার এমটিভি শনাক্ত করার পরে, আপনি প্রান্ত / পৃষ্ঠের স্বাভাবিক জানেন যে আপনার বিরুদ্ধে পরীক্ষা করা দরকার। আপনি ইন্টারপেনেটেটিং অবজেক্টের লিনিয়ার বেগ ভেক্টরটিও জানেন।

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

vec3 vertex;
float mindot = FLT_MAX;
for ( vert : vertices )
{
    if (dot(vert, MTV) < mindot)
    {
         mindot = dot(vert, MTV);
         vertex = vert;
    }
}

একবার আপনি প্রান্তিক শনাক্ত হয়ে গেলে, বাইনারি অর্ধেক ধাপটি কম ব্যয়বহুল হয়ে যায়:

//mindistance is the where the reference edge/plane intersects it's own normal. 
//The max dot product of all vertices in B along the MTV will get you this value.
halfstep = 1.0f;
vec3 cp = vertex;
vec3 v = A.velocity*framedurationSeconds;
float errorThreshold = 0.01f; //choose meaningful value here
//alternatively, set the while condition to be while halfstep > some minimum value
while (abs(dot(cp,normal)) > errorThreshold)
{            
    halfstep*=0.5f;
    if (dot(cp,normal) < mindistance) //cp is inside the object, move backward
    {
        cp += v*(-1*halfstep);
    }
    else if ( dot(cp,normal) > mindistance) //cp is outside, move it forward
    {
        cp += v*(halfstep);
    }
}

return cp;

এটি যুক্তিযুক্তভাবে সঠিক, তবে কেবলমাত্র একক ক্ষেত্রে একক সংঘর্ষের পয়েন্ট সরবরাহ করবে।

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

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

মজার বিষয় হল, এই হাফস্টেপ পদ্ধতিটি ফ্রেমের সময় অবজেক্টটি সংঘটিত হওয়ার (প্রায়) সঠিক সময় দিতে পারে:

float collisionTime = frametimeSeconds * halfstep;

যদি আপনি কোনও ধরণের পদার্থবিজ্ঞানের সংঘর্ষের রেজোলিউশন করে থাকেন তবে আপনি এ দ্বারা অবস্থিতি দ্বারা ঠিক করতে পারেন:

v - (v*halfstep)

তাহলে আপনি সেখান থেকে আপনার পদার্থবিজ্ঞানটি সাধারণত করতে পারেন। অবক্ষয়টি হ'ল যদি বস্তুটি যথাযথভাবে দ্রুতগতিতে চলে আসে, আপনি দেখবেন এটির বেগটি ভেক্টর বরাবর টেলিপোর্ট করে।

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