function main() {

const r = 10;

const fn = 32;

const h = 10;

numSegments = (h+1)*fn;

const points = seq(numSegments+1).flatMap( i => threadTriangle(r,360/fn*i,i/fn-1) );

const closeFirst = [0,1,2];

const segments = seq(numSegments).flatMap( i => {

const m = i*3;

return [

[0,3,4,1].map(x => x+m),

[1,4,5,2].map(x => x+m),

[2,5,3,0].map(x => x+m)

];

})

const closeLast = [

points.length-1,

points.length-2,

points.length-3,

];

const threadPoly = polyhedron({

points,

polygons: [ closeFirst, ...segments, closeLast ]

});

const threadPolyTrimmed = intersection(

threadPoly,

cylinder({r:r+0.5,h,fn})

);

return union(

threadPolyTrimmed,

cylinder({r:r,h,fn})

);

}

function threadTriangle(r,a,z) {

const rad = a * Math.PI/180;

const x1 = r * Math.cos(rad);

const y1 = r * Math.sin(rad);

const x2 = (r+0.475) * Math.cos(rad);

const y2 = (r+0.475) * Math.sin(rad);

return [[x1,y1,z],[x1,y1,0.95+z],[x2,y2,0.5+z]];

}

function seq(length) {

return Array.apply(null, {length}).map(Function.call, Number);

}

function main() {

const r = 10;

const fn = 32;

const h = 10;

numSegments = (h+1)*fn;

const points = seq(numSegments+1).flatMap( i => threadTriangle(r,360/fn*i,i/fn-1) );

const closeFirst = [0,1,2];

const segments = seq(numSegments).flatMap( i => {

const m = i*3;

return [

[0,3,4,1].map(x => x+m),

[1,4,5,2].map(x => x+m),

[2,5,3,0].map(x => x+m)

];

})

const closeLast = [

points.length-1,

points.length-2,

points.length-3,

];

const threadPoly = polyhedron({

points,

polygons: [ closeFirst, ...segments, closeLast ]

});

const threadPolyTrimmed = intersection(

threadPoly,

cylinder({r:r+0.5,h,fn})

);

return union(

threadPolyTrimmed,

cylinder({r:r,h,fn})

);

}

function threadTriangle(r,a,z) {

const rad = a * Math.PI/180;

const x1 = r * Math.cos(rad);

const y1 = r * Math.sin(rad);

const x2 = (r+0.475) * Math.cos(rad);

const y2 = (r+0.475) * Math.sin(rad);

return [[x1,y1,z],[x1,y1,0.95+z],[x2,y2,0.5+z]];

}

function seq(length) {

return Array.apply(null, {length}).map(Function.call, Number);

}

]]>