我最近一直在尝试在C中实现Perlin Noise生成器(基于Ken Perlin的网站,使用SDL库作为屏幕输出),但输出显示插值块之间的边缘不连续或平滑 - 插值块真的表现为块.
我尝试了四种插值,所有"平滑"插值看起来都差不多; 只有余弦看起来(非常)略微更好,直线性看起来比较可怕.(以下是余弦和线性)

具有讽刺意味的是,如果制作一个分形噪声和(我的最终目的),线性会以"块状"的方式吹走平滑插值,实际上看起来几乎没问题.

我很确定我的代码中缺少某些东西或做错了,但我似乎无法找到它.
作为参考,我目前的代码如下:
#include<stdio.h>
#include<math.h>
#include<SDL/SDL.h>
void normalize3(float *vec3){
float distX=0,distY=0,distZ=0;
distX=vec3[0];
distX*=distX;
distY=vec3[1];
distY*=distY;
distZ=vec3[2];
distZ*=distZ;
float dist=sqrtf(distX+distY+distZ);
vec3[0]/=dist;
vec3[1]/=dist;
vec3[2]/=dist;
}
float sinterpolate(float scale){
//return scale*scale*(3.0-2*scale); //Classic 3*t^2-2*t^3
/*float t=scale*scale;
float u=t*t;
return (6.0*u*scale-15.0*u+10.0*t*scale);*/ //Improved 6*t^5-15*t^4+10*t^3
return (0.5-cosf(scale*M_PI)/2.0); //Straight cosine interpolation
}
float linterpolate(float a,float b,float scale){
return a+scale*(b-a);
}
float noise3(float *vec3,float *grads,Uint8 *perms){
vec3[0]=fmodf(vec3[0],256.0);
vec3[1]=fmodf(vec3[1],256.0);
vec3[2]=fmodf(vec3[2],256.0);
Uint8 ivec3[3];
float relPos[3],temp;
float cube[2][2][2];
Uint8 index;
//One loop …Run Code Online (Sandbox Code Playgroud) 我知道这个问题已经一次又一次地以多种不同的形式得到了回答,也许是C++设计中最令人困惑的问题之一,但是我在多年后在纯C中做很多事情时都试着学习这种语言.在C++世界中非常违法(想想函数指针杂耍).在放弃和使用另一种语言之前,我想尝试自学C++思维模式.
我刚刚开始了一个项目,其中最基本的组件是流类,为此我希望它是通用的:它将流式传输到它的子类的数据类型.
template <typename T>
class BasicStream {
protected:
T *buffer;
unsigned int bufferSize;
unsigned int bufferPos;
bool streamEnd=false;
public:
virtual T read();
};
Run Code Online (Sandbox Code Playgroud)
我的想法是将对象链接在一起,就像某个类的一个对象的输出被另一个类的另一个对象直接读取一样.但为了使其工作,所有对象必须能够接受泛型read()函数并返回其所需类型.例如,我有一个类来拼接接受字节(unsigned char)作为输入的位:
class BitExtractor : public BasicStream<bool> {
private:
unsigned char bitMask;
unsigned char byte;
BasicStream<unsigned char> &byteSource;
public:
BitExtractor(BasicStream<unsigned char> &source);
virtual bool read();
};
Run Code Online (Sandbox Code Playgroud)
它返回一个bool类型,需要任何派生自BasicStream并具有<unsigned char>返回类型作为输入的类.我的想法是使输入与数据源完全无关; 无论是文件,互联网流,还是记忆中的某些位置; 所有包裹来自的类BasicStream<unsigned char>.
一个例子是一个FileReader类,用于处理/同步文件加载:
class FileReader : public BasicStream<unsigned char> {
protected:
FILE *file;
bool asyncFlag; …Run Code Online (Sandbox Code Playgroud)