OpenSCAD Benutzerhandbuch/Transformationen
Grundkonzept
[Bearbeiten]Transformationen wirken auf ihre Kind-Objekte und verändern sie – wie der Name schon sagt – auf verschiedene Weise: z. B. durch Verschieben, Drehen oder Skalieren.
Transformationen werden vor dem Objekt geschrieben, das sie beeinflussen sollen, z. B.:
translate([10,20,30])
cube(10);
Beachte: Hinter einem Transformationsbefehl steht kein Semikolon!
Möchtest du mehrere Objekte gemeinsam transformieren, schließt du sie mit "{" und "}" in einen Block ein:
translate([0,0,-5])
{
cube(10);
cylinder(r=5,h=10);
}
Du kannst Transformationen auch verschachteln, um mehrere Effekte hintereinander anzuwenden:
rotate([45,45,45])
translate([10,20,30])
cube(10);

Die Kombination von Transformationen erfolgt sequenziell von rechts nach links. Schau dir diese beiden Beispiele an:
color("red") translate([0,10,0]) rotate([45,0,0]) cube(5);
color("green") rotate([45,0,0]) translate([0,10,0]) cube(5);
Obwohl beide dieselben Befehle enthalten, passiert etwas völlig anderes:
- Beim roten Würfel wird zuerst um den Ursprung gedreht – danach wird er um "[0,10,0]" verschoben.
- Beim grünen Würfel wird zuerst verschoben – erst danach wird um den Ursprung gedreht. Dadurch bewegt sich der Würfel auf einem Kreisbogen mit Radius 10 um den Ursprung.
Die Reihenfolge macht also einen riesigen Unterschied!
Fortgeschrittenes Konzept
[Bearbeiten]OpenSCAD nutzt unterschiedliche Bibliotheken für verschiedene Funktionen – das kann zu kleinen Inkonsistenzen im Vorschaumodus (F5) führen.
„Klassische“ Transformationen wie "translate", "rotate", "scale", "mirror" und "multmatrix" werden in der Vorschau über OpenGL gerendert. Komplexere Befehle wie "resize" hingegen nutzen CGAL – sie verändern also das eigentliche Geometrieobjekt, statt es nur optisch zu transformieren.
Das wirkt sich besonders bei Modifikator-Zeichen wie "#" (Highlight) oder "%" (Transparent) aus: Manchmal wird das ursprüngliche, manchmal das berechnete Objekt hervorgehoben – je nachdem, ob es sich um eine „echte“ CSG-Operation handelt oder nicht.
scale
[Bearbeiten]Skaliert alle Kind-Objekte mit dem angegebenen Vektor. Im Gegensatz zu "resize()" wird hier multipliziert: Die aktuelle Größe wird mit dem Faktor im Vektor multipliziert. Der Parametername ist optional.
Beispiel:
cube(10);
translate([15,0,0]) scale([0.5,1,2]) cube(10);
resize
[Bearbeiten]Passt die Größe des Kind-Objekts exakt an die angegebenen x-, y- und z-Werte an.
"resize()" ist eine CGAL-Operation – sie arbeitet also mit der vollen Geometrie und braucht daher auch in der Vorschau (F5) etwas Zeit.
Beispiel:
// Vergrößere die Kugel auf 30 in X, 60 in Y und 10 in Z
resize(newsize=[30,60,10]) sphere(r=10);
Ist einer der Werte (x, y oder z) 0, bleibt diese Dimension unverändert:
// Vergrößere den 1×1×1-Würfel auf 2×2×1
resize([2,2,0]) cube();
Mit dem Parameter "auto = true" werden alle 0-Dimensionen automatisch skaliert, um das Seitenverhältnis zu erhalten:
// Vergrößere den 1×2×0.5-Würfel auf 7×14×3.5
resize([7,0,0], auto=true) cube([1,2,0.5]);
Du kannst auch gezielt einzelne Dimensionen automatisch skalieren lassen:
// Vergrößere auf 10×8×1 – Z bleibt unverändert
resize([10,0,0], auto=[true,true,false]) cube([5,4,1]);
rotate
[Bearbeiten]Dreht das Kind-Objekt um einen bestimmten Winkel – entweder um die Standardachsen oder um eine beliebige Achse.
Die Parameternamen sind optional, wenn die Argumente in der richtigen Reihenfolge stehen.
// Nutzung:
rotate(a = winkel, v = [x, y, z]) { ... }
// oder
rotate(winkel, [x, y, z]) { ... }
rotate(a = [wx, wy, wz]) { ... }
rotate([wx, wy, wz]) { ... }
Wenn "a" ein Array ist (z. B. "[ax,ay,az]"), wird der "v"-Parameter ignoriert. Die Drehung erfolgt dann nacheinander: erst um X, dann um Y, dann um Z. Das heißt:
rotate(a=[ax,ay,az]) {...}
ist das Gleiche wie:
rotate(a=[0,0,az]) rotate(a=[0,ay,0]) rotate(a=[ax,0,0]) {...}
Um ein Objekt z. B. auf den Kopf zu stellen, drehst du es um 180° um die Y-Achse:
rotate([0,180,0]) { ... }
Der optionale Parameter "v" definiert eine beliebige Rotationsachse als Normalenvektor. Beispiel: Drehung um 45° um die Achse "[1,1,0]":
rotate(a=45, v=[1,1,0]) { ... }
Ein einzelner Zahlenwert dreht immer um die Z-Achse – besonders praktisch in 2D:
rotate(45) square(10);
Hilfestellung zur Drehregel
[Bearbeiten]
Für "rotate([a, b, c])" gilt:
- a: Drehung um die X-Achse – von +Y Richtung +Z
- b: Drehung um die Y-Achse – von +Z Richtung +X
- c: Drehung um die Z-Achse – von +X Richtung +Y
Das folgt der Rechte-Hand-Regel: Zeig mit dem rechten Daumen in Richtung der positiven Achse – deine Finger zeigen die Drehrichtung.
Wenn du "a = 0" setzt und nur "b" und "c" veränderst, erhältst du ein Kugelkoordinatensystem. So baust du z. B. einen Zylinder vom Ursprung zu einem Punkt "(x,y,z)":
x= 10; y = 10; z = 10; // Zielpunkt
length = norm([x,y,z]); // Abstand zum Ursprung
b = acos(z/length); // Neigungswinkel (Inklination)
c = atan2(y,x); // Azimutwinkel
rotate([0, b, c])
cylinder(h=length, r=0.5);
%cube([x,y,z]); // Ecke des Würfels sollte mit Zylinderspitze übereinstimmen
translate
[Bearbeiten]Verschiebt alle Kind-Objekte entlang des angegebenen Vektors. Der Parametername ist optional.
Beispiel:
cube(2,center = true);
translate([5,0,0])
sphere(1,center = true);
mirror
[Bearbeiten]Erzeugt ein Spiegelbild des Kind-Objekts an einer Ebene durch den Ursprung. Der übergebene Vektor ist der Normalenvektor dieser Spiegelebene.
Beispiel: "mirror([1,0,0])" spiegelt an der YZ-Ebene – alle x-Koordinaten wechseln ihr Vorzeichen.
Funktions-Signatur:
[Bearbeiten]mirror(v = [x, y, z]) { ... }
Beispiele
[Bearbeiten]Das Original ist rechts. Beachte: "mirror()" erzeugt keine Kopie – es verändert das Objekt direkt (genau wie "rotate" oder "scale").
-
hand(); // originalmirror([1,0,0]) hand(); -
hand(); // originalmirror([1,1,0]) hand(); -
hand(); // originalmirror([1,1,1]) hand();
// Original
rotate([0,0,-30]){
cube([23,12,10]);
translate([0.5, 4.4, 9.9]){
color("red", 1.0){
linear_extrude(height=2){
text("OpenSCAD", size= 3);
}
}
}
}
// Gespiegelt
mirror([1,0,0]){
rotate([0,0,-30]){
cube([23,12,10]);
translate([0.5, 4.4, 9.9]){
color("red", 1.0){
linear_extrude(height=2){
text("OpenSCAD", size= 3);
}
}
}
}
}
multmatrix
[Bearbeiten]Wendet eine affine Transformationsmatrix auf alle Kind-Objekte an. Die Matrix ist 4×3 (drei Zeilen mit je vier Werten) oder 4×4 (vierte Zeile muss "[0,0,0,1]" sein).
Nutzung: "multmatrix(m = [...]) { ... }"
Was du mit den einzelnen Elementen erreichen kannst (erste drei Zeilen):
| Skalierung X | Scherung X nach Y | Scherung X nach Z | Verschiebung X |
| Scherung Y nach X | Skalierung Y | Scherung Y nach Z | Verschiebung Y |
| Scherung Z nach X | Scherung Z nach Y | Skalierung Z | Verschiebung Z |
Jeder Punkt wird als 4D-Vektor "[x, y, z, 1]" behandelt. Die vierte Zeile "[0,0,0,1]" sorgt dafür, dass die Verschiebung korrekt funktioniert.
Dieses Beispiel dreht um 45° in der XY-Ebene und verschiebt um "[10,20,30]" – äquivalent zu "translate([10,20,30]) rotate([0,0,45])":
angle=45;
multmatrix(m = [ [cos(angle), -sin(angle), 0, 10],
[sin(angle), cos(angle), 0, 20],
[ 0, 0, 1, 30],
[ 0, 0, 0, 1]
]) union() {
cylinder(r=10.0,h=10,center=false);
cube(size=[10,10,10],center=false);
}
Mit "multmatrix" kannst du auch Scherungen erzeugen – das geht mit anderen Transformationen nicht:
M = [ [ 1 , 0 , 0 , 0 ],
[ 0 , 1 , 0.7, 0 ], // 0.7 = Scherfaktor: Y wird bei steigendem Z verschoben
[ 0 , 0 , 1 , 0 ],
[ 0 , 0 , 0 , 1 ] ] ;
multmatrix(M) { union() {
cylinder(r=10.0,h=10,center=false);
cube(size=[10,10,10],center=false);
} }
color
[Bearbeiten]Färbt die Kind-Objekte mit der angegebenen Farbe (RGBA). Achtung: Farben wirken nur in der Vorschau (F5) – beim Rendern (F6) und im STL-Export werden sie ignoriert.
Funktions-Signatur:
[Bearbeiten]color(c = [r, g, b, a]) { ... }
color(c = [r, g, b], alpha = 1.0) { ... }
color("#hexwert") { ... }
color("farbname", 1.0) { ... }
Alle RGBA-Werte müssen als Fließkommazahlen zwischen 0.0 und 1.0 angegeben werden. Möchtest du Werte aus dem Bereich [0–255] verwenden, teile einfach durch 255:
color([0,125,255]/255) { ... }
Vorlage:OpenSCAD User Manual/Tip
Benannte Farben
[Bearbeiten]Vorlage:Requires Farben lassen sich auch per Namen angeben (Groß-/Kleinschreibung egal):
color("red") sphere(5);
color("Blue",0.5) cube(5);
color("green",alpha=0.5) cube(5);
Die Namen stammen aus der SVG-Farbliste des W3C. OpenSCAD kennt zusätzlich ""transparent"" → "[0,0,0,0]".
|
CSS-Farbnamen-Tabelle | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
|
|
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Tabelle basierend auf „Web Colors“ von Wikipedia
Hex-Farbwerte
[Bearbeiten]Vorlage:Requires Du kannst Farben auch als Hex-String angeben – in RGB oder RGBA, mit 3/4 oder 6/8 Zeichen:
- "#rgb"
- "#rgba"
- "#rrggbb"
- "#rrggbbaa"
Wird Alpha sowohl im Hex-Wert als auch separat angegeben, hat der separate Parameter Vorrang.
Beispiel
[Bearbeiten]
for(i=[0:36]) {
for(j=[0:36]) {
color([0.5+sin(10*i)/2, 0.5+sin(10*j)/2, 0.5+sin(10*(i+j))/2])
translate([i, j, 0])
cube(size = [1, 1, 11+10*cos(10*i)*sin(10*j)]);
}
}
Da "-1 ≤ sin(x) ≤ 1", liegt jeder Farbwert sicher zwischen 0 und 1.
Beispiel 2
[Bearbeiten]So kannst du Farben optional ein- oder ausschalten:
module myModule(withColors=false) {
c = withColors ? "red" : undef;
color(c) circle(r=10);
}
"undef" als Farbe behält die Standardfarbe bei.
offset
[Bearbeiten]Vorlage:Requires Standardwert (ohne Angabe): "r = 1", "chamfer = false"
"offset()" erzeugt eine neue 2D-Innen- oder Außenkontur aus einer bestehenden.
Es gibt zwei Modi:
- Radial ("r"): Ein Kreis mit Radius "r" „rollt“ um die Kontur herum → abgerundete Ecken.
- Delta ("delta"): Die neue Kontur hat überall denselben Abstand zur alten → eckige Ecken.
"offset" ist super, um dünne Wände zu erzeugen – z. B. durch Subtraktion einer negativen von einer positiven Offset-Kontur.
Damit kannst du auch Abrundungen simulieren:
- Innenrundung (Fillet): "offset(r=-3) offset(delta=+3)"
- Außenrundung (Round): "offset(r=+3) offset(delta=-3)"
Parameter
[Bearbeiten]Der erste Parameter kann ohne Namen übergeben werden → wird als "r" interpretiert.
r oder delta
- Zahl. Betrag der Verschiebung. Negativ = nach innen.
- "r" (Standard): Radius des „Rollkreises“ → abgerundete Ecken.
- "delta": fester Abstand → eckige Ecken.
- chamfer
- Boolesch. Bei "delta" bestimmt dies, ob Ecken abgeschrägt ("true") oder verlängert ("false") werden. Hat keine Wirkung bei "r".
$fa, $fs, $fn
- Steuern die Glätte bei radialen Offsets (keine Wirkung bei "delta").
Beispiele
[Bearbeiten]
// Beispiel 1
linear_extrude(height = 60, twist = 90, slices = 60) {
difference() {
offset(r = 10) square(20, center = true);
offset(r = 8) square(20, center = true);
}
}
// Beispiel 2: Fillet-Modul
module fillet(r) {
offset(r = -r) offset(delta = r) children();
}
fill
[Bearbeiten]"fill()" entfernt Löcher aus Polygonen, ohne die Außenkontur zu verändern. Bei konvexen Formen ist das Ergebnis identisch mit "hull()".
Beispiel

