Sign in to follow this  

What kind of math do i need for curves?

This topic is 4837 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Here is what i want to make. Please tell me what i need to read up on in order to get it working. Please forgive me for not remembering my highschool math so well ;-) I want to build a "color curve". Basically, i want a list of X number of arbitrary RGB colors tied to a point in time. So basically its a simple graph:
C  |              X
O  |  X  
L  |
O  |       X
R  |________________
        TIME 
I want to be able to interpolate values in between the points with a curve.
C  | X            X
O  |  X         XX
L  |   XX     XX
O  |     XXXXX
R  |________________
        TIME 
I know this is simple but i'm not sure of the terminology and whatnot in order to be able to look it up on my own. If you want to explain it to me personally, that would be even better. Please remember that i am looking for an arbitrary number of points, not simply two or three. Thanks

Share this post


Link to post
Share on other sites
Perhaps i should also ask: is there a faster way to do this altogether?

What i'm trying to do is make a color ramp for things like particles and effects which need to change colors or fade. So want an object that i can set with a series of colors to flip through

[ percentage of run time, color ]

0.00 - PINK
0.10 - BLUE
0.35 - LIGHTBLUE
0.80 - WHITE
1.00 - YELLOW

for instance. Than i want to say:

color_curve.GetRedAtInterval( 0.6 );

and because of it's rather sloppy nature, i'm not in need of something ultra-precise, just quick and usable.

Share this post


Link to post
Share on other sites
You can try LaGrangian Interpolation. It's a method in which you give it n points, and it will create a polynomial that passes through those n points. If you're having trouble understanding/implementing it, then ask more.

[edit]
Didnt see that second post of yours. Making a function like color_value.GetRedAt( 0.6 ) shouldnt be that difficult without the above method i mentioned. You can just use linear interpolation between the two colors. Get the difference between the time the color starts and the time the color ends and the see how much the time requested is into that and lerp. Hard to explain, I think code will help:


Color Lerp( Color one, Color two, float time )
{
Color out;
out.r = one.r + time * (two.r - one.r);
out.g = one.g + time * (two.g - one.g);
out.b = one.b + time * (two.b - one.b);
out.r = one.a + time * (two.a - one.a);
}

BYTE color_value::GetRedAt( float time )
{
// totalTime is total time from start to finish.
// In your case its 0 to 1 (pink to yellow)

// colors is a std::vector container that has the
// DIfferent color values stored at differen times
// struct ColorTime
// {
// Color col;
// float at;
// };
// std::vector<ColorTime> colors;
for( int i = 0; i < colors.size() - 1; ++i )
{
if( colors[i].at <= time && colors[i + 1].at >= time )
{
// Found our color.
float difference = colors[i + 1].at - colors[i].at;
float s = difference / ( time - colors[i].at );
Color c = Lerp( colors[i].color, colors[i + 1].color, s );
return c.r;
}
}
}


[Edited by - IFooBar on September 17, 2004 11:33:44 PM]

Share this post


Link to post
Share on other sites
LaGrangian interpolation probably isn't what you want. Unless your points are very well placed, it will be wavy and the interpolated values will go outside the range [0,1].

I recommend using a piecewise cubic curve of some kind. You might try a natural cubic spline or a Catmull-Rom spline. Both are fairly easy to calculate once you understand the math, and both should give excellent results.

-- Eric Lengyel

Share this post


Link to post
Share on other sites
At first i was going to snub the linear idea, but now that i think about it, that's how a "color ramp" would work anyway, isn't it? Maybe i'm making the whole thing much too over complicated.


Like let's say i have this (letters represent colors in a gradient):


A--------------B---------------------------------C
^


At the specified point, the color would be about 25% B and 75% C. That's very easy to figure out.

If i missed something, please let me know. It's not all a waste, i did go explore Lagrange interpolation for an hour or two and almost had a new class debugged for it. I even relearned Sigma and Pi Notation ;-)

Share this post


Link to post
Share on other sites
Simple linear, cubic or cosine interpolation methods should work just fine. Use cubic for a continuous curve which will pass through all given control points, or cosine for a cruder, slightly faster approximation of a curve passing through all control points. The actual visible differences between the various methods in this context are probably going to be so slight as to likely not be noticeable, so I would tend to favor simple linear interpolation. Note that you probably will want to pre-generate a lookup table if the color ramp is going to be accessed frequently, as a table lookup will be much cheaper than evaluating a curve every time. Since you want to use it for color-changing particles, I'd recommend this approach. Just allocate an array of RGBs, and fill it with evaluated samples when the color ramp is constructed.

Share this post


Link to post
Share on other sites
creating your own interpolation function isnt really as hard as it might seem.

1. what do you know?

color(p1) = c1
color(p2) = c2
color(p3) = c3

2. hmmm, three constraints, means we can solve for three unknown

3. ax^2 + bx + c has three unknown, how handy. so lets say color(x) = ax^2 + bx + c

thus we know:

ap1^2 + bp1 + c = c1
ap2^2 + bp2 + c = c2
ap3^2 + bp3 + c = c3

all p and c is know, lets take a few sample values:
p1 = 0, p2 = 1, p3 = 2
c1 = .9, c2 = .2, c3 = .5

now our formulas simplify to:

c = .9
a + b + c = .2
4a + 2b + c = .5

a + b = -.7
b = -.2 - 2a
a = .5
b = -1.2

color(x) = .5x^2 - 1.2x + .9


the same simple steps can be applied to any dataset you wish to interpolate between using a polynomal.

Share this post


Link to post
Share on other sites
Okay i got it working with simple linear interpolation and it looks pretty good. Thanks for all your help. I might possibly add other interpolation methods in the future, but for now, this works very nice. Here is a three point gradient:

Share this post


Link to post
Share on other sites

This topic is 4837 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this