Class: AutoColors::ColorScheme
- Inherits:
-
Object
- Object
- AutoColors::ColorScheme
- Defined in:
- lib/autocolors/colorscheme.rb
Instance Attribute Summary collapse
-
#contrast ⇒ Object
Returns the value of attribute contrast.
-
#dark ⇒ Object
Returns the value of attribute dark.
-
#light ⇒ Object
Returns the value of attribute light.
-
#name ⇒ Object
Returns the value of attribute name.
-
#saturation ⇒ Object
Returns the value of attribute saturation.
-
#seed ⇒ Object
Returns the value of attribute seed.
Instance Method Summary collapse
- #concrete_index(entry, k) ⇒ Object protected
- #concrete_lvl(entry, k) ⇒ Object protected
- #concrete_style(entry) ⇒ Object protected
- #dark_i(idx) ⇒ Object protected
- #dark_s(idx) ⇒ Object protected
- #do_concrete_mapping ⇒ Object protected
- #generate ⇒ Object
-
#initialize(name = nil) ⇒ ColorScheme
constructor
A new instance of ColorScheme.
- #lab(intensity, chroma, a, b, rand_adjust = false) ⇒ Object protected
- #light_i(idx) ⇒ Object protected
- #light_s(idx) ⇒ Object protected
- #new_color(base_idx, diff_level, depth) ⇒ Object protected
- #new_color_old(base_idx, diff_level, depth) ⇒ Object protected
- #nrand(mean = 0, stddev = nil, floor = nil, ceil = nil) ⇒ Object protected
- #nrand_color ⇒ Object protected
- #rand_color ⇒ Object protected
- #rand_seq(min, max, points, contraction = 1.0) ⇒ Object protected
-
#simplelogit(x) ⇒ Object
protected
(inverse s-curve, steepest on edges).
Constructor Details
#initialize(name = nil) ⇒ ColorScheme
Returns a new instance of ColorScheme.
6 7 8 9 10 11 12 13 14 15 |
# File 'lib/autocolors/colorscheme.rb', line 6 def initialize(name=nil) srand rand(0xffffffff) name ||= Webster.new.random_word @name = name @seed = @name.hash srand @seed @dark = {} @light = {} generate end |
Instance Attribute Details
#contrast ⇒ Object
Returns the value of attribute contrast.
5 6 7 |
# File 'lib/autocolors/colorscheme.rb', line 5 def contrast @contrast end |
#dark ⇒ Object
Returns the value of attribute dark.
5 6 7 |
# File 'lib/autocolors/colorscheme.rb', line 5 def dark @dark end |
#light ⇒ Object
Returns the value of attribute light.
5 6 7 |
# File 'lib/autocolors/colorscheme.rb', line 5 def light @light end |
#name ⇒ Object
Returns the value of attribute name.
5 6 7 |
# File 'lib/autocolors/colorscheme.rb', line 5 def name @name end |
#saturation ⇒ Object
Returns the value of attribute saturation.
5 6 7 |
# File 'lib/autocolors/colorscheme.rb', line 5 def saturation @saturation end |
#seed ⇒ Object
Returns the value of attribute seed.
5 6 7 |
# File 'lib/autocolors/colorscheme.rb', line 5 def seed @seed end |
Instance Method Details
#concrete_index(entry, k) ⇒ Object (protected)
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/autocolors/colorscheme.rb', line 72 def concrete_index(entry, k) return if entry.data[k].is_a? Integer primes = entry.data[k].count("'") entry.data[k].gsub! "'",'' if entry.data[k] =~ /^(\d+)$/ # Direct index if primes > 0 entry.data[k] = new_color(Integer($1), primes, entry.depth) else # Otherwise good to go entry.data[k] = Integer($1) end elsif entry.data[k] =~ /^<$/ # Inherit from parent if entry.parent.nil? $stderr.puts "Mapping refers to parent without having a parent" exit(2) else concrete_index(entry.parent, k) if primes == 0 # Directly inherit entry.data[k] = entry.parent.data[k] else # Modify a bit entry.data[k] = new_color(entry.parent.data[k], primes, entry.depth) end end end end |
#concrete_lvl(entry, k) ⇒ Object (protected)
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/autocolors/colorscheme.rb', line 97 def concrete_lvl(entry, k) return if entry.data[k].is_a? Integer c_parent = entry.data[k].count('<') c_plus = entry.data[k].count('+') c_minus = entry.data[k].count('-') c_neut = entry.data[k].count('~') val = 0 if c_parent == 0 val = 3 - c_minus + c_plus else concrete_lvl(entry.parent, k) offset = entry.parent.data[k] val = offset + c_plus - c_minus end entry.data[k] = [[val,7].min,0].max end |
#concrete_style(entry) ⇒ Object (protected)
114 115 116 |
# File 'lib/autocolors/colorscheme.rb', line 114 def concrete_style(entry) entry.data[:styles] = 'NONE' end |
#dark_i(idx) ⇒ Object (protected)
118 |
# File 'lib/autocolors/colorscheme.rb', line 118 def dark_i(idx) @intensity[idx] end |
#dark_s(idx) ⇒ Object (protected)
120 |
# File 'lib/autocolors/colorscheme.rb', line 120 def dark_s(idx) @fcolor[idx] end |
#do_concrete_mapping ⇒ Object (protected)
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/autocolors/colorscheme.rb', line 50 def do_concrete_mapping @mapping = Marshal.load(Marshal.dump(MAPPING)) @mapping.entries.each do |name, entry| [:fg_idx, :bg_idx].each{|k| concrete_index(entry,k)} [:fg_intensity, :fg_saturation, :bg_intensity, :bg_saturation].each{|k| concrete_lvl(entry,k)} concrete_style(entry) end @mapping.entries.each do |name, entry| ldat = entry.data.dup ddat = entry.data.dup fg_a, fg_b, _ = @base_colors[ldat[:fg_idx]] bg_a, bg_b, _ = @base_colors[ldat[:bg_idx]] ldat[:fg] = lab(light_i(ldat[:fg_intensity]-1), light_s(ldat[:fg_saturation]+1), fg_a, fg_b) ldat[:bg] = lab(light_i(ldat[:bg_intensity]), light_s(ldat[:bg_saturation]), bg_a, bg_b, false) ddat[:fg] = lab( dark_i(ldat[:fg_intensity]), dark_s(ldat[:fg_saturation]), fg_a, fg_b) ddat[:bg] = lab( dark_i(ldat[:bg_intensity]), dark_s(ldat[:bg_saturation]), bg_a, bg_b, false) @dark[name] = ddat @light[name] = ldat end end |
#generate ⇒ Object
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 |
# File 'lib/autocolors/colorscheme.rb', line 17 def generate # OVERALL CONTRAST: Value between 0.75 and 1.0 used to contract/spread # out intensity values. @contrast = nrand(0.95, 0.1, 0.75, 1.1) # OVERALL CHROMACITY: Value between 0.0 and 1.0 used to # contract/intensify colorfulness @chromacity = nrand(0.8, 0.3, 0.0, 1.0) # OVERALL COLORFULNESS: Value between 0.3 and 1.0 determining how many # hues overall end up in the colorscheme @colorfulness = nrand(0.8, 0.4, 0.5, 1.0) @intensity = rand_seq(0.0, 1.0, 8, @contrast).map{|i| simplelogit(i) * 105} @fcolor = (0..7).map {|i| i.to_f / 7.0 * 100.0 * Math.sqrt(2.0) * @chromacity } hues = rand_seq(0.0, 1.0, 10, @colorfulness).shuffle @base_colors = hues.map do |h| c = Color.new([50, 10, 10]) c.hue = h [c.ca, c.cb, 1] end require 'pp' puts "Intensity" pp @intensity puts "Chromacity" pp @fcolor puts "Base Colors" pp @base_colors do_concrete_mapping end |
#lab(intensity, chroma, a, b, rand_adjust = false) ⇒ Object (protected)
123 124 125 126 127 128 |
# File 'lib/autocolors/colorscheme.rb', line 123 def lab(intensity, chroma, a, b, rand_adjust=false) ivar = rand_adjust ? (@colorfulness * rand * 16) - 8 : 0 c = Color.new([[[intensity + ivar,0].max,140].min, a, b]) c.chroma = chroma return c end |
#light_i(idx) ⇒ Object (protected)
119 |
# File 'lib/autocolors/colorscheme.rb', line 119 def light_i(idx) @intensity[[[7 - idx,0].max,7].min] end |
#light_s(idx) ⇒ Object (protected)
121 |
# File 'lib/autocolors/colorscheme.rb', line 121 def light_s(idx) @fcolor[[idx,7].min] end |
#new_color(base_idx, diff_level, depth) ⇒ Object (protected)
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/autocolors/colorscheme.rb', line 130 def new_color(base_idx, diff_level, depth) # TODO: Use actual mapping metrics for very even spread a, b, count = @base_colors[base_idx] c = Color.new([50, a, b]) current_hue = c.hue diff_level = diff_level.to_f # Usually 1 or 2 - from prime marks depth = depth.to_f # Usually 1, less frequently 2, 3, to 5... count = count.to_f # How many others already based off of the same parent direction = rand(2) == 1 ? -1.0 : 1.0 maxdiff = @colorfulness * (1.0 / @base_colors.size) * 1.5 # allocated roughly per major color group cdiff = direction * maxdiff / (depth+0.5) * count * 2.5 * diff_level cdiff += current_hue cdiff = 1.0 + cdiff if cdiff < 0.0 cdiff = cdiff - 1.0 if cdiff > 1.0 c.hue = cdiff new_idx = @base_colors.size @base_colors[new_idx] = [c.ca, c.cb, 1] @base_colors[base_idx][2] += 1 return new_idx end |
#new_color_old(base_idx, diff_level, depth) ⇒ Object (protected)
151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/autocolors/colorscheme.rb', line 151 def new_color_old(base_idx, diff_level, depth) a,b,count = @base_colors[base_idx] base_diff = (diff_level.to_f + 1.0) * 4.0 / ((depth.to_f + 1.0) / 2.0) * count.to_f a_dir = rand(2) == 1 ? -1.0 : 1.0 b_dir = rand(2) == 1 ? -1.0 : 1.0 a_p = a + (base_diff * a_dir) b_p = b + (base_diff * b_dir) new_idx = @base_colors.size @base_colors[new_idx] = [a_p, b_p, 1] @base_colors[base_idx][2] += 1 return new_idx end |
#nrand(mean = 0, stddev = nil, floor = nil, ceil = nil) ⇒ Object (protected)
167 168 169 170 171 172 173 174 175 176 |
# File 'lib/autocolors/colorscheme.rb', line 167 def nrand(mean=0, stddev=nil, floor=nil, ceil=nil) theta = 2 * Math::PI * rand rho = Math.sqrt(-2 * Math.log(1 - rand)) scale = stddev * rho res = (rand >= 0.5) ? Math.cos(theta) : Math.sin(theta) res = mean.to_f + scale * res res = floor if (! floor.nil?) && (res < floor) res = ceil if (! ceil.nil?) && (res > ceil) return res end |
#nrand_color ⇒ Object (protected)
165 |
# File 'lib/autocolors/colorscheme.rb', line 165 def nrand_color; nrand(0.0, 40.0, -120.0, 120.0) end |
#rand_color ⇒ Object (protected)
164 |
# File 'lib/autocolors/colorscheme.rb', line 164 def rand_color; rand(180) - 90 end |
#rand_seq(min, max, points, contraction = 1.0) ⇒ Object (protected)
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/autocolors/colorscheme.rb', line 178 def rand_seq(min, max, points, contraction=1.0) max = max.to_f; min = min.to_f; contraction = contraction.to_f spread = max - min base_step = spread / (points.to_f - 1.0) * contraction partial = base_step / 3.0 curr = 0.0 res = [curr] while res.size < points curr += nrand(base_step, partial / 2.0, base_step - (partial), base_step + (partial)) res << curr end if curr > spread factor = spread / curr res.map!{|v| factor * v} else offset = (spread - curr) * rand res.map!{|v| offset + v} end return res.map{|v| v + min} end |
#simplelogit(x) ⇒ Object (protected)
(inverse s-curve, steepest on edges)
200 201 202 203 204 |
# File 'lib/autocolors/colorscheme.rb', line 200 def simplelogit(x) return 0.0 if x <= 0.0 return 1.0 if x >= 1.0 [[Math.log(x.to_f / (1.0 - x.to_f)) / Math.log(Math::E ** 4.5) + 0.5,0.0].max,1.0].min end |