多邊形面積計算及頂點順-逆時針方向判斷


格林(Green)公式告訴我們,在平面閉區域D上的二重積分可以通過沿閉區域D的邊界曲線L上的曲線積分來表達。即,設閉區域$D$由分段光滑的曲線$L$圍成,函數$P(x,y)$及$Q(x,y)$在$D$上具有一階連續偏導數,則有$$\iint_{D}(\frac{\partial Q}{\partial x}-\frac{\partial P}{\partial y})dxdy=\oint_{L}Pdx+Qdy$$其中$L$是$D$的取正向的邊界曲線。根據公式推導過程(參考高等數學同濟版下),有如下關系存在:$$-\iint_{D}\frac{\partial P}{\partial y}dxdy=\oint_{L}Pdx\\\iint_{D}\frac{\partial Q}{\partial x}dxdy=\oint_{L}Qdy $$

對於上面兩個式子,分別取$P=-y$,$Q=x$可得到:$$\begin{align}&\iint_{D}dxdy=A=-\oint_{L}ydx\\&\iint_{D}dxdy=A=\oint_{L}xdy\end{align}$$

其中,$A$為閉區域$D$的面積。根據式(1)和(2)也可得出:$$A=\frac{1}{2}\oint_{L}xdy-ydx$$

根據公式(2)來計算多邊形面積,參考下面的示意圖,曲線$L$由多段光滑的直線段$L_i$連接而成。由於$L$是分段光滑的,則有向曲線$L$上對坐標的曲線積分等於在光滑的各段上對坐標的曲線積分之和。即$A=\oint_Lxdy=\int_{L_0}xdy+...+\int_{L_6}xdy$

 

直線段$L_i$從點$(x_i,y_i)$到點$(x_{i+1},y_{i+1})$的參數方程為$L_i(t)=\left ((x_{i+1}-x_i)t+x_i,(y_{i+1}-y_i)t+y_i\right),\quad 0\leq t\leq 1$,於是對線段$L_i$的坐標積分為:$$\begin{aligned}\int_{Li}xdy&=\int_0^1((x_{i+1}-x_i)t+x_i)(y_{i+1}-y_i)dt\\&=(y_{i+1}-y_i)(x_it+\frac{1}{2}t^2(x_{i+1}-x_i))\big|_{0}^{1}\\&=\frac{1}{2}(x_{i+1}+x_i)(y_{i+1}-y_i)\end{aligned}$$

將每段結果相加得到多邊形的面積為:$$\boxed{A=\sum_{i=0}^{n}\frac{(x_{i+1}+x_i)(y_{i+1}-y_i)}{2}}$$

其中,$n$為多邊形頂點數-1,$(x_{n+1},y_{n+1})=(x_0,y_0)$。類似的,根據公式(1)可計算出多邊形的面積為:$$\boxed{A=\sum_{i=0}^{n}\frac{(x_i-x_{i+1})(y_i+y_{i+1})}{2}}$$

多邊形面積和頂點數組的順-逆時針方向可以根據上面的公式計算,即如果是逆時針($L$為正向),則計算出的面積為正值;如果是順時針,計算出的面積為負值。可參考下面的代碼:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

def isCounterclockwise(points):
    s = 0
    points_count = len(points)
    for i in range(points_count):
        point = points[i]
        point2 = points[(i + 1) % points_count]
        s += (point.x - point2.x) * (point.y + point2.y)
    return s > 0


def poly_area(points):
    s = 0
    points_count = len(points)
    for i in range(points_count):
        point = points[i]
        point2 = points[(i + 1) % points_count]
        s += (point.x - point2.x) * (point.y + point2.y)
    return abs(s/2)


if __name__ == "__main__":
    polygon1 = [Point(0,0), Point(0.5,0), Point(0.5,0.5), Point(0,1)] # counter-clockwise
    polygon2 = polygon1[::-1]  # clockwise
    print(isCounterclockwise(polygon1), isCounterclockwise(polygon2)) # True, False
    print(poly_area(polygon1)) # 0.375

 

 

 

參考:

Shoelace formula

A formula for the area of a polygon

判斷多邊形邊界曲線順/逆時針 兩種方法

如何判斷一個多邊形的環是逆時針還是順時針

判斷多邊形順時針還是逆時針--根據多邊形面積正負

格林公式的幾何意義是什么?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM