最近需要實現乙個計算非凸多邊形面積的功能,需要輸入是順次排序的多邊形頂點座標,假設輸入的多邊形頂點是v=,則多邊形的邊為e=。要求輸出該多邊形所圍成的面積。
對於凸多邊形來講,比較容易操作,只需要選擇乙個點作為公共頂點,然後將這個選定的公共頂點與所有其他頂點相連,即可將這個凸多邊形分割為n-2個三角形,求這些三角形的面積之和即可。這裡n為多邊形的頂點個數,這些三角形都有這個選定的點作為乙個公共頂點。
而對於非凸多邊形顯然無法直接這樣操作。這一篇文章給出了一種求解任意多邊形當然包括非凸多邊形面積的演算法。他的做法是給每個三角形的面積值乙個符號,其基本思想仍然是構造乙個類似於凸多邊形的情況(並不一定是凸多邊形,只是類似),然後減去多餘的面積。這個思路是不錯的,但是他在接下來具體實現的時候做法並不高明。具體在計算每個三角形的面積的時候,使用的方法不太好,不僅時間複雜度高,並且當兩條線比較靠近的時候,使用開方操作,可能會導致溢位而無法開根號。因此我在這裡對原作者的實現方法進行了一些改進。
三角形帶符號的面積,容易讓人想起向量的叉乘,之前在graham-scan演算法計算凸包的python**實現一文中也使用了向量的叉乘。向量的叉乘是帶符號的,並且其絕對值為兩個向量共起點時所構成的平行四邊形的面積。而平行四邊形的對角線將整個平行四邊形分割成了兩個全等的三角形,因而每個三角形的面積為整個平行四邊形的一半。
具體的python實現及測試**如下:
import numpy as np
""" 計算多邊形的面積,包括非凸多邊形的情況,
要求輸入的頂點是按照逆時針順序順次排列的。
所要求解面積的多邊形即為這些頂點乙個乙個地相連而成
e =
@author: sdu_brz
@date: 2019/02/18
"""def coss_multi(v1, v2):
"""計算兩個向量的叉乘
:param v1:
:param v2:
:return:
"""return v1[0]*v2[1] - v1[1]*v2[0]
def polygon_area(polygon):
"""計算多邊形的面積,支援非凸情況
:param polygon: 多邊形頂點,已經進行順次逆時針排序
:return: 該多邊形的面積
"""n = len(polygon)
if n < 3:
return 0
vectors = np.zeros((n, 2))
for i in range(0, n):
vectors[i, :] = polygon[i, :] - polygon[0, :]
area = 0
for i in range(1, n):
area = area + coss_multi(vectors[i-1, :], vectors[i, :]) / 2
return area
if __name__ == "__main__":
"""測試"""
polygon1 = np.array([[0, 0],
[1, 0],
[1, 1],
[0, 1]])
print(polygon_area(polygon1))
polygon2 = np.array([[0, 0],
[5, 0],
[5, 4],
[4, 4],
[4, 1],
[1, 1],
[1, 7],
[0, 7]])
print(polygon_area(polygon2))
任意多邊形面積計算
任意多邊形的面積可由任意一點與多邊形上依次兩點連線構成的三角形向量面積求和得出。向量面積 三角形兩邊向量的叉乘。如下圖 按定理,多邊形面積由p點與a g的各頂點連線所構成的三角形向量面積構成,假定多邊形頂點座標順序為a g,逆時針為正方向,則有如下結論 pab,pbc,pcd均為順時針,面積為負 p...
任意多邊形面積
給定多邊形的頂點座標 有序 讓你來求這個多邊形的面積,你會怎麼做?我們知道,任意多邊形都可以分割為n個三角形,所以,如果以這為突破點,那麼我們第一步就是把給定的多邊形,分割為數個三角形,分別求面積,最後累加就可以了,把多邊形分割為三角形的方式多種多樣,在這裡,我們按照如下圖的方法分割 s點作為起始點...
任意多邊形面積的計算
原理論述1 書中給出定理 任意多邊形的面積可由任意一點與多邊形上依次兩點連線構成的三角形向量面積求和得出。向量面積 三角形兩邊向量的叉乘。如下圖 按定理,多邊形面積由p點與a g的各頂點連線所構成的三角形向量面積構成,假定多邊形頂點座標順序為a g,逆時針為正方向,則有如下結論 pab,pbc,pc...