Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have a set of numbers I normalize ( so the converted number is between 0 and 1 ) which I want to pass trough a function, which in return gives me a different number between 0 and 1 based on the curve/shape.

For animation the following would do for easeInQuad ( From ):

Math.easeInQuad = function (t, b, c, d) {
    t /= d;
    return c*t*t + b;
};

Where t = current time. b = start value. c = change in value. d = duration

which looks like:

enter image description here

In my case the min is always 0 and max is always 1. How would I go about creating a function equal to the shape but without all parameters that are required for animation?

share|improve this question
2  
so your function is f:[0,1] -> [0,1]? If yes, and you require it to be quadratic, one obvious solution should be f(t) = t*t. For the matter of fact, you could map [0,1] into itself in countless ways, but most popular are using Hermite polynomials or cosine interpolation (as far as some animation algorithms are concerned). Aside from these options, you always have a nice theory of splines and their families, but you're probably not going to need them for this problem. –  teodron Apr 16 '13 at 10:09
    
@teodron thanks for your input. So basically if I were to look at all the equations on the website, i should just discard all the b,c and d parameters and just work with t? Im looking for several equations that I could use. I was also thinking of bezier curves, I do like to be able to actually control how the shape looks like ( for example my "curve" could consist of smooth and linear lines ) –  Sidar Apr 16 '13 at 10:12
    
Well, beziers are approximating curve which decay in intuitiveness with the degree (they only pass through the end and start point, but might not remain on the [0,1]x[0,1] square if your control points are outside the domain. Not to overcomplicate things, I'll foresee an actual answer linking to a smoothstep function, commonly/heavily used in shader programs. Wikipedia link -> en.wikipedia.org/wiki/Smoothstep –  teodron Apr 16 '13 at 10:18
    
@teodron thanks again. –  Sidar Apr 16 '13 at 10:40
1  
What do you mean by "the shape"? Do you want it to look like the picture you have above, or do you want to be able to input an arbitrary shape, and design a function that matches it? If it's the latter, then how do you imagine specifying such a shape (or is this also implicit in your question)? –  Mokosha Apr 16 '13 at 15:25
show 1 more comment

1 Answer

up vote 0 down vote accepted

Not exactly what I'm looking for but I've opt it for another less "elegant" way of doing it.

I set up a table of points and their values.

The object looks like

public class CustomCurve {

    public float[] points; 
    public float[] height;
    public int size;

    public CustomCurve(int size){
        points = new float[size];
        height = new float[size];
        this.size = size;
    }   
}

points are the points on line t;
height are their values from which the lines are drawn from one point to another.

The function that goes with it:

 public static float Custom(float t, CustomCurve c)
 {

    float result = 0.0f;


    if(t > 1) return c.height[c.height.Length-1];
    if(t < 0) return c.height[0];

    for (int i = 0; i < c.size-1; i++) {
        if(t >= c.points[i] && t <= c.points[i+1]){

            result = Linear(t/(c.points[i+1]-c.points[i]),c.height[i],c.height[i+1]);
            break;
        }

    }
    return result;

}

Simply put, I iterate over the points on my t line. Check if t is between any of the points and calculate the inner interpolation of two points. Using the simple linear interpolation equation:

v0+(v1-v0)*t;

So a table of:

Point   Height
0       0
0,2     0,95
0,3     1
0,33    0,95
0,4     0
0,5     0,95
0,7     1
0,8     0,95
1       0

Looks like: enter image description here

Granted, the line won't be smooth. But if I need more detail I add more points. And once created I can reuse them.

If anyone knows a way to get rid of the forloop please do tell!

share|improve this answer
1  
if your points are sorted, simply use binary search instead of linear search. –  concept3d Apr 17 '13 at 8:52
    
@concept3d Any example/link to how I would do this? en.wikipedia.org/wiki/Binary_search_algorithm This what you're talking about? –  Sidar Apr 17 '13 at 9:25
1  
If your points are equally distributed (it doesn't seem so, since you're jumping from 0 to 0.2, and you also have 0.33), you can simply put them in an array, and store the amount of points n in it. Your sampling point is s = (t * n), your lower point is s_l = floor(s) and your upper point is s_u = ceil(s). Your interpolation factor is i_f = s - s_l, so the value you're looking for is at Linear(i_f, c.points[s_l], c.points[s_u]). I do exactly what you're doing with cubic splines all the time. –  Panda Pajama Apr 17 '13 at 10:26
    
@PandaPajama Yes, eventhough the 0.33 is unlikely it gives me more control on how "fine" a curve can be created from stright lines. Care to elaborate on how I could extend this to a spline interpolation? Btw floor(s) would always result in 0 in my case, since t is smaller or equal to 1. –  Sidar Apr 17 '13 at 10:29
1  
Unfortunately this only works for equally distributed points. The polynomial approximation to bezier curves gives you equally distributed points, so they work with this method. Regarding floor and ceil, remember that I'm applying it to s, not t. In s, you stretch your t from (0..1) to (0..n). –  Panda Pajama Apr 17 '13 at 10:43
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.