Gradient

I'm sure this has been figured out. Simple concept...

I want to fill a bar with a "gradient" of sorts. To represent cold to hot... to slowly fill from Purple (cold) to Red (hot). Maybe following the natural light spectrum.

So based on a % FULL from 0 to 100%, I want RBG values that go from Purple to Red. Then I can fill the bar at each % with the appropriate slice of color.

Anyone have a function that generates the [R,G,B] = f(percentage)? I'm thinking there might be a cool set of formulas rather than a lookup table.

I could break this into maybe 5-6 segments rather than 100 to save computational demand.... but if there are formulas that work on a continuous basis that would be cool.

  • var l_pal = [];
    for (var r = 0x0; r <= 0xff0000; r += 0x550000) {
    	for (var g = 0x0; g <= 0x00ff00; g += 0x005500) {
        	for (var b = 0x0; b <= 0x0000ff; b += 0x000055) {
    			l_pal.add(r|g|b);
    		}
    	}
    }	

    This generates the 64 color palette, but If you have a device with more then you could change the increment and limits as needed to generate an array of colors, or maybe generating and storing the whole array then just using the part you need?

  • So if I send a value of 88% I'd want the RGB to be in the Orange to slightly Red color. A value of 15% would be Purple-ish. 50% would be Green. That kind of thing. Bascally the l_pal array will have 64 (0-63) elements so a 50% would pull from index 31. That is brilliant!

  • All of your posts are about gradients. Maybe you should rename the thread to color gradient :)

  • I tryed your code (thank you), but the result I got is not satisfying. 
    Maybe I did something wrong.

            var l_pal = [];     // sollte ein kompletter Farbverlauf sein - funzt nicht!
            var x = 10;
            for (var r = 0x0; r <= 0xff0000; r += 0x550000) {
                for (var g = 0x0; g <= 0x00ff00; g += 0x005500) {
                    for (var b = 0x0; b <= 0x0000ff; b += 0x000055) {
                        l_pal.add(r|g|b);
                        x ++;
                        dc.setColor( (r|g|b), Graphics.COLOR_TRANSPARENT);
                        dc.drawLine(x, 300, x, 350);
                        //System.println((r|g|b));
                    }
                }
            }
    

  • Yeah, now that I think about it it makes sense. Maybe try something from here: stackoverflow.com/.../convert-rgb-to-light-frequency

    Or maybe a lookup table with 16 or maybe 8 colors will be easier (and probably less code+data) Also because of the few actual RGB cokors used by MIP displays, the table can be compressed somewhat.

        function rgb6(color as ColorType) as Number {
            return (
                ((color & 0xC00000) >> 18) +
                ((color & 0xC000) >> 12) +
                ((color & 0xC0) >> 6)
            );
        }
    
        function color6(rgb6 as Number) as ColorType {
            // convert the 6-bit color back to 24-bits
            return
                (rgb6 & 0x03) * 0x55 +
                (rgb6 & 0x0C) * 0x1540 +
                (rgb6 & 0x30) * 0x55000;
        }
    

    You only need the color6 function in your code, 'cause ideally you'll do the compression not in Monkey C but with some other script and generate your constant lookup table into some generate rainbow.mc file.

  • Playing around in Powerpoint with Color Gradients, I think this is good enough for my needs.Five main colors. Purple, Blue, Green (central), Orange and Red (Yellow doesn't work well). Equally Spaced. And for each of those, I'll pick 3 shades to transition. So 15 RGB colors. That go from "cold" to "hot" with green being the central values. Looks like there isn't a clean formula to generate the natural light spectrum from left to right. Thanks!

  • I created 2 (nearly the same) functions for my needs.
    Both functions make a color gradient from one chosable color to another into a filled rectangle.

    One function I use for background coloring of HR or Power zones. 2 mirrored gradients.

    The other function only draws a filled rectangle with the color gradient.
    I did a set of gradients for the zone colors grey, blue, green, orange, red and purple.

    ( variable fx is only to magnify all values by 1.7 for Edge 1050)

    dc.drawText(fieldWidth / 2, fieldHeight / 4 - 50*fx, Graphics.FONT_MEDIUM, "BackGrColor = " + backgroundColor, textCenter);
    dc.drawText(fieldWidth / 2, fieldHeight / 4 - 10*fx, Graphics.FONT_MEDIUM, "ForeGrColor = " + foregroundColor, textCenter);
    
    fillRectGradient2( dc, 5*fx, 200*fx, 86*fx, 30*fx, 25*fx, myRed, backgroundColor );        
    fillRectGradient2( dc, fieldWidth/2 -43*fx, 200*fx, 86*fx, 30*fx,  25*fx, myLBlue, backgroundColor );    
    fillRectGradient2( dc, fieldWidth-5*fx-86*fx, 200*fx, 86*fx, 30*fx,  25*fx, myLGreen, backgroundColor );    
    
    var fadeColor = [backgroundColor, myGrey, myLBlue, myGreen, myOrange, myRed, myPurple];
    for ( var i = 0; i < 6; i ++ ) {
        fillRectGradient( dc, (15 + i*40)*fx, 300*fx, 40*fx, 6*fx, fadeColor[i], fadeColor[i+1] );        
    }
    

    STRANGE FORUM SOFTWARE: I'm not allowed to add code. Says "I'm blocked"

    So, I add one of the functions as normal text:
    (All my efforts to work with decimal or hex colors directly did not work. Only to split colors into RGB did work finally!)


        function fillRectGradient( dc, x, y, w, h, c1, c2) {  
            // Gradient soll den Zielwert schrittweise erreichen -> in w Schritten    
            var r1 = Math.round( c1 / (256*256));
            var g1 = Math.round( c1 / 256 ) % 256;
            var b1 = c1 % 256;
            var r2 = Math.round( c2 / (256*256));
            var g2 = Math.round( c2 / 256 ) % 256;
            var b2 = c2 % 256;
            for ( var i = 0; i <= w; i ++ ) {
                var rDiff = (i*(r2-r1)/w).toNumber();
                var gDiff = (i*(g2-g1)/w).toNumber();
                var bDiff = (i*(b2-b1)/w).toNumber();
                var newCol = ( r1+rDiff )*65536 + ( g1+gDiff )*256 + ( b1+bDiff );
                dc.setColor( newCol, Graphics.COLOR_TRANSPARENT);
                dc.drawLine(x+i, y, x+i, y+h);
            }
        }


  • AMOLED only? If not, then you should use the MIP's 64 colors or you'll get surprises