peachykeen의 대답을 읽고 인터넷에서 자신의 연구를 수행 한 결과 다음과 같은 해결책을 찾았습니다. 값의 범위를 사용 Perlin 노이즈 내 구현
[0.0 ... 1.0] 경로 노드가 가장 적합한 번개 값 통과 (더블) M/(더블) N받는 노드 M 대 펄린 노이즈 기능. 노드 N과 노드 N-1에 대해 동일한 값을 반환하려면 다음 식을 적용하면됩니다. F '(M) = ((M-N) * F (N) + 번개 경로 오프셋을 0에서 시작하고 끝내려면 경로를 계산 한 후 모든 번개 경로 오프셋에서 F '(0)을 뺄 필요가 있습니다.
각 경로 노드에 대한 오프셋을 계산하기 전에 낙뢰 오프셋 R을 계산하여 잡음 함수로 전달 된 값에 더할 수 있으므로 노드의 오프셋 O = F '(N + 아르 자형). 번개를 움직이게하려면 두 번개 경로를 계산해야합니다 (시작 프레임과 끝 프레임). 그런 다음 각 경로 정점을 시작 위치와 끝 위치 사이에서 찾아야합니다. 끝 프레임에 도달하면 끝 프레임이 시작 프레임이되고 새 끝 프레임이 계산됩니다. 3D 경로의 경우 각 경로 노드 N에 대해 두 개의 오프셋 벡터가 계산 될 수 있으며 두 개의 1D Perlin 노이즈 값으로 스케일되어 노드 위치가 시작에서 끝 프레임 위치까지 lerp됩니다 . 3D Perlin 노이즈를 처리하는 것보다 비용이 적게 들고 응용 프로그램에서 상당히 잘 작동합니다.
여기 참조 표준 1D 펄린 노이즈 (I는 전략 패턴 응용 프로그램에서 표준 또는 개선 펄린 노이즈를 사용할 수 있도록 개선 펄린 노이즈 기지로이를 사용하고 있기 때문에 몇 가지 물건 가상입니다 내 구현입니다.
헤더 파일 :
#ifndef __PERLIN_H
#define __PERLIN_H
class CPerlin {
private:
int m_randomize;
protected:
double m_amplitude;
double m_persistence;
int m_octaves;
public:
virtual void Setup (double amplitude, double persistence, int octaves, int randomize = -1);
double ComputeNoise (double x);
protected:
double LinearInterpolate (double a, double b, double x);
double CosineInterpolate (double a, double b, double x);
double CubicInterpolate (double v0, double v1, double v2, double v3, double x);
double Noise (int v);
double SmoothedNoise (int x);
virtual double InterpolatedNoise (double x);
};
#endif //__PERLIN_H
구현 :
를 코드뿐만 아니라) 여기를 게시하기위한 더 간결하게 다소 단순화 된
#include <math.h>
#include <stdlib.h>
#include "perlin.h"
#define INTERPOLATION_METHOD 1
#ifndef Pi
# define Pi 3.141592653589793240
#endif
inline double CPerlin::Noise (int n) {
n = (n << 13)^n;
return 1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff)/1073741824.0;
}
double CPerlin::LinearInterpolate (double a, double b, double x) {
return a * (1.0 - x) + b * x;
}
double CPerlin::CosineInterpolate (double a, double b, double x) {
double f = (1.0 - cos (x * Pi)) * 0.5;
return a * (1.0 - f) + b * f;
}
double CPerlin::CubicInterpolate (double v0, double v1, double v2, double v3, double x) {
double p = (v3 - v2) - (v0 - v1);
double x2 = x * x;
return v1 + (v2 - v0) * x + (v0 - v1 - p) * x2 + p * x2 * x;
}
double CPerlin::SmoothedNoise (int v) {
return Noise (v)/2 + Noise (v-1)/4 + Noise (v+1)/4;
}
int FastFloor (double v) { return (int) ((v < 0) ? v - 1 : v; }
double CPerlin::InterpolatedNoise (double v) {
int i = FastFloor (v);
double v1 = SmoothedNoise (i);
double v2 = SmoothedNoise (i + 1);
#if INTERPOLATION_METHOD == 2
double v0 = SmoothedNoise (i - 1);
double v3 = SmoothedNoise (i + 2);
return CubicInterpolate (v0, v1, v2, v3, v - i);
#elif INTERPOLATION_METHOD == 1
return CosineInterpolate (v1, v2, v - i);
#else
return LinearInterpolate (v1, v2, v - i);
#endif
}
double CPerlin::ComputeNoise (double v) {
double total = 0, amplitude = m_amplitude, frequency = 1.0;
v += m_randomize;
for (int i = 0; i < m_octaves; i++) {
total += InterpolatedNoise (v * frequency) * amplitude;
frequency *= 2.0;
amplitude *= m_persistence;
}
return total;
}
void CPerlin::Setup (double amplitude, double persistence, int octaves, int randomize) {
m_amplitude = (amplitude > 0.0) ? amplitude : 1.0;
m_persistence = (persistence > 0.0) ? persistence : 2.0/3.0;
m_octaves = (octaves > 0) ? octaves : 6;
m_randomize = (randomize < 0) ? (rand() * rand()) & 0xFFFF : randomize;
}
이 질문은 위대한 내용입니다. – sharptooth
http://www.noisemachine.com/talk1/23.html –