Perlin noise: Difference between revisions
Content added Content deleted
(→{{header|Evaldraw}}: moved image) |
(New post.) |
||
Line 214: | Line 214: | ||
C:\rosettaCode>perlin.exe perlinData.txt 3.14 42 7 |
C:\rosettaCode>perlin.exe perlinData.txt 3.14 42 7 |
||
Perlin Noise for (3.14,42,7) is 0.13691995878400012 |
Perlin Noise for (3.14,42,7) is 0.13691995878400012 |
||
</pre> |
|||
=={{header|C++}}== |
|||
<syntaxhighlight> |
|||
#include <cmath> |
|||
#include <cstdint> |
|||
#include <fstream> |
|||
#include <iomanip> |
|||
#include <iostream> |
|||
#include <sstream> |
|||
#include <string> |
|||
#include <vector> |
|||
std::vector<int32_t> p(512, 0); |
|||
double fade(const double& t) { |
|||
return t * t * t * ( t * ( t * 6 - 15 ) + 10 ); |
|||
} |
|||
double lerp(const double& t, const double& a, const double& b) { |
|||
return a + t * ( b - a ); |
|||
} |
|||
double grad(const int32_t& hash, const double& x, const double& y, const double& z) { |
|||
const int32_t h = hash & 15; // CONVERT LOW 4 BITS OF HASH CODE |
|||
const double u = h < 8 ? x : y; // INTO 12 GRADIENT DIRECTIONS. |
|||
const double v = h < 4 ? y : ( h == 12 || h == 14 ) ? x : z; |
|||
return ( ( h & 1 ) == 0 ? u : -u ) + ( ( h & 2 ) == 0 ? v : -v ); |
|||
} |
|||
double perlin_noise(double x, double y, double z) { |
|||
int32_t X = static_cast<int32_t>(floor(x)) & 0xff; // FIND UNIT CUBE THAT |
|||
int32_t Y = static_cast<int32_t>(floor(y)) & 0xff; // CONTAINS POINT. |
|||
int32_t Z = static_cast<int32_t>(floor(z)) & 0xff; |
|||
x -= floor(x); // FIND RELATIVE X,Y,Z |
|||
y -= floor(y); // OF POINT IN CUBE. |
|||
z -= floor(z); |
|||
const double u = fade(x); // COMPUTE FADE CURVES |
|||
const double v = fade(y); // FOR EACH OF X,Y,Z. |
|||
const double w = fade(z); |
|||
const int32_t A = p[X ] + Y; |
|||
const int32_t AA = p[A ] + Z; |
|||
const int32_t AB = p[A + 1] + Z; // HASH COORDINATES OF |
|||
const int32_t B = p[X + 1] + Y; |
|||
const int32_t BA = p[B ] + Z; |
|||
const int32_t BB = p[B + 1] + Z; // THE 8 CUBE CORNERS, |
|||
return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), // AND ADD |
|||
grad(p[BA ], x - 1, y , z )), // BLENDED |
|||
lerp(u, grad(p[AB ], x , y - 1, z ), // RESULTS |
|||
grad(p[BB ], x - 1, y - 1, z ))),// FROM 8 |
|||
lerp(v, lerp(u, grad(p[AA + 1], x , y , z - 1), // CORNERS |
|||
grad(p[BA + 1], x - 1, y , z - 1)), // OF CUBE |
|||
lerp(u, grad(p[AB + 1], x , y - 1, z - 1), |
|||
grad(p[BB + 1], x - 1, y - 1, z - 1)))); |
|||
} |
|||
void read_file(const std::string& file_name) { |
|||
std::ifstream file("../" + file_name); |
|||
if ( file.is_open() ) { |
|||
int32_t index = 0; |
|||
std::string line; |
|||
while( std::getline(file, line) ) { |
|||
std::istringstream stream(line); |
|||
std::string word; |
|||
while ( std::getline(stream, word, ',') ) { |
|||
const int32_t number = std::stoi(word); |
|||
p[index] = number; |
|||
p[256 + index] = number; |
|||
index++; |
|||
} |
|||
} |
|||
} else { |
|||
std::cout << "Cannot open file" << std::endl; |
|||
} |
|||
} |
|||
int main() { |
|||
read_file("permutation.txt"); |
|||
std::cout << "Perlin noise applied to (3.14, 42.0, 7.0) gives " << std::setprecision(16) |
|||
<<perlin_noise(3.14, 42.0, 7.0) << std::endl; |
|||
} |
|||
</syntaxhighlight> |
|||
{{ out }} |
|||
<pre> |
|||
Perlin noise applied to (3.14, 42.0, 7.0) gives 0.1369199587840001 |
|||
</pre> |
</pre> |
||