Author Topic: Create a radial gradient  (Read 1267 times)

0 Members and 1 Guest are viewing this topic.

Offline flightcrank

  • C= 64
  • **
  • Posts: 35
  • Karma: 24
    • View Profile
Create a radial gradient
« on: August 07, 2013 »
Hi all.

I am having a little trouble creating a radial gradient. Also I can not find any documentation on creating them programaticly.

Here is where I'm at so far:

Assume I want to make a radial gradient fill a small 16px width by 16px height rectangle/square. I take the center pixel (x =8 , y = 8) and I calculate the distance each pixel in the rectangle is from that center pixel using Pythagoras theorem. I'm left with a table of values that look like this

Code: [Select]
11.31  10.63  10.00   9.43   8.94   8.54   8.25   8.06   8.00   8.06   8.25   8.54   8.94   9.43  10.00  10.63
 10.63   9.90   9.22   8.60   8.06   7.62   7.28   7.07   7.00   7.07   7.28   7.62   8.06   8.60   9.22   9.90
 10.00   9.22   8.49   7.81   7.21   6.71   6.32   6.08   6.00   6.08   6.32   6.71   7.21   7.81   8.49   9.22
  9.43   8.60   7.81   7.07   6.40   5.83   5.39   5.10   5.00   5.10   5.39   5.83   6.40   7.07   7.81   8.60
  8.94   8.06   7.21   6.40   5.66   5.00   4.47   4.12   4.00   4.12   4.47   5.00   5.66   6.40   7.21   8.06
  8.54   7.62   6.71   5.83   5.00   4.24   3.61   3.16   3.00   3.16   3.61   4.24   5.00   5.83   6.71   7.62
  8.25   7.28   6.32   5.39   4.47   3.61   2.83   2.24   2.00   2.24   2.83   3.61   4.47   5.39   6.32   7.28
  8.06   7.07   6.08   5.10   4.12   3.16   2.24   1.41   1.00   1.41   2.24   3.16   4.12   5.10   6.08   7.07
  8.00   7.00   6.00   5.00   4.00   3.00   2.00   1.00   0.00   1.00   2.00   3.00   4.00   5.00   6.00   7.00
  8.06   7.07   6.08   5.10   4.12   3.16   2.24   1.41   1.00   1.41   2.24   3.16   4.12   5.10   6.08   7.07
  8.25   7.28   6.32   5.39   4.47   3.61   2.83   2.24   2.00   2.24   2.83   3.61   4.47   5.39   6.32   7.28
  8.54   7.62   6.71   5.83   5.00   4.24   3.61   3.16   3.00   3.16   3.61   4.24   5.00   5.83   6.71   7.62
  8.94   8.06   7.21   6.40   5.66   5.00   4.47   4.12   4.00   4.12   4.47   5.00   5.66   6.40   7.21   8.06
  9.43   8.60   7.81   7.07   6.40   5.83   5.39   5.10   5.00   5.10   5.39   5.83   6.40   7.07   7.81   8.60
 10.00   9.22   8.49   7.81   7.21   6.71   6.32   6.08   6.00   6.08   6.32   6.71   7.21   7.81   8.49   9.22
 10.63   9.90   9.22   8.60   8.06   7.62   7.28   7.07   7.00   7.07   7.28   7.62   8.06   8.60   9.22   9.90

Now am I on the right track here ? it seems like I am and that it makes sense to do it this way.. but now I'm stuck and cant actually draw the gradient.

so far I have tried to take the inverse of each number by dividing 1 by each number which give me this... each number is between 0 and 1.0

Code: [Select]
0.09   0.09   0.10   0.11   0.11   0.12   0.12   0.12   0.12   0.12   0.12   0.12   0.11   0.11   0.10   0.09
  0.09   0.10   0.11   0.12   0.12   0.13   0.14   0.14   0.14   0.14   0.14   0.13   0.12   0.12   0.11   0.10
  0.10   0.11   0.12   0.13   0.14   0.15   0.16   0.16   0.17   0.16   0.16   0.15   0.14   0.13   0.12   0.11
  0.11   0.12   0.13   0.14   0.16   0.17   0.19   0.20   0.20   0.20   0.19   0.17   0.16   0.14   0.13   0.12
  0.11   0.12   0.14   0.16   0.18   0.20   0.22   0.24   0.25   0.24   0.22   0.20   0.18   0.16   0.14   0.12
  0.12   0.13   0.15   0.17   0.20   0.24   0.28   0.32   0.33   0.32   0.28   0.24   0.20   0.17   0.15   0.13
  0.12   0.14   0.16   0.19   0.22   0.28   0.35   0.45   0.50   0.45   0.35   0.28   0.22   0.19   0.16   0.14
  0.12   0.14   0.16   0.20   0.24   0.32   0.45   0.71   1.00   0.71   0.45   0.32   0.24   0.20   0.16   0.14
  0.12   0.14   0.17   0.20   0.25   0.33   0.50   1.00    inf   1.00   0.50   0.33   0.25   0.20   0.17   0.14
  0.12   0.14   0.16   0.20   0.24   0.32   0.45   0.71   1.00   0.71   0.45   0.32   0.24   0.20   0.16   0.14
  0.12   0.14   0.16   0.19   0.22   0.28   0.35   0.45   0.50   0.45   0.35   0.28   0.22   0.19   0.16   0.14
  0.12   0.13   0.15   0.17   0.20   0.24   0.28   0.32   0.33   0.32   0.28   0.24   0.20   0.17   0.15   0.13
  0.11   0.12   0.14   0.16   0.18   0.20   0.22   0.24   0.25   0.24   0.22   0.20   0.18   0.16   0.14   0.12
  0.11   0.12   0.13   0.14   0.16   0.17   0.19   0.20   0.20   0.20   0.19   0.17   0.16   0.14   0.13   0.12
  0.10   0.11   0.12   0.13   0.14   0.15   0.16   0.16   0.17   0.16   0.16   0.15   0.14   0.13   0.12   0.11
  0.09   0.10   0.11   0.12   0.12   0.13   0.14   0.14   0.14   0.14   0.14   0.13   0.12   0.12   0.11   0.10

I can multiply each one by 255 to give me a range of values I can use to colour the pixel. and it works ! producing a radial gradient (that's only 16px in diameter for this example).

But when I want a bigger gradient lets say one inside a rectangle of 512*512. It wont work it will still produce the small gradient.

so for example if the screen was 512*512 pixel 0,0 would have a value of 256px left from center and 256px up from the center. which would give it a distance of 362.04px from the center (sqrt(256^2 + 256^2)). The inverse of that 1/362.04 which = 0.0027. so if I get that value in the integer range of 0 to 255 I get 0.0027 * 255 = 0.68. which gets culled to just 0.

so what do I do ? scale the numbers to have bigger values ? I'm out of my depth here!

I also have learning difficulty so if anyone could explain it all to my like I'm 5 or step by step like a debugger would that would be groovy !!

Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1289
  • Karma: 466
    • View Profile
    • my stuff
Re: Create a radial gradient
« Reply #1 on: August 07, 2013 »
Pick a color value for the beginning of the gradient (that's where the distance to the center is 0).
Define where the gradient ends (could be 8.0 or 11.3 or something different) and pick a color value for the end, too.

For every value do a linear interpolation between these colors:
Code: [Select]
if (distance < startValue)
   color= startColor;
else if (distance > endValue)
   color= endColor;
else
   color = startColor + (endColor - startColor) * (distance - startValue) / (endValue - startValue);
Challenge Trophies Won:

Offline flightcrank

  • C= 64
  • **
  • Posts: 35
  • Karma: 24
    • View Profile
Re: Create a radial gradient
« Reply #2 on: August 07, 2013 »
and you lost me. I understand the concept but dont understand the formula or how you got it.
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1289
  • Karma: 466
    • View Profile
    • my stuff
Re: Create a radial gradient
« Reply #3 on: August 07, 2013 »
Ok, my fault. Let's assume the following situation:
Your gradient starts at a distance of 5.1 with color "A" and ends at a distance of 9.7 with color "B".
Now you've got some value "x" somewhere in between your starting and end-point - what color is there?
Code: [Select]
     5.1          9.7
------+--------x---+-------
      A            B

Some obvious observations:
when x=5.1 the color is A.
when x=9.7 the color is B.
when x=7.4 (halfway between A and B) the color should be A/2+B/2.

So we figure out a linear factor "a" between 0..1 which tells how far we are between A and B:
length= 9.7 - 5.1
a= (x - 5.1) / length

For different values of x we get the following factors:
x=5.1 -> a=0.0     -> color= A*1.0 + B*0.0
x=7.4 -> a=0.5     -> color= A*0.5 + B*0.5
x=9.7 -> a=1.0     -> color= A*0.0 + B*1.0

Now that looks kinda useful to calculate the resulting colors from A, B and a:
Code: [Select]
color= A * (1-a) + B * a
     = A + (B-A) * a

So more generally for a pair of values:
start: valueA
end: valueB
You can find the corresponding "value" for any "position" between start..end by:
Code: [Select]
a= (position - start) / (end - start)
value= valueA + (valueB - valueA) * a
« Last Edit: August 08, 2013 by hellfire »
Challenge Trophies Won:

Offline flightcrank

  • C= 64
  • **
  • Posts: 35
  • Karma: 24
    • View Profile
Re: Create a radial gradient
« Reply #4 on: August 08, 2013 »
Thanks so much hellfire I understand it so much better now. I got some nice gradients going !
Challenge Trophies Won:

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1666
  • Karma: 133
    • View Profile
Re: Create a radial gradient
« Reply #5 on: August 08, 2013 »
excellent little tut hellfire,

@flightcrank id just like too add that you will find as you venture into different projects, that what hellfire has put up there can be used with lots more than just color you can and probably will use this for things like course position markers in games even too 2d software fill triangles routines..

its a an excellent thing too understand and its uses in programing are wide and varied.
Challenge Trophies Won: