বিন্দুটি একটি বৃত্তের মধ্যে থাকলে পরীক্ষার জন্য সমীকরণ


309

আপনার যদি কেন্দ্র (center_x, center_y)এবং ব্যাসার্ধ সহ একটি বৃত্ত radiusথাকে তবে স্থানাঙ্কের সাথে প্রদত্ত বিন্দুটি (x, y)বৃত্তের ভিতরে থাকলে আপনি কীভাবে পরীক্ষা করবেন ?


20
এই প্রশ্নটি সত্যই ভাষা অজ্ঞানী, আমি জাভাতে একই সূত্রটি ব্যবহার করছি, সুতরাং পুনরায় ট্যাগিং করুন।
গৌতম

দেখে মনে হচ্ছে আপনার ধনাত্মক সমন্বয় কেবলমাত্র। নীচের সমাধানগুলি স্বাক্ষরিত স্থানাঙ্কগুলির সাথে কাজ করে না।
সিজবার্থ

সর্বাধিক সমাধান নিচে কি ইতিবাচক ও নেতিবাচক স্থানাঙ্ক সঙ্গে কাজ করে। এই প্রশ্নের ভবিষ্যতের দর্শকদের জন্য কেবল সেই উত্তম সংশোধন করা।
উইলিয়াম মরিসন

আমি এই প্রশ্নটিকে অফ-টপিক হিসাবে বন্ধ করতে ভোট দিচ্ছি কারণ এটি প্রোগ্রামিংয়ের পরিবর্তে মধ্য বিদ্যালয়ের গণিত সম্পর্কে।
এন। 'সর্বনাম' মি।

উত্তর:


481

সাধারণভাবে, xএবং yসন্তুষ্ট করা আবশ্যক (x - center_x)^2 + (y - center_y)^2 < radius^2

দয়া করে মনে রাখবেন পয়েন্ট যে উপরোক্ত সমীকরণ সন্তুষ্ট সঙ্গে <দ্বারা প্রতিস্থাপিত ==পয়েন্ট বলে মনে করা হয় উপর বৃত্ত, এবং পয়েন্ট যে উপরোক্ত সমীকরণ সন্তুষ্ট সঙ্গে <দ্বারা প্রতিস্থাপিত >বলে মনে করা হয় বাহিরে বৃত্ত।


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

30
এটি সর্বাধিক বোধগম্য ব্যাখ্যা যা কেবলমাত্র একটি সাধারণ বাক্যে এবং অবিলম্বে ব্যবহারযোগ্য সমীকরণে সরবরাহ করা হয়। সাবাশ.
thgc

এটি দুর্দান্ত ইচ্ছা আমি এই উত্সটি আরও দ্রুত খুঁজে পেতে চাই। মানটি কোথা থেকে আসে?
ডেভিন ট্রিপ

2
@ ডেভিনিট্রিপ 'এক্স' হ'ল বিন্দুটি পরীক্ষা করা হচ্ছে এর এক্স স্থানাঙ্ক।
ক্রিস

5
এটি সুস্পষ্ট হতে পারে তবে এটি বর্ণিত হওয়া উচিত <=যা বৃত্তের ভিতরে বা এর প্রান্তে পয়েন্টগুলি খুঁজে পাবে।
টাইলার

131

গাণিতিকভাবে, পাইথাগোরাস সম্ভবত একটি সহজ পদ্ধতি যা ইতিমধ্যে অনেকে উল্লেখ করেছেন।

(x-center_x)^2 + (y - center_y)^2 < radius^2

গণনামূলকভাবে, আরও দ্রুত উপায় আছে। নির্ধারণ:

dx = abs(x-center_x)
dy = abs(y-center_y)
R = radius

যদি কোনও বিন্দু এই বৃত্তের বাইরে হওয়ার সম্ভাবনা বেশি থাকে তবে তার চারপাশে আঁকানো বর্গক্ষেত্রটি কল্পনা করুন যে এটির পাশগুলি এই বৃত্তের স্পর্শকাতর:

if dx>R then 
    return false.
if dy>R then 
    return false.

এখন এই বৃত্তের ভিতরে টানা একটি বর্গাকার হীরাটি কল্পনা করুন যে এটির কোণটি এই বৃত্তটিকে স্পর্শ করে:

if dx + dy <= R then 
    return true.

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

if dx^2 + dy^2 <= R^2 then 
    return true
else 
    return false.

