gzz-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gzz-commits] gzz ./TODO Documentation/Manuscripts/Paper/pape...


From: Janne V. Kujala
Subject: [Gzz-commits] gzz ./TODO Documentation/Manuscripts/Paper/pape...
Date: Mon, 14 Oct 2002 13:49:30 -0400

CVSROOT:        /cvsroot/gzz
Module name:    gzz
Changes by:     Janne V. Kujala <address@hidden>        02/10/14 13:49:30

Modified files:
        .              : TODO 
        Documentation/Manuscripts/Paper: paper.tex 
        gfx/demo       : paperbasis.py 
        gfx/demo/color : colors.py 
        gfx/libcolor   : spaces.py 
        gfx/libpaper   : colors.py 

Log message:
        Use a linear color space with configurable lightness weigths of RGB 
primaries in libpaper; uses the same luminance nonlinearity as CIELAB; results 
in slightly different saturations and interpolated hues between the color 
circle sample points compared to the old code

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/TODO.diff?tr1=1.289&tr2=1.290&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/Documentation/Manuscripts/Paper/paper.tex.diff?tr1=1.17&tr2=1.18&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/demo/paperbasis.py.diff?tr1=1.12&tr2=1.13&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/demo/color/colors.py.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/libcolor/spaces.py.diff?tr1=1.9&tr2=1.10&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/gzz/gzz/gfx/libpaper/colors.py.diff?tr1=1.14&tr2=1.15&r1=text&r2=text

Patches:
Index: gzz/Documentation/Manuscripts/Paper/paper.tex
diff -c gzz/Documentation/Manuscripts/Paper/paper.tex:1.17 
gzz/Documentation/Manuscripts/Paper/paper.tex:1.18
*** gzz/Documentation/Manuscripts/Paper/paper.tex:1.17  Sat Oct  5 09:04:11 2002
--- gzz/Documentation/Manuscripts/Paper/paper.tex       Mon Oct 14 13:49:29 2002
***************
*** 84,91 ****
--- 84,95 ----
  \subsection{Colors}
  
  Readability
+ 
  Different palettes 
+ 
  Enough different colors for recognition
+ 
+ Color spaces: perceptually uniform
  
  {\bf jvk}
  
Index: gzz/TODO
diff -c gzz/TODO:1.289 gzz/TODO:1.290
*** gzz/TODO:1.289      Mon Oct 14 09:59:32 2002
--- gzz/TODO    Mon Oct 14 13:49:29 2002
***************
*** 16,22 ****
                needed for palettes and color textures.
                Maybe just a wrapper class? Talk to Tjl
                [jvk: wrapper class added]
-       + [GI03] simplify libpaper color space
        + [GI03] think about modeling textures
        + [GI03] libpaper NV2x combined passes
      jvk,tjl,marke: 
--- 16,21 ----
Index: gzz/gfx/demo/color/colors.py
diff -c gzz/gfx/demo/color/colors.py:1.8 gzz/gfx/demo/color/colors.py:1.9
*** gzz/gfx/demo/color/colors.py:1.8    Mon Sep 30 06:18:54 2002
--- gzz/gfx/demo/color/colors.py        Mon Oct 14 13:49:30 2002
***************
*** 461,467 ****
        putnoc(vs, background((0.5,0.5,0.5)))
  
          code = """
!             Translate 5 1 0
          """
      
          for L in [5*r for r in range(10,20)]:
--- 461,468 ----
        putnoc(vs, background((0.5,0.5,0.5)))
  
          code = """
!             Translate 1 2 0
!             Scale .5 .5 .5
          """
      
          for L in [5*r for r in range(10,20)]:
***************
*** 472,478 ****
                  Vertex 0 0
              """ % (r, g, b)
  
!             for hue in [d * 10 for d in range(-18,18+1)]:
  
                  angle0 = (hue / 180.0) * pi
                  angle = getangle((hue + 360) % 360 / 360.0)
--- 473,479 ----
                  Vertex 0 0
              """ % (r, g, b)
  
!             for hue in [d * 5 for d in range(-18*2,18*2+1)]:
  
                  angle0 = (hue / 180.0) * pi
                  angle = getangle((hue + 360) % 360 / 360.0)
***************
*** 491,497 ****
              
              code += """
                  End
!                 #Translate +2.2 0 0
              """
                  
        vs.put(getDList(code), "foobar", 10, 0, 0, 150, 150);
--- 492,498 ----
              
              code += """
                  End
!                 Translate +2.2 0 0
              """
                  
        vs.put(getDList(code), "foobar", 10, 0, 0, 150, 150);
Index: gzz/gfx/demo/paperbasis.py
diff -c gzz/gfx/demo/paperbasis.py:1.12 gzz/gfx/demo/paperbasis.py:1.13
*** gzz/gfx/demo/paperbasis.py:1.12     Tue Oct  8 05:51:07 2002
--- gzz/gfx/demo/paperbasis.py  Mon Oct 14 13:49:29 2002
***************
*** 261,267 ****
              ActiveTexture TEXTURE0
      """)
  
!     texid = gfx.libpaper.textures.ptextures["RGB2"][3].getTexId();
      
      constcode = """
          ActiveTexture TEXTURE0
--- 261,267 ----
              ActiveTexture TEXTURE0
      """)
  
!     texid = gfx.libpaper.textures.ptextures["RGB2"][9].getTexId();
      
      constcode = """
          ActiveTexture TEXTURE0
Index: gzz/gfx/libcolor/spaces.py
diff -c gzz/gfx/libcolor/spaces.py:1.9 gzz/gfx/libcolor/spaces.py:1.10
*** gzz/gfx/libcolor/spaces.py:1.9      Mon Sep 30 06:18:54 2002
--- gzz/gfx/libcolor/spaces.py  Mon Oct 14 13:49:30 2002
***************
*** 107,119 ****
      return LABclamp(rgb)
  
  
  def LABclamp(rgb):
      """Clamp a RGB color into [0,1]^3 towards the CIELAB L-axis 
  
      rgb: the color in RGB709
      returns: the clamped color in RGB709
      """
!     if len(filter((lambda x: x<0 or x>1), rgb)) == 0:
          return rgb
  
      (L,a,b) = RGBtoLAB(rgb)
--- 107,124 ----
      return LABclamp(rgb)
  
  
+ def inUnit(vec):
+     """Tests whether the vector is inside the unit cube [0,1]^n"""
+     return len(filter((lambda x: x<0 or x>1), vec)) == 0
+     
+ 
  def LABclamp(rgb):
      """Clamp a RGB color into [0,1]^3 towards the CIELAB L-axis 
  
      rgb: the color in RGB709
      returns: the clamped color in RGB709
      """
!     if inUnit(rgb):
          return rgb
  
      (L,a,b) = RGBtoLAB(rgb)
***************
*** 122,129 ****
      bit = .5
      for iter in range(0,10):
          rgb = LABtoRGB([L,(r+bit)*a,(r+bit)*b])
!         if len(filter((lambda x: x<0 or x>1), rgb)) == 0:
              r = r + bit
          bit = bit * .5
      return LABtoRGB([L,r*a,r*b])
      
--- 127,221 ----
      bit = .5
      for iter in range(0,10):
          rgb = LABtoRGB([L,(r+bit)*a,(r+bit)*b])
!         if inUnit(rgb):
              r = r + bit
          bit = bit * .5
      return LABtoRGB([L,r*a,r*b])
+ 
+ 
+ # The YST color space below is a linear color space with 
+ # a lightness component and a color plane vector whose angle and
+ # radius specify the hue and saturation, respectively.
+ # Opposite colors are 180 degrees apart.
+ #
+ # The Y component is the CIE Y lightness (but the weights can be changed) and
+ # the ST-plane has the RGB primaries 120 (R = 0, G = 120, B = 240) degrees 
apart
+ # at radius 1.
+ #    
+ # Lightness weights of the RGB primaries used in YST color space functions
+ Wr = 0.212671 
+ Wg = 0.715160
+ Wb = 0.072169
+ 
+ def YSTtoRGB(v):
+     n = 1.0 / (Wr+Wg+Wb)
+     mat =  [ [n, n*(Wg+Wb), n*(Wb - Wg)  / math.sqrt(3) ],
+              [n, n*(-Wr), n*(2*Wb + Wr) / math.sqrt(3) ],
+              [n, n*(-Wr), n*-(2*Wg + Wr) / math.sqrt(3) ] ]
+     
+     return [ mat[0][0] * v[0] + mat[0][1] * v[1] + mat[0][2] * v[2],
+              mat[1][0] * v[0] + mat[1][1] * v[1] + mat[1][2] * v[2],
+              mat[2][0] * v[0] + mat[2][1] * v[1] + mat[2][2] * v[2] ]
+ 
+ def RGBtoYST(v):
+     mat = [[ Wr, Wg, Wb ],
+            [ 1, -.5, -.5],
+            [ 0, .5*math.sqrt(3), -.5*math.sqrt(3) ]]
+ 
+     return [ mat[0][0] * v[0] + mat[0][1] * v[1] + mat[0][2] * v[2],
+              mat[1][0] * v[0] + mat[1][1] * v[1] + mat[1][2] * v[2],
+              mat[2][0] * v[0] + mat[2][1] * v[1] + mat[2][2] * v[2] ]
+ 
+ def maxYSTsat(YST):
+     """Return the maximum saturation factor in RGB cube of the given color"""
+ 
+     # Split into "lightness" and "color" components
+     Y = YSTtoRGB((YST[0],0,0))
+     vec = YSTtoRGB((0,YST[1],YST[2]))
+ 
+     assert 0 <= Y[0] == Y[1] == Y[2] <= 1
+ 
+     return min( ((vec[0] > 0) - Y[0]) / vec[0],
+                 ((vec[1] > 0) - Y[1]) / vec[1],
+                 ((vec[2] > 0) - Y[2]) / vec[2] )
+ 
      
+ def clampSat(rgb):
+     """Clamp an RGB color keeping hue and lightness constant"""
+ 
+     if inUnit(rgb):
+         return rgb
+ 
+     (Y,S,T) = RGBtoYST(rgb)
+ 
+     r = maxYSTsat((Y,S,T))
+ 
+     return YSTtoRGB((Y,r*S,r*T))
+ 
+ 
+ 
+ def YSThue(RGB):
+     YST = RGBtoYST(RGB)
+     return math.atan2(YST[2],YST[1])
+ 
+ 
+ 
+ 
+ """
+ # Kluge: Emulate LAB color space using YST hues
+ angles = map(YSThue, colors)
+ angles = map(lambda a: a + (a < 0) * 2 * math.pi, angles)
+ angles.sort()
+ angles += [angles[0] + 2 * math.pi]
+ 
+ LABclamp = clampSat
+ LABtoRGB = lambda lab: YSTtoRGB((lab[0]*.01,lab[1]*.01,lab[2]*.01))
+ 
+ def RGBtoLAB(rgb):
+     yst = RGBtoYST(rgb)
+     return [ -16 + 116 * pow(yst[0], 1./3), 100 * yst[1], 100 * yst[2] ]
+ 
+ def LABtoRGB(lab):
+     yst = [ pow((lab[0] + 16.0) / 116, 3), lab[1] / 100.0, lab[2] / 100.0 ]
+     return YSTtoRGB(yst)
+ """
Index: gzz/gfx/libpaper/colors.py
diff -c gzz/gfx/libpaper/colors.py:1.14 gzz/gfx/libpaper/colors.py:1.15
*** gzz/gfx/libpaper/colors.py:1.14     Fri Oct 11 08:17:47 2002
--- gzz/gfx/libpaper/colors.py  Mon Oct 14 13:49:30 2002
***************
*** 1,6 ****
  # Choosing colors and 3-dotproduct factors for papers.
  
! from gfx.libcolor.spaces import 
getRandomColor,getRandomColor2,RGBtoLAB,LABtoRGB,LABclamp,getangle
  
  from math import sin,cos,atan2,pi,log
  from random import Random,shuffle
--- 1,7 ----
  # Choosing colors and 3-dotproduct factors for papers.
  
! from gfx.libcolor.spaces import 
getRandomColor,getRandomColor2,YSTtoRGB,clampSat
! from gfx.libcolor.spaces import RGBtoLAB,LABtoRGB,LABclamp
  
  from math import sin,cos,atan2,pi,log
  from random import Random,shuffle
***************
*** 18,47 ****
  
          colors = 8
        minlum = 80
-         #huerange = (45 + rnd.nextGaussian() * 45)
          huerange = rnd.nextGaussian() * 90
  
          # Note: This color sampling scheme only produces
          # palettes with similar colors.
          # It could be nice to have other schemes
          # with, e.g., complementary colors.
!         # (Note: color complementing should be done in RGB space)
  
          # Sample hues uniformly from the range shifted to a random angle
!         if 0:
!             huerange *= pi / 180
!             hue0 = rnd.nextDouble() * 2*pi
!             hues = ([hue0, hue0 + huerange] + 
!                     [hue0 + rnd.nextDouble() * huerange for i in 
range(2,colors)])
!             shuffle(hues, rnd.nextDouble)
!         else:
!             huerange /= 360
!             hue0 = rnd.nextDouble()
!             hues = ([hue0, hue0 + huerange] + 
!                     [hue0 + rnd.nextDouble() * huerange for i in 
range(2,colors)])
!             hues = map(getangle, hues)
!             shuffle(hues, rnd.nextDouble)
!         
  
          # Take one half dark colors and one half light colors
          lumrange = 100 - minlum
--- 19,47 ----
  
          colors = 8
        minlum = 80
          huerange = rnd.nextGaussian() * 90
  
          # Note: This color sampling scheme only produces
          # palettes with similar colors.
          # It could be nice to have other schemes
          # with, e.g., complementary colors.
! 
!         # Add orange color to the color circle
!         def getangle(f):
!             # 0 = red, 120 = green, 240 = blue
!             angles = [ 0, 30, 60, 120, 180, 240, 300, 360 ]
!             n = len(angles) - 1
!             f *= n / 360.0
!             index = int(f) % n
!             fract = f - int(f)
!             return (1 - fract) * angles[index] + fract * angles[index + 1]
  
          # Sample hues uniformly from the range shifted to a random angle
!         hue0 = rnd.nextDouble() * 360
!         hues = ([hue0, hue0 + huerange] + 
!                 [hue0 + rnd.nextDouble() * huerange for i in range(2,colors)])
!         hues = map(getangle, hues)
!         shuffle(hues, rnd.nextDouble)
  
          # Take one half dark colors and one half light colors
          lumrange = 100 - minlum
***************
*** 54,67 ****
          # Sample saturation:
          #  - take the most saturated color 2/3 of the time
          #    and a dull color 1/3 of the time
!         sats = [100 * (1 - (1 - (1 - rnd.nextDouble())**2) * 
(rnd.nextDouble() < .333))
                  for i in range(0, colors)]
  
!         # Construct colors and clamp towards the CIELAB L-axis
!         # (keeping hue and luminance) to fit into the RGB cube
!         lab = [(lums[i], sats[i] * cos(hues[i]), sats[i] * sin(hues[i]))
!                for i in range(0,colors)]        
!         col = [LABclamp(LABtoRGB(c)) for c in lab]
          shuffle(col, rnd.nextDouble)
          
          if dbg:
--- 54,69 ----
          # Sample saturation:
          #  - take the most saturated color 2/3 of the time
          #    and a dull color 1/3 of the time
!         sats = [(1 - (1 - (1 - rnd.nextDouble())**2) * (rnd.nextDouble() < 
.333))
                  for i in range(0, colors)]
  
!         # Construct colors and clamp to RGB cube keeping hue and luminance 
constant
!         yst = [(pow((lums[i] + 16.0) / 116, 3),
!                 sats[i] * cos(hues[i]*pi/180),
!                 sats[i] * sin(hues[i]*pi/180))
!                for i in range(0,colors)]
!                    
!         col = [clampSat(YSTtoRGB(c)) for c in yst]
          shuffle(col, rnd.nextDouble)
          
          if dbg:




reply via email to

[Prev in Thread] Current Thread [Next in Thread]