9. Kugeln, Kegel und Pyramiden
Versuchen wir uns mit Kugeln und Pyramiden. Schachfiguren eignen sich dafür besonders gut. Bei Wettbewerben muss eine Schachfigur der Norm entsprechen. Aber es gibt auch viele „Fantasiefiguren“, die sich noch einfacher mit einem 3D-Drucker realisieren lassen.

9.1 Schachfigur Bauer
Beginnen wir mit dem Bauer.

Er soll fürs Erste aus drei Teilen bestehen:
- Bodenplatte
- Kegel
- Kugel
9.1.1 Bodenplatte
Damit die Schachfiguren flexibel groß sein können, gibt es eine Konstante, mit der sich die Figuren skalieren lassen. Skalieren heißt, dass die Größe beliebig geändert werden kann. Aktuell lautet sie: skale = 1;.
Alle Werte im Code müssen mit «skale» multipliziert werden. So muss nur «skale» verändert werden, und die ganze Figur ändert ihre Größe.
$fn=40; // Auflösung von Kreisen
skale=1;
color("green") {
// Boden
linear_extrude(skale*1)
circle(skale*5.5);
}
Mit skale=1; sieht die Bodenplatte so aus...

9.1.2 Kegel oder auch Zylinder
Nun zu einer neuen geometrischen Figur: dem Kegel. Im Kapitel 4 haben wir bereits die Figur Zylinder kennengelernt. Dabei haben wir einen circle() (eine Scheibe) mit linear_extrude() in die Höhe wachsen lassen.
Es gibt aber auch die Funktion cylinder(). Der Befehl cylinder() hat eine Höhe und zwei Radien. Sind die beiden Radien gleich groß, ergibt das die gleiche Figur wie mit circle() und linear_extrude() – viele Wege führen nach Rom!
cylinder(h=12, r1=5.5, r2=3, center=false);
oder vereinfacht
cylinder(12,5.5,3);
"center=false" muss nicht angegeben werden, da center=false die standard Einstellung ist.
Da der Sockel 3 mm hoch ist, wird der cylinder() um 2.9 mm angehoben. So entsteht noch eine kleine Überlappung der beiden Figuren.
Das Ganze packen wir zusätzlich in ein union() (Verschmelzen), damit am Ende wirklich ein zusammenhängendes Stück entsteht.
color("green") {
union(){
// Boden
linear_extrude(skale*3)
circle(skale*5.5);
// Kegel
translate([0,0,skale*2.9]) {
cylinder(skale*12,skale*5.5,skale*3);
}
}
}
Der Bauer wird langsam erkennbar.

9.1.3 Kugel
Was noch fehlt, ist der Kopf. Der entsprechende Befehl lautet: sphere(r = x);
Die Kugel ist etwas kleiner als die Bodenplatte, aber die Werte können nach Belieben geändert werden. Ohne translate in z würde die Kugel zentriert im Nullpunkt liegen.
Da die Bodenplatte 3 mm, der Kegel 12 mm und die Kugel 4.9 mm groß sind, muss die Kugel in z fast 20 mm angehoben werden.
Testen wir es mit z = 20 und immer mit «skale» multiplizieren!
...
// Kugel
translate([0,0,skale*20]) {
sphere(skale*4.9);
}
...
Knapp daneben – die Kugel schwebt noch über dem Kegel.

Wir könnten den z-Wert exakt berechnen, aber mit ein wenig Ausprobieren geht es ebenfalls.
...
// Kugel
translate([0,0,skale*18.5]) {
sphere(skale*4.9);
}
...
Mit 18.5 mm passt es.

Die erste Figur ist fertig. Ein paar Schnörkel wären natürlich noch schön – das können wir später noch ergänzen.
9.2 Der Turm
Der Turm ist eine etwas komplexere Figur. Die folgende Zeichnung zeigt seinen Aufbau. Anstelle von Fixwerten verwenden wir Konstanten, die später beliebig angepasst werden können.

So lassen sich Größe und Dicke nach Belieben anpassen. Der Code sollte ausschließlich Konstanten verwenden, mit Ausnahme der 0.1 mm Überlappung, die für den 3D-Druck notwendig ist.
9.2.1 alle Konstanten die wir brauchen
Zuerst legen wir alle Konstanten fest, die für die Definition des Turms nötig sind. Die Werte können später jederzeit angepasst werden.
Hinweis: Der Wert turm ergibt sich aus der Summe aller Höhenwerte, die mit z_ beginnen.
$fn=40; // Auflösung von Kreisen
skale=1; // aktuell 1 kann aber später beliebig verändert werden
sockel=7.5; // Radius Sockel
ring=6; // Radius Ring oben
rand=1; // Dicke des Randes
r_unten=5.5; // Turmradius unten
r_oben=4.8; // Turmradius oben
z_sockel=2; // Höhe Sockel
z_erster=2; // Höhe erster Kegel
z_turm=12; // Höhe Turmteil
z_zweiter=2; // Höhe zweiter Kegel
z_ring=5; // Höhe Ring oben
guck=2; // Schiessscharten-Breite
//Summe gesamte Turmhöhe
turm=z_sockel+z_erster+z_turm+z_zweiter+z_ring;```code
Da kommst schon eine ganze Menge zusammen...
9.2.2 Turmaufbau
Nach der Definition der Konstanten beginnt der eigentliche Aufbau des Turms, inklusive difference()- und union()-Blöcken. Der gesamte Turm wird mit union() zu einem Stück verschmolzen, enthält aber auch Elemente, die ausgespart werden müssen.
Jedes grafische Element ist mit //... kommentiert, sodass unten nur noch der passende Code-Teil eingefügt werden muss.
color("green") {
difference() {
union(){
// Boden
linear_extrude(skale*z_sockel)
circle(skale*sockel);
// Kegel 1
// Kegel 2
// Kegel 3
// Turmkopf
}
// Turmkopf innen
// Guckloch
// Guckloch 90Grad
}
}
Nach jedem Schritt empfiehlt sich ein F5 (Vorschau). Kleine Fehler treten schnell auf und könnten beispielsweise wie folgt aussehen:

Im Beispiel wurde versehentlich „rind“ statt „rand“ geschrieben – und schon läuft der Code nicht!
Der erste Code-Block (siehe oben) erzeugt den Bodenring des Turms. Dabei muss die Konstante skale bei jeder Wertangabe berücksichtigt werden.

Nach dem Bodenring sollte eine "Verjüngung", also ein Kegel folgen. Er beginnt nach der z_sockel-Höhe minus unserem 0.1 Überschneidungswert. Da Punkt vor Strich gerechnet wird muss nicht (skale*z_sockel)-0.1 geschrieben werden!!
Der Zylinder hat dann eine Höhe von z_erster+0.1, einen unteren Radius von «sockel» und einen oberen Radius von «r_unten». Vergleicht die Namen der Konstanten mit der Skizze. Und klar, jeder Wert wird mit «skale» multipliziert.
// Kegel 1
translate([0,0,skale*z_sockel-0.1])
cylinder(skale*z_erster+0.1,skale*sockel,skale*r_unten);

Nun geht es weiter mit dem eigentlichen Turm, der als // Kegel 2 bezeichnet wird. Die Verschiebung in z ergibt sich aus z_sockel plus z_erster; anschließend werden noch 0.1 mm hinzugefügt.
Wichtig: Die Klammer skale*(z_sockel + z_erster) - 0.1 sorgt dafür, dass z_sockel und z_erster zuerst summiert werden, bevor die Multiplikation mit skale erfolgt.
// Kegel 2
translate([0,0,skale*(z_sockel+z_erster)-0.1])
cylinder(skale*z_turm+0.1,skale*r_unten,skale*r_oben);
Langsam lässt sich der Turm erahnen.

Es folgen nun noch die oberen zwei Teile. Das Zusammenzählen der verschiedenen z_-Werte können wir hier etwas vereinfachen.
Die z-Verschiebung des Kegel 3 wird wie bisher durch das Aufsummieren der z_-Werte berechnet. Beim Turmkopf rechnen wir von oben: Wir nehmen die Gesamthöhe turm und ziehen z_ring davon ab.Außerdem ist der Turmkopf wieder ein circle() und kein cylinder().
// Kegel 3
translate([0,0,skale*(z_sockel+z_erster+z_turm)-0.1])
cylinder(skale*(z_zweiter+0.1),skale*r_oben,skale*ring);
// Turmkopf
translate([0,0,skale*(turm-z_ring)-0.1])
linear_extrude(skale*z_ring)
circle(skale*ring);
Nun fehlen nur noch die Schiessscharten und die Vertiefung.

9.2.3 Schiessscharten und Vertiefung
Die Vertiefung oben im Turmkopf soll genauso tief sein wie die Gucklöcher. Darum gilt: z = (turm - guck). Der Radius ist (ring - rand) in Klammern und wird mit skale multipliziert. Ohne die Klammern bliebe rand immer 1, selbst wenn skale auf 10 gesetzt wäre.
// Turmkopf innen
translate([0,0,skale*(turm-guck)])
linear_extrude(skale*guck+0.1)
circle(skale*(ring-rand));
Zu beachten ist, dass der // Turmkopf innen außerhalb der union() { ... }-Klammer stehen muss.Sonst wird dieses Element dazugerechnet, statt herausgeschnitten!

Nun folgen noch die Schießscharten. Fürs Erste schreibe ich den Code der Schießscharten direkt nach der difference(){...}-Klammer, so sieht man, wo die Elemente genau gezeichnet werden.Oft passiert bei F5 gar nichts – der Grund ist meist eine falsche Verschiebung mit translate().
Um zu zeigen, was gemeint ist, ein kleines Beispiel: translate() ist in x und y auf 0 gesetzt, in z steht -2.
// Gucklöcher Test
translate([skale*0,skale*0,skale*(-2)])
cube([skale*(ring*2+2),skale*guck,skale*guck+0.1]);
Der Code ist außerhalb der difference()-Klammer geschrieben und wird daher angezeigt – allerdings am falschen Ort.

Hätten wir den Code im difference()-Bereich geschrieben, würden wir keinen Unterschied sehen – außer wir kippen den Turm um und betrachten die kleine Vertiefung am Boden.

Noch ein Test außerhalb des difference()-Bereichs. Dieser Test erfolgt mit korrekter Verschiebung und korrekter Länge.
// Guckloch Test
translate([skale*-(ring+0.1),skale*-(guck/2),skale*(turm-guck)])
cube([skale*(ring*2+0.2),skale*guck,skale*guck+0.1]);

Bevor wir den Code an die richtige Stelle verschieben, kommt noch die zweite Schiessscharte.
// Guckloch 90Grad
rotate([0,0,90])
translate([skale*-(ring+0.1),skale*-(guck/2),skale*(turm-guck)])
cube([skale*(ring*2+0.2),skale*2,skale*2]);
Genau so sollte es sein.

Der fertige Turm...

9.3 Pyramide
Die Pyramide haben wir bereits im Kapitel „4.5 Kreisauflösung“ gestreift.Die Funktion linear_extrude() kennt nicht nur die Höhe, sondern noch eine Reihe weiterer Parameter (Fachbegriff), die der Funktion übergeben werden können.Der erste Wert (Höhe) kann direkt als Zahl angegeben werden. Alle weiteren Parameter benötigen einen Text, damit die Funktion erkennt, was gemeint ist.
Das Wort „skalieren“ haben wir oben schon kennengelernt. Hier heißt es scale=... Mit diesem Wert beschreiben wir die Skalierung der Grundfläche:
- 1 bedeutet gleich gross
2.3 ist 2.3-mal grösser
0 wird auf einen Punkt verkleinert.
linear_extrude(15,scale = 0)
circle(10,$fn=4);
Die Funktion circle(10,$fn=4); ergibt ein Kreis mit Radius 10 und einer Kreisauflösung von 4. Mit linear_extrude(..scale=0); ergibt das eine Pyramide.

Hier die gesamten Parameter der Funktion linear_extrude().
linear_extrude(height = 5, v = [0, 0, 1], center = true, convexity = 10, twist = -fanrot, slices = 20, scale = 1.0, $fn = 16)
circle(10,$fn=4);