-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathcolor.py
More file actions
executable file
·163 lines (97 loc) · 4.21 KB
/
color.py
File metadata and controls
executable file
·163 lines (97 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import colorsys
import math
import pygame
from debug import *
from events import *
# Normalization method, so the colors are in the range [0,1]
def normalize( color ):
return color[0] / 255.0, \
color[1] / 255.0, \
color[2] / 255.0
# Reformats a color tuple, that uses the range [0,1] to a 0xFF
# representation.
def reformat( color ):
return int( round( color[0] * 255 ) ), \
int( round( color[1] * 255 ) ), \
int( round( color[2] * 255 ) )
def logSequence( n ):
"""
Returns values in range 0..1.
Distances between values are maximal.
"""
return math.log( 2*n+1, 2 ) % 1
class ColorValue:
def __init__( self, group ):
self.group = group
self.value = group.next() # Value of Color: 0..1
self.rgb = () # Calculated RGB color
def color( self ):
"Return color"
if not self.rgb:
saturation = 0.6 # Saturation is constant
self.rgb = reformat( colorsys.hsv_to_rgb( self.group.hue, saturation, self.value ) )
return self.rgb
class ColorGroup:
def __init__( self ):
self.hue = 0 # Hue of Color: 0..1
self.count = 0 # Counter of Variables
def next( self ):
"Get next color value for ColorValue object"
#step = ( 5 ** .5 - 1 ) * .5 # Step of values
min = 0.5 # Minimal value
#val = ( self.count * step % 1 ) *(1-min)+min
val = logSequence( self.count ) *(1-min)+min
self.count += 1
return val
class ColorSpace:
def __init__( self, expression= None ):
self.vars = {} # Dict {var:ColorValue}
self.groups = [] # Color Groups
if expression:
self.add( expression )
def add( self, expression, groups= None ):
"Add Variables of Expression to Space"
if not groups:
# Get groups of Variables by Expression
vars, groups = expression.getClosed()
if vars:
groups[0] += list( vars ) # Add Free vars to last Group
debug('color','init color groups:',groups)
# Create groups and vars collections
for g in groups:
self.addGroup(g)
def addGroup( self, vars ):
"Adds Group into Color Space"
group = None
for var in vars:
if var not in self.vars: # Var may be already in Space (at Deref)
if not group: # Create Group once if needed
n = len( self.groups )
group = ColorGroup()
group.hue = logSequence( n ) # Det Hue of Group
self.groups.append( group )
self.vars[ var ] = ColorValue( group ) # Fill dict {var:ColorValue}
def color( self, var ):
if 0 == var: # Free Variable
return 0xFF,0xFF,0xFF
elif None == var: #!!! Special Constant (Gold coin)
return 0xFF,0xFF,0x7F
elif var in self.vars:
return self.vars[ var ].color()
else:
debug( 1, 'Error. Color of Unknow Variable' )
return 0xFF,0x00,0x00
class ColorChange:
"It may be used for smooth changing of colors at figure rebuilding.."
# Not implemented
def __init__( self ):
#self.event = pygame.event.Event( COLOREVENT, handler= self.handler, \
# timefunc= None, \
# cur_hsv= None )
pass
def handler( self, event ):
if event != self.event:
debug( 'event', 'Error? ColorValue wrong event.' )
return
return
yield self.event