Diversions
 Pixel Joint Forum : The Lounge : Diversions
Message Icon Topic: Programming a gradient Post Reply Post New Topic
Author Message
shampoop
Commander
Commander
Avatar

Joined: 12 January 2015
Online Status: Offline
Posts: 202
Quote shampoop Replybullet Topic: Programming a gradient
    Posted: 01 March 2011 at 10:18am
Hello,

I am writing software that will draw a terrain database to the screen.  I would like the deepest valleys to be a dark green and the highest peeks to be a light brown.  I would also like everything above 12000 to be white.  Everything in between should be a gradient between the two colors.

here is some code I have so far.
//I already have a latitude and longitude that the pixel represents in geo
//This function will return the elevation for that geo location.  This is done for
//every pixel on the screen

elev = TRN_getElevation(geo);

//Now I will assign a color for that elevation
r = 0;
g = 0;
b = 0;
       
if (elev < -10000)
{
      g = 40;
}
else if (elev < 2000)
{
     g = (200*elev)/2000 + 40;
}
else if (elev < 12000)
{
     int h = (elev - 2000);
     r = 220-(250*h)/10000;
     g = 110-(140*h)/10000;
     b = 36-(36*h)/10000;
}
else
{
     r = 255;
     g = 255;
     b = 255;
}

---------------------------
Here is a picture of what I get:


As you can see I get to much of a color change when the elevation passes 2000.  I think I am on the right track by defining an upper and lower bound.  It is in between that I need some help with.  Here is an image I found on the internet that I am trying to get my map to look like.



My question is how do I assign the rgb values mathematically to achieve this gradient???  If anyone wants my to try some code, I will post an image of the results as soon as I can.  Thanks.

(DawnBringer? any ideas?)
IP IP Logged
dpixel
Commander
Commander
Avatar

Joined: 03 February 2015
Online Status: Offline
Posts: 564
Quote dpixel Replybullet Posted: 01 March 2011 at 11:10am
Your second comparison looks like between -10000 and 2000 which is 12000.  Divided by the g range of 255 would be about 47.
Your 3rd comparison looks between 2000 and 12000 which is 10000.  Divided by 255 would be about 39.  And to make brownish, red would be the higher value then green and then blue.

Maybe in the ballpark?  lol  Try it.


r = 0;
g = 0;
b = 0;
       
if (elev < -10000)
{
      g = 40;
}
else if (elev < 2000)
{
     g = (elev / 47);
}
else if (elev < 12000)
{
     r = elev / 39; 
     g = r / 2;
     b = r / 3;
}
else
{
     r = 255;
     g = 255;
     b = 255;
}
hehe (ಠ_ಠ ) o_- :p
IP IP Logged
shampoop
Commander
Commander
Avatar

Joined: 12 January 2015
Online Status: Offline
Posts: 202
Quote shampoop Replybullet Posted: 01 March 2011 at 11:49am
Originally posted by dpixel

Your second comparison looks like between -10000 and 2000 which is 12000.  Divided by the g range of 255 would be about 47.
Your 3rd comparison looks between 2000 and 12000 which is 10000.  Divided by 255 would be about 39.  And to make brownish, red would be the higher value then green and then blue.

Maybe in the ballpark?  lol  Try it.


r = 0;
g = 0;
b = 0;
       
if (elev < -10000)
{
      g = 40;
}
else if (elev < 2000)
{
     g = (elev / 47);
}
else if (elev < 12000)
{
     r = elev / 39; 
     g = r / 2;
     b = r / 3;
}
else
{
     r = 255;
     g = 255;
     b = 255;
}



I like it, thanks.  Here are some results of your algorithm:



I will tweak it a little to lighten everything up.  I especially want to ensure that the rivers aren't black.
IP IP Logged
dpixel
Commander
Commander
Avatar

Joined: 03 February 2015
Online Status: Offline
Posts: 564
Quote dpixel Replybullet Posted: 01 March 2011 at 1:48pm
Hmmm.  I thought that would generate some greens in the lower levels like you're original.  Where do you get the elevation data from?
hehe (ಠ_ಠ ) o_- :p
IP IP Logged
shampoop
Commander
Commander
Avatar

Joined: 12 January 2015
Online Status: Offline
Posts: 202
Quote shampoop Replybullet Posted: 01 March 2011 at 2:17pm
The elevation comes from a custom built database specifically for this project.  The software is for the avionic industry and my project is to draw a TOPO map.  I've done all the work to rotate the map with the plain.  We saw problems due to certain elevations producing a magenta color.  This is the same color we use to draw route lines so we had complaints that the magenta line could not be seen in some locations.

