diff --git a/attachments.scad b/attachments.scad index 1a7ddded..01c81806 100644 --- a/attachments.scad +++ b/attachments.scad @@ -1052,7 +1052,9 @@ module attach(parent, child, overlap, align, spin=0, norot, inset=0, shiftout=0, * affine3d_zrot(-parent_abstract_anchor[3]) * rot(from=parent_abstract_anchor[2],to=UP) * rot(v=anchor,-spin), - align); + align); + + spinaxis = two_d? UP : anchor_dir; olap = - overlap * reference - inset*inset_dir + shiftout * (inset_dir + factor*reference); if (norot || (approx(anchor_dir,reference) && anchor_spin==0)) @@ -3532,7 +3534,8 @@ function attach_geom( ) ) ) : - ["point", cp, offset, anchors]; + two_d? ["point2d", cp, offset, anchors] + : ["point", cp, offset, anchors]; @@ -3554,7 +3557,7 @@ function attach_geom( function _attach_geom_2d(geom) = let( type = geom[0] ) type == "trapezoid" || type == "ellipse" || - type == "rgn_isect" || type == "rgn_extent"; + type == "rgn_isect" || type == "rgn_extent" || type=="point2d"; /// Internal Function: _attach_geom_size() @@ -3567,6 +3570,7 @@ function _attach_geom_2d(geom) = function _attach_geom_size(geom) = let( type = geom[0] ) type == "point"? [0,0,0] : + type == "point2d"? [0,0] : type == "prismoid"? ( //size, size2, shift, axis let( size=geom[1], size2=geom[2], shift=point2d(geom[3]), @@ -3992,6 +3996,12 @@ function _find_anchor(anchor, geom)= pos = point3d(cp) + point3d(offset), vec = unit(anchor,UP) ) [anchor, pos, vec, oang] + ) : type == "point2d"? ( + let( + anchor = unit(_force_anchor_2d(anchor), [0,0]), + pos = point2d(cp) + point2d(offset), + vec = unit(anchor,BACK) + ) [anchor, pos, vec, oang] ) : type == "spheroid"? ( //r let( rr = geom[1], @@ -4984,7 +4994,7 @@ function _local_struct_val(struct, key)= function _force_anchor_2d(anchor) = - is_undef(anchor) || len(anchor)==2 ? anchor : + is_undef(anchor) || len(anchor)==2 || is_string(anchor) ? anchor : assert(anchor.y==0 || anchor.z==0, "Anchor for a 2D shape cannot be fully 3D. It must have either Y or Z component equal to zero.") anchor.y==0 ? [anchor.x,anchor.z] : point2d(anchor); diff --git a/drawing.scad b/drawing.scad index a9d2fe28..5a4d360d 100644 --- a/drawing.scad +++ b/drawing.scad @@ -299,7 +299,8 @@ module stroke( // We want to allow "paths" with length 1, so we can't use the normal path/region checks paths = is_matrix(path) ? [path] : path; assert(is_list(paths),"The path argument must be a list of 2D or 3D points, or a region."); - attachable(){ + attachable(two_d=true) + { for (path = paths) { pathvalid = is_path(path,[2,3]) || same_shape(path,[[0,0]]) || same_shape(path,[[0,0,0]]); diff --git a/shapes2d.scad b/shapes2d.scad index 2bb2e9a6..a948c197 100644 --- a/shapes2d.scad +++ b/shapes2d.scad @@ -260,14 +260,14 @@ function rect(size=1, rounding=0, chamfer=0, atype="box", anchor=CENTER, spin=0, // Example(2D): Fit to Three Points // pts = [[50,25], [25,-25], [-10,0]]; // circle(points=pts); -// color("red") move_copies(pts) circle(); +// color("red") move_copies(pts) circle(r=1.5,$fn=12); // Example(2D): Fit Tangent to Inside Corner of Two Segments // path = [[50,25], [-10,0], [25,-25]]; // circle(corner=path, r=15); // color("red") stroke(path); // Example(2D): Called as Function // path = circle(d=50, anchor=FRONT, spin=45); -// stroke(path); +// stroke(path,closed=true); function circle(r, d, points, corner, anchor=CENTER, spin=0) = assert(is_undef(corner) || (is_path(corner,[2]) && len(corner) == 3)) assert(is_undef(points) || is_undef(corner), "Cannot specify both points and corner.") @@ -377,41 +377,41 @@ module circle(r, d, points, corner, anchor=CENTER, spin=0) { // r=[10,3]; // ydistribute(7){ // union(){ -// stroke([ellipse(r=r, $fn=100)],width=0.05,color="blue"); -// stroke([ellipse(r=r, $fn=6)],width=0.1,color="red"); +// stroke([ellipse(r=r, $fn=100)],width=0.1,color="blue"); +// stroke([ellipse(r=r, $fn=6)],width=0.2,color="red"); // } // union(){ -// stroke([ellipse(r=r, $fn=100)],width=0.05,color="blue"); -// stroke([ellipse(r=r, $fn=6,uniform=true)],width=0.1,color="red"); +// stroke([ellipse(r=r, $fn=100)],width=0.1,color="blue"); +// stroke([ellipse(r=r, $fn=6,uniform=true)],width=0.2,color="red"); // } // } -// Example(2D): The realigned hexagons are even more different +// Example(2D,NoAxes): The realigned hexagons are even more different // r=[10,3]; // ydistribute(7){ // union(){ -// stroke([ellipse(r=r, $fn=100)],width=0.05,color="blue"); -// stroke([ellipse(r=r, $fn=6,realign=true)],width=0.1,color="red"); +// stroke([ellipse(r=r, $fn=100)],width=0.1,color="blue"); +// stroke([ellipse(r=r, $fn=6,realign=true)],width=0.2,color="red"); // } // union(){ -// stroke([ellipse(r=r, $fn=100)],width=0.05,color="blue"); -// stroke([ellipse(r=r, $fn=6,realign=true,uniform=true)],width=0.1,color="red"); +// stroke([ellipse(r=r, $fn=100)],width=0.1,color="blue"); +// stroke([ellipse(r=r, $fn=6,realign=true,uniform=true)],width=0.2,color="red"); // } // } -// Example(2D): For odd $fn the result may not look very elliptical: +// Example(2D,NoAxes): For odd $fn the result may not look very elliptical: // r=[10,3]; // ydistribute(7){ // union(){ -// stroke([ellipse(r=r, $fn=100)],width=0.05,color="blue"); -// stroke([ellipse(r=r, $fn=5,realign=false)],width=0.1,color="red"); +// stroke([ellipse(r=r, $fn=100)],width=0.1,color="blue"); +// stroke([ellipse(r=r, $fn=5,realign=false)],width=0.2,color="red"); // } // union(){ -// stroke([ellipse(r=r, $fn=100)],width=0.05,color="blue"); -// stroke([ellipse(r=r, $fn=5,realign=false,uniform=true)],width=0.1,color="red"); +// stroke([ellipse(r=r, $fn=100)],width=0.1,color="blue"); +// stroke([ellipse(r=r, $fn=5,realign=false,uniform=true)],width=0.2,color="red"); // } // } -// Example(2D): The same ellipse, turned 90 deg, gives a very different result: +// Example(2D,NoAxes): The same ellipse, turned 90 deg, gives a very different result: // r=[3,10]; -// xdistribute(7){ +// xdistribute(9){ // union(){ // stroke([ellipse(r=r, $fn=100)],width=0.1,color="blue"); // stroke([ellipse(r=r, $fn=5,realign=false)],width=0.2,color="red");