python - 从 xyz 坐标查找多边形的面积

标签 python 3d polygon area

我正在尝试使用 shapely.geometry.Polygon 模块来查找多边形的面积,但它在 xy 平面上执行所有计算。这对我的一些多边形来说很好,但其他多边形也有 z 维度,所以它不是我想要的。

是否有一个包可以根据 xyz 坐标给出平面多边形的面积,或者有一个包或算法可以将多边形旋转到 xy 平面这样我就可以使用 shapely.geometry.Polygon().area 了?

多边形表示为 [(x1,y1,z1),(x2,y2,z3),...(xn,yn,zn)] 形式的元组列表 .

最佳答案

Here is the derivation of a formula for calculating the area of a 3D planar polygon

这是实现它的 Python 代码:

#determinant of matrix a
def det(a):
    return a[0][0]*a[1][1]*a[2][2] + a[0][1]*a[1][2]*a[2][0] + a[0][2]*a[1][0]*a[2][1] - a[0][2]*a[1][1]*a[2][0] - a[0][1]*a[1][0]*a[2][2] - a[0][0]*a[1][2]*a[2][1]

#unit normal vector of plane defined by points a, b, and c
def unit_normal(a, b, c):
    x = det([[1,a[1],a[2]],
             [1,b[1],b[2]],
             [1,c[1],c[2]]])
    y = det([[a[0],1,a[2]],
             [b[0],1,b[2]],
             [c[0],1,c[2]]])
    z = det([[a[0],a[1],1],
             [b[0],b[1],1],
             [c[0],c[1],1]])
    magnitude = (x**2 + y**2 + z**2)**.5
    return (x/magnitude, y/magnitude, z/magnitude)

#dot product of vectors a and b
def dot(a, b):
    return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]

#cross product of vectors a and b
def cross(a, b):
    x = a[1] * b[2] - a[2] * b[1]
    y = a[2] * b[0] - a[0] * b[2]
    z = a[0] * b[1] - a[1] * b[0]
    return (x, y, z)

#area of polygon poly
def area(poly):
    if len(poly) < 3: # not a plane - no area
        return 0

    total = [0, 0, 0]
    for i in range(len(poly)):
        vi1 = poly[i]
        if i is len(poly)-1:
            vi2 = poly[0]
        else:
            vi2 = poly[i+1]
        prod = cross(vi1, vi2)
        total[0] += prod[0]
        total[1] += prod[1]
        total[2] += prod[2]
    result = dot(total, unit_normal(poly[0], poly[1], poly[2]))
    return abs(result/2)

为了测试它,这里有一个倾斜的 10x5 正方形:

>>> poly = [[0, 0, 0], [10, 0, 0], [10, 3, 4], [0, 3, 4]]
>>> poly_translated = [[0+5, 0+5, 0+5], [10+5, 0+5, 0+5], [10+5, 3+5, 4+5], [0+5, 3+5, 4+5]]
>>> area(poly)
50.0
>>> area(poly_translated)
50.0
>>> area([[0,0,0],[1,1,1]])
0

最初的问题是我过于简单化了。它需要计算垂直于平面的单位向量。面积是点积与所有叉积之和的一半,而不是所有叉积量值之和的一半。

这可以稍微清理一下(矩阵和向量类会使它更好,如果你有它们,或者行列式/叉积/点积的标准实现),但它在概念上应该是合理的。

关于python - 从 xyz 坐标查找多边形的面积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12642256/

相关文章:

list - 从具有特定参数的列表中获取特定对象

python - 谷歌应用引擎代理

css - 以 3d 视角翻转圆圈

html - 使用 CSS 以小 Angular 倾斜 Div 的左侧和右侧

java - 查找并表示嵌套的、不相交的多边形之间的区域

Python - BeautifulSoup - 通过列表中的特定元素遍历 findall

algorithm - "false 3D"棱镜墙的渲染顺序

java - 基于时间的轮换

java - 确定多边形是否在 map 边界内

python - 如何从 MySQL 日期时间转换为 numpy datetime64?