2

我需要八面体内的随机点,均匀分布。我将八面体定​​义为所有点满足abs(x) + abs(y) + abs(z) <= 1绝对值的体积。IE:六个顶点中的每一个都在一个轴上,距离 0,0,0 1。也许你可以称它为单位八面体。

考虑到定义,我可以天真地生成一个点,如下所示:

val x: Double = nextDouble() // 0-1 range
val y = nextDouble(1.0 -x) // 1-x is upper bound, probably <1
val z = nextDouble(1.0 -(x+y))

问题在于这倾向于较小的 y 值和较小的 z 值。显然不是均匀分布。同样清楚的是,所有这些点都在八个象限之一中。

我避免使用discard 方法,因为这个函数会被调用很多次,而且看起来我应该比丢掉大部分分数做得更好。

请注意,八面体的对偶是立方体。正因为如此,我有一个暗示,可能存在一个简单的函数来将立方体内的任何点转换为八面体内,但这只是我仍在探索的直觉。

4

2 回答 2

1

这是想法 - 来自 D+1 中狄利克雷分布的样本点,选择 D 点,这样你在单纯形中是均匀的

x 0 +x 1 +x 2 <= 1, x i >= 0

要制作八面体,请随机选择八分圆来说明您的观点。

Python 中的代码

import math
import random

def Dirichlet():
    """sample 4d Dirichlet"""
    x0 = -math.log(1.0 - random.random()) # exponential
    x1 = -math.log(1.0 - random.random()) # exponential
    x2 = -math.log(1.0 - random.random()) # exponential
    x3 = -math.log(1.0 - random.random()) # exponential
    s = 1.0/(x0+x1+x2+x3) # scaling

    return (x0*s, x1*s, x2*s, x3*s)

def OctahedronSampling():

    x0, x1, x2, _ = Dirichlet()

    octant = random.randint(0, 7)

    if octant == 0:
        return (x0, x1, x2)
    elif octant == 1:
        return (x0, -x1, x2)
    elif octant == 2:
        return (x0, x1, -x2)
    elif octant == 3:
        return (x0, -x1, -x2)
    elif octant == 4:
        return (-x0, x1, x2)
    elif octant == 5:
        return (-x0, -x1, x2)
    elif octant == 6:
        return (-x0, x1, -x2)
    elif octant == 7:
        return (-x0, -x1, -x2)

    return None

for _ in range(0, 2000):
    x0, x1, x2 = OctahedronSampling()

    print(f"{x0}   {x1}   {x2}")

这是带有 2K 点的快速图表

在此处输入图像描述

于 2019-11-07T03:07:37.967 回答
0

你知道如何在一个立方体中选择均匀分布的点,一个立方体可以被分解成八个方形金字塔。(对不起,我无法提供图形。)

我将从一个立方体开始:abs(x) <= 1; abs(y) <= 1; abs(z) <= 1

在其中选择一个点(列向量,(x, y, z)),然后反射以将其带入“顶部和底部”金字塔:

if abs(x) > abs(z), swap x and z. Equivalently, multiply by

0 0 1
0 1 0
1 0 0

if abs(y) > abs(z), swap y and z. Equivalently, multiply by 

1 0 0
0 0 1
0 1 0

然后将两个金字塔倒转形成一个八面体:

if z>0
 z = 1-z

if z<0
 z = -1-z

然后旋转和缩放:

multiply by

1/2 -1/2  0
1/2  1/2  0
  0    0  1
于 2019-11-07T23:34:04.127 回答