Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Cosine Interpolation Rendering as linear  (Read 1005 times)

0 Members and 1 Guest are viewing this topic.

DGYLLEANN

  • Newbie
  • *
  • Posts: 4
    • View Profile
Cosine Interpolation Rendering as linear
« on: August 31, 2022, 11:24:58 pm »
Hi Guys
Yesterday I made a post about help manually making a draw function to render my interpolation. I have got that working now however my cosine interpolation is rendering as linear. My linear one works fine, but my cosine one doesn't look any different.

here is my function for linear interpolation (which works correctly):
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);
}
A is the point to interpolate from, B is the point to interpolate to, and randN is obv random number

Here is my function for cosine interpolation:
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);
   
}
same variables as above :)

And here is my manual drawing function:

//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{};
    }

fidelity is the number of points, and noisespots is a vector of sf::Vector2f's that stores the coOrdinants of all points to interpolate between. I think the issue is with my draw function but I'm not sure what it could be. If you guys could give any help that would be much appreciated

an image is attached of each interpolation method. the red one is the "Cubic interpolation" and the white one is the linear

Edit: Ok after rigorous testing, the draw function is fine, but the cosine interpolation function seems to be outputting linear interpolation function coordinates. If I change one of the values of f in the return, I get curvy lines but they aren't cosine interpolation
« Last Edit: September 01, 2022, 06:37:47 am by DGYLLEANN »

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: Cosine Interpolation Rendering as linear
« Reply #1 on: September 01, 2022, 07:02:11 am »
Right now you are interpolating 1000 points in a straight line between each noiseSpot, which is going to cover the entire line since they look pretty close together, a cosine distribution won't be easy to see.

Did you want the lines between noiseSpots to be curved instead? For that you'd want linear interpolation for the x axis and cosine for the y.
this->graph.setPixel(linearInterpolate.x, coInterpolatedVec.y, sf::Color(255, 0, 0));

Edit: Or modify the function to do it, which would be better. Sorry, I'm tired. :)
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);
   
}
« Last Edit: September 01, 2022, 07:04:47 am by kojack »

DGYLLEANN

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Cosine Interpolation Rendering as linear
« Reply #2 on: September 01, 2022, 07:59:16 am »
Thanks Kojack, had just figured it out before I saw your post :)
Yeah my issue was that I was interpolating on both axis, rather than just the Y, and so the cosine waves were going in opposite directions, cancelling out and making a straight(linear) interpolation.
All sorted now, just had to change this
return sf::Vector2f(a.x * (1-f) + b.x * f,
        a.y * (1 - f) + b.y * f);

to this:
    return sf::Vector2f(a.x * (1-randN ) + b.x * randN ,
        a.y * (1 - f) + b.y * f);
but yeah thanks for help regardless.
Also I'm not interpolating between 1000 points, those 1000 points are the points being drawn between the two points i am interpolating between, to make a solid line. Ik using a random number to pick numbers between 0 and 1 isnt most efficient but I am not going to be ending up rendering these lines in future, it was just so I could see my cosine interpolation function was working.