Thread: Representing floats with color?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    166

    Representing floats with color?

    Ok I've got a challenge for you, a nut to crack.

    We have a color class with values r, g, b and a.

    r,g,b and a each go from 0 to 255 as integers.

    How do you make the color value represent any float value? Find some logic for how you could combine the four values to represent a float.

    ..or perhaps a reasonable value like between 0.0f and 1000000.0f. 2-3 decimals would be enough to store.

    Will try to solve this myself in some way too...

    Edit: Things got a bit easier... added a fourth "a" value since we have an alpha channel as well.
    Last edited by DrSnuggles; 12-19-2008 at 03:00 AM.

  2. #2
    village skeptic
    Join Date
    Aug 2008
    Posts
    31
    Why would you want to do this?

  3. #3
    Registered User
    Join Date
    Oct 2007
    Posts
    166
    Why would I NOT want to do this?

    The thing is I want to find a way to store the surface thickness of a 3d object at each pixel. Perhaps there is a better way? Any ideas are welcome.

    I figured I can use the alpha channel to store the decimals like this:

    Code:
    int decimals = (int) (val - floor(val)) * 100.0f);
    Only two decimals, 0 to 99 but that should be enough.

  4. #4
    village skeptic
    Join Date
    Aug 2008
    Posts
    31
    Quote Originally Posted by misterMatt View Post
    Why would you want to do this?
    Should I rephrase? In what context would representing an RGB+alpha value as a float be useful?

    A memory saving device perhaps?

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    One way it's possible, assuming a float is 4 bytes long:
    Code:
    union {
      float fv;
      char sv[4];
    } e;
    e.sv[0] = color.red;
    e.sv[1] = color.green;
    e.sv[2] = color.blue;
    e.sv[3] = color.alpha;
    
    /* e.fv is your unique float-type variable representing the color */
    Not to mention that such a thing would be utterly pointless and stupid, but it's a solution. Sort of.

  6. #6
    Registered User
    Join Date
    Oct 2007
    Posts
    166
    Quote Originally Posted by EVOEx View Post
    One way it's possible, assuming a float is 4 bytes long:
    Code:
    union {
      float fv;
      char sv[4];
    } e;
    e.sv[0] = color.red;
    e.sv[1] = color.green;
    e.sv[2] = color.blue;
    e.sv[3] = color.alpha;
    
    /* e.fv is your unique float-type variable representing the color */
    Not to mention that such a thing would be utterly pointless and stupid, but it's a solution. Sort of.
    Hmm, not sure about this one...
    Last edited by DrSnuggles; 12-19-2008 at 05:29 AM.

  7. #7
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Ignore the problems for a moment; can you post some pseudo-source illustrating what you want to do?

    So far, what you are saying just isn't adding up.

    Soma

  8. #8
    Registered User
    Join Date
    Oct 2007
    Posts
    166
    Quote Originally Posted by misterMatt View Post
    Should I rephrase? In what context would representing an RGB+alpha value as a float be useful?

    A memory saving device perhaps?
    Memory is an issue yes. I want to calculate the thickness of a 3d object at each pixel and store the thickness value for each pixel in a bitmap. Only after that will I have the info I need about what is the minimum and maximum thickness so after that step I want to work with the float values I stored in the bitmap and convert between the color and the float value.

    I don't want to store an array in memory with possibly several million floats. Working with such an array would also be slow. With a bitmap I have the benefit of being able to easially check neighbors of the values as well.

    In the final step the float value at each pixel will be converted to the color that the bitmap will actually have.
    Last edited by DrSnuggles; 12-19-2008 at 04:52 AM.

  9. #9
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    Quote Originally Posted by DrSnuggles View Post
    I don't want to store an array in memory with possibly several million floats. Working with such an array would also be slow. With a bitmap I have the benefit of being able to easially check neighbors of the values as well.
    It's still not clear why you want to do so much arithmetic on several million pixels.

    Why would working with floats be slower than working with quadruples of 4 chars? And why would checking neighbors be easier with 4 chars. If I understand your solution, you will have to look at all 4 chars for each comparison, since (for example) [255, 0, 0, 0] will be closer to [0,255,255,255] than [0,0,0,0] is to [0,0,0,10]. Correct?

    If you are starting out with float values to begin with, and are primarily trying to save space, why is EVOEx's solution not preferable? The bitmap can be an array of unions instead of an array of 4-tuples of chars. Initially you would store the float values there. Do whatever processing you need to do on them, and do only a single conversion at the end, storing the float in each pixel with the 4 chars to display the image?

    What's wrong with that?

  10. #10
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    This is EXACTLY what I need. What strange coincidence that I logged on to get the answer to this question... and there the question is.

    I for one, have a huge 2D array of doubles that will represent some physical value. First, though, I need to read in the properties of those points from a BMP, indicated by color. Finding a simple bijection between double bit patterns and 24-bit colors would save me a lot of redesign, and memory.

    Edit: but I don't like the proposed solution.

    Edit: Actually, think I found a workaround. Still -- an interesting question. Would there be a portable way?
    Last edited by CodeMonkey; 12-19-2008 at 03:53 AM.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  11. #11
    Registered User
    Join Date
    Oct 2007
    Posts
    166
    Ok cool.

    My second post was not a solution though just an initial idea. I may find that only 2 decimals is too limiting. I think I need at least 3.

  12. #12
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    Well take a look in float.h

    It'll tell you the bit-space of a float's different components. You could build a fairly safe method that way.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  13. #13
    Registered User
    Join Date
    Oct 2007
    Posts
    166
    Quote Originally Posted by CodeMonkey View Post
    Well take a look in float.h

    It'll tell you the bit-space of a float's different components. You could build a fairly safe method that way.
    Thanks, had a quick look but couldn't find anything I understand to use. Might need to read up on bit operations a bit.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It's really quite a poor solution. The float's actual value would be undefined.
    It's better to just use 4 chars to do this. Perhaps even use std::tr1::array to wrap them in a single container with no overhead.
    But I still fail to understand what exactly it is that must be achieved, so this is the best solution I know of.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Oct 2007
    Posts
    166
    Quote Originally Posted by Elysia View Post
    It's really quite a poor solution. The float's actual value would be undefined.
    It's better to just use 4 chars to do this. Perhaps even use std::tr1::array to wrap them in a single container with no overhead.
    But I still fail to understand what exactly it is that must be achieved, so this is the best solution I know of.
    Why would it be undefined, if it is a union the float will have the same place in memory as the chars right? So starting from a float value I would assign the float value and in the char[4] that float value would be split up in 4 parts each part holding 0 - 255. Isn't this a really elegant solution?

    So in my case I could do:

    Code:
    union {
      float fv;
      char sv[4];
    } e;
    
    float thickness = 40.86f;
    e.fv = thickness;
    Color col;
    col.r = e.sv[0];
    col.g = e.sv[1];
    col.b = e.sv[2];
    col.a = e.sv[3];
    
    bitmap->putPixels(x,y,col);
    and to convert back:

    Code:
    Color col = Color(12,64,255,0);
    char ch[4] = {(char)col.r, (char)col.g, (char)col.b, (char)col.a};
    e.sv = ch;
    float thickness = e.fv;
    Or could I?
    Last edited by DrSnuggles; 12-19-2008 at 06:27 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Critique my lighting model.
    By psychopath in forum Game Programming
    Replies: 4
    Last Post: 08-12-2006, 06:23 PM
  2. egavga.bgi problem
    By sunil21 in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 09-22-2003, 05:06 PM
  3. My opinion on skin color
    By Leeman_s in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 07-11-2003, 12:12 PM
  4. [WinAPI] Developing a color customizable program
    By Templario in forum Windows Programming
    Replies: 6
    Last Post: 02-04-2003, 06:12 PM
  5. Just one Question?
    By Irish-Slasher in forum C++ Programming
    Replies: 6
    Last Post: 02-12-2002, 10:19 AM