Die Datei sterne.scad:
(Sie benutzt polyline2d aus der Library dotSCAD und mirror_copy aus der Library BOSL2.)
// $Author: bernhard $
// $Id: sterne.scad 1024 2026-01-01 13:28:38Z bernhard $
// $Date: 2026-01-01 14:28:38 +0100 (Do, 01. Jan 2026) $
/*
CC0 BY (Public Domain)
2025 by bernhard (3d.bit-field.de) is licensed under the Creative Commons - Attribution license.
*/
////////////////////////////////////////////////////
use <line2d.scad>
include <polyline2d.scad>
include <BOSL2/std.scad>
$fn = $preview ? 12 : 48;
eps = 0.1;
shrink = 1.075;
p1 = [[0,0], [8,4], [12, 2], [20,10], [38,0]];
off1 = 0.0;
w1 = 1.2;
p2 = [[0,0], [24, 10], [48,0], [0,0]];
off2 = 0.2;
w2 = 2;
p = p2;
w = w2;
off = off2;
/*
p = p1;
w = w1;
off = off1;
*/
module stern()
{
for(i=[0:45:360-45])
rotate([0, 0, i])
mirror_copy([0, 1, 0])
linear_extrude(1.5)
offset(off)
polyline2d(points=p, width=w, endingStyle="CAP_ROUND");
}
//minkowski()
{
difference()
{
color("red") stern();
if ( p == p2 ) {
translate([0, 0, -eps]) cylinder(d = 6. * shrink + 0.1 , h =2);
}
}
sphere(0.05);
}
Die Datei xmas_balls_1.scad:
(Diese Datei zeigt einen rekursiven Funktionsaufruf. Das ist hier nicht unbedingt nötig, aber als Beispiel für eine Rekursion, die einmal etwas anderes als Fakultät berechnet, doch sinnvoll.
Du kannst etwas mit gap und den anderen Parametern spielen. Die Voreinstellungen sind mit viel "Spiel" für das "print in place"-Drucken gestaltet. So kann man auch die einzelnen Ringe einfach rausdrücken. Wenn mann dann zwei oder mehr Exemplare mit jeweils einer anderen Farbe druckt und die Ringe austauscht, kann man auch ohne AMS. MMU oder derartige Zusatzeinrichtungen mehrfarbige Kugeln drucken.)
// $Revision: 1024 $
// $Id: xmas_balls_1.scad 1024 2026-01-01 13:28:38Z bernhard $
// $Author: bernhard $
// $Date: 2026-01-01 14:28:38 +0100 (Do, 01. Jan 2026) $
/*
CC0 BY (Public Domain)
2025 by bernhard (3d.bit-field.de) is licensed under the Creative Commons - Attribution license.
*/
#include <BOSL2/std.scad>
$fn = $preview ? 64 : 92;
i_d = 60;
wand = 5;
high = 8;
rund = 1.5;
gap = 1;
kugel_d = 5;
kugel_r = kugel_d / 2;
module ring(innen_d = i_d)
{
color(innen_d % 24 == 0 ? "red" : "yellow")
difference()
{
union()
{
tube(id = innen_d, wall = wand, h = high, rounding = rund ); // der Ring
back(innen_d/2 + wand) scale([1, 1.2, 1]) sphere(d=kugel_d); // die "Nasen"
fwd(innen_d/2 + wand) scale([1, 1.2, 1]) sphere(d=kugel_d);
}
back(innen_d/2 - 0*wand) sphere(d=kugel_d + gap); // Löcher für Nasen
fwd(innen_d/2 - 0*wand) sphere(d=kugel_d + gap);
}
render();
}
module aussen_ring() // Ring mit Öse zum Aufhängen
{
difference()
{
color("yellow")
union()
{
ring();
back(i_d/2 + wand + 2)
cuboid ([high, high , high], rounding = 1 );
}
back(i_d/2 + wand + 2)
left(0*high) yrot(90) cyl (r = kugel_r/2, h = 2*high, rounding = 1);
}
}
aussen_ring();
// Funktion f, die Innenradius des nächstkleineren Kreises berechnet
function f(x) = x - 1*wand - kugel_d -2 * gap ;
// Startwert
x_start = 48 * 1;
// Schleife, die rekursiv die Innendurchmesser berechnet und Ringe zeichnet
module generate_rings(x) {
echo(x = x);
if (x >= 10) { // Abbruchbedingung (z. B. wenn x (innendurchmesser) kleiner als 10 ist)
yrot($t*360*x)
ring(x); // Ring mit aktuellem x erzeugen
generate_rings(f(x)); // Rekursiver Aufruf mit neuem x
}
}
// Starte die Rekursion
generate_rings(x_start);
Titelbildquelle: eigenes Bild
... because software matters