peachykeen के उत्तर पढ़ने और इंटरनेट में कुछ (अधिक) स्वयं के शोध करने के बाद, मुझे मेरे लिए काम करने के लिए निम्नलिखित समाधान मिल गया है।
- पर्लिन शोर के अपने कार्यान्वयन के साथ
, के एक मूल्य रेंज का उपयोग कर [0.0 .. 1.0] बिजली पथ नोड्स सबसे अच्छा काम करते हैं, मूल्य पारित करने के लिए (डबल) एम/(डबल) एन नोड M के लिए पर्लिन शोर समारोह।
शोर फ़ंक्शन करने के लिए एफ 'नोड 0 और नोड एन -1 के लिए समान मान लौटाएं, निम्न सूत्र लागू किया जा सकता है: एफ' (एम) = ((एम - एन) * एफ (एन) + एन * एफ (एन - एम))/एम। बिजली पथ ऑफसेट शुरू करने और 0 के साथ समाप्त करने के लिए, आपको बस पथ की गणना करने के बाद सभी बिजली पथ ऑफसेट से एफ '(0) घटाएं।
प्रत्येक पथ नोड के लिए ऑफसेट कंप्यूटिंग से पहले बिजली पथ randomize करने के लिए, एक यादृच्छिक ऑफसेट आर गणना की जा सकती है और, मूल्यों शोर समारोह के लिए पारित करने के लिए जोड़ा है, ताकि एक नोड का ऑफ़सेट हे = एफ '(N + आर)। बिजली को एनिमेट करने के लिए, दो बिजली पथों को गणना (प्रारंभ और अंत फ्रेम) की आवश्यकता होती है, और फिर प्रत्येक पथ चरम को अपनी प्रारंभ और अंत स्थिति के बीच ले जाना पड़ता है। एक बार अंत फ्रेम तक पहुंचने के बाद, अंत फ्रेम प्रारंभ फ्रेम बन जाता है और एक नया अंत फ्रेम गणना की जाती है। 3 डी पथ के लिए, प्रत्येक पथ नोड एन के लिए दो ऑफ़सेट वैक्टरों की गणना की जा सकती है जो नोड एन और एक दूसरे पर पथ के लंबवत होते हैं, और दो 1 डी पर्लिन शोर मानों के साथ स्केल किए जा सकते हैं ताकि नोड स्थिति को प्रारंभ से अंत तक फ्रेम स्थिति में ले जाया जा सके। । यह 3 डी पर्लिन शोर करने से सस्ता हो सकता है और मेरे आवेदन में काफी अच्छा काम करता है।
यहाँ एक संदर्भ के रूप में मानक -1 डी पर्लिन शोर (कुछ सामान आभासी क्योंकि मैं पर्लिन शोर में सुधार के लिए आधार के रूप में इस का उपयोग कर रहा है, एक रणनीति पैटर्न आवेदन में मानक या सुधार पर्लिन शोर उपयोग करने की अनुमति है की मेरी कार्यान्वयन है। कोड कुछ सरल कर दिया गया है और साथ ही इसे और अधिक इसे यहाँ प्रकाशित करने) के लिए संक्षिप्त बनाने के लिए:
हैडर फ़ाइल:
#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 –