// -*- C -*- function vecdiff2d(a,b) = [b[0]-a[0], b[1]-a[1]]; function vecdiff(a,b) = [b[0]-a[0], b[1]-a[1], b[2]-a[2]]; #define dsq(i) (a[i]-b[i])*(a[i]-b[i]) function dist2d(a,b) = sqrt(dsq(0) + dsq(1)); function dist(a,b) = sqrt(dsq(0) + dsq(1) + dsq(2)); #undef dsq #define vsq(i) (v[i]*v[i]) function vectorlen2d(v) = sqrt(vsq(0) + vsq(1)); function vectorlen(v) = sqrt(vsq(0) + vsq(1) + vsq(2)); #undef vsq function unitvector2d(v) = v / vectorlen2d(v); function unitvector(v) = v / vectorlen(v); function atan2vector(v) = atan2(v[1], v[0]); // | m[0][0] m[0][1] | // | m[1][0] m[1][1] | function determinant2(m) = (m[0][0] * m[1][1] - m[0][1] * m[1][0]); function clockwise2d(v) = [v[1], -v[0]]; // intersection of lines p1..p2 and p3..p4 function line_intersection_2d(p1,p2,p3,p4) = [ // from https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection#Given_two_points_on_each_line #define XY12 determinant2([p1,p2]) #define XY34 determinant2([p3,p4]) #define XU12 QU(0,1,2) #define XU34 QU(0,3,4) #define YU12 QU(1,1,2) #define YU34 QU(1,3,4) #define QU(c,i,j) determinant2([[ p##i[c], 1 ], \ [ p##j[c], 1 ]]) #define DENOM \ determinant2([[ XU12, YU12 ], \ [ XU34, YU34 ]]) //---- determinant2([[ XY12, XU12 ], [ XY34, XU34 ]]) / DENOM, determinant2([[ XY12, YU12 ], [ XY34, YU34 ]]) / DENOM, ]; #undef XY12 #undef XY34 #undef XU12 #undef XU34 #undef YU12 #undef YU34 #undef QU #undef DENOM function circle_point(c, r, alpha) = [ c[0] + r * cos(alpha), c[1] + r * sin(alpha) ]; #define d (dist2d(a,c)) #define alpha (atan2(a[1]-c[1],a[0]-c[0])) #define gamma (asin(r / d)) #define beta (alpha + 90 - gamma) function tangent_intersect_beta(c,r,a) = beta; function tangent_intersect_b(c,r,a) = circle_point(c, r, beta); #undef d #undef alpha #undef gamma #undef beta function tangents_intersect_beta(cbig,rbig,csmall,rsmall) = tangent_intersect_beta(cbig,rbig-rsmall,csmall); function reflect_in_y(p) = [-p[0], p[1]]; function angle_map_range(in,base) = in < base ? in + 360 : in >= base + 360 ? in - 360 : in;