Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.04.07;
Скачать: CL | DM;

Вниз

Геометрия, блин   Найти похожие ветки 

 
Merlin ©   (2003-03-20 12:41) [0]

Нужно два алгоритма:
1. определить факт пересечения двух отрезков
2. определить факт пересечения отрезка и окружности
Отрезки заданы координатами концов (x1,y1) - (x2,y2)
Окружность задана координатами центра и радиусом: (x1,y1, radius)
Нужен оптимальный алгоритм, т.к. эти вычисления будут производиться по неск. сотен в секунду. Не надо вычислять координаты пересечения, нужен только факт пересечения: true/false

Для отрезков я сейчас делаю: вычисляю параметры прямой (Ax+By+C=0), вычисляю точку пересечения этих прямых и проверяю принадлежность этой точки обоим отрезкам. Алгоритм получается достаточно громоздкий (много вычисления), наверняка все можно упростить.


 
myor ©   (2003-03-20 12:51) [1]

> ...наверняка все можно упростить.

сам алгоритм вряд ли, а, вот, реализацию- возможно.
зы
надо покумекать.


 
Johnmen ©   (2003-03-20 12:53) [2]

1. max(x11,x21)<=min(x12,x22) and max(y11,y21)<=min(y12,y22)


 
pasha676   (2003-03-20 12:53) [3]

Чую, что по отрезкам, если нужно только тру-фалсе, можно анализировать координаты на больше меньше, как то попарно и делать вывод о пересечении. Но это чисто интуитивно.

Возможно реально что то тем же способом сделать и с кругом. Сравнивать координаты концов отрезка с радиусом и центром.


 
myor ©   (2003-03-20 12:55) [4]

а если проверить расстояние между прямыми (отрезками) в диепазане (x1..x2;y1..y2) на ноль (т. е. их пересечение)?
выгодского нужно бы полистать.


 
Думкин ©   (2003-03-20 13:05) [5]


> Merlin © (20.03.03 12:41)

Я знаю ответ. А в чем интерес?


 
Danilka ©   (2003-03-20 13:09) [6]

пересечение отрезков:

/**
* Tests if the line segment from (X1, Y1) to
* (X2, Y2) intersects the line segment from (X3, Y3)
* to (X4, Y4).
* @param X1, Y1 the coordinates of the beginning of the first
* specified line segment
* @param X2, Y2 the coordinates of the end of the first
* specified line segment
* @param X3, Y3 the coordinates of the beginning of the second
* specified line segment
* @param X4, Y4 the coordinates of the end of the second
* specified line segment
* @return true if the first specified line segment
* and the second specified line segment intersect
* each other; false otherwise.
*/
public static boolean linesIntersect(double X1, double Y1,
double X2, double Y2,
double X3, double Y3,
double X4, double Y4) {
return ((relativeCCW(X1, Y1, X2, Y2, X3, Y3) *
relativeCCW(X1, Y1, X2, Y2, X4, Y4) <= 0)
&& (relativeCCW(X3, Y3, X4, Y4, X1, Y1) *
relativeCCW(X3, Y3, X4, Y4, X2, Y2) <= 0));
}


только это не дельфи, а ява, выдрано из исходников класса: awt.geom.Line2D


 
Danilka ©   (2003-03-20 13:11) [7]

упс, вот это забыл:


public static int relativeCCW(double X1, double Y1,
double X2, double Y2,
double PX, double PY) {
X2 -= X1;
Y2 -= Y1;
PX -= X1;
PY -= Y1;
double ccw = PX * Y2 - PY * X2;
if (ccw == 0.0) {
// The point is colinear, classify based on which side of
// the segment the point falls on. We can calculate a
// relative value using the projection of PX,PY onto the
// segment - a negative value indicates the point projects
// outside of the segment in the direction of the particular
// endpoint used as the origin for the projection.
ccw = PX * X2 + PY * Y2;
if (ccw > 0.0) {
// Reverse the projection to be relative to the original X2,Y2
// X2 and Y2 are simply negated.
// PX and PY need to have (X2 - X1) or (Y2 - Y1) subtracted
// from them (based on the original values)
// Since we really want to get a positive answer when the
// point is "beyond (X2,Y2)", then we want to calculate
// the inverse anyway - thus we leave X2 & Y2 negated.
PX -= X2;
PY -= Y2;
ccw = PX * X2 + PY * Y2;
if (ccw < 0.0) {
ccw = 0.0;
}
}
}
return (ccw < 0.0) ? -1 : ((ccw > 0.0) ? 1 : 0);
}



 
Romkin ©   (2003-03-20 13:12) [8]

Насчет окружности: Довольно просто, определяешь расстояние между концами отрезка и центром окружности, далее если одно меньше, а другое больше радиуса - есть пересечение (корни извлекать не надо, можно взять квадраты расстояний и возвести в квадрат радиус - соотношение сохраняется)
Отрезки: Где-то я видел решение, то ли у Кнута, толи где-то еще...


 
Nikolay M. ©   (2003-03-20 13:14) [9]

По поводу отрезков:
1) перейти в систему координат, где один из отрезков лежит на оси ОХ, а один из его концов совпадает с началом координат
2) подсчитать уравнение прямой (y=kx+b), на которой лежит второй отрезок исходя из условия (y2-y)/(x2-x) = (y2-y1)/(x2-x1), подсчитать абсциссу точки пересечения прямой с осью ОХ (это будет -b/k). Если эта точка принадлежит первому отрезку (который лежит на ОХ), то есть пересечение.


 
alxx ©   (2003-03-20 13:14) [10]

Допустим, отрезок описывается прямоугольником,
т.е. отрезок (х1, у1)-(х2,у2) описывается прямоугольником (х1, у1)-(х2,у2).

Тогда два отрезка пересекаются, когда первый прямоугольник пересекает (верхнюю и нижнюю сторону второго) или (левую и правую второго), ну и наоборот.

Похоже так. Много условий, ноль делений и умножений.


 
Nikolay M. ©   (2003-03-20 13:16) [11]

> Romkin © (20.03.03 13:12)
Привет.
Абсолютно не обязательно :)
Оба расстояния могут быть больше, а пересечение может как быть, так и нет


 
myor ©   (2003-03-20 13:19) [12]

о, по окружности уже есть.


 
alxx ©   (2003-03-20 13:21) [13]

Похоже, я херню сказал. Надо еще учитывать из какого угла в какой отрезок идет.


 
myor ©   (2003-03-20 13:24) [14]

перпендикуляр из центра окружности на отрезок меньше радиуса (если отрезок больше диаметра).


 
Merlin ©   (2003-03-20 13:24) [15]


> Johnmen ©

поясни, не понял.


 
myor ©   (2003-03-20 13:33) [16]

по отрезкам
a(x11,y11;x12,y12), b(x21,y21;x22,y22):
пусть
x1<x2
y1<y2
тогда:
max(xi1)<=min(xi2)
and max(yi1)<=min(yi2)
т. е., координаты начал обех отрезков (по обеим осям), меньшее координат концов.


 
Romkin ©   (2003-03-20 13:34) [17]

2Nikolay M. Млин, точно, это достаточное условие... Если выполняется - пересекает.
Дополню: Не пересекает, если перпендикуляр из центра окружности к отрезку пересекает отрезок и меньше радиуса окружности... Вот это найти сложнее, но можно сделать вторым этапом


 
Romkin ©   (2003-03-20 13:38) [18]

Так.. Надо пояснить... Отрезок пересекает окружность, если
1. расстояния от концов отрезка до центра окружности одно меньше радиуса, другое больше
2. Расстояния от концов отрезка до центра больше радиуса и при этом перпендикуляр из центра окружности пересекает отрезок и его длина меньше радиуса окружности.

Вроде так...


 
pasha676   (2003-03-20 13:42) [19]

Люди!!! Просят определить оптимальный для вычисления алгоритм.
А вы "растояние между точками", "перпендикуляр из центра...", "перевод в другие координаты".
Да на построение пенпендикуляра уйдет столько же времени, как и на решение уравнений.

Про описание отрезка многоугольниками... вообще сильно.

Вот Ромкин про окружность толково предложил. Пока лучше ничего не придумал.


 
Merlin ©   (2003-03-20 13:44) [20]


> Danilka ©

Удивительно, но работает :) Хотя смысла этих формул я не понял...


 
Merlin ©   (2003-03-20 13:47) [21]


> Romkin ©
> ... и при этом перпендикуляр из центра окружности пересекает
> отрезок и его длина меньше радиуса окружности.

А разве одного этого условия недостаточно?


 
myor ©   (2003-03-20 13:48) [22]

Romkin © (20.03.03 13:38)

хочу заметить, что условие с перпендикуляром выполняется в обоих случаях (l<d, l>d). я не уверен, что заведомо известно отношение длины отрезка и диаметра окружности, поэтому, как вы предлагаете, сначала проверить расстояния от центра до концов, а потом (вторым этапом) длину перпендикуляра- это неправильно. определение длины перпендикуляра, конечно, сложнее (по-моему нужно уравнение прямой), но это достаточное условия (или я уже переработался).


 
Merlin ©   (2003-03-20 13:49) [23]

Первый пункт по пересечению отрезков снимается. Функций предложенных Danilka © достаточно.


 
pasha676   (2003-03-20 13:51) [24]

2myor
ЭЭЭЭ.... max(xi1) - это что за хрен в сутане.



 
myor ©   (2003-03-20 13:52) [25]

таки переработался. нужен отдых.
хочу домой!!!!!!


 
pasha676   (2003-03-20 13:54) [26]

По варианту Ромкина
1 - го условия не достаточно. В случае хорды или касательной.


 
MBo ©   (2003-03-20 13:55) [27]

1 отрезок x1,y2-x2,y2
2 - x1",y1"-x2",y2"
В параметрическом виде (t=0..1)

x=t*ax+bx
y=t*ay+by

bx=x1
by=y1
ax=x2-x1
ay=y2-y1

bx"=x1"
by"=y1"
ax"=x2"-x1"
ay"=y2"-y1"


точка пересечения

ax*t+bx=ax"*t"+bx"
ay*t+by=ay"*t"+by"

решив, получим

Z=(y2-y1)(x2"-x1")-(y2"-y1")(x2-x1)

если Z=0, то отрезки параллельны
иначе

t=[(y1"-y1)(x2"-x1")-(x1"-x1)(y2"-y1")]/z

t"=[(y1"-y1)(x2-x1)-(x1"-x1)(y2-y1)]/z

если и t, и t" лежат в пределах промежутка [0..1], то отрезки пересекаются








 
pasha676   (2003-03-20 13:56) [28]

А в случае отрезков наверное все же будет оптимальным по скорости вариант с попарным сравнением. Однако при этом придеться расмотреть довольно много вариантов.


 
Romkin ©   (2003-03-20 13:58) [29]

Это граничные условия, я исходил из того, что сама окружность не входит в область. Вместо меньше можно подразумевать "не больше" и тд. Уж на совпадение расстояния с радиусом можно проверить.
Дополнение к п.2: Перпендикуляр из центра окружности к отрезку пересекает отрезок в том и только в том случае, если оба угла между отрезком и направлением на центр окружности на концах отрезка меньше 90 градусов. Установить, меньше или больше этот угол можно через скалярное произведение и модуль вектора.


 
JibSkeart ©   (2003-03-20 13:58) [30]

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


 
myor ©   (2003-03-20 14:01) [31]

pasha676 (20.03.03 13:51)
а выше что написано?
a(x11,y11;x12,y12)...
см. johnmen
снимешь сутану, а это и не хрен вовсе.


 
myor ©   (2003-03-20 14:06) [32]

2 Romkin © (20.03.03 13:58)

myor © (20.03.03 13:52)


 
Romkin ©   (2003-03-20 14:11) [33]

2myor Заработался. Поясняю. Отрезок может полностью принадлежать окружности (лежать внутри нее), и может случится, что перпендикуляр к нему его пересекает... А п.1 у меня - чтобы не делать лишней работы по поиску длины перпендикуляра - если один конец - в окружности, а другой - вне ее, то понятно, что отрезок ее пересекает :-))), и напротив, если оба расстояния меньше радиуса - понятно, что не пересекает (лежит внутри). Остается третий случай - оба конца вне окружности, но пересечение есть (две точки пересечения), см. п.2


 
myor ©   (2003-03-20 14:37) [34]

