}
}
+module rectfromto(a,b) {
+ ab = b - a;
+ translate([min(a[0], b[0]), min(a[1], b[1])])
+ square([abs(ab[0]), abs(ab[1])]);
+}
+module circleat(c,r) { translate(c) circle(r); }
+module linextr(z0,z1, convexity=20) {
+ translate([0,0,z0])
+ linear_extrude(height=z1-z0, convexity=convexity)
+ children();
+}
+
+module linextr_x_yz(x0,x1, convexity=20) { // XY turn into YZ
+ rotate([90,0,0])
+ rotate([0,90,0])
+ linextr(x0,x1, convexity=convexity)
+ children();
+}
+
+module linextr_y_xz(y0,y1, convexity=20) { // XY turn into YZ
+ rotate([0,0,180])
+ rotate([90,0,0])
+ linextr(y0,y1, convexity=convexity)
+ children();
+}