color mix

Repost; the list bounced my last attempt.

···

On Fri, 2008-09-19 at 18:42 -0400, Tom Holroyd wrote:

On Thu, 2008-09-18 at 20:40 +0200, Jouni K. Seppänen wrote:
> I would prefer something like the following options:
>
> fc={'orange': 20, 'white': None}
> fc=[[20, 'orange'], [None, 'white']]
> fc=ColorMixture('orange', 20, 'white') # where ColorMixture is a fairly
> # trivial class

+1

simpler, easier to read & write, less ad-hoc

I'd go ahead and make ColorMixture a fancy class with __rmul__ and
__add__ methods to allow things like
  orange = ColorMixture(255, 165, 0)
  blue = ColorMixture(0, 0, 255)
  mycolor = .7 * orange + .2 * blue

like,

class cm:
  def __init__(self, r, g, b):
    self.r = r
    self.g = g
    self.b = b
  def __rmul__(self, a):
    return cm(a * self.r, a * self.g, a * self.b)
  def __add__(self, a):
    return cm(a.r + self.r, a.g + self.g, a.b + self.b)

--
Elephants can paint.

hsv mixing is much more useful. Take a known color and you can imagine
what a darker/lighter or paler/deeper version would look like, such as
dark green or pale blue. These are just value and saturation. Even hue
can be imagined to some degree (bluish, greenish, etc.) to move one hue
toward another, but that is harder to imagine across the circle
(e.g, greenish purple or bluish yellow).

Rather than averaging it would be easier to move some percentage toward
the other color, such as blue, but hue 20% toward green.

This can probably be expressed in operations on a color mixture class
as above.

Also a linear perceptual scale would work better than HSV but I don't
know of one off hand.

- Paul

···

On Sep 23, 2008, at 8:29 PM, Tom Holroyd wrote:

Repost; the list bounced my last attempt.

On Fri, 2008-09-19 at 18:42 -0400, Tom Holroyd wrote:

On Thu, 2008-09-18 at 20:40 +0200, Jouni K. Seppänen wrote:

I would prefer something like the following options:

    fc={'orange': 20, 'white': None}
    fc=[[20, 'orange'], [None, 'white']]
    fc=ColorMixture('orange', 20, 'white') # where ColorMixture is a fairly
                                           # trivial class

+1

simpler, easier to read & write, less ad-hoc

I'd go ahead and make ColorMixture a fancy class with __rmul__ and
__add__ methods to allow things like
  orange = ColorMixture(255, 165, 0)
  blue = ColorMixture(0, 0, 255)
  mycolor = .7 * orange + .2 * blue

Paul Kienzle wrote:

Also a linear perceptual scale would work better than HSV but I don't
know of one off hand.

L*u*v* or its cylindrical-coordinate cousin L*t*theta* (or LCH_uv). "Choosing Color Palettes for Statistical Graphics" is a nice paper talking about an implementation in R (although they do seem to misname L*t*theta* as HCL, which officially is different):

   http://eeyore.ucdavis.edu/stat250/epub-wu-01_abd.pdf

For the "real" HCL, which also might be useful:

   http://mmis.doc.ic.ac.uk/mmir2005/CameraReadyMissaoui.pdf

The main problem with perceptual colorspaces is that they do not map neatly to the color gamut of the RGB or CMYK colorspaces of typical rendering devices.

···

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
  that is made terrible by our own mad attempt to interpret it as though it had
  an underlying truth."
   -- Umberto Eco