Color arithmetical operations are broken
Hi, I played with colors and found out, that arithmetical operations with colors are completely broken. https://pharo.fogbugz.com/f/cases/15188/Color-ariphmetical-operations-are-br... Result is not a valid Color - just garbage. It happens because alpha is not being initialized and stays nil. It seems that operation were implemented before alpha support was added. So I propose the following solution: Color red - Color red = Color transparent (Color white alpha: 1) - (Color white alpha: 0.5) = (Color white alpha:
0.5)
R,G,B are subtracted as before. Alpha channels are subtracted too. Color red + Color blue = Color magenta Color red + Color transparent = Color red (Color white alpha: 0.5) + (Color white alpha: 0.5) = (Color white alpha: 1)
R,G,B are added as before. Alpha channels are added too. Multiplication and division by number doesn't change alpha channel. Cheers, Alex
2015-03-21 0:19 GMT+01:00 Aliaksei Syrel <alex.syrel@gmail.com>:
Hi,
I played with colors and found out, that arithmetical operations with colors are completely broken.
https://pharo.fogbugz.com/f/cases/15188/Color-ariphmetical-operations-are-br...
Result is not a valid Color - just garbage. It happens because alpha is not being initialized and stays nil. It seems that operation were implemented before alpha support was added. So I propose the following solution:
Color red - Color red = Color transparent
(Color white alpha: 1) - (Color white alpha: 0.5) = (Color white alpha:
0.5)
R,G,B are subtracted as before. Alpha channels are subtracted too.
Color red + Color blue = Color magenta
Color red + Color transparent = Color red
(Color white alpha: 0.5) + (Color white alpha: 0.5) = (Color white alpha:
1)
R,G,B are added as before. Alpha channels are added too.
Multiplication and division by number doesn't change alpha channel.
Cheers, Alex
I would not change the alpha at all. Instead, set alpha 255 in setPrivateRed: r green: g blue: b
I would not change the alpha at all. Instead, set alpha 255 in setPrivateRed: r green: g blue: b
It makes sense to be consistent. However blindly setting it to 255 is sometimes unexpected too: Color transparent + Color transparent is assume to get Color transparent and not black. Maybe for + we could add alphas, but for subtraction take the smallest alpha of two colors? Cheers, Alex On Sat, Mar 21, 2015 at 12:32 AM, Nicolai Hess <nicolaihess@web.de> wrote:
2015-03-21 0:19 GMT+01:00 Aliaksei Syrel <alex.syrel@gmail.com>:
Hi,
I played with colors and found out, that arithmetical operations with colors are completely broken.
https://pharo.fogbugz.com/f/cases/15188/Color-ariphmetical-operations-are-br...
Result is not a valid Color - just garbage. It happens because alpha is not being initialized and stays nil. It seems that operation were implemented before alpha support was added. So I propose the following solution:
Color red - Color red = Color transparent
(Color white alpha: 1) - (Color white alpha: 0.5) = (Color white alpha:
0.5)
R,G,B are subtracted as before. Alpha channels are subtracted too.
Color red + Color blue = Color magenta
Color red + Color transparent = Color red
(Color white alpha: 0.5) + (Color white alpha: 0.5) = (Color white alpha:
1)
R,G,B are added as before. Alpha channels are added too.
Multiplication and division by number doesn't change alpha channel.
Cheers, Alex
I would not change the alpha at all. Instead, set alpha 255 in setPrivateRed: r green: g blue: b
Do we need to do something for Pharo 4? And what is the simplest/quickest thing that would work - even if it needs revisiting in Pharo 5? cheers -ben On Sat, Mar 21, 2015 at 8:31 AM, Aliaksei Syrel <alex.syrel@gmail.com> wrote:
I would not change the alpha at all. Instead, set alpha 255 in
setPrivateRed: r green: g blue: b
It makes sense to be consistent. However blindly setting it to 255 is sometimes unexpected too:
Color transparent + Color transparent is assume to get Color transparent and not black.
Maybe for + we could add alphas, but for subtraction take the smallest alpha of two colors?
Cheers, Alex
On Sat, Mar 21, 2015 at 12:32 AM, Nicolai Hess <nicolaihess@web.de> wrote:
2015-03-21 0:19 GMT+01:00 Aliaksei Syrel <alex.syrel@gmail.com>:
Hi,
I played with colors and found out, that arithmetical operations with colors are completely broken.
https://pharo.fogbugz.com/f/cases/15188/Color-ariphmetical-operations-are-br...
Result is not a valid Color - just garbage. It happens because alpha is not being initialized and stays nil. It seems that operation were implemented before alpha support was added. So I propose the following solution:
Color red - Color red = Color transparent
(Color white alpha: 1) - (Color white alpha: 0.5) = (Color white alpha:
0.5)
R,G,B are subtracted as before. Alpha channels are subtracted too.
Color red + Color blue = Color magenta
Color red + Color transparent = Color red
(Color white alpha: 0.5) + (Color white alpha: 0.5) = (Color white
alpha: 1)
R,G,B are added as before. Alpha channels are added too.
Multiplication and division by number doesn't change alpha channel.
Cheers, Alex
I would not change the alpha at all. Instead, set alpha 255 in setPrivateRed: r green: g blue: b
On Sat, Mar 21, 2015 at 3:41 AM, Ben Coman <btc@openinworld.com> wrote:
Do we need to do something for Pharo 4? And what is the simplest/quickest thing that would work - even if it needs revisiting in Pharo 5?
The most simple that works is to at least set alpha to any value. - Multiplication - alpha doesn't change - Division - alpha doesn't change - Addition - (color1 apha + color2 alpha) min: 1.0 - simple addition and check to not allow alpha to overcome max value - Subtraction - if two colors are the same alpha becomes 0, otherwise we take alpha of message receiver (minuend) Slice is in inbox (15188) Cheers, Alex
Yes it sounds reasonable. Stef Le 21/3/15 14:32, Aliaksei Syrel a écrit :
On Sat, Mar 21, 2015 at 3:41 AM, Ben Coman <btc@openinworld.com <mailto:btc@openinworld.com>> wrote:
Do we need to do something for Pharo 4? And what is the simplest/quickest thing that would work - even if it needs revisiting in Pharo 5?
The most simple that works is to at least set alpha to any value.
* Multiplication - alpha doesn't change * Division - alpha doesn't change * Addition - (color1 apha + color2 alpha) min: 1.0 - simple addition and check to not allow alpha to overcome max value * Subtraction - if two colors are the same alpha becomes 0, otherwise we take alpha of message receiver (minuend)
Slice is in inbox (15188)
Cheers, Alex
Why not take the average of alpha in all cases? Eliot (phone) On Mar 21, 2015, at 6:32 AM, Aliaksei Syrel <alex.syrel@gmail.com> wrote:
On Sat, Mar 21, 2015 at 3:41 AM, Ben Coman <btc@openinworld.com> wrote:
Do we need to do something for Pharo 4? And what is the simplest/quickest thing that would work - even if it needs revisiting in Pharo 5?
The most simple that works is to at least set alpha to any value. Multiplication - alpha doesn't change Division - alpha doesn't change Addition - (color1 apha + color2 alpha) min: 1.0 - simple addition and check to not allow alpha to overcome max value Subtraction - if two colors are the same alpha becomes 0, otherwise we take alpha of message receiver (minuend) Slice is in inbox (15188)
Cheers, Alex
2015-03-21 15:51 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com>:
Why not take the average of alpha in all cases?
Eliot (phone)
On Mar 21, 2015, at 6:32 AM, Aliaksei Syrel <alex.syrel@gmail.com> wrote:
Or weight the argument by its alpha and don't change the alpha of the receiver: Color white - (Color white alpha:0) = Color white Color white - (Color white alpha:0.5) = Color gray. Color white - (Color white alpha:1.0) = Color black. For what do you need the color arithmetic ? Maybe there are already other operations defined on Color that you can used instead. As the arithmetic operations on Color doesn't work (for years?), maybe we should remove the operation now, and replace them with a more verbose api addRGB/ addRGBA/ subRGBA .... nicolai
On Sat, Mar 21, 2015 at 3:41 AM, Ben Coman <btc@openinworld.com> wrote:
Do we need to do something for Pharo 4? And what is the simplest/quickest thing that would work - even if it needs revisiting in Pharo 5?
The most simple that works is to at least set alpha to any value.
- Multiplication - alpha doesn't change - Division - alpha doesn't change - Addition - (color1 apha + color2 alpha) min: 1.0 - simple addition and check to not allow alpha to overcome max value - Subtraction - if two colors are the same alpha becomes 0, otherwise we take alpha of message receiver (minuend)
Slice is in inbox (15188)
Cheers, Alex
2015-03-22 12:43 GMT+01:00 Nicolai Hess <nicolaihess@web.de>:
2015-03-21 15:51 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com>:
Why not take the average of alpha in all cases?
Eliot (phone)
On Mar 21, 2015, at 6:32 AM, Aliaksei Syrel <alex.syrel@gmail.com> wrote:
Or weight the argument by its alpha and don't change the alpha of the receiver: Color white - (Color white alpha:0) = Color white Color white - (Color white alpha:0.5) = Color gray. Color white - (Color white alpha:1.0) = Color black.
For what do you need the color arithmetic ? Maybe there are already other operations defined on Color that you can used instead.
As the arithmetic operations on Color doesn't work (for years?), maybe we should remove the operation now, and replace them with a more verbose api addRGB/ addRGBA/ subRGBA ....
nicolai
Ah, this issue is already closed. That was a rather short discussion. And #/ and #* still don't work for colors.
On Sat, Mar 21, 2015 at 3:41 AM, Ben Coman <btc@openinworld.com> wrote:
Do we need to do something for Pharo 4? And what is the simplest/quickest thing that would work - even if it needs revisiting in Pharo 5?
The most simple that works is to at least set alpha to any value.
- Multiplication - alpha doesn't change - Division - alpha doesn't change - Addition - (color1 apha + color2 alpha) min: 1.0 - simple addition and check to not allow alpha to overcome max value - Subtraction - if two colors are the same alpha becomes 0, otherwise we take alpha of message receiver (minuend)
Slice is in inbox (15188)
Cheers, Alex
No wait, multiplication and division aren't supposed to work with colors , only aNumberOrArray. And this is working now. 2015-03-22 13:35 GMT+01:00 Nicolai Hess <nicolaihess@web.de>:
2015-03-22 12:43 GMT+01:00 Nicolai Hess <nicolaihess@web.de>:
2015-03-21 15:51 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com>:
Why not take the average of alpha in all cases?
Eliot (phone)
On Mar 21, 2015, at 6:32 AM, Aliaksei Syrel <alex.syrel@gmail.com> wrote:
Or weight the argument by its alpha and don't change the alpha of the receiver: Color white - (Color white alpha:0) = Color white Color white - (Color white alpha:0.5) = Color gray. Color white - (Color white alpha:1.0) = Color black.
For what do you need the color arithmetic ? Maybe there are already other operations defined on Color that you can used instead.
As the arithmetic operations on Color doesn't work (for years?), maybe we should remove the operation now, and replace them with a more verbose api addRGB/ addRGBA/ subRGBA ....
nicolai
Ah, this issue is already closed. That was a rather short discussion. And #/ and #* still don't work for colors.
On Sat, Mar 21, 2015 at 3:41 AM, Ben Coman <btc@openinworld.com> wrote:
Do we need to do something for Pharo 4? And what is the simplest/quickest thing that would work - even if it needs revisiting in Pharo 5?
The most simple that works is to at least set alpha to any value.
- Multiplication - alpha doesn't change - Division - alpha doesn't change - Addition - (color1 apha + color2 alpha) min: 1.0 - simple addition and check to not allow alpha to overcome max value - Subtraction - if two colors are the same alpha becomes 0, otherwise we take alpha of message receiver (minuend)
Slice is in inbox (15188)
Cheers, Alex
On 22 Mar 2015, at 13:35, Nicolai Hess <nicolaihess@web.de> wrote:
2015-03-22 12:43 GMT+01:00 Nicolai Hess <nicolaihess@web.de <mailto:nicolaihess@web.de>>:
2015-03-21 15:51 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com <mailto:eliot.miranda@gmail.com>>: Why not take the average of alpha in all cases?
Eliot (phone)
On Mar 21, 2015, at 6:32 AM, Aliaksei Syrel <alex.syrel@gmail.com <mailto:alex.syrel@gmail.com>> wrote:
Or weight the argument by its alpha and don't change the alpha of the receiver: Color white - (Color white alpha:0) = Color white Color white - (Color white alpha:0.5) = Color gray. Color white - (Color white alpha:1.0) = Color black.
For what do you need the color arithmetic ? Maybe there are already other operations defined on Color that you can used instead.
As the arithmetic operations on Color doesn't work (for years?), maybe we should remove the operation now, and replace them with a more verbose api addRGB/ addRGBA/ subRGBA ....
nicolai
Ah, this issue is already closed. That was a rather short discussion. And #/ and #* still don't work for colors.
Yes⦠I think we have a problem that there is no âthis is ready for integrationâ check. We need to get more careful⦠Marcus
Color white - (Color white alpha:0) = Color white Color white - (Color white alpha:0.5) = Color gray. Color white - (Color white alpha:1.0) = Color black. For what do you need the color arithmetic ? Maybe there are already other operations defined on Color that you can used instead.
That is too complicated :) The idea was to have one-line fix that just leaves the behaviour as it was before, simply makes it not produce garbage. Basically there should be a long discussion after pharo 4 is released. How it is now: (Color white alpha: 0) = Color transparent => false Color white - (Color white alpha: 0) = Color black => true
From logical point of view is should not be black. But from mathematical point of view Color is just a vector and operations with it should be the same or almost the same as with vectors.
For what do you need the color arithmetic ? I wanted to get linear discrete transformation from one color to another to use it in animation Cheers, Alex On Sun, Mar 22, 2015 at 1:54 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On 22 Mar 2015, at 13:35, Nicolai Hess <nicolaihess@web.de> wrote:
2015-03-22 12:43 GMT+01:00 Nicolai Hess <nicolaihess@web.de>:
2015-03-21 15:51 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com>:
Why not take the average of alpha in all cases?
Eliot (phone)
On Mar 21, 2015, at 6:32 AM, Aliaksei Syrel <alex.syrel@gmail.com> wrote:
Or weight the argument by its alpha and don't change the alpha of the receiver: Color white - (Color white alpha:0) = Color white Color white - (Color white alpha:0.5) = Color gray. Color white - (Color white alpha:1.0) = Color black.
For what do you need the color arithmetic ? Maybe there are already other operations defined on Color that you can used instead.
As the arithmetic operations on Color doesn't work (for years?), maybe we should remove the operation now, and replace them with a more verbose api addRGB/ addRGBA/ subRGBA ....
nicolai
Ah, this issue is already closed. That was a rather short discussion. And #/ and #* still don't work for colors.
Yes⦠I think we have a problem that there is no âthis is ready for integrationâ check.
We need to get more carefulâ¦
Marcus
wait a sec why Alpha affects the Color ? o_O Color white - (Color white alpha:0.5) = Color gray. What ? No ! This make no sense Color white - (Color white alpha:0) = Color white Ok reasonable Color white - (Color white alpha:1.0) = Color black. again reasonable On Sun, Mar 22, 2015 at 4:06 PM, Aliaksei Syrel <alex.syrel@gmail.com> wrote:
Color white - (Color white alpha:0) = Color white
Color white - (Color white alpha:0.5) = Color gray. Color white - (Color white alpha:1.0) = Color black. For what do you need the color arithmetic ? Maybe there are already other operations defined on Color that you can used instead.
That is too complicated :) The idea was to have one-line fix that just leaves the behaviour as it was before, simply makes it not produce garbage. Basically there should be a long discussion after pharo 4 is released.
How it is now: (Color white alpha: 0) = Color transparent => false Color white - (Color white alpha: 0) = Color black => true
From logical point of view is should not be black. But from mathematical point of view Color is just a vector and operations with it should be the same or almost the same as with vectors.
For what do you need the color arithmetic ?
I wanted to get linear discrete transformation from one color to another to use it in animation
Cheers, Alex
On Sun, Mar 22, 2015 at 1:54 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On 22 Mar 2015, at 13:35, Nicolai Hess <nicolaihess@web.de> wrote:
2015-03-22 12:43 GMT+01:00 Nicolai Hess <nicolaihess@web.de>:
2015-03-21 15:51 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com>:
Why not take the average of alpha in all cases?
Eliot (phone)
On Mar 21, 2015, at 6:32 AM, Aliaksei Syrel <alex.syrel@gmail.com> wrote:
Or weight the argument by its alpha and don't change the alpha of the receiver: Color white - (Color white alpha:0) = Color white Color white - (Color white alpha:0.5) = Color gray. Color white - (Color white alpha:1.0) = Color black.
For what do you need the color arithmetic ? Maybe there are already other operations defined on Color that you can used instead.
As the arithmetic operations on Color doesn't work (for years?), maybe we should remove the operation now, and replace them with a more verbose api addRGB/ addRGBA/ subRGBA ....
nicolai
Ah, this issue is already closed. That was a rather short discussion. And #/ and #* still don't work for colors.
Yes⦠I think we have a problem that there is no âthis is ready for integrationâ check.
We need to get more carefulâ¦
Marcus
On Sun, Mar 22, 2015 at 3:31 PM, kilon alios <kilon.alios@gmail.com> wrote:
Color white - (Color white alpha:1.0) = Color black. again reasonable
No, it's not really reasonable ;)
(Color white alpha: 1.0) = Color white => true
I personally assume to get Color transparent when subtract two absolutely equal colors. And by the way there is no way in pharo to detect that they could be not equal: (Color white alpha: 1.0) != Color white Color white - (Color white alpha:1.0) The same as
Color white - Color white
Cheers, Alex
"I personally assume to get Color transparent when subtract two absolutely equal colors." why ? that makes no sense to me. I guess we reason about things differently. In art black and white are not colors, they are called "neutrals" and they have the meaning of the existence of light (white) and non existence of light (black) as such black has the meaning of zero. Transparency does not affect colors its a characteristic of materials by allowing some of the light to pass through. In my view for arithmetical operation transparency should be ignored and operate only on the color itself.
2015-03-22 15:06 GMT+01:00 Aliaksei Syrel <alex.syrel@gmail.com>:
Color white - (Color white alpha:0) = Color white
Color white - (Color white alpha:0.5) = Color gray. Color white - (Color white alpha:1.0) = Color black. For what do you need the color arithmetic ? Maybe there are already other operations defined on Color that you can used instead.
That is too complicated :) The idea was to have one-line fix that just leaves the behaviour as it was before, simply makes it not produce garbage.
Yes, but I think the operation were defined as the Color class did not contain the alpha value
Basically there should be a long discussion after pharo 4 is released.
How it is now: (Color white alpha: 0) = Color transparent => false Color white - (Color white alpha: 0) = Color black => true
From logical point of view is should not be black. But from mathematical point of view Color is just a vector and operations with it should be the same or almost the same as with vectors.
Yes and no, I don't think the mathematical point of view should play here. Color is not just a vector.
For what do you need the color arithmetic ?
I wanted to get linear discrete transformation from one color to another to use it in animation
Ah, Ok. In that case I would not use the arithmetic operations at all. never :) What is wrong with Color>>mix:shades: ? | w r cl | cl := Color red mix: Color green shades:50. w := Display width // cl size. r := 0@0 extent: w@((w min: 30) max: 10). cl do: [:c | Display fill: r fillColor: c. r := r translateBy: w@0]. Or do you need to change the alpha based on the operands? Nicolai
Cheers, Alex
On Sun, Mar 22, 2015 at 1:54 PM, Marcus Denker <marcus.denker@inria.fr> wrote:
On 22 Mar 2015, at 13:35, Nicolai Hess <nicolaihess@web.de> wrote:
2015-03-22 12:43 GMT+01:00 Nicolai Hess <nicolaihess@web.de>:
2015-03-21 15:51 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com>:
Why not take the average of alpha in all cases?
Eliot (phone)
On Mar 21, 2015, at 6:32 AM, Aliaksei Syrel <alex.syrel@gmail.com> wrote:
Or weight the argument by its alpha and don't change the alpha of the receiver: Color white - (Color white alpha:0) = Color white Color white - (Color white alpha:0.5) = Color gray. Color white - (Color white alpha:1.0) = Color black.
For what do you need the color arithmetic ? Maybe there are already other operations defined on Color that you can used instead.
As the arithmetic operations on Color doesn't work (for years?), maybe we should remove the operation now, and replace them with a more verbose api addRGB/ addRGBA/ subRGBA ....
nicolai
Ah, this issue is already closed. That was a rather short discussion. And #/ and #* still don't work for colors.
Yes⦠I think we have a problem that there is no âthis is ready for integrationâ check.
We need to get more carefulâ¦
Marcus
On Sun, Mar 22, 2015 at 8:17 PM, Nicolai Hess <nicolaihess@web.de> wrote:
Yes, but I think the operation were defined as the Color class did not contain the alpha value
Exactly Ah, Ok. In that case I would not use the arithmetic operations at all.
never :)
I wanted to solve the problem without actually solving it :) In the image there is a general animation class that supports linear interpolation defined as:
(to - from) * delta + from
So it can theoretically work with all objects polymorphic with numbers in sense of math operations. I browsed Color class and surprisingly found that it is polymorphic with Number! What a lucky moment :) However when I tried I failed. Then I realized that color's value can't be negative, so general solution will not work, since (to - from) can't be negative Color. That is why I had to interpolate each channel separately: |r g b a|
r := (to red - from red) * delta + from red. g := (to green - from green) * delta + from green. b := (to blue - from blue) * delta + from blue. a := (to alpha - from alpha) * delta + from alpha. ^ Color r: r g: g b: b alpha: a
I don't need math operations with colors anymore :) But having that feature doesn't work we should do something before release ;) That's why issue was opened. Feel free to make slice requests Cheers, Alex
2015-03-22 21:26 GMT+01:00 Aliaksei Syrel <alex.syrel@gmail.com>:
On Sun, Mar 22, 2015 at 8:17 PM, Nicolai Hess <nicolaihess@web.de> wrote:
Yes, but I think the operation were defined as the Color class did not contain the alpha value
Exactly
Ah, Ok. In that case I would not use the arithmetic operations at all.
never :)
I wanted to solve the problem without actually solving it :)
In the image there is a general animation class that supports linear interpolation defined as:
(to - from) * delta + from
So it can theoretically work with all objects polymorphic with numbers in sense of math operations. I browsed Color class and surprisingly found that it is polymorphic with Number! What a lucky moment :) However when I tried I failed. Then I realized that color's value can't be negative, so general solution will not work, since (to - from) can't be negative Color.
In that case you may be interested on this issue: 15138 <https://pharo.fogbugz.com/default.asp?15138> inprecise interpolateTo:at: for floats
That is why I had to interpolate each channel separately:
|r g b a|
r := (to red - from red) * delta + from red. g := (to green - from green) * delta + from green. b := (to blue - from blue) * delta + from blue. a := (to alpha - from alpha) * delta + from alpha. ^ Color r: r g: g b: b alpha: a
I don't need math operations with colors anymore :) But having that feature doesn't work we should do something before release ;) That's why issue was opened. Feel free to make slice requests
Cheers, Alex
participants (7)
-
Aliaksei Syrel -
Ben Coman -
Eliot Miranda -
kilon alios -
Marcus Denker -
Nicolai Hess -
stepharo