1 |
# Choosing colors and 3-dotproduct factors for papers. |
# Choosing colors and 3-dotproduct factors for papers. |
2 |
|
|
3 |
from gfx.libcolor.spaces import getRandomColor,getRandomColor2,RGBtoLAB |
from gfx.libcolor.spaces import getRandomColor,getRandomColor2,RGBtoLAB,LABtoRGB,LABclamp |
4 |
|
|
5 |
from math import atan2,pi |
from math import sin,cos,atan2,pi |
6 |
|
from random import shuffle |
7 |
|
|
8 |
import java; |
import java; |
9 |
|
|
10 |
|
dbg=0 |
11 |
|
|
12 |
class Colors: |
class Colors: |
13 |
def _js(self, arg): |
def _js(self, arg): |
14 |
return " ".join([str(a) for a in arg]) |
return " ".join([str(a) for a in arg]) |
15 |
def __init__(self, seed): |
def __init__(self, seed): |
16 |
rnd = self.rnd = java.util.Random(seed) |
rnd = self.rnd = java.util.Random(seed) |
17 |
|
|
18 |
# currently, 4 colors |
# currently, 4 colors |
19 |
|
colors = 4 |
20 |
minlum = 80 |
minlum = 80 |
21 |
|
huerange = (45 + rnd.nextGaussian() * 45) * (pi / 180) |
22 |
|
|
23 |
# Just take alternating dark and light colors |
# Note: This color sampling scheme only produces |
24 |
while 1: |
# palettes with similar colors. |
25 |
t = (100 - minlum)/2 |
# It could be nice to have other schemes |
26 |
col = [ getRandomColor2(minlum + t - t * (i & 1), |
# with, e.g., complementary colors. |
27 |
100 - t * (i & 1), rnd) |
# (Note: color complementing should be done in RGB space) |
28 |
for i in range(0,4) ] |
|
29 |
if 120 - self._AB_angle(col) > 90 * rnd.nextFloat(): break |
# Sample hues uniformly from the range shifted to a random angle |
30 |
#if self._AB_angle(col) < 180: break |
hue0 = rnd.nextDouble() * 2*pi |
31 |
print "ANGLE=", self._AB_angle(col), "AREA=", self._AB_area(col)*100 |
hues = [hue0 + rnd.nextDouble() * huerange for i in range(0,colors)] |
32 |
|
|
33 |
while 0: |
# Take one half dark colors and one half light colors |
34 |
col = [ |
lumrange = 100 - minlum |
35 |
getRandomColor2(minlum,100, rnd), |
lums = ([minlum + rnd.nextDouble() * lumrange/2 |
36 |
getRandomColor2(minlum,minlum + (100-minlum)*0.7, rnd), |
for i in range(0,colors/2)] + |
37 |
getRandomColor2(minlum + (100-minlum)*0.7, 100, rnd), |
[minlum + (1 + rnd.nextDouble()) * lumrange/2 |
38 |
# getRandomColor2(minlum + (100-minlum)*0.5, 100, rnd), |
for i in range(colors/2,colors)] |
39 |
] |
) |
40 |
#print self._AB_angle(col) |
|
41 |
#print self._AB_avg_dot(col) |
# Sample saturation: |
42 |
# if abdiff(col[0], col[1]) < 40: continue |
# - take the most saturated color 2/3 of the time |
43 |
#if abdiff(col0, col2) < 40: continue |
# and a dull color 1/3 of the time |
44 |
#if abdiff(col0, col3) < 40: continue |
sats = [100 * (1 - (1 - (1 - rnd.nextDouble())**2) * (rnd.nextDouble() < .333)) |
45 |
#if abdiff(col1, col2) < 40: continue |
for i in range(0, colors)] |
46 |
#if abdiff(col1, col3) < 40: continue |
|
47 |
# if abdiff(col[2], col[3]) < 40: continue |
# Construct colors and clamp towards the CIELAB L-axis |
48 |
break |
# (keeping hue and luminance) to fit into the RGB cube |
49 |
|
lab = [(lums[i], sats[i] * cos(hues[i]), sats[i] * sin(hues[i])) |
50 |
|
for i in range(0,colors)] |
51 |
|
col = [LABclamp(LABtoRGB(c)) for c in lab] |
52 |
|
shuffle(col, rnd.nextDouble) |
53 |
|
|
54 |
|
if dbg: |
55 |
|
print "ANGLE=", self._AB_angle(col), "AREA=", self._AB_area(col)*100 |
56 |
|
|
57 |
self.colors = [self._js(c) for c in col] |
self.colors = [self._js(c) for c in col] |
58 |
|
|