Skip to content

Commit bc110a2

Browse files
correct version number in test
extend spheroid() to take vector radius to make ellipsoids
1 parent be38143 commit bc110a2

2 files changed

Lines changed: 26 additions & 10 deletions

File tree

shapes3d.scad

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3347,7 +3347,10 @@ function sphere(r, d, anchor=CENTER, spin=0, orient=UP) =
33473347
// vnf = spheroid(r|d, [circum], [style]);
33483348
// Description:
33493349
// Creates a spheroid object, with support for anchoring and attachments.
3350-
// This is a drop-in replacement for the built-in `sphere()` module.
3350+
// This is a drop-in replacement for the built-in `sphere()` module. The `r` or `d` value can
3351+
// be a 3-vector to produce an ellipsoid. This differs from scaling the ellipsoid manually because
3352+
// it doesn't rescale children that you attach to the ellipsoid.
3353+
// .
33513354
// When called as a function, returns a [VNF](vnf.scad) for a spheroid.
33523355
// The exact triangulation of this spheroid can be controlled via the `style=`
33533356
// argument, where the value can be one of `"orig"`, `"aligned"`, `"stagger"`,
@@ -3379,10 +3382,10 @@ function sphere(r, d, anchor=CENTER, spin=0, orient=UP) =
33793382
// The "octa" style has the property that it blends neatly with a cylinder of the same $fn along any of the coordinate axes.
33803383
// This is true for both the regular and circumscribed "octa" spheroid.
33813384
// Arguments:
3382-
// r = Radius of the spheroid.
3385+
// r = Radius of the spheroid or 3-vector giving the 3 semiaxes.
33833386
// style = The style of the spheroid's construction. One of "orig", "aligned", "stagger", "octa", or "icosa". Default: "aligned"
33843387
// ---
3385-
// d = Diameter of the spheroid.
3388+
// d = Diameter of the spheroid or 3-vector giving three axes lengths.
33863389
// circum = If true, the approximate sphere circumscribes the true sphere of the requested size. Otherwise inscribes. Note that for some styles, the circumscribed sphere looks different than the inscribed sphere. Default: false (inscribes)
33873390
// anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER`
33883391
// spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0`
@@ -3415,6 +3418,8 @@ function sphere(r, d, anchor=CENTER, spin=0, orient=UP) =
34153418
// $fn=16;
34163419
// color("lightblue")spheroid(r=10, style="octa", circum=true);
34173420
// xcyl(r=10.01, h=15, anchor=RIGHT, circum=true);
3421+
// Example: Ellipsoid
3422+
// spheroid(r=[100,50,35]);
34183423
// Example: Anchoring
34193424
// spheroid(d=100, anchor=FRONT);
34203425
// Example: Spin
@@ -3445,10 +3450,11 @@ function sphere(r, d, anchor=CENTER, spin=0, orient=UP) =
34453450
module spheroid(r, style="aligned", d, circum=false, dual=false, anchor=CENTER, spin=0, orient=UP)
34463451
{
34473452
r = get_radius(r=r, d=d, dflt=1);
3448-
sides = segs(r);
3449-
vsides = ceil(sides/2);
3453+
assert((is_finite(r) && r>=0) || (is_vector(r,3) && all_positive(r)),"\nr/d must be a nonnegative value or a positive 3-vector");
34503454
attachable(anchor,spin,orient, r=r) {
34513455
if (style=="orig" && !circum) {
3456+
sides = segs(min(r));
3457+
vsides = ceil(sides/2);
34523458
merids = [ for (i=[0:1:vsides-1]) 90-(i+0.5)*180/vsides ];
34533459
path = [
34543460
let(a = merids[0]) [0, sin(a)],
@@ -3460,9 +3466,11 @@ module spheroid(r, style="aligned", d, circum=false, dual=false, anchor=CENTER,
34603466
// Don't now how to construct faces for these efficiently, so use hull_points, which
34613467
// is much faster than using hull() as happens in the spheroid() function
34623468
else if (circum && (style=="octa" || style=="icosa")) {
3463-
orig_sphere = spheroid(r,style,circum=false);
3469+
minr = min(r);
3470+
scale = r/minr;
3471+
orig_sphere = spheroid(minr,style,circum=false);
34643472
dualvert = _dual_vertices(orig_sphere);
3465-
hull_points(dualvert,fast=true);
3473+
hull_points(scale(scale,dualvert),fast=true);
34663474
} else {
34673475
vnf = spheroid(r=r, circum=circum, style=style);
34683476
vnf_polyhedron(vnf, convexity=2);
@@ -3651,8 +3659,16 @@ let(
36513659
function spheroid(r, style="aligned", d, circum=false, anchor=CENTER, spin=0, orient=UP) =
36523660
assert(in_list(style, ["orig", "aligned", "stagger", "octa", "icosa"]))
36533661
let(
3654-
r = get_radius(r=r, d=d, dflt=1),
3655-
hsides = segs(r),
3662+
r = get_radius(r=r, d=d, dflt=1)
3663+
)
3664+
is_vector(r,3) ? let(
3665+
minr = min(r),
3666+
scale = r/minr
3667+
)
3668+
scale(scale,spheroid(minr, style=style, circum=circum, anchor=anchor,
3669+
spin=spin, orient=orient))
3670+
: let(
3671+
hsides = segs(min(r)),
36563672
vsides = max(2,ceil(hsides/2)),
36573673
icosa_steps = round(max(5,hsides)/5),
36583674
stagger = style=="stagger"

threading.scad

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2099,7 +2099,7 @@ module generic_threaded_rod(
20992099

21002100
module __rot_if_old()
21012101
{
2102-
if (version_num()>=20250314) children();
2102+
if (version_num()>=20250106) children();
21032103
else zrot(180) children();
21042104
}
21052105

0 commit comments

Comments
 (0)