File Coverage

blib/lib/Graphics/Colourset.pm
Criterion Covered Total %
statement 9 172 5.2
branch 0 80 0.0
condition 0 470 0.0
subroutine 3 10 30.0
pod 7 7 100.0
total 19 739 2.5


line stmt bran cond sub pod time code
1             package Graphics::Colourset;
2 2     2   43797 use strict;
  2         5  
  2         441  
3 2     2   12 use warnings;
  2         5  
  2         142  
4              
5             =head1 NAME
6              
7             Graphics::Colourset - create sets of colours.
8              
9             =head1 VERSION
10              
11             This describes version B<0.01> of Graphics::Colourset.
12              
13             =cut
14              
15             our $VERSION = '0.01';
16              
17             =head1 SYNOPSIS
18              
19             use Graphics::Colourset;
20              
21             my $cs1 = Graphics::Colourset->new(hue=>60, shade=>1);
22              
23             my $col_str = $cs1->as_hex_string('foreground');
24              
25             my $cs2 = $cs1->new_alt_colourset(shade=>4);
26              
27             my @colsets = $cs1->new_alt_coloursets(3);
28              
29             =head1 DESCRIPTION
30              
31             This module generates the colour definitions of a set of colours
32             suitable for using as the basis of a colour-scheme for an X-Windows
33             window-manager. They can also be used for CSS colour descriptions for
34             Web-pages. The colours are defined as the usual "hex string",
35             or as the more recent "rgb string".
36              
37             The aim of this is to avoid having to generate harmonious colour schemes
38             by hand but to input a minimum number of parameters and to create all
39             the colours from that.
40              
41             =head1 DETAILS
42              
43             =head2 Coloursets
44              
45             A "colourset" is a set of five colours, suitable for defining one type
46             of component in a window-manager or web-site "theme" or "colour scheme".
47             All colours in a colourset have the same hue, but have different
48             saturation and value (different "strengths") in keeping with their
49             different roles.
50              
51             They are oriented towards being used for generating colours for buttons
52             and borders.
53              
54             =over
55              
56             =item background
57              
58             The background colour is the main colour of the colourset, to be used
59             for the background of the "component" (whatever that may be).
60              
61             =item topshadow
62              
63             The topshadow colour is a colour slightly lighter than the background
64             colour, suitable for using to define a "top shadow" colour.
65              
66             =item bottomshadow
67              
68             The bottomshadow colour is a colour slightly darker than the background
69             colour, suitable for using to define a "bottom shadow" colour.
70              
71             =item foreground
72              
73             The foreground colour is the colour designated to be used for the
74             foreground, for text and the like. It is either much lighter or much
75             darker than the background colour, in order to contrast suitably.
76              
77             =item foreground_inactive
78              
79             The "inactive" foreground colour is a colour which is intended to be
80             used for things which are "greyed out", or not active. It is a colour
81             which contrasts with the background, but not as much as the "foreground"
82             colour.
83              
84             =back
85              
86             There are two parameters which determine the colours of a colourset.
87              
88             =over
89              
90             =item hue
91              
92             The hue in a 360 degree colour wheel. As a special tweak, if the hue
93             equals 360, it is taken to be no hue at all (grey). This doesn't
94             actually lose any hues, since 360 is normally exactly the same as zero
95             (red).
96              
97             =item shade
98              
99             The general "lightness" of the background. This is a range from 1 to 4, with 1
100             being the darkest and 4 being the lightest. This also determines the
101             foreground colour, since a dark background will need a light foreground and
102             visa-versa.
103              
104             If the shade is outside this range, a random shade will be picked.
105              
106             =back
107              
108             =head2 Base and Alternative Coloursets
109              
110             The "base" colourset is considered to be the main colourset; additional
111             coloursets can be generated which are related to the base colourset in a
112             contrasting-but-harmonious way.
113              
114             One test for the harmoniousness is to compare two coloursets and decide
115             whether they would be "ugly" together. This is done in a rule-of-thumb
116             way, which isn't perfect.
117              
118             =cut
119              
120 2     2   2418 use Graphics::ColorObject;
  2         129970  
  2         5560  
121              
122             =head1 CLASS METHODS
123              
124             =head2 new
125              
126             Create a new colourset, given an input hue, and foreground/background
127             disposition.
128              
129             $my colset = Graphics::Colourset->new(
130             hue=>$hue,
131             shade=>1,
132             );
133              
134             =cut
135              
136             sub new {
137 0     0 1   my $class = shift;
138 0           my %parameters = @_;
139 0   0       my $self = bless ({%parameters}, ref ($class) || $class);
140 0   0       $self->{hue} ||= 0;
141 0 0         $self->{shade} = 0 if !defined $self->{shade};
142              
143 0 0 0       if ($self->{shade} < 1 or $self->{shade} > 4)
144             {
145 0           $self->{shade} = int(rand(4)) + 1;
146             }
147              
148 0 0         if ($self->{hue} == 360) # make it grey
149             {
150 0 0         if ($self->{shade} == 1) # darkest
    0          
    0          
    0          
151             {
152 0           $self->{foreground} =
153             Graphics::ColorObject->new_HSV([0, 0, 0.99]);
154 0           $self->{foreground_inactive} =
155             Graphics::ColorObject->new_HSV([0, 0, 0.70]);
156 0           $self->{background} =
157             Graphics::ColorObject->new_HSV([0, 0, 0.40]);
158 0           $self->{topshadow} =
159             Graphics::ColorObject->new_HSV([0, 0, 0.50]);
160 0           $self->{bottomshadow} =
161             Graphics::ColorObject->new_HSV([0, 0, 0.30]);
162             }
163             elsif ($self->{shade} == 2)
164             {
165 0           $self->{foreground} =
166             Graphics::ColorObject->new_HSV([0, 0, 0.95]);
167 0           $self->{foreground_inactive} =
168             Graphics::ColorObject->new_HSV([0, 0, 0.80]);
169 0           $self->{background} =
170             Graphics::ColorObject->new_HSV([0, 0, 0.60]);
171 0           $self->{topshadow} =
172             Graphics::ColorObject->new_HSV([0, 0, 0.70]);
173 0           $self->{bottomshadow} =
174             Graphics::ColorObject->new_HSV([0, 0, 0.50]);
175             }
176             elsif ($self->{shade} == 3)
177             {
178 0           $self->{foreground} =
179             Graphics::ColorObject->new_HSV([0, 0, 0.05]);
180 0           $self->{foreground_inactive} =
181             Graphics::ColorObject->new_HSV([0, 0, 0.60]);
182 0           $self->{background} =
183             Graphics::ColorObject->new_HSV([0, 0, 0.75]);
184 0           $self->{topshadow} =
185             Graphics::ColorObject->new_HSV([0, 0, 0.85]);
186 0           $self->{bottomshadow} =
187             Graphics::ColorObject->new_HSV([0, 0, 0.65]);
188             }
189             elsif ($self->{shade} == 4) # lightest
190             {
191 0           $self->{foreground} =
192             Graphics::ColorObject->new_HSV([0, 0, 0.20]);
193 0           $self->{foreground_inactive} =
194             Graphics::ColorObject->new_HSV([0, 0, 0.55]);
195 0           $self->{background} =
196             Graphics::ColorObject->new_HSV([0, 0, 0.88]);
197 0           $self->{topshadow} =
198             Graphics::ColorObject->new_HSV([0, 0, 0.96]);
199 0           $self->{bottomshadow} =
200             Graphics::ColorObject->new_HSV([0, 0, 0.78]);
201             }
202             }
203             else # coloured
204             {
205 0 0         if ($self->{shade} == 1) # darkest
    0          
    0          
    0          
206             {
207 0           $self->{foreground} =
208             Graphics::ColorObject->new_HSV([$self->{hue},
209             0.10, 0.99]);
210 0           $self->{foreground_inactive} =
211             Graphics::ColorObject->new_HSV([$self->{hue},
212             0.30, 0.80]);
213 0           $self->{background} =
214             Graphics::ColorObject->new_HSV([$self->{hue},
215             0.90, 0.60]);
216 0           $self->{topshadow} =
217             Graphics::ColorObject->new_HSV([$self->{hue},
218             0.70, 0.75]);
219 0           $self->{bottomshadow} =
220             Graphics::ColorObject->new_HSV([$self->{hue},
221             0.90, 0.40]);
222             }
223             elsif ($self->{shade} == 2)
224             {
225 0           $self->{foreground} =
226             Graphics::ColorObject->new_HSV([$self->{hue},
227             0, 0.99]);
228 0           $self->{foreground_inactive} =
229             Graphics::ColorObject->new_HSV([$self->{hue},
230             0.30, 0.90]);
231 0           $self->{background} =
232             Graphics::ColorObject->new_HSV([$self->{hue},
233             0.80, 0.80]);
234 0           $self->{topshadow} =
235             Graphics::ColorObject->new_HSV([$self->{hue},
236             0.50, 0.95]);
237 0           $self->{bottomshadow} =
238             Graphics::ColorObject->new_HSV([$self->{hue},
239             0.80, 0.65]);
240             }
241             elsif ($self->{shade} == 3)
242             {
243 0 0 0       if ($self->{hue} > 220 && $self->{hue} < 280)
244             {
245             # blue/purple are too dark to deal with this
246 0           $self->{foreground} =
247             Graphics::ColorObject->new_HSV([$self->{hue},
248             0.99, 0.05]);
249 0           $self->{foreground_inactive} =
250             Graphics::ColorObject->new_HSV([$self->{hue},
251             0.90, 0.60]);
252 0           $self->{background} =
253             Graphics::ColorObject->new_HSV([$self->{hue},
254             0.50, 0.85]);
255 0           $self->{topshadow} =
256             Graphics::ColorObject->new_HSV([$self->{hue},
257             0.50, 0.95]);
258 0           $self->{bottomshadow} =
259             Graphics::ColorObject->new_HSV([$self->{hue},
260             0.70, 0.75]);
261             }
262             else
263             {
264 0           $self->{foreground} =
265             Graphics::ColorObject->new_HSV([$self->{hue},
266             0.99, 0.05]);
267 0           $self->{foreground_inactive} =
268             Graphics::ColorObject->new_HSV([$self->{hue},
269             0.90, 0.60]);
270 0           $self->{background} =
271             Graphics::ColorObject->new_HSV([$self->{hue},
272             0.85, 0.95]);
273 0           $self->{topshadow} =
274             Graphics::ColorObject->new_HSV([$self->{hue},
275             0.50, 0.99]);
276 0           $self->{bottomshadow} =
277             Graphics::ColorObject->new_HSV([$self->{hue},
278             0.70, 0.80]);
279             }
280             }
281             elsif ($self->{shade} == 4) # lightest
282             {
283 0           $self->{foreground} =
284             Graphics::ColorObject->new_HSV([$self->{hue},
285             0.90, 0.20]);
286 0           $self->{foreground_inactive} =
287             Graphics::ColorObject->new_HSV([$self->{hue},
288             0.40, 0.55]);
289 0           $self->{background} =
290             Graphics::ColorObject->new_HSV([$self->{hue},
291             0.30, 0.90]);
292 0           $self->{topshadow} =
293             Graphics::ColorObject->new_HSV([$self->{hue},
294             0.20, 0.95]);
295 0           $self->{bottomshadow} =
296             Graphics::ColorObject->new_HSV([$self->{hue},
297             0.40, 0.75]);
298             }
299             }
300 0           return ($self);
301             } # new
302              
303             =head1 OBJECT METHODS
304              
305             =head2 as_hex_string
306              
307             my $colstr = $self->as_hex_string('foreground');
308              
309             Return the given colour as a hex colour string
310             such as #99FF00
311              
312             =cut
313              
314             sub as_hex_string {
315 0     0 1   my $self = shift;
316 0           my $colour = shift;
317              
318 0           my $hex = $self->{$colour}->as_RGBhex();
319 0           return "#$hex";
320             } # as_hex_string
321              
322             =head2 as_rgb_string
323              
324             my $colstr = $self->as_rgb_string('foreground');
325              
326             Return the given colour as an X colour string
327             such as rgb:99/FF/00
328              
329             =cut
330              
331             sub as_rgb_string {
332 0     0 1   my $self = shift;
333 0           my $colour = shift;
334              
335 0           my ($r, $g, $b) = @{$self->{$colour}->as_RGB255()};
  0            
336 0           return sprintf("rgb:%02X/%02X/%02X", $r, $g, $b);
337             } # as_rgb_string
338              
339             =head2 equals
340              
341             Checks if the given colourset equals the passed-in one.
342              
343             if ($colset->equals($other_colset))
344             {
345             ...
346             }
347              
348             =cut
349             sub equals {
350 0     0 1   my $self = shift;
351 0           my $colset2 = shift;
352              
353 0   0       return ($self->{hue} == $colset2->{hue}
354             && $self->{shade} == $colset2->{shade});
355             } # equals
356              
357             =head2 is_ugly
358              
359             my $ret = $colset1->is_ugly($colset2);
360              
361             Compares two coloursets and declares whether they would be ugly
362             together. This is naturally a subjective assessment on the part of
363             the author, but hopefully helpful.
364              
365             =cut
366             sub is_ugly {
367 0     0 1   my $colset1 = shift;
368 0           my $colset2 = shift;
369              
370 0 0 0       if (($colset1->{hue} == 360
    0 0        
    0 0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
371             && $colset2->{hue} >= 50
372             && $colset2->{hue} <= 80)
373             || ($colset2->{hue} == 360
374             && $colset1->{hue} >= 50
375             && $colset1->{hue} <= 80))
376             {
377             # yellow doesn't go with grey
378 0           return 1;
379             }
380             elsif (($colset1->{hue} == 360
381             && $colset2->{hue} > 10
382             && $colset2->{hue} < 50
383             && $colset2->{shade} > 1)
384             || ($colset2->{hue} == 360
385             && $colset1->{hue} > 10
386             && $colset1->{hue} < 50
387             && $colset1->{shade} > 1))
388             {
389             # orange only looks good if it's dark
390 0           return 1;
391             }
392             elsif ($colset1->{hue} == 360
393             || $colset2->{hue} == 360)
394             {
395             # everything else goes with grey
396 0           return 0;
397             }
398             # all colours within 30 degrees of each other look good
399 0           my $hdiff = abs($colset1->{hue} - $colset2->{hue});
400 0 0         if ($hdiff <= 30)
401             {
402 0           return 0;
403             }
404            
405 0 0 0       if (($colset1->{hue} >= 0
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
406             && $colset1->{hue} < 10
407             && $colset1->{shade} == 4
408             && $colset2->{hue} >= 60
409             && $colset2->{hue} < 70
410             && $colset2->{shade} != 4)
411             || ($colset2->{hue} >= 0
412             && $colset2->{hue} < 10
413             && $colset2->{shade} == 4
414             && $colset1->{hue} >= 60
415             && $colset1->{hue} < 70
416             && $colset1->{shade} != 4))
417             {
418             # rose doesn't go with yellow or green
419 0           return 1;
420             }
421 0 0 0       if (($colset1->{hue} > 10
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
422             && $colset1->{hue} <= 40
423             && $colset1->{shade} > 1
424             && $colset1->{shade} < 4
425             && $colset2->{hue} > 60
426             && $colset2->{hue} <= 100)
427             || ($colset2->{hue} > 10
428             && $colset2->{hue} <= 40
429             && $colset2->{shade} > 1
430             && $colset2->{shade} < 4
431             && $colset1->{hue} > 60
432             && $colset1->{hue} <= 100))
433             {
434             # orange doesn't go with green
435 0           return 1;
436             }
437 0 0 0       if (($colset1->{hue} >= 270
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
438             && $colset1->{hue} < 280
439             && $colset2->{hue} >= 330
440             && $colset2->{hue} < 340
441             && $colset2->{shade} > 1)
442             || ($colset2->{hue} >= 270
443             && $colset2->{hue} < 280
444             && $colset1->{hue} >= 330
445             && $colset1->{hue} < 340
446             && $colset1->{shade} > 1))
447             {
448             # purple doesn't go with pinky-red
449 0           return 1;
450             }
451 0 0 0       if (($colset1->{hue} >= 280
      0        
      0        
      0        
      0        
      0        
      0        
452             && $colset1->{hue} < 360
453             && (($colset2->{hue} >= 340
454             && $colset2->{hue} < 360)
455             || ($colset2->{hue} >= 0
456             && $colset2->{hue} < 50))
457             )
458             || ($colset2->{hue} >= 280
459             && $colset2->{hue} < 360
460             && (($colset1->{hue} >= 340
461             && $colset1->{hue} < 360)
462             || ($colset1->{hue} >= 0
463             && $colset1->{hue} < 50))
464             )
465             )
466             {
467             # violet doesn't go with pink/red
468 0           return 1;
469             }
470 0 0 0       if (($colset1->{hue} > 10
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
471             && $colset1->{hue} <= 40
472             && ($colset1->{shade} == 2
473             || $colset1->{shade} == 3)
474             && $colset2->{hue} > 100
475             && $colset2->{hue} <= 130)
476             || ($colset2->{hue} > 10
477             && $colset2->{hue} <= 40
478             && ($colset2->{shade} == 2
479             || $colset2->{shade} == 3)
480             && $colset1->{hue} > 100
481             && $colset1->{hue} <= 130))
482             {
483             # orange doesn't go with green
484 0           return 1;
485             }
486 0 0 0       if (($colset1->{hue} >= 260
      0        
      0        
      0        
      0        
      0        
      0        
487             && $colset1->{hue} < 280
488             && (($colset2->{hue} >= 350
489             && $colset2->{hue} < 360)
490             || ($colset2->{hue} >= 0
491             && $colset2->{hue} <= 10)))
492             || ($colset2->{hue} >= 260
493             && $colset2->{hue} < 280
494             && (($colset1->{hue} >= 350
495             && $colset1->{hue} < 360)
496             || ($colset1->{hue} >= 0
497             && $colset1->{hue} <= 10))))
498             {
499             # purple doesn't go with tomato-red or rose
500 0           return 1;
501             }
502 0 0 0       if (($colset1->{hue} >= 280
      0        
      0        
      0        
      0        
      0        
      0        
503             && $colset1->{hue} < 350
504             && $colset2->{hue} >= 10
505             && $colset2->{hue} < 80)
506             || ($colset2->{hue} >= 280
507             && $colset2->{hue} < 350
508             && $colset1->{hue} >= 10
509             && $colset1->{hue} < 80))
510             {
511             # purple & pink don't go with orange, yellow or green
512 0           return 1;
513             }
514 0 0 0       if (($colset1->{hue} > 10
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
515             && $colset1->{hue} < 90
516             && $colset1->{shade} != 1
517             && $colset2->{hue} > 130
518             && $colset2->{hue} < 210
519             && $colset2->{shade} != 1)
520             || ($colset2->{hue} > 10
521             && $colset2->{hue} < 90
522             && $colset2->{shade} != 1
523             && $colset1->{hue} > 130
524             && $colset1->{hue} < 210
525             && $colset1->{shade} != 1))
526             {
527             # orange & yellow don't go with green or cyan
528 0           return 1;
529             }
530 0 0 0       if (($colset1->{hue} > 50
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
531             && $colset1->{hue} < 70
532             && $colset1->{shade} == 1
533             && $colset2->{hue} > 130
534             && $colset2->{hue} < 210
535             && $colset2->{shade} != 1)
536             || ($colset2->{hue} > 50
537             && $colset2->{hue} < 70
538             && $colset2->{shade} == 1
539             && $colset1->{hue} > 130
540             && $colset1->{hue} < 210
541             && $colset1->{shade} != 1))
542             {
543             # Khaki doesn't go with green or cyan
544 0           return 1;
545             }
546 0 0 0       if (($colset1->{hue} > 150
      0        
      0        
      0        
      0        
      0        
      0        
547             && $colset1->{hue} < 200
548             && $colset2->{hue} > 270
549             && $colset2->{hue} < 320)
550             || ($colset2->{hue} > 150
551             && $colset2->{hue} < 200
552             && $colset1->{hue} > 270
553             && $colset1->{hue} < 320))
554             {
555             # turquoise/cyan doesn't go with orchid
556 0           return 1;
557             }
558 0 0 0       if (($colset1->{hue} > 240
      0        
      0        
      0        
      0        
      0        
      0        
559             && $colset1->{hue} < 290
560             && $colset2->{hue} > 0
561             && $colset2->{hue} < 50)
562             || ($colset2->{hue} > 240
563             && $colset2->{hue} < 290
564             && $colset1->{hue} > 0
565             && $colset1->{hue} < 50))
566             {
567             # blue/purple doesn't go with orange
568 0           return 1;
569             }
570 0 0 0       if ($colset1->{hue} >= 290
      0        
      0        
571             && $colset1->{hue} < 350
572             && $colset2->{hue} >= 50
573             && $colset2->{hue} < 110)
574             {
575             # violet/pink doesn't go with yellow/green
576 0           return 1;
577             }
578            
579             # glary colour don't do well with dull or pale
580             # unless they're the same hue
581 0 0 0       if ((($colset1->{shade} == 3
      0        
582             && ($colset1->{hue} < 200
583             || $colset1->{hue} > 280)
584             && ($colset2->{shade} == 2
585             || $colset2->{shade} == 4))
586             || ($colset2->{shade} == 3
587             && ($colset2->{hue} < 200
588             || $colset2->{hue} > 280)
589             && ($colset1->{shade} == 2
590             || $colset1->{shade} == 4)))
591             && $colset1->{hue} != $colset2->{hue})
592             {
593 0           return 1;
594             }
595             # pink doesn't go with green or yellow, even though red does
596 0 0 0       if (($colset1->{hue} >= 0
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
597             && $colset1->{hue} < 30
598             && $colset1->{shade} == 4
599             && $colset2->{hue} > 60
600             && $colset2->{hue} <= 120
601             && $colset2->{shade} != 4)
602             || ($colset2->{hue} >= 0
603             && $colset2->{hue} < 30
604             && $colset2->{shade} == 4
605             && $colset1->{hue} > 60
606             && $colset1->{hue} <= 120
607             && $colset1->{shade} != 4))
608             {
609 0           return 1;
610             }
611             # pale orange doesn't go with green
612 0 0 0       if (($colset1->{hue} >= 30
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
613             && $colset1->{hue} < 50
614             && $colset1->{shade} == 4
615             && $colset2->{hue} > 90
616             && $colset2->{hue} <= 130
617             && $colset2->{shade} != 4)
618             || ($colset2->{hue} >= 30
619             && $colset2->{hue} < 50
620             && $colset2->{shade} == 4
621             && $colset1->{hue} > 90
622             && $colset1->{hue} <= 130
623             && $colset1->{shade} != 4))
624             {
625 0           return 1;
626             }
627             # glary red don't like khaki
628 0 0 0       if (($colset1->{hue} >= 0
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
629             && $colset1->{hue} < 30
630             && $colset1->{shade} == 3
631             && $colset2->{hue} > 50
632             && $colset2->{hue} < 70
633             && $colset2->{shade} != 3)
634             || ($colset2->{hue} >= 0
635             && $colset2->{hue} < 30
636             && $colset2->{shade} == 3
637             && $colset1->{hue} > 50
638             && $colset1->{hue} < 70
639             && $colset1->{shade} != 3))
640             {
641 0           return 1;
642             }
643              
644 0           return 0;
645             } # is_ugly
646              
647             =head2 new_alt_colourset
648              
649             my $alt = $colset->new_alt_colourset(shade=>$shade,
650             hue=>$hue);
651              
652             Make an alternative colourset based on the input "base" colourset.
653              
654             If both hue and shade are given, use those. Otherwise randomly generate (one or both) but check with is_ugly to ensure that it isn't ugly. It will also be checked to make sure that it isn't the same as the base colourset.
655              
656             =cut
657             sub new_alt_colourset {
658 0     0 1   my $self = shift;
659 0           my %args = (
660             hue=>undef,
661             shade=>undef,
662             @_
663             );
664 0           my $shade = $args{shade};
665 0           my $hue2 = $args{hue};
666              
667 0           my $basehue = $self->{hue};
668              
669             # make the second hue a random given interval away
670 0           my @intervals = qw(0 30 60 90 120 -30 -60 -90 -120);
671             # add the diff for grey
672 0           push @intervals, (360 - $basehue);
673 0 0         if (!defined $hue2)
674             {
675 0           $hue2 = $basehue + $intervals[int(rand(@intervals))];
676 0 0         $hue2 += 360 if ($hue2 < 0);
677 0 0         $hue2 -= 360 if ($hue2 > 360);
678             }
679 0           my $newalt = Graphics::Colourset->new(hue=>$hue2, shade=>$shade);
680 0   0       while ($self->equals($newalt)
681             || $self->is_ugly($newalt))
682             {
683 0           $hue2 = $basehue + $intervals[int(rand(@intervals))];
684 0 0         $hue2 += 360 if ($hue2 < 0);
685 0 0         $hue2 -= 360 if ($hue2 > 360);
686 0           $newalt = Graphics::Colourset->new(hue=>$hue2, shade=>$shade);
687             }
688 0           return $newalt;
689             } # new_alt_colourset
690              
691             =head2 new_alt_coloursets
692              
693             my @colsets = $colset->new_alt_coloursets($num);
694              
695             Make $num alternative coloursets based on the input "base" colourset.
696             The hue and shade of the alt colourset will be randomly generated, but
697             checked with is_ugly to ensure that it isn't ugly. It will also be checked
698             to make sure that they aren't the same as the base colourset!
699              
700             my @colsets = $colset->new_alt_coloursets(4,
701             shades=>[1,0,3,4],
702             hues=>[10,50,undef,undef]);
703              
704             If the optional shades are given, then the shades will be those shades.
705             If the optional hues are given, then the hues will be those hues.
706             A negative hue means pick a random hue.
707              
708             Note that larger numbers will take longer and be more difficult to generate.
709              
710             =cut
711             sub new_alt_coloursets {
712 0     0 1   my $self = shift;
713 0           my $num_colsets = shift;
714 0           my %args = (
715             shades=>undef,
716             hues=>undef,
717             @_
718             );
719              
720             # set an array of shades; by default zero means random
721 0           my @shades = ();
722 0           for (my $i = 0; $i < $num_colsets; $i++)
723             {
724 0           $shades[$i] = 0;
725             }
726             # if shades are passed in, use them
727 0 0         if (defined $args{shades})
728             {
729 0           for (my $i = 0; $i < @{$args{shades}}; $i++)
  0            
730             {
731 0           $shades[$i] = $args{shades}->[$i];
732             }
733             }
734             # set an array of hues; by default undefined means random
735 0           my @hues = ();
736 0           for (my $i = 0; $i < $num_colsets; $i++)
737             {
738 0           $hues[$i] = undef;
739             }
740             # if hues are passed in, use them
741 0 0         if (defined $args{hues})
742             {
743 0           for (my $i = 0; $i < @{$args{hues}}; $i++)
  0            
744             {
745 0           $hues[$i] = $args{hues}->[$i];
746             }
747             }
748              
749 0           my $basehue = $self->{hue};
750              
751 0           my @colsets = ();
752              
753 0           while (@colsets < $num_colsets)
754             {
755 0           my $newalt;
756 0           my $is_okay = 0;
757 0           while (!$is_okay)
758             {
759             # get the index of the next colset
760 0           my $ind = @colsets;
761 0           my $shade = $shades[$ind];
762 0           my $hue = $hues[$ind];
763 0           $newalt = $self->new_alt_colourset(hue=>$hue,
764             shade=>$shade);
765 0           $is_okay = 1;
766 0           foreach my $cs (@colsets)
767             {
768 0 0 0       if ($newalt->equals($cs)
769             || $newalt->is_ugly($cs))
770             {
771 0           $is_okay = 0;
772 0           last;
773             }
774             }
775             }
776 0           push @colsets, $newalt;
777             }
778 0           return @colsets;
779             } # new_alt_coloursets
780              
781             =head1 REQUIRES
782              
783             Graphics::ColorObject
784             Getopt::Long
785             Getopt::ArgvFile
786             Pod::Usage
787             Test::More
788              
789             =head1 INSTALLATION
790              
791             To install this module, run the following commands:
792              
793             perl Build.PL
794             ./Build
795             ./Build test
796             ./Build install
797              
798             Or, if you're on a platform (like DOS or Windows) that doesn't like the
799             "./" notation, you can do this:
800              
801             perl Build.PL
802             perl Build
803             perl Build test
804             perl Build install
805              
806             In order to install somewhere other than the default, such as
807             in a directory under your home directory, like "/home/fred/perl"
808             go
809              
810             perl Build.PL --install_base /home/fred/perl
811              
812             as the first step instead.
813              
814             This will install the files underneath /home/fred/perl.
815              
816             You will then need to make sure that you alter the PERL5LIB variable to
817             find the modules, and the PATH variable to find the script.
818              
819             Therefore you will need to change:
820             your path, to include /home/fred/perl/script (where the script will be)
821              
822             PATH=/home/fred/perl/script:${PATH}
823              
824             the PERL5LIB variable to add /home/fred/perl/lib
825              
826             PERL5LIB=/home/fred/perl/lib:${PERL5LIB}
827              
828             =head1 SEE ALSO
829              
830             perl(1).
831              
832             =head1 BUGS
833              
834             Please report any bugs or feature requests to the author.
835              
836             =head1 AUTHOR
837              
838             Kathryn Andersen (RUBYKAT)
839             perlkat AT katspace dot com
840             http://www.katspace.com
841              
842             =head1 COPYRIGHT AND LICENCE
843              
844             Copyright (c) 2005 by Kathryn Andersen
845              
846             This program is free software; you can redistribute it and/or modify it
847             under the same terms as Perl itself.
848              
849              
850             =cut
851              
852             1; # End of Graphics::Colourset
853             __END__