Якщо у вас є коло з центром (center_x, center_y)
і радіусом radius
, як ви перевіряєте, чи є дана точка з координатами (x, y)
всередині кола?
Якщо у вас є коло з центром (center_x, center_y)
і радіусом radius
, як ви перевіряєте, чи є дана точка з координатами (x, y)
всередині кола?
Відповіді:
Загалом, 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.
Якщо більша ймовірність, що точка знаходиться всередині цього кола, то зворотний порядок перших 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);
}
inCircleN
ви використовуєте непотрібний ABS. Напевно, без різниці між АБС inCircle
і inCircleN
було б менше.
Ви можете використовувати Піфагора, щоб виміряти відстань між точкою та центром і побачити, чи нижчий він від радіуса:
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
Також Джейсон зауважив, що його <=
слід замінити <
і залежно від використання це може насправді мати сенсхоча я вважаю, що це неправда в суворому математичному сенсі. Я стою виправлений.
**
або ^
. Найшвидший спосіб зробити це, коли вам просто потрібно x ^ 2 або x ^ 3 - це зробити це «вручну» : x*x
.
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 ...
Як було сказано вище - використовуйте евклідову відстань.
from math import hypot
def in_radius(c_x, c_y, r, x, y):
return math.hypot(c_x-x, c_y-y) <= r
Знайдіть відстань між центром кола і поданими точками. Якщо відстань між ними менша за радіус, то точка знаходиться всередині кола. якщо відстань між ними дорівнює радіусу кола, то точка знаходиться на окружності кола. якщо відстань більша за радіус, то точка знаходиться поза колом.
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");
Рівняння нижче є виразом , яке перевіряє , є чи точка знаходиться в межах заданої окружності , де хРи & Урів є координатами точки, хс & вус є координатами центру кола , а R являє собою радіус цієї заданої окружності.
Якщо наведене вище вираження є істинним, то точка знаходиться в колі.
Нижче представлений зразок реалізації в 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;
}
Це те саме рішення, що згадував Джейсон Пуньйон , але воно містить приклад псевдокоду та ще деякі деталі. Я побачив його відповідь після написання цього, але не хотів знімати свою.
Я думаю, що найбільш легко зрозумілим способом є спочатку обчислити відстань між центром кола та точкою. Я б використав цю формулу:
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
- координати точки.
Моя відповідь на 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)) { }
Як було сказано раніше, щоб показати, чи точка знаходиться в колі, ми можемо використовувати наступне
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)
Я використовував код нижче для початківців, як я :).
публічний клас 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");
}
}
}
}}
Перемістившись у світ 3D, якщо ви хочете перевірити, чи є 3D-точка в одиничній сфері, ви зробите щось подібне. Все, що потрібно для роботи в 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;
}
Я знаю, що минуло кілька років від найкращої проголосованої відповіді, але мені вдалося скоротити час обчислення на 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));
}
Ось простий код Java для вирішення цієї проблеми:
і математика за ним: /math/198764/how-to-know-if-a-point-is-inside-a-circle
boolean insideCircle(int[] point, int[] center, int radius) {
return (float)Math.sqrt((int)Math.pow(point[0]-center[0],2)+(int)Math.pow(point[1]-center[1],2)) <= radius;
}