যদি কোনও বিন্দু এই বৃত্তের ভিতরে থাকার সম্ভাবনা বেশি থাকে তবে প্রথম 3 টি ধাপের বিপরীত ক্রম:

if dx + dy <= R then 
    return true.
if dx > R then 
    return false.
if dy > R 
    then return false.
if dx^2 + dy^2 <= R^2 then 
    return true
else
    return false.

বিকল্প পদ্ধতিগুলি হীরার পরিবর্তে এই বৃত্তের অভ্যন্তরে একটি বর্গক্ষেত্রের কল্পনা করে তবে এর জন্য সামান্যতর আরও পরীক্ষা ও গণনার দরকার নেই কোনও গণনীয় সুবিধা (অভ্যন্তরীণ বর্গক্ষেত্র এবং হীরার অভিন্ন অঞ্চল রয়েছে):

k = R/sqrt(2)
if dx <= k and dy <= k then 
    return true.

হালনাগাদ:

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

আমি ফাঁসির সময় পেয়েছি obtained time ./a.out

টাইমিং ওভারহেড নির্ধারণের জন্য আমি এই পদ্ধতিটি, একটি সাধারণ পদ্ধতি এবং একটি ডামি পদ্ধতিটি প্রয়োগ করেছি।

Normal: 21.3s This: 19.1s Overhead: 16.5s

সুতরাং, মনে হয় এই পদ্ধতিটি এই বাস্তবায়নে আরও দক্ষ।

// compile gcc -O3 <filename>.c
// run: time ./a.out

#include <stdio.h>
#include <stdlib.h>

#define TRUE  (0==0)
#define FALSE (0==1)

#define ABS(x) (((x)<0)?(0-(x)):(x))

int xo, yo, R;

int inline inCircle( int x, int y ){  // 19.1, 19.1, 19.1
  int dx = ABS(x-xo);
  if (    dx >  R ) return FALSE;
  int dy = ABS(y-yo);
  if (    dy >  R ) return FALSE;
  if ( dx+dy <= R ) return TRUE;
  return ( dx*dx + dy*dy <= R*R );
}

int inline inCircleN( int x, int y ){  // 21.3, 21.1, 21.5
  int dx = ABS(x-xo);
  int dy = ABS(y-yo);
  return ( dx*dx + dy*dy <= R*R );
}

int inline dummy( int x, int y ){  // 16.6, 16.5, 16.4
  int dx = ABS(x-xo);
  int dy = ABS(y-yo);
  return FALSE;
}

#define N 1000000000

int main(){
  int x, y;
  xo = rand()%1000; yo = rand()%1000; R = 1;
  int n = 0;
  int c;
  for (c=0; c<N; c++){
    x = rand()%1000; y = rand()%1000;
//    if ( inCircle(x,y)  ){
    if ( inCircleN(x,y) ){
//    if ( dummy(x,y) ){
      n++;
    }
  }
  printf( "%d of %d inside circle\n", n, N);
}

5
এই উত্তরটি দুর্দান্ত। আপনার প্রস্তাবিত কয়েকটি অপ্টিমাইজেশন আমি কখনই বুঝতে পারি নি। সাবাশ.
উইলিয়াম মরিসন

2
আমি জানতে আগ্রহী যে আপনি এই অপটিমাইজেশন প্রোফাইল করেছেন কিনা? আমার অন্ত্র অনুভূতি হ'ল একাধিক শর্তসাপেক্ষ কিছু গণিত এবং একটি শর্তসাপেক্ষের চেয়ে ধীর হবে তবে আমি ভুল হতে পারি।
yoyo

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

2
ফাংশনে inCircleNআপনি অপ্রয়োজনীয় এবিএস ব্যবহার করছেন। সম্ভবত ABS পার্থক্য ছাড়াই inCircleএবং inCircleNআরও ছোট হবে।
tzologa

1
এবিএস অপসারণ কর্কেলএন কর্মক্ষমতা উন্নত করে তবে পর্যাপ্ত নয়। তবে, আমার পদ্ধতিটি আর = 1 থেকে চেনাশোনার বাইরে পয়েন্টগুলির পক্ষে আরও বেশি পক্ষপাতদুষ্ট ছিল। এলোমেলো ব্যাসার্ধের সাথে [0..499], প্রায় 25% পয়েন্টগুলি বৃত্তের অভ্যন্তরে ছিল এবং ইনসিভারলন দ্রুততর।
ফিলাকলবর্ন

