1/* 2float fOpUnionRound(float a, float b, float r) { 3 vec2 u = max(vec2(r - a,r - b), vec2(0)); 4 return max(r, min (a, b)) - length(u); 5} 6 7float fOpIntersectionRound(float a, float b, float r) { 8 vec2 u = max(vec2(r + a,r + b), vec2(0)); 9 return min(-r, max (a, b)) + length(u); 10} 11*/ 12 13round_min2(k,a,b) = max(k, min(a,b)) - mag(max([k-a,k-b], 0)); 14round_union2 k (s1, s2) = make_shape { 15 dist p : round_min2(k, s1.dist p, s2.dist p), 16 colour p : ( 17 var d1 := s1.dist p; 18 var d2 := s2.dist p; 19 if (d2 <= 0 || d2 <= d1) s2.colour p else s1.colour p 20 ), 21 bbox : [min(s1.bbox'0, s2.bbox'0), max(s1.bbox'1, s2.bbox'1)], 22 is_2d : s1.is_2d && s2.is_2d, 23 is_3d : s1.is_3d && s2.is_3d, 24}; 25 26round_min3(k,a,b,c) = max(k, min(a,b,c)) - mag(max([k-a,k-b,k-c], 0)); 27round_union3 k (s1, s2, s3) = make_shape { 28 dist p : round_min3(k, s1.dist p, s2.dist p, s3.dist p), 29/* 30 colour p : ( 31 var d1 := s1.dist p; 32 var d2 := s2.dist p; 33 if (d2 <= 0 || d2 <= d1) s2.colour p else s1.colour p 34 ), 35*/ 36 bbox : [min(s1.bbox'0, s2.bbox'0), max(s1.bbox'1, s2.bbox'1)], 37 is_2d : s1.is_2d && s2.is_2d, 38 is_3d : s1.is_3d && s2.is_3d, 39}; 40 41/* bad gradient 42round_union2 .5 ( 43 rect.exact(.1,3), 44 rect.exact(3,.1) >> rotate(45*deg), 45) 46*/ 47 48/* it works 49round_union3 1.184 ( 50 circle 1 >> move(cis(90*deg)), 51 circle 1 >> move(cis(-30*deg)), 52 circle 1 >> move(cis(-150*deg)), 53) 54*/ 55 56union ( 57 round_union2 1 ( 58 square 1, 59 square 1, 60 ), 61 square 1 >> colour black, 62 square .25 >> colour red >> move(.625,0), 63) 64