t = "OpenSCAD";
linear_extrude(15) {
text(t, 50);
}
color("darkslategray") {
linear_extrude(2) {
offset(4) {
fill() {
text(t, 50);
}
}
}
}
minkowski
[Bearbeiten]

Zeigt die Minkowski-Summe der Kind-Objekte an.
Beispiel: Du willst einen flachen Quader mit abgerundeten Kanten? Nimm den Quader und einen Zylinder:
$fn=50;
cube([10,10,1]);
cylinder(r=2,h=1);
Und bilde die Minkowski-Summe:
$fn=50;
minkowski() {
cube([10,10,1]);
cylinder(r=2,h=1);
}
Achtung: Der Ursprung des zweiten Objekts bestimmt die Addition! Diese beiden Varianten liefern unterschiedliche Ergebnisse:
minkowski() {
cube([10, 10, 1]);
cylinder(1, center=true); // symmetrisch um Ursprung
}
minkowski() {
cube([10, 10, 1]);
cylinder(1); // liegt bei z ≥ 0
}
Warnung: Bei hohen "$fn"-Werten wird’s schnell sehr rechenintensiv – denn jeder Punkt des ersten Objekts wird mit jedem Punkt des zweiten kombiniert!
Warnung: Wenn eine Eingabe aus mehreren Teilen besteht (z. B. "sphere(); cylinder();"), behandelt "minkowski" sie als getrennte Objekte – das führt oft zu unerwünschten „Brücken“. Um das zu vermeiden, packe alles in ein "union()".
hull
[Bearbeiten]

Zeigt die konvexe Hülle der Kind-Objekte an.
Beispiel:
hull() {
translate([15,10,0]) circle(10);
circle(10);
}
"hull()" arbeitet bei 2D-Objekten nur in der XY-Ebene – die Z-Höhe wird ignoriert.
Tipp: Es ist viel schneller, "hull()" auf 2D-Kreisen anzuwenden und das Ergebnis dann mit "linear_extrude()" in 3D zu heben, als direkt "hull()" auf 3D-Zylindern zu verwenden – auch wenn das Ergebnis gleich aussieht!
