生成三角域内的随机位置

时间:2017-11-21 09:53:48

标签: python numpy random triangular

我希望生成具有统一分布的xy,并受[xmin,xmax][ymin,ymax]

的限制

点(x,y)应该在三角形内。

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:4)

这是一些在平面中的任意三角形上均匀生成点的代码。

import random

def point_on_triangle(pt1, pt2, pt3):
    """
    Random point on the triangle with vertices pt1, pt2 and pt3.
    """
    s, t = sorted([random.random(), random.random()])
    return (s * pt1[0] + (t-s)*pt2[0] + (1-t)*pt3[0],
            s * pt1[1] + (t-s)*pt2[1] + (1-t)*pt3[1])

这个想法是计算三个顶点的加权平均值,权重由单位间隔[0, 1]随机分解为三个部分(均匀地在所有这些间隔上)。

以下是在三角形中生成10000点的示例用法:

pt1 = (1, 1)
pt2 = (2, 4)
pt3 = (5, 2)
points = [point_on_triangle(pt1, pt2, pt3) for _ in range(10000)]

从上面得到的情节,证明了均匀性。该图由此代码生成:

import matplotlib.pyplot as plt
x, y = zip(*points)
plt.scatter(x, y, s=0.1)
plt.show()

这是图像:

enter image description here

由于您使用“numpy”标记标记了问题,因此这是一个NumPy版本,可以同时生成多个样本。请注意,它使用Python 3.5中引入的矩阵乘法运算符@,并在NumPy> = 1.10中受支持。您需要在较旧的Python或NumPy版本上调用np.dot来替换它。

import numpy as np

def points_on_triangle(v, n):
    """
    Give n random points uniformly on a triangle.

    The vertices of the triangle are given by the shape
    (2, 3) array *v*: one vertex per row.
    """
    x = np.sort(np.random.rand(2, n), axis=0)
    return np.column_stack([x[0], x[1]-x[0], 1.0-x[1]]) @ v


# Example usage
v = np.array([(1, 1), (2, 4), (5, 2)])
points = points_on_triangle(v, 10000)

答案 1 :(得分:1)

三角形上的制服?

import numpy as np

N = 10 # number of points to create in one go

rvs = np.random.random((N, 2)) # uniform on the unit square
# Now use the fact that the unit square is tiled by the two triangles
# 0 <= y <= x <= 1 and 0 <= x < y <= 1
# which are mapped onto each other (except for the diagonal which has
# probability 0) by swapping x and y.
# We use this map to send all points of the square to the same of the
# two triangles. Because the map preserves areas this will yield 
# uniformly distributed points.
rvs = np.where(rvs[:, 0, None]>rvs[:, 1, None], rvs, rvs[:, ::-1])

Finally, transform the coordinates
xmin, ymin, xmax, ymax = -0.1, 1.1, 2.0, 3.3
rvs = np.array((ymin, xmin)) + rvs*(ymax-ymin, xmax-xmin)

统一边际?最简单的解决方案是将质量均匀地集中在线上(ymin,xmin) - (ymax,xmax)

rvs = np.random.random((N,))
rvs = np.c_[ymin + (ymax-ymin)*rvs, xmin + (xmax-xmin)*rvs]

但这不是很有趣,是吗?

答案 2 :(得分:1)

好的,我想是时候添加另一个版本了。已知的算法可以在三角形中均匀采样,有关详细信息,请参阅paper,第4.2章。

Python代码:

import math
import random

import matplotlib.pyplot as plt

def trisample(A, B, C):
    """
    Given three vertices A, B, C, 
    sample point uniformly in the triangle
    """
    r1 = random.random()
    r2 = random.random()

    s1 = math.sqrt(r1)

    x = A[0] * (1.0 - s1) + B[0] * (1.0 - r2) * s1 + C[0] * r2 * s1
    y = A[1] * (1.0 - s1) + B[1] * (1.0 - r2) * s1 + C[1] * r2 * s1

    return (x, y)

random.seed(312345)
A = (1, 1)
B = (2, 4)
C = (5, 2)
points = [trisample(A, B, C) for _ in range(10000)]

xx, yy = zip(*points)
plt.scatter(xx, yy, s=0.2)
plt.show()

结果看起来像

enter image description here

答案 3 :(得分:0)

步骤(1):使用xr

[xmin, xmax]yr [ymin, ymax]中生成随机数[xr, yr]的坐标

步骤(2):如果SELECT * FROM `table name` ORDER BY `rate` ASC LIMIT 1 不在三角形内,则丢弃坐标并选择另一个随机坐标。如果点位于像三角形这样的凸多边形内部,则有不同的方法可以检查,例如:

  • 将三角形划分为三个子三角形并检查三个子三角形的面积是否与原始三角形相同
  • 如果随机坐标与三角形的第三个点位于平面的同一侧,则检查三角形的每一行
  • 使用重心坐标

后两种策略更详细地解释Python random function

还有更多方法,但即使数学背景很少,这三种方法也很容易在Python中实现。

P.S。:维基百科也链接到in this article,带有示例代码