diff --git a/edges.scad b/edges.scad index 3401d63..fbc4786 100644 --- a/edges.scad +++ b/edges.scad @@ -6,57 +6,69 @@ ////////////////////////////////////////////////////////////////////// -// CommonCode: -// module text3d(txt,size=3) { -// if (is_list(txt)) { -// for (i=idx(txt)) { -// down((i-len(txt)/2+1)*size*1.25) { -// text3d(txt[i], size=size); -// } -// } -// } else { -// xrot(90) color("#000") -// linear_extrude(height=0.1) { -// text(text=txt, size=size, halign="center", valign="center"); -// } -// } -// } -// module edge_cube(size=20, chamfer=3, txtsize=3, edges="ALL") { -// lbl = is_string(edges)? [str("\"",edges,"\"")] : concat( -// edges.z>0? ["TOP"] : edges.z<0? ["BTM"] : [], -// edges.y>0? ["BACK"] : edges.y<0? ["FWD"] : [], -// edges.x>0? ["RIGHT"] : edges.x<0? ["LEFT"] : [] -// ); -// lbl2 = [for (i=idx(lbl)) i0? ["TOP"] : corners.z<0? ["BTM"] : [], -// corners.y>0? ["BACK"] : corners.y<0? ["FWD"] : [], -// corners.x>0? ["RIGHT"] : corners.x<0? ["LEFT"] : [] -// ); -// lbl2 = [for (i=idx(lbl)) i0) -// translate(CORNER_OFFSETS[i]*size/2) -// color("red") -// cube(1, center=true); -// fwd(size/2) text3d(lbl2, size=txtsize); -// color("yellow",0.7) cuboid(size=size); -// } +module _edges_text3d(txt,size=3) { + if (is_list(txt)) { + for (i=idx(txt)) { + down((i-len(txt)/2+0.5)*size*1.5) { + _edges_text3d(txt[i], size=size); + } + } + } else { + xrot(90) color("#000") + linear_extrude(height=0.1) { + text(text=txt, size=size, halign="center", valign="center"); + } + } +} -// Section: Sets of Edges -// Constants for specifying edges for `cuboid()`, etc. +function _edges_vec_txt(x) = is_string(x)? str("\"", x, "\"") : + assert(is_string(x) || is_vector(x,3), str(x)) + let( + lst = concat( + x.z>0? ["TOP"] : x.z<0? ["BTM"] : [], + x.y>0? ["BACK"] : x.y<0? ["FWD"] : [], + x.x>0? ["RIGHT"] : x.x<0? ["LEFT"] : [] + ), + out = [ + for (i = idx(lst)) + i>0? str("+",lst[i]) : lst[i] + ] + ) out; +function _edges_text(edges) = + is_string(edges) ? [str("\"",edges,"\"")] : + edges==EDGES_NONE ? ["EDGES_NONE"] : + edges==EDGES_ALL ? ["EDGES_ALL"] : + is_edge_array(edges) ? [""] : + is_vector(edges,3) ? _edges_vec_txt(edges) : + is_list(edges) ? let( + lst = [for (x=edges) each _edges_text(x)], + out = [ + for (i=idx(lst)) + str( + (i==0? "[" : ""), + lst[i], + (i0? 1 : 0]]; // [X-Y-, X+Y-, X-Y+, X+Y+] // ] // ``` -// Figure(3DBig): Edge Vectors +// Figure(3D,Big): Edge Vectors // ydistribute(50) { // xdistribute(30) { -// edge_cube(edges=BOT+RIGHT); -// edge_cube(edges=BOT+BACK); -// edge_cube(edges=BOT+LEFT); -// edge_cube(edges=BOT+FRONT); +// show_edges(edges=BOT+RIGHT); +// show_edges(edges=BOT+BACK); +// show_edges(edges=BOT+LEFT); +// show_edges(edges=BOT+FRONT); // } // xdistribute(30) { -// edge_cube(edges=FWD+RIGHT); -// edge_cube(edges=BACK+RIGHT); -// edge_cube(edges=BACK+LEFT); -// edge_cube(edges=FWD+LEFT); +// show_edges(edges=FWD+RIGHT); +// show_edges(edges=BACK+RIGHT); +// show_edges(edges=BACK+LEFT); +// show_edges(edges=FWD+LEFT); // } // xdistribute(30) { -// edge_cube(edges=TOP+RIGHT); -// edge_cube(edges=TOP+BACK); -// edge_cube(edges=TOP+LEFT); -// edge_cube(edges=TOP+FRONT); +// show_edges(edges=TOP+RIGHT); +// show_edges(edges=TOP+BACK); +// show_edges(edges=TOP+LEFT); +// show_edges(edges=TOP+FRONT); // } // } -// Figure(3DBig): Corner Vector Edge Sets +// Figure(3D,Big): Corner Vector Edge Sets // ydistribute(50) { // xdistribute(30) { -// edge_cube(edges=FRONT+LEFT+TOP); -// edge_cube(edges=FRONT+RIGHT+TOP); -// edge_cube(edges=FRONT+LEFT+BOT); -// edge_cube(edges=FRONT+RIGHT+BOT); +// show_edges(edges=FRONT+LEFT+TOP); +// show_edges(edges=FRONT+RIGHT+TOP); +// show_edges(edges=FRONT+LEFT+BOT); +// show_edges(edges=FRONT+RIGHT+BOT); // } // xdistribute(30) { -// edge_cube(edges=TOP+LEFT+BACK); -// edge_cube(edges=TOP+RIGHT+BACK); -// edge_cube(edges=BOT+LEFT+BACK); -// edge_cube(edges=BOT+RIGHT+BACK); +// show_edges(edges=TOP+LEFT+BACK); +// show_edges(edges=TOP+RIGHT+BACK); +// show_edges(edges=BOT+LEFT+BACK); +// show_edges(edges=BOT+RIGHT+BACK); // } // } -// Figure(3D): Face Vector Edge Sets +// Figure(3D,Med): Face Vector Edge Sets // ydistribute(50) { // xdistribute(30) { -// edge_cube(edges=LEFT); -// edge_cube(edges=FRONT); -// edge_cube(edges=RIGHT); +// show_edges(edges=LEFT); +// show_edges(edges=FRONT); +// show_edges(edges=RIGHT); // } // xdistribute(30) { -// edge_cube(edges=TOP); -// edge_cube(edges=BACK); -// edge_cube(edges=BOTTOM); +// show_edges(edges=TOP); +// show_edges(edges=BACK); +// show_edges(edges=BOTTOM); // } // } -// Figure(3D): Named Edge Sets +// Figure(3D,Med): Named Edge Sets // ydistribute(50) { // xdistribute(30) { -// edge_cube(edges="X"); -// edge_cube(edges="Y"); -// edge_cube(edges="Z"); +// show_edges(edges="X"); +// show_edges(edges="Y"); +// show_edges(edges="Z"); // } // xdistribute(30) { -// edge_cube(edges="ALL"); -// edge_cube(edges="NONE"); +// show_edges(edges="ALL"); +// show_edges(edges="NONE"); // } // } -// Example: Just the front-top edge -// edges(FRONT+TOP) -// Example: All edges surrounding either the front or top faces -// edges([FRONT,TOP]) -// Example: All edges around the bottom face, except any that are also on the front -// edges(BTM, except=FRONT) -// Example: All edges except those around the bottom face. -// edges("ALL", except=BOTTOM) -// Example: All Z-aligned edges except those around the back face. -// edges("Z", except=BACK) -// Example: All edges around the bottom or front faces, except the bottom-front edge. -// edges([BOTTOM,FRONT], except=BOTTOM+FRONT) -// Example: All edges, except Z-aligned edges on the front. -// edges("ALL", except=edges("Z", except=BACK)) +// +// Arguments: +// v = The edge set to include. +// except = The edge set to specifically exclude, even if they are in `v`. +// +// Example(3D): Just the front-top edge +// edg = edges(FRONT+TOP); +// show_edges(edges=edg); +// Example(3D): All edges surrounding either the front or top faces +// edg = edges([FRONT,TOP]); +// show_edges(edges=edg); +// Example(3D): All edges around the bottom face, except any that are also on the front +// edg = edges(BTM, except=FRONT); +// show_edges(edges=edg); +// Example(3D): All edges except those around the bottom face. +// edg = edges("ALL", except=BOTTOM); +// show_edges(edges=edg); +// Example(3D): All Z-aligned edges except those around the back face. +// edg = edges("Z", except=BACK); +// show_edges(edges=edg); +// Example(3D): All edges around the bottom or front faces, except the bottom-front edge. +// edg = edges([BOTTOM,FRONT], except=BOTTOM+FRONT); +// show_edges(edges=edg); +// Example(3D): All edges, except Z-aligned edges on the front. +// edg = edges("ALL", except=edges("Z", except=BACK)); +// show_edges(edges=edg); function edges(v, except=[]) = (is_string(v) || is_vector(v) || is_edge_array(v))? edges([v], except=except) : (is_string(except) || is_vector(except) || is_edge_array(except))? edges(v, except=[except]) : @@ -231,38 +282,48 @@ function edges(v, except=[]) = ); -// Constant: EDGES_OFFSETS -// See Also: edges() +// Module: show_edges() +// Usage: +// show_edges(edges, , , ); // Description: -// Array of XYZ offsets to the center of each edge. -EDGE_OFFSETS = [ - [ - [ 0,-1,-1], - [ 0, 1,-1], - [ 0,-1, 1], - [ 0, 1, 1] - ], [ - [-1, 0,-1], - [ 1, 0,-1], - [-1, 0, 1], - [ 1, 0, 1] - ], [ - [-1,-1, 0], - [ 1,-1, 0], - [-1, 1, 0], - [ 1, 1, 0] - ] -]; +// Draws a semi-transparent cube with the given edges highlighted in red. +// Arguments: +// edges = The edges to highlight. +// size = The scalar size of the cube. +// text = The text to show on the front of the cube. +// txtsize = The size of the text. +// Example: +// show_edges(size=30, edges=["X","Y"]); +module show_edges(edges="ALL", size=20, text, txtsize=3) { + edge_set = edges(edges); + text = !is_undef(text) ? text : _edges_text(edges); + color("red") { + for (axis=[0:2], i=[0:3]) { + if (edge_set[axis][i] > 0) { + translate(EDGE_OFFSETS[axis][i]*size/2) { + if (axis==0) xcyl(h=size, d=2); + if (axis==1) ycyl(h=size, d=2); + if (axis==2) zcyl(h=size, d=2); + } + } + } + } + fwd(size/2) _edges_text3d(text, size=txtsize); + color("yellow",0.7) cuboid(size=size); +} -// Section: Corner Sets -// Constants for specifying corners. + +// Section: Corner Constants +// Constants for working with corners. // Constant: CORNERS_NONE // See Also: CORNERS_ALL, corners() // Description: // The set of no corners. +// Figure(3D): +// show_corners(corners="NONE"); CORNERS_NONE = [0,0,0,0,0,0,0,0]; // No corners. @@ -270,9 +331,23 @@ CORNERS_NONE = [0,0,0,0,0,0,0,0]; // No corners. // See Also: CORNERS_NONE, corners() // Description: // The set of all corners. +// Figure(3D): +// show_corners(corners="ALL"); CORNERS_ALL = [1,1,1,1,1,1,1,1]; +// Constant: CORNER_OFFSETS +// See Also: CORNERS_NONE, CORNERS_ALL, corners() +// Description: +// The vectors pointing to each corner of a unit sized cube. +// Each item in a corner array will have a corresponding vector in this array. +CORNER_OFFSETS = [ + [-1,-1,-1], [ 1,-1,-1], [-1, 1,-1], [ 1, 1,-1], + [-1,-1, 1], [ 1,-1, 1], [-1, 1, 1], [ 1, 1, 1] +]; + + + // Section: Corner Helpers // Function: is_corner_array() @@ -331,70 +406,75 @@ function _corner_set(v) = // ``` // [X-Y-Z-, X+Y-Z-, X-Y+Z-, X+Y+Z-, X-Y-Z+, X+Y-Z+, X-Y+Z+, X+Y+Z+] // ``` -// Figure(3DBig): Edge Vectors +// Figure(3D,Big): Corners by Corner Vector // ydistribute(55) { // xdistribute(35) { -// corner_cube(corners=BOT+RIGHT); -// corner_cube(corners=BOT+BACK); -// corner_cube(corners=BOT+LEFT); -// corner_cube(corners=BOT+FRONT); +// show_corners(corners=FRONT+LEFT+TOP); +// show_corners(corners=FRONT+RIGHT+TOP); +// show_corners(corners=FRONT+LEFT+BOT); +// show_corners(corners=FRONT+RIGHT+BOT); // } // xdistribute(35) { -// corner_cube(corners=FWD+RIGHT); -// corner_cube(corners=BACK+RIGHT); -// corner_cube(corners=BACK+LEFT); -// corner_cube(corners=FWD+LEFT); -// } -// xdistribute(35) { -// corner_cube(corners=TOP+RIGHT); -// corner_cube(corners=TOP+BACK); -// corner_cube(corners=TOP+LEFT); -// corner_cube(corners=TOP+FRONT); +// show_corners(corners=TOP+LEFT+BACK); +// show_corners(corners=TOP+RIGHT+BACK); +// show_corners(corners=BOT+LEFT+BACK); +// show_corners(corners=BOT+RIGHT+BACK); // } // } -// Figure(3DBig): Corner Vector Edge Sets +// Figure(3D,Big): Corners by Edge Vectors // ydistribute(55) { // xdistribute(35) { -// corner_cube(corners=FRONT+LEFT+TOP); -// corner_cube(corners=FRONT+RIGHT+TOP); -// corner_cube(corners=FRONT+LEFT+BOT); -// corner_cube(corners=FRONT+RIGHT+BOT); +// show_corners(corners=BOT+RIGHT); +// show_corners(corners=BOT+BACK); +// show_corners(corners=BOT+LEFT); +// show_corners(corners=BOT+FRONT); // } // xdistribute(35) { -// corner_cube(corners=TOP+LEFT+BACK); -// corner_cube(corners=TOP+RIGHT+BACK); -// corner_cube(corners=BOT+LEFT+BACK); -// corner_cube(corners=BOT+RIGHT+BACK); +// show_corners(corners=FWD+RIGHT); +// show_corners(corners=BACK+RIGHT); +// show_corners(corners=BACK+LEFT); +// show_corners(corners=FWD+LEFT); +// } +// xdistribute(35) { +// show_corners(corners=TOP+RIGHT); +// show_corners(corners=TOP+BACK); +// show_corners(corners=TOP+LEFT); +// show_corners(corners=TOP+FRONT); // } // } -// Figure(3D): Face Vector Edge Sets +// Figure(3D,Med): Corners by Face Vectors // ydistribute(55) { // xdistribute(35) { -// corner_cube(corners=LEFT); -// corner_cube(corners=FRONT); -// corner_cube(corners=RIGHT); +// show_corners(corners=LEFT); +// show_corners(corners=FRONT); +// show_corners(corners=RIGHT); // } // xdistribute(35) { -// corner_cube(corners=TOP); -// corner_cube(corners=BACK); -// corner_cube(corners=BOTTOM); +// show_corners(corners=TOP); +// show_corners(corners=BACK); +// show_corners(corners=BOTTOM); // } // } -// Figure(3D): Named Edge Sets +// Figure(3D,Med): Corners by Name // xdistribute(35) { -// corner_cube(corners="ALL"); -// corner_cube(corners="NONE"); +// show_corners(corners="ALL"); +// show_corners(corners="NONE"); // } -// Example: Just the front-top-right corner -// corners(FRONT+TOP+RIGHT) -// Example: All corners surrounding either the front or top faces -// corners([FRONT,TOP]) -// Example: All corners around the bottom face, except any that are also on the front -// corners(BTM, except=FRONT) -// Example: All corners except those around the bottom face. -// corners("ALL", except=BOTTOM) -// Example: All corners around the bottom or front faces, except those on the bottom-front edge. -// corners([BOTTOM,FRONT], except=BOTTOM+FRONT) +// Example(3D): Just the front-top-right corner +// crn = corners(FRONT+TOP+RIGHT); +// show_corners(corners=crn); +// Example(3D): All corners surrounding either the front or top faces +// crn = corners([FRONT,TOP]); +// show_corners(corners=crn); +// Example(3D): All corners around the bottom face, except any that are also on the front +// crn = corners(BTM, except=FRONT); +// show_corners(corners=crn); +// Example(3D): All corners except those around the bottom face. +// crn = corners("ALL", except=BOTTOM); +// show_corners(corners=crn); +// Example(3D): All corners around the bottom or front faces, except those on the bottom-front edge. +// crn = corners([BOTTOM,FRONT], except=BOTTOM+FRONT); +// show_corners(corners=crn); function corners(v, except=[]) = (is_string(v) || is_vector(v) || is_corner_array(v))? corners([v], except=except) : (is_string(except) || is_vector(except) || is_corner_array(except))? corners(v, except=[except]) : @@ -405,19 +485,10 @@ function corners(v, except=[]) = ) normalize_corners(a - b); -// Constant: CORNER_OFFSETS -// See Also: corners() -// Description: -// Array of XYZ offsets to each corner. -CORNER_OFFSETS = [ - [-1,-1,-1], [ 1,-1,-1], [-1, 1,-1], [ 1, 1,-1], - [-1,-1, 1], [ 1,-1, 1], [-1, 1, 1], [ 1, 1, 1] -]; - - // Function: corner_edges() // Description: -// Returns [XCOUNT,YCOUNT,ZCOUNT] where each is the count of edges aligned with that axis that are in the edge set and touch the given corner. +// Returns [XCOUNT,YCOUNT,ZCOUNT] where each is the count of edges aligned with that +// axis that are in the edge set and touch the given corner. // Arguments: // edges = Standard edges array. // v = Vector pointing to the corner to count edge intersections at. @@ -426,7 +497,8 @@ function corner_edges(edges, v) = // Function: corner_edge_count() -// Description: Counts how many given edges intersect at a specific corner. +// Description: +// Counts how many given edges intersect at a specific corner. // Arguments: // edges = Standard edges array. // v = Vector pointing to the corner to count edge intersections at. @@ -434,4 +506,49 @@ function corner_edge_count(edges, v) = let(u = (v+[1,1,1])/2) edges[0][u.y+u.z*2] + edges[1][u.x+u.z*2] + edges[2][u.x+u.y*2]; +function _corners_text(corners) = + is_string(corners) ? [str("\"",corners,"\"")] : + corners==CORNERS_NONE ? ["CORNERS_NONE"] : + corners==CORNERS_ALL ? ["CORNERS_ALL"] : + is_corner_array(corners) ? [""] : + is_vector(corners,3) ? _edges_vec_txt(corners) : + is_list(corners) ? let( + lst = [for (x=corners) each _corners_text(x)], + out = [ + for (i=idx(lst)) + str( + (i==0? "[" : ""), + lst[i], + (i, , ); +// Description: +// Draws a semi-transparent cube with the given corners highlighted in red. +// Arguments: +// corners = The corners to highlight. +// size = The scalar size of the cube. +// text = If given, overrides the text to be shown on the front of the cube. +// txtsize = The size of the text. +// Example: +// show_corners(corners=FWD+RIGHT, size=30); +module show_corners(corners="ALL", size=20, text, txtsize=3) { + corner_set = corners(corners); + text = !is_undef(text) ? text : _corners_text(corners); + for (i=[0:7]) if (corner_set[i]>0) + translate(CORNER_OFFSETS[i]*size/2) + color("red") sphere(d=2, $fn=16); + fwd(size/2) _edges_text3d(text, size=txtsize); + color("yellow",0.7) cuboid(size=size); +} + + + // vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap