PDA

View Full Version : mathematic question...


CapitanRed
01-17-2009, 01:59 AM
what I want to do is select some objects and apply a custom wirecolor for each one of them. I know that I could do that with the random function.
but I'd like to do it so the color increments from 0 to 255 for each r,g,b. blue goes fastest up, then green and lastly red.

so I would like to have something like:
index = 0
for r = 1 to 255 by nr do(
for g = 1 to 255 by ng do(
for b = 1 to 255 by nb do(
index +=1
selection[index].wirecolor = color r g b
)
)
)

now how do I get nr ng and nb so it applys to no matter how many objects i select, as long there is less than (255*255*255) ?

just out of curiosity ;)

ZeBoxx2
01-17-2009, 05:51 AM
you've got your logic a wee bit backwards - you need to make sure that you only loop over the number of objects you have selected - instead of the (potentially) 16 million or so you would get with your current nested loops (could use that - but I don't think that's what you're after).

Try something like...

curSel = getCurrentSelection()
curSelCount = curSel.count
for i = 1.0 to curSelCount do (
r = i / curSelCount
g = amin (r * 2) 1.0
b = amin (r * 3) 1.0
-- curSel[i].wirecolor = (color (r * 255) (g * 255) (b * 255))
curSel[i].wirecolor = [r,g,b,0]
)

drdubosc
01-17-2009, 03:04 PM
ZB answered, in principle, but to step evenly through the whole RGB range in the way you describe, you'd need to do something like this:

fn int2Color intParam = (

r = bit.shift ( bit.and intParam 0xFF0000 ) -16
g = bit.shift ( bit.and intParam 0x00FF00 ) -8
b = bit.and intParam 0x0000FF
color r g b

)

curSel = getCurrentSelection()
curSelCount = curSel.count

for i = 1.0 to curSelCount do (

intColor = (i/curSelCount) * 0xFFFFFF -- (255,255,255)
curSel[i].wirecolor = int2Color intColor

)

..which does clock through the colors, but isn't very good looking. If your selection count is unlucky, the steps might be in phase with say, a certain hue, and so can produce a range of greys, for example.

It might be better to fix Saturation and Value, and step through Hue, but I think you'd have to write your own convertor.:)

CapitanRed
01-19-2009, 06:28 PM
interesting! But I have to say that I have trouble to understand both of them. will try to take more time to understand them. Thanks a lot for the solutions :)

dellis
01-19-2009, 07:23 PM
I think that i have someones tutorial for doing just this. I'll take a look around for it tonight.

drdubosc
01-20-2009, 11:08 AM
...I have to say that I have trouble to understand both of them..

My approach was to think of the 3 bytes of a colour as a single, 3-digit number, counting from [0][0][0] to [255][255][255] base 256 ( 00000000 to 16777215 decimal).

You can then count through the colours, with the least significant digit meaning 'blue', changing fastest, and the most significant meaning 'red', changing slowest.

The number can be written as a 6-digit hexadecimal number, counting from 0x000000 to 0xFFFFFF, which is the way MXS looks at it.

To get back to the 3-digit representation, you read the 6 hexadecimal digits off in 3 pairs. That's all int2Color does.

Hope that helps, a bit.


EDIT: ZB's gone one step further, and interpreted what you asked for less literally, so his tends to look better than mine!

ZeBoxx2
01-20-2009, 11:27 AM
Whereas mine basically just looks at how many objects you have in your selection, and tries to spread a red gradient evenly across all objects, a green gradient that spreads between the first object in the selection and whatever object is at about half of the number of objects, and a blue gradient that spreads between the first object and whatever object is at about 1/3rds of the number of objects.
Thus it starts out black, then quickly turns to a blueish color, then a more cyanish color, and ends in white.

Here's the code again with some comments...


-- get the currently selected objects into an array
curSel = getCurrentSelection()

-- get the number of objects in that array (thus the number of objects selected)
curSelCount = curSel.count

-- create a loop with a counter (i) that starts at 1 and ends with the number of objects
for i = 1.0 to curSelCount do (
-- set red to be equal to the counter divided by the number of objects
-- so say you have 10 objects. If the counter is at 1, then the value of red will be 1.0/10 = 0.1
-- if the counter is at 5, then the value will be 0.5, and if the counter is at 10, the value will be 1.0
-- so red is spread out evenly across all objects
r = i / curSelCount

-- green, on the other hand, we want to kick in a little faster - say twice as fast.
-- so we simply multiply the red value by 2. So if the counter was at 2, then...
-- red will be 2.0 / 10 = 0.2
-- green will be at 0.2 * 2 = 0.4
-- now to prevent it from going over the value of 1.0, we use amin:
-- amin automatically uses the minimum of 2 (or more) values.
-- So at 0.4 it will continue to use 0.4, but at 1.2 it would use 1.0.
g = amin (r * 2) 1.0

-- this should look familiar now
b = amin (r * 3) 1.0

-- now all we have to do is set the Nth object's wireframe color to the r, g and b values.
-- I'm using a point4 [r,g,b,a] color value here, rather than a standard color (color r g b a) value.
-- that saves me multiplication by 255, nothing more
curSel[i].wirecolor = [r,g,b,0]
)
-- all done

CGTalk Moderation
01-20-2009, 11:27 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.