"ConvexHull", "alpha_shape" in python 为什么生成不同的面积值?
"ConvexHull", "alpha_shape" in python generate different area values why?
我正在尝试计算不规则多边形的面积。
我使用了“ConvexHull”和“alpha_shape”但是表面(面积)的输出不一样。
有什么建议吗?
您将在下面找到数据和用于计算面积的代码:
###################################################################
data = [(1.866200,4.379100),
(1.128700,4.814700),
(2.036000,3.074600),
(1.077500,6.100000),
(1.833300,7.126600),
(2.061200,8.399900),
(2.710500,9.418000),
(3.426000,9.141000),
(2.795400,2.644300),
(2.773300,1.400700),
(3.554100,1.084300),
(4.338900,2.025600),
(4.365600,9.981400),
(5.284800,9.657300),
(6.305400,10.194400),
(6.829000,9.124800),
(5.889000,4.120900),
(4.884500,1.854300),
(5.694300,2.821400),
(6.825100,6.487400),
(6.698000,5.189600),
(7.676500,8.884200),
(7.670500,7.610700)]
####################################################
import numpy as np
from shapely.geometry import Polygon
from scipy.spatial import ConvexHull, convex_hull_plot_2d
####################################################
hull = ConvexHull(data)
print('area of the surface = ', hull.volume)
####################################################
polygon = Polygon(data)
print('area of the surface = ', polygon.area)
你的形状多边形不是船体图形(它甚至不是凸面),所以它的面积较小也就不足为奇了:
import numpy as np
from shapely.geometry import Polygon
from scipy.spatial import ConvexHull, convex_hull_plot_2d
from matplotlib import pyplot as plt
hull = ConvexHull(data)
print('area of the surface = ', hull.volume)
polygon = Polygon(data)
print('area of the surface = ', polygon.area)
fig, ax = plt.subplots()
convex_hull_plot_2d(hull, ax=ax)
x, y = polygon.exterior.xy
ax.plot(x, y, c="red", ls="--", label="shapely")
ax.legend()
plt.show()
如果我们按照凸包对数据点进行排序,
data_shapely = [
(2.710500,9.418000),
(4.365600,9.981400),
(6.305400,10.194400),
(7.676500,8.884200),
(7.670500,7.610700),
(6.698000,5.189600),
(5.694300,2.821400),
(4.884500,1.854300),
(3.554100,1.084300),
(2.773300,1.400700),
(1.128700,4.814700),
(1.077500,6.100000),
(2.061200,8.399900)
]
polygon = Polygon(data_shapely)
那么面积是一样的:
area of the surface = 41.115790855
area of the surface = 41.11579085500001
您还误解了 shapely 如何计算 non-convex 多边形的面积。
data_shapely = [
(0,0),
(0,1),
(1,1),
(1,0)
]
面积为 1 不足为奇。人们可能会认为
data_shapely = [
(0,0),
(1,1),
(0,1),
(1,0)
]
根据其形状,面积为 0.5。然而,结果为 0,因为 non-convex 多边形中看似“翻转”的区域被计为负值。
如果您的点表现良好,并且您希望获得与通过相同点的多边形具有大致相同面积的凸包,则需要重新排序这些点。例如,您可以按关于重心的角度对它们进行排序:
data = np.array(data)
center = data.mean(0)
angle = np.arctan2(*(data - center).T[::-1])
index = np.argsort(angle)
polygon2 = Polygon(data[index])
剧情现在看起来好多了:
fig, ax = plt.subplots(1, 2)
ax[0].set_title("Original")
convex_hull_plot_2d(hull, ax=ax[0])
ax[0].plot(*polygon.exterior.xy, 'r--')
ax[1].set_title("Untangled")
convex_hull_plot_2d(hull, ax=ax[1])
ax[1].plot(*polygon2.exterior.xy, 'r--')
ax[1].plot(*center, 'kx')
plt.show()
事实上,您现在知道外壳仅比多边形大 10%:
>>> polygon2.area
37.25662339499999
>>> hull.volume
41.115790855
>>> polygon2.area / hull.volume * 100
90.61390434247064
>>> (hull.volume / polygon2.area - 1) * 100
10.35833929200876
我正在尝试计算不规则多边形的面积。
我使用了“ConvexHull”和“alpha_shape”但是表面(面积)的输出不一样。
有什么建议吗?
您将在下面找到数据和用于计算面积的代码:
###################################################################
data = [(1.866200,4.379100),
(1.128700,4.814700),
(2.036000,3.074600),
(1.077500,6.100000),
(1.833300,7.126600),
(2.061200,8.399900),
(2.710500,9.418000),
(3.426000,9.141000),
(2.795400,2.644300),
(2.773300,1.400700),
(3.554100,1.084300),
(4.338900,2.025600),
(4.365600,9.981400),
(5.284800,9.657300),
(6.305400,10.194400),
(6.829000,9.124800),
(5.889000,4.120900),
(4.884500,1.854300),
(5.694300,2.821400),
(6.825100,6.487400),
(6.698000,5.189600),
(7.676500,8.884200),
(7.670500,7.610700)]
####################################################
import numpy as np
from shapely.geometry import Polygon
from scipy.spatial import ConvexHull, convex_hull_plot_2d
####################################################
hull = ConvexHull(data)
print('area of the surface = ', hull.volume)
####################################################
polygon = Polygon(data)
print('area of the surface = ', polygon.area)
你的形状多边形不是船体图形(它甚至不是凸面),所以它的面积较小也就不足为奇了:
import numpy as np
from shapely.geometry import Polygon
from scipy.spatial import ConvexHull, convex_hull_plot_2d
from matplotlib import pyplot as plt
hull = ConvexHull(data)
print('area of the surface = ', hull.volume)
polygon = Polygon(data)
print('area of the surface = ', polygon.area)
fig, ax = plt.subplots()
convex_hull_plot_2d(hull, ax=ax)
x, y = polygon.exterior.xy
ax.plot(x, y, c="red", ls="--", label="shapely")
ax.legend()
plt.show()
如果我们按照凸包对数据点进行排序,
data_shapely = [
(2.710500,9.418000),
(4.365600,9.981400),
(6.305400,10.194400),
(7.676500,8.884200),
(7.670500,7.610700),
(6.698000,5.189600),
(5.694300,2.821400),
(4.884500,1.854300),
(3.554100,1.084300),
(2.773300,1.400700),
(1.128700,4.814700),
(1.077500,6.100000),
(2.061200,8.399900)
]
polygon = Polygon(data_shapely)
那么面积是一样的:
area of the surface = 41.115790855
area of the surface = 41.11579085500001
您还误解了 shapely 如何计算 non-convex 多边形的面积。
data_shapely = [
(0,0),
(0,1),
(1,1),
(1,0)
]
面积为 1 不足为奇。人们可能会认为
data_shapely = [
(0,0),
(1,1),
(0,1),
(1,0)
]
根据其形状,面积为 0.5。然而,结果为 0,因为 non-convex 多边形中看似“翻转”的区域被计为负值。
如果您的点表现良好,并且您希望获得与通过相同点的多边形具有大致相同面积的凸包,则需要重新排序这些点。例如,您可以按关于重心的角度对它们进行排序:
data = np.array(data)
center = data.mean(0)
angle = np.arctan2(*(data - center).T[::-1])
index = np.argsort(angle)
polygon2 = Polygon(data[index])
剧情现在看起来好多了:
fig, ax = plt.subplots(1, 2)
ax[0].set_title("Original")
convex_hull_plot_2d(hull, ax=ax[0])
ax[0].plot(*polygon.exterior.xy, 'r--')
ax[1].set_title("Untangled")
convex_hull_plot_2d(hull, ax=ax[1])
ax[1].plot(*polygon2.exterior.xy, 'r--')
ax[1].plot(*center, 'kx')
plt.show()
事实上,您现在知道外壳仅比多边形大 10%:
>>> polygon2.area
37.25662339499999
>>> hull.volume
41.115790855
>>> polygon2.area / hull.volume * 100
90.61390434247064
>>> (hull.volume / polygon2.area - 1) * 100
10.35833929200876