OpenSCAD - tworzenie własnych funkcji

Autor podstrony: Krzysztof Zajączkowski

Stronę tą wyświetlono już: 1878 razy

Funkcje w OpenSCAD-ie umożliwiają przeprowadzanie obliczeń i zwracanie ich wyników czy to w postaci liczby czy też wektora liczb. Dla przykładu utworzę funkcję, która obliczy punkty krzywej parametrycznej Béziera na podstawie podanych:

Krzywa Béziera
Rys. 1
Krzywa Béziera z oznaczonymi punktami kontrolnymi (na czerwono)

Krzywą Béziera opisuje następujący wzór:

Wzór opisujący krzywą Béziera [1]

Zapis wyrażenia w formacie TeX-a:

\vec{P(t)} = \vec{P_1}\cdot (1-t)^3 + 3\cdot \vec{P_{s1}}\cdot t\cdot (1-t)^2 + 3\cdot \vec{P_{s2}}\cdot t^2\cdot (1-t) + P_3\cdot t^3

gdzie:

Implementacja funkcji w dwóch wersjach wygląda następująco:

function bezierLine(p1, pc, p2) = [for(t = [0: 0.01: 1.01]) p1 * (1 - t) * (1 - t) * (1 - t) + 3 * pc * t * (1 - t) * (1 - t) + 3 * pc * t * t * (1 - t) + p2 * t * t * t]; function bezierLine4(p1, pc1, pc2, p2) = [for(t = [0: 0.01: 1.01]) p1 * (1 - t) * (1 - t) * (1 - t) + 3 * pc1 * t * (1 - t) * (1 - t) + 3 * pc2 * t * t * (1 - t) + p2 * t * t * t];

Pierwsza funkcja bezierLine upraszcza wzór [1] do postaci, gdzie Ps1 = Ps2. Jak widać funkcje w OpenSCAD-ie są dość dziwaczną konstrukcją. OpenSCAD poprawnie obsługuje operatory matematyczne na wektorach, więc jako parametry powyższych funkcji powinny zostać podane punkty 2W. Przykład wykorzystania jednej z powyższych funkcji pokazany został poniżej.

OpenSCAD - przykład wykorzystania praktycznego własnej funkcji do wygenerowania bryły obrotowej
Rys. 2

OpenSCAD - przykład wykorzystania praktycznego własnej bezierLine do wygenerowania bryły obrotowej

function bezierLine(p1, pc, p2) = [for(t = [0: 0.01: 1.01]) p1 * (1 - t) * (1 - t) * (1 - t) + 3 * pc * t * (1 - t) * (1 - t) + 3 * pc * t * t * (1 - t) + p2 * t * t * t]; difference(){ rotate_extrude(angle = 360, convexity = 2, $fn = 100) polygon(bezierLine([0, 0], [45, 45], [90, 0])); rotate_extrude(angle=360, convexity = 2, $fn = 100) polygon(bezierLine([10, -1], [35, 35], [85, -1])); }