Уравнение для тестирования, если точка находится внутри круга
Если у вас есть круг с центром (center_x, center_y)
и радиус radius
, как вы можете проверить, находится ли заданная точка с координатами (x, y)
внутри круга?
- Что такое оптимизация хвостового звонка?
- Сгенерировать список всех возможных перестановок строки
- Как вы находите точку на заданном перпендикулярном расстоянии от линии?
- Изучение теории сбора мусора
- Что такое lambda?
- Существует ли алгоритм сортировки по целому числу O (n)?
- Вычислить наибольший прямоугольник во вращающемся прямоугольнике
- Является ли двойным действительно неподходящим для денег?
В общем случае x
и y
должны удовлетворять (x - center_x)^2 + (y - center_y)^2 < radius^2
.
Обратите внимание, что точки, которые удовлетворяют приведенному выше уравнению с заменой на ==
, считаются точками на окружности, а точки, которые удовлетворяют уравнению с заменой на >
, считаются вне круга.
Математически Пифагор, вероятно, является простым методом, о котором многие уже упоминали.
(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.
Обновить:
Для тех, кто заинтересован в производительности, я реализовал этот метод в c и скомпилировал с -O3.
Я получил время выполнения по time ./a.out
Я реализовал этот метод, обычный метод и манекен, чтобы определить временные накладные расходы.
Normal: 21.3s This: 19.1s Overhead: 16.5s
Таким образом, кажется, что этот метод более эффективен в этой реализации.
// 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
Вы можете использовать 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
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
Кроме того, Джейсон отметил, что <=
следует заменить на <
и в зависимости от использования это может иметь смысл хотя я считаю, что это неверно в строгом математическом смысле , Я стою исправлено.
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; }
Это более эффективно и удобочитаемо. Это позволяет избежать дорогостоящей работы с квадратным корнем. Я также добавил проверку, чтобы определить, находится ли точка в пределах ограничивающего прямоугольника круга.
Проверка прямоугольника не нужна, за исключением множества точек или многих кругов. Если большинство точек находится внутри кругов, проверка ограничивающего прямоугольника на самом деле замедляет работу!
Как всегда, обязательно рассмотрите свой вариант использования.
Рассчитать расстояние
D = Math.Sqrt(Math.Pow(center_x - x, 2) + Math.Pow(center_y - y, 2)) return D <= radius
это в C # ... конвертировать для использования в python ...
Вы должны проверить, меньше ли расстояние от центра круга до точки, чем радиус, т. Е.
if (x-center_x)**2 + (y-center_y)**2 <= radius**2: # inside circle
Как сказано выше, используйте евклидову дистанцию.
from math import hypot def in_radius(c_x, c_y, r, x, y): return math.hypot(c_x-x, c_y-y) <= r
Это то же самое решение, о котором упоминал Джейсон Пуньон , но он содержит пример псевдокода и некоторые подробности. Я видел его ответ, написав это, но я не хотел удалять меня.
Я думаю, что наиболее понятным способом является сначала рассчитать расстояние между центром круга и точкой. Я бы использовал эту формулу:
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
- координаты точки.
Найдите расстояние между центром круга и указанными точками. Если расстояние между ними меньше радиуса, то точка находится внутри круга. если расстояние между ними равно радиусу круга, то точка находится на окружности круга. если расстояние больше радиуса, то точка находится за пределами круга.
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");
Мой ответ на 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)) { }
Я использовал код ниже для новичков вроде меня :).
публичный class 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"); } } } }}
Как указывалось ранее, чтобы показать, находится ли точка в круге, мы можем использовать следующее
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)
Перейдя в мир 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; }