
12

I need advice on how to model an hyperbola (i.e., z=xy). There's no primitive like sphere() or cylinder() so I'm wondering what would be the best way to do it.
In case it matters, my goal is to intersect it with a sphere to cut the sphere in half.


This depends somewhat on what kind of resolution you need.
You can stitch together a polyhedron from scratch. Or you use the easy to understand, but slow chainhull method. Here is an example for a one dimensional case: z=x*x. Generalize it to two dimensions and your good to go. Just limit the $fn of the spheres to small numbers. for (i=[10:101]){ hull(){ s(i); s(i+1); t(i); t(i+1); } } module s(i){ translate([i,0,0.1*i*i])sphere(r=1,$ fn=8); }module t(i){ translate([i,0,0])sphere(r=1,$ fn=8); }
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


try something like this:
$fn=100;
difference()
{
sphere(.99);
rotate_extrude()
polygon(points = concat([[0,1]], hyperbola(1, .02)));
}
function hyperbola(X, step) = [for(i=[0:step:X])[i, i*i]];
 Rudolf


It looks like this:  Here is the code I used to make it: xmin = 0; xmax = 1; ymin = 0; ymax = 1; step = 0.05;
xpoints = floor((xmax  xmin) / step) + 1; ypoints = floor((ymax  ymin) / step) + 1; function index(x,y) = x * ypoints + y + 1; function x(i) = xmin + i * step; function y(i) = ymin + i * step;
points = concat([[x(xpoints  1), y(ypoints  1), 0]], [for(i = [0 : xpoints  1]) for(j = [0 : ypoints  1]) [x(i), y(j), x(i) * y(j)]]);
function flatten(l) = [for(a = l) for (b = a) b];
base = [[0, 1, index(xpoints 1, 0)], [1, 0, index(0, ypoints 1)], [0, index(xpoints  1, ypoints  1), index(0, ypoints  1)], [0, index(xpoints  1, 0), index(xpoints  1, ypoints  1)], ];
faces = flatten([for(i = [0 : xpoints  2]) for(j = [0 : ypoints  2]) [[index(i,j), index(i, j + 1), index(i + 1, j + 1)], [index(i + 1, j + 1), index(i + 1, j ), index(i, j)]] ]); polyhedron(points, concat(base, faces));
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Exactly right, nophead: a rotated 2D hyperbola != a 3D hyperbola.
Thanks for the code! I need the actual saddle area and when I put in 1 for the minimum x and y values (instead of 0), it kind of "selfintersects" through the origin as it ties the faces to [1,1,0] and [1,1,1].
I suppose I could whack "points = concat([[x(xpoints  1), y(ypoints  1), 0]], ..." and change the 0 to like 5 or something but it worries me that I don't understand the code well enough to cover this case properly. Can you show me the correct way?


That is actually simpler as it can be closed by two triangles. xmin = 1; xmax = 1; ymin = 1; ymax = 1; step = 0.05;
xpoints = floor((xmax  xmin) / step) + 1; ypoints = floor((ymax  ymin) / step) + 1; function index(x,y) = x * ypoints + y; function x(i) = xmin + i * step; function y(i) = ymin + i * step;
points = [for(i = [0 : xpoints  1]) for(j = [0 : ypoints  1]) [x(i), y(j), x(i) * y(j)]];
function flatten(l) = [for(a = l) for (b = a) b];
base = [ [index(0, 0), index(xpoints 1, 0), index(0, ypoints 1)], [index(xpoints 1, ypoints 1), index(0, ypoints 1), index(xpoints 1, 0)], ];
faces = flatten([for(i = [0 : xpoints  2]) for(j = [0 : ypoints  2]) [[index(i,j), index(i, j + 1), index(i + 1, j + 1)], [index(i + 1, j + 1), index(i + 1, j ), index(i, j)]] ]); polyhedron(points, concat(base, faces));
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Or maybe this shape is more useful. xmin = 1; xmax = 1; ymin = 1; ymax = 1; step = 0.05; zmin = min(xmin *ymax, xmax * ymin);
xpoints = floor((xmax  xmin) / step) + 1; ypoints = floor((ymax  ymin) / step) + 1; function index(x,y) = x * ypoints + y + 2; function x(i) = xmin + i * step; function y(i) = ymin + i * step;
points = concat([[xmin, ymin, zmin]], [[xmax, ymax, zmin]], [for(i = [0 : xpoints  1]) for(j = [0 : ypoints  1]) [x(i), y(j), x(i) * y(j)]]);
function flatten(l) = [for(a = l) for (b = a) b];
base = [ [1, 0, index(xpoints 1, 0)], [0, 1, index(0, ypoints 1)], [0, index(0, 0), index(xpoints  1,0)], [0, index(0, ypoints 1), index(0, 0)], [1, index(xpoints  1, ypoints  1), index(0, ypoints 1)], [1, index(xpoints 1, 0), index(xpoints  1, ypoints  1)], ];
faces = flatten([for(i = [0 : xpoints  2]) for(j = [0 : ypoints  2]) [[index(i,j), index(i, j + 1), index(i + 1, j + 1)], [index(i + 1, j + 1), index(i + 1, j ), index(i, j)]] ]);
polyhedron(points, concat(base, faces));
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


That's exactly what I needed. Thank you!
Cutting a sphere with it throws an exception for some reason. This code:
difference() {
sphere(r=.5, $fn=20);
polyhedron(points, concat(base, faces));
}
generates this error:
ERROR: CGAL error in CGAL_Nef_polyhedron3(): CGAL ERROR: assertion violation! Expr: e>incident_sface() != SFace_const_handle() File: /data/OpenSCAD/librariesmingw32master/mxe/usr/i686w64mingw32.static/include/CGAL/Nef_S2/SM_const_decorator.h Line: 326
Suggestions?


Here is one that works:  xmin = 1; xmax = 1; ymin = 1; ymax = 1; step = 0.1; zmin = min(xmin *ymax, xmax * ymin);
xpoints = floor((xmax  xmin) / step) + 1; ypoints = floor((ymax  ymin) / step) + 1; function index(x,y) = x * ypoints + y + 2; function x(i) = xmin + i * step; function y(i) = ymin + i * step;
points = concat([[xmin, ymin, zmin]], [[xmax, ymax, zmin]], [for(i = [0 : xpoints  1]) for(j = [0 : ypoints  1]) [x(i), y(j), x(i) * y(j)]]);
function flatten(l) = [for(a = l) for (b = a) b];
base = [ [1, 0, index(xpoints 1, 0)], [0, 1, index(0, ypoints 1)], flatten([for(i = [0 : xpoints  2]) [0, index(i, 0), index(i + 1,0)]]), flatten([for(j = [0 : ypoints  2]) [0, index(0, j), index(0, j + 1)]]), flatten([for(i = [0 : xpoints  2]) [1, index(i + 1, ypoints  1), index(i, ypoints  1)]]), flatten([for(j = [0 : ypoints  2]) [1, index(xpoints  1, j), index(xpoints  1, j + 1)]]), ];
faces = flatten([for(i = [0 : xpoints  2]) for(j = [0 : ypoints  2]) [[index(i,j), index(i, j + 1), index(i + 1, j + 1)], [index(i + 1, j + 1), index(i + 1, j ), index(i, j)]] ]);
difference() { sphere(r=.5, $fn=20); polyhedron(points, concat(base, faces), convexity = 2); }
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


Actually it still doesn't work. I found one bug but I am stuck now. The error as gone away but it still doesn't render:
xmin = 1; xmax = 1; ymin = 1; ymax = 1; step = 0.1; zmin = min(xmin *ymax, xmax * ymin);
xpoints = floor((xmax  xmin) / step) + 1; ypoints = floor((ymax  ymin) / step) + 1; function index(x,y) = x * ypoints + y + 2; function x(i) = xmin + i * step; function y(i) = ymin + i * step;
points = concat([[xmin, ymin, zmin]], [[xmax, ymax, zmin]], [for(i = [0 : xpoints  1]) for(j = [0 : ypoints  1]) [x(i), y(j), x(i) * y(j)]]);
function flatten(l) = [for(a = l) for (b = a) b];
base = [ [1, 0, index(xpoints 1, 0)], [0, 1, index(0, ypoints 1)], flatten([for(i = [0 : xpoints  2]) [0, index(i, 0), index(i + 1, 0)]]), flatten([for(j = [0 : ypoints  2]) [0, index(0, j + 1), index(0, j)]]), flatten([for(i = [0 : xpoints  2]) [1, index(i + 1, ypoints  1), index(i, ypoints  1)]]), flatten([for(j = [0 : ypoints  2]) [1, index(xpoints  1, j), index(xpoints  1, j + 1)]]), ];
faces = flatten([for(i = [0 : xpoints  2]) for(j = [0 : ypoints  2]) [[index(i,j), index(i, j + 1), index(i + 1, j + 1)], [index(i + 1, j + 1), index(i + 1, j ), index(i, j)]] ]);
difference() { sphere(r=.5, $fn=20); polyhedron(points, concat(base, faces), convexity = 2); }
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


This stuff is way over my head but FWIW, this code:
intersection() {
polyhedron(points, concat(base, faces), convexity = 2);
sphere(r=.5, $fn=80);
}
generates a preview of a zerothickness contour (that looks like a potato chip). That is, the intersection() shows only where the *surface* of the polyhedron intersects with the volume of the sphere and excludes all the volume that the two objects share.
Maybe that is useful to know.


1. If I change for(i = [0 : xpoints  1])
to for(i = [0 : xpoints  0])
I see no visual change.
2. Also when I F6 the object I get a result but its not using the color scheme I've chosen.
I think this means there is something wrong with the model.
3. If I reverse the difference:
difference() {
polyhedron(points, concat(base, faces), convexity = 2);
sphere(r=.5, $fn=45);
}
I get a CGAL error  coincident face.
ERROR: CGAL error in CGAL_Nef_polyhedron3(): CGAL ERROR: assertion violation! Expr: e>incident_sface() != SFace_const_handle() File: /data/OpenSCAD/librariesmingw64master/mxew64/usr/x86_64w64mingw32.static/include/CGAL/Nef_S2/SM_const_decorator.h Line: 326
Looks like one of the indices is off in base=... ??maybe??
still looking

12
