- Joined
- Nov 11, 2004
- Messages
- 1,986
I have shared with many these functions, but I had never posted them officially:
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.
If you want a better understanding, download the Test Map. It's better documented and has a clean and short code.
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:
Bezier 3 Points:
Bezier 4 Points:
Don't forget to download the Test Map
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:
Bezier 3 Points:
Bezier 4 Points:
Don't forget to download the Test Map
Attachments
Last edited: