如何在 3D 空间中生成随机点? [英] How do I generate random points in 3D space?

查看:44
本文介绍了如何在 3D 空间中生成随机点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到的最大问题是我没有词汇来描述我所追求的东西,所以如果不出意外,我们将不胜感激.

The biggest problem I am having is that I do not have the vocabulary to describe what I am after so if nothing else, some help with that would be much appreciated.

据我所知,Perlin 噪声可以为 3D 空间中的一个点提供一个随机值,此外,任何附近的点都将具有相似的值.当随机值超过某个阈值时,我在一个程序中使用它来生成漂浮在空间中的 3D 斑点.这很有效,因为我可以选择任何点,而不必担心之前计算过哪些点,确定它的值(如果我愿意,可以线程化 blob 生成).

From what I understand, Perlin noise can give you a random value for a point in 3D space and in addition any nearby points will have values that are similar. I have this working in a program to generate 3D blobs floating in space when the random value passes a certain threshold. This works well because I can pick any point, and without worrying about what points were calculated before, determine its value (could thread the blob generation if I wanted).

我现在想做一些类似的事情,除了,如果随机值超过某个阈值,我想更改 blob 上那个点的颜色.但是,我希望这是随机的并且与其邻居无关(与柏林噪声不同).

I now want to do something similar except, I want to change the color of that point on the blob if the random value passes a certain threshold. However I want this to be random and unrelated to its neighbors (unlike Perlin noise).

我需要什么样的算法来实现这一点?

What kind of algorithm am I looking for to accomplish this?

关键标准:

  1. 该函数将一个 3D 矢量作为参数.
  2. 点与点之间的值完全无关.
  3. 顺序检查点不影响函数的结果.
  4. 如果将相同的点传递给该函数,则该函数返回相同的结果.

结果

所以我决定使用类似于 Kahler 的答案的方法,并进行一些非常小的调整.我不想使用重复实例化甚至只是重复播种随机数生成器所使用的所有重定向和操作.我最终复制了 UE4 RandomStream 类中使用的随机数生成器,使其符合我的需要.我确信这个生成器不是他们一个人的,因为使用的数字似乎出现在其他地方,但我就是在那里找到的.

So I decided to use an approach similar to the answer by Kahler with some very small tweaks. I didn't want to use all the redirection and operations used by repeatedly instantiating or even just repeatedly seeding a random number generator. I ended up copying the random number generator used in the UE4 RandomStream class and making it fit my needs. I'm sure this generator is not theirs alone, as the numbers used seem to appear in other places, but that is where I found it.

float WhiteNoise::GetNoise3D(const FVector& vector) const
{
    int32 s1 = seed;
    int32 s2 = ((s1 + FMath::TruncToInt(vector.X)) * 196314165) + 907633515;
    int32 s3 = ((s2 + FMath::TruncToInt(vector.Y)) * 196314165) + 907633515;
    int32 s4 = ((s3 + FMath::TruncToInt(vector.Z)) * 196314165) + 907633515;

    const float tmp = 1.0f;

    float result;

    *(int32*)&result = (*(int32*)&tmp & 0xff800000) | (s4 & 0x007fffff);

     return FMath::Fractional(result);
}

上面的代码有一些明显的问题.一个是数字不是很随机,另一个是导致粒度问题的截断.在我的情况下,这两者都是完全可以接受的,因此效果相当好.

There are some obvious issues with the above code. One being that the numbers are not very random and the other being the truncation causing a granularity issue. Both of those are totally acceptable in my situation so this works reasonably well.

推荐答案

如果函数每次传入相同的参数都返回相同的数字,则它不是随机函数.要在不保存每个点的确切结果的情况下获得明显随机的模式,您可以使用随机生成器,其种子取决于位置.

If the function returns the same number each time the same parameter is passed in, it's not a random function. To get an apparently random pattern without saving the exact result of each point, you can use a random generator with seed dependent on position.

类似的东西

value_t get_value(coord_t x, coord_t  y, coord_t z)
{
    seed_t seed = some_equation(x,y,z);
    return generate_random_with_seed(seed);
}

C++ 现在有 <random> 库,你必须调整方程以获得满意的结果.每次种子重复时它们都会重复,具有明显的随机模式,每次调用.一种可能的种子生成器将所有可能的离散可能性散布到种子的类型上,因为相等的种子意味着相等的结果.

C++ now has the <random> library, you will have to tune the equation to give satisfactory results.And they will be repeated each time the seed repeats, with apparent random pattern, every call. One possible seed generator is spreading all possible discrete possibilities over the type of the seed, as equals seeds means equal results.

(所以一个 256x256x256 的网格可以使用种子 (x*256*256 + y*256 + z)

(so a 256x256x256 grid could use the seed (x*256*256 + y*256 + z)

这个策略实际上将一个有序集合映射到一个明显无序的集合.输出将通过对种子的随机生成器操作与位置相关.

This strategy actually maps an ordered set to an apparently unordered set. The output will be related to the position by the random generator operation on the seed.

由于对唯一种子的要求可能变得非常繁琐,您还可以通过将您的卷分成较小的种子来获得可重复的结果,每个由 N 点组成,并且整个块共享相同的唯一种子,第 i 元素的随机值是带有块种子的随机生成器的 i 次运行.

As the requirements for unique seeds can become quite cumbersome, you can also get repeatable results by spliting your volume on smaller ones, each consisted of N-points, and the whole chunk share the same unique seed, the random value of the i-th element is the i-th run of the random generator with the chunk seed.

这会将唯一种子的需求减少 N 倍,但将平均检索操作增加 (N-1)/2 倍.

This will reduce the requirement of unique seeds by a factor of N, but increase the average retrieve operations by a factor of (N-1)/2.

不久前,我尝试了几个 <random> 分布,这里有一些显示~图形~输出的代码(注释是葡萄牙语,但代码很简单).

A while ago, I've tried several of the <random> distributions, here's some code that shows ~graphical~ output (the comments are in portuguese, but the code is simple).

您可能需要一个均匀随机变量作为阈值,这里是uniform_int_distribution 的在线参考.

You probably will want an uniformly random variable for the threshold, here's an online reference to uniform_int_distribution.

这篇关于如何在 3D 空间中生成随机点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