Skip to content

Instantly share code, notes, and snippets.

@Eclmist
Last active August 18, 2019 08:01
Show Gist options
  • Save Eclmist/cbcb8590ac2e615c3c6a68b00a28bf85 to your computer and use it in GitHub Desktop.
Save Eclmist/cbcb8590ac2e615c3c6a68b00a28bf85 to your computer and use it in GitHub Desktop.
Generates a colorful heart in source academy
// Minified, token reduced:
function procedural_heart()
{
function f(u,v){const r=0.15/(math_pow(0.5-u,2)+math_pow(0.75-(v+math_sqrt(math_abs(u-0.5)+0.1)*0.5),2)+0.01);return color(square,r,r-v*r,u*r);}
function i(x,y,acc){return x>=150?acc:i(x+1,y,beside_frac(x/(x+1),acc,f(x/150,y/150)));}
function j(y,acc){return y>=150?acc:j(y+1,stack_frac(y/(y+1),acc,i(0,y,blank)));}
return j(0,blank);
}
// Full source code that actually have a chance of making sense
function procedural_heart() {
// Resolution
const res = 150;
// Square magnitude of vector (x, y)
// the sqrt function is expensive when we are calling this res^2 times.
function mag_sqr(x, y) {
return math_abs(x * x + y * y);
}
// returns a large number if position (u, v) is within 0.15 of position (x,y),
// small number if (u,v) is far away from (x,y)
function circle(u, v, x, y) {
return 0.15 / (mag_sqr(x - u, y - v) + 0.01); //0.01 is added such that we will never have division by 0
}
// Similar to a fragment function in GLSL
function frag(u, v) {
// Calculate the rgb values to output for each black_bb (fragment)
const b = u;
const g = (1 - v);
// This is supposed to produce a circle, but since we add some function of u into v, we can skew the circle to
// Make it look like a heart
const r = circle(u, v + math_sqrt(math_abs(u - 0.5) + 0.1) * 0.5, 0.5, 0.75);
// magic numbers to get nice colors
return color(square, r, g * r, b * r);
}
// Generates row of black_bb, colored by the frag function
function helper_x(x, y, acc) {
// we call frag(x / rex, y / res) to stack a new colored black_bb to our accumulator.
// remember to divide by res to normalize our x and y values to between 0-1
return x >= res
? acc
: helper_x(x + 1, y, beside_frac(x / (x + 1), acc, frag(x / res, y / res)));
}
// Generate column of rows
function helper_y(y, acc) {
return y >= res
? acc
: helper_y(y + 1, stack_frac(y / (y + 1), acc, helper_x(0, y, blank)));
}
return helper_y(0, blank);
}
// Shows the rune
show(procedural_heart());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment