Thread: Representing floats with color?

  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
    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

  5. #5
    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.

  6. #6
    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

  7. #7
    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?

  8. #8
    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.

  9. #9
    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.

  10. #10
    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.

  11. #11
    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.

  12. #12
    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.

  13. #13
    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

  14. #14
    Registered User
    Join Date
    Oct 2007
    Posts
    166
    Quote Originally Posted by phantomotap View Post
    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
    Well I explained what I'm doing... but a bit more...

    I'm drawing a bitmap that shows the thickness of a 3d object. When the bitmap is applied to the object each pixel of the bitmap will be at a certain surface point on the object. I calculate the thickness at that point and want to assign that thickness(float) to the corresponding pixel on the bitmap I'm drawing. The thing is that the final bitmap will go from black at the thickest point to white at the thinnest so after all pixels has been assigned float values I need to clamp them between 0.0 and 1.0.

    Instead of creating an additional huge array of values it would be better and faster to do the calculation directly in the bitmap since the bitmap will already exists in memory. The bitmap is also very memory efficient and has access to neighbors that I need so it is the perfect container for my values, that is if can make floats fit in as colors. That is the challenge here.

  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