Romkin © (20.03.03 14:11)

пояснения излишни. давайте лучше сформулируем алгоритм:
O(x0,y0)- центр окружности, R- радиус,
A(x1,y1), B(x2,y2)- концы отрезка,
P- перпендикуляр из центра на отрезок.

если (A-O>R и B-O<=R) или (A-O<=R и B-O>R)
то пересекает
если A-O>R и B-O>R и P<R
то пересекает

так?


 
MBo ©   (2003-03-20 14:58) [35]

отрезок описываем параметрически
x=t*ax+bx
y=t*ay+by
(t=0..1)

x=(x2-x1)*t+x1
y=(y2-y1)*t+y1

dx=x2-x1
dy=y2-y1

окружность x0,y0,R

найдем точки пересечения окружности и прямой, на которой лежит отрезок

(x-x0)^2+(y-y0)^2=R^2

(dx*t+(x1-x0))^2+(dy*t+(y1-y0))^2=R^2

раскроем скобки

t^2*(dx^2+dy^2)+t*2(dx*(x1-x0)+dy*(y1-y0))+[(x1-x0)^2+(y1-y0)^2-R^2]=0

a=dx^2+dy^2;
b=2(dx*(x1-x0)+dy*(y1-y0))
c=(x1-x0)^2+(y1-y0)^2-R^2

считаем D этого кв. уравнения. Если <0, пересечения нет
иначе находим 2 точки пересечения (1 при D=0)
Если хотя бы одна в промежутке 0..1, то отрезок пересекается с окружностью.






 
Axis_Of_Evil ©   (2003-03-20 15:39) [36]

>1. определить факт пересечения двух отрезков
>2. определить факт пересечения отрезка и окружности

И это тема на 35 постов???
С такими офигительно сложными вопросами???
Да ...


 
Danilka ©   (2003-03-20 15:58) [37]

Merlin © (20.03.03 13:44)
я сам не понял... хотя и пользовался ими. ;))

Кстати, в этом пакете есть еще пересечение эллипса с прямоугольником. Тоже такое-же непонятное. Думаю, при желании можно оттуда вывести пересечение окружности с прямой.

Если надо, могу верезать и выложить сюда.


 
nikkie ©   (2003-03-20 16:30) [38]

алгоритм Ромкина для задачи с окружностью
даны: точки A,B, и O, радиус R
обозначаем: OA = a, OB = b, AB = c

1. считаем a^2 и b^2

2. a^2 < R^2 and b^2 < R^2 => пересечения нет

3. (a^2 < R^2 and b^2 >= R^2) or (a^2 >= R^2 and b^2 < R^2) => пересечения есть

4. остался вариант (a^2 >= R^2 and b^2 >= R^2). считаем высоту перпендикуляра из O на AB.
h^2 = (2 a^2 b^2 + 2 a^2 c^2 + 2 b^2 c^2 - a^4 - b^4 - c^4) / c^2

5. если h^2 > R^2 - пересечения нет.

6. проверяем, что углы острые. если одно скалярных произведений меньше нуля
(AO, AB) < 0 or (BO, BA) < 0 - пересечения нет

7. иначе пересечение есть.

пункты (4,5) и 6 можно поменять местами.


 
MBo ©   (2003-03-20 16:32) [39]

>Danilka
>Тоже такое-же непонятное
см. (20.03.03 14:58)


 
Romkin ©   (2003-03-20 16:33) [40]

4. и 6. местами поменяй - если угол тупой, то и перпендикуляр считать не надо.
А вообще, вместо п. 2 Mbo уже сказал - гораздо проще



Страницы: 1 2 вся ветка

Текущий архив: 2003.04.07;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.014 c
3-19473
Дмитрий К.К.
2003-03-18 06:29
2003.04.07
Еще раз о BDE


1-19578
Юлия
2003-03-27 10:44
2003.04.07
длинные слова в отчете


6-19719
ola
2003-02-13 09:41
2003.04.07
Подтверждение о получении письма?


6-19735
_MAD_
2003-02-08 23:31
2003.04.07
TIdTCPServer и TServerSocket


14-19794
Эльф
2003-03-19 18:09
2003.04.07
Собственный cmd.com