বৃত্ত-আয়তক্ষেত্রের সংঘর্ষ সনাক্তকরণ (ছেদ)


192

আমি কীভাবে বলতে পারি যে একটি বৃত্ত এবং একটি আয়তক্ষেত্র 2D ইউক্লিডিয়ান স্পেসে ছেদ করে কিনা? (যেমন ক্লাসিক 2 ডি জ্যামিতি)


1
আয়তক্ষেত্রটি কি সর্বদা অক্ষগুলির সাথে একত্রিত হয়, বা এটি একটি নির্বিচারে কোণ দ্বারা ঘোরানো যেতে পারে?
জেমস 0

11
@ ইজেমস: এটি কীভাবে গুরুত্বপূর্ণ? আপনি একটি বৃত্ত দিয়ে ছেদ করার জন্য আয়তক্ষেত্রটি পরীক্ষা করছেন ; আপনি সর্বদা আপনার সমন্বয় ব্যবস্থাটি রূপান্তর করতে পারেন যাতে আয়তক্ষেত্রটি অক্ষরেখানের সমান্তরাল হয় যার সাথে বৃত্তের কোনও পরিবর্তন হয় না :-)
শ্রীভাতসার

আপনি একটি উত্তর হিসাবে যে যোগ করা উচিত, -Θ মাধ্যমে আবর্তিত এবং সব ...
AIB

2
@ শ্রীভাতসার: এটি গুরুত্বের সাথে বিবেচনা করা উচিত বা সেই সমন্বয়মূলক অনুবাদটি সম্পর্কে আমাকে চিন্তার দরকার নেই। @ আইয়ব: ওহে প্রিয়!
জেমস

উত্তর:


191

কেবল দুটি ক্ষেত্রে দেখা যায় যখন বৃত্তটি আয়তক্ষেত্রের সাথে ছেদ করে:

  • হয় বৃত্তের কেন্দ্রটি আয়তক্ষেত্রের অভ্যন্তরে অবস্থিত, অথবা
  • আয়তক্ষেত্রের একটি প্রান্তের বৃত্তে একটি বিন্দু রয়েছে।

নোট করুন যে এটিটির জন্য আয়তক্ষেত্রটি অক্ষ-সমান্তরাল হওয়া দরকার না।

কিছু পৃথক উপায়ে একটি বৃত্ত এবং আয়তক্ষেত্র ছেদ করতে পারে

(এটি দেখার একটি উপায়: যদি কোনও প্রান্তের বৃত্তে কোনও বিন্দু না থাকে (যদি সমস্ত প্রান্তটি বৃত্তের "সম্পূর্ণ" বাইরে "থাকে) তবে কেবলমাত্র বৃত্তটি বহুভুজকে ছেদ করতে পারে যদি এটি সম্পূর্ণরূপে থাকে তবে বহুভুজ।)

যে অন্তর্দৃষ্টি দিয়ে, নিচের মত কিছু কাজ করবে, যেখানে বৃত্ত সেন্টার রয়েছে Pএবং ব্যাসার্ধ R, এবং আয়তক্ষেত্র কোণ রয়েছে A, B, C, D, যাতে (সম্পূর্ণ হয়নি কোড) মধ্যে:

def intersect(Circle(P, R), Rectangle(A, B, C, D)):
    S = Circle(P, R)
    return (pointInRectangle(P, Rectangle(A, B, C, D)) or
            intersectCircle(S, (A, B)) or
            intersectCircle(S, (B, C)) or
            intersectCircle(S, (C, D)) or
            intersectCircle(S, (D, A)))

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

0 ≤ AP·AB ≤ AB·AB and 0 ≤ AP·AD ≤ AD·AD

এবং intersectCircle()এটি কার্যকর করাও সহজ: একটি উপায় Pহ'ল লম্ব থেকে লম্বের লম্বার পাটি পর্যাপ্ত এবং শেষ পয়েন্টগুলির মধ্যে রয়েছে কিনা তা পরীক্ষা করা এবং অন্যথায় শেষ পয়েন্টগুলি পরীক্ষা করা।

দুর্দান্ত জিনিসটি হ'ল একই ধারণাটি কেবল আয়তক্ষেত্রের জন্য নয়, কোনও সাধারণ বহুভুজ সহ একটি বৃত্তের ছেদকেও কার্যকর করে - এমনকি উত্তল হতে হবে না!


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

2
@ পানিক: ঠিক আছে, দুজনেই ধ্রুবক সময়। :-) তবে হ্যাঁ, এটি সাধারণ সমাধান হিসাবে আরও কার্যকর, কোনও দিকনির্দেশের সাথে আয়তক্ষেত্রগুলি আবৃত করে এবং বাস্তবে কোনও সাধারণ বহুভুজ।
শ্রীভাতসারআর

7
যে ক্ষেত্রে ক্ষেত্রে আয়তক্ষেত্রটি পুরো বৃত্তের ভিতরে থাকে তবে বৃত্তের কেন্দ্রটি আয়তক্ষেত্রের মধ্যে নয়?
এরিকসোক

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

2
@ ডেক্সডি.হান্টার যদি বৃত্তের কেন্দ্রটি আয়তক্ষেত্রের বাইরে থাকে তবে এর একটি অংশ আয়তক্ষেত্রের অভ্যন্তরে থাকে তবে অগত্যা আয়তক্ষেত্রের একটি প্রান্তটি বৃত্তটিকে ছেদ করে।
শ্রীভাতসার

289

আমি এখানে এটি কীভাবে করব:

bool intersects(CircleType circle, RectType rect)
{
    circleDistance.x = abs(circle.x - rect.x);
    circleDistance.y = abs(circle.y - rect.y);

    if (circleDistance.x > (rect.width/2 + circle.r)) { return false; }
    if (circleDistance.y > (rect.height/2 + circle.r)) { return false; }

    if (circleDistance.x <= (rect.width/2)) { return true; } 
    if (circleDistance.y <= (rect.height/2)) { return true; }

    cornerDistance_sq = (circleDistance.x - rect.width/2)^2 +
                         (circleDistance.y - rect.height/2)^2;

    return (cornerDistance_sq <= (circle.r^2));
}

এখানে কিভাবে এটা কাজ করে:

illusration

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

  2. দ্বিতীয় জোড়া লাইনগুলি এমন সহজ কেসগুলিকে সরিয়ে দেয় যেখানে বৃত্তটি আয়তক্ষেত্র থেকে অনেক দূরে (উভয় দিকে) যে কোনও ছেদ করা সম্ভব নয় is এটি চিত্রের সবুজ অঞ্চলের সাথে মিলে যায়।

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

  4. অবশিষ্ট রেখাগুলি কঠিন ক্ষেত্রে গণনা করে যেখানে বৃত্তটি আয়তক্ষেত্রের কোণটিকে ছেদ করতে পারে। সমাধানের জন্য, বৃত্তের কেন্দ্র এবং কোণ থেকে দূরত্বটি গণনা করুন এবং তারপরে যাচাই করুন যে দূরত্বটি বৃত্তের ব্যাসার্ধের চেয়ে বেশি নয়। এই গণনাটি সমস্ত চেনাশোনাগুলির জন্য মিথ্যা প্রত্যাবর্তন করে যার কেন্দ্রটি লাল ছায়াযুক্ত অঞ্চলের মধ্যে রয়েছে এবং সেই সমস্ত চেনাশোনাগুলির জন্য সত্য ফিরে আসে যার কেন্দ্রটি সাদা ছায়াযুক্ত অঞ্চলের মধ্যে।


4
খুব সুন্দর! দ্রষ্টব্য: আপাতদৃষ্টিতে এখানে, rect.x / y আয়তক্ষেত্রের উপরের ডানদিকে রয়েছে। ব্যাসার্ধের স্কোয়ারের সাথে তুলনা করে আপনি ব্যয়বহুল বর্গমূলকে বাদ দিতে পারেন।
luqui

2
ওহ না, আমার খারাপ। rect.x / y আয়তক্ষেত্রের নীচে বাম দিকে। আমি লিখতাম: বৃত্তীয় দূরত্ব.x = অ্যাবস (সার্কেল.এক্স - (rect.x + rect.width / 2));
luqui

2
@ ট্যানার: আমরা সেখানে যাই। ব্যাকআপ এবং ওসিডি;)
জেমস

11
কেবল পরিষ্কার করতে - এই উত্তরটি কেবল অক্ষ-সংযুক্ত আয়তক্ষেত্রগুলিতে প্রযোজ্য। এটি অন্যান্য উত্তরের মন্তব্যের মাধ্যমে পড়া থেকে পরিষ্কার তবে এই উত্তরটি + মন্তব্যগুলি থেকে পরিষ্কার নয়। (অক্ষ-
সংযুক্তি পাঠের

3
গ্রেট! এটি গুরুত্বপূর্ণ পাঠকদের জানতে জন্য আমি বিশ্বাস করি এখানে যে একটি RECT সংজ্ঞা rect.x & rect.y হয় হয় কেন্দ্র RECT করুন। আমার বিশ্বে একটি circleDistance_x = abs(circle.x - (rect.x-rect.w/2)); circleDistance_y = abs(circle.y - (rect.y-rect.h/2));
রেক্টরের জাইসিটি রেক্টরের

123

এটি কার্যকর করার জন্য বেশ সহজ সমাধানের একটি আরও সমাধান রয়েছে (এবং খুব দ্রুত)। এটি গোলকটি সম্পূর্ণরূপে আয়তক্ষেত্রটিতে প্রবেশ করার সময় সহ সমস্ত ছেদগুলিকে ধরে ফেলবে।

// clamp(value, min, max) - limits value to the range min..max

// Find the closest point to the circle within the rectangle
float closestX = clamp(circle.X, rectangle.Left, rectangle.Right);
float closestY = clamp(circle.Y, rectangle.Top, rectangle.Bottom);

// Calculate the distance between the circle's center and this closest point
float distanceX = circle.X - closestX;
float distanceY = circle.Y - closestY;

// If the distance is less than the circle's radius, an intersection occurs
float distanceSquared = (distanceX * distanceX) + (distanceY * distanceY);
return distanceSquared < (circle.Radius * circle.Radius);

যে কোনও শালীন গণিত লাইব্রেরির সাথে, এটি 3 বা 4 লাইনে সংক্ষিপ্ত করা যেতে পারে।


3
আপনার সেখানে একটি বাগ রয়েছে, আপনি শীর্ষ এবং নীচে নয়, বাম এবং ডানদিকে নিকটবর্তী Y অনুসন্ধান করুন, অন্যথায় সুন্দর সমাধান।
ম্যানভেরু

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

2
আমি মনে করি যে আয়তক্ষেত্রটি x- এবং y- অক্ষগুলির সাথে তির্যক হলে আপনার সমাধান ব্যর্থ হয়।
লিও

3
@ লিও আমি মনে করি এই ক্ষেত্রে সামঞ্জস্য করার জন্য এই অ্যালগরিদমটি সংশোধন করা খুব কঠিন নয়, যেহেতু উত্সটি আয়তক্ষেত্র কেন্দ্রে রয়েছে এবং আয়তক্ষেত্রটি আর তির্যক নয় সেখানে একটি সমন্বিত রূপান্তর প্রয়োগ করা উচিত। আপনাকে কেবলমাত্র বৃত্ত কেন্দ্রে রূপান্তরটি প্রয়োগ করতে হবে।
enobayram

1
এটি মাইগাপ্রো / সার্কেল- এবং- ক্রোটেটেড-र्ग্যাঙ্গেল- ক্যালিজিশন- সনাক্তকরণের কোডের মতোই যা আমি ওজেক্টিভ -সি তেও পোর্ট করেছি। খুব ভাল কাজ করে; এটি সমস্যার একটি দুর্দান্ত সমাধান।
পিকেসিএলসসফ্ট

10

আপনার গোলক এবং আয়তক্ষেত্রটি IIF ছেদ করে ক্ষেত্রের
কেন্দ্র এবং আপনার আয়তক্ষেত্রের একটি শীর্ষের মধ্যবর্তী দূরত্বটি আপনার গোলকের ব্যাসার্ধের চেয়ে ছোট
বা
বৃত্ত-কেন্দ্র এবং আপনার আয়তক্ষেত্রের এক প্রান্তের মধ্যবর্তী দূরত্বটি আপনার গোলকের ব্যাসার্ধের চেয়ে ছোট হয় ( [ পয়েন্ট-লাইনের দূরত্ব ])
অথবা
বৃত্ত কেন্দ্রটি রেট

পয়েন্ট-পয়েন্ট দূরত্বের মধ্যে রয়েছে:

পি 1 = [এক্স 1, ওয়াই 1]
পি 2 = [x2, y2]
দূরত্ব = স্কয়ার্ট (অ্যাবস (x1 - x2) + অ্যাবস (y1-y2)

পয়েন্ট-লাইন দূরত্ব:

L1 = [x1, y1], L2 = [x2, y2] (আপনার লাইনের দুটি পয়েন্ট, অর্থাৎ শীর্ষস্থানীয় পয়েন্ট)
পি 1 = [পিক্স, পাই] কিছু পয়েন্ট

দূরত্ব d = অ্যাবস ((x2-x1) (y1-py) - (x1-px) (y2-y1)) / দূরত্ব (এল 1, এল 2)


আয়তক্ষেত্রের ভিতরে বৃত্ত কেন্দ্র:
একটি পৃথক অক্ষটি গ্রহণ করুন: বিন্দু থেকে আয়তক্ষেত্রটি পৃথক করে এমন কোনও রেখার উপরে যদি কোনও প্রক্ষেপণ উপস্থিত থাকে তবে তারা ছেদ করে না

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

আপনার কেবলমাত্র অভ্যন্তরীণ-পণ্য প্রয়োজন (x = [x1, x2], y = [y1, y2], x * y = x1 * y1 + x2 * y2)

আপনার পরীক্ষাটি দেখতে এমন হবে:

// আয়তক্ষেত্র প্রান্ত: টিএল (উপরে বাম), টিআর (উপরের ডানদিকে), বিএল (নীচে বাম), বিআর (নীচে ডান)
// পরীক্ষার পয়েন্ট: পিওআই

seperated = false
উদাহরণস্বরূপ {L টিএল, টিআর}, {বিএল, বিআর}, {টিএল, বিএল}, {টিআর-বিআর} //: // প্রান্তগুলিতে
    ডি = প্রান্ত [0] - প্রান্ত [1]
    ইনারপ্রড = ডি * পিওআই
    বিরতি_মিনি = মিনিট (ডি * প্রান্ত [0], ডি * প্রান্ত [1])
    ইন্টারভাল_ম্যাক্স = সর্বোচ্চ (ডি * প্রান্ত [0], ডি * প্রান্ত [1])
    যদি না হয় (ইন্টারভাল_মিনি ≤ অভ্যন্তরীণপ্রড ≤ ইন্টারভাল_ম্যাক্স) 
           বিচ্ছিন্ন = সত্য
           ব্রেক // লুপ জন্য শেষ 
    যদি শেষ
জন্য শেষ
যদি (পৃথক সত্য হয়)    
      "কোন ছেদ নেই" ফিরে
আর 
      "ছেদ" ফিরে
যদি শেষ

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


1
দূরত্বের বিন্দুটি কোনও বর্গ ব্যবহার করা উচিত নয়, কোনও অ্যাবস নয়?
টমাস

6

এটি দ্রুততম সমাধান:

public static boolean intersect(Rectangle r, Circle c)
{
    float cx = Math.abs(c.x - r.x - r.halfWidth);
    float xDist = r.halfWidth + c.radius;
    if (cx > xDist)
        return false;
    float cy = Math.abs(c.y - r.y - r.halfHeight);
    float yDist = r.halfHeight + c.radius;
    if (cy > yDist)
        return false;
    if (cx <= r.halfWidth || cy <= r.halfHeight)
        return true;
    float xCornerDist = cx - r.halfWidth;
    float yCornerDist = cy - r.halfHeight;
    float xCornerDistSq = xCornerDist * xCornerDist;
    float yCornerDistSq = yCornerDist * yCornerDist;
    float maxCornerDistSq = c.radius * c.radius;
    return xCornerDistSq + yCornerDistSq <= maxCornerDistSq;
}

মৃত্যুদন্ড কার্যকর করার ক্রমটি নোট করুন এবং অর্ধেক প্রস্থ / উচ্চতা প্রাক-গণিত is এছাড়াও কিছু ঘড়ির চক্র সংরক্ষণ করতে স্কোয়ারিংটি "ম্যানুয়ালি" করা হয়।


3
আমি মনে করি না যে আপনি দাবি করতে পারেন যে সবচেয়ে ব্যয়বহুল কোড পাথের পাঁচটি পরীক্ষা / তুলনা কোনও প্রমাণ ছাড়াই "দ্রুততম সমাধান"।
সাম হোচেভার


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

6

আমি যে সহজ সমাধানটি নিয়ে এসেছি তা হ'ল বেশ সোজা।

এটি বৃত্তের নিকটতম আয়তক্ষেত্রের বিন্দুটি সন্ধান করে এবং তারপরে দূরত্বের তুলনা করে কাজ করে।

আপনি কয়েকটি অপারেশন দিয়ে এগুলি সব করতে পারেন এবং এমনকি স্কয়ারটি ফাংশনটি এড়িয়ে যেতে পারেন।

public boolean intersects(float cx, float cy, float radius, float left, float top, float right, float bottom)
{
   float closestX = (cx < left ? left : (cx > right ? right : cx));
   float closestY = (cy < top ? top : (cy > bottom ? bottom : cy));
   float dx = closestX - cx;
   float dy = closestY - cy;

   return ( dx * dx + dy * dy ) <= radius * radius;
}

এবং এটাই! উপরের সমাধানটি বিশ্বের উপরের বামে এক্স-অক্ষটি নির্দেশ করে একটি উত্স ধরে নেয়।

আপনি যদি কোনও চলমান চেনাশোনা এবং আয়তক্ষেত্রের মধ্যে সংঘর্ষগুলি পরিচালনা করার সমাধান চান তবে এটি আমার চেয়ে আরও জটিল এবং আরও একটি উত্তরে covered াকা রয়েছে।


বৃত্তের ব্যাসার্ধ খুব ছোট এবং এর কেন্দ্রটি আয়তক্ষেত্রের অভ্যন্তরে থাকলে এটি ছেদগুলি সনাক্ত করতে ব্যর্থ হবে!
Yoav

2
আপনি কি আসল ইনপুট সরবরাহ করতে পারেন যা এটি ব্যর্থ করে তোলে? যখন বৃত্তটি ভিতরে থাকে, পরীক্ষার বাম অংশটি 0.0 হয়। ব্যাসার্ধটি শূন্য না হলে পরীক্ষার ডান অংশটি 0.0> হওয়া উচিত
ক্লিকারমনকি

এটি কি ঘোরানো আয়তক্ষেত্রগুলির জন্যও কাজ করবে? যদি না হয় তবে দয়া করে আমাকে সে সম্পর্কে একটি ইঙ্গিত দিন .....
এম আব্দুল সামি

4

আসলে, এটি অনেক বেশি সহজ। আপনার কেবল দুটি জিনিস দরকার।

প্রথমত, আপনাকে বৃত্ত কেন্দ্র থেকে আয়তক্ষেত্রের প্রতিটি রেখার জন্য চারটি orthogonal দূরত্বের সন্ধান করতে হবে। তারপরে যদি কোনও তিনটি বৃত্ত ব্যাসার্ধের চেয়ে বড় হয় তবে আপনার বৃত্তটি আয়তক্ষেত্রটিকে ছেদ করবে না।

দ্বিতীয়ত, আপনাকে বৃত্ত কেন্দ্র এবং আয়তক্ষেত্র কেন্দ্রের মধ্যবর্তী দূরত্বটি সন্ধান করতে হবে, তারপরে আপনি বৃত্তটি আয়তক্ষেত্রের অভ্যন্তরে থাকবেন না যদি দূরতটি আয়তক্ষেত্রাকার দৈর্ঘ্যের অর্ধেকের চেয়ে বড় হয়।

শুভকামনা!


3

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

float physicsProcessCollisionBetweenSelfAndActorRect(SPhysics *self, SPhysics *actor)
{
    float diff = 99999;

    SVector relative_position_of_circle = getDifference2DBetweenVectors(&self->worldPosition, &actor->worldPosition);
    rotateVector2DBy(&relative_position_of_circle, -actor->axis.angleZ); // This aligns the coord system so the rect becomes an AABB

    float x_clamped_within_rectangle = relative_position_of_circle.x;
    float y_clamped_within_rectangle = relative_position_of_circle.y;
    LIMIT(x_clamped_within_rectangle, actor->physicsRect.l, actor->physicsRect.r);
    LIMIT(y_clamped_within_rectangle, actor->physicsRect.b, actor->physicsRect.t);

    // Calculate the distance between the circle's center and this closest point
    float distance_to_nearest_edge_x = relative_position_of_circle.x - x_clamped_within_rectangle;
    float distance_to_nearest_edge_y = relative_position_of_circle.y - y_clamped_within_rectangle;

    // If the distance is less than the circle's radius, an intersection occurs
    float distance_sq_x = SQUARE(distance_to_nearest_edge_x);
    float distance_sq_y = SQUARE(distance_to_nearest_edge_y);
    float radius_sq = SQUARE(self->physicsRadius);
    if(distance_sq_x + distance_sq_y < radius_sq)   
    {
        float half_rect_w = (actor->physicsRect.r - actor->physicsRect.l) * 0.5f;
        float half_rect_h = (actor->physicsRect.t - actor->physicsRect.b) * 0.5f;

        CREATE_VECTOR(push_vector);         

        // If we're at one of the corners of this object, treat this as a circular/circular collision
        if(fabs(relative_position_of_circle.x) > half_rect_w && fabs(relative_position_of_circle.y) > half_rect_h)
        {
            SVector edges;
            if(relative_position_of_circle.x > 0) edges.x = half_rect_w; else edges.x = -half_rect_w;
            if(relative_position_of_circle.y > 0) edges.y = half_rect_h; else edges.y = -half_rect_h;   

            push_vector = relative_position_of_circle;
            moveVectorByInverseVector2D(&push_vector, &edges);

            // We now have the vector from the corner of the rect to the point.
            float delta_length = getVector2DMagnitude(&push_vector);
            float diff = self->physicsRadius - delta_length; // Find out how far away we are from our ideal distance

            // Normalise the vector
            push_vector.x /= delta_length;
            push_vector.y /= delta_length;
            scaleVector2DBy(&push_vector, diff); // Now multiply it by the difference
            push_vector.z = 0;
        }
        else // Nope - just bouncing against one of the edges
        {
            if(relative_position_of_circle.x > 0) // Ball is to the right
                push_vector.x = (half_rect_w + self->physicsRadius) - relative_position_of_circle.x;
            else
                push_vector.x = -((half_rect_w + self->physicsRadius) + relative_position_of_circle.x);

            if(relative_position_of_circle.y > 0) // Ball is above
                push_vector.y = (half_rect_h + self->physicsRadius) - relative_position_of_circle.y;
            else
                push_vector.y = -((half_rect_h + self->physicsRadius) + relative_position_of_circle.y);

            if(fabs(push_vector.x) < fabs(push_vector.y))
                push_vector.y = 0;
            else
                push_vector.x = 0;
        }

        diff = 0; // Cheat, since we don't do anything with the value anyway
        rotateVector2DBy(&push_vector, actor->axis.angleZ);
        SVector *from = &self->worldPosition;       
        moveVectorBy2D(from, push_vector.x, push_vector.y);
    }   
    return diff;
}

2

ভিজ্যুয়ালাইজ করতে আপনার কীবোর্ডের নামপ্যাড নিন। যদি কী '5' আপনার আয়তক্ষেত্রকে উপস্থাপন করে, তবে 1-9 এর সমস্ত কীগুলি 9 টি চতুর্দিকে স্থানটি রেখা দ্বারা বিভক্ত করে যা আপনার আয়তক্ষেত্রটি তৈরি করে (5 টি অভ্যন্তরের সাথে রয়েছে) with

1) যদি বৃত্তের কেন্দ্রটি 5 টি চতুর্ভুজ (অর্থাত্ আয়তক্ষেত্রের অভ্যন্তরে) থাকে তবে দুটি আকারটি ছেদ করে।

এর বাইরে যাওয়ার সাথে সাথে দুটি সম্ভাব্য কেস রয়েছে: ক) আয়তক্ষেত্রের দুটি বা আরও বেশি প্রতিবেশী প্রান্ত দিয়ে বৃত্তটি ছেদ করে। খ) বৃত্তটি আয়তক্ষেত্রের একটি প্রান্তের সাথে ছেদ করে।

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

