Я пытаюсь найти, если прямоугольник пересекает вогнутый полигон. выполнить ли этот алгоритм?

голоса
7

Я пытаюсь найти, если прямоугольник пересекает вогнутый полигон. Я нашел этот алгоритм:

double determinant(Vector2D vec1, Vector2D vec2){
    return vec1.x*vec2.y-vec1.y*vec2.x;
}

//one edge is a-b, the other is c-d
Vector2D edgeIntersection(Vector2D a, Vector2D b, Vector2D c, Vector2D d){
    double det=determinant(b-a,c-d);
    double t=determinant(c-a,c-d)/det;
    double u=determinant(b-a,c-a)/det;
    if ((t<0)||(u<0)||(t>1)||(u>1))return NO_INTERSECTION;
    return a*(1-t)+t*b;
}

Если я выполнить это в 4 раза (Top направо, сверху вниз слева, вверху справа внизу, внизу справа) * (все ребра моего полигона) бы это эффективно и точно сказать мне, если прямоугольник имеет часть или все вогнутые многоугольник внутри? Если не то, что будет отсутствовать?

благодаря

Задан 11/08/2010 в 23:05
источник пользователем
На других языках...                            


3 ответов

голоса
2

Я думаю, что следующее должно работать:

(1) for each e1 in rectangle_edges, e2 in polygon_edges
    (1.1) if edgeIntersection(e1,e2) != NO_INTERSECTION
        (1.1.1) return true
(2) if (max_polygon_x < max_rectangle_x) and (min_polygon_x > min_rectangle_x) and (max_polygon_y < max_rectangle_y) and (min_polygon_y > min_rectangle_y)
    (2.1) return true
(2) return false

Edit : Добавлена проверка для того , многоугольник находится внутри прямоугольника.

Ответил 11/08/2010 в 23:12
источник пользователем

голоса
13

Код пытается найти точку пересечения двух сегментов - AB и CD.

Есть много различных способов, чтобы объяснить, как он это делает, в зависимости от того, как интерпретировать эти операции.

Скажем, точка А имеет координаты (ха, уа), B - (хь, Yb) и так далее. Скажем,

dxAB = xb - xa
dyAB = yb - ya
dxCD = xd - xc
dyCD = yd - yc

Следующая система двух линейных уравнений

| dxAB dxCD |   | t |   | xc-xa |
|           | * |   | = |       |
| dyAB dyCD |   | u |   | yc-ya |

если решена tи u, даст вам пропорциональное положение точки пересечения на линии АВ (значение t) и по линии CD (значение u). Эти значения будут лежать в диапазоне , [0, 1]если точка принадлежит соответствующему сегменту , так и вне этого диапазона , если точка лежит вне отрезка (на линии , содержащей сегмент).

Для решения этой системы линейных уравнений можно использовать хорошо известное правило Крамера . Для этого нам понадобится определитель

| dxAB dxCD |
|           |
| dyAB dyCD |

что именно determinant(b - a, c - d)из вашего кода. ( На самом деле, что я здесь determinant(b - a, d - c), но это не очень важно для целей данного объяснения. Код , который вы размещены по какой - то причине свопы C и D, см PS примечание ниже).

И мы также должны определитель

| xc-xa dxCD |
|            |
| yc-ya dyCD |

что именно determinant(c-a,c-d)из вашего кода, и определитель

| dxAB xc-xa |
|            |
| dyAB yc-ya |

который точно determinant(b-a,c-a).

Разделив эти детерминанты в соответствии с правилом Крамера даст нам значение tи u, что это именно то , что делается в коде, который размещен.

Затем код продолжает проверять значения tи uпроверить , если отрезки действительно пересекаются, то есть ли как tи uпринадлежат [0, 1]диапазону. И если они делают, он вычисляет фактическую точку пересечения путем оценки a*t+b*(1-t)( то же самое, что можно было бы оценить c*u+d*(1-u)). (Опять же , см PS примечание ниже).

PS В исходном коде точки D и C являются «местами» в том смысле , что код делает c - d, где я делаю d - cв моем объяснении. Но это не имеет никакого значения для общей идеи алгоритма, пока один внимательном со знаками.

Это своп C и D точки также является причиной для a*(1-t)+t*bвыражения используется при оценке точки пересечения. Обычно, как в моем объяснении, one'd ожидал увидеть что - то вроде a*t+b*(1-t)там. (У меня есть сомнения по этому поводу , хотя. Я бы ожидал увидеть a*t+b*(1-t)там даже в вашей версии. Может быть ошибкой.)

PPS Автор , если код забыл проверить det == 0(или очень близко к 0), что будет происходить в случае , когда сегменты параллельны.

Ответил 11/08/2010 в 23:30
источник пользователем

голоса
0

Насколько я могу сказать после того, как быстрый взгляд, он пытается определить, 2 отрезки пересекаются, и если они делают, то, что координаты точки пересечения являются.

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

Ответил 11/08/2010 в 23:56
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more