• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Snippet] Interpolation Functions

I have shared with many these functions, but I had never posted them officially:

Overview:


Interpolation functions are used to draw curves and lines on n-dimensional spaces. They are quite useful to achieve certain effects at low performance cost and low knowledge of mathematical functions.

Background for understanding.
Most of these functions are composed by 2 or more point values and a position value(t or s).
What these function basicly do is get points from known points.

For example, let's say you have points P1(0,8) and P2(4,16) and you want to interpolate linearly between these 2 points.

Let's make our new point, PM, stands for 'Middle Point'. So PM = (Linear(P1.x,P2.x,0.5),Linear(P1.y,P2.y,0.5)) if we compute this we get.
Code:
PM.x = 0 + (4-0)*0.5
PM.y = 8 + (16-8)*0.5
//After we compute we get:
//PM(2,12) which is the middle point.

If you want a better understanding, download the Test Map. It's better documented and has a clean and short code.


JASS:
library Interpolation
    function Linear takes real a, real b, real t returns real
         return a + (b-a)*t
    endfunction

// Bezier Interpolation: Bezier_[Point_number]

    function Bezier_3 takes real a, real b, real c, real t returns real
         return a + 2.*(b-a)*t + (c -2.*b + a)*t*t
    endfunction //Uses 3 points

    //This function returns the derivate of the bezier curve on certain point.
    function DerivBezier_3 takes real a,real b, real c, real t returns real
        return 2.*(b-a) + 2.*(c-2.*b+a)*t //This function is d(Bezier_3())/dt
    endfunction
    
    function Bezier_4 takes real a, real b, real c, real d, real t returns real
    local real m = t*t
        return  a + 3.*t*(b - a) + 3.*m*(c - 2.*b + a) + m*t*(3.*(b-c) + d - a)
    endfunction //Uses 4 points
    
    function DerivBezier_4 takes real a,real b, real c, real d, real t returns real
        return 3.*(b-a) + 6.*(c-2.*b+a)*t + 3.*(3.*(b-c) + d -a)*t*t
    endfunction
    
    //This function returns the angle in radians of the facing of the missile tangent to the curve.
    //I suggest you to look at Test4 to understand it's use.
    //To compute dy you must use DerivBezier3 or 4 on the Y axi, same for dx but in the X axi.
    function AxiAngle takes real dy, real dx returns real
        return Atan2(dy,dx)
    endfunction
    
//You can use Bezier 3 to graphic perfect parabols

//Bezier_4(<Start Point>, <OutTan_of_StartPoint>, <InTan_of_EndPoint>, <EndPoint>)

    //Hermite Interpolation
    function Hermite takes real p1, real p2, real t1, real t2, real s returns real
        local real s2 = s*s
        local real h1 = 8.0*s*s2 - 9.0*s2
        local real h2 = h1*(-1)
        local real h3 = s2*(s - 2.0) + s
        local real h4 = s2*(s - 1.0)
        set h1 = h1 + 1
        return h1*p1 + h2*p2 + h3*t1 + h4*t2
    endfunction
//Hermite(<StartPoint>,<EndPoint>,<Tangent1>,<Tangent2>)

    function GetCardTan takes real p1, real p3 returns real
       return 0.5*(p3-p1)
    endfunction

// TCB functions for finding the tangents among 3 points
// Most modellers may know TCB from 3dsmax, in which they are used to make rotations
// look very smooth.
// t = tension, c = continuity, b = bias
// tension is how sharply the curve makes turns.
// continuity specifies the rate of change between speed and direction.
// bias specifies the direction of the curve.
// sidenote: specify p1 as 0, when working with 2 points.

// the next function returns the intan of p2

    function InTan takes real p1, real p2, real p3, real t, real c, real b returns real
           return (1.0-t)*(1.0-c)*(1.0+b)*(p2-p1)/2. + (1.0-t)*(1.0+c)*(1.0-b)*(p3-p2)/2.
    endfunction

// the next function returns the outtan of p2

    function OutTan takes real p1, real p2, real p3, real t, real c, real b returns real
           return (1.0-t)*(1.0+c)*(1.0+b)*(p2-p1)/2. + (1.0-t)*(1.0-c)*(1.0-b)*(p3-p2)/2.
    endfunction

endlibrary



JASS:
library Interpolation {

    define {
        //For forced inlining.
        In_Linear(a,b,t) = (a + (b - a) * t);
        In_LinearA(a,m) = a + m;
        //m is a precomputed (b-a)*t
        //use this for constant velocities just keep adding the same value over and over
        //note a is not the startpoint but the current point
        In_Bezier3(a,b,c,t) = a + 2.*(b-a)*t + (c -2.*b + a)*t*t;
        In_Bezier3A(a,m,p,t) = a + m + p*t;
        ///////////////////////////////////////////////////////////
        In_Bezier4(a,b,c,d,t) = a + 3.*t*(b - a) + 3.*t*t*(c - 2.*b + a) + Pow(t,3.)*(3.*(b-c) + d - a);
        //again for precomputing.
        In_AxiAngle(dy,dx) = Atan2(dy,dx);
        In_AxiAngleA(dy,dx) = Atan2(dy,dx)*57.29577; //makes it into degrees
    }
    
    float Linear(float a, float b, float t) {
        return a + (b-a)*t;
    }

// Bezier Interpolation: Bezier_[Point_number]

    float Bezier_3(float a, float b, float c, float t) {
        return a + 2.*(b-a)*t + (c -2.*b + a)*t*t;
    } //Uses 3 points

    //This function returns the derivate of the bezier curve on certain point.
    float DerivBezier_3(float a,float b, float c, float t) {
        return 2.*(b-a) + 2.*(c-2.*b+a)*t; //This function is d(Bezier_3())/dt
    }
    
    float Bezier_4(float a, float b, float c, float d, float t) {
    float m = t*t;
        return  a + 3.*t*(b - a) + 3.*m*(c - 2.*b + a) + m*t*(3.*(b-c) + d - a);
    }//Uses 4 points
    
    float DerivBezier_4(float a,float b, float c, float d, float t) {
        return 3.*(b-a) + 6.*(c-2.*b+a)*t + 3.*(3.*(b-c) + d -a)*t*t;
    }
    
    //This function returns the angle in radians of the facing of the missile tangent to the curve.
    //I suggest you to look at Test4 to understand it's use.
    //To compute dy you must use DerivBezier3 or 4 on the Y axi, same for dx but in the X axi.
    float AxiAngle(float dy, float dx) {
        return Atan2(dy,dx);
    }
    //for cJass users I suggest using the inline version instead
//You can use Bezier 3 to graphic perfect parabols

//Bezier_4(<Start Point>, <OutTan_of_StartPoint>, <InTan_of_EndPoint>, <EndPoint>)

    //Hermite Interpolation
    float Hermite(float p1, float p2, float t1, float t2, float s) {
        float s2 = s*s;
        float h1 = 8.0*s*s2 - 9.0*s2;
        float h2 = h1*(-1);
        float h3 = s2*(s - 2.0) + s;
        float h4 = s2*(s - 1.0);
            h1+= 1.;
            return h1*p1 + h2*p2 + h3*t1 + h4*t2;
    }
//Hermite(<StartPoint>,<EndPoint>,<Tangent1>,<Tangent2>)

    float GetCardTan(float p1, float p3) {
       return 0.5*(p3-p1);
    }

// TCB functions for finding the tangents among 3 points
// Most modellers may know TCB from 3dsmax, in which they are used to make rotations
// look very smooth.
// t = tension, c = continuity, b = bias
// tension is how sharply the curve makes turns.
// continuity specifies the rate of change between speed and direction.
// bias specifies the direction of the curve.
// sidenote: specify p1 as 0, when working with 2 points.

// the next function returns the intan of p2

    float InTan(float p1, float p2, float p3, float t, float c, float b) {
           return (1.0-t)*(1.0-c)*(1.0+b)*(p2-p1)/2. + (1.0-t)*(1.0+c)*(1.0-b)*(p3-p2)/2.;
    }

// the next function returns the outtan of p2

    float OutTan(float p1, float p2, float p3, float t, float c, float b) {
           return (1.0-t)*(1.0+c)*(1.0+b)*(p2-p1)/2. + (1.0-t)*(1.0-c)*(1.0-b)*(p3-p2)/2.;
    }

}


Reminder All these functions should be use on Axis individually, which is good if you want to convine different interpolations. You can interpolate anything with these, from distances to accelerations.

Anyways Screenshots:


Linear Interpolation:
attachment.php

Bezier 3 Points:
attachment.php

attachment.php

Bezier 4 Points:
attachment.php

attachment.php



Don't forget to download the Test Map
 

Attachments

  • Bezier3Interpolation.jpg
    Bezier3Interpolation.jpg
    163.3 KB · Views: 1,109
  • Bezier3Interpolation2.jpg
    Bezier3Interpolation2.jpg
    127 KB · Views: 1,115
  • Bezier4Interpolation.jpg
    Bezier4Interpolation.jpg
    177.1 KB · Views: 1,111
  • Bezier4InterpolationUnit.jpg
    Bezier4InterpolationUnit.jpg
    171 KB · Views: 1,106
  • LinearInterpolation.jpg
    LinearInterpolation.jpg
    141.5 KB · Views: 1,224
  • InterpolationTest.w3x
    24 KB · Views: 362
Last edited:
Level 16
Joined
Oct 12, 2008
Messages
1,570
You used += once in vJass version and forgot a call there also, when that is fixed, works like a charm! ^^ Really good job!
(Both mistakes were in Test Trigger so nothing wrong with the system itself!!!!)
 
Top