Skip to content

Commit e0c6280

Browse files
cylindrical_extrude bugfix
1 parent 683bab1 commit e0c6280

File tree

1 file changed

+28
-13
lines changed

1 file changed

+28
-13
lines changed

miscellaneous.scad

+28-13
Original file line numberDiff line numberDiff line change
@@ -251,19 +251,30 @@ module path_extrude(path, convexity=10, clipsize=100) {
251251
// Usage:
252252
// cylindrical_extrude(ir|id=, or|od=, [size=], [convexity=], [spin=], [orient=]) 2D-CHILDREN;
253253
// Description:
254-
// Extrudes its 2D children outwards, curved around a cylindrical shape. Uses $fn/$fa/$fs to
255-
// control the faceting of the extrusion.
254+
// Chops the 2D children into rectangles and extrudes each rectangle as a facet around an
255+
// approximate cylindrical shape. Uses $fn/$fa/$fs to control the number of facets.
256+
// By default the calculation assumes that the children occupy in the X direction one revolution of the
257+
// cylinder of specified radius/diameter and are not more than 1000 units tall (in the Y direction).
258+
// If the children are in fact much smaller in width then this assumption is inefficient. If the children
259+
// are wider then they will be truncated at one revolution. To address either of these problems you can set
260+
// the `size` parameter. Note that the specified height isn't very important: it just needs to be larger than
261+
// the actual height of the children, which is why it defaults to 1000. If you set `size` to a scalar then
262+
// that only changes the X value and the Y value remains at the default of 1000.
263+
// .
264+
// When performing the wrap, the X=0 line of the children maps to the Y- axis and the facets are centered on the Y- axis.
265+
// This is not consistent with how cylinder() creates its facets. If `$fn` is a multiple of 4 then the facets will line
266+
// up with a cylinder. Otherwise you must rotate a cylinder by 90 deg in the case of `$fn` even or `90-360/$fn/2` if `$fn` is odd.
256267
// Arguments:
257268
// ir = The inner radius to extrude from.
258269
// or = The outer radius to extrude to.
259270
// ---
260271
// od = The outer diameter to extrude to.
261272
// id = The inner diameter to extrude from.
262-
// size = The [X,Y] size of the 2D children to extrude. Default: [1000,1000]
273+
// size = If a scalar, the width of the 2D children. If a vector, the [X,Y] size of the 2D children. Default: [2*PI*or,1000]
263274
// convexity = The max number of times a line could pass though a wall. Default: 10
264275
// spin = Amount in degrees to spin around cylindrical axis. Default: 0
265276
// orient = The orientation of the cylinder to wrap around, given as a vector. Default: UP
266-
// Example:
277+
// Example: Basic example with defaults. This will run faster with large facet counts if you set `size=100`
267278
// cylindrical_extrude(or=50, ir=45)
268279
// text(text="Hello World!", size=10, halign="center", valign="center");
269280
// Example: Spin Around the Cylindrical Axis
@@ -272,29 +283,33 @@ module path_extrude(path, convexity=10, clipsize=100) {
272283
// Example: Orient to the Y Axis.
273284
// cylindrical_extrude(or=40, ir=35, orient=BACK)
274285
// text(text="Hello World!", size=10, halign="center", valign="center");
275-
module cylindrical_extrude(ir, or, od, id, size=1000, convexity=10, spin=0, orient=UP) {
286+
// Example(Med): You must give a size argument for this example where the child wraps fully around the cylinder
287+
// cylindrical_extrude(or=27, ir=25, size=300, spin=-85)
288+
// zrot(-10)text(text="This long text wraps around the cylinder.", size=10, halign="center", valign="center");
289+
module cylindrical_extrude(ir, or, od, id, size, convexity=10, spin=0, orient=UP) {
276290
req_children($children);
277-
check1 = assert(is_num(size) || is_vector(size,2));
278-
size = is_num(size)? [size,size] : size;
279291
ir = get_radius(r=ir,d=id);
280292
or = get_radius(r=or,d=od);
281293
check2 = assert(all_positive([ir,or]), "Must supply positive inner and outer radius or diameter");
282-
index_r = or;
283-
circumf = 2 * PI * index_r;
284-
width = min(size.x, circumf);
285-
check3 = assert(width <= circumf, "Shape would more than completely wrap around.");
294+
circumf = 2 * PI * or;
295+
size = is_undef(size) ? [circumf, 1000]
296+
: is_num(size) ? [size, 1000]
297+
: size;
298+
check1 = assert(is_vector(size,2) && all_positive(size), "Size must be a positive number or 2-vector");
286299
sides = segs(or);
287300
step = circumf / sides;
288-
steps = ceil(width / step);
301+
steps = ceil(size.x / step);
302+
scalefactor = sides/PI*sin(180/sides); // Scale from circle to polygon, which has shorter length
289303
attachable() {
290304
rot(from=UP, to=orient) rot(spin) {
291-
for (i=[0:1:steps-2]) {
305+
for (i=[0:1:steps-1]) {
292306
x = (i+0.5-steps/2) * step;
293307
zrot(360 * x / circumf) {
294308
fwd(or*cos(180/sides)) {
295309
xrot(-90) {
296310
linear_extrude(height=or-ir, scale=[ir/or,1], center=false, convexity=convexity) {
297311
yflip()
312+
xscale(scalefactor)
298313
intersection() {
299314
left(x) children();
300315
rect([quantup(step,pow(2,-15)),size.y]);

0 commit comments

Comments
 (0)