
#define PI 3.14159265359
#define PI_2 6.2831

// From https://www.shadertoy.com/view/wdtfWX
float sdTriangle(in vec2 p, in vec2 a, in vec2 b, in vec2 c) {
    vec2 ba = b - a, cb = c - b, ac = a - c;
    vec2 pa = p - a, pb = p - b, pc = p - c;

    // Barycentric triangle areas
    float abc = ba.x * cb.y - ba.y * cb.x;
    float abp = ba.x * pa.y - ba.y * pa.x;
    float bcp = cb.x * pb.y - cb.y * pb.x;
    float cap = ac.x * pc.y - ac.y * pc.x;

    // Edge distances
    vec2 ae = pa - ba * clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
    vec2 be = pb - cb * clamp(dot(pb, cb) / dot(cb, cb), 0.0, 1.0);
    vec2 ce = pc - ac * clamp(dot(pc, ac) / dot(ac, ac), 0.0, 1.0);

    // Combined edge distances
    float tri = sqrt(min(dot(ae, ae), min(dot(be, be), dot(ce, ce))));

    // Combine with the appropriate sign (-1 if inside +1 if outside)
    return tri * sign(max(-abp, max(-bcp, -cap)) * max(abp, max(bcp, cap)));
}

// https://www.shadertoy.com/view/3lVGWt
mat2 rot2d(in float angle) {
	float a = angle * PI / 180.0;
    float s = sin(a), c=cos(a);
    return mat2(c, -s, s, c);
}

float sdRectangle(in vec2 p, in vec2 p1, in vec2 p2, in vec2 p3, in vec2 p4) {
    return min(sdTriangle(p, p1, p2, p3), sdTriangle(p, p3, p4, p1));
}

float tan60 = tan(PI_2 * 60. / 360.);

float sdPenroseSide(in vec2 p, in float r, in float t) {
    // A side consists of two rectangles: An outer and inner bit
    // This func draws one on the bottom around center 0,0.
    // Rotate the input p by 120 degr to get the other ones


    float hgap = t / tan60;
    float x = r * cos(30. / 360. * PI_2);
    float y = r * sin(30. / 360.0 * PI_2);
    float gap = hgap * 2.;

    vec2 a = r * vec2(-x + gap,     -y);
    vec2 b = r * vec2( x - gap,     -y);
    vec2 c = r * vec2( x - hgap,    -y + t);
    vec2 d = r * vec2(-x + 1.5*gap, -y + t);
    vec2 e = r * vec2(-x + 2.5*gap, -y + t);
    vec2 f = r * vec2( 0.,           r - 4.*t);
    vec2 g = r * vec2(-hgap,         r - 3.*t);

    return min(sdRectangle(p, a, b, c, d), sdRectangle(p, d, e, f, g));
    // return r * sdRectangle(p, a, b, c, d);
    // return sdRectangle(p, d, e, f, g);
}

vec3 penroseTriangle(in vec2 uv, in float r, in float t) {
    float d1 = sdPenroseSide(uv,               r, t);
    float d2 = sdPenroseSide(uv * rot2d(120.), r, t);
    float d3 = sdPenroseSide(uv * rot2d(240.), r, t);

    vec3 col =     (1. - smoothstep(0., fwidth(d1), d1)) * 1.0 * vec3(1.); // vec3(1., 0.5, 0.5);
    col = max(col, (1. - smoothstep(0., fwidth(d2), d2)) * 1.0 * vec3(0.8)); // vec3(0.5, 1., 0.5));
    col = max(col, (1. - smoothstep(0., fwidth(d3), d3)) * 1.0 * vec3(0.6)); // vec3(0.5, 0.5, 1.));

    return col;
}

float sdCircle(in vec2 p, in float r) {
  return length(p) - r;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;

    uv = rot2d(iTime * 20.) * uv * (1. + sin(iTime * 1.5) * 0.5);

    uv = mod(uv + vec2(0.5), 1.);
    uv -= vec2(0.5);

    float s = 2.5;
    float squareD = sdRectangle(
                uv * s,
                vec2(-1, -1),
                vec2( 1, -1),
                vec2( 1,  1),
                vec2(-1,  1)
    );


    vec3 col = vec3(0.); // 0.5 + 0.5*cos(iTime+uv.xyx+vec3(0,2,4));

    // float t = s * 0.06; // 0.2 + 0.05 * sin(iTime * PI_2 * 0.5);
    float t = 0.15 + 0.05 * sin(iTime * PI_2 * 0.5);
    col += penroseTriangle(uv * s, 1., t);
    col += penroseTriangle(uv * s, 1. - 5. * t / tan60, t * 0.5);
    col += penroseTriangle(uv * s, 1. - 7.5 * t / tan60, t * 0.25);



    // Debug circle
    //float cirD = sdCircle(uv * s, 1.);
    //col += 1. - smoothstep(0., fwidth(cirD), abs(cirD));
    // col = min(col, 10. * mod(cirD, 0.1));

    // Debug triangle helper
    //float triD = sdTriangle(uv * s, vec2(0., 1.), vec2(0., 1.) * rot2d(120.), vec2(0., 1.) * rot2d(240.));
    //float triD2 = sdTriangle(uv * (s + t), vec2(0., 1.), vec2(0., 1.) * rot2d(120.), vec2(0., 1.) * rot2d(240.));
    // col += 1.0 - sign(d);
    // Anti-aliasing with smoothstep + fwidth
    // col += 1. - smoothstep(0., fwidth(squareD), abs(squareD)); // square border
    // col += 1. - smoothstep(0., 0.006, abs(triD)); // tri border
    // col += 1. - smoothstep(0., 0.006, abs(triD2)); // tri border

    // Output to screen
    fragColor = vec4(col,1.0);
}