// Circle packing
// https://en.wikipedia.org/wiki/Circle_packing

// Hue taken from https://www.shadertoy.com/view/4tlBWB

#define tau 6.28318
#define pi 3.14159
#define ep 1e-2  // epsilon (fix edge cases)

vec3 hue( in vec3 c )
{
	return c.z*(1.-c.y*smoothstep(2.,1.,abs(mod(c.x*6.+vec3(0,4,2),6.) -3.)));
}

float circle(vec2 xy, vec2 c, float r, bool fill){
    float dist = length(xy-c)-r;
    return 1.-smoothstep(-2./iResolution.y,3./iResolution.y,fill?dist:abs(dist));
}

vec3 circles(vec2 xy, vec2 C, float R, float r, float ph){
    
	float t = 2.*asin(r/(R+r)); 		// theta for each surrounding circle
    
    float div = abs(tau/t)+ep;
	int n = int(div); 					// number of surrounding circles
    float pad = fract(div)*t/float(n);	// circles padding                                       
    
    float rt = -t/2.-pad/2.+ph;			// plane rotation
    mat2 rm = mat2(cos(rt),-sin(rt),sin(rt),cos(rt));
    vec2 zw = rm*(xy-C);				// rotated plane
    
    float i = floor((atan(zw.y,zw.x))/(t+pad));                 // i-th circle
    vec2 c = vec2(cos(i*(t+pad)+ph),sin(i*(t+pad)+ph))*(r+R)+C; // center of surrounding circles
	
    vec3 hsl = vec3(i/float(n),1.,.75); // color for each surrounding circle
    return circle(xy,c,r,true)*hue(hsl);
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 xy = (2.*fragCoord.xy-iResolution.xy)/iResolution.y;
	vec3 col = vec3(0);
        
    vec2 C = vec2(0); // center
    float R = .175;	// central circle radius
	float r = .075;	// surrounding circle radius

    col+=circle(xy, C, R, false);// draw central circle
    
    float n = 20.; // number of layers
    float i = floor((min(r*2.*(n-1.)+ep,length(xy-C)-R))/(r*2.)); // i-th layer
    
    if(i>=0.)
        col+=circles(xy, C, R+r*i*2., r,pi*sin(iTime)/n*i);  // draw surrounding circles
    
    fragColor = vec4(1.-col,1.0);
}
