Я пытаюсь портировать 1D Perlin шума учебник на переполнение стека

Я пытаюсь портировать 1D Perlin шума учебник на C ++ с использованием SFMl lib: (учебник ссылка в JavaScript) https://codepen.io/Tobsta/post/procedural-generation-part-1-1d-perlin-noise

Однако это не работает, я не получаю никакой ошибки, но это то, что я получаю: https://i.imgur.com/2tAPhsH.png .
в основном прямая линия

И вот что я должен получить: https://i.imgur.com/GPnfsuK.png

Вот перенесенный код по ссылке выше:

Конструктор 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 в игровом цикле

0

Решение

я все равно решил свою проблему ты за ответ 🙂
Мне приходилось сталкиваться с типами проблем: 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

Если это может помочь кому-нибудь в будущем 🙂

1

Другие решения

C ++ требует тщательного выбора типов числовых переменных, чтобы избежать переполнений и неожиданных преобразований.

Фрагмент, показанный в вопросе OP, не определяет типы M, A а также Z, но использует std::uniform_int_distribution из ИНТ, в то время как 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
}
}
0

По вопросам рекламы [email protected]