discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Re: [OpenSCAD] screw (thread) around a cone

R
Ronaldo
Tue, Mar 21, 2017 8:22 PM

oda wrote

(i'd like do make a screw cone)
How can I do that?

There are many different solutions to get that model. I usually prefer to
use polyhedron primitive by computing the surfaces points and facets which
renders quite faster. The hard point of that way is, besides to compute the
points, you will have to generate the facet combinatoric. To facilitate that
generation task it is recommended to use some robust library like the
Parkinbot's  sweep.scad http://www.thingiverse.com/thing:1208001  . My
example here is autonomous and include 2 functions and a module to build the
polyhedron instead of sweep.scad.

r = 100; // cone base radius
h = 250; // cone height
n = 20;  // # spiral points per turn
k = 8;  // # removed thread apex points
tw = 5;  // # screw twists

// screw teeth 2D profile
shape = 20*[[0,1],[0,-1],[0.7,-0.5],[0.7,0.5]];
// cone
cylinder(r1=r+0.001,r2=0.001,h=h,$fn=n);
// screw
build_screw(shape,r,h,tw,n);

module build_screw(shape,r,h,tw,n) {
scrw = screw(shape,r,h,tw,tw*n);
msh  = mesh2polyhedron(scrw);
fac1 = polygon2polyhedron(scrw[0],true);
fac2 = polygon2polyhedron(scrw[len(scrw)-1]);
make_polyhedron([msh,fac1,fac2], convexity = 10);
}

// screw surface mesh
function screw(shp,r,h,tw,n) =
[for(i=[0:n-k]) let(ang=360i/n)
[for(j=[0:len(shp)])
let(p = [shp[j%len(shp)][0],0,shp[j%len(shp)][1]])
tr(p,ang,r,h,tw)] ];
// map 3D point p to cone spiral at angle 0<= ang <=360
function tr(p,ang,r,h,tw) =
let( a=tw
ang, b=atan2(r,h) )
rotZ(twang)rotY(b)p +
[ r
(1-ang/360)cos(twang),
r
(1-ang/360)sin(twang),
h
ang/360 ] ;

function rotZ(a) =
[[ cos(a), -sin(a), 0],
[ sin(a),  cos(a), 0],
[ 0,      0,      1] ];
function rotY(a) =
[[ cos(a), 0, -sin(a)],
[ 0,      1, 0      ],
[ sin(a), 0, cos(a) ] ];

// unify all polyhedron data of list polys
// in one polyhedron call
// polys[i] has the format [points, faces]
module make_polyhedron(polys, convexity = 10) {
vertlist = [for(p=polys, pt=p[0]) pt]; // collect all verts from
polyhedra
vertlen  = [for(p=polys) p[0] ];
acclen  = acc_len(vertlen);
facets  = [ for(i=[0:len(polys)-1], f=polys[i][1] ) [ for(v=f)
acclen[i]+v ] ];

 polyhedron(
     points = vertlist,
     faces  = facets,
     convexity = convexity
 );
 function _accum_sum(l, offs=0, res=[]) =
     len(res) == len(l) ?
         res :
         _accum_sum(l, offs+l[len(res)], concat(res, [ offs+l[len(res)]

] ));

 function acc_len( f ) =
     concat([0], _accum_sum([ for(fi=f) len(fi) ]));

}

// generates polyhedron data for a mesh,
// a rectangular matrix of 3D points
function mesh2polyhedron(mesh, rev =false) =
let( n = len(mesh) != 0 ? len(mesh) : 0,
m = n==0 ? 0 : len(mesh[0]) != 0 ? len(mesh[0]) : 0 ,
l = nm)
l > 0 ?
let( range    = rev  ? [len(mesh)-1: -1: 0] : [0:len(mesh)-1],
vertices = l == 0 ? [] : [ for(i=range) for(pt=mesh[i]) pt ],
tris = concat(  [ for(i=[0:n-2],j=[0:m-2]) [ i
m+j, i*m+j+1,
(i+1)m+j ] ] ,
[ for(i=[0:n-2],j=[0:m-2]) [ i
m+j+1,
(i+1)*m+j+1, (i+1)*m+j ] ] ) )
[ vertices, tris ]:
[] ;

// generates polyhedron data for a closed polygonal face
function polygon2polyhedron(polygon, rev =false) =
let( vertices  = polygon,
range    = rev  ? [len(polygon)-1: -1: 0] : [0:len(polygon)-1],
facets    = [[for(i=range) i ]] )
[ vertices, facets ];

http://forum.openscad.org/file/n20986/coneScrew.png

The math of the spiral along a cone is in function tr(). The function
screw() generates a mesh of points for the screw surface based on a given
thread profile. The module build_screw() produces the polyhedron by calling
the last 3 auxiliary functions and module. The cone itself is generated by a
simple cylinder.

The profile of the screw thread is defined by the variable shape, a list of
2D points ( [x,y] ). In this example, the profile is a parallelogram but
many other simple polygons may be used here. To lay the profile upon the
cone surface it must have a vertical edge x=0 and all points should have
y>=0.

--
View this message in context: http://forum.openscad.org/screw-thread-around-a-cone-tp20965p20986.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

oda wrote > (i'd like do make a screw cone) > How can I do that? There are many different solutions to get that model. I usually prefer to use polyhedron primitive by computing the surfaces points and facets which renders quite faster. The hard point of that way is, besides to compute the points, you will have to generate the facet combinatoric. To facilitate that generation task it is recommended to use some robust library like the Parkinbot's sweep.scad <http://www.thingiverse.com/thing:1208001> . My example here is autonomous and include 2 functions and a module to build the polyhedron instead of sweep.scad. > r = 100; // cone base radius > h = 250; // cone height > n = 20; // # spiral points per turn > k = 8; // # removed thread apex points > tw = 5; // # screw twists > > // screw teeth 2D profile > shape = 20*[[0,1],[0,-1],[0.7,-0.5],[0.7,0.5]]; > // cone > cylinder(r1=r+0.001,r2=0.001,h=h,$fn=n); > // screw > build_screw(shape,r,h,tw,n); > > module build_screw(shape,r,h,tw,n) { > scrw = screw(shape,r,h,tw,tw*n); > msh = mesh2polyhedron(scrw); > fac1 = polygon2polyhedron(scrw[0],true); > fac2 = polygon2polyhedron(scrw[len(scrw)-1]); > make_polyhedron([msh,fac1,fac2], convexity = 10); > } > > // screw surface mesh > function screw(shp,r,h,tw,n) = > [for(i=[0:n-k]) let(ang=360*i/n) > [for(j=[0:len(shp)]) > let(p = [shp[j%len(shp)][0],0,shp[j%len(shp)][1]]) > tr(p,ang,r,h,tw)] ]; > // map 3D point p to cone spiral at angle 0<= ang <=360 > function tr(p,ang,r,h,tw) = > let( a=tw*ang, b=atan2(r,h) ) > rotZ(tw*ang)*rotY(b)*p + > [ r*(1-ang/360)*cos(tw*ang), > r*(1-ang/360)*sin(tw*ang), > h*ang/360 ] ; > > function rotZ(a) = > [[ cos(a), -sin(a), 0], > [ sin(a), cos(a), 0], > [ 0, 0, 1] ]; > function rotY(a) = > [[ cos(a), 0, -sin(a)], > [ 0, 1, 0 ], > [ sin(a), 0, cos(a) ] ]; > > // unify all polyhedron data of list polys > // in one polyhedron call > // polys[i] has the format [points, faces] > module make_polyhedron(polys, convexity = 10) { > vertlist = [for(p=polys, pt=p[0]) pt]; // collect all verts from > polyhedra > vertlen = [for(p=polys) p[0] ]; > acclen = acc_len(vertlen); > facets = [ for(i=[0:len(polys)-1], f=polys[i][1] ) [ for(v=f) > acclen[i]+v ] ]; > > polyhedron( > points = vertlist, > faces = facets, > convexity = convexity > ); > function _accum_sum(l, offs=0, res=[]) = > len(res) == len(l) ? > res : > _accum_sum(l, offs+l[len(res)], concat(res, [ offs+l[len(res)] > ] )); > > function acc_len( f ) = > concat([0], _accum_sum([ for(fi=f) len(fi) ])); > } > > // generates polyhedron data for a mesh, > // a rectangular matrix of 3D points > function mesh2polyhedron(mesh, rev =false) = > let( n = len(mesh) != 0 ? len(mesh) : 0, > m = n==0 ? 0 : len(mesh[0]) != 0 ? len(mesh[0]) : 0 , > l = n*m) > l > 0 ? > let( range = rev ? [len(mesh)-1: -1: 0] : [0:len(mesh)-1], > vertices = l == 0 ? [] : [ for(i=range) for(pt=mesh[i]) pt ], > tris = concat( [ for(i=[0:n-2],j=[0:m-2]) [ i*m+j, i*m+j+1, > (i+1)*m+j ] ] , > [ for(i=[0:n-2],j=[0:m-2]) [ i*m+j+1, > (i+1)*m+j+1, (i+1)*m+j ] ] ) ) > [ vertices, tris ]: > [] ; > > // generates polyhedron data for a closed polygonal face > function polygon2polyhedron(polygon, rev =false) = > let( vertices = polygon, > range = rev ? [len(polygon)-1: -1: 0] : [0:len(polygon)-1], > facets = [[for(i=range) i ]] ) > [ vertices, facets ]; <http://forum.openscad.org/file/n20986/coneScrew.png> The math of the spiral along a cone is in function tr(). The function screw() generates a mesh of points for the screw surface based on a given thread profile. The module build_screw() produces the polyhedron by calling the last 3 auxiliary functions and module. The cone itself is generated by a simple cylinder. The profile of the screw thread is defined by the variable shape, a list of 2D points ( [x,y] ). In this example, the profile is a parallelogram but many other simple polygons may be used here. To lay the profile upon the cone surface it must have a vertical edge x=0 and all points should have y>=0. -- View this message in context: http://forum.openscad.org/screw-thread-around-a-cone-tp20965p20986.html Sent from the OpenSCAD mailing list archive at Nabble.com.
O
oda
Wed, Mar 22, 2017 9:59 AM

I find it wonderful that code and mathematics can create complex models, but
I find it more wonderful still find people on the other side of the world to
spend their time to help other people: thank you for your help.
I will study your code as soon as possible.
Oda

--
View this message in context: http://forum.openscad.org/screw-thread-around-a-cone-tp20965p20989.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

I find it wonderful that code and mathematics can create complex models, but I find it more wonderful still find people on the other side of the world to spend their time to help other people: thank you for your help. I will study your code as soon as possible. Oda -- View this message in context: http://forum.openscad.org/screw-thread-around-a-cone-tp20965p20989.html Sent from the OpenSCAD mailing list archive at Nabble.com.
O
oda
Fri, May 5, 2017 12:22 PM

Hi,
I'm still studying ... waiting to understand your code (but I've almost
succeeded).
In the meantime, I have found a much less beautiful but more comprehensible
way and more of the neophytes' reach to do my cone. I post it just for the
beginning person in our community:

linear_extrude(height=60,twist=825, scale=0)
square(50,center=true);

Obviously, it is only a didactic example!

Thank you again for your help!
Oda

--
View this message in context: http://forum.openscad.org/screw-thread-around-a-cone-tp20965p21409.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Hi, I'm still studying ... waiting to understand your code (but I've almost succeeded). In the meantime, I have found a much less beautiful but more comprehensible way and more of the neophytes' reach to do my cone. I post it just for the beginning person in our community: linear_extrude(height=60,twist=825, scale=0) square(50,center=true); Obviously, it is only a didactic example! Thank you again for your help! Oda -- View this message in context: http://forum.openscad.org/screw-thread-around-a-cone-tp20965p21409.html Sent from the OpenSCAD mailing list archive at Nabble.com.
RP
Ronaldo Persiano
Fri, May 5, 2017 1:10 PM

As I said, there are many solutions to your problem. Direct application of
linear_extrude is the worst of them except in very specific cases (for
example:
http://forum.openscad.org/linear-extrude-thickness-td21345.html#a21346).
The solutions with polyhedron are fast (although not so fast as with
linear_extrude) and may be general but it is more technical. If you are not
acquainted with polyhedron, you may use a library that encloses its use
like sweep.scad. And if your thread profile is convex (as usually they are)
you can apply a non-polyhedron slower approach like
http://forum.openscad.org/Mirror-rotations-and-sweep-td21256.html
. Anyway the computation of the thread path is inevitable in the sweep
approach.

2017-05-05 9:22 GMT-03:00 oda odaepo@gmail.com:

Hi,
I'm still studying ... waiting to understand your code (but I've almost
succeeded).
In the meantime, I have found a much less beautiful but more comprehensible
way and more of the neophytes' reach to do my cone. I post it just for the
beginning person in our community:

linear_extrude(height=60,twist=825, scale=0)
square(50,center=true);

Obviously, it is only a didactic example!

Thank you again for your help!
Oda

--
View this message in context: http://forum.openscad.org/
screw-thread-around-a-cone-tp20965p21409.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

As I said, there are many solutions to your problem. Direct application of linear_extrude is the worst of them except in very specific cases (for example: http://forum.openscad.org/linear-extrude-thickness-td21345.html#a21346). The solutions with polyhedron are fast (although not so fast as with linear_extrude) and may be general but it is more technical. If you are not acquainted with polyhedron, you may use a library that encloses its use like sweep.scad. And if your thread profile is convex (as usually they are) you can apply a non-polyhedron slower approach like http://forum.openscad.org/Mirror-rotations-and-sweep-td21256.html . Anyway the computation of the thread path is inevitable in the sweep approach. 2017-05-05 9:22 GMT-03:00 oda <odaepo@gmail.com>: > Hi, > I'm still studying ... waiting to understand your code (but I've almost > succeeded). > In the meantime, I have found a much less beautiful but more comprehensible > way and more of the neophytes' reach to do my cone. I post it just for the > beginning person in our community: > > > linear_extrude(height=60,twist=825, scale=0) > square(50,center=true); > > > Obviously, it is only a didactic example! > > Thank you again for your help! > Oda > > > > > > -- > View this message in context: http://forum.openscad.org/ > screw-thread-around-a-cone-tp20965p21409.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >