মোড়ানো প্রান্ত দিয়ে বিশ্বে ভ্রমণের দিক সন্ধান করা


20

আমার 2 ডি জগতের এক বিন্দু থেকে অন্য বিন্দুতে যেখানে প্রান্তগুলি মোড়ানো রয়েছে (যেমন গ্রহাণু ইত্যাদি) এর সবচেয়ে কম দূরত্বের দিকটি খুঁজে পেতে হবে। আমি কীভাবে সবচেয়ে কম দূরত্ব খুঁজে পেতে জানি তবে এটি কোন দিকে রয়েছে তা খুঁজে পেতে লড়াই করে যাচ্ছি ling

সংক্ষিপ্ততম দূরত্বটি দিয়েছেন:

int rows = MapY;
int cols = MapX;

int d1 = abs(S.Y - T.Y);
int d2 = abs(S.X - T.X);
int dr = min(d1, rows-d1);
int dc = min(d2, cols-d2);

double dist = sqrt((double)(dr*dr + dc*dc));

বিশ্বের উদাহরণ

                   :         
                   :  T    
                   :         
    :--------------:---------
    :              :
    :           S  :
    :              :
    :              :
    :  T           :
    :              :
    :--------------:

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

আমি এস এবং টি উভয়ের অবস্থান জানি কিন্তু আমার ধারণা আমি পুনরাবৃত্তি টি এর অবস্থানটি যদিও সেখানে 1 এরও বেশি খুঁজে পেতে হবে।

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

দেখে মনে হচ্ছে এটি খুব কঠিন হওয়া উচিত নয় তবে আমি কোনও সমাধান বের করতে সক্ষম হয়েছি না। আমি আশা করি সোমোন সাহায্য করতে পারে? যে কোনও ওয়েবসাইট প্রশংসা করা হবে।


উপরের ডানদিকে টির জন্য স্থানাঙ্কগুলি কী কী?

তির্যক মোড়ক দিয়ে কোনও খেলা দেখিনি। সাধারণত প্রতিটি দিকের জন্য আপনার একটি করে মোড়ানো থাকে (এন, ই, এস, ডাব্লু)।

5
অনুভূমিক এবং উল্লম্ব উভয় মোড়ক থাকা যে কোনও গেমের ডিফল্টরূপে তির্যক মোড়ানো থাকে।

প্রতিটি সমন্বয়কে একটি চেনাশোনাতে বেঁচে থাকার কথা ভাবেন এবং পৃথকভাবে প্রতিটি সমন্বয়ের জন্য দুটি সম্ভাব্য দূরত্বের সংক্ষিপ্ত আকারটি নির্ধারণ করুন।
কেরেক এসবি

1
@ ক্র্যাজি: উইকিপিডিয়ায় "টরাস" দেখুন ...
কেরেক এসবি

উত্তর:


8

কোণটি নির্ণয় করতে আপনাকে আপনার অ্যালগরিদমকে কিছুটা সামান্য তিরস্কার করতে হবে - বর্তমানে আপনি কেবলমাত্র অবস্থানের মধ্যে নিখুঁত পার্থক্য রেকর্ড করেছেন, তবে আপনার আপেক্ষিক পার্থক্যের প্রয়োজন (যেমন পজিশনের উপর নির্ভর করে ইতিবাচক বা নেতিবাচক হতে পারে)।

int dx = T.X - S.X; // difference in position
int dy = T.Y - S.Y;

if (dx > MapX / 2) // if distance is bigger than half map width, then looping must be closer
    dx = (dx - MapX) * -1; // reduce distance by map width, reverse 
else if (dx < -MapX / 2) // handle the case that dx is negative
    dx = (dx + MapX) * -1;

//Do the same for dy
if (dy > MapY / 2)
    dy = (dy - MapY) * -1;
else if (dy < -MapY / 2)
    dy = (dy + MapY) * -1;

double dist = sqrt(dy*dy+dx*dx); // same as before
double angle = atan2(dy,dx) * 180 / PI; // provides angle in degrees

1
টিএক্স এসএক্সের চেয়ে কম বা টিওয়াই এক্সওয়াইর চেয়ে কম হলে কোডটি ভেঙে যাওয়ার সাথে সাথে dx এবং dy এর চিহ্নগুলিতে আপনার কিছু কাজ করা দরকার যা ব্যতীত এটিই সেরা সমাধান আইএমএইচও।
স্কট চেম্বারলাইন

ঠিক তখনই আমি এটি ঠিক করব।

1
ডেক্স এবং ডাই এর চিহ্নটি কী হবে তা নিয়ে এখনও কিছু ত্রুটি পেয়েছে যখন সমস্ত বলা হয় এবং হয়ে যায়, আমি যদি সম্পাদনা করি তবে মনে রাখবেন?
স্কট চেম্বারলাইন

কেন এটি গৃহীত উত্তর ?? এটি এমনকি কাজ করে না । ধরা যাক MapX100, T.X90 এবং S.X10 হয় 10 dxস্পষ্টভাবে 20 হওয়া উচিত, তবে এই অ্যালগরিদম 30 ফিরে আসবে!
সাম হোচেভার

