Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.graphics.algorithms > #928

Re: decorative random colors algorithm

From JohnF <john@please.see.sig.for.email.com>
Newsgroups comp.graphics.algorithms
Subject Re: decorative random colors algorithm
Date 2012-07-05 05:54 +0000
Organization PANIX Public Access Internet and UNIX, NYC
Message-ID <jt3a5q$hub$1@reader1.panix.com> (permalink)
References <jspf0f$moq$1@reader1.panix.com> <34b5c6a0-c79e-4a8f-bf71-4d480c9a5dc3@googlegroups.com> <jt3121$i2j$1@reader1.panix.com>

Show all headers | View raw


JohnF <john@please.see.sig.for.email.com> wrote:
> gernot.hoffmann@hs-emden-leer.de wrote:
>> On the other hand, I had recognized early, that this color space 
>> suffers much from a disadvantage: The saturation on the surface of 
>> the double cone is S=1. On the vertical axis we have S=0. Near to poles
>> we have in vicinity S=1 and S=0, which is in my opinion a not acceptable
>> discontinuity. In order to resolve this problem I had developed my own
>> HLS space, which uses S as a true cylinder coordinate - small S for 
>> small radius. At that time, trigonometric functions were sufficiently 
>> fast, using the standard floating point unit.  
> 
> Okay, I'll add your Section 8 code to my C function, along with
> an option to use either the "standard" or "hoffmann" method
> (yours will become the default, of course:).

Okay, that's done, and comparison "color circles" are at
forkosh.com/decorativef.ps and forkosh.com/decorativeho.ps (both eps).
The cgi has also been updated. Add attribute hlsmethod=1 for Foley
and hlsmethod=2 for Hoffmann, with 2 the default.

I don't see much visual difference, except maybe slightly brighter
yellows for "f" in the lower-right quadrant. Of course, it's not
a thorough exercise, with l=0.5,s=1.0 constant, with only variation
h=3degrees (positive-x axis), incrementing three per line clockwise.

But you can diff the downloaded files for more precise comparison, e.g.,
the first few lines of diff decorativef.ps decorativeho.ps are
  132c132
  < 0.78 0.00 0.78 1.00 0.05 0.00 setrgb01 % hls0=..., hls1=3.00,0.50,1.00
  ---
  > 0.78 0.00 0.78 1.00 0.18 0.13 setrgb01 % hls0=..., hls1=3.00,0.50,1.00
  135c135
  < 0.78 0.00 0.78 1.00 0.10 0.00 setrgb01 % hls0=..., hls1=6.00,0.50,1.00
  ---
  > 0.78 0.00 0.78 1.00 0.22 0.11 setrgb01 % hls0=..., hls1=6.00,0.50,1.00
So there's some numerical difference.

I think I got your (and Foley,van Dam's) algorithms right,
but have included the updated function below. For example,
I didn't have your limtab, and just clipped your single
r,g,b's to 1.0. Don't think that accounts for
any of the "diff difference".

/* ==========================================================================
 * Function:    hlstorgb ( h,l,s, rgb, method )
 * Purpose:     convert h,l,s color model cylindrical coordinates
 *              to equivalent cartesian r,g,b coordinates
 * --------------------------------------------------------------------------
 * Arguments:   h (I)           double containing hue "angle" in degrees,
 *                              0.0<=h<360.0
 *              l (I)           double containing lightness "vertical axis",
 *                              0.0<=l<=1.0
 *              s (I)           double containing saturation "radius",
 *                              0.0<=s<=1.0
 *              rgbswitch (I)   int containing 1 to return r(ed) coord,
 *                              2 for g(reen) coord, or 3 for b(lue) coord.
 *                              Alternatively, 0 returns ((256*r+g)*256)+b,
 *                              i.e., 24-bit composite with b in the low-order
 *                              eight bits, g in the next eight bits,
 *                              and r in the high-order (of 24) eight bits.
 *              method (I)      int containing 1 for standard Foley, van Dam
 *                              hls conversion, or containing 2 for
 *                              Hoffmann conversion (see Notes below).
 * --------------------------------------------------------------------------
 * Returns:     ( int )         r or g or b, if rgb=1 or 2 or 3, respectively,
 *                              or ((256*r+g)*256)+b composite if rgb=0,
 *                              or 0 for any error.
 * --------------------------------------------------------------------------
 * Notes:     o See http://www.fho-emden.de/~hoffmann/hlscone03052001.pdf
 *              for discussion, derivation, and pascal/postscript code
 *              from which this function was taken.
 * ======================================================================= */
/* --- entry point --- */
int     hlstorgb ( double h, double l, double s, int rgbswitch, int method )
{
/* -------------------------------------------------------------------------
allocations and declarations
-------------------------------------------------------------------------- */
int     rgb[3]={0,0,0}, irgb=0;         /* r=rgb[0], g=rgb[1], b=rgb[2] */
/* -------------------------------------------------------------------------
check input arguments
-------------------------------------------------------------------------- */
if ( h<0.0 || h>=360.0 ) {              /* restrict 0<=h<360 */
  h = fmod(h,360.0);                    /* now -360<h<+360 */
  if ( h < 0.0 ) h += 360.0; }          /* now 0<=360<h, as needed below */
if (l<0.0) l=0.0;  if (l>1.0) l=1.0;    /* restrict 0<=l<=1 */
if (s<0.0) s=0.0;  if (s>1.0) s=1.0;    /* restrict 0<=s<=1 */
if (rgbswitch<0) rgbswitch=0;           /* interpret as 0 */
if (rgbswitch>3) rgbswitch=(rgbswitch%4); /* interpret mod 4 */
if (method<1) method=1;  if (method>2) method=2; /* only method=1,2 exist */
/* -------------------------------------------------------------------------
Foley, van Dam method...
-------------------------------------------------------------------------- */
if ( method == 1 ) {
  /* ---
  allocations and declarations
  ---------------------------- */
  double hlsmax=0.0, hlsmin=0.0, hlsmmm=0.0; /* hls params max,min,max-min */
  double hlshue=0.0, hlscolor=0.0;      /* hls hue and color */
  /* ---
  hls parameterization
  -------------------- */
  hlsmax = ((l<=0.5)? l*(1.0+s) : (l+s)-(l*s));
  hlsmin = 2.0*l - hlsmax;
  hlsmmm = (hlsmax - hlsmin)/60.0;
  /* ---
  loop over red, green, blue
  -------------------------- */
  for ( irgb=0; irgb<=2; irgb++ ) {     /* for each rgb component */
    if ( rgbswitch!=0 && rgbswitch!=irgb+1 ) continue;/*this one not needed*/
    hlshue = h + 120.0*((double)(1-irgb)); /* h+120, h, h-120 */
    if ( irgb==0 ) { if ( hlshue > 360.0 ) hlshue -= 360.0; }
    if ( irgb==2 ) { if ( hlshue < 0.0 )   hlshue += 360.0; }
    if ( hlshue < 60.0 )
      hlscolor = hlsmin + hlsmmm*hlshue;
    else if ( hlshue < 180.0 )
      hlscolor = hlsmax;
    else if ( hlshue < 240.0 )
      hlscolor = hlsmin + hlsmmm*(240.0-hlshue);
    else
      hlscolor = hlsmin;
    rgb[irgb] = (int)(0.5+(hlscolor*255.0));
    } /* --- end-of-for(irgb) --- */
  } /* --- end-of-if(method==1) --- */
/* -------------------------------------------------------------------------
Hoffmann method...
-------------------------------------------------------------------------- */
if ( method == 2 ) {
  /* ---
  allocations and declarations
  ---------------------------- */
  double
    pi = 3.14159265359,                 /*pi (convert 0<=h<=360 to radians)*/
    hcos = cos(h*pi/180.), hsin = sin(h*pi/180.), /* cos,sin(h in radians) */
    h0 = 30.0 + 60.0*((double)((int)(h/60.))),
    h0cos=cos(h0*pi/180.), h0sin=sin(h0*pi/180.); /* cos,sin(h0 in radians)*/
  double
    d = 0.5*sqrt(3.0)*s/((hcos*h0cos)+(hsin*h0sin)),
    u = hcos*d/3.0,
    v = hsin*d/sqrt(3.0);
  double
    r = l+u+u,  g = l-u+v,  b = l-u-v;
  double
    rgbmax = (r>g? (r>b?r:b) : (g>b?g:b));
  if ( rgbmax > 1.0 ) {
    r /= rgbmax;  g /= rgbmax;  b /= rgbmax; }
  rgb[0] = (int)(255.0*r + 0.5);
  rgb[1] = (int)(255.0*g + 0.5);
  rgb[2] = (int)(255.0*b + 0.5);
  } /* --- end-of-if(method==2) --- */
/* -------------------------------------------------------------------------
end-of-job
-------------------------------------------------------------------------- */
/*end_of_job:*/
return ( (rgbswitch==0?                 /* back with r,g,b or composite */
        rgb[2] + 256*(rgb[1] + 256*rgb[0]) : /* rgb composite */
        rgb[rgbswitch-1]) );            /* r,g,b component */
} /* --- end-of-function hlstorgb() --- */

-- 
John Forkosh  ( mailto:  j@f.com  where j=john and f=forkosh )

Back to comp.graphics.algorithms | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-01 12:15 +0000
  Re: decorative random colors algorithm gernot.hoffmann@hs-emden-leer.de - 2012-07-01 07:59 -0700
    Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-02 07:58 +0000
      Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-02 12:29 +0000
  Re: decorative random colors algorithm Nobody <nobody@nowhere.com> - 2012-07-01 16:25 +0100
    Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-02 08:28 +0000
  Re: decorative random colors algorithm gernot.hoffmann@hs-emden-leer.de - 2012-07-03 01:17 -0700
    Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-03 10:27 +0000
  Re: decorative random colors algorithm gernot.hoffmann@hs-emden-leer.de - 2012-07-03 21:50 -0700
    Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-04 05:15 +0000
      Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-04 08:01 +0000
  Re: decorative random colors algorithm gernot.hoffmann@hs-emden-leer.de - 2012-07-04 02:20 -0700
    Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-04 09:51 +0000
      Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-04 10:59 +0000
        Re: decorative random colors algorithm Wally W. <ww84wa@aim.com> - 2012-07-04 09:03 -0400
          Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-04 13:46 +0000
            Re: decorative random colors algorithm Wally W. <ww84wa@aim.com> - 2012-07-04 12:39 -0400
  Re: decorative random colors algorithm gernot.hoffmann@hs-emden-leer.de - 2012-07-04 07:10 -0700
    Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-04 15:05 +0000
  Re: decorative random colors algorithm gernot.hoffmann@hs-emden-leer.de - 2012-07-04 09:12 -0700
    Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-05 03:18 +0000
      Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-05 05:54 +0000
        Re: decorative random colors algorithm John Forkosh <forkosh@panix.com> - 2012-07-05 12:23 +0000
  Re: decorative random colors algorithm "Skybuck Flying" <Windows7IsOK@DreamPC2006.com> - 2012-07-05 07:48 +0200
    Re: decorative random colors algorithm JohnF <john@please.see.sig.for.email.com> - 2012-07-05 06:14 +0000
    Re: decorative random colors algorithm Wally W. <ww84wa@aim.com> - 2012-07-05 07:30 -0400

csiph-web