pointsandfaces – einige Interna

Gehen wir nochmal zurück zu unserem ersten Beispiel und werfen einen Blick hinter die Kulissen. Um zu sehen, was wir eigentlich bekommen haben, drücken wir <Strg>+1, um die Kanten, die die Dreiecke bilden, die die Oberfläche des Objektes formen, sichtbar zu machen, verringern den Wert von fn auf 6, setzen als Höhe 10 ein, machen eine dickere Wand, setzen vor das polyhydron()-Statement ein “%”, fügen ein echo()-Statement ein, um die Felder auszugeben, fügen einen Aufruf von PnfDebugPoints() (zu finden in pnf_littlehelpers.scad) ein, um die Positionen der Punkte zu zeigen, und drücken <F5>, um uns das Ergebnis anzuschauen.

use <inc/pnf/pnf_cylinder.scad>
use <inc/pnf/pnf_littlehelpers.scad>
fn = 6;
outer_radius = 30;
wall_thickness = 8;
height = 10;

v = pnf_tube_pnf_v(r = outer_radius, h = height, wt = wall_thickness, nz = 1, fn = fn);
%polyhedron(v[0], v[1], 4);
PnfDebugPoints(v[0],true)
echo(v);

Ich habe die Ausgabe des echo()-Statements etwas formatiert und ein paar Werte gerundet, um sie leserlicher zu machen:

Punkte:

Unterer äußerer Ring:
[30, 0, 0], [15, 26, 0], [-15, 26, 0], [-30, 0, 0], [-15, -26, 0], [15, -26, 0]
Oberer äußerer Ring:
[30, 0, 10], [15, 26, 10], [-15, 26, 10], [-30, 0, 10], [-15, -26, 10], [15, -26, 10]
Oberer innerer Ring: 
[26, 0, 10], [13, 22.5, 10], [-13, 22.5, 10], [-26, 0, 10], [-13, -22.5, 10], [13, -22.5, 10]
Unterer innerer Ring: 
[26, 0, 0], [13, 22.5, 0], [-13, 22.5, 0], [-26, 0, 0], [-13, -22.5, 0], [13, -22.5, 0]

Faces:

[ 0,  6,  7], [ 1,  7,  8], [ 2,  8,  9], [ 3,  9, 10], [ 4, 10, 11], [ 5, 11,  6],
[ 0,  7,  1], [ 1,  8,  2], [ 2,  9,  3], [ 3, 10,  4], [ 4, 11,  5], [ 5,  6,  0],
[ 6, 12, 13], [ 7, 13, 14], [ 8, 14, 15], [ 9, 15, 16], [10, 16, 17], [11, 17, 12],
[ 6, 13,  7], [ 7, 14,  8], [ 8, 15,  9], [ 9, 16, 10], [10, 17, 11], [11, 12,  6],
[12, 18, 19], [13, 19, 20], [14, 20, 21], [15, 21, 22], [16, 22, 23], [17, 23, 18],
[12, 19, 13], [13, 20, 14], [14, 21, 15], [15, 22, 16], [16, 23, 17], [17, 18, 12],
[18,  0,  1], [19,  1,  2], [20,  2,  3], [21,  3,  4], [22,  4,  5], [23,  5,  0],
[18,  1, 19], [19,  2, 20], [20,  3, 21], [21,  4, 22], [22,  5, 23], [23,  0, 18]

Und das ist, was wir sehen. Beachte die Reihenfolge der Punkte. Sie werden durch die Werte im Faces-Feld indiziert. Das erste Dreieck ist (0,6,7), und wenn wir diese Punkte im Bild unten nachschauen, sehen wir, dass sie ein Dreieck auf der Oberfläche des Objektes beschreiben. Beachte die Reihenfolge der Punkte dieses Dreiecks. Sie ist, gesehen von der Außenseite des Objekts, im Uhrzeigersinn. Diese Reihenfolge definiert, wo die Außenseite ist. Also achte auf sie! Das zweite Dreieck ist (1,7,8). Wenn Du es identifizierst, stellst Du fest, dass es nicht (0,7,1) ist was der Nachbar wäre und diese Seite des Objektes vervollständigen würde. Die Reihenfolge, in der die Faces im Faces-Feld erscheinen, ist nicht relevant, so dass in jeder Reihe die links-oben-Dreiecke zuerst kommen, und dann die rechts-unten Dreiecke. Das Schema der Nummerierung sieht einfach aus. Jeder Kreis von Punkten hat 6 Elemente, und das ist die Differenz im Index zwischen dem ersten und zweiten Punkt im linken oberen Dreieck. Die Differenz zwischen dem Indes des zweiten und dritten Punktes ist normalerweise 1, außer für das letzte Face in der Reihe, denn hier schließt es die Reihe und verbindet sich mit dem Anfang. Die Regel dafür ist auch einfach. Wenn eine Reihe von Dreiecken sich mit ihrem Anfang verbindet, muss der Index des rechtesten Punktes der Index des ersten Punktes sein. Das Schema für die rechts-unten Dreiecke folgt dem selben Prinzip.

Jede Reihe folgt diesem Schema. Nun macht es Sinn, dass die äußeren Punkte von unten nach oben, und die inneren Punkte von oben nach unten gehen. Anstatt die Außenwand, die Innenwand, und die beiden Ränder oben und unten separat zu handhaben, können wir ein Schema für alle Faces des Rohrs verwenden. Die einzige Ausnahme ist der untere Rand, der die letzte Reihe von Punkten mit der ersten Reihe verbindet, aber diese Ausnahme zu handhaben ist so einfach, wie Reihen zu schließen. In Anbetracht dieses Aspektes ist es einfacher, ein Rohr zu konstruieren, als einen Zylinder!

Ich empfehle einen Blick auf die Funktion  pnf_row_of_faces_v() in pnf.scad, die die Kernroutine zum Verbinden zweier Punktreihen darstellt.

Nahezu ebenso einfach zu verstehen, zumindest was die Komplexität des Aufbaus des Faces-Feldes angeht, ist das nächste Beispiel