Уравнение для тестирования, если точка находится внутри круга

Если у вас есть круг с центром (center_x, center_y) и радиусом radius, как вы можете проверить, находится ли данная точка с координатами (x, y) внутри круга?

Ответ 1

В общем случае x и y должны удовлетворять (x - center_x)^2 + (y - center_y)^2 < radius^2.

Обратите внимание, что точки, которые удовлетворяют приведенному выше уравнению с заменой < на ==, считаются точками на окружности, а точки, которые удовлетворяют уравнению с заменой < на >, считаются внешними круг.

Ответ 2

Математически, Pythagoras, вероятно, простой метод, о котором многие уже упоминали.

(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.

Если точка с большей вероятностью находится внутри этого круга, то обратный порядок первых трех шагов:

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.

Update:

Для тех, кто заинтересован в производительности, я реализовал этот метод в 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);
}

Ответ 3

Вы можете использовать Pythagoras для измерения расстояния между вашей точкой и центром и посмотреть, меньше ли это радиуса:

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

Кроме того, Джейсон отметил, что <= следует заменить на <, и в зависимости от использования это может иметь смысл , хотя я считаю, что это не верно в строгом математическом смысле. Я исправляюсь.

Ответ 4

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;
}

Это более эффективный и читаемый. Это позволяет избежать дорогостоящей работы с квадратным корнем. Я также добавил проверку, чтобы определить, находится ли точка в пределах ограничивающего прямоугольника круга.

Проверка прямоугольника не нужна, за исключением множества точек или многих кругов. Если большинство точек находятся внутри кругов, проверка ограничивающего прямоугольника будет делать вещи медленнее!

Как всегда, обязательно рассмотрите свой вариант использования.

Ответ 5

Рассчитать расстояние

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

что в С#... конвертировать для использования в python...

Ответ 6

Вы должны проверить, меньше ли расстояние от центра круга до точки, чем радиус, т.е.

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

Ответ 7

Как сказано выше - используйте евклидову дистанцию.

from math import hypot

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

Ответ 8

Найдите расстояние между центром круга и указанными точками. Если расстояние между ними меньше радиуса, то точка находится внутри круга. если расстояние между ними равно радиусу круга, то точка находится на окружности круга. если расстояние больше радиуса, то точка находится вне круга.

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");

Ответ 9

Это то же самое решение, что и упомянутое Джейсоном Пеньоном, но оно содержит пример псевдокода и некоторые подробности. Я видел его ответ, написав это, но я не хотел удалять мои.

Я думаю, что наиболее понятным способом является сначала рассчитать расстояние между центром окружности и точкой. Я бы использовал эту формулу:

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 - координаты точки.

Ответ 10

Мой ответ на С# как полное решение для вырезания и вставки (не оптимизированное):

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)) { }

Ответ 11

Как указывалось ранее, чтобы показать, находится ли точка в круге, мы можем использовать следующие

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)

Ответ 12

Уравнение ниже представляет собой выражение, которое проверяет, находится ли точка в данном круге, где xP & yP - координаты точки, xC & yC - координаты центра круга, а R - радиус этого заданного круга.

enter image description here

Если приведенное выше выражение истинно, то точка находится внутри круга.

Ниже приведен пример реализации в С#:

    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;
    }

Ответ 13

Я использовал код ниже для новичков вроде меня:).

public class 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");
    } 
}



    }
}}

Ответ 14

Перейдя в мир 3D, если вы хотите проверить, находится ли 3D-точка в единице измерения, вы делаете что-то подобное. Все, что необходимо для работы в 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;
    }

Ответ 15

Я знаю, что через несколько лет я получил ответ, получивший наибольшее количество голосов, но мне удалось сократить время расчета на 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));
}