দুটি আয়তক্ষেত্রের ছেদ সনাক্ত করতে অ্যালগরিদম?


143

দুটি আয়তক্ষেত্র ছেদ করেছে কিনা তা সনাক্ত করার জন্য আমি একটি অ্যালগরিদমের সন্ধান করছি (একটি নির্বিচারে কোণে, অন্যটি কেবল উল্লম্ব / অনুভূমিক রেখা সহ)।

একটি কোণার অন্য ALMOST কাজ করে কিনা পরীক্ষা করা হচ্ছে। এটি ব্যর্থ হয় যদি আয়তক্ষেত্রগুলি ক্রস-জাতীয় আকার তৈরি করে।

লাইনগুলির opালু ব্যবহার এড়াতে ভাল ধারণা বলে মনে হচ্ছে, যার জন্য উল্লম্ব লাইনের জন্য বিশেষ ক্ষেত্রে প্রয়োজন।


আপনি যদি আপনার কোণার পরীক্ষায় যুক্ত হন তবে এটি দেখতে একটি চেক দ্বিতীয় আয়তক্ষেত্রটি কোণাকৃত আয়তক্ষেত্রের (আয়তক্ষেত্রাকার) ভিতরে রয়েছে কিনা?
ওয়েজ পি

আপনি কোন ভাষায় এটি করতে যাচ্ছেন? কারণ জাভাতে অন্তর্নির্মিত ক্লাস রয়েছে যা আপনাকে এটি করতে দেয়।
মার্টিজেন

আমি মনে করি গ্রাফিক্স এপিআই এবং বেশিরভাগ জিইআইআই লাইব্রেরি (সুইংয়ের মতো) এটি প্রয়োগ করেছে।
l_39217_l

এটি কেসগুলি মিস করতে পারে যেখানে তারা ওভারল্যাপ করে তবে কোনও কোণ কোনও আয়তক্ষেত্রের অভ্যন্তরে নেই
ফ্লোরিয়িয়ান Bösch

1
এই প্রশ্নটি প্রায় একই: স্ট্যাকওভারফ্লো . com/ জিজ্ঞাসা / 306316/… । যদিও, এটি এমন একটি সমাধান খুঁজছেন যা বিশেষত সি ++ এর জন্য। গৃহীত উত্তরটিও বেশ সহজ এবং সোজা।
সিলভার গঞ্জেলস

উত্তর:


162

স্ট্যান্ডার্ড পদ্ধতিটি হ'ল পৃথক অক্ষ পরীক্ষা করা ( এটিতে একটি গুগল অনুসন্ধান করুন)।

সংক্ষেপে:

  • দুটি বস্তু ছেদ করে না যদি আপনি কোনও লাইন খুঁজে পান যা দুটি বস্তুকে পৃথক করে। উদাহরণস্বরূপ, কোনও সামগ্রীর অবজেক্ট / সমস্ত পয়েন্টগুলি লাইনের বিভিন্ন দিকে থাকে।

মজার বিষয় হ'ল এটি দুটি আয়তক্ষেত্রের সমস্ত প্রান্তটি পরীক্ষা করার পক্ষে যথেষ্ট। যদি আয়তক্ষেত্রগুলি কোনও প্রান্তকে ওভারল্যাপ না করে তবে তা পৃথক অক্ষ হবে।

2 ডি তে আপনি ঝাল ব্যবহার না করে এটি করতে পারেন। একটি প্রান্তটি কেবল দু'টি শীর্ষে যেমন পার্থক্য হিসাবে সংজ্ঞায়িত করা হয়, যেমন eg

  edge = v(n) - v(n-1)

আপনি এটি 90 ° ঘোরার মাধ্যমে একটি লম্ব পেতে পারেন ° 2 ডি তে এটি সহজ:

  rotated.x = -unrotated.y
  rotated.y =  unrotated.x

সুতরাং কোনও ত্রিকোণমিতি বা opালু জড়িত নেই। ভেক্টরকে ইউনিট-দৈর্ঘ্যে সাধারণকরণের প্রয়োজন হয় না।

যদি আপনি পরীক্ষা করতে চান যে কোনও বিন্দু লাইনের এক বা অন্য দিকে থাকে আপনি কেবল বিন্দু-পণ্যটি ব্যবহার করতে পারেন। সাইন আপনাকে জানাবে যে আপনি কোন দিকে আছেন:

  // rotated: your rotated edge
  // v(n-1) any point from the edge.
  // testpoint: the point you want to find out which side it's on.

  side = sign (rotated.x * (testpoint.x - v(n-1).x) + 
               rotated.y * (testpoint.y - v(n-1).y);

এখন আয়তক্ষেত্র A এর সমস্ত বিন্দু B এবং তদ্বিপরীত প্রান্তগুলির বিরুদ্ধে পরীক্ষা করুন। যদি আপনি একটি পৃথক প্রান্ত দেখতে পান তবে অবজেক্টগুলি ছেদ না করে (বিতে সমস্ত অন্যান্য পয়েন্ট সরবরাহ করার জন্য প্রান্তের অন্য দিকে রয়েছে - নীচের চিত্রটি দেখুন)। যদি আপনি কোনও পৃথক প্রান্ত খুঁজে না পান হয় হয় আয়তক্ষেত্রগুলি ছেদ করছে বা অন্য একটিতে একটি আয়তক্ষেত্র রয়েছে।

পরীক্ষাটি কোনও উত্তল বহুভুজ বিটিডব্লিউয়ের সাথে কাজ করে ..

সংশোধন: একটি পৃথক প্রান্ত চিহ্নিত করতে, এটি প্রতিটি আয়তক্ষেত্রের সমস্ত পয়েন্টের অন্য প্রান্তের বিপরীতে পরীক্ষা করা যথেষ্ট নয়। প্রার্থী প্রান্ত E (নীচে) যেমন পৃথক প্রান্ত হিসাবে চিহ্নিত হবে, কারণ A এর সমস্ত পয়েন্ট E এর একই অর্ধ-সমতলে রয়েছে। তবে এটি কোনও পৃথক প্রান্ত নয় কারণ বি এর শীর্ষক Vb1 এবং Vb2 রয়েছে অর্ধ বিমানেও আছে। এটি কেবল তখনই পৃথক প্রান্ত হতে পারে যদি এমনটি না ঘটে http://www.iassess.com/collision.png


2
এই অ্যালগরিদম সমস্ত ক্ষেত্রে কাজ করে না। দ্বিতীয় আয়তক্ষেত্রটি প্রথম আয়তক্ষেত্রটি 45 ডিগ্রি ঘোরানো এবং তির্যক বরাবর অফসেট স্থাপন করা সম্ভব যাতে এটি উপরের ছেদ পরীক্ষাটি পূরণ করে তবে ছেদ না করে।
স্কিজে

6
স্কিজ, আটটি কিনারা পরীক্ষা করুন। বস্তু আট প্রান্ত নয় ছেদ এক করতে পারেন হবে তাদেরকে পৃথক। আপনি আপনার কেস দেখাচ্ছে এমন কোনও চিত্র পোস্ট করেন না কেন? আমি আপনাকে অক্ষটি দেখাতে পারি ..
নিলস পাইপেনব্রিংক

2
আমার ভুল, এটি সেই অবস্থার সাথে লড়াই করে।
স্কিজ

2
চিত্রটি এখন মারা গেছে (নভেম্বর 2012)
জন ডিভোরাক

2
এটি দেখার জন্য আমার অনেক সমস্যা হয়েছিল তাই আমি মনে করি যা চিত্রটি রেফারেন্স করা হচ্ছে তা আবার তৈরি করেছি। imgur.com/bNwrzsv
Rjdlee

16

মূলত নিম্নলিখিত ছবিটি দেখুন:


দুটি বাক্সের সংঘর্ষ হলে এ এবং বি রেখাগুলি ওভারল্যাপ হয়ে যাবে।

নোট করুন যে এটি এক্স এবং ওয়াই অক্ষ উভয় করতে হবে এবং আয়তক্ষেত্রগুলির সংঘর্ষের জন্য উভয়কেই ওভারল্যাপ করা দরকার to

Gamsutra.com এ একটি ভাল নিবন্ধ রয়েছে যা প্রশ্নের উত্তর দেয় (ছবিটি নিবন্ধ থেকে)। আমি 5 বছর আগে অনুরূপ অ্যালগরিদম করেছি এবং পরে এখানে পোস্ট করার জন্য আমার কোড স্নিপেট খুঁজে পেতে হবে

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


1
স্পষ্টতই, দুটি স্কোয়ার (0,0,1,1) এবং (0,3,1,4) ওভারল্যাপ না করে তবে এক্স অক্ষগুলিতে তাদের অনুমানগুলি সম্পূর্ণরূপে ওভারল্যাপ হয়। উভয় পরীক্ষা প্রয়োজনীয়, সংমিশ্রণ যথেষ্ট।
এমসাল্টারস

18
এক্স এবং ওয়াই অনুমানগুলি ওভারল্যাপ করার পক্ষে এটি পর্যাপ্ত নয়: উদাহরণস্বরূপ আয়তক্ষেত্রগুলি নিন [(0,0), (0,3), (3,3), (3,0)] এবং [(2,5), (5,2), (7,4), (4,7)]।
জোয়েল

4
আমি জিএলে @ জোয়েলের সাথে একমত এই পদ্ধতিতে বড় আকারের কেসগুলি মিস হয় যেখানে আয়তক্ষেত্রগুলি ওভারল্যাপ হয় না, তবুও তাদের অনুমানিত রেডিয়াই এক্স এবং y উভয় ক্ষেত্রেই করে।
স্কটি টি

5
এই উত্তরটি ভুল নয়, তবে এটি বিভ্রান্তিকর। এটি সত্য যে: দুটি বক্সের সাথে যদি সংঘর্ষ হয়, তবে A এবং B লাইনগুলি ওভারল্যাপ হবে। তবে এটিও সত্য যে: A এবং B লাইনগুলি যদি ওভারল্যাপ হয় তবে দুটি বাক্স সংঘর্ষে থাকতে পারে বা নাও পারে
ম্যাট

7
@floater: আমি বলতে চাই এটা হচ্ছে শুধুমাত্র না ভুল, কিন্তু এছাড়াও বিভ্রান্তিকর, যা এমনকি খারাপ।
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

4

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

এম_পিগ্ল্যাডিয়েটারের উত্তরের সমালোচনা পয়েন্টটি হ'ল আমাদের উভয় অক্ষের (x এবং y) দুটি আয়তক্ষেত্রের প্রজেকশন পরীক্ষা করা উচিত। যদি দুটি অনুমানগুলি ওভারল্যাপ করা হয়, তবে আমরা বলতে পারি যে এই দুটি আয়তক্ষেত্র ওভারল্যাপ করা আছে। সুতরাং m_p গ্ল্যাডিয়েটরের উত্তরের উপরের মন্তব্যগুলি ভুল।

সাধারণ পরিস্থিতির জন্য, যদি দুটি আয়তক্ষেত্র ঘোরানো না হয়, তবে আমরা কাঠামোর সাথে একটি আয়তক্ষেত্র উপস্থাপন করি:

struct Rect {
    x, // the center in x axis
    y, // the center in y axis
    width,
    height
}

আমরা আয়তক্ষেত্র A, B এর সাথে rectA, rectB রেখেছি।

    if Math.abs(rectA.x - rectB.x) < (Math.abs(rectA.width + rectB.width) / 2) 
&& (Math.abs(rectA.y - rectB.y) < (Math.abs(rectA.height + rectB.height) / 2))
    then
        // A and B collide
    end if

দুটি আয়তক্ষেত্রের যে কোনও একটি যদি ঘোরানো হয়, তবে এক্স এবং ওয়াই অক্ষের উপর তাদের প্রক্ষেপণ নির্ধারণের জন্য কিছু প্রচেষ্টা প্রয়োজন হতে পারে। স্ট্রাক্ট রোটেটরেটকে নিম্নলিখিত হিসাবে সংজ্ঞায়িত করুন:

struct RotatedRect : Rect {
    double angle; // the rotating angle oriented to its center
}

সোজা জন্য: পার্থক্য কিভাবে প্রস্থ 'widthA এখন একটু ভিন্ন' হল Math.sqrt(rectA.width*rectA.width + rectA.height*rectA.height) * Math.cos(rectA.angle) widthB 'rectB জন্য:Math.sqrt(rectB.width*rectB.width + rectB.height*rectB.height) * Math.cos(rectB.angle)

    if Math.abs(rectA.x - rectB.x) < (Math.abs(widthA' + widthB') / 2) 
&& (Math.abs(rectA.y - rectB.y) < (Math.abs(heightA' + heightB') / 2))
    then
        // A and B collide
    end if

একটি GDC (গেম বিকাশ সম্মেলন 2007) পিপিটি পড়ুন গেল www.realtimecollisiondetection.net/pubs/GDC07_Ericson_Physics_Tutorial_SAT.ppt


নেতিবাচক প্রশস্ততাগুলি পরিচালনা করতে আপনার "ম্যাথ.এবস (রেকটিএ.উইথ + রেকটিবি.উইথথ)" তে ম্যাথ.এবস () কেন দরকার?
অ্যালেক্সওয়েন

পৃথক অক্ষটি অগত্যা একটি কম্পাস দিক নয়, এটি কোনও কোণ থাকতে পারে।
বেন ভয়েগট

অ-ঘোরানো আয়তক্ষেত্রাকার আয়তক্ষেত্র (x = 0, y = 0, প্রস্থ = 1, উচ্চতা = 1) এবং রেকটিবি (x = 2, y = 0, প্রস্থ = 100, উচ্চতা = 1) ছেদ করে না তবে আপনার পদ্ধতি সেগুলি বলে ছেদ করে। আমি কি ভুল কিছু করছি?
কাগামী স্যাসা রোজলাইট

4

কোকোয় আপনি সহজেই সনাক্ত করতে পারবেন নির্বাচিতআরিয়া রেক্টটি আপনার ঘোরানো এনএসভিউয়ের ফ্রেম রেক্টটিকে ছেদ করে কিনা। আপনি বহুভুজ গণনা করার প্রয়োজন নেই, যেমন একটি সাধারণ। কেবলমাত্র আপনার এনএসভিউ সাবক্লাসে এই পদ্ধতিগুলি যুক্ত করুন। উদাহরণস্বরূপ, ব্যবহারকারী এনএসভিউর তত্ত্বাবধানে একটি অঞ্চল নির্বাচন করে, তারপরে আপনি পদ্ধতিটি নাছিসরেটসেক্টমেটকে নির্বাচিতআরিয়া রেক্টটি পাস করে কল করবেন। API রূপান্তর: সেই কাজটি করবে will এটি নির্বাচন করার জন্য আপনি এনএসভিউতে ক্লিক করলে একই কৌশল কাজ করে। সেক্ষেত্রে নীচে হিটস্টেস্ট পদ্ধতিটি কেবল ওভাররাইড করুন। API কনভার্টপয়েন্ট: সেই কাজটি করবে ;-)

- (BOOL)DoesThisRectSelectMe:(NSRect)selectedArea
{
    NSRect localArea = [self convertRect:selectedArea fromView:self.superview];

    return NSIntersectsRect(localArea, self.bounds);
}


- (NSView *)hitTest:(NSPoint)aPoint
{
    NSPoint localPoint = [self convertPoint:aPoint fromView:self.superview];
    return NSPointInRect(localPoint, self.bounds) ? self : nil;
}

2
এই কোডটি কেবল স্ক্রিনের বর্গক্ষেত্রের আয়তক্ষেত্রগুলির জন্য কাজ করে। এটি একটি তুচ্ছ ঘটনা। অনুমানটি হ'ল আমরা এমন আয়তক্ষেত্রগুলি নিয়ে কাজ করছি যা পর্দা বা একে অপরের 90 ডিগ্রি কোণে নয়।
ডানকান সি

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

এটি অ্যালগরিদম বর্ণনা করে না, যদিও এটি কেবল একটি লাইব্রেরির উল্লেখ করেছে যা এটি ইতিমধ্যে ব্যবহার করেছে।
বেন ভয়েগট

2

একটি আয়তক্ষেত্রের যে কোনও রেখা অন্যের যে কোনও রেখাকে ছেদ করে কিনা তা পরীক্ষা করে দেখুন। নিষ্পাপ লাইন বিভাগের ছেদটি কোড করা সহজ।

