Zeichnen Sie eine Kugel mit 3D-Pixel (Voxel-Sculpting -)
Können Sie vorschlagen, ein Algorithmus, der zeichnen kann, der eine Kugel im 3D-Raum mit nur die grundlegenden plot(x,y,z)
primitiv (was zeichnet ein einzelnes voxel)?
Ich hatte gehofft, für etwas ähnliches wie Bresenham-Kreis-Algorithmus, aber für 3D statt 2D.
Zur info, ich arbeite an einer hardware-Projekt ist ein low-res-3D-display mit einem 3-dimensionalen matrix von LEDs, so muss ich eigentlich ziehen eine Sphäre, die nicht nur eine 2D-Projektion (d.h. Kreis).
Das Projekt ist sehr ähnlich wie diese:
... oder sehen Sie es in Aktion hier.
Eine Möglichkeit, die ich im Sinn habe, ist dies:
- berechnen der Y-Koordinaten der Pole (den radius) (für eine Kugel zentriert im Ursprung, diese wäre
-r
und+r
) - schneiden Sie die Kugel: für jede horizontale Ebene
p
i - zwischen diesen Koordinaten berechnen Sie den radius des Kreises, die durch sich schneidende, sagte Flugzeug mit dem Bereich =>r
i. - zeichnen die tatsächliche Kreis der radius
r
i auf Ebenep
i mit Bresenham ' s Algorithmus.
FWIW, ich bin mit einem .NET-micro-framework-Mikroprozessor, so ist die Programmierung in C#, aber ich muss nicht Antworten werden in C#.
- Die Beurteilung durch die LED-Kugel sollten wir davon ausgehen, müssen Sie das innere der Kugel gezeichnet als auch irgendwie?
- Ich denke nicht so. In diesem Fall würde er nicht darüber reden Bresenham-Kreis Rasterung und konnte einfach japreiss' brute-force-Lösung.
- Eigentlich hätte ich gerne beide Optionen.
- In diesem Fall, ich schlage vor, mit der brute-force-Algorithmus zum generieren der solid-version, und verwenden Sie dann eine morphologische operation, um die Oberfläche.
Solid - Erode(Solid)
sollte den trick tun. - Ich bin mir nicht sicher, aber vielleicht habe ich Ihre Frage beantwortet mit einem Bresenham-wie Kugel-Algorithmus hier: stackoverflow.com/questions/9683965/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die einfache, brute-force-Methode ist eine Schleife über alle voxel im Gitter, und berechnen Sie dessen Abstand von der Sphäre center. Dann die Farbe der voxel, wenn deren Distanz kleiner ist als die sphere-radius. Sie können sparen eine Menge von Anweisungen, die durch den Wegfall der Wurzel und vergleichen Sie das Skalarprodukt, um den radius zum Quadrat.
Ziemlich weit von optimal, sicher. Aber auf einem 8x8x8 raster angezeigt, müssen Sie diese operation 512 mal pro Kugel. Wenn die Sphäre center ist auf dem Gitter und der radius ist ein integer, brauchen Sie nur integer-math. Das Skalarprodukt wird mit 3 multipliziert und die 2 adds. Multipliziert langsam sind, lassen Sie sagen, Sie nehmen 4 Hinweise jedes. Plus benötigen Sie ein Vergleich. Fügen Sie in das lädt und speichert, sagen wir, es kostet 20 Instruktionen pro voxel. Das ist 10240 Anweisungen pro Kugel.
Einem Arduino läuft mit 16 MHz schieben könnte 1562 Kugeln pro Sekunde. Es sei denn, Sie tun eine Menge anderer Mathematik-und I/O-dieser Algorithmus sollte gut genug sein.
Ich glaube nicht, dass das ausführen der midpoint circle Algorithmus auf jeder Ebene, werden Sie die gewünschten Ergebnisse, wenn Sie erreichen die Polen, wie Sie haben Lücken in der Oberfläche, wo die LEDs nicht Leuchten. Dies kann das Ergebnis, die Sie wollen, jedoch so, dass wäre bis zur ästhetik. Dieser Beitrag ist auf der Basis der Mittelpunkt-Kreis-Algorithmus, um zu bestimmen, den radius der Schichten in der Mitte durch zwei senkrechte oktanten, und dann bei der Zeichnung der einzelnen Kreise, auch die Punkte für die polar-oktanten.
Ich denke, basierend auf dem @Nick Udall ' s Kommentar und Antwort hier verwenden des Kreis-Algorithmus, um zu bestimmen, den radius Ihrer horizontalen Scheibe wird die Arbeit mit einer Modifikation, die ich vorgeschlagen, in einem Kommentar auf seine Antwort. Der Kreis-Algorithmus geändert werden sollte, um nehmen als Eingabe einen ersten Fehler und zeichnen auch die zusätzlichen Punkte für die polar-oktanten.
y0 + y1
undy0 - y1
:x0 +/- x, z0 +/- z, y0 +/- y1
,x0 +/- z, z0 +/- x, y0 +/- y1
, insgesamt 16 Punkte. Dies bildet den Hauptteil der vertikalen Sphäre.x0 +/- y1, z0 +/- x, y0 +/- z
undx0 +/- x, z0 +/- y1, y0 +/- z
, insgesamt 16 Punkte, die form der Polkappen für die Kugel.Indem die äußeren Algorithmus-Fehler in der Kreis-Algorithmus, der es erlaubt, die für die sub-voxel-Anpassung der beiden Ebenen Kreis. Ohne die Fehler in den inneren Algorithmus, der äquator des Kreises angenähert werden, um einen Zylinder, und jede Sphäre angenähert Gesicht auf der x -, y-und z-Achsen bilden ein Quadrat. Mit der Fehler enthalten, jedes Gesicht gegeben, einen ausreichend großen radius angenähert werden als mit einem gefüllten Kreis.
Dem folgenden code wird geändert von Wikipedia Midpoint circle Algorithmus. Die
DrawCircle
Algorithmus hat die Nomenklatur geändert, um den Betrieb in der xz-Ebene, neben der Dritten Ausgangspunkty0
, das y-offsety1
, und anfängliche Fehlererror0
.DrawSphere
wurde geändert von derselben Funktion nehmen Sie die Dritte Ausgangspunkty0
und fordertDrawCircle
eher alsDrawPixel
Für eine Kugel mit radius 4 (die eigentlich erfordert 9x9x9), würde dies führen Sie drei Iterationen der
DrawCircle
routine, mit der ersten Zeichnung einer typischen radius: 4 Lochkreis (in drei Schritten), die zweite Zeichnung einen radius von 4 Kreis mit dem ersten Fehler von 0 (drei Schritte), und dann die Dritte Zeichnung einen Kreis mit radius 3 ersten Fehler 0 (drei Schritte). Dass am Ende neun Punkte berechnet, Zeichnung 32 Pixel jedes.Das macht 32 (Punkte pro Kreis) x 3 (addieren oder subtrahieren Operationen pro Punkt) + 6 (addition, Subtraktion, shift-Operationen pro iteration) = 102 addieren, subtrahieren, oder shift-Operationen pro Punkt berechnet. In diesem Beispiel, dass die 3 Punkte für jeden Kreis = 306 Vorgänge pro Schicht. Der radius-Algorithmus fügt auch 6 Vorgänge pro Schicht und 3-mal iteriert, so
306 + 6 * 3 = 936
Grundrechenarten für das Beispiel wird ein radius von 4.Die Kosten hier ist, dass Sie immer wieder einige Pixel ohne die zusätzliche Bedingung prüft (d.h. x = 0, y = 0 oder z = 0), so dass, wenn Sie Ihre I/O ist langsam, Sie können es besser das hinzufügen der Bedingung überprüft. Vorausgesetzt, alle LEDs wurden geräumt an den start, das Beispiel Kreis setzen würden, 288 LEDs, während es viele weniger LED, die eigentlich leuchtet, durch wiederholen Sie die Sätze.
Es sieht aus wie wäre dies besser als der bruteforce-Methode für alle Lebensbereiche, die passen würde in der 8x8x8-raster, sondern die bruteforce-Methode müsste konsistente timing unabhängig von radius, während diese Methode verlangsamt beim zeichnen großen radius Sphären, wo nur ein Teil angezeigt. Da das display cube erhöht in der Auflösung, aber diese timing-Algorithmus wird konsistent bleiben, während bruteforce erhöhen.
Vorausgesetzt, dass Sie bereits ein Grundstück haben, funktionieren wie Sie sagte:
Dass, sollte die Funktion plot eine Kugel im Ursprung mit der angegebenen Breite und Länge-Auflösung (Beurteilung durch den Würfel, die Sie wahrscheinlich wollen etwas um die 40 oder 50 als eine grobe Schätzung). Dieser Algorithmus nicht "füllen" die Kugel, obwohl, so wird es nur eine Gliederung, sondern spielen mit der radius sollte lassen Sie Sie füllen das innere, wahrscheinlich mit Abnehmender Auflösung des lats und sehnt sich auf dem Weg.
Gerade ein altes q&eine über die Sphäre Mesh, aber die top-Antwort tatsächlich gibt Sie ein kurzes Stück pseudo-code zu generieren, Ihre X -, Y-und Z :
(x, y, z) = (sin(Pi * m/M) cos(2Pi * n/N), sin(Pi * m/M) sin(2Pi * n/N), cos(Pi * m/M))
Überprüfen Sie dieses Q&A für details 🙂
prozedural erzeugen eine Sphäre mesh