2) আয়তক্ষেত্রের কোন, A, B, C, D কোণার যদি বৃত্তের ভিতরে থাকে তবে দুটি আকারকে ছেদ করে।

দ্বিতীয় কেসটি কৌশলযুক্ত। আমাদের লক্ষ করা উচিত যে এটি কেবল তখনই ঘটতে পারে যখন বৃত্তের কেন্দ্রটি 2, 4, 6 বা 8 এর মধ্যে কোনও এক চতুর্থাংশের মধ্যে থাকে (প্রকৃতপক্ষে, কেন্দ্রটি যদি 1, 3, 7, 8 এর কোয়াড্রেন্টগুলির কোনওটিতে থাকে) সংশ্লিষ্ট কোণটি এটির নিকটতম স্থান হবে))

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

3) প্রতিটি লাইনের জন্য এবি, বিসি, সিডি, ডিএ, বৃত্তের কেন্দ্র পি মাধ্যমে লম্ব লাইন পি (এবি, পি), পি (বিসি, পি), পি (সিডি, পি), পি (ডিএ, পি) তৈরি করুন প্রতিটি লম্ব লাইন, যদি মূল প্রান্তের ছেদটি বৃত্তের ভিতরে থাকে তবে দুটি আকারকে ছেদ করে।

এই শেষ পদক্ষেপের জন্য একটি শর্টকাট রয়েছে। যদি বৃত্তের কেন্দ্রটি 8 টি চতুষ্কোণ হয় এবং প্রান্ত AB শীর্ষে প্রান্ত হয় তবে ছেদ বিন্দুতে A এবং B এর y- স্থানাঙ্ক হবে এবং কেন্দ্র P এর x- স্থানাঙ্ক হবে If

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

