Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!204.52.135.9.MISMATCH!newsfeed.hal-mli.net!feeder1.hal-mli.net!69.16.185.11.MISMATCH!npeer01.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!nx02.iad01.newshosting.com!newshosting.com!novia!news-out.readnews.com!news-xxxfer.readnews.com!panix!not-for-mail From: JohnF Newsgroups: comp.graphics.algorithms Subject: Re: decorative random colors algorithm Date: Mon, 2 Jul 2012 12:29:47 +0000 (UTC) Organization: PANIX Public Access Internet and UNIX, NYC Lines: 108 Message-ID: References: <2e449cd7-eba0-4741-968a-ab1404d568e2@googlegroups.com> NNTP-Posting-Host: panix3.panix.com X-Trace: reader1.panix.com 1341232187 26784 166.84.1.3 (2 Jul 2012 12:29:47 GMT) X-Complaints-To: abuse@panix.com NNTP-Posting-Date: Mon, 2 Jul 2012 12:29:47 +0000 (UTC) User-Agent: tin/2.0.0-20110823 ("Ardenistiel") (UNIX) (NetBSD/5.1.2 (i386)) X-Received-Bytes: 6588 Xref: csiph.com comp.graphics.algorithms:909 JohnF wrote: > gernot.hoffmann@hs-emden-leer.de wrote: >> >> you'll get better control over your colors if you use >> basically the HLS-model (and convert to RGB). >> For instance, you may map your pseudo-random-numbers to >> a limited Hue-range, Lightness-range and Saturation-range, >> for instance S=0.5...1.0 in order to avoid little satu- >> rated or washed-out colors. >> (1) >> http://www.fho-emden.de/~hoffmann/hlscone03052001.pdf >> The doc contains procedures for the conversions HLS<-->RGB >> in Pascal and PostScript. > > I already tried "nobody"'s suggestion, since it only took > about five minutes. And a first cut of yours is at forkosh.com/decorative3.ps That uses random h,l (still using drand48()) and s=1.0 fixed. But the C code below, mechanically taken (without a whole lot of understanding beforehand -- I need to add some meaningful comments) from your Section 7, accepts any args. I'll have to try more intelligently restricting the h,l,s ranges as you suggested above. Thanks again, /* ========================================================================== * Function: hlstorgb ( h,l,s, rgbswitch ) * 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. * -------------------------------------------------------------------------- * 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 * ======================================================================= */ /* --- entry point --- */ int hlstorgb ( double h, double l, double s, int rgbswitch ) { /* ------------------------------------------------------------------------- allocations and declarations -------------------------------------------------------------------------- */ int rgbcolor = 0, /* color returned to caller */ rgb[3]={0,0,0}, irgb=0; /* r=rgb[0], g=rgb[1], b=rgb[2] */ double hlsmax=0.0, hlsmin=0.0, hlsmmm=0.0; /* hls param max,min,max-min */ double hlshue=0.0, hlscolor=0.0; /* hls hue and color */ /* ------------------------------------------------------------------------- check input arguments -------------------------------------------------------------------------- */ if ( h<0.0 || h>=360.0 ) { /* restrict 0<=h<360 */ h = fmod(h,360.0); /* now -3601.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 */ /* ------------------------------------------------------------------------- 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; /*don't need this one*/ 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-job -------------------------------------------------------------------------- */ /*end_of_job:*/ switch ( rgbswitch ) { default: rgbcolor = 0; break; /* error */ case 0: rgbcolor = rgb[2] + 256*(rgb[1] + 256*rgb[0]); break; /*composite*/ case 1: rgbcolor = rgb[0]; break; /* red requested */ case 2: rgbcolor = rgb[1]; break; /* green requested */ case 3: rgbcolor = rgb[2]; break; } /* blue requested */ return ( rgbcolor ); /* back to caller with r,g,b or rgb */ } /* --- end-of-function hlstorgb() --- */ -- John Forkosh ( mailto: j@f.com where j=john and f=forkosh )