আপনার যদি আরও গতির প্রয়োজন হয় তবে লাইন সেগমেন্ট ছেদ (সুইপ-লাইন) এর জন্য উন্নত অ্যালগরিদম রয়েছে। Http://en.wikedia.org/wiki/Line_segment_intersection দেখুন


4
সাবধান হন!
কেসটি

2

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

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


1

আমি মনে করি এটিই সমস্ত সম্ভাব্য কেসের যত্ন নেবে। নিম্নলিখিত পরীক্ষা করুন।

  1. আয়তক্ষেত্র 1 এর উল্লম্বগুলির মধ্যে যে কোনওটি আয়তক্ষেত্র 2 এবং এর বিপরীতে থাকুন Check যে কোনও সময় আপনি অন্য একটি আয়তক্ষেত্রের অভ্যন্তরে অবস্থিত একটি শীর্ষবিন্দু খুঁজে পান আপনি এটিকে ছেদ করতে এবং অনুসন্ধান বন্ধ করে দিতে পারেন। এটি সম্পূর্ণরূপে অন্যটির অভ্যন্তরে থাকা একটি আয়তক্ষেত্রের যত্ন নেবে।
  2. উপরের পরীক্ষাটি যদি বেআইনী হয় তবে অন্যান্য আয়তক্ষেত্রের প্রতিটি রেখার সাথে 1 টি আয়তক্ষেত্রের প্রতিটি রেখার ছেদযুক্ত বিন্দুগুলি সন্ধান করুন। ছেদ বিন্দু একবার খুঁজে পাওয়া যায় যে এটি সম্পর্কিত 4 ​​পয়েন্ট দ্বারা নির্মিত কল্পিত আয়তক্ষেত্রের মধ্যে বাস করে কিনা। এই জাতীয় বিন্দু যখন পাওয়া যায় তখন তারা সিদ্ধান্তকে ছেদ করে এবং অনুসন্ধান বন্ধ করে দেয় stop

