简体   繁体   English

余弦插值渲染为线性插值

[英]Cosine interpolation Rendering as Linear Interpolation

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我正在使用 C++ 进行编码并使用 SFML 进行渲染

My linear interpolation function is:我的线性插值 function 是:

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.其中a是插值点,b是插值点,randN是随机数。 for those unfamiliar with sfml, the vector2f is just a vector of two floats, which are the coordinates of the pixel to draw对于那些不熟悉 sfml 的人来说,vector2f 只是两个浮点数的向量,它们是要绘制的像素的坐标

My cosine interpolation function.我的余弦插值 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)我认为这里出了点问题,因为它似乎返回了线性插值 function 坐标,但是从我所见过的每一个资源中,数学都是正确的(我认为)

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从本教程中找到: https://web.archive.org/web/20160530124230/http://freespace.virgin.net/hugo.elias/models/m_perlin.htm

My function to draw the pixels is:我绘制像素的 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{};
    }

noiseSpots is a vector of each spot to interpolate between, and fidelity is the number of those spots. noiseSpots 是每个点的插值向量,保真度是这些点的数量。

I think I may need to put my cosine function call outside of the pixel drawing loop but am unsure how to implement this.我想我可能需要将余弦 function 调用放在像素绘图循环之外,但我不确定如何实现这一点。

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) PS:在任何人问之前,由于某种原因,std::next 无法访问我向量中的下一个元素,所以我使用这个解决方法,从 0 开始并增加每次迭代,这就是为什么会有那种丑陋的this->noiseSpots.at(a + 1)

An example of my linear interpolation as requested by molbdino: molbdino 要求的线性插值示例:

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编辑:好的,所以我已将其完全缩小到余弦插值 function,因为我可以通过用 randN 替换 1 个或多个 f 值来获得曲线,但我仍然不确定为什么我不能让该死的余弦插值工作

Ok so turns out I'm an idiot, LEARN FROM MY MISTAKE BEFORE YOU SPEND DAYS TRYING TO FIX THIS YOURSELF.好吧,事实证明我是个白痴,在你花几天时间试图自己解决这个问题之前,先从我的错误中学习。

DO NOT COSINE 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.如果你在 x 轴而不是 Y 轴上这样做,你会得到相反方向的余弦波。 If you do BOTH (like I was), the waves cancel out and you just get a straight line.如果你两者都做(就像我一样),波浪会抵消,你会得到一条直线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM