OpenSCAD Benutzerhandbuch/Kapitel 2
Teile oder das ganze Modell skalieren
[Bearbeiten]Das Modell, das du im letzten Kapitel erstellt hast, war ein super Ausgangspunkt, um mit OpenSCAD zu arbeiten – aber vielleicht ist dir beim Anschauen direkt aufgefallen, dass hier und da noch was geändert werden sollte. Genau darum geht’s jetzt: Wir schauen uns an, wie du Komponenten deines Designs anpassen kannst. Eine Möglichkeit dafür ist der scale-Befehl – einer der Transformationsbefehle.
Ändere die Zeile, die den Unterbau der Fahrzeugkarosserie erzeugt, folgendermaßen ab, um die Länge des Fahrzeugs um den Faktor 1,2 zu vergrößern:
|
car_with_lengthened_body_base.scad …
// Car body base
scale([1.2,1,1])
cube([60,20,10],center=true);
…
|
Dir fällt sicher auf, dass der `scale`-Befehl genauso verwendet wird wie die `translate`- und `rotate`-Befehle: Er wird links vor eine bestehende Anweisung gesetzt, ohne dass dazwischen ein Semikolon steht, und erhält als Eingabeparameter einen Vektor mit drei Werten. Genau wie bei `translate` und `rotate` entspricht dabei jeder Wert dem Skalierungsfaktor entlang der X-, Y- bzw. Z-Achse.
| Probier mal aus, die Eingabewerte des `scale`-Befehls so zu verändern, dass die Basis des Fahrzeugkörpers um den Faktor 1,2 entlang der X-Achse und entweder um den Faktor 0,1 oder 2 entlang der Y-Achse skaliert wird. Bekommst du so etwas hin, das an einen Mars-Rover oder einen Panzer erinnert? Überrascht es dich, wie unterschiedlich die Modelle im Vergleich zum ursprünglichen Auto aussehen? |
Du kannst denselben `scale`-Befehl – oder auch jede andere Transformationsanweisung – übrigens auch auf mehrere Objekte gleichzeitig anwenden. Verwende dazu den folgenden Code, um sowohl die Basis als auch das Dach des Fahrzeugkörpers zu skalieren:
|
car_with_lengthened_body.scad scale([1.2,1,1]) {
// Car body base
cube([60,20,10],center=true);
// Car body top
translate([5,0,10 - 0.001])
cube([30,20,10],center=true);
}
|
Als Erstes fällt dir sicher auf: Um den `scale`-Befehl auf mehrere Objekte gleichzeitig anzuwenden, brauchst du geschweifte Klammern `{}`. Alle Anweisungen, die zu den betreffenden Objekten gehören – inklusive ihrer Semikolons – kommen einfach zwischen diese Klammern. Und keine Sorge: Nach der schließenden Klammer brauchst du kein Semikolon.
Als Zweites siehst du wahrscheinlich, wie sehr Leerzeichen und Kommentare deinen Code lesbarer machen. Der folgende Code macht exakt dasselbe – entscheide selbst, welchen du lieber lesen würdest:
scale([1.2,1,1]) {
cube([60,20,10],center=true);
translate([5,0,10 - 0.001])
cube([30,20,10],center=true);
}
|
| Probier mal aus, den `scale`-Befehl auf dein komplettes Modell anzuwenden. Hast du daran gedacht, wirklich alle Anweisungen in die geschweiften Klammern einzuschließen? Welche Beziehung müssen die Skalierungsfaktoren entlang der X- und Z-Achse haben, damit sich die Räder nicht verformen? Und welche Werte brauchst du, um ein Auto mit denselben Proportionen, aber der doppelten Größe zu erhalten? |
- Damit sich die Räder nicht verformen, sollten die Skalierungsfaktoren entlang der X- und Z-Achse gleich sein.
|
scaled_car.scad $fa = 1;
$fs = 0.4;
scale([2,2,2]) {
// Car body base
cube([60,20,10],center=true);
// Car body top
translate([5,0,10 - 0.001])
cube([30,20,10],center=true);
// Front left wheel
translate([-20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=8,center=true);
// Front right wheel
translate([-20,15,0])
rotate([90,0,0])
cylinder(h=3,r=8,center=true);
// Rear left wheel
translate([20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=8,center=true);
// Rear right wheel
translate([20,15,0])
rotate([90,0,0])
cylinder(h=3,r=8,center=true);
// Front axle
translate([-20,0,0])
rotate([90,0,0])
cylinder(h=30,r=2,center=true);
// Rear axle
translate([20,0,0])
rotate([90,0,0])
cylinder(h=30,r=2,center=true);
}
|
Schnelles Quiz
[Bearbeiten]Das folgende Skript ist das Modell, das du im ersten Kapitel erstellt hast.
$fa = 1;
$fs = 0.4;
// Car body base
cube([60,20,10],center=true);
// Car body top
translate([5,0,10 - 0.001])
cube([30,20,10],center=true);
// Front left wheel
translate([-20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=8,center=true);
// Front right wheel
translate([-20,15,0])
rotate([90,0,0])
cylinder(h=3,r=8,center=true);
// Rear left wheel
translate([20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=8,center=true);
// Rear right wheel
translate([20,15,0])
rotate([90,0,0])
cylinder(h=3,r=8,center=true);
// Front axle
translate([-20,0,0])
rotate([90,0,0])
cylinder(h=30,r=2,center=true);
// Rear axle
translate([20,0,0])
rotate([90,0,0])
cylinder(h=30,r=2,center=true);
|
| Probier mal aus, die vorderen Räder um 20 Grad um die Z-Achse zu drehen, als ob das Auto eine Rechtskurve fahren würde. Damit dein Modell überzeugender wirkt, drehe außerdem den Fahrzeugkörper (Basis und Dach) um 5 Grad um die X-Achse – und zwar in die entgegengesetzte Richtung der Kurve. Um die Räder zu drehen, ändere die Eingabeparameter der bestehenden `rotate`-Befehle. Um den Körper zu drehen, füge einen neuen `rotate`-Befehl hinzu. |
|
turning_car.scad $fa = 1;
$fs = 0.4;
rotate([5,0,0]) {
// Car body base
cube([60,20,10],center=true);
// Car body top
translate([5,0,10 - 0.001])
cube([30,20,10],center=true);
}
// Front left wheel
translate([-20,-15,0])
rotate([90,0,-20])
cylinder(h=3,r=8,center=true);
// Front right wheel
translate([-20,15,0])
rotate([90,0,-20])
cylinder(h=3,r=8,center=true);
// Rear left wheel
translate([20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=8,center=true);
// Rear right wheel
translate([20,15,0])
rotate([90,0,0])
cylinder(h=3,r=8,center=true);
// Front axle
translate([-20,0,0])
rotate([90,0,0])
cylinder(h=30,r=2,center=true);
// Rear axle
translate([20,0,0])
rotate([90,0,0])
cylinder(h=30,r=2,center=true);
|
Parameter für Teile deines Modells eingeben
[Bearbeiten]Du hast wahrscheinlich schon mitbekommen, dass ein Modell meistens nicht nur in einer einzigen Version existieren soll. Eine der großen Stärken der OpenSCAD-Skriptsprache liegt darin, es dir leicht zu machen, Modelle immer wiederzuverwenden oder einfach damit herumzuspielen, bis du mit einer endgültigen Version zufrieden bist. Zeit also, ein paar Änderungen an deinem Auto vorzunehmen!
| Ändere mal den Radius der Räder auf 10 Einheiten. Wie leicht fiel es dir, die richtigen Werte zu finden? Musstest du dieselbe Änderung viermal durchführen? |
|
car_with_larger_wheels.scad // Front left wheel
translate([-20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=10,center=true);
// Front right wheel
translate([-20,15,0])
rotate([90,0,0])
cylinder(h=3,r=10,center=true);
// Rear left wheel
translate([20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=10,center=true);
// Rear right wheel
translate([20,15,0])
rotate([90,0,0])
cylinder(h=3,r=10,center=true);
|
Obwohl es nicht besonders schwer war, die Radgröße zu ändern, hätte es noch viel einfacher sein können. Erstens wäre es hilfreich gewesen, die betreffenden Werte schneller zu finden. Zweitens hättest du nur einen Wert ändern müssen, da alle Räder denselben Radius haben. Beides lässt sich mit Variablen erreichen. Im folgenden Skript wird eine Variable für den Radradius eingeführt:
wheel_radius = 8;
// Front left wheel
translate([-20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Front right wheel
translate([-20,15,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear left wheel
translate([20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear right wheel
translate([20,15,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
|
Jede Variable besteht aus zwei Teilen: einem Namen und einem Wert. In diesem Beispiel lautet der Variablenname `wheel_radius`. Ein gültiger Variablenname darf nur alphanumerische Zeichen und Unterstriche enthalten (also A–Z, a–z, 0–9 und `_`). Nach dem Namen folgt ein Gleichheitszeichen, das den Namen vom Wert trennt, danach kommt der eigentliche Wert. Am Ende der Zeile wird ein Semikolon benötigt, um die Anweisung abzuschließen. Es hat sich bewährt, alle Variablen am Anfang deines Dokuments zu definieren, damit sie übersichtlich bleiben.
Sobald eine Variable definiert ist, kannst du sie im Code verwenden, um ihren Wert zu repräsentieren. In diesem Beispiel wurden die `cylinder`-Befehle so angepasst, dass sie für den Parameter `r` die Variable `wheel_radius` verwenden. Beim Auswerten des Skripts setzt OpenSCAD den Parameter `r` automatisch auf den Wert der Variable `wheel_radius`.
| Verwende eine Variable namens `wheel_radius`, um die Größe der Räder deines Autos festzulegen. Ändere die Radgröße ein paar Mal, indem du einfach den Wert der `wheel_radius`-Variable anpasst. Wie viel einfacher fandest du es, die Radgröße mithilfe dieser Variable zu verändern? |
|
car_with_smaller_wheels.scad $fa = 1;
$fs = 0.4;
wheel_radius = 6;
// Car body base
cube([60,20,10],center=true);
// Car body top
translate([5,0,10 - 0.001])
cube([30,20,10],center=true);
// Front left wheel
translate([-20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Front right wheel
translate([-20,15,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear left wheel
translate([20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear right wheel
translate([20,15,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Front axle
translate([-20,0,0])
rotate([90,0,0])
cylinder(h=30,r=2,center=true);
// Rear axle
translate([20,0,0])
rotate([90,0,0])
cylinder(h=30,r=2,center=true);
|
Es gibt jedoch einen wichtigen Punkt, den du zum Verhalten von Variablen in OpenSCAD beachten solltest: Variablen in OpenSCAD verhalten sich wie Konstanten. Sie können zwar mehrfach zugewiesen werden, aber beim Rendern des Modells gilt stets der letzte zugewiesene Wert – und zwar für das gesamte Modell, unabhängig davon, wo im Code die Variable verwendet wird. Was passiert also, wenn du am Anfang des Skripts einen Wert für `wheel_radius` festlegst und nach der Definition der beiden Vorderräder einen neuen Wert zuweist? Haben die Hinterräder dann eine andere Größe als die Vorderräder?
| Weise der Variable `wheel_radius` direkt nach der Definition der Vorderräder einen anderen Wert zu. Hat dein Auto nun unterschiedlich große Vorder- und Hinterräder? |
|
car_with_same_sized_wheels.scad $fa = 1;
$fs = 0.4;
wheel_radius = 6;
// Car body base
cube([60,20,10],center=true);
// Car body top
translate([5,0,10 - 0.001])
cube([30,20,10],center=true);
// Front left wheel
translate([-20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Front right wheel
translate([-20,15,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
wheel_radius = 12;
// Rear left wheel
translate([20,-15,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear right wheel
translate([20,15,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Front axle
translate([-20,0,0])
rotate([90,0,0])
cylinder(h=30,r=2,center=true);
// Rear axle
translate([20,0,0])
rotate([90,0,0])
cylinder(h=30,r=2,center=true);
|
Du wirst feststellen, dass alle Räder dieselbe Größe haben – nämlich die des zuletzt zugewiesenen Werts (`12`). Selbst die Vorderräder, die vor der zweiten Zuweisung definiert wurden, nutzen diesen letzten Wert. OpenSCAD wertet das gesamte Skript zunächst aus und verwendet dann überall den finalen Wert der Variable.
In solchen Fällen gibt OpenSCAD außerdem eine Warnung aus: WARNING: wheel_radius was assigned on line 3 but was overwritten on line 17
| Eine Variablenzuweisung innerhalb von { geschweiften Klammern } gilt nur innerhalb dieses Blocks. Mehrfache Zuweisungen auf verschiedenen Verschachtelungsebenen gelten nicht als Konflikt. |
Parameterisiere weitere Teile deines Modells
[Bearbeiten]Du kannst jetzt die Größe der Räder ganz leicht anpassen – das ist schon ziemlich praktisch! Noch besser wäre es, wenn du auch andere Aspekte deines Modells genauso einfach verändern könntest. Achte aber mal kurz darauf: Wenn du nur die Radgröße änderst, bleibt das übrige Modell davon unberührt – es „zerbricht“ nicht. Das ist leider nicht immer der Fall.
| Ändere die Höhe der Fahrzeugbasis und des Dachs, indem du zwei neue Variablen `base_height` und `top_height` definierst und die entsprechenden `cube`-Befehle anpasst. Weise `base_height` den Wert 5 und `top_height` den Wert 8 zu. Was fällt dir auf? |
|
car_with_floating_body_top.scad base_height = 5;
top_height = 8;
// Car body base
cube([60,20,base_height],center=true);
// Car body top
translate([5,0,10 - 0.001])
cube([30,20,top_height],center=true);
|
Es ist offensichtlich: Der Fahrzeugkörper wirkt nicht mehr wie ein zusammenhängendes Ganzes – Basis und Dach lösen sich voneinander. Das passiert, weil die korrekte Position des Dachs von der Höhe der Basis und der Höhe des Dachs selbst abhängt. Erinnerst du dich? Damit das Dach direkt auf der Basis sitzt, musstest du es entlang der Z-Achse um die Hälfte der Basis-Höhe plus die Hälfte der Dach-Höhe verschieben. Wenn du also die Höhen parameterisierst, musst du auch die Verschiebung des Dachs entsprechend anpassen.
| Parameterisiere die Verschiebung des Dachs entlang der Z-Achse mithilfe der Variablen `base_height` und `top_height`, sodass es stets korrekt auf der Basis aufliegt. Probiere verschiedene Werte für diese beiden Variablen aus. Bleibt die Position des Dachs dabei immer richtig? |
|
car_with_properly_attached_body_top.scad base_height = 5;
top_height = 8;
wheel_radius = 8;
// Car body base
cube([60,20,base_height],center=true);
// Car body top
translate([5,0,base_height/2+top_height/2 - 0.001])
cube([30,20,top_height],center=true);
|
|
car_with_higher_body.scad base_height = 8; top_height = 14; |
Merke dir: Immer wenn du einen Aspekt deines Modells parameterisierst, solltest du auch alle davon abhängigen Teile anpassen – sonst fällt dein Modell buchstäblich auseinander.
| Parameterisiere den Spurweitenabstand (also den Abstand zwischen linkem und rechtem Rad) mit einer neuen Variable namens `track`. Probiere verschiedene Werte für `track` aus. Fällt dir etwas auf? Hängt irgendein anderer Teil deines Modells vom Wert dieser Variable ab? Falls ja, passe diesen Teil ebenfalls mit `track` an, damit dein Modell intakt bleibt. |
|
car_with_unattached_wheels.scad track = 40;
// Front left wheel
translate([-20,-track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Front right wheel
translate([-20,track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear left wheel
translate([20,-track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear right wheel
translate([20,track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
|
|
car_with_properly_attached_wheels.scad track = 40;
// Front left wheel
translate([-20,-track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Front right wheel
translate([-20,track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear left wheel
translate([20,-track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear right wheel
translate([20,track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Front axle
translate([-20,0,0])
rotate([90,0,0])
cylinder(h=track,r=2,center=true);
// Rear axle
translate([20,0,0])
rotate([90,0,0])
cylinder(h=track,r=2,center=true);
|
Challenge
[Bearbeiten]Das folgende Skript zeigt dein Fahrzeugmodell mit bereits parameterisierten Werten für Radradius (`wheel_radius`), Basis-Höhe (`base_height`), Dach-Höhe (`top_height`) und Spurweite (`track`).
|
car_from_parameterized_script.scad $fa = 1;
$fs = 0.4;
wheel_radius = 8;
base_height = 10;
top_height = 10;
track = 30;
// Car body base
cube([60,20,base_height],center=true);
// Car body top
translate([5,0,base_height/2+top_height/2 - 0.001])
cube([30,20,top_height],center=true);
// Front left wheel
translate([-20,-track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Front right wheel
translate([-20,track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear left wheel
translate([20,-track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Rear right wheel
translate([20,track/2,0])
rotate([90,0,0])
cylinder(h=3,r=wheel_radius,center=true);
// Front axle
translate([-20,0,0])
rotate([90,0,0])
cylinder(h=track,r=2,center=true);
// Rear axle
translate([20,0,0])
rotate([90,0,0])
cylinder(h=track,r=2,center=true);
|
| Füge eine Variable `wheel_width` hinzu, um die Breite der Räder zu steuern, eine Variable `wheels_turn`, um die Drehung der Vorderräder um die Z-Achse festzulegen, und eine Variable `body_roll`, um die Neigung des Fahrzeugkörpers um die X-Achse zu definieren. Experimentiere mit verschiedenen Werten für `wheel_radius`, `base_height`, `top_height`, `track`, `wheel_width`, `wheels_turn` und `body_roll`, bis du eine Fahrzeugversion erhältst, die dir gefällt. |
|
turning_car_from_parameterized_script.scad $fa = 1;
$fs = 0.4;
wheel_radius = 10;
base_height = 10;
top_height = 14;
track = 40;
wheel_width = 10;
body_roll = -5;
wheels_turn = 20;
rotate([body_roll,0,0]) {
// Car body base
cube([60,20,base_height],center=true);
// Car body top
translate([5,0,base_height/2+top_height/2 - 0.001])
cube([30,20,top_height],center=true);
}
// Front left wheel
translate([-20,-track/2,0])
rotate([90,0,wheels_turn])
cylinder(h=wheel_width,r=wheel_radius,center=true);
// Front right wheel
translate([-20,track/2,0])
rotate([90,0,wheels_turn])
cylinder(h=wheel_width,r=wheel_radius,center=true);
// Rear left wheel
translate([20,-track/2,0])
rotate([90,0,0])
cylinder(h=wheel_width,r=wheel_radius,center=true);
// Rear right wheel
translate([20,track/2,0])
rotate([90,0,0])
cylinder(h=wheel_width,r=wheel_radius,center=true);
// Front axle
translate([-20,0,0])
rotate([90,0,0])
cylinder(h=track,r=2,center=true);
// Rear axle
translate([20,0,0])
rotate([90,0,0])
cylinder(h=track,r=2,center=true);
|
Inzwischen sollte dir klar sein: Durch das Parameterisieren deiner Modelle erschließt du die volle Kraft des Designs – du kannst deine Konstruktionen mühelos wiederverwenden, anpassen, weiterentwickeln und spielend leicht verschiedene Varianten ausprobieren.