LINUX.ORG.RU

Площадь невыпуклого многоугольника

 ,


0

1

Здравствуйте, подскажите алгоритм для на хождения площади невыпуклого многоугольника. Его нужно дробить на треугольники или можно проще?

★★★★★

Последнее исправление: CYB3R (всего исправлений: 1)

Ответ на: комментарий от trex6

Пример из статьи не работает. Для многоугольника (1,0) (0,1) (1,2) (2,1) (1,1) выдает 4.5 вместо 1.5

Aswed ★★★★★
() автор топика

Обходишь его по кругу по направленым векторам - его сторонам. Суммируешь площади трапеций со знаком, у которых основы - перпендикуляры на какую-то ось, одна боковая сторона часть этой оси, а вторая сам вектор. Знак площади нужно брать в зависимости от того точка в какую сторону направлена проекция вектора на выбраную ось

vertexua ★★★★★
()

Теорема Гаусса-Остроградского в помощь. Уже не помню, какой там это курс матана.

yvv ★★☆
()
Ответ на: комментарий от vertexua

А трапеции то зачем? Можно просто считать площади треугольников, образованных стороной и вектором из нач. координат к началу стороны. Площадь треугольника брать как посл. элемент векторного произведения, со знаком ес-но...

AIv ★★★★★
()
Последнее исправление: AIv (всего исправлений: 1)
Ответ на: комментарий от vertexua

ну например (1,0) (0,1) (1,2) (2,1) (1,1)

Aswed ★★★★★
() автор топика
Ответ на: комментарий от vertexua

только там пополам ес-но, векторное произведение дает площадь параллелограмма

L = [(1,0), (0,1), (1,2), (2,1), (1,1)]
.5*abs(sum([ a[0]*(b[1]-a[1])-a[1]*(b[0]-a[0]) for a, b in zip(L, L[-1:]+L[:-1]) ]))

AIv ★★★★★
()
Ответ на: комментарий от yvv

Пардон, для площади фигуры формула Стокса нужна. Всё время их путаю.

два чая этому господину.

dikiy ★★☆☆☆
()
Ответ на: комментарий от exlevan

нет

Prelude> let s l = 0.5 * sum $ zipWith (\(a0,a1) (b0,b1) -> a0*(b1-a1)-a1*(b0-a0))  l (last l:l)
Prelude> let s l = (0. 5 *) .  sum $ zipWith (\(a0,a1) (b0,b1) -> a0*(b1-a1)-a1*(b0-a0))  l (last l:l)

<interactive>:4:5:
    Could not deduce (Num (a -> b0))
      arising from the ambiguity check for `s'

да и в point-free оно убодо не переписывается

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

Я разве советовал поставить пробел в середине числа?

Оригинальная s неприменима к списку пар чисел из-за приоритета ($): сначала вычислится (0.5 * sum), где sum — не число:

Prelude> let s l = 0.5 * sum $ zipWith (\(a0,a1) (b0,b1) -> a0*(b1-a1)-a1*(b0-a0))  l (last l:l)
Prelude> s [(1,0), (0,1), (1,2), (2,1), (1,1)]

<interactive>:29:1:
    No instance for (Fractional ([a0] -> a0)) arising from a use of `s'
    Possible fix:
      add an instance declaration for (Fractional ([a0] -> a0))
    In the expression: s [(1, 0), (0, 1), (1, 2), (2, 1), ....]
    In an equation for `it': it = s [(1, 0), (0, 1), (1, 2), ....]

Поэтому нужны скобки или композиция:

Prelude> let s l = (0.5 *) . sum $ zipWith (\(a0,a1) (b0,b1) -> a0*(b1-a1)-a1*(b0-a0))  l (last l:l)
Prelude> s [(1,0), (0,1), (1,2), (2,1), (1,1)]
1.5
Prelude> let s l = 0.5 * (sum $ zipWith (\(a0,a1) (b0,b1) -> a0*(b1-a1)-a1*(b0-a0))  l (last l:l))
Prelude> s [(1,0), (0,1), (1,2), (2,1), (1,1)]
1.5

exlevan
()
Ответ на: комментарий от qnikst

Не понял. Причину делать неработающий код работающим? По-моему, очевидно. Причину предпочитать композицию скобочкам? Личное предпочтение.

exlevan
()
Ответ на: комментарий от exlevan

ну логично, что я не про очевидный вопрос спрашивал :)

ясно. и тогда уж предпочитать композицию постфиксной записи т.к. ты заменил 0.5 * (f) на (0.5 *) . f

qnikst ★★★★★
()
Последнее исправление: qnikst (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.