def color_in_loop(self, progress, blended=True): """ This returns a contiguous loop of colors where each one blend into the next without a hard edge. 0.0 and 1.0 are the same color. Think rainbow that is a repeated pattern with no discernible boundary. """ progress = math.modf(progress)[0] pos = progress * self.num_colors low_ix = int(math.floor(pos)) high_ix = low_ix + 1 # High might need to wrap if high_ix >= self.num_colors: high_ix = 0 interval_distance = pos - low_ix if blended: return color.Color(tween.hsvLinear(self.colors[low_ix], self.colors[high_ix], interval_distance)) else: return self.colors[low_ix]
def color_in_ramp(self, progress, blended=True): """ A color from the palette without wrapping smoothly back to the beginning. Color 0.0 is the first, and color 1.0 is the last, but these will not be the same color. Color 1.01 will be the same as color 0.01 though. """ # Special case this because it will otherwise get eaten # by the modf (wrapped to 0). This effectively means that we are # fudging the very first interval slightly so that the 1.0 # value is the "pure" final answer for the 0 to 1 interval # but in all other integer cases after 1 the value will be the # 0 value not the 1 value. This fudging makes life make more # sense IMHO, and is likely only hit when other code is # special case explicitly trying to get the 1.0 color. if progress == 1.0: return self.colors[self.num_colors-1] progress = math.modf(progress)[0] pos = progress * (self.num_colors - 1) low_ix = int(math.floor(pos)) high_ix = low_ix + 1 # High might need to wrap if high_ix >= self.num_colors: high_ix = 0 interval_distance = pos - low_ix if blended: return color.Color(tween.hsvLinear(self.colors[low_ix], self.colors[high_ix], interval_distance)) else: return self.colors[low_ix]
def update_at_progress(self, progress, new_loop, loop_instance): units = geom.by_faces for ix, unit in enumerate(units): distance = 0 l = len(unit) - 1 for jx, cell_id in enumerate(unit): if self.cm.modifiers[1]: # Reverse distance = (float(l-jx) / float(len(unit))) + progress else: distance = (float(jx) / float(len(unit))) + progress # Clamp if distance > 1.0: distance = distance - 1.0 if distance < 0.0: distance = distance + 1.0 # Color if self.cm.modifiers[0]: clr = color.HSVryb(distance, 1.0, 1.0) elif self.cm.modifiers[1]: clr = color.Color(tween.hsvLinear(self.cm.chosen_colors[0], self.cm.chosen_colors[1], distance)) else: clr = color.HSV(distance, 1.0, 1.0) # Set the one cell self.ss.party.set_cell(cell_id, clr)
def update_at_progress(self, progress, new_loop, loop_instance): mode = self.step_mode(self.num_steps) # mode 0 stripes = geom.by_long_planes if mode == 1: stripes = geom.by_short_planes elif mode == 2: stripes = geom.by_edges elif mode == 3: stripes = geom.by_faces # elif mode == 4: # stripes = geom.SPIRAL # elif mode == 5: # stripes = geom.ICICLES l = len(stripes) - 1 for ix, row in enumerate(stripes): distance = 0.0 if self.cm.modifiers[1]: # Reverse distance = (float(l - ix) / float(len(stripes))) + progress else: # Normal progression distance = (float(ix) / float(len(stripes))) + progress # Clamp while distance > 1.0: distance = distance - 1.0 while distance < 0.0: distance = distance + 1.0 if self.cm.modifiers[0]: clr = color.HSVryb(distance, 1.0, 1.0) elif self.cm.modifiers[1]: clr = color.Color( tween.hsvLinear(self.cm.chosen_colors[0], self.cm.chosen_colors[1], distance)) else: clr = color.HSV(distance, 1.0, 1.0) if mode == 4: self.ss.both.set_cell(row, clr) else: self.ss.both.set_cells(row, clr)
def tween_hsv_at(self, progress, output): """ Go through all cells that we have in next and morph them towards their next color at the given progress value """ for cell_id in self.next.keys(): next_color = self.next[cell_id] if cell_id in self.last: last_color = self.last[cell_id] else: last_color = color.BLACK cell_color = color.Color( tween.hsvLinear(last_color, next_color, progress)) output(cell_id, cell_color)
def update_at_progress(self, progress, new_loop, loop_instance): mode = self.step_mode(3) if new_loop: # For everything that was in transition, they are now fully # transitioned to their new state. We also pick new values # for things that will transition in this loop. for (ix, trans) in enumerate(self.in_transition): if trans: self.is_quartz[ix] = not self.is_quartz[ix] self.in_transition[ix] = (random.randrange(10) > 7) # For anything that will transition, determine some # pixel thresholds for it if self.in_transition[ix]: for x in range(0, geom.BIRD_SIZE): self.pixel_thresholds[ix][x] = random.random() # Update all birds for (ix, bird) in enumerate(geom.BIRDS): if not self.in_transition[ix]: # Single gender clr = geom.ROSE if self.is_quartz[ix]: clr = geom.QUARTZ self.ss.party.set_cells(bird, clr) else: # In transition between those two states current = geom.ROSE future = geom.QUARTZ if self.is_quartz[ix]: current = geom.QUARTZ future = geom.ROSE if mode == 2: # Linear movement clr = color.Color( tween.hsvLinear(current, future, progress)) self.ss.party.set_cells(bird, clr) elif mode == 1: # Flip pixels one at a time for each bird pt = self.pixel_thresholds[ix] for (pix, pVal) in enumerate(bird): clr = current if pt[pix] < progress: clr = future self.ss.party.set_cell(pVal, clr) elif mode == 0: # Linear by pixel from front to back distance = progress * geom.BIRD_SIZE / 2 for (pix, pVal) in enumerate(bird): to_front = pix if pix >= geom.BIRD_SIZE / 2: to_front = geom.BIRD_SIZE - pix if to_front < distance: clr = future else: clr = current self.ss.party.set_cell(pVal, clr)
def update_at_progress(self, progress, new_loop, loop_instance): if new_loop: if self.cm.modifiers[0]: self.foreground = self.cm.chosen_colors[0] self.background = self.cm.chosen_colors[1] else: if self.cm.modifiers[1] or (random.randrange(10) > 7) or ( not hasattr(self, "foreground")): # Definitely need a new color if random.randrange(10) > 7: # Also reverse direction self.cm.set_modifier(2, not self.cm.modifiers[2]) if self.cm.modifiers[4] or (not hasattr( self, "foreground")): # Two totally new colors self.foreground = random_color(luminosity="dark") self.background = self.foreground.copy() if self.background.h < 0.5: self.background.h += 0.5 else: self.background.h -= 0.5 else: # Keep old foreground self.background = self.foreground self.foreground = random_color(luminosity="dark") for ring in geom.RINGS: el_size = 1.0 / len(ring) # Debug ring 3 only # debug = el_size < 0.4 # if debug: # print for ix, el in enumerate(ring): partial = 1.0 el_start = (ix * el_size) + 0.25 if el_start >= 1.0: el_start -= 1.0 el_end = ((ix + 1) * el_size) + 0.25 if el_end > 1.0: el_end -= 1.0 v = 0.0 p = progress backwards = self.cm.modifiers[2] if backwards: p = 1.0 - progress mode = self.step_mode(2) if mode == 0: # A single edge that sweeps from 0 to full if p >= el_end: v = 1.0 elif p > el_start: v = (p - el_start) / el_size # else v stays at 0 elif mode == 1: # A 0.25 segment v = self.calcV(el_start, el_end, p, 0.25, debug=False) # if debug: # print " %0.4f" % v clr = color.HSV( *tween.hsvLinear(self.background, self.foreground, v)) self.ss.party.set_cell(el, clr)