Equação para testar se um ponto está dentro de um círculo

Se você tem um círculo com centro (center_x, center_y) e radius radius , como você testa se um determinado ponto com coordenadas (x, y) está dentro do círculo?

Em geral, x e y devem satisfazer (x - center_x)^2 + (y - center_y)^2 < radius^2 .

Observe que os pontos que satisfazem a equação acima com < substituído por == são considerados os pontos no círculo, e os pontos que satisfazem a equação acima com < substituído por > são considerados fora do círculo.

Matematicamente, Pitágoras é provavelmente um método simples, como muitos já mencionaram.

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

Computacionalmente, existem maneiras mais rápidas. Definir:

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

Se é mais provável que um ponto esteja fora deste círculo, então imagine um quadrado desenhado em torno dele de tal forma que os lados são tangentes a este círculo:

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

Agora imagine um diamante quadrado desenhado dentro desse círculo de tal forma que os vértices tocam este círculo:

 if dx + dy < = R then return true. 

Agora cobrimos a maior parte do nosso espaço e apenas uma pequena área deste círculo permanece entre o nosso quadrado e o diamante a ser testado. Aqui voltamos a Pitágoras como acima.

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

Se é mais provável que um ponto esteja dentro deste círculo, então inverta a ordem dos 3 primeiros passos:

 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. 

Métodos alternativos imaginam um quadrado dentro desse círculo em vez de um diamante, mas isso requer um pouco mais de testes e cálculos sem vantagem computacional (o quadrado interno e os diamantes têm áreas idênticas):

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

Atualizar:

Para aqueles interessados ​​em performance, eu implementei este método em c, e compilado com -O3.

Obtive tempos de execução por time ./a.out

Eu implementei este método, um método normal e um método fictício para determinar a sobrecarga de tempo.

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

Então, parece que esse método é mais eficiente nessa implementação.

 // compile gcc -O3 .c // run: time ./a.out #include  #include  #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 

Você pode usar Pitágoras para medir a distância entre o seu ponto e o centro e ver se ele é menor que o raio:

 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 (gorjeta de chapéu para Paul)

Na prática, a quadratura é frequentemente muito mais barata do que obter a raiz quadrada e, como estamos interessados ​​apenas em uma ordenação, podemos, é claro, renunciar à raiz quadrada:

 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 

Além disso, Jason observou que < = deve ser substituído por < e, dependendo do uso, isso pode realmente fazer sentido mesmo que eu acredite que não é verdade no sentido matemático estrito . Eu estou corrigido.

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

Isso é mais eficiente e legível. Evita a dispendiosa operação de raiz quadrada. Também adicionei uma verificação para determinar se o ponto está dentro do retângulo delimitador do círculo.

A verificação do retângulo é desnecessária, exceto com muitos pontos ou muitos círculos. Se a maioria dos pontos estiver dentro de círculos, a verificação do retângulo irá realmente tornar as coisas mais lentas!

Como sempre, não deixe de considerar seu caso de uso.

Calcular a distância

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

isso é em C # ... converter para uso em python ...

Você deve verificar se a distância do centro do círculo até o ponto é menor que o raio, ou seja,

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

Como dito acima – use a distância euclidiana.

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

Essa é a mesma solução mencionada por Jason Punyon , mas contém um exemplo de pseudocódigo e mais alguns detalhes. Eu vi a sua resposta depois de escrever isso, mas não queria remover a minha.

Acho que a maneira mais fácil de entender é calcular primeiro a distância entre o centro do círculo e o ponto. Eu usaria essa fórmula:

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

Então, simplesmente compare o resultado dessa fórmula, a distância ( d ), com o radius . Se a distância ( d ) for menor ou igual ao raio ( r ), o ponto estará dentro do círculo (na borda do círculo, se d e r forem iguais).

Aqui está um exemplo de pseudocódigo que pode ser facilmente convertido em qualquer linguagem de programação:

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

Onde circle_x e circle_y são as coordenadas centrais do círculo, r é o raio do círculo e x e y são as coordenadas do ponto.

Encontre a distância entre o centro do círculo e os pontos dados. Se a distância entre eles é menor que o raio, então o ponto está dentro do círculo. se a distância entre eles é igual ao raio do círculo, então o ponto está na circunferência do círculo. se a distância for maior que o raio, o ponto estará fora do círculo.

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

Minha resposta em C # como uma solução completa de recortar e colar (não otimizada):

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

Uso:

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

Eu usei o código abaixo para iniciantes como eu :).

class pública incirkel {

 public static void main(String[] args) { int x; int y; int middelx; int middely; int straal; { // Adjust the coordinates of x and yx = -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"); } } } }} 

Como dito anteriormente, para mostrar se o ponto está no círculo, podemos usar o seguinte

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

Para representá-lo graficamente, podemos usar:

 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) 

Movendo-se para o mundo da 3D, se você quiser verificar se um ponto 3D está em uma unidade, você acaba fazendo algo similar. Tudo o que é necessário para trabalhar em 2D é usar operações vetoriais 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; }