যদি উপরের 2 টি পরীক্ষা মিথ্যা ফিরে আসে তবে এই 2 টি আয়তক্ষেত্র ওভারল্যাপ হয় না।


0

আপনি যদি জাভা ব্যবহার করছেন তবে শেপ ইন্টারফেসের সমস্ত বাস্তবায়নের একটি ছেদ করার পদ্ধতি রয়েছে যা একটি আয়তক্ষেত্র গ্রহণ করে।


দুর্ভাগ্যক্রমে আমি সি # ব্যবহার করছি। আয়তক্ষেত্র শ্রেণিতে একটি সমন্বিত () পদ্ধতি রয়েছে তবে এটি কেবল ঘোরানো আয়তক্ষেত্রগুলির জন্য।
ব্যবহারকারী 20493

ছেদ করা () পদ্ধতিটি বেশ বেহুদা কারণ এটি আমার অনুমানের ছেলের পরিবর্তে বুলিয়ান ফিরে আসে।
জেডজেড 5

0

ঠিক আছে, নিষ্ঠুর বল পদ্ধতিটি অনুভূমিক আয়তক্ষেত্রের প্রান্তগুলি চালনা করা এবং প্রতিটি পয়েন্টটি অন্য আয়তক্ষেত্রে পড়েছে কিনা তা দেখার জন্য প্রান্তটি বরাবর পরীক্ষা করা।

গাণিতিক উত্তর হ'ল উভয় আয়তক্ষেত্রের প্রতিটি প্রান্তকে বর্ণনা করে সমীকরণ তৈরি করা। এখন আপনি কেবল খুঁজে পেতে পারেন যে আয়তক্ষেত্র A থেকে চারটি রেখার যে কোনও একটি আয়তক্ষেত্র B এর যে কোনও রেখা ছেদ করে, এটি একটি সরল (দ্রুত) রৈখিক সমীকরণ দ্রাবক হওয়া উচিত।

-Adam


2
সমীকরণগুলির সাথে সমস্যা হ'ল আপনার যখন একটি উল্লম্ব রেখা থাকে, যার অসীম opeাল থাকে।
ব্যবহারকারী 20493

প্রতিটি সমাধানের জন্য কোণার কেস রয়েছে।
অ্যাডাম ডেভিস

2
এবং একটি বর্গ সম্পূর্ণরূপে অন্যটি বেষ্টিত।
অলিভার হাল্লাম

0

অক্ষ-প্রান্তরেখার প্রতিটি পাশের কোণযুক্ত আয়তক্ষেত্রের প্রতিটি ছেদটি আপনি খুঁজে পেতে পারেন। প্রতিটি পক্ষ যে অনন্ত লাইনের সমীকরণ (যেমন v1 + t (v2-v1) এবং v'1 + t '(v'2-v'1) মূলত) এর বিন্দুটি সন্ধান করে এটি করুন এই দুটি সমীকরণ সমান হলে লাইনগুলি টিয়ের জন্য সমাধান করে (যদি সেগুলি সমান্তরাল হয় তবে আপনি এটির জন্য পরীক্ষা করতে পারেন) এবং তারপরে পরীক্ষা করে যে বিন্দুটি দুটি শীর্ষ স্তরের মধ্যবর্তী রেখার অংশে রয়েছে কিনা, এটি সত্য যে 0 <= t <= 1 এবং 0 <= t '<= 1।