সম্পাদনা: এটি দেখা যাচ্ছে যে, আমি # 2 টি উপরের # 3 এর একটি সাবকেস বলে সরল সত্যটিকে উপেক্ষা করেছি। সর্বোপরি, কোণগুলিও প্রান্তগুলিতে পয়েন্ট। একটি দুর্দান্ত ব্যাখ্যার জন্য নীচে @ শ্রীভাতসার এর উত্তর দেখুন। এবং এরই মধ্যে, আপনি যদি দ্রুত তবে অপ্রয়োজনীয় চেক না চান তবে উপরের # 2 টি ভুলে যান।


2

এই ফাংশনটি বৃত্ত এবং আয়তক্ষেত্রের মধ্যে সংঘর্ষ (ছেদগুলি) সনাক্ত করে। তিনি তার উত্তরে ই জেমস পদ্ধতির মতো কাজ করেন তবে এটি একটি আয়তক্ষেত্রের সমস্ত কোণের জন্য সংঘর্ষ সনাক্ত করে (কেবল ডানদিকে নয়)।

বিঃদ্রঃ:

aRect.origin.x এবং aRect.origin.y আয়তক্ষেত্রের নীচে বাম কোণের স্থানাঙ্ক!

এ সার্কেল.এক্স এবং এ সার্কেল.ই সার্কেল সেন্টারের সমন্বয়কারী!