74

আপনি আপনার পয়েন্ট এবং কেন্দ্রের মধ্যকার দূরত্ব পরিমাপ করতে পাইথাগোরাস ব্যবহার করতে পারেন এবং এটি ব্যাসার্ধের চেয়ে কম কিনা তা দেখতে পারেন:

def in_circle(center_x, center_y, radius, x, y):
    dist = math.sqrt((center_x - x) ** 2 + (center_y - y) ** 2)
    return dist <= radius

সম্পাদনা করুন (পলকে টুপি টিপুন )

অনুশীলনে স্কোয়ারিং প্রায়শই বর্গক্ষেত্রের মূল গ্রহণের তুলনায় অনেক কম সস্তা এবং যেহেতু আমরা কেবল একটি অর্ডারে আগ্রহী তাই আমরা অবশ্যই বর্গাকার মূল গ্রহণের আগেই করতে পারি:

def in_circle(center_x, center_y, radius, x, y):
    square_dist = (center_x - x) ** 2 + (center_y - y) ** 2
    return square_dist <= radius ** 2

এছাড়াও, জেসন উল্লেখ করেছেন যে <=প্রতিস্থাপন করা উচিত <এবং ব্যবহারের উপর নির্ভর করে এটি প্রকৃত অর্থে বোধগম্য হতে পারেযদিও আমি বিশ্বাস করি এটি কঠোর গাণিতিক অর্থে সত্য নয়আমি সংশোধন করেছি.


1
বৃত্তের ভিতরে থাকা বিন্দুর জন্য পরীক্ষার জন্য ডি <ব্যাসার্ধের সাথে << ব্যাসার্ধ দ্বারা প্রতিস্থাপন করুন।
জেসন

16
স্কয়ার্ট ব্যয়বহুল। যদি সম্ভব হয় তবে এড়িয়ে চলুন - x ^ 2 + y ^ y এর সাথে r ^ 2 এর সাথে তুলনা করুন।
পল টমলিন

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

3
একটি বৃত্তের অভ্যন্তরের আনুষ্ঠানিক গাণিতিক সংজ্ঞাটি আমি আমার পোস্টে দিয়েছিলাম। উইকিপিডিয়া থেকে: সাধারণভাবে, কোনও কিছুর অভ্যন্তরটি এর বাইরের চারপাশে যে কোনও ধরণের প্রাচীর বা সীমানা বাদ দিয়ে তার ভিতরে থাকা স্থান বা অংশকে বোঝায়। en.wikedia.org/wiki/ অভ্যন্তরীণ_( টোটোলজি)
জেসন

1
প্যাস্কল, ডেলফি এবং এফপিসিতে উভয় শক্তি এবং স্কয়ার্ট ব্যয়বহুল , এবং কোনও পাওয়ার-অপারেটর ইজি নেই: **বা ^। দ্রুততম উপায় এটা করতে যখন আপনি শুধু x ^ 2 বা এক্স ^ 3 এটি "ম্যানুয়ালি" করতে হয় প্রয়োজন: x*x
JHolta

37
boolean isInRectangle(double centerX, double centerY, double radius, 
    double x, double y)
{
        return x >= centerX - radius && x <= centerX + radius && 
            y >= centerY - radius && y <= centerY + radius;
}    

//test if coordinate (x, y) is within a radius from coordinate (center_x, center_y)
public boolean isPointInCircle(double centerX, double centerY, 
    double radius, double x, double y)
{
    if(isInRectangle(centerX, centerY, radius, x, y))
    {
        double dx = centerX - x;
        double dy = centerY - y;
        dx *= dx;
        dy *= dy;
        double distanceSquared = dx + dy;
        double radiusSquared = radius * radius;
        return distanceSquared <= radiusSquared;
    }
    return false;
}

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

বহু পয়েন্ট বা বহু চেনাশোনা ছাড়া আয়তক্ষেত্র চেক অপ্রয়োজনীয়। বেশিরভাগ পয়েন্টগুলি যদি চেনাশোনাগুলির মধ্যে থাকে তবে সীমাবদ্ধ আয়তক্ষেত্রের চেকটি আসলে জিনিসগুলিকে ধীর করে দেবে!

সর্বদা হিসাবে, আপনার ব্যবহারের ক্ষেত্রে বিবেচনা করতে ভুলবেন না।


12

দূরত্ব গণনা করুন

D = Math.Sqrt(Math.Pow(center_x - x, 2) + Math.Pow(center_y - y, 2))
return D <= radius

এটি সি # তে রয়েছে ... পাইথনে ব্যবহারের জন্য রূপান্তর করুন ...


11
আপনি ডি-স্কোয়ার্ড ব্যাসার্ধ-স্কোয়ারের সাথে তুলনা করে দুটি ব্যয়বহুল স্কয়ার্ট কল এড়াতে পারবেন।
পল টমলিন

10

বৃত্তের কেন্দ্র থেকে পয়েন্টের দূরত্বটি ব্যাসার্ধের চেয়ে কম কিনা তা আপনার পরীক্ষা করা উচিত

if (x-center_x)**2 + (y-center_y)**2 <= radius**2:
    # inside circle

5

উপরে যেমন বলা হয়েছে - ইউক্লিডিয়ান দূরত্ব ব্যবহার করুন।

from math import hypot

def in_radius(c_x, c_y, r, x, y):
    return math.hypot(c_x-x, c_y-y) <= r

4

বৃত্তের কেন্দ্র এবং প্রদত্ত পয়েন্টগুলির মধ্যে দূরত্ব সন্ধান করুন। যদি তাদের মধ্যে দূরত্ব ব্যাসার্ধের চেয়ে কম হয় তবে বিন্দুটি বৃত্তের অভ্যন্তরে। যদি তাদের মধ্যে দূরত্বটি বৃত্তের ব্যাসার্ধের সমান হয় তবে বিন্দুটি বৃত্তের পরিধির উপর। যদি দূরত্ব ব্যাসার্ধের চেয়ে বেশি হয় তবে বিন্দুটি বৃত্তের বাইরে।

int d = r^2 - (center_x-x)^2 + (center_y-y)^2;

if(d>0)
  print("inside");
else if(d==0)
  print("on the circumference");
else
  print("outside");

4

নিচে সমীকরণ একটি অভিব্যক্তি যে পরীক্ষার একটি বিন্দু প্রদত্ত বৃত্ত যেখানে মধ্যে এক্সপি & YP বিন্দুর স্থানাঙ্ক হয়, XC & YC বৃত্তের কেন্দ্র স্থানাঙ্ক এবং আর প্রদত্ত বৃত্তের ব্যাসার্ধ হয়।

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

উপরের ভাবটি যদি সত্য হয় তবে বিন্দুটি বৃত্তের মধ্যে।

নীচে সি # তে একটি নমুনা বাস্তবায়ন রয়েছে:

    public static bool IsWithinCircle(PointF pC, Point pP, Single fRadius){
        return Distance(pC, pP) <= fRadius;
    }

    public static Single Distance(PointF p1, PointF p2){
        Single dX = p1.X - p2.X;
        Single dY = p1.Y - p2.Y;
        Single multi = dX * dX + dY * dY;
        Single dist = (Single)Math.Round((Single)Math.Sqrt(multi), 3);

        return (Single)dist;
    }

অনেক অনেক ধন্যবাদ: ডি
গ্রেস নিকোল

2

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

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

d = sqrt((circle_x - x)^2 + (circle_y - y)^2)

তারপরে, কেবলমাত্র সেই সূত্রের ফলাফলের সাথে, দূরত্ব ( d) এর সাথে তুলনা করুন radius। যদি দূরত্ব ( d) ব্যাসার্ধের ( r) এর চেয়ে কম বা সমান হয় তবে বিন্দুটি বৃত্তের ভিতরে (বৃত্তের প্রান্তে যদি থাকে dএবং rসমান হয়)।

এখানে একটি সিডো-কোড উদাহরণ যা সহজেই যে কোনও প্রোগ্রামিং ভাষায় রূপান্তর করা যায়:

function is_in_circle(circle_x, circle_y, r, x, y)
{
    d = sqrt((circle_x - x)^2 + (circle_y - y)^2);
    return d <= r;
}

বৃত্তের কেন্দ্র স্থানাঙ্ক কোথায় circle_xএবং কোথায় circle_yএটি বৃত্তের rব্যাসার্ধ xএবং yএটি বিন্দুর স্থানাঙ্ক।


2

সম্পূর্ণ উত্তর কাটা এবং পেস্ট (অনুকূলিত নয়) সমাধান হিসাবে সি # তে আমার উত্তর:

public static bool PointIsWithinCircle(double circleRadius, double circleCenterPointX, double circleCenterPointY, double pointToCheckX, double pointToCheckY)
{
    return (Math.Pow(pointToCheckX - circleCenterPointX, 2) + Math.Pow(pointToCheckY - circleCenterPointY, 2)) < (Math.Pow(circleRadius, 2));
}

ব্যবহার:

if (!PointIsWithinCircle(3, 3, 3, .5, .5)) { }

1

পূর্বে যেমন বলা হয়েছে, পয়েন্টটি বৃত্তে রয়েছে কিনা তা দেখানোর জন্য আমরা নিম্নলিখিতটি ব্যবহার করতে পারি

if ((x-center_x)^2 + (y - center_y)^2 < radius^2) {
    in.circle <- "True"
} else {
    in.circle <- "False"
}

গ্রাফিকালি এটি উপস্থাপন করতে আমরা ব্যবহার করতে পারি:

plot(x, y, asp = 1, xlim = c(-1, 1), ylim = c(-1, 1), col = ifelse((x-center_x)^2 + (y - center_y)^2 < radius^2,'green','red'))
draw.circle(0, 0, 1, nv = 1000, border = NULL, col = NA, lty = 1, lwd = 1)

0

আমি আমার মতো নতুনদের জন্য নীচের কোডটি ব্যবহার করেছি :)।

পাবলিক বর্গ incirkel {

public static void main(String[] args) {
    int x; 
    int y; 
    int middelx; 
    int middely; 
    int straal; {

// Adjust the coordinates of x and y 
x = -1;
y = -2;

// Adjust the coordinates of the circle
middelx = 9; 
middely = 9;
straal =  10;

{
    //When x,y is within the circle the message below will be printed
    if ((((middelx - x) * (middelx - x)) 
                    + ((middely - y) * (middely - y))) 
                    < (straal * straal)) {
                        System.out.println("coordinaten x,y vallen binnen cirkel");
    //When x,y is NOT within the circle the error message below will be printed
    } else {
        System.err.println("x,y coordinaten vallen helaas buiten de cirkel");
    } 
}



    }
}}

0

3 ডি জগতে স্থানান্তরিত হওয়া আপনি যদি 3D পয়েন্টটি ইউনিট গোলকের মধ্যে আছে কিনা তা পরীক্ষা করতে চান তবে আপনি অনুরূপ কিছু করে শেষ করছেন। 2 ডি তে কাজ করার জন্য যা প্রয়োজন তা হ'ল 2 ডি ভেক্টর অপারেশন ব্যবহার করা।

    public static bool Intersects(Vector3 point, Vector3 center, float radius)
    {
        Vector3 displacementToCenter = point - center;

        float radiusSqr = radius * radius;

        bool intersects = displacementToCenter.magnitude < radiusSqr;

        return intersects;
    }

0

আমি জানি যে সেরা ভোট দেওয়া উত্তর থেকে কয়েক বছর পরে, তবে আমি গণনার সময় 4 দ্বারা কাটতে পেরেছি।

আপনাকে কেবল বৃত্তের 1/4 থেকে পিক্সেল গণনা করতে হবে, তারপরে 4 দিয়ে গুণ করুন।

এটিই পৌঁছেছে সমাধান:

#include <stdio.h>
#include <stdlib.h>
#include <time.h> 

int x, y, r;
int mx, c, t;
int dx, dy;
int p;

int main() {
    for (r = 1; r < 128; r++){

        clock_t t; 
        t = clock();

        p = calculatePixels(r);

        t = clock() - t; 
        double time_taken = ((double)t)/CLOCKS_PER_SEC; // in seconds 

        printf( "%d of pixels inside circle with radius %d, took %f seconds to execute \n", p, r, time_taken);
    }
}

int calculatePixels(int r){
    mx = 2 * r;
    c = (mx+1)*(mx+1);
    t = r * r;
    int a = 0;
    for (x = 0; x < r; x++){
      for (y = 0; y < r; y++){
          dx = x-r;
          dy = y-r;
          if ((dx*dx + dy*dy) > t)
              a++;
          else 
              y = r;
      }
    }
    return (c - (a * 4));
}


0

পিএইচপি

if ((($x - $center_x) ** 2 + ($y - $center_y) ** 2) <=  $radius **2) {
    return true; // Inside
} else {
    return false; // Outside
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.