我正在尝试在 C++ 上移植 1D perlin 噪声教程
I'm trying to port a 1D perlin noise tutorial on C++
我正在尝试使用 SFMl lib 在 C++ 上移植一维柏林噪声教程:(javascript 中的教程 link)https://codepen.io/Tobsta/post/procedural-generation-part-1-1d-perlin-noise
但是这不起作用,我没有收到任何错误,但这就是我得到的:https://i.imgur.com/2tAPhsH.png。
基本上是一条直线
这就是我应该得到的:https://i.imgur.com/GPnfsuK.png
这是上面 link 的移植代码:
TerrainBorder 构造函数:
TerrainBorder::TerrainBorder(sf::RenderWindow &window) {
M = 4294967296;
A = 1664525;
C = 1;
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> dist(0, M);
Z = floor(dist(rng) * M);
x = 0;
y = window.getSize().y / 2.0f;
amp = 100;
wl = 100;
fq = 1.0f / wl;
a = rand();
b = rand();
ar = sf::VertexArray(sf::Points);
}
函数:
double TerrainBorder::rand()
{
Z = (A * Z + C) % M;
return Z / M - 0.5;
}
double TerrainBorder::interpolate(double pa, double pb , double px) {
double ft = px * PI,
f = (1 - cos(ft)) * 0.5;
return pa * (1 - f) + pb * f;
}
void TerrainBorder::drawPoints(sf::RenderWindow &window) {
while (x < window.getSize().x) {
if (static_cast<int> (x) % wl == 0) {
a = b;
b = rand();
y = window.getSize().y / 2 + a * amp;
} else {
y = window.getSize().y / 2 + interpolate(a, b, static_cast<int> (x)
% wl / wl) * amp;
}
ar.append(sf::Vertex(sf::Vector2f(x, y)));
x += 1;
}
}
然后我正在绘制 sf::VectorArray
(其中包含游戏循环中的所有 sf::Vertex
C++ 需要仔细选择数值变量的类型,以避免溢出和意外转换。
OP 问题中显示的代码段未指定 M
、A
和 Z
的类型,但使用了 的 std::uniform_int_distribution
int,而 M
在大多数实现中使用超出 int
范围的值进行初始化。
还值得注意的是,标准库已经提供了 std::linear_congruential_engine
:
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 rng(rd());
// Calculate the first value
constexpr std::size_t M = 4294967296;
std::uniform_int_distribution<std::size_t> ui_dist(0, M);
std::size_t Z = ui_dist(rng);
// Initialize the engine
static std::linear_congruential_engine<std::size_t, 1664525, 1, M> lcg_dist(Z);
// Generate the values
for (int i = 0; i < 10; ++i)
{
Z = lcg_dist();
std::cout << Z / double(M) << '\n'; // <- To avoid an integer division
}
}
无论如何我都解决了我的问题:)
我不得不处理类型问题 :p
我想通了:
double c = x % 100 / 100;
std::cout << c << std::endl; // 0
!=
double c = x % 100;
std::cout << c / 100 << std::endl; // Some numbers depending on x
如果以后对大家有帮助的话:)
我正在尝试使用 SFMl lib 在 C++ 上移植一维柏林噪声教程:(javascript 中的教程 link)https://codepen.io/Tobsta/post/procedural-generation-part-1-1d-perlin-noise
但是这不起作用,我没有收到任何错误,但这就是我得到的:https://i.imgur.com/2tAPhsH.png。 基本上是一条直线
这就是我应该得到的:https://i.imgur.com/GPnfsuK.png
这是上面 link 的移植代码:
TerrainBorder 构造函数:
TerrainBorder::TerrainBorder(sf::RenderWindow &window) {
M = 4294967296;
A = 1664525;
C = 1;
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<int> dist(0, M);
Z = floor(dist(rng) * M);
x = 0;
y = window.getSize().y / 2.0f;
amp = 100;
wl = 100;
fq = 1.0f / wl;
a = rand();
b = rand();
ar = sf::VertexArray(sf::Points);
}
函数:
double TerrainBorder::rand()
{
Z = (A * Z + C) % M;
return Z / M - 0.5;
}
double TerrainBorder::interpolate(double pa, double pb , double px) {
double ft = px * PI,
f = (1 - cos(ft)) * 0.5;
return pa * (1 - f) + pb * f;
}
void TerrainBorder::drawPoints(sf::RenderWindow &window) {
while (x < window.getSize().x) {
if (static_cast<int> (x) % wl == 0) {
a = b;
b = rand();
y = window.getSize().y / 2 + a * amp;
} else {
y = window.getSize().y / 2 + interpolate(a, b, static_cast<int> (x)
% wl / wl) * amp;
}
ar.append(sf::Vertex(sf::Vector2f(x, y)));
x += 1;
}
}
然后我正在绘制 sf::VectorArray
(其中包含游戏循环中的所有 sf::Vertex
C++ 需要仔细选择数值变量的类型,以避免溢出和意外转换。
OP 问题中显示的代码段未指定 M
、A
和 Z
的类型,但使用了 的 std::uniform_int_distribution
int,而 M
在大多数实现中使用超出 int
范围的值进行初始化。
还值得注意的是,标准库已经提供了 std::linear_congruential_engine
:
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 rng(rd());
// Calculate the first value
constexpr std::size_t M = 4294967296;
std::uniform_int_distribution<std::size_t> ui_dist(0, M);
std::size_t Z = ui_dist(rng);
// Initialize the engine
static std::linear_congruential_engine<std::size_t, 1664525, 1, M> lcg_dist(Z);
// Generate the values
for (int i = 0; i < 10; ++i)
{
Z = lcg_dist();
std::cout << Z / double(M) << '\n'; // <- To avoid an integer division
}
}
无论如何我都解决了我的问题:) 我不得不处理类型问题 :p
我想通了:
double c = x % 100 / 100;
std::cout << c << std::endl; // 0
!=
double c = x % 100;
std::cout << c / 100 << std::endl; // Some numbers depending on x
如果以后对大家有帮助的话:)