

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.
_______________________________________________
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


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


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


@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

Administrator

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!

