6. Kombinationen mit bekannten Befehlen
Bereits bekannte Befehle:
rotate()
linear_extrude(6)
circle(7);
union() {...}
difference() {...}
color("#800000")
translate([20,20,0])
cube([10,20,1]);
Wir kennen nun bereits eine ganze Reihe von Befehlen der Skriptsprache von OpenSCAD. Mit diesen Befehlen können bereits komplexe Objekte erstellt werden.
6.1 Kombi-Cube
Dieser kombinierte Würfel ist unsere nächste Aufgabe. Wir kennen bereits den Rahmenwürfel aus Abschnitt 3.5.1 — hier wenden wir neue Befehle wie circle() und rotate() kombiniert an.
Dabei erfordert es etwas Denkarbeit, da es oft mehrere Wege gibt, ein Ziel zu erreichen. Am besten übernimmst du den Code schrittweise in OpenSCAD und testest jeden Schritt direkt selbst.

6.2 Der Basis-Cube
Die Basis des Objekts ist erneut ein cube([20,20,20]) in color("green")— allerdings muss der Würfel innen hohl sein, mit einer Wandstärke von 2 mm. Hier direkt der komplette cube() mit Hohlraum:
difference() {
color("green")
cube([20,20,20]); // Basiswürfel
color("red")
translate([2,2,2])
cube([16,16,16]); // Hohlraum
}

Man sieht nicht, ob der Würfel innen hohl ist. Schneiden wir daher zur Überprüfung einfach die zweite Hälfte des Würfels weg. Im neuen Codebeispiel ist nicht mehr alles vollständig dargestellt — die drei Punkte ... zeigen an, dass vor und nach dem Codeausschnitt weiterer Code steht. Die neuen drei Zeilen müssen vor dem abschließenden } eingefügt werden!
...
color("yellow")
translate([10,-0.1,-0.1])
cube([16,21,21]);
...
Sollte eine Fehlermeldung erscheinen oder das Ergebnis nicht mit diesem Bild übereinstimmen, überprüfe den Code bitte nochmals sorgfältig!

6.3 Die Minus-Seite
Entfernen wir den Kontrollschnitt wieder und beginnen mit der Bearbeitung der Seiten. Hier das Gerüst für unseren
difference() {
color("green")
cube([20,20,20]); // Basiswürfel
color("red")
translate([2,2,2])
cube([16,16,16]); // Hohlraum
// Minus
// Division
// Plus
// Dreieck
// Fünfeck
// Multiplikation
} // Ende von difference
Wir werden nun jede Seite einzeln bearbeiten.
Die einfachste Seite des Würfels ist die Minus-Seite. Die Länge des Minuszeichens beträgt x = 10 mm (der Würfel hat 20 mm), und die Höhe des Zeichens ist z = 2 mm.
Die Wandstärke des Würfels beträgt 2 mm. Wie bereits gesehen, benötigt difference() immer einen Vor- und Nachlauf — das heißt, das Objekt, das herausgeschnitten werden soll, muss etwas vor dem Basisobjekt beginnen und auch etwas darüber hinausreichen.
Wir werden nun jede Seite einzeln abarbeiten.
// Minus
color("yellow")
translate([5,-0.1,9])
cube([10,3,2]); //
Warum translate([5,-0.1,9])?
Bei komplexeren Objekten ist es vorteilhaft, zunächst eine skizzierte Zeichnung mit Bemassung anzufertigen. Das lässt sich gut auf Papier erledigen — oft geht es schneller als mit einem Computerprogramm.

- Bild 1: Ansicht von vorne — zeigt die x- und z-Richtung. Die Mitte der Seite liegt bei 10 mm.
- Bild 2: Ein cube() mit Länge 10 mm und Höhe 2 mm, positioniert bei 0,0 — also genau dort, wo es später im Zentrum der
- Bild 3: Um welchen Betrag muss der cube() nun in x- und z-Richtung verschoben werden?
Seite platziert sein soll.
Die Formel für die Verschiebung in x lautet: (Basiswürfel-Länge / 2) - (Minus-Länge / 2) = x
(20 / 2) - ( 10 / 2) = 5
Im Beispiel ist die Minus-Länge genau die Hälfte der Würfelkantenlänge — daher könnten wir auch einfach rechnen:
Würfel-Länge / 4 = 5 mm
Das erscheint logisch. Wäre die Würfelkante jedoch 434.6 mm lang und das Minuszeichen wiederum genau die Hälfte davon, lautete die Formel:
434.6 / 4 = 108.65
Bei einfachen Maßen wie 20 mm und 10 mm lässt sich die Berechnung oft schnell im Kopf erledigen. Werden das Objekt und die Berechnungen komplexer, hilft — wie oben gezeigt — eine kleine Skizze mit Bemaßung.
Nun fehlt noch die Formel für die z-Verschiebung:
(Basiswürfel-Länge / 2) - (Minus-Dicke / 2) = z
(20 / 2) - ( 2 / 2) = 9
Die y-Verschiebung um –0,1 mm dient dazu, das Problem von difference() zu umgehen: Das herauszuschneidende Objekt muss leicht vor der Oberfläche des Basisobjekts beginnen — also nicht exakt auf der Fläche, sondern minimal davor.

Die Minus-Seite war noch die Einfachste... gehen zur Division-Seite.
6.4 Die Division-Seite
Nun wenden wir uns der Division-Seite zu. Dazu benötigen wir zwei Zylinder, die um 90 Grad um die y-Achse gekippt und an die gewünschte Position verschoben werden.
Damit die einzelnen Schritte besser übersichtlich bleiben, fügen wir den neuen Code ganz am Ende des bestehenden Blocks ein — hinter der geschweiften Klammer von difference() und nach der Zeile: } // Ende von difference
...
} // Ende von difference
color("magenta") {
linear_extrude(3)
circle(2);
}
Als Erstes fällt auf, dass der Zylinder — basierend auf circle(2) — sehr grob gerendert wird, da die Standard-Auflösung für Kreise in OpenSCAD recht niedrig ist.

Wie im vorherigen Kapitel setzen wir ganz am Anfang des Codes $fn = 60; — dies erhöht die Auflösung aller Kreise und Zylinder im Modell.
$fn=60;
So wird der Zylinder in einer bessern Auflösung dargestellt.

Er steht jedoch noch am falschen Ort und muss noch gekippt werden. Wie bereits gesehen, beeinflusst die Reihenfolge von rotate() und translate() das Ergebnis stark.
Wir testen dies an zwei Varianten:
- In der ersten Variante kommt der Zylinder an die gewünschte Position.
- In der zweiten Variante werden dieselben Werte verwendet, doch rotate() und translate() wurden vertauscht.
...
} // Ende von difference
color("magenta") {
translate([17.9,10,14])
rotate([0,90,0])
linear_extrude(3)
circle(2);
rotate([0,90,0])
translate([17.9,10,14])
linear_extrude(3)
circle(2);
}
Obwohl beide Beispiele dieselben Werte verwenden, landet der zweite Zylinder an einem völlig anderen Ort — weil die Reihenfolge von rotate() und translate() entscheidend ist.

Bauen wir die Variante mit rotate() als erstem Befehl Schritt für Schritt auf.
...
} // Ende von difference
color("magenta") {
rotate([0,90,0])
translate([0,0,0])
linear_extrude(3)
circle(2);
}
Durch rotate([0,90,0]) um die y-Achse zeigen x- und z-Richtung in eine völlig andere Richtung als gewohnt.

Um den gekippten Zylinder auf die Höhe der gewünschten Seite zu verschieben, muss der z-Wert von translate() — und nicht der „eigentliche“ x-Wert — angepasst werden. Durch rotate() dreht sich ja das gesamte „Universum“ der nachfolgenden Befehle.
Der Würfel hat eine Kantenlänge von 20 mm, abzüglich einer Wanddicke von 2 mm und einer kleinen Versetzung von 0.1 mm — das ergibt 17.9 mm auf der z-Achse.
color("magenta") {
rotate([0,90,0])
translate([0,0,17.9])
linear_extrude(3)
circle(2);
}
Mit etwas Drehen in der 3D-Ansicht sehen wir, dass der Zylinder in die richtige Richtung verschoben wurde.

Die y-Richtung ist ja noch dieselbe wie zuvor — also 10 mm in y-Richtung.
Nun zur x-Achse: Um wie viel muss in x-Richtung verschoben werden, und in welche Richtung?
Auf dem Bild weiter oben mit dem gedrehten xyz-Kreuz sehen wir, dass die x-Richtung im negativen Bereich liegt. Der erste Punkt der Division soll etwas über der Mitte liegen — nehmen wir 14 mm. Achtung: –14 mm.
color("magenta") {
rotate([0,90,0])
translate([-14,10,17.9])
linear_extrude(3)
circle(2);
}
Geschafft!

Der erste Punkt ist positioniert. Nun können wir den Code in den difference()-Bereich verschieben — er steht momentan außerhalb des { }-Bereichs. Gleichzeitig fügen wir den zweiten Punkt hinzu, der in x nur –6 mm beträgt.
// Division
color("magenta") {
rotate([0,90,0])
translate([-14,10,17.9])
linear_extrude(3)
circle(2);
rotate([0,90,0])
translate([-6,10,17.9])
linear_extrude(3)
circle(2);
}

Nun geht es eine Seite weiter, zum Plus.
6.5 Die Plus-Seite
Ein Plus + enthält ja auch den Minus-Balken. Also kopieren wir den Minus-Code einfach für das Plus.Bevor wir den vertikalen Balken definieren, betrachten wir noch einmal die Skizze des Minus mit dem vertikalen Balken.
Dabei bleiben wir auf der Seite unseres Minus und schreiben den Code erneut ganz am Ende — nach der Zeile } // Ende von difference.

} // Ende von difference
// plus
color("blue") {
translate([5,-0.1,9])
cube([10,3,2]);
translate([9,-0.1,5])
cube([2,3,10]);
}
Die y-Richtung ist im Beispiel –0.1, damit wir das Kreuz bereits sehen können.

Es muss nur an der y-Verschiebung „geschraubt“ werden.
Da der Würfel eine Seitenlänge von 20 mm hat, muss der y-Wert 20 mm minus die Wanddicke minus 0.1 mm betragen — also 17.9 mm. Um etwas zu sehen, muss der Würfel in der Ansicht gedreht werden.
Verschieben wir den Code gleich an seinen richtigen Ort im difference()-Bereich.
// plus
color("blue") {
translate([5,17.9,9])
cube([10,3,2]); //
translate([9,17.9,5])
cube([2,3,10]); //
}
Damit wir das Plus auch sehen können, müssen wir den Würfel in der 3D-Ansicht drehen. Dabei können wir auch durch den Würfel die Öffnung des Minus erkennen.

6.6 Das Fünfeck am Boden
Die nächste Öffnung soll das Fünfeck am Boden des Würfels sein. Wie erstellt man ein Fünfeck?
Kurz nachgedacht — und genau: Im Kapitel 4.5 Kreisauflösung haben wir circle(10, $fn=4) kennengelernt. Damit wird ein Kreis als Viereck dargestellt!
Somit ist ein Fünfeck kein Problem. Da circle() ohne weitere Angaben zentriert gezeichnet wird, beträgt die Verschiebung in x und y jeweils 10 mm. Die z-Verschiebung muss erneut um 0.1 mm in den Minusbereich erfolgen.
// Fünfeck
color("aqua")
translate([10,10,-0.1])
linear_extrude(3)
circle(7,$fn=5);
Damit wir das Fünfeck am Boden sehen können, muss die Ansicht erneut gedreht werden.

6.7 Das Dreieck oben am Würfel
Das wäre dann ganz einfach: Gleich wie das Fünfeck, nur in z um 17.9 mm verschoben.
// Dreieck
color("aqua")
translate([10,10,17.9])
linear_extrude(3)
circle(7,$fn=3);
Das Dreieck scheint jedoch nicht schön zentriert zu sein.

Schieben wir das Ganze einfach etwas näher an die 0-Linie in x-Richtung.
translate([8.5,10,17.9])
So passt es.

6.8 Die Multiplikation
Die letzte Seite wartet mit der schwierigsten Aufgabe. Wenn wir die Aufgabe jedoch geschickt angehen, ist auch das gut machbar.
Die Multiplikation ist ja eigentlich „nur“ ein Plus, das um 45 Grad gekippt ist.Wenn wir jedoch das bereits erstellte Plus verwenden und kippen, wird es anschließend kompliziert.Das Beispiel steht wieder außerhalb von difference(), damit wir genau sehen, wo sich das Objekt befindet.Am Ende können wir es wieder in den difference()-Bereich kopieren.
// kopie von Plus
color("yellow") {
translate([0,-1,4])
cube([10,3,2]); //
translate([4,-1,0])
cube([2,3,10]); //
}
Das Plus wurde so platziert, dass es unten sowie an der Seite genau bei x = 0 und z = 0 liegt.

Wenn wir nun rotate([0,45,90]) anwenden, entspricht das Ergebnis nicht unseren Erwartungen.
// kopie von Plus
color("yellow") {
rotate([0,45,90]) {
translate([0,-1,4])
cube([10,3,2]); //
translate([4,-1,0])
cube([2,3,10]); //
}
}
Zwar wurde in y um 45 Grad und in z um 90 Grad gedreht, aber wo genau ist das Multiplikationszeichen gelandet? Um wie viel muss es verschoben werden, damit es genau im Zentrum der Seite steht?

Es gibt einen einfacheren Weg! Warum nicht bei cube() „center = true“ setzen (siehe 1.5: Cube geht auch anders)? Dann dreht sich alles genau um das Zentrum des Pluszeichens.
// kopie von Plus
color("yellow") {
cube([10,3,2], center =true );
cube([2,3,10], center =true );
}
So braucht es nicht einmal ein translate() für die beiden cube(), da sie bereits genau zentriert sind.

Nun noch rotate(), wie oben bereits gesehen …
// kopie von Plus
color("yellow") {
rotate([0,45,90]) {
cube([10,3,2], center =true );
cube([2,3,10], center =true );
}
}
… und das Multiplikationszeichen befindet sich nun genau bei 0,0!

Nun müssen wir das Ganze nur noch um 10,10 verschieben … und weil auch die „Tiefe“ zentriert ist, braucht es dort ebenfalls eine kleine Verschiebung 1. Alternativ könnten wir die cube() statt 3 mm einfach 5 mm dick machen.
// Multiplikation
color("yellow") {
translate([1,10,10]) {
rotate([0,45,90]) {
cube([10,3,2], center =true );
cube([2,3,10], center =true );
}
}
}
Das rotate() funktioniert bei zentrierten Objekten um einiges einfacher!