The black/dark green is a problem in Florida.  The elevation there is just above see level and you see mostly all black.  For example elev = 4, the g = (4/ 47).  Your rgb in this case is (0, 0, 0).

One thing I forgot to mention is we use 16-bit color.  This means 5 bits are used for red and blue and 6 bits are used for green.  Also, the -10000 elevation is for no data.  You get this on coast lines where the database isn't covered.


Here is a screen shot of the application running in demo mode:


(This is Portland, OR heading east)


IP IP Logged
shampoop
Commander
Commander
Avatar

Joined: 12 January 2015
Online Status: Offline
Posts: 202
Quote shampoop Replybullet Posted: 02 March 2011 at 4:45pm
Well, I finally figured out how to do this.  First off, here is the code I used to calculate the gradient:

-----------------------

                        typedef struct {
                          int r,g,b;
                        } COLOR;

                        COLOR draw, low, high;

                        draw.r = 0;
                        draw.g = 0;
                        draw.b = 0;

                        low.r = 0;
                        low.g = 0;
                        low.b = 0;

                        high.r = 0;
                        high.g = 0;
                        high.b = 0;
                       
                        float ratio = 0;

                        if (elev <= -1369)
                        {
                            low.r = 0;
                            low.g = 0;
                            low.b = 0;

                            high.r = 0;
                            high.g = 0;
                            high.b = 0;

                            ratio = 1;
                        }
                        else if (elev > -1369 && elev <= 0)
                        {
                            low.r = 0;
                            low.g = 0;
                            low.b = 0;

                            high.r = 0;
                            high.g = 40;
                            high.b = 0;

                            ratio = (-1 * (float) elev) / 1369;
                        }
                        else if (elev > 0 && elev <= 2000)
                        {
                            low.r = 0;
                            low.g = 40;
                            low.b = 0;

                            high.r = 75;
                            high.g = 122;
                            high.b = 52;

                            ratio = (float) elev / 2000;
                        }
                        else if (elev > 2000 && elev <= 4000)
                        {
                            low.r = 75;
                            low.g = 122;
                            low.b = 52;

                            high.r = 175;
                            high.g = 188;
                            high.b = 72;

                            ratio = ((float) elev - 2000) / 2000;
                        }
                        else if (elev > 4000 && elev <= 6000)
                        {
                            low.r = 175;
                            low.g = 188;
                            low.b = 72;

                            high.r = 217;
                            high.g = 215;
                            high.b = 96;

                            ratio = ((float) elev - 4000) / 2000;
                        }
                        else if (elev > 6000 && elev <= 8000)
                        {
                            low.r = 217;
                            low.g = 215;
                            low.b = 96;

                            high.r = 188;
                            high.g = 149;
                            high.b = 56;

                            ratio = ((float) elev - 6000) / 2000;
                        }
                        else if (elev > 8000 && elev <= 10000)
                        {
                            low.r = 188;
                            low.g = 149;
                            low.b = 56;

                            high.r = 161;
                            high.g = 94;
                            high.b = 39;

                            ratio = ((float) elev - 8000) / 2000;
                        }
                        else if (elev > 10000 && elev <= 12000)
                        {
                            low.r = 161;
                            low.g = 94;
                            low.b = 39;

                            high.r = 129;
                            high.g = 46;
                            high.b = 30;

                            ratio = ((float) elev - 10000) / 2000;
                        }
                        else
                        {
                            low.r = 111;
                            low.g = 38;
                            low.b = 26;

                            high.r = 111;
                            high.g = 38;
                            high.b = 26;

                            ratio = 1;
                        }

                        draw.r = low.r * (1 - ratio) + high.r * ratio;
                        draw.g = low.g * (1 - ratio) + high.g * ratio;
                        draw.b = low.b * (1 - ratio) + high.b * ratio;

                        VGA_setForeColor(draw.r, draw.g, draw.b);
---------------------------------------

I picked the colors from this picture I found on google:



and came up with this:


Here are the results:




Here is the old display:


As you can see the Magenta line problem is solved.
IP IP Logged
dpixel
Commander
Commander
Avatar

Joined: 03 February 2015
Online Status: Offline
Posts: 564
Quote dpixel Replybullet Posted: 03 March 2011 at 7:25am
Cool looking program.  I don't know all that much about c or c++, but I do use c graphic library's with FreeBASIC.  Right now I'm using SDL.  What graphic library are you using with this one? 
hehe (ಠ_ಠ ) o_- :p
IP IP Logged
Post Reply Post New Topic
Printable version Printable version

Forum Jump
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot delete your posts in this forum
You cannot edit your posts in this forum
You cannot create polls in this forum
You cannot vote in polls in this forum