import numpy as np
$$A=\sum_{i=1}^{N-1}I_{i+1,i}+I_{1,N}$$where e.g.
$$I_{2,1}=\intop_{x_{1}}^{x_{2}}ydx=\frac{1}{2}(y_{2}+y_{1})(x_{2}-x_{1})$$
def poly_area(xy):
"""
Calculates polygon area.
x = xy[:,0], y = xy[:,1]
"""
l = len(xy)
s = 0.0
# Python arrys are zer0-based
for i in range(l):
j = (i+1)%l # keep index in [0,l)
s += (xy[j,0] - xy[i,0])*(xy[j,1] + xy[i,1])
return -0.5*s
def poly_plot(xy, titlestr = "", margin = 0.25):
"""
Plots polygon. For arrow see:
http://matplotlib.org/examples/pylab_examples/arrow_simple_demo.html
x = xy[:,0], y = xy[:,1]
"""
xmin = np.min(xy[:,0])
xmax = np.max(xy[:,0])
ymin = np.min(xy[:,1])
ymax = np.max(xy[:,1])
hl = 0.1
l = len(xy)
for i in range(l):
j = (i+1)%l # keep index in [0,l)
dx = xy[j,0] - xy[i,0]
dy = xy[j,1] - xy[i,1]
dd = sqrt(dx*dx + dy*dy)
dx = dx*(1 - hl/dd)
dy = dy*(1 - hl/dd)
arrow(xy[i,0], xy[i,1], dx, dy, head_width=0.05, head_length=0.1, fc='b', ec='b')
xlim(xmin-margin, xmax+margin)
ylim(ymin-margin, ymax+margin)
title(titlestr)
xy = np.array([[1,1],[4,1],[4,3],[1,3]])
poly_plot(xy,'rectangle')
print(poly_area(xy))
def poly_area1(xy):
"""
Calculates polygon area.
x = xy[:,0], y = xy[:,1]
"""
xy1 = np.roll(xy,-1,axis = 0) # shift by -1
return -0.5*np.inner(xy1[:,0] - xy[:,0],xy1[:,1] + xy[:,1])
print(poly_area1(xy))
uv = np.array([[1,1],[4,3],[4,1],[1,3]])
poly_plot(uv,'Self-intersecting polygon')
print(poly_area(uv))
uv1 = np.array([[1,1],[2.5,2],[4,1],[4,3],[2.5,2],[1,3]])
poly_plot(uv1,'polygon')
print(poly_area(uv1))
$A(uv_1) = \frac{1}{2} A(uv)$
def poly_perimeter(xy):
"""
Calculates polygon perimeter.
x = xy[:,0], y = xy[:,1]
"""
xy1 = np.roll(xy,-1,axis = 0) # shift by -1
return np.sum(sqrt((xy1[:,0] - xy[:,0])**2 + (xy1[:,1] - xy[:,1])**2))
print(poly_perimeter(xy))
print(poly_perimeter(uv))
$P(uv) = 2*(2+\sqrt{13}) = 11.211102550927978586 $
print(poly_perimeter(uv1))
def poly_perimeter2(xy):
"""
Calculates polygon perimeter.
x = xy[:,0], y = xy[:,1]
"""
xy1 = np.roll(xy,-1,axis = 0) # shift by -1
return np.sum(apply_along_axis(linalg.norm, 1, xy1-xy))
print(poly_perimeter2(xy))
print(poly_perimeter2(uv1))