diff --git a/beziers.scad b/beziers.scad index e9a6e98..5589f2c 100644 --- a/beziers.scad +++ b/beziers.scad @@ -887,15 +887,19 @@ function is_bezier_patch(x) = // Description: // Returns a flat rectangular bezier patch of degree `N`, centered on the XY plane. // Arguments: -// size = 2D XY size of the patch. +// size = scalar or 2-vector giving the X and Y dimensions of the patch. // --- -// N = Degree of the patch to generate. Since this is flat, a degree of 1 should usually be sufficient. -// orient = The orientation to rotate the edge patch into. Given as an [X,Y,Z] rotation angle list. -// trans = Amount to translate patch, after rotating to `orient`. +// N = Degree of the patch to generate. Since this is flat, a degree of 1 should usually be sufficient. Default: 1 +// orient = A direction vector. Point the patch normal in this direction. +// spin = Spin angle to apply to the patch +// trans = Amount to translate patch, after orient and spin. // Example(3D): -// patch = bezier_patch_flat(size=[100,100], N=3); +// patch = bezier_patch_flat(size=[100,100]); // debug_bezier_patches([patch], size=1, showcps=true); -function bezier_patch_flat(size=[100,100], N=4, spin=0, orient=UP, trans=[0,0,0]) = +function bezier_patch_flat(size, N=1, spin=0, orient=UP, trans=[0,0,0]) = + assert(N>0) + let(size = force_list(size,2)) + assert(is_vector(size,2)) let( patch = [ for (x=[0:1:N]) [ @@ -994,6 +998,7 @@ function _bezier_rectangle(patch, splinesteps=16, style="default") = // It can be a scalar, which gives a uniform grid, or // it can be [USTEPS, VSTEPS], which gives difference spacing in the U and V parameters. // Note that the surface you produce may be disconnected and is not necessarily a valid manifold in OpenSCAD. +// You must also ensure that the patches mate exactly along their edges, or the VNF will be invalid. // Arguments: // patches = The bezier patch or list of bezier patches to convert into a vnf. // splinesteps = Number of segments on the border of the bezier surface. You can specify [USTEPS,VSTEPS]. Default: 16 @@ -1010,21 +1015,23 @@ function _bezier_rectangle(patch, splinesteps=16, style="default") = // vnf = bezier_vnf(patch, splinesteps=16); // vnf_polyhedron(vnf); // Example(3D,FlatSpin,VPD=444): Combining multiple patches -// patch = [ +// patch = 100*[ // // u=0,v=0 u=1,v=0 -// [[0, 0,0], [33, 0, 0], [67, 0, 0], [100, 0,0]], -// [[0, 33,0], [33, 33, 33], [67, 33, 33], [100, 33,0]], -// [[0, 67,0], [33, 67, 33], [67, 67, 33], [100, 67,0]], -// [[0,100,0], [33,100, 0], [67,100, 0], [100,100,0]], +// [[0, 0,0], [1/3, 0, 0], [2/3, 0, 0], [1, 0,0]], +// [[0,1/3,0], [1/3,1/3,1/3], [2/3,1/3,1/3], [1,1/3,0]], +// [[0,2/3,0], [1/3,2/3,1/3], [2/3,2/3,1/3], [1,2/3,0]], +// [[0, 1,0], [1/3, 1, 0], [2/3, 1, 0], [1, 1,0]], // // u=0,v=1 u=1,v=1 // ]; +// fpatch = bezier_patch_flat([100,100]); // tpatch = translate([-50,-50,50], patch); +// flatpatch = translate([0,0,50], fpatch); // vnf = bezier_vnf([ // tpatch, // xrot(90, tpatch), // xrot(-90, tpatch), // xrot(180, tpatch), -// yrot(90, tpatch), +// yrot(90, flatpatch), // yrot(-90, tpatch)]); // vnf_polyhedron(vnf); // Example(3D): diff --git a/drawing.scad b/drawing.scad index 62738e5..4d85321 100644 --- a/drawing.scad +++ b/drawing.scad @@ -21,6 +21,7 @@ // stroke(path, [width], [closed], [endcaps], [endcap_width], [endcap_length], [endcap_extent], [trim]); // stroke(path, [width], [closed], [endcap1], [endcap2], [endcap_width1], [endcap_width2], [endcap_length1], [endcap_length2], [endcap_extent1], [endcap_extent2], [trim1], [trim2]); // Topics: Paths (2D), Paths (3D), Drawing Tools +// See Also: offset_stroke(), path_sweep() // Description: // Draws a 2D or 3D path with a given line width. Joints and each endcap can be replaced with // various marker shapes, and can be assigned different colors. If passed a region instead of @@ -28,7 +29,13 @@ // given with a region or list of paths, then each path is drawn without the closing line segment. // To facilitate debugging, stroke() accepts "paths" that have a single point. These are drawn with // the style of endcap1, but have their own scale parameter, `singleton_scale`, which defaults to 2 -// so that singleton dots with endcap "round" are clearly visible. +// so that singleton dots with endcap "round" are clearly visible. +// . +// In 2d the stroke module works by creating a sequence of rectangles (or trapezoids if line width varies) and +// filling in the gaps with rounded wedges. This is fast and produces a good result. In 3d the modules +// creates a cylinders (or cones) and fills the gaps with rounded wedges made using rotate_extrude. This process will be slow for +// long paths due to the 3d unions, and the faces on sequential cylinders may not line up. In many cases, {{path_sweep()}} will be +// a better choice, both running faster and producing superior output, when working in three dimensions. // Figure(Med,NoAxes,2D,VPR=[0,0,0],VPD=250): Endcap Types // cap_pairs = [ // ["butt", "chisel" ], diff --git a/lists.scad b/lists.scad index 25cd15c..37b3e1a 100644 --- a/lists.scad +++ b/lists.scad @@ -802,12 +802,14 @@ function list_remove_values(list,values=[],all=false) = // Function: idx() // Usage: -// rng = idx(list, [s=], [e=], [step=]); +// range = idx(list, [s=], [e=], [step=]); // for(i=idx(list, [s=], [e=], [step=])) ... // Topics: List Handling, Iteration -// See Also: pair(), triplet(), combinations(), permutations() +// See Also: count() // Description: -// Returns the range of indexes for the given list. +// Returns the range that gives the indices for a given list. This makes is a little bit +// easier to loop over a list by index, when you need the index numbers and looping of list values isn't enough. +// Note that the return is a **range** not a list. // Arguments: // list = The list to returns the index range of. // --- diff --git a/screws.scad b/screws.scad index 761ce61..26345c5 100644 --- a/screws.scad +++ b/screws.scad @@ -426,7 +426,7 @@ Torx values: https://www.stanleyengineeredfastening.com/-/media/web/sef/resourc // screw("1/4-20,3/8", head="hex",orient=UP,anchor=BOTTOM,tolerance="1A"); // down(INCH*1/20*1.395) nut("1/4-20", thickness=8, nutwidth=0.5*INCH, tolerance="1B"); // } -// Example: Here is a screw with nonstadard threading and a weird head size, which we create by modifying the screw structure: +// Example: Here is a screw with nonstandard threading and a weird head size, which we create by modifying the screw structure: // spec = screw_info("M6x2,12",head="socket"); // newspec = struct_set(spec,["head_size",20,"head_height",3]); // screw(newspec);