यदि एक बिंदु एक सर्कल के अंदर है, तो परीक्षण के लिए समीकरण


309

यदि आपके पास केंद्र (center_x, center_y)और त्रिज्या के साथ एक सर्कल है radius, तो आप कैसे परीक्षण करते हैं यदि निर्देश दिया गया निर्देशांक (x, y)सर्कल के अंदर है?


20
यह सवाल वास्तव में भाषा अज्ञेय है, मैं जावा में एक ही सूत्र का उपयोग कर रहा हूं, इसलिए पुनः टैगिंग।
गौतम

ऐसा लगता है कि आपकी धारणा सकारात्मक समन्वय करती है। नीचे दिए गए समाधान हस्ताक्षरित निर्देशांक के साथ काम नहीं करते हैं।
cjbarth

अधिकांश समाधान नीचे कर सकारात्मक और नकारात्मक निर्देशांक के साथ काम करते हैं। इस सवाल के भविष्य के दर्शकों के लिए बस उस tidbit को सही करना।
विलियम मॉरिसन

मैं इस प्रश्न को ऑफ-टॉपिक के रूप में बंद करने के लिए मतदान कर रहा हूं क्योंकि यह प्रोग्रामिंग के बजाय मध्य विद्यालय के गणित के बारे में है।
एन। 'सर्वनाम' मी।

जवाबों:


481

सामान्य तौर पर, xऔर yसंतुष्ट होना चाहिए (x - center_x)^2 + (y - center_y)^2 < radius^2

कृपया ध्यान दें कि उपर्युक्त समीकरण को <प्रतिस्थापित के साथ संतुष्ट करने ==वाले बिंदुओं को वृत्त पर स्थित बिंदुओं पर विचार किया जाता है , और उपरोक्त समीकरण को <प्रतिस्थापित करने वाले बिंदुओं को सर्कल >के बाहर माना जाता है ।


6
यह त्रिज्या के मुकाबले दूरी को मापने के लिए उपयोग किए जाने वाले वर्गमूल संचालन को देखने के लिए कुछ कम गणित दिमाग वाले लोगों की मदद कर सकता है। मुझे लगता है कि यह इष्टतम नहीं है, लेकिन जैसा कि आपके उत्तर में कोड की तुलना में समीकरण की तरह अधिक स्वरूपित होता है शायद यह अधिक समझ में आता है? केवल एक सलाह।
विलियम मॉरिसन

30
यह एक सरल वाक्य और तुरंत प्रयोग करने योग्य समीकरण में प्रदान की जाने वाली सबसे अधिक स्पष्ट व्याख्या है। बहुत बढ़िया।
thgc

यह बड़ी कामना है कि मुझे यह संसाधन जल्दी मिले। मान x कहाँ से आता है?
डेविन ट्रिप

2
@DevinTripp 'x' बिंदु का x समन्वय है जिसका परीक्षण किया जा रहा है।
क्रिस

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.

अब हमने अपने अधिकांश अंतरिक्ष को कवर कर लिया है और परीक्षण करने के लिए हमारे सर्कल और हीरे के बीच में इस सर्कल का केवल एक छोटा क्षेत्र बना हुआ है। यहाँ हम उपर्युक्त के रूप में पाइथागोरस की ओर लौटते हैं।

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.

अपडेट करें:

प्रदर्शन में रुचि रखने वालों के लिए मैंने इस पद्धति को c में लागू किया, और -O3 के साथ संकलित किया।

मैं द्वारा निष्पादन समय प्राप्त किया 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
मुझे यह जानने की उत्सुकता है कि क्या आपने इन अनुकूलन को प्रोफाइल किया है? मेरी आंत की भावना यह है कि कई हालत कुछ गणित और एक सशर्त से धीमी होगी, लेकिन मैं गलत हो सकता है।
योयो

3
@ योयो, मैंने कोई प्रोफाइलिंग नहीं की है - यह प्रश्न किसी भी प्रोग्रामिंग भाषा के लिए एक विधि के बारे में है। अगर किसी को लगता है कि यह उनके आवेदन में प्रदर्शन में सुधार कर सकता है, तो उन्हें सुझाव देना चाहिए, जैसा कि आप दिखाते हैं, यह सामान्य परिदृश्यों में तेज है।
दार्शनिकॉन

2
फ़ंक्शन में inCircleNआप अनावश्यक ABS का उपयोग कर रहे हैं। शायद एबीएस के बीच अंतर के बिना inCircleऔर inCircleNछोटा होगा।
tzaloga

1
ABS को हटाने से inCircleN प्रदर्शन में सुधार होता है लेकिन पर्याप्त नहीं है। हालाँकि, मेरी विधि आर = 1 के बाद से सर्कल के बाहर अधिक संभावना वाले बिंदुओं के लिए पक्षपाती थी। यादृच्छिक त्रिज्या [0..499] के साथ, लगभग 25% अंक सर्कल के अंदर थे और inCircleN तेज है।
फिल्कोब्बरन

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

EDIT (पॉल को टोपी की टिप)

व्यवहार में, वर्गमूल लेने की तुलना में स्क्वेरिंग अक्सर बहुत सस्ता होता है और चूँकि हम केवल एक ऑर्डरिंग में रुचि रखते हैं, हम निश्चित रूप से वर्गमूल लेने में अग्रसर हो सकते हैं:

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
सर्कल के अंदर होने वाले बिंदु के परीक्षण के लिए dist <= त्रिज्या को dist <त्रिज्या से बदलें।
जेसन २६'०१

16
sqrt महंगा है। यदि संभव हो तो इससे बचें - x ^ 2 + y ^ y से r ^ 2 की तुलना करें।
पॉल टॉम्बलिन

जेसन: हमारे परिभाषाओं असहमत हो सकते हैं लेकिन मेरे लिए, एक बात यह है कि पर वृत्त की परिधि भी सबसे जोरदार ढंग से है में चक्र और मैं बहुत यकीन है कि मेरा औपचारिक, गणितीय परिभाषा के साथ समझौते में है हूँ।
कोनराड रुडोल्फ

3
एक सर्कल के इंटीरियर की औपचारिक गणितीय परिभाषा वह है जो मैंने अपनी पोस्ट में दी थी। विकिपीडिया से: सामान्य तौर पर, किसी चीज का आंतरिक भाग उसके अंदर की जगह या भाग को संदर्भित करता है, इसके बाहर किसी भी तरह की दीवार या सीमा को छोड़कर। en.wikipedia.org/wiki/Interior_(topology)
jason

1
पास्कल, डेल्फी और एफपीसी में, बिजली, और sqrt दोनों महंगे हैं , और कोई पावर-ऑपरेटर ईजी: **या नहीं है ^। इसे करने का सबसे तेज़ तरीका जब आपको बस x ^ 2 या x ^ 3 की आवश्यकता है, तो इसे "मैन्युअल रूप से" करना है x*x:।
झोलता

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
आप D-squared की त्रिज्या-वर्ग की तुलना करके दो महंगी Sqrt कॉल से बच सकते हैं।
पॉल टॉम्बलिन

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

नीचे दिए गए समीकरण एक अभिव्यक्ति है कि परीक्षण करता है, तो एक बिंदु एक दिया चक्र जहां के भीतर है xP और YP बिंदु के निर्देशांक हैं, XC और वाईसी चक्र के केंद्र के निर्देशांक और आर कि दिए गए वृत्त की त्रिज्या है।

यहां छवि विवरण दर्ज करें

यदि उपरोक्त अभिव्यक्ति सत्य है तो बिंदु वृत्त के भीतर है।

नीचे C # में एक नमूना कार्यान्वयन है:

    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

C # में मेरा उत्तर पूर्ण कट और पेस्ट (अनुकूलित नहीं) समाधान के रूप में है:

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

मैंने मेरे जैसे शुरुआती लोगों के लिए नीचे दिए गए कोड का उपयोग किया :)।

पब्लिक क्लास इंक्रील {

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 डी बिंदु है अगर आप की जाँच करना चाहते हैं 3 डी की दुनिया में चल रहा है, तो आप कुछ इसी तरह कर रहे हैं। 2D में काम करने के लिए सभी को 2D वेक्टर ऑपरेशन का उपयोग करना आवश्यक है।

    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

मुझे पता है कि सबसे अच्छे वोट वाले उत्तर से कुछ साल, लेकिन I´ve गणना समय को 4 से काटने में कामयाब रहा।

आपको केवल सर्कल के 1/4 से पिक्सेल की गणना करने की आवश्यकता है, फिर 4 से गुणा करें।

यह वह समाधान है जो I ve तक पहुंचा है:

#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
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.