static inline BOOL RectIntersectsCircle(CGRect aRect, Circle aCircle) {

    float testX = aCircle.x;
    float testY = aCircle.y;

    if (testX < aRect.origin.x)
        testX = aRect.origin.x;
    if (testX > (aRect.origin.x + aRect.size.width))
        testX = (aRect.origin.x + aRect.size.width);
    if (testY < aRect.origin.y)
        testY = aRect.origin.y;
    if (testY > (aRect.origin.y + aRect.size.height))
        testY = (aRect.origin.y + aRect.size.height);

    return ((aCircle.x - testX) * (aCircle.x - testX) + (aCircle.y - testY) * (aCircle.y - testY)) < aCircle.radius * aCircle.radius;
}

1

আমি একটি পদ্ধতি করেছি যা ব্যয়বহুল পাইথাগোরাসগুলি এড়ানো যায় না - প্রয়োজনে। যখন আয়তক্ষেত্রের বাক্সগুলি এবং বৃত্তটি ছেদ করে না।

এবং এটি ইউক্লিডিয়ানহীনদের জন্যও কাজ করবে:

class Circle {
 // create the bounding box of the circle only once
 BBox bbox;

 public boolean intersect(BBox b) {
    // test top intersect
    if (lat > b.maxLat) {
        if (lon < b.minLon)
            return normDist(b.maxLat, b.minLon) <= normedDist;
        if (lon > b.maxLon)
            return normDist(b.maxLat, b.maxLon) <= normedDist;
        return b.maxLat - bbox.minLat > 0;
    }

    // test bottom intersect
    if (lat < b.minLat) {
        if (lon < b.minLon)
            return normDist(b.minLat, b.minLon) <= normedDist;
        if (lon > b.maxLon)
            return normDist(b.minLat, b.maxLon) <= normedDist;
        return bbox.maxLat - b.minLat > 0;
    }

    // test middle intersect
    if (lon < b.minLon)
        return bbox.maxLon - b.minLon > 0;
    if (lon > b.maxLon)
        return b.maxLon - bbox.minLon > 0;
    return true;
  }
}
  • মিনিট ল্যাট, ম্যাক্সল্যাট মিনি, ম্যাক্সওয়াই এবং মিনলনের জন্য একই, ম্যাক্সলনের সাথে প্রতিস্থাপন করা যেতে পারে: এটি মিনিট, ম্যাক্সএক্সের সাথে প্রতিস্থাপন করুন
  • normDist ist মাত্র কিছুটা দ্রুত পদ্ধতি তখন সম্পূর্ণ দূরত্বের গণনা। ইউক্লিডিয় স্থান স্কয়ার রুট ছাড়া যেমন (অথবা haversine জন্য অন্যান্য উপাদান অনেক ছাড়াই): dLat=(lat-circleY); dLon=(lon-circleX); normed=dLat*dLat+dLon*dLon। অবশ্যই আপনি যদি সেই আদর্শ তালিকা ব্যবহার করেন তবে আপনাকে normedDist = dist*dist;বৃত্তের জন্য একটি তৈরি করতে হবে

