python - 计算许多三角形的符号面积

标签 python arrays numpy perfplot

我需要计算 signed area二维中的许多三角形,由形状为 (2, 3, n) 的 numpy 数组给出(x/y 坐标,三角形中的节点,三角形的数量)。我正在寻找一种快速完成它的方法,到目前为止我能想到的最好方法是

import numpy
import perfplot


def six(p):
    return (
        +p[0][2] * p[1][0]
        + p[0][0] * p[1][1]
        + p[0][1] * p[1][2]
        - p[0][2] * p[1][1]
        - p[0][0] * p[1][2]
        - p[0][1] * p[1][0]
    ) / 2


def mix(p):
    return (
        +p[0][2] * (p[1][0] - p[1][1])
        + p[0][0] * (p[1][1] - p[1][2])
        + p[0][1] * (p[1][2] - p[1][0])
    ) / 2


def mix2(p):
    p1 = p[1] - p[1][[1, 2, 0]]
    return (+p[0][2] * p1[0] + p[0][0] * p1[1] + p[0][1] * p1[2]) / 2


def cross(p):
    e1 = p[:, 1] - p[:, 0]
    e2 = p[:, 2] - p[:, 0]
    return (e1[0] * e2[1] - e1[1] * e2[0]) / 2


def einsum(p):
    return (
        +numpy.einsum("ij,ij->j", p[0][[2, 0, 1]], p[1][[0, 1, 2]])
        - numpy.einsum("ij,ij->j", p[0][[2, 0, 1]], p[1][[1, 2, 0]])
    ) / 2


def einsum2(p):
    return numpy.einsum("ij,ij->j", p[0][[2, 0, 1]], p[1] - p[1][[1, 2, 0]]) / 2


def einsum3(p):
    return (
        numpy.einsum(
            "ij,ij->j", numpy.roll(p[0], 1, axis=0), p[1] - numpy.roll(p[1], 2, axis=0)
        )
        / 2
    )


perfplot.save(
    "out.png",
    setup=lambda n: numpy.random.rand(2, 3, n),
    kernels=[six, mix, mix2, cross, einsum, einsum2, einsum3],
    n_range=[2 ** k for k in range(19)],
)

关于如何使其更高效的任何提示?

enter image description here

最佳答案

我认为问题不在于计算,而在于数据在内存中的组织方式。如果您不需要保留原始数据,您可以尝试使用 inplace 函数来尽量减少内存中临时对象的数量:

def mymix(p):

    p[0][1] -= p[0][0] # x1 = x1 - x0
    p[0][2] -= p[0][0] # x2 = x2 - x0
    p[1][1] -= p[1][0] # y1 = y1 - y0
    p[1][2] -= p[1][0] # y2 = y2 - y0

    p[0][1] *= p[1][2] # x1 = (x1-x0) * (y2-y0)
    p[0][2] *= p[1][1] # x2 = (x2-x0) * (y1-y0)

    p[0][1] -= p[0][2] # r = (x1-x0) * (y2-y0) - (x2-x0) * (y1-y0)
    p[0][1] /= 2

    return p[0][1]

关于python - 计算许多三角形的符号面积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50411583/

相关文章:

Python :Wave. 将帧读取到 numpy 数组以获取 fft

python - 用于删除实体名称的正则表达式

javascript - 在 ES2016 或更高版本中,像这样的列表推导式相当于什么?

java - 使用二进制搜索从排序的 int[] 中删除重复项

python - NumPy 相当于 pandas 日期时间访问器操作

python - numpy 中多维数组的三角索引

python - 从 mongoengine 的文档中获取必填字段?

Python:在 PIL 和/或 pygame 中操作 16 位 .tiff 图像:以某种方式转换为 8 位?

python - 安装redis时缺少redis库

javascript - 从 for 循环创建变量数组(Javascript)