@@ -251,19 +251,30 @@ module path_extrude(path, convexity=10, clipsize=100) {
251
251
// Usage:
252
252
// cylindrical_extrude(ir|id=, or|od=, [size=], [convexity=], [spin=], [orient=]) 2D-CHILDREN;
253
253
// 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.
256
267
// Arguments:
257
268
// ir = The inner radius to extrude from.
258
269
// or = The outer radius to extrude to.
259
270
// ---
260
271
// od = The outer diameter to extrude to.
261
272
// 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]
263
274
// convexity = The max number of times a line could pass though a wall. Default: 10
264
275
// spin = Amount in degrees to spin around cylindrical axis. Default: 0
265
276
// 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`
267
278
// cylindrical_extrude(or=50, ir=45)
268
279
// text(text="Hello World!", size=10, halign="center", valign="center");
269
280
// Example: Spin Around the Cylindrical Axis
@@ -272,29 +283,33 @@ module path_extrude(path, convexity=10, clipsize=100) {
272
283
// Example: Orient to the Y Axis.
273
284
// cylindrical_extrude(or=40, ir=35, orient=BACK)
274
285
// 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) {
276
290
req_children($ children);
277
- check1 = assert(is_num(size) || is_vector(size,2 ));
278
- size = is_num(size)? [size,size] : size;
279
291
ir = get_radius(r= ir,d= id);
280
292
or = get_radius(r= or,d= od);
281
293
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" );
286
299
sides = segs(or);
287
300
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
289
303
attachable() {
290
304
rot(from= UP, to= orient) rot(spin) {
291
- for (i= [0 :1 :steps- 2 ]) {
305
+ for (i= [0 :1 :steps- 1 ]) {
292
306
x = (i+ 0.5 - steps/2 ) * step;
293
307
zrot(360 * x / circumf) {
294
308
fwd(or* cos (180 /sides)) {
295
309
xrot(- 90 ) {
296
310
linear_extrude(height= or- ir, scale = [ir/or,1 ], center= false , convexity= convexity) {
297
311
yflip()
312
+ xscale(scalefactor)
298
313
intersection () {
299
314
left(x) children();
300
315
rect([quantup(step,pow (2 ,- 15 )),size.y]);
0 commit comments