6

I need to make a picture box to lerp from position to position (like you can do that in unity).
How can I do that , is there a built-in function?
thanks :)

Paz Haviv
  • 137
  • 1
  • 1
  • 10
  • 1
    Please show what you have done in attempt to do this or some code that would help us to figure out what you are doing. – Elipzer Oct 09 '15 at 18:29
  • @Elipzer , I have no idea how to do so , for example in unity engine , you can call Vector2.Lerp / Vector3.Lerp / Mathf.Lerp. How can I do that with the microsoft libraries? or an idea how something like that will work – Paz Haviv Oct 09 '15 at 18:31
  • Try explaining the code that you know in your question. You may need to create your own class. – Elipzer Oct 09 '15 at 18:34
  • @Elipzer , there isnt a code I know , what I know is that in unity and in XNA you can call Vector2.Lerp(Vector2 from , Vector2 to , float weight); But im not using vectors – Paz Haviv Oct 09 '15 at 18:39

4 Answers4

16

Linear interpolation (lerp) is actually a pretty easy function to implement. The equation is

float Lerp(float firstFloat, float secondFloat, float by)
{
     return firstFloat * (1 - by) + secondFloat * by;
}

A higher order Lerp just wraps lower order lerps:

Vector2 Lerp(Vector2 firstVector, Vector2 secondVector, float by)
{
    float retX = Lerp(firstVector.x, secondVector.x, by);
    float retY = Lerp(firstVector.y, secondVector.y, by);
    return new Vector2(retX, retY);
}

The DirectX SDK has all manner of math functions like Unity, but that's a lot of overhead to bring in just for Lerp. You're probably best off just implementing your own.

Greg Bahm
  • 638
  • 6
  • 11
8

Greg Bahm wrote inverted lerp equation firstFloat * by + secondFloat * (1 - by), where firstFloat is the secondFloat and secondFloat is the firstFloat.

In fact, corrent lerp equation is:

firstFloat * (1 - by) + secondFloat * by

But the fastest way to linear interpolation is:

firstFloat + (secondFloat - firstFloat) * by

That's 2 additions/subtractions and 1 multiplication instead of 2 addition/subtractions and 2 multiplications. Lerp for Vector2 is correct.

Also, the fastest way is less precise (thank you, cid):

Imprecise method, which does not guarantee v = v1 when t = 1, due to floating-point arithmetic error. This method is monotonic
This form may be used when the hardware has a native fused multiply-add instruction. https://en.wikipedia.org/wiki/Linear_interpolation#Programming_language_support

Bodix
  • 404
  • 5
  • 7
  • 1
    The second implementation seems a lot simpler and cleaner. Thanks a lot! – Unknown Coder Aug 17 '18 at 15:51
  • I think the second implementation makes it less understandable, what is done. It may be mathematical correct and minimal. Considering a new user who is looking the first time on the code (or after some years have passed), most likely the first implementation is understood much faster. – FrankM Oct 09 '18 at 08:31
  • Caution, the fastest way is also apparently considered the less precise one: https://en.wikipedia.org/wiki/Linear_interpolation#Programming_language_support – cid Mar 18 '21 at 16:30
1

Try this instead

  float Lerp(float a, float b, float t)
    {
        //return firstFloat * by + secondFloat * (1 - by);
        return (1f - t) * a + t * b;
    }

    PointF Lerp(PointF a, PointF b, float t)
    {
        float retX = Lerp(a.X, b.X, t);
        float retY = Lerp(a.Y, b.Y, t);
        return new PointF(retX, retY);
    }
Nick Turner
  • 927
  • 1
  • 11
  • 21
1
    public static float CubicInterpolation(float v0, float v1, float v2, float v3, float t) {
        //var v01 = Lerp( v0, v1, t );
        //var v12 = Lerp( v1, v2, t );
        //var v23 = Lerp( v2, v3, t );
        //var v012 = Lerp( v01, v12, t );
        //var v123 = Lerp( v12, v23, t );
        //return Lerp( v012, v123, t );
        var p = (v3 - v2) - (v0 - v1);
        var q = (v0 - v1) - p;
        var r = v2 - v0;
        var s = v1;
        return (p * t * 3) + (q * t * 2) + (r * t) + s;
        //var r = 1f - t;
        //var f0 = r * r * r;
        //var f1 = r * r * t * 3;
        //var f2 = r * t * t * 3;
        //var f3 = t * t * t;
        //return (v0 * f0) + (v1 * f1) + (v2 * f2) + (v3 * f3);
    }
    public static float QuadraticInterpolation(float v0, float v1, float v2, float t) {
        var v01 = Lerp( v0, v1, t );
        var v12 = Lerp( v1, v2, t );
        return Lerp( v01, v12, t );
    }
    public static float Lerp(float v1, float v2, float t) {
        return v1 + ((v2 - v1) * t);
    }


    public static float CosInterpolation(float t) {
        t = (float) -Math.Cos( t * Math.PI ); // [-1, 1]
        return (t + 1) / 2; // [0, 1]
    }
    public static float PerlinSmoothStep(float t) {
        // Ken Perlin's version
        return t * t * t * ((t * ((6 * t) - 15)) + 10);
    }
    public static float SmoothStep(float t) {
        return t * t * (3 - (2 * t));
    }
Denis535
  • 3,407
  • 4
  • 25
  • 36