【问题标题】:Determining all discrete points inside a triangle确定三角形内的所有离散点
【发布时间】:2021-09-14 22:29:48
【问题描述】:

问题输入由三个点A, B, C指定,每个点有两个坐标x, y

解决方案应该是三角形内所有点的数组,具有自然坐标。

示例:

输入是: A, B, C

输出是: 图中所有命名点

请注意,我正在尝试计算所有分数而不是计算它们,所以this question 与我的相差很大。

我遇到的问题:

主要问题是,指定所有三个段需要计算所有段的系数a, b,这可能会扩展我的代码,因为我必须涵盖所有情况水平线和垂直线。

那么我能想到的最好的方法是:

  1. 遍历自然x'es,从最小xA, B, C 到最大。
  2. 遍历自然y's,从最小yA, B, C 到最大。
  3. 对于每个点,检查是否满足具有 9 个不等式的方程组,我可以使用 numpy 手动求解。大量的不等式是第二最难的问题。

一般而言,我能想到的任何方式都需要我编写很多包含很多可能错误的代码。此外,我编写的指令越多,性能就越低,因为使用了许多非平凡的计算方法。

任何有关更简单解决方案的帮助将不胜感激。

【问题讨论】:

  • 谷歌“测试点是否在三角形中”。有很多资源。您不必解决 9 个不等式。
  • 我不确定它是否有效,但我相信你可以计算出三个高度。这对第 1 点和第 2 点没有帮助,但会将不等式的数量减少到三个。因为要位于三角形内,到点 A 的距离必须小于 h_a 等等
  • 一些想法http://stackoverflow.com/questions/2049582/how-to-determine-a-point-in-a-2d-triangle
  • 您可以使用barycentric coödrdinates 来确定一个点是否在三角形中(光线追踪器),但如果您需要一个点列表(前向几何体),那么最好进行光栅化.

标签: python algorithm


【解决方案1】:

你肯定需要三角形光栅化。

Arbitrary article。您将更正每条扫描线的起点和终点,以确保它们在三角形内。

【讨论】:

  • 是的。只需检查扫描线的第一个和最后一个点(例如,PointInTriangle 测试的纯整数版本)
【解决方案2】:

您可以找到通过每对点(线 AB、BC、AC)的线,并检查这些线的哪一边是三角形的内侧。位于所有线“内侧”侧的点都在三角形内:

def insidetriangle((x1,x2,x3),(y1,y2,y3)):
    import numpy as np
    xs=np.array((x1,x2,x3),dtype=float)
    ys=np.array((y1,y2,y3),dtype=float)

    # The possible range of coordinates that can be returned
    x_range=np.arange(np.min(xs),np.max(xs)+1)
    y_range=np.arange(np.min(ys),np.max(ys)+1)

    # Set the grid of coordinates on which the triangle lies. The centre of the
    # triangle serves as a criterion for what is inside or outside the triangle.
    X,Y=np.meshgrid( x_range,y_range )
    xc=np.mean(xs)
    yc=np.mean(ys)

    # From the array 'triangle', points that lie outside the triangle will be
    # set to 'False'.
    triangle = np.ones(X.shape,dtype=bool)
    for i in range(3):
        ii=(i+1)%3
        if xs[i]==xs[ii]:
            include = X *(xc-xs[i])/abs(xc-xs[i]) > xs[i] *(xc-xs[i])/abs(xc-xs[i])
        else:
            poly=np.poly1d([(ys[ii]-ys[i])/(xs[ii]-xs[i]),ys[i]-xs[i]*(ys[ii]-ys[i])/(xs[ii]-xs[i])])
            include = Y *(yc-poly(xc))/abs(yc-poly(xc)) > poly(X) *(yc-poly(xc))/abs(yc-poly(xc))
        triangle*=include

    # Output: 2 arrays with the x- and y- coordinates of the points inside the
    # triangle.
    return X[triangle],Y[triangle]

在循环中解决了 3 个不等式,生成的布尔数组相乘后仅产生三角形内的点。

编辑: 循环可以写成更不言自明:

for i in range(3):
    ii=(i+1)%3
    if xs[i]==xs[ii]:
        if xc>xs:
            include = (X > xs[i])
        else:
            include = (X < xs[i])
    else:
        slope=(ys[ii]-ys[i])/(xs[ii]-xs[i])
        poly=np.poly1d([slope,ys[i]-xs[i]*slope])

        if yc>poly(xc):
            include = (Y > poly(X))
        else:
            include = (Y < poly(X))
    triangle*=include

【讨论】:

    猜你喜欢
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 2019-05-12
    • 2013-09-22
    • 2014-03-05
    • 1970-01-01
    相关资源
    最近更新 更多