যাইহোক, যখন কোনও আয়তক্ষেত্র অন্যটিকে পুরোপুরি coversেকে দেয় তখন বিষয়টি কেস করে না। যেটি আয়তক্ষেত্রের চারটি পয়েন্টই অন্য আয়তক্ষেত্রের মধ্যে রয়েছে কিনা তা পরীক্ষা করে আপনি কভার করতে পারেন can


0

এই সমস্যার 3 ডি সংস্করণের জন্য আমি এটিই করব :

সমীকরণ পি 1 এবং পি 2 দ্বারা বর্ণিত প্লেন হিসাবে 2 টি আয়তক্ষেত্রের মডেল করুন, তারপরে P1 = P2 লিখুন এবং ছেদ সমীকরণের রেখাটি থেকে বের করুন, বিমানগুলি সমান্তরাল (কোনও ছেদ নেই), বা একই সমতলে থাকলে, উপস্থিত থাকবে না, কোন ক্ষেত্রে আপনি 0 = 0 পান। সেক্ষেত্রে আপনাকে একটি 2 ডি আয়তক্ষেত্র ছেদ আলগোরিদিম নিয়োগ করতে হবে।

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

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

এটি গাণিতিক বিবরণ, দুর্ভাগ্যক্রমে আমার উপরোক্ত কোনও কোড নেই।


আপনি সেই অংশটি মিস করেছেন যেখানে আপনি প্ল্যানার ছেদ রেখাটি খুঁজে পেয়েছেন, আপনাকে নিশ্চিত করতে হবে যে এর একটি অংশ উভয় আয়তক্ষেত্রের মধ্যেই বিদ্যমান।
লি লুভিয়ের

0

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

এই অ্যালগরিদমটি পৃথক অক্ষ পরীক্ষার চেয়ে কিছুটা বেশি দীর্ঘ-বায়ুযুক্ত তবে এটি দ্রুত কারণ কেনাগুলি কেবল দুটি কোয়াড্র্যান্ট অতিক্রম করে থাকলে এটির জন্য অর্ধ-বিমানের পরীক্ষা প্রয়োজন (পৃথক অক্ষ পদ্ধতিটি ব্যবহার করে 32 টি পর্যন্ত পরীক্ষার বিপরীতে)

অ্যালগরিদমের আরও সুবিধা রয়েছে যে এটি যে কোনও বহুভুজ (উত্তল বা অবতল) এর ওভারল্যাপ পরীক্ষা করতে ব্যবহার করা যেতে পারে । যতদূর আমি জানি, অ্যালগরিদমটি কেবল 2 ডি স্পেসে কাজ করে।


3
আমি ভুল হতে পারি, তবে এটি কি কেবল একটি আয়তক্ষেত্রের উল্লম্ব অন্যটির ভিতরে থাকে কিনা তা পরীক্ষা করে না? যদি হ্যাঁ, এটি পর্যাপ্ত নয় কারণ আয়তক্ষেত্রগুলি ভিতরে কোনও দিক ছাড়াই ওভারল্যাপ হতে পারে।
sinelaw

তারা কি আয়তক্ষেত্র সহ? কিভাবে? আমার কাছে মনে হয় যে 2 টি আয়তক্ষেত্র ছেদ করার জন্য, কোনও একটি আয়তক্ষেত্রের কমপক্ষে একটি ভার্টেক্সটি অবশ্যই অন্য আয়তক্ষেত্রের উপরে থাকা উচিত।
ডানকান সি

@ ডানক্যানসি: হ্যাঁ, তারা পারেন। কাউন্টারিক নমুনা একটি ক্রস এবং এটি এমনকি মূল প্রশ্নে তালিকাভুক্ত ছিল।
বেন ভয়েগট

@ বেনভয়েগ্ট এটি একটি খুব পুরানো থ্রেড, তবে আপনি একেবারে ঠিক।
ডানকান সি

0

হয় আমি অন্য কিছু মিস করছি কেন এত জটিল করে তুলছি?

যদি (x1, y1) এবং (X1, Y1) আয়তক্ষেত্রগুলির কোণে থাকে তবে ছেদটি ছেদন করার জন্য এটি করুন:

    xIntersect = false;
    yIntersect = false;
    if (!(Math.min(x1, x2, x3, x4) > Math.max(X1, X2, X3, X4) || Math.max(x1, x2, x3, x4) < Math.min(X1, X2, X3, X4))) xIntersect = true;
    if (!(Math.min(y1, y2, y3, y4) > Math.max(Y1, Y2, Y3, Y4) || Math.max(y1, y2, y3, y4) < Math.min(Y1, Y2, Y3, Y4))) yIntersect = true;
    if (xIntersect && yIntersect) {alert("Intersect");}

3
আপনি অনুপস্থিত যে তিনি চাইছেন যে কোনও একটি নির্বিচারে কোণে ঘোরানো হোক।
রোবটব্যাগস

0

আমি এটি এর মতো প্রয়োগ করেছি:

bool rectCollision(const CGRect &boundsA, const Matrix3x3 &mB, const CGRect &boundsB)
{
    float Axmin = boundsA.origin.x;
    float Axmax = Axmin + boundsA.size.width;
    float Aymin = boundsA.origin.y;
    float Aymax = Aymin + boundsA.size.height;

    float Bxmin = boundsB.origin.x;
    float Bxmax = Bxmin + boundsB.size.width;
    float Bymin = boundsB.origin.y;
    float Bymax = Bymin + boundsB.size.height;

    // find location of B corners in A space
    float B0x = mB(0,0) * Bxmin + mB(0,1) * Bymin + mB(0,2);
    float B0y = mB(1,0) * Bxmin + mB(1,1) * Bymin + mB(1,2);

    float B1x = mB(0,0) * Bxmax + mB(0,1) * Bymin + mB(0,2);
    float B1y = mB(1,0) * Bxmax + mB(1,1) * Bymin + mB(1,2);

    float B2x = mB(0,0) * Bxmin + mB(0,1) * Bymax + mB(0,2);
    float B2y = mB(1,0) * Bxmin + mB(1,1) * Bymax + mB(1,2);

    float B3x = mB(0,0) * Bxmax + mB(0,1) * Bymax + mB(0,2);
    float B3y = mB(1,0) * Bxmax + mB(1,1) * Bymax + mB(1,2);

    if(B0x<Axmin && B1x<Axmin && B2x<Axmin && B3x<Axmin)
        return false;
    if(B0x>Axmax && B1x>Axmax && B2x>Axmax && B3x>Axmax)
        return false;
    if(B0y<Aymin && B1y<Aymin && B2y<Aymin && B3y<Aymin)
        return false;
    if(B0y>Aymax && B1y>Aymax && B2y>Aymax && B3y>Aymax)
        return false;

    float det = mB(0,0)*mB(1,1) - mB(0,1)*mB(1,0);
    float dx = mB(1,2)*mB(0,1) - mB(0,2)*mB(1,1);
    float dy = mB(0,2)*mB(1,0) - mB(1,2)*mB(0,0);

    // find location of A corners in B space
    float A0x = (mB(1,1) * Axmin - mB(0,1) * Aymin + dx)/det;
    float A0y = (-mB(1,0) * Axmin + mB(0,0) * Aymin + dy)/det;

    float A1x = (mB(1,1) * Axmax - mB(0,1) * Aymin + dx)/det;
    float A1y = (-mB(1,0) * Axmax + mB(0,0) * Aymin + dy)/det;

    float A2x = (mB(1,1) * Axmin - mB(0,1) * Aymax + dx)/det;
    float A2y = (-mB(1,0) * Axmin + mB(0,0) * Aymax + dy)/det;

    float A3x = (mB(1,1) * Axmax - mB(0,1) * Aymax + dx)/det;
    float A3y = (-mB(1,0) * Axmax + mB(0,0) * Aymax + dy)/det;

    if(A0x<Bxmin && A1x<Bxmin && A2x<Bxmin && A3x<Bxmin)
        return false;
    if(A0x>Bxmax && A1x>Bxmax && A2x>Bxmax && A3x>Bxmax)
        return false;
    if(A0y<Bymin && A1y<Bymin && A2y<Bymin && A3y<Bymin)
        return false;
    if(A0y>Bymax && A1y>Bymax && A2y>Bymax && A3y>Bymax)
        return false;

    return true;
}

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

এটি যতটা সম্ভব অনুকূল নাও হতে পারে। গতি একটি বিশাল উদ্বেগ ছিল না। তবে এটি আমার জন্য ঠিক আছে বলে মনে হচ্ছে।


0

গৃহীত উত্তরের একটি মতলব বাস্তবায়ন এখানে:

function olap_flag = ol(A,B,sub)

%A and B should be 4 x 2 matrices containing the xy coordinates of the corners in clockwise order

if nargin == 2
  olap_flag = ol(A,B,1) && ol(B,A,1);
  return;
end

urdl = diff(A([1:4 1],:));
s = sum(urdl .* A, 2);
sdiff = B * urdl' - repmat(s,[1 4]);

olap_flag = ~any(max(sdiff)<0);

0

এটি প্রচলিত পদ্ধতি, লাইনে লাইনে যান এবং লাইনগুলি ছেদ করছে কিনা তা পরীক্ষা করুন। এটি ম্যাটল্যাবে কোড in

C1 = [0, 0];    % Centre of rectangle 1 (x,y)
C2 = [1, 1];    % Centre of rectangle 2 (x,y)
W1 = 5; W2 = 3; % Widths of rectangles 1 and 2
H1 = 2; H2 = 3; % Heights of rectangles 1 and 2
% Define the corner points of the rectangles using the above
R1 = [C1(1) + [W1; W1; -W1; -W1]/2, C1(2) + [H1; -H1; -H1; H1]/2];
R2 = [C2(1) + [W2; W2; -W2; -W2]/2, C2(2) + [H2; -H2; -H2; H2]/2];

R1 = [R1 ; R1(1,:)] ;
R2 = [R2 ; R2(1,:)] ;

plot(R1(:,1),R1(:,2),'r')
hold on
plot(R2(:,1),R2(:,2),'b')


%% lines of Rectangles 
L1 = [R1(1:end-1,:) R1(2:end,:)] ;
L2 = [R2(1:end-1,:) R2(2:end,:)] ;
%% GEt intersection points
P = zeros(2,[]) ;
count = 0 ;
for i = 1:4
    line1 = reshape(L1(i,:),2,2) ;
    for j = 1:4
        line2 = reshape(L2(j,:),2,2) ;
        point = InterX(line1,line2) ;
        if ~isempty(point)
            count = count+1 ;
            P(:,count) = point ;
        end
    end
end
%%
if ~isempty(P)
    fprintf('Given rectangles intersect at %d points:\n',size(P,2))
    plot(P(1,:),P(2,:),'*k')
end

ইন্টারএক্স ফাংশনটি ডাউনলোড করা যেতে পারে: https://in.mathworks.com/matlabcentral/fileexchange/22441-curve-intersections?focused=5165138&tab=function


0

আমার নিজস্ব একটি সহজ পদ্ধতি আছে, যদি আমাদের 2 টি আয়তক্ষেত্র থাকে:

আর 1 = (মিনিট x1, সর্বোচ্চ_এক্স 1, মিনিট_ই 1, সর্বোচ্চ_ওয়াই 1)

আর 2 = (মিনিট_ এক্স 2, সর্বোচ্চ_এক্স 2, মিনিট_ই 2, সর্বোচ্চ_ওয়াই 2)

তারা ওভারল্যাপ করে যদি এবং কেবল যদি:

ওভারল্যাপ = (সর্বোচ্চ_এক্স 1> মিনি_এক্স 2) এবং (সর্বোচ্চ_এক্স 2> মিনি_এক্স 1) এবং (সর্বোচ্চ_এই 1> মিনিট_2 2) এবং (সর্বোচ্চ_এ 2> মিনি_ই 1)

আপনি এটি 3D বাক্সের জন্যও করতে পারেন, এটি এটি যে কোনও সংখ্যক মাত্রার জন্য কাজ করে।


0

অন্যান্য উত্তরে যথেষ্ট বলা হয়েছে, সুতরাং আমি কেবল সিউডোকোড ওয়ান-লাইনার যুক্ত করব:

!(a.left > b.right || b.left > a.right || a.top > b.bottom || b.top > a.bottom);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.