6

I am trying to assign a color brewer to my turtles in 2 different boxes each time they hatch and find the mean color of the turtles in each hatch.

I could have easily done it with the pallet extension but it hasn't been updated for Netlogo 5.1 and therefore, I am using a gradient extension which uses RGB colors ([ n n n]) as input and output and as a result, I cannot find the mean of colors.

This is the related part of my code:

hatch 1 
[ set generation generation + 0.1  
  ifelse ( tlake = "A" )
    [ set color gradient:scale [ [255 0 0 ] [255 255 0] [0 0 255] ] (generation) 0 500 ]
    [ set color gradient:scale [ [255 0 0 ] [255 255 0] [0 0 255] ] (generation) 500 0 ]                
  set AVEA mean [color] of (turtles with [tlake = "A"])
  set AVEB mean [color] of (turtles with [tlake = "B"])
....
]

And this is the error I am getting:

  Can't find the mean of a list that contains non-numbers : [255 0 0] is a list.

How to create a color brewer or obtain the mean value of rgb color type?

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Sahar
  • 169
  • 2
  • 1
    Is there even a single definition of "mean" in the RGB color space? I don't think just averaging the numbers will give good results. see e.g. http://stackoverflow.com/q/14819058/86485 – Seth Tisue Mar 19 '15 at 19:55
  • 1
    You say you "could easily have done it with Pallet[e] extension". If you show how you would have done it there - you can use that in combination with the [extension source code](https://github.com/NetLogo/Palette-Extension/tree/master/src) to work out how to do it. Would you have created a gradient, then selected the colour at the mid point? – J Richard Snape Mar 20 '15 at 12:09
  • 1
    Has the palette extension now been updated, and can it actually be used to take the average of two colours as suggested here? – JenB Dec 05 '15 at 09:44

2 Answers2

0

As Seth pointed out in the comments, exactly what it means to take the average of two colors is complicated. That said, averaging each RGB component is relatively simple.

The most brute force way would be to just calculate the mean of each component separately:

let r mean [ item 0 color ] of turtles
let g mean [ item 1 color ] of turtles
let b mean [ item 2 color ] of turtles
let mean-color (list r g b)

We can clean this up a bit by using n-values:

let mean-color n-values 3 [ mean [ item ? color ] of turtles ]
Bryan Head
  • 12,360
  • 5
  • 32
  • 50
  • I think the real solution is to go via RYB such as recommended at http://stackoverflow.com/questions/11312680/how-to-set-combined-color-for-overlapped-area-of-two-different-color-objects/11356035#11356035. That introduces more problems, but is viable http://stackoverflow.com/questions/4945457/conversion-between-rgb-and-ryb-color-spaces – JenB Dec 09 '15 at 10:03
0

With more arrogance than sense here is my attempt

The Trivial

to-report mean-rgb [in]
   report rgb (mean [item 0 color] of in) (mean [item 1 color] of in) (mean [item 2 color] of in)
end

this scheme has the problems y'all talked about the mean of yellow and blue is gray but it is fast and simple.

The Tangential

don't use RGB use HSB the means are more meaningful. Although it is a bit more cumbersome.

to-report mean-color [in] report hsb (mean [item 0 to-hsb color] of in) (mean [item 1 to-hsb color] of in) (mean [item 2 to-hsb color] of in)
end

where to-hsb is a piece of code from an answer by Seth Tissue which I will put here for your convenience.

to-report to-hsb [ rgb-color ]
  if is-number? rgb-color [ set rgb-color extract-rgb rgb-color ]
   let r item 0 rgb-color / 255
   let g item 1 rgb-color / 255
   let b item 2 rgb-color / 255
   let v max (list r g b)
    let chroma v - (min (list r g b))
    let h 0
    let s ifelse-value (v = 0) [ 0 ] [ chroma / v ]

   if chroma > 0 [
           if v = r [
           set h ((g - b) / chroma) mod 6
        ]
       if v = g [
       set h (b - r) / chroma + 2
   ]
     if v = b [
    set h (r - g) / chroma + 4
  ]
  set h h / 6
 ]
 report map [ precision (? * 255) 3 ] (list h s v)
end

In this scheme the mean of Yellow and Blue is Green, Red and Green is Amber. Of course there some weirdness the mean of red yellow and blue is a sickly green

I hope that helps

Community
  • 1
  • 1
King-Ink
  • 2,096
  • 12
  • 18