আমার গ্রাফহপার প্রকল্পের পুরো বিবিক্স এবং সার্কেল কোডটি দেখুন ।


1

আকৃতি নিয়ে কাজের জন্য আমি ক্লাস তৈরি করেছি আশা করি আপনি উপভোগ করবেন

public class Geomethry {
  public static boolean intersectionCircleAndRectangle(int circleX, int circleY, int circleR, int rectangleX, int rectangleY, int rectangleWidth, int rectangleHeight){
    boolean result = false;

    float rectHalfWidth = rectangleWidth/2.0f;
    float rectHalfHeight = rectangleHeight/2.0f;

    float rectCenterX = rectangleX + rectHalfWidth;
    float rectCenterY = rectangleY + rectHalfHeight;

    float deltax = Math.abs(rectCenterX - circleX);
    float deltay = Math.abs(rectCenterY - circleY);

    float lengthHypotenuseSqure = deltax*deltax + deltay*deltay;

    do{
        // check that distance between the centerse is more than the distance between the circumcircle of rectangle and circle
        if(lengthHypotenuseSqure > ((rectHalfWidth+circleR)*(rectHalfWidth+circleR) + (rectHalfHeight+circleR)*(rectHalfHeight+circleR))){
            //System.out.println("distance between the centerse is more than the distance between the circumcircle of rectangle and circle");
            break;
        }

        // check that distance between the centerse is less than the distance between the inscribed circle
        float rectMinHalfSide = Math.min(rectHalfWidth, rectHalfHeight);
        if(lengthHypotenuseSqure < ((rectMinHalfSide+circleR)*(rectMinHalfSide+circleR))){
            //System.out.println("distance between the centerse is less than the distance between the inscribed circle");
            result=true;
            break;
        }

        // check that the squares relate to angles
        if((deltax > (rectHalfWidth+circleR)*0.9) && (deltay > (rectHalfHeight+circleR)*0.9)){
            //System.out.println("squares relate to angles");
            result=true;
        }
    }while(false);

    return result;
}

public static boolean intersectionRectangleAndRectangle(int rectangleX, int rectangleY, int rectangleWidth, int rectangleHeight, int rectangleX2, int rectangleY2, int rectangleWidth2, int rectangleHeight2){
    boolean result = false;

    float rectHalfWidth = rectangleWidth/2.0f;
    float rectHalfHeight = rectangleHeight/2.0f;
    float rectHalfWidth2 = rectangleWidth2/2.0f;
    float rectHalfHeight2 = rectangleHeight2/2.0f;

    float deltax = Math.abs((rectangleX + rectHalfWidth) - (rectangleX2 + rectHalfWidth2));
    float deltay = Math.abs((rectangleY + rectHalfHeight) - (rectangleY2 + rectHalfHeight2));

    float lengthHypotenuseSqure = deltax*deltax + deltay*deltay;

    do{
        // check that distance between the centerse is more than the distance between the circumcircle
        if(lengthHypotenuseSqure > ((rectHalfWidth+rectHalfWidth2)*(rectHalfWidth+rectHalfWidth2) + (rectHalfHeight+rectHalfHeight2)*(rectHalfHeight+rectHalfHeight2))){
            //System.out.println("distance between the centerse is more than the distance between the circumcircle");
            break;
        }

        // check that distance between the centerse is less than the distance between the inscribed circle
        float rectMinHalfSide = Math.min(rectHalfWidth, rectHalfHeight);
        float rectMinHalfSide2 = Math.min(rectHalfWidth2, rectHalfHeight2);
        if(lengthHypotenuseSqure < ((rectMinHalfSide+rectMinHalfSide2)*(rectMinHalfSide+rectMinHalfSide2))){
            //System.out.println("distance between the centerse is less than the distance between the inscribed circle");
            result=true;
            break;
        }

        // check that the squares relate to angles
        if((deltax > (rectHalfWidth+rectHalfWidth2)*0.9) && (deltay > (rectHalfHeight+rectHalfHeight2)*0.9)){
            //System.out.println("squares relate to angles");
            result=true;
        }
    }while(false);

    return result;
  } 
}

1

এখানে 100% কাজ করা সংশোধিত কোডটি রয়েছে:

public static bool IsIntersected(PointF circle, float radius, RectangleF rectangle)
{
    var rectangleCenter = new PointF((rectangle.X +  rectangle.Width / 2),
                                     (rectangle.Y + rectangle.Height / 2));

    var w = rectangle.Width  / 2;
    var h = rectangle.Height / 2;

    var dx = Math.Abs(circle.X - rectangleCenter.X);
    var dy = Math.Abs(circle.Y - rectangleCenter.Y);

    if (dx > (radius + w) || dy > (radius + h)) return false;

    var circleDistance = new PointF
                             {
                                 X = Math.Abs(circle.X - rectangle.X - w),
                                 Y = Math.Abs(circle.Y - rectangle.Y - h)
                             };

    if (circleDistance.X <= (w))
    {
        return true;
    }

    if (circleDistance.Y <= (h))
    {
        return true;
    }

    var cornerDistanceSq = Math.Pow(circleDistance.X - w, 2) + 
                                    Math.Pow(circleDistance.Y - h, 2);

    return (cornerDistanceSq <= (Math.Pow(radius, 2)));
}

বাসম আলুগিলি


1

এটির জন্য এখানে একটি দ্রুত এক-লাইন পরীক্ষা:

if (length(max(abs(center - rect_mid) - rect_halves, 0)) <= radius ) {
  // They intersect.
}

এটি অক্ষ-সংলগ্ন কেস যেখানে rect_halvesএকটি ধনাত্মক ভেক্টরটি আয়তক্ষেত্রের মাঝামাঝি থেকে কোণে নির্দেশ করে। ভিতরে length()প্রকাশটি একটি ডেল্টা ভেক্টর থেকে centerআয়তক্ষেত্রের নিকটতম বিন্দুতে। এটি যে কোনও মাত্রায় কাজ করে।


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

এটি দক্ষ, কারণ:

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

1

আমার জন্য কাজ করেছে (কেবল তখনই কাজ যখন আয়তক্ষেত্রের কোণ 180 হয়)

function intersects(circle, rect) {
  let left = rect.x + rect.width > circle.x - circle.radius;
  let right = rect.x < circle.x + circle.radius;
  let top = rect.y < circle.y + circle.radius;
  let bottom = rect.y + rect.height > circle.y - circle.radius;
  return left && right && bottom && top;
}

হুমম ... আমি এটিকে ভোট দিয়েছি তবে সঠিকভাবে পরীক্ষা করা হয়েছে এবং আমি মনে করি এটি উদাহরণস্বরূপ কোণে কাজ করে না। এটি দুটি আয়তক্ষেত্রের জন্য কাজ করবে।
ড্যান জেন

1

ই-জেমসের উত্তরটি কিছুটা উন্নত করা:

double dx = abs(circle.x - rect.x) - rect.w / 2,
       dy = abs(circle.y - rect.y) - rect.h / 2;

if (dx > circle.r || dy > circle.r) { return false; }
if (dx <= 0 || dy <= 0) { return true; }

return (dx * dx + dy * dy <= circle.r * circle.r);

এই subtracts rect.w / 2এবং rect.h / 2একবার পরিবর্তে তিনবার পর্যন্ত।


0

সেই সার্কেল / SQL এর সঙ্গে ভৌগলিক স্থানাঙ্ক আয়তক্ষেত্র সংঘর্ষের নিরূপণ করা আছে,
এই 11 Oracle এ আমার বাস্তবায়ন প্রস্তাব অ্যালগরিদম e.James

ইনপুটতে এর জন্য বৃত্তের স্থানাঙ্ক, কিলোমিটারের বৃত্ত ব্যাসার্ধ এবং আয়তক্ষেত্রের দুটি সূক্ষ্ম স্থানাঙ্কের প্রয়োজন:

CREATE OR REPLACE FUNCTION "DETECT_CIRC_RECT_COLLISION"
(
    circleCenterLat     IN NUMBER,      -- circle Center Latitude
    circleCenterLon     IN NUMBER,      -- circle Center Longitude
    circleRadius        IN NUMBER,      -- circle Radius in KM
    rectSWLat           IN NUMBER,      -- rectangle South West Latitude
    rectSWLon           IN NUMBER,      -- rectangle South West Longitude
    rectNELat           IN NUMBER,      -- rectangle North Est Latitude
    rectNELon           IN NUMBER       -- rectangle North Est Longitude
)
RETURN NUMBER
AS
    -- converts km to degrees (use 69 if miles)
    kmToDegreeConst     NUMBER := 111.045;

    -- Remaining rectangle vertices 
    rectNWLat   NUMBER;
    rectNWLon   NUMBER;
    rectSELat   NUMBER;
    rectSELon   NUMBER;

    rectHeight  NUMBER;
    rectWIdth   NUMBER;

    circleDistanceLat   NUMBER;
    circleDistanceLon   NUMBER;
    cornerDistanceSQ    NUMBER;

BEGIN
    -- Initialization of remaining rectangle vertices  
    rectNWLat := rectNELat;
    rectNWLon := rectSWLon;
    rectSELat := rectSWLat;
    rectSELon := rectNELon;

    -- Rectangle sides length calculation
    rectHeight := calc_distance(rectSWLat, rectSWLon, rectNWLat, rectNWLon);
    rectWidth := calc_distance(rectSWLat, rectSWLon, rectSELat, rectSELon);

    circleDistanceLat := abs( (circleCenterLat * kmToDegreeConst) - ((rectSWLat * kmToDegreeConst) + (rectHeight/2)) );
    circleDistanceLon := abs( (circleCenterLon * kmToDegreeConst) - ((rectSWLon * kmToDegreeConst) + (rectWidth/2)) );

    IF circleDistanceLon > ((rectWidth/2) + circleRadius) THEN
        RETURN -1;   --  -1 => NO Collision ; 0 => Collision Detected
    END IF;

    IF circleDistanceLat > ((rectHeight/2) + circleRadius) THEN
        RETURN -1;   --  -1 => NO Collision ; 0 => Collision Detected
    END IF;

    IF circleDistanceLon <= (rectWidth/2) THEN
        RETURN 0;   --  -1 => NO Collision ; 0 => Collision Detected
    END IF;

    IF circleDistanceLat <= (rectHeight/2) THEN
        RETURN 0;   --  -1 => NO Collision ; 0 => Collision Detected
    END IF;


    cornerDistanceSQ := POWER(circleDistanceLon - (rectWidth/2), 2) + POWER(circleDistanceLat - (rectHeight/2), 2);

    IF cornerDistanceSQ <=  POWER(circleRadius, 2) THEN
        RETURN 0;  --  -1 => NO Collision ; 0 => Collision Detected
    ELSE
        RETURN -1;  --  -1 => NO Collision ; 0 => Collision Detected
    END IF;

    RETURN -1;  --  -1 => NO Collision ; 0 => Collision Detected
END;    

0

কাজ করে, এক সপ্তাহ আগে এটি বের করা হয়েছিল এবং এখনই এটি পরীক্ষা করে দেখা হয়েছে।

double theta = Math.atan2(cir.getX()-sqr.getX()*1.0,
                          cir.getY()-sqr.getY()*1.0); //radians of the angle
double dBox; //distance from box to edge of box in direction of the circle

if((theta >  Math.PI/4 && theta <  3*Math.PI / 4) ||
   (theta < -Math.PI/4 && theta > -3*Math.PI / 4)) {
    dBox = sqr.getS() / (2*Math.sin(theta));
} else {
    dBox = sqr.getS() / (2*Math.cos(theta));
}
boolean touching = (Math.abs(dBox) >=
                    Math.sqrt(Math.pow(sqr.getX()-cir.getX(), 2) +
                              Math.pow(sqr.getY()-cir.getY(), 2)));

চেনাশোনা-স্কোয়ারের জন্য কাজ করতে পারে তবে প্রশ্নটি বৃত্ত-আয়তক্ষেত্র সম্পর্কে।
মার্টিনো

0
def colision(rect, circle):
dx = rect.x - circle.x
dy = rect.y - circle.y
distance = (dy**2 + dx**2)**0.5
angle_to = (rect.angle + math.atan2(dx, dy)/3.1415*180.0) % 360
if((angle_to>135 and angle_to<225) or (angle_to>0 and angle_to<45) or (angle_to>315 and angle_to<360)):
    if distance <= circle.rad/2.+((rect.height/2.0)*(1.+0.5*abs(math.sin(angle_to*math.pi/180.)))):
        return True
else:
    if distance <= circle.rad/2.+((rect.width/2.0)*(1.+0.5*abs(math.cos(angle_to*math.pi/180.)))):
        return True
return False

-2

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

if sqrt((rectangleRight.x - circleCenter.x)^2 +
        (rectangleBottom.y - circleCenter.y)^2) < radius
// then they intersect

if sqrt((rectangleRight.x - circleCenter.x)^2 +
        (rectangleTop.y - circleCenter.y)^2) < radius
// then they intersect

if sqrt((rectangleLeft.x - circleCenter.x)^2 +
        (rectangleTop.y - circleCenter.y)^2) < radius
// then they intersect

if sqrt((rectangleLeft.x - circleCenter.x)^2 +
        (rectangleBottom.y - circleCenter.y)^2) < radius
// then they intersect

একটি ছোট বৃত্ত একটি বৃহত আয়তক্ষেত্র দ্বারা সম্পূর্ণভাবে আবদ্ধ আছে এমন ক্ষেত্রে কী হবে? অবশ্যই এটি একটি ছেদ, এবং এই উত্তরে পরীক্ষা ব্যর্থ হবে।
কেন পল

হ্যাঁ হ্যাঁ, আমি এটি ভাবিনি। আপনি যদি আরও চেক যুক্ত করতে পারেন যেমন sqrt ((আয়তক্ষেত্রলাইট.এক্স / 2 - वृत्तকেন্দ্র.এক্স) ^ 2 + (আয়তক্ষেত্র নীচে। তবে আমার মাথার উপরের দিক থেকে আমি সবচেয়ে ভাল আসতে পারি।
ওউনগুডের জন্য

তারা যে কোনও প্রান্তে যে কোনও [একক এক] পয়েন্টকে ছেদ করতে পারে। আপনার পাশাপাশি প্রান্ত-কেন্দ্রের দূরত্বগুলিও খুঁজে পাওয়া উচিত। (ওহ, এবং আপনার কোণগুলিকে "কোণ" বলুন :)
আইব

এটি কেবল কোণে যখন বৃত্তের ভিতরে থাকে তা সনাক্ত করতে দেখা যায়।
সম্পূর্ণ

-2

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

H^2 = A^2 + B^2

এই কৌশলটির কিছু সীমা রয়েছে। তবে এটি গেম ডেভেলপারদের পক্ষে আরও ভাল কাজ করবে। বিশেষত সংঘর্ষ সনাক্তকরণ

এটি আরভোর অ্যালগোরিদমের একটি ভাল আপডেট


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