উঘ এটি তখনই ঘটে যখন আপনার পোস্ট করার আগে কোড টেস্ট করার সুযোগ নেই। ঠিক করবে. যদি কেউ এর সাথে অন্য কোনও ত্রুটি খুঁজে পায় তবে খুব বেশি লোক বিভ্রান্ত হওয়ার আগেই আমি সম্ভবত এটি মুছে ফেলব।
টুমাই

11

যেমন একটি বিশ্বে আছে অসীম টি আসুন বোঝাতে S থেকে পাথ সংখ্যা দ্বারা টি স্থানাঙ্ক (Tx, Ty)দ্বারা এস এর স্থানাঙ্ক (Sx, Sy), এবং বিশ্বের আকার (Wx, Wy)। টি আবৃত স্থানাঙ্ক হয় (Tx + i * Wx, Ty + j * Wy), যেখানে iএবং jপূর্ণসংখ্যার সেট উপাদান, যে {..., -2, -1, 0, 1, 2, ...}। এস সাথে টি সংযুক্ত ভেক্টর হয় (Dx, Dy) := (Tx + i * Wx - Sx, Ty + j * Wy - Sy)। একটি প্রদত্ত জন্য (i, j)যুগল, দূরত্ব ভেক্টর, এর দৈর্ঘ্য হল sqrt(Dx * Dx + Dy * Dy), এবং রেডিয়ানে দিক হল atan(Dy / Dx)সবচেয়ে কম পাথ 9 পাথ, যেখানে এক iএবং jরয়েছে {-1, 0, 1}: এখানে চিত্র বর্ণনা লিখুন

iএবং jমান সবচেয়ে কম পথ সরাসরি নির্ধারিত করা যেতে পারে:

int i = Sx - Tx > Wx / 2 ? 1 : Sx - Tx < -Wx / 2 ? -1 : 0;
int j = Sy - Ty > Wy / 2 ? 1 : Sy - Ty < -Wy / 2 ? -1 : 0;

আপনাকে ধন্যবাদ, ইলমারী কারোনেন, @ সামহোসেভর এবং @ ক্রোমেনস আপনার সহায়তার জন্য!


1
আপনি তার থেকে আরও ভাল করতে পারেন: যদি abs(Tx-Sx) < Wx/2, তবে i=0সর্বোত্তম হয়; অন্যথায় সর্বোত্তম পছন্দটি i=-1বা i=1এর চিহ্নের উপর নির্ভর করে Tx-Sx। একই জন্য Ty-Syএবং j
ইলমারি করোনেন

1
এই উত্তরটি এত সাধারণ সমস্যার জন্য অবিশ্বাস্যরকম জটিল। যখন সর্বনিম্ন মানটি সরাসরি গণনা করা যায় তখন লিনিয়ার অনুসন্ধান ব্যবহার করার দরকার নেই।
সাম হোচেভার

চমৎকার ছবি, তবে প্রস্তাবিত অ্যালগরিদম এই উত্তরটি যেভাবে বাড়িয়েছে তার প্রাপ্য নয়।
রোমানস্ট

5

একটি সম্ভাব্য দিকনির্দেশক ভেক্টর গণনা করুন, এমনকি যদি এটি স্বল্পতম না হয় তবে তার এক্স স্থানাঙ্কটি মোড়ানো যাতে এটি [-MapX/2,MapX/2]পরিসীমাতে থাকে এবং ওয়াইয়ের জন্য একই:

int DirX = (T.X - S.X + 3 * MapX / 2) % MapX) - MapX / 2;
int DirY = (T.Y - S.Y + 3 * MapY / 2) % MapY) - MapY / 2;

এটাই! আপনি আরও গণনা ছাড়াই দূরত্ব পাবেন:

double dist = sqrt((double)(DirX*DirX + DirY*DirY));

ধন্যবাদ! vec2 toroidalNearestWay (vec2 from, vec2 to, vec2 mapSize) { return (mod((to - from + 3.0 * mapSize / 2.0), mapSize)) - mapSize / 2.0; }
জিএলএসএল

0

আমি অনুমান করি এটি করার বিভিন্ন উপায় রয়েছে। আমি এখানে আমার মাথার উপরের অংশটি ভাবতে পারি 2:

# 1: ম্যানুয়ালি কেসগুলি হ্যান্ডেল করুন

ঠিক 10 টি ঘটনা ঘটতে পারে:

  • এটি একই টাইল হয় S
  • এটি আশেপাশের 8 টি টাইলের মধ্যে রয়েছে
  • এটি মোটেও পাওয়া যায় না।

আশেপাশের প্রতিটি টাইলের জন্য যদিও তারা X বা Y দূরত্বের উপাদানটির জন্য বিভিন্ন গণনার ক্রমবিন্যাস। কারণ এটি একটি সীমাবদ্ধ সংখ্যা, আপনি কীভাবে তাদের গণনা করতে পারেন তা আপনি কেবল হার্ড-কোড করতে পারেন এবং এগুলির মধ্যে স্বল্পতম দূরত্বটি খুঁজে পেতে পারেন।

এটি সন্ধানের জন্য 2 টি মামলার উদাহরণ রয়েছে dx। কেস 1, যেখানে Tহিসাবে একই টালি হয় S, DX ঠিক হয় S.x - T.x। ডানদিকে টাইলগুলির জন্য dxগণনা করা হবে TileWidth - S.x + T.x

               :         
               :  T    
               :         
:--------------:---------
:              :
:           S  :
:  |--------|--:--|
:dx=(S.x-T.x) dx=(TileWidth-S.x+T.x)
:  T           :
:              :
:--------------:

একটি ছোট্ট অপ্টিমাইজেশন হিসাবে, বর্গমূল নেওয়ার আগে সর্বনিম্ন দূরত্বটি সন্ধান করুন। তারপরে আপনি 7 টি sqrtকল পর্যন্ত নিজেকে বাঁচান ।

# 2: স্থানাঙ্কগুলি বিমূর্ত করুন

আপনার যদি কোনও পথ-সন্ধানকারী অ্যালগরিদমের মতো আরও কিছু স্পেসিয়ালি "তরল" করার দরকার হয় তবে কেবল স্থানাঙ্কগুলিকে বিমূর্ত করুন যাতে আপনার পথটি অ্যালগরিদমের সন্ধানও করতে পারে না যে পৃথিবী পুনরাবৃত্তি টাইলস দিয়ে তৈরি। পথ সন্ধানকারী অ্যালগরিদম তাত্ত্বিকভাবে যে কোনও দিক থেকে সীমাহীনভাবে যেতে পারে (ঠিক আছে আপনি সংখ্যার সীমাবদ্ধতার দ্বারা সীমাবদ্ধ থাকবেন তবে আপনি পয়েন্টটি পাবেন)।

সাধারণ দূরত্ব গণনার জন্য, এটি করে বিরক্ত করবেন না।


স্কয়ারটি নেওয়ার আগে বর্গক্ষেত্রের দূরত্বের মান তুলনা করার বিষয়ে স্মার্ট ধারণা!
স্কট চেম্বারলাইন

আমি দেখছি, @ কোলের আরও একটি গাণিতিক ব্যাখ্যা সহ একই রকম উত্তর রয়েছে, ধন্যবাদ এটি আমাকে কাজ করার জন্য কিছু দেয়

স্কোয়ার্টের তুলনায় স্কোয়ার দূরত্বের তুলনা আরও স্মার্ট হতে পারে তবে ম্যানহাটনের দূরত্বটি ব্যবহার করা আরও স্মার্ট কারণ এটির জন্য কোনও গুণকের প্রয়োজন নেই।
সাম হোচেভার

0

"9 দিকনির্দেশ" নিয়ে বিরক্ত করবেন না। কারণটি হল যে 9 টির মধ্যে 5 টি অবক্ষয়যুক্ত কেস রয়েছে: "সরাসরি উত্তর", "স্ট্রেইট ওয়েস্ট", "সোজা দক্ষিণ", "সরাসরি পূর্ব" এবং "অভিন্ন"। উদাহরণস্বরূপ, সরল উত্তর অবক্ষয়যুক্ত কারণ এটি সেই ক্ষেত্রে প্রতিনিধিত্ব করে যেখানে উত্তর-পশ্চিম এবং উত্তর-পূর্বে যোগ দেয় এবং একই ফল প্রকাশ করে produce

সুতরাং, গণনা করার জন্য আপনার কাছে 4 টি দিক রয়েছে এবং আপনি সর্বনিম্ন চয়ন করতে পারেন।


আমি মনে করি না এটি সঠিক, বা আমি আপনাকে পুরোপুরি ভুল বুঝেছি। দুই এর মধ্যে এক.

-1

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

অন্য কেউ এই পৃষ্ঠাটি সন্ধান করে এবং একই বিপরীত ওয়াই সিস্টেম রয়েছে সে ক্ষেত্রে আমি পোস্ট করেছি।

  int dx = T.X - S.X; // difference in position
int dy = S.Y - T.Y;

if (dx > MapX / 2) // if distance is bigger than half map width, then looping must be closer
    dx = (dx - (MapX / 2)) * -1; // reduce distance by half map width, reverse 
else if (dx < -MapX / 2) // handle the case that dx is negative
    dx = (dx + (MapX / 2)) * -1;

//Do the same for dy
if (dy > MapY / 2)
    dy = (MapY - dy)) * -1;
else if (dy < -MapY / 2)
    dy = (dy + MapY);

double angle = atan2(dy,dx) * 180 / PI; // provides angle in degrees

angle = 180 - angle; //convert to 360 deg

এই কোডটি তোমাইয়ের চেয়ে কিছুটা ভাল তবে কোনওটিই কাজ করে না।
সাম হোচেভার

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