通过将三角形分成更小的部分来均匀采样三角形?

时间:2017-09-17 07:49:41

标签: random triangulation

要统一采样三角形ABC,我可以使用以下公式:

P =(1 - sqrt(r1))* A +(sqrt(r1)*(1 - r2))* B +(r2 * sqrt(r1))* C

其中r1和r2是0到1之间的随机数。你采取的样本越多越好。但是,如果我希望获得更好的分布,同时保持低样本数量呢?

例如,如果我有一个正方形,我可以隐式地将其划分为N x N网格,并在较小的网格正方形内生成随机样本。像这样:

float u = (x + rnd(seed)) / width;
float v = (y + rnd(seed)) / height;

重点是我强制采样以较低的样本分辨率覆盖整个网格。

如何用三角形实现这一目标?我能想到的唯一方法是使用类似Triangle的库将其明确细分为多个三角形。但有没有办法像广场一样隐式地做这个,而不必实际划分三角形?

2 个答案:

答案 0 :(得分:2)

好的,我有一些想法,并相信使用准随机数可以改善"均匀性"在没有细分为较小三角形的情况下,三角形中的点覆盖范围。使用Sobol序列的Quasirandom sampling可以提供更好的覆盖范围,如Wiki文章所示。

这是使用标准RNG的三角形中的200个点(无论它在Python中是什么) enter image description here

这是从Sobol 2D序列中采集200点的图片

enter image description here

对我来说看起来好多了。用于播放的Python代码

import os
import math
import random

import numpy as np
import matplotlib.pyplot as plt

import sobol_seq

def trisample(A, B, C, r1, r2):
    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)

if __name__ == "__main__":
    N = 200

    A = (0.0, 0.0)
    B = (1.0, 0.0)
    C = (0.5, 1.0)

    seed = 1
    xx = list()
    yy = list()
    random.seed(312345)
    for k in range(0, N):

        pts, seed = sobol_seq.i4_sobol(2, seed)
        r1 = pts[0]
        r2 = pts[1]

        # uncomment if you want standard rng
        #r1 = random.random()
        #r2 = random.random()

        pt = trisample(A, B, C, r1, r2)
        xx.append(pt[0])
        yy.append(pt[1])

    plt.scatter(xx,  yy)
    plt.show()

    sys.exit(0)

答案 1 :(得分:0)

我建议使用泊松磁盘采样(short academic paper link,  pretty visualization linkwiki linkcode link)在三角形的边界框内生成配置,然后裁剪到由三角形限定的区域。

我建议从简短的学术论文开始。这里的工作原理很容易理解。这个想法的很多变种在那里漂浮,所以要掌握它并找到适合你的那个。

Field generated with Poisson disk sampling