My goal: a hemisphere coated with kindaevenlyspaced bumps, for a robot
wheel's treads. I get that this is hard because spacefilling spheres on the skin of a sphere is hard. Is there an easy approximate way to do it that I'm missing, something like make a bunch of spheres around the equator move up in latitude a bit shrink the spherering offset the start (rotation) by .5 spheres reduce the number of spheres so they still fit (might get messy at the end of each rotation) continue until you get something reasonable. I tried it with random rotations, and meh... it was ok. The overclustering was annoying, but that is what I get for doing it the lazy way with random rotations. num_spheres = 800; random_vect=rands(0,360,num_spheres*3,43); for(v=[0:num_spheres1]) rotate([random_vect[v],random_vect[v*2],random_vect[v*3]]) translate([0,50,0]) sphere(5, center=true); <http://forum.openscad.org/file/t1597/Screen_Shot_20180524_at_9.png>  Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
I wrote part of my Master's thesis on this problem ;). What you want to do is start with the vertices of a platonic solid mapped up to the sphere, then subdivide each face to get more spheres as needed. The subdivision is easiest if you use a solid with triangular faces. An icosahedron would be best but if you are lazy you can use an octahedron (which is easy since the vertices are just {(1,0,0), (1,0,0), (0,1,0), (0,1,0), (0,0,1), (0,0,1)} To subdivide a triangle just find the midpoint of each edge, then triangulate them to get four subtriangles. When you do this on a polyhedron, divide the resulting vector from the origin of the sphere to get a length1 vector lying on the surface of the sphere. Once you have enough vertices replace them with spheres of a suitable size and subtract them from a base sphere. It's easy to do this kind of thing recursively if you don't mind duplicate spheres, harder if you try to avoid them. But if you are lazy just live with the duplicates; differencing will be a little slower but it *should* still work. Note that subdivisions will not result in a perfectly even distribution but that's impossible anyway. Starting from an icosahedron will give you a more uniform distribution but try the octahedron first. On Fri, May 25, 2018 at 1:23 PM, benjaminhill <[hidden email]> wrote: My goal: a hemisphere coated with kindaevenlyspaced bumps, for a robot _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
This post was updated on .
Here some (tricky) code that demonstrates subdivision starting from a regular
octahedron. Although the code is very lazy and therefore quite slow, the result is printable. It recursively loops over a dirty polyhedron() call (sorry for this, Carsten) and employes hull() to avoid all the nasty work usually connected with subdivison. s = 100; p = [[s, 0, 0], [0, s, 0],[s, 0, 0], [0, s, 0], [0, 0, s], [0, 0, s]]; d = [ // octahedron [p[0], p[1], p[4]], [p[1], p[2], p[4]], [p[2], p[3], p[4]], [p[3], p[0], p[4]], [p[0], p[1], p[5]], [p[1], p[2], p[5]], [p[2], p[3], p[5]], [p[3], p[0], p[5]], ]; for(k=[0:4]) translate([k*s*2.01, 0, 0]) hull() for(i=d) subdivide(i, n=k); // n<5 module subdivide(d, n=2) if(n==0) polyhedron(d, [[0,1,2]]); else for(l=div(d)) subdivide(l, n1); function div(d) = let(r = norm(d[0])) let(b = [for(i=[0:2]) half(d[i], d[(i+1)%3], r)]) [[d[0], b[0], d[1]], [d[1], b[1], d[2]], [d[2], b[2], d[0]], b]; function half(a, b, r) = let (x = a+0.5*(ba)) x/norm(x)*r;  Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list Discuss@lists.openscad.org http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by benjaminhill
After reading the original post, I felt that geodesic spheres might be useful
in this situation. The foundation for a geodesic sphere is an icosahedron, which of course, has all vertices on the surface of a sphere. A geodesic progression splits each edge and moves the split point to the sphere's surface, then joins them with additional edges. A 1v is an icosahedron, while a 2v breaks each edge into two sections. The progression is linear and complex at the higher frequency figures. I did a quick search for geodesic sphere coordinates and was surprised at the number of technical documents returned. The math is well beyond my comprehension, but I suspect one could take the formulae that generates the coordinates and use those numbers as translate parameters for the bumps. You'd get as regular a construction as space allowed, especially by allowing for parametric entry of major sphere diameter and minor sphere diameters, as well as frequency. I've assembled a paper 3v geodesic sphere and it's a work of art. Having a 3D model that allows me to place spheres at each vertex would be an interesting bit of code.  Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by Parkinbot
I wrote some (probably lessthanoptimal) subdivision sphere code a while ago
that constructs a list of vertices and faces and calls polyhedron to generate the sphere. It is quite similar to what others have described in this thread: ssphere(r=1.0, n=1); function norm(v) = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); function normalize(v) = [v[0]/norm(v), v[1]/norm(v), v[2]/norm(v)]; function flatten(vec) = [for (v=vec) for(e=v) e]; module ssphere(r=1, n=0) { C0 = (1+sqrt(5))/4; pts = [[0.5, 0, C0], [0.5, 0, C0], [0.5, 0, C0], [0.5, 0, C0], [C0, 0.5, 0], [C0, 0.5, 0], [C0, 0.5, 0], [C0, 0.5, 0], [0, C0, 0.5], [0, C0, 0.5], [0, C0, 0.5], [0, C0, 0.5]]; fcs = [[10, 2, 0], [5, 10, 0], [4, 5, 0], [8, 4, 0], [2, 8, 0], [11, 1, 3], [7, 11, 3], [6, 7, 3], [9, 6, 3], [1, 9, 3], [7, 6, 2], [10, 7, 2], [11, 7, 10], [5, 11, 10], [1, 11, 5], [4, 1, 5], [9, 1, 4], [8, 9, 4], [6, 9, 8], [2, 6, 8]]; npts = [for (v=pts) normalize(v)]; subdiv_sphere(npts, fcs, r, n); } module subdiv_sphere(pts, fcs, r, n) { if (n>0) { spts = concat(pts, flatten([for (f=fcs) [(pts[f[0]]+pts[f[1]]), (pts[f[1]]+pts[f[2]]), (pts[f[2]]+pts[f[0]])]])); nsfcs = flatten([for (i=[0:len(fcs)1]) [[fcs[i][0], len(pts)+3*i+0, len(pts)+3*i+2], [len(pts)+3*i+0, len(pts)+3*i+1, len(pts)+3*i+2], [len(pts)+3*i+0, fcs[i][1], len(pts)+3*i+1], [len(pts)+3*i+2, len(pts)+3*i+1, fcs[i][2]]]]); nspts = [for (v=spts) r*normalize(v)]; subdiv_sphere(nspts, nsfcs, r, n1); } else polyhedron(points=pts, faces=fcs); } You could just (ab)use the list of points to place smaller spheres to be subtracted from the main sphere in order to generate dimples. The subdivided distribution of points probably looks closer to what a real golf ball's dimple distribution looks like... MKB  Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Well done. Your code is nice, fast, and operational!
 Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
In reply to this post by berkenb
@berkenb,
Excellent code. Immediately stop my attempt to come up with a sphere myself. I modified it to a single function that returns [pts, fcs]: function spherePF(r=1,n=1,_pts=[],_fcs=[])= ( // Modified from berkenb's excellent ssphere: // http://forum.openscad.org/Coatingaspherewithbumpsgolfballishforwheeltreadstp24090p24094.html // return [pt, faces] _pts==[]? let( C0 = (1+sqrt(5))/4 , pts = [ [0.5,0,C0],[0.5,0,C0],[0.5,0,C0],[0.5,0,C0] , [C0,0.5,0],[C0,0.5,0],[C0,0.5,0],[C0,0.5,0] , [0,C0,0.5],[0,C0,0.5],[0,C0,0.5],[0,C0,0.5]] , fcs = [ [10,2,0],[5,10,0],[4,5,0],[8,4,0],[2,8,0] , [11,1,3],[7,11,3],[6,7,3],[9,6,3],[1,9,3] , [7,6,2],[10,7,2],[11,7,10],[5,11,10],[1,11,5] , [4,1,5],[9,1,4],[8,9,4],[6,9,8],[2,6,8]] , npts = [for (v=pts) v/norm(v) ] ) ( n==0?[npts, fcs] : spherePF(r=r,n=n1,_pts=npts,_fcs=fcs) ) : let( spts = concat(_pts , [ each for (f=_fcs) [(_pts[f[0]]+_pts[f[1]]) ,(_pts[f[1]]+_pts[f[2]]) ,(_pts[f[2]]+_pts[f[0]]) ] ] ) , nsfcs = [each for (i=[0:len(_fcs)1]) [ [_fcs[i][0], len(_pts)+3*i+0, len(_pts)+3*i+2] , [len(_pts)+3*i+0, len(_pts)+3*i+1, len(_pts)+3*i+2] , [len(_pts)+3*i+0, _fcs[i][1], len(_pts)+3*i+1] , [len(_pts)+3*i+2, len(_pts)+3*i+1, _fcs[i][2]] ] ] , nspts = [for (v=spts) r*v/norm(v)] ) n==0? [nspts, nsfcs] : spherePF(r=r,n=n1,_pts=nspts,_fcs=nsfcs) ); berkenb wrote > module ssphere(r=1, n=0) { > ...  $ Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText ( OpenSCAD lexer ); $ Tips ; $ Snippets  Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets 
<http://forum.openscad.org/file/t1597/Screen_Shot_20180530_at_7.png>
You all are amazing. Here is right before my print to flexible TPU for the "cap a motor tilted at 45°" wheel.  Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Administrator

In reply to this post by benjaminhill
benjaminhill wrote
> My goal: a hemisphere coated with kindaevenlyspaced bumps, for a robot > wheel's treads. So was the hemisphere a stylish choice, or is it expected to dig deep so the bumps closer to the axle actual get grip?  Admin  PM me if you need anything, or if I've done something stupid... Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above. The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!  Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Admin  email* me if you need anything,
or if I've done something stupid... * click on my MichaelAtOz label, there is a link to email me. Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above. The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out! 
MichaelAtOz wrote
> So was the hemisphere a stylish choice, or is it expected to dig deep so > the bumps closer to the axle actual get grip? I was thinking of mounting the motors at a 45 degree angle, but I wasn't sure that 45 degrees would work and I wanted some flexibility, and I was kinda hoping that in rougher terrain the rest of the wheel would dig deep as it spun. Like a hybrid bike tire. Maybe. If I'm lucky. Like a HOG wheel <https://en.wikipedia.org/wiki/Hemispherical_omnidirectional_gimbaled_wheel> , but without the motorized tilt.  Sent from: http://forum.openscad.org/ _______________________________________________ OpenSCAD mailing list [hidden email] http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org 
Free forum by Nabble  Edit this page 