Iteration mit OpenSCAD

OP #7390781
Lesenswert?

Hallo Foraner! Habe momentan ein Projekt mit OpenSCAD, das ein Module nach einem iterativem Muster aneinanderreiht. Also der Wert eines for() Durchlaufs hängt vom letzten Durchlauf ab. aber das funktioniert so nicht in OpenSCAD:

"for() is not an exception to the rule about variables having only one value within a scope. Each evaluation is given its own scope, allowing any variables to have unique values. No, you still can't do a=a+1;

Remember this is not an iterative language, the for() does not loop in the programmatic sense, it builds a tree of objects one branch for each item in the range/vector, inside each branch the 'variable' is a specific and separate instantiation or scope."

Ich habe die Berechnung separat mit PureBasic erstellt und getestet. Einen ersten Prototypen habe ich erstellt, indem ich die berechneten Werte cit copy/paste übertragen habe. Schön ist anders.

Was wäre die beste/sauberste Möglichkeit, das Problem zu lösen? Ich sehe gerade nur eine Möglichkeit:

Erstellen einer Datei der einzelnen Module-Aufrufe mit PureBasic und include in OpenSCAD

Danke für Ideen!

Gruss Chregu

Moderator #7390851
Lesenswert?

Christian M. schrieb:

Also der Wert eines for() Durchlaufs hängt vom letzten Durchlauf ab. aber das funktioniert so nicht in OpenSCAD:

Dann musst du den Code eben so umschreiben, dass der Wert /nicht/ vom letzten Durchlauf, sondern nur vom Wert der Laufvariable abhängt. In den allermeisten Anwendungsfällen von OpenSCAD geht das problemlos. Falls nicht, kann – wie in jeder Funktionalsprache – auch mittels Rekursion iteriert werden.

OP #7390873
Lesenswert?

Also ich beschreibe mal exakt, was ich erreichen will:

Es geht darum, Schwellenroste für die Modelleisenbahn zu erzeugen. Für einfache Bögen ist ja das kein Problem, das Modul (eine Schwelle mit den Verbindungsstummeln) wird einfach mit den trigonometrischen Funktionen Sinus und Cosinus zusammengesetzt.

Jetzt will ich noch Uebergangsradien (Klothoide). Ein Bogen ist aus 56 Elementen berechnet, wobei bei jedem Element die Hypotenuse eine fixe Länge hat. Die X- und Y-Koordinaten werden einfach addiert. Und hier ist das Problem in OpenSCAD; eine Addition aus dem alten Wert in der for-Schleife ist nicht möglich. Ich habe das PureBasic-Programm und dessen graphische Darstellung sowie das bis anhin erreichte OpenSCAD-Script angehängt.

Gruss Chregu

Edit: PS: Grundformel ist y=x^3/6C nach https://drahtkupplung.de/gtbhb2423.xhtml

#7390876
Lesenswert?

In der for-Schleife hast du doch einen Schleifenzähler, der sich mit jedem Durchlauf ändert. Reicht der nicht?

Beispiel: aus dem Schleifenzähler eine Position berechnen:

1
hoehe = 10;
2
abstand = 10;
3
groesse = 3;
4

5
for( i = [0:5] )
6
{
7
     translate([i*abstand,0,0]) cube( [groesse,groesse,hoehe] );
8
     hoehe = hoehe + 2;
9
}

In a.png sieht man, daß bei jedem Durchlauf die Position geändert wird.

In der Tat hilft es in openSCAD nicht, in der Schleife Werte zu ändern:

1
hoehe = 10;
2
abstand = 10;
3
groesse = 3;
4

5
for( i = [0:5] )
6
{
7
     translate([i*abstand,0,0]) cube( [groesse,groesse,hoehe] );
8
     hoehe = hoehe + 2;
9
}

In b.png ist die Höhe jeder Säule gleich (aber 12 statt 10).

Angehängte Dateien:
OP #7390898
Lesenswert?

Yalu X. schrieb:

dass der Wert nicht vom letzten Durchlauf, sondern nur vom Wert der Laufvariable abhängt.

Ja eben. Ich kann mir das in meinem Fall nicht mathematisch vorstellen, dafür bin ich zuwenig fit, wenn das überhaupt geht.

Yalu X. schrieb:

mittels Rekursion iteriert werden.

Etwa so:

1
module iterieren(schritt) {
2
  if (schritt < 56) {
3
    schritt = schritt + 1;
4
    echo(schritt);
5
    iterieren(schritt);
6
  }
7
}
8

9
iterieren(0);

Ja, das geht! :-))

Gruss Chregu

OP #7390932
Lesenswert?

Geschafft!

1
module iterieren(i, x1, y1, sw) {
2
  if (i < 56) {
3
    i  = i + 1;
4
    x2 = pow(i,3)/12100;    //X_neu
5
    w  = asin((x2-x1)/sw);  //Winkel
6
    y2 = cos(w)*sw+y1;      //Y_neu
7
    if ((i+2)%4==0) {       //nur #2,6,10,14...
8
      echo(i);
9
      swnr = abs((i+2)/4);  //Schwellen nummerieren 1,2,3,4...
10
      schwelle(x2,y2,-w,0,0,swnr);
11
    }
12
    iterieren(i, x2, y2, sw);
13
  }
14
}
15

16
iterieren(0, 0, 0, sw);

Vielen Dank an alle!

Gruss Chregu

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren