use strict; my $hueClipInput = []; my $hueClipOutput = []; my $maxAdjustedHue = 360; sub initHueAdjuster { my $hueClipBoundaries = [[0, 15], [55, 70], [75, 85], [90, 150], [160, 170], [185, 205], [230, 250], [255, 265], [270, 280], [290, 325]]; die unless $hueClipBoundaries->[0]->[0] == 0; # algorithm would have to be different if not true my $currentMax = 0; my $lastMax = 0; foreach my $subrange (@$hueClipBoundaries) { push(@$hueClipInput, $subrange->[0]); push(@$hueClipInput, $subrange->[1]); $maxAdjustedHue -= $subrange->[1] - $subrange->[0]; $currentMax += $subrange->[0] - $lastMax; push(@$hueClipOutput, $currentMax); $lastMax = $subrange->[1]; } } initHueAdjuster(); warn "adjusted hue has range 0..$maxAdjustedHue\n"; sub adjustHue { my($hue) = @_; my $min = 0; my $max = scalar @$hueClipInput; my $pos = int($max/2); while ($pos > $min) { if ($hue < $hueClipInput->[$pos]) { $max = $pos; } else { $min = $pos; } $pos = $min + int(($max - $min) / 2); } if ($pos % 2 == 0) { $hue = $hueClipOutput->[$pos/2]; } else { $hue = ($hue - $hueClipInput->[$pos]) + $hueClipOutput->[int($pos/2)]; } return $hue; } for (my $testH = 0; $testH < 360; $testH += 0.4) { my $H = $testH; if ($H > 0) { if ($H < 15) { $H = 0; } else { if ($H > 55) { if ($H < 70) { $H = 55; } else { if ($H > 75) { if ($H < 85) { $H = 75; } else { if ($H > 90) { if ($H < 150) { $H = 90; } else { if ($H > 160) { if ($H < 170) { $H = 160; } else { if ($H > 185) { if ($H < 205) { $H = 185; } else { if ($H > 230) { if ($H < 250) { $H = 230; } else { if ($H > 255) { if ($H < 265) { $H = 255; } else { if ($H > 270) { if ($H < 280) { $H = 270; } else { if ($H > 290) { if ($H < 325) { $H = 290; } else { $H -= 35; } } $H -= 10; } } $H -= 10; } } $H -= 20; } } $H -= 20; } } $H -= 10; } } $H -= 60; } } $H -= 10; } } $H -= 15; } } $H -= 15; } } my $H2 = adjustHue($testH); printf("test: %15f %15f %15f\n", $testH, $H, $H2) unless $H == $H2; }