Last active
March 16, 2018 08:38
-
-
Save exhuma/ddfed1da0ba1703cae820894f555be50 to your computer and use it in GitHub Desktop.
Colorise parametric value using Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from math import pi, cos | |
from functools import partial | |
def sinusoidal(v): | |
''' | |
Create a sinusoidal easing function. | |
*v* is assumed to range from 0 to 1. The function will return a new value | |
from 0 to 1. | |
>>> sinusoidal(0) | |
0.0 | |
>>> sinusoidal(1) | |
1.0 | |
>>> sinusoidal(0.5) | |
0.5 | |
>>> sinusoidal(0.75) | |
0.8535533905932737 | |
''' | |
output = cos(pi * v) | |
output = (output / 2) + 0.5 | |
output = 1 - output | |
return output | |
def squeeze(start, end): | |
''' | |
Given a "start" and "end" value, returns slope and intercept coefficients | |
for a linear function which ranges from 0 to 1 and intercepts x=0 at *start* | |
and x=1 at *1-end*. | |
>>> squeeze(0, 0) | |
(1.0, -0.0) | |
>>> squeeze(0.2, 0) | |
(1.25, -0.25) | |
>>> squeeze(0, 0.2) | |
(1.25, -0.0) | |
>>> squeeze(0.2, 0.2) | |
(1.6666666666666665, -0.3333333333333333) | |
''' | |
tan_alpha = 1 / (1-start-end) | |
slope = tan_alpha | |
intercept = -(start * (1 / (1-start-end))) | |
return slope, intercept | |
def clamped_sinusoidal(v, x1=0.0, x2=0.0): | |
''' | |
Applies :py:func:`sinusoidal` only between *start+x1* and *end-x2*. | |
Returns a sinusoidal function mapping a value in [0..1] to a new value in | |
from [0..1]. The curve is "squeezed" between *0+start* and *1-end* | |
effectively ramping up late, and levelling out early. | |
>>> clamped_sinusoidal(0.5, 0, 0) == sinusoidal(0.5) | |
True | |
>>> clamped_sinusoidal(0.1, 0, 0) == sinusoidal(0.1) | |
True | |
>>> clamped_sinusoidal(0.9, 0, 0) == sinusoidal(0.9) | |
True | |
>>> clamped_sinusoidal(0.5, 0.2, 0.2) | |
0.4999999999999999 | |
>>> clamped_sinusoidal(0.5, 0, 0.2) | |
0.6913417161825448 | |
>>> clamped_sinusoidal(0.5, 0.2, 0) | |
0.3086582838174551 | |
''' | |
a, b = squeeze(x1, x2) | |
if x1 and v <= x1: | |
return 0.0 | |
if x2 and v >= (1-x2): | |
return 1.0 | |
return sinusoidal(a*v+b) | |
def percentage_position(percentage, items): | |
''' | |
Returns an item from a list by a percentage position. | |
Example:: | |
>>> percentage_position(0.0, [1, 2, 3]) | |
1 | |
>>> percentage_position(0.5, [1, 2, 3]) | |
2 | |
>>> percentage_position(0.99, [1, 2, 3]) | |
3 | |
''' | |
position = (len(items)-1) * percentage | |
return items[round(position)] | |
def main(): | |
print('Visualising Easing function') | |
ease = partial(clamped_sinusoidal, x1=0.3, x2=0.2) | |
print(' Visualising Easing Curve '.center(80, '-')) | |
for n in range(30): | |
progress = ease(n/30) | |
print('%3s' % n, '*'*round((80*(progress)))) | |
print(' Example with fixed pallette '.center(80, '-')) | |
colors = [ | |
'#ff0000', | |
'#aaaa00', | |
'#ffff00', | |
'#aaff00', | |
'#00ff00', | |
] | |
print('Pallette:', colors) | |
for n in range(30): | |
value = ease(n / 30) | |
out = percentage_position(value, colors) | |
print('%3s' % n, out) | |
print(' Example with a smooth transition '.center(80, '-')) | |
for n in range(30): | |
value = ease(n / 30) | |
hue = 120 * value | |
out = 'hsl(%d%%, 50%%, 50%%)' % round(hue) | |
print('%3s' % n, out) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment