I am trying to create different interpolation methods between points. So far I have got Linear interpolation Down, but my Cosine interpolation seems to be rendering as linear, so I have something very wrong. I am using C++ to code and SFML to render
My linear interpolation function is:
sf::Vector2f game::linearInterpolate(sf::Vector2f a, sf::Vector2f b, float randN) {
return sf::Vector2f(a.x * (1 - randN) + b.x * randN,
a.y * (1 - randN) + b.y * randN);
}
where a is the point to interpolate from and b is the point to interpolate to, and randN is a random number. for those unfamiliar with sfml, the vector2f is just a vector of two floats, which are the coordinates of the pixel to draw
My cosine interpolation function. I think something is wrong here, as it seems to be returning linear interpolation function coordinates, but the math is correct from every resource I have seen(I think)
sf::Vector2f game::cosineInterpolate(sf::Vector2f a, sf::Vector2f b, float randN) {
float ft = randN * 3.1415927f;
float f = (1 - cos(ft)) * 0.5f;
return sf::Vector2f(a.x * (1-f) + b.x * f,
a.y * (1 - f) + b.y * f);
}
which was found from this tutorial: https://web.archive.org/web/20160530124230/http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
My function to draw the pixels is:
//For each point to interpolate between:
for (sf::Vector2f &l : this->noiseSpots) {
//How many pixels between each point:
for (unsigned long xScreen = 0; xScreen < 1000; xScreen++) {
//random number between 0 and one
float r = this->rand01();
//calculate points to draw
sf::Vector2f lInterpolatedVec = linearInterpolate(l, this->noiseSpots.at(a + 1), r);
sf::Vector2f coInterpolatedVec = cosineInterpolate(l, this->noiseSpots.at(a + 1), r);
//draw linear interpolated graph
this->graph.setPixel(lInterpolatedVec.x, lInterpolatedVec.y, sf::Color(255, 255, 255));
//draw cosine interpolated graph
this->graph.setPixel(coInterpolatedVec.x, coInterpolatedVec.y, sf::Color(255, 0, 0));
}
if (a < fidelity-1) { a++; }else{};
}
noiseSpots is a vector of each spot to interpolate between, and fidelity is the number of those spots.
I think I may need to put my cosine function call outside of the pixel drawing loop but am unsure how to implement this.
PS: before anyone asks, for some reason std::next is not working to access my next element in my vector, so I am using this workaround with a starting out as 0 and increasing each iteration which is why there is that sorta ugly this->noiseSpots.at(a + 1)
An example of my linear interpolation as requested by molbdino:
And an example of my "Cosine" interpolation:
Edit: Ok so I have fully narrowed it down to the cosine interpolation function, as I can get curved lines by replacing 1 or more of the f values with randN, but I still am unsure why I cant get the damn cosine interpolation working
Ok so turns out I'm an idiot, LEARN FROM MY MISTAKE BEFORE YOU SPEND DAYS TRYING TO FIX THIS YOURSELF.
DO NOT INTERPOLATE ON BOTH AXIS:
sf::Vector2f game::cosineInterpolate(sf::Vector2f a, sf::Vector2f b, float randN) {
float ft = randN * 3.1415927f;
float f = (1 - cos(ft)) * 0.5f;
return sf::Vector2f(a.x * (1-f) + b.x * f,
a.y * (1 - f) + b.y * f);
}
Should be:
sf::Vector2f game::cosineInterpolate(sf::Vector2f a, sf::Vector2f b, float randN) {
float ft = randN * 3.1415927f;
float f = (1 - cos(ft)) * 0.5f;
return sf::Vector2f(a.x * (1-randN) + b.x * randN,
a.y * (1 - f) + b.y * f);
}
if you do that on the x axis not the Y you get cosine waves in the opposite direction. If you do BOTH (like I was), the waves cancel out and you just get a straight line.