public
Last active

Quasicrystal in Core Image

  • Download Gist
gistfile1.c
C
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
// Quasicrystal in Core Image
// port of http://mainisusuallyafunction.blogspot.com/2011/10/quasicrystals-as-sums-of-waves-in-plane.html
 
 
// HSV conversion
// adapted from http://shapeof.com/archives/2010/07/making_a_color_wheel_in_core_image.html
bool isOdd(int v) {
float dividend = float(v) / 2.0;
return dividend != floor(dividend);
}
vec4 hsvToRgb(vec4 hsv) {
float h = hsv.r*6.;
float s = hsv.g;
float v = hsv.b;
int i = int(floor(h));
float f = isOdd(i) ? h - float(i) : 1.0 - (h - float(i));
float m = v * (1.0 - s);
float n = v * (1.0 - s * f);
vec4 result = (i == 0) ? vec4(v, n, m, hsv.a) : ((i == 1) ?
vec4(n, v, m, hsv.a) : ((i == 2) ? vec4(m, v, n, hsv.a) : ((i == 3) ?
vec4(m, n, v, hsv.a) : ((i == 4) ? vec4(n, m, v, hsv.a) : ((i == 5) ?
vec4(v, m, n, hsv.a) : vec4(v, n, m, hsv.a))))));
return (h == -1.0) ? vec4(v, v, v, hsv.a) : result;
}
 
 
// triangle wave from 0 to 1
float wrap(float n) {
return abs(mod(n, 2.)-1.)*-1. + 1.;
}
 
// creates a cosine wave in the plane at a given angle
float wave(float angle, vec2 point) {
float cth = cos(angle);
float sth = sin(angle);
return (cos (cth*point.x + sth*point.y) + 1.) / 2.;
}
 
// sum 7 cosine waves at various interfering angles
// wrap values when they exceed 1
float quasi(float interferenceAngle, vec2 point) {
float sum = 0;
for (float i = 0.; i < 7.; i++) {
sum += wave(3.1416*i*interferenceAngle, point);
}
return wrap(sum);
}
 
kernel vec4 effect(float scale, float huePhase, float interferenceAngle) {
float brightness = quasi(interferenceAngle, destCoord() * scale);
return hsvToRgb(vec4(mod(brightness+huePhase, 0.5)*2., 1, brightness, 1));
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.