C++中叠加图形生成1D分形噪声的实现难题
1D分形噪声叠加实现修正
你的核心问题是:当前代码只是把不同频率的噪声点数组追加拼接,但分形噪声的本质是对同一个X坐标的不同层级噪声值进行加权叠加,而非简单拼接点集。
修正思路
- 提前确定最终要生成的噪声点数量(比如你指定的1000个),预先生成所有目标X坐标,初始化Y值为0。
- 对每一次迭代的噪声层级,针对每个目标X坐标,计算该频率下的噪声值,乘以对应振幅后叠加到结果的Y值上。
- 最终得到的数组就是叠加后的分形噪声点集,直接用于渲染。
修改后的代码
void fractalNoise() { std::vector<sf::Vector2f> result; const int totalPoints = 1000; const float xStep = 1.0f; // 可根据你的渲染需求调整X轴步长 // 初始化结果数组,生成所有目标X坐标,Y初始为0 result.reserve(totalPoints); for (int i = 0; i < totalPoints; i++) { result.emplace_back(i * xStep, 0.0f); } float persistance = 0.8f; int iterations = 10; for (int i = 0; i < iterations; i++) { float frequency = pow(2, i); float amplitude = pow(persistance, i); float scale = 300.0f; // 控制噪声Y轴的整体缩放 // 对每个目标X点,叠加当前层级的噪声 for (int j = 0; j < totalPoints; j++) { float x = result[j].x; // 按指定X值采样插值后的噪声 float noiseValue = this->sampleNoise(x * frequency, 3); // 加权叠加到结果Y值上 result[j].y += noiseValue * amplitude * scale; } } this->noiseGenerated = result; } // 按指定X值采样插值后的噪声(基于原有interpolateNoise逻辑改造) float sampleNoise(float x, int interpolationMethod) { float floorX = floor(x); float fracX = x - floorX; // 获取相邻整数坐标的随机噪声值 float val1 = getRandomNoiseValue(static_cast<int>(floorX)); float val2 = getRandomNoiseValue(static_cast<int>(floorX) + 1); // 应用指定插值方法 if (interpolationMethod == 3) { // 余弦插值 fracX = (1 - cos(fracX * M_PI)) * 0.5f; } // 线性插值 return val1 + fracX * (val2 - val1); } // 根据整数坐标生成伪随机噪声值 float getRandomNoiseValue(int x) { // 简单哈希生成伪随机值,可替换为你原有的噪声生成逻辑 x = (x << 13) ^ x; return (1.0f - ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f); }
关键说明
- 原代码的
interpolateNoise是生成固定数量的点集,现在改造成按任意X值采样的sampleNoise函数,确保每个目标X坐标都能匹配到对应频率的噪声值。 - 频率的作用是缩放X轴:乘以频率后,相同的目标X范围会覆盖更多噪声控制点,实现细节层级的提升。
- 振幅的作用是加权:高频噪声的振幅随迭代次数衰减,保证底层大尺度噪声占主导,小尺度噪声仅做细节补充。
内容的提问来源于stack exchange,提问作者DGYLLEANN
相关产品推荐
相关产品推荐

