Nodes:0#` Lines:2#,!0 Circles:2#,0#0. circles:{ / generate circles if[0<#Nodes c:_(#Nodes)%r:__sqrt#Nodes;r+:(#Nodes)!r Circles::+,/(1+(!r),\:/:!c)*\:\:(x,y)%1+r,c] } load:{t:1:x;;@[_d;!t;:;t[]];} / load file save:{x 1:.+(`Nodes`Circles`Lines;(Nodes;Circles;Lines))} / object cc:{[d;c;r]_sqr[r*2]>+/_sqr d-c} / circles overlap? pc:{[p;c;r]_sqr[r]>+/_sqr p-c} / point in circle? dpp:{[p;q]_sqrt+/_sqr p-q} / dist point to point dpc:{[p;c;r]dpp[p;c]-r} / dist point to circle dpl:{[p;s;e]dpp[p]ip[p;s;e]} / dist point to line nc:{e?&/e:dpc[x,y;Circles]z} / nearest circle to point nl:{d?&/d:dpl[x,y].'+(+Circles)Lines} / nearest line to point sl:%/|- / slope of line sel:{x!#*Circles} / next select ip:{[p;s;e] / point on line if[s[0]=*e;:s[0],p 1] if[s[1]=e 1;:p[0],s 1] i:-%k:sl[e]s x:(p[1]+(k**s)-s[1]+i**p)%k-i y:s[1]+k*x-*s x,y} icr:{[c;p;r] / point on circle w/radius if[c[0]=*p;:c[0],:[c[1]>p 1;c[1]-r;r+c 1]] if[c[1]=p 1;::[c[0]>*p;c[0]-r;r+*c],c 1] t:r%_sqrt 1+_sqr m:sl[p]c x1:c[0]+t;y1:c[1]+m*x1-*c;p1:x1,y1 x2:c[0]-t;y2:c[1]+m*x2-*c;p2:x2,y2 :[dpp[p1;p]x r}