Ein 3d-Grid zweidimensional darstellen

CyborgBeta

Commander
Registriert
Jan. 2021
Beiträge
2.918
Die Frage ist jetzt ggf. merkwürdig, aber ich habe eine 3d Box (Würfel), die mit Gegenständen gefüllt wurde. Wie kann ich den Inhalt der Box am besten zweidimensional darstellen?

Zwei Probleme sehe ich, a) man sieht eigentlich immer nur eine Seite des Würfels und b) man sieht immer nur die äußere "Schicht".

Na ja, aber beim Globus/Landkarte funktioniert es ja auch.
 
schau mal nach affinen abbildungen / projektionen / transformationen
 
Zuletzt bearbeitet:
Evtl. so? Bastelanleitung aus dem Kindergarten...


4bc49e0e80435a68a29ba33438e58cce.jpg
 
  • Gefällt mir
Reaktionen: kuddlmuddl, BAGZZlash, BeBur und 3 andere
CyborgBeta schrieb:
Na ja, aber beim Globus/Landkarte funktioniert es ja auch.
Da geht es aber nur um die Projektion einer "ebenen" Fläche auf eine andere.

Du hast einen mit Objekten gefüllten Raum den du zweidimensional darstellen möchtest.

Aber vielleicht die Oberfläche des Würfels wie oben dargestellt und bei den Objekten im Würfel mit Semitransparenz arbeiten. Oder halt auf mehrere Ansichten verteilen, damit man jedes Objekt sieht.
 
  • Gefällt mir
Reaktionen: BeBur und CyborgBeta
CyborgBeta schrieb:
Na ja, aber beim Globus/Landkarte funktioniert es ja auch.

Aber nicht gut.
Auf Grund der Verzerrungen ist die 2D Ansicht einer Landkarte/Globus alles andere als akkurat.
 
  • Gefällt mir
Reaktionen: pcBauer, CyborgBeta und BeBur
Mal nach OpenGL oder DirectX googeln und eine 3D-Szene draus bauen mit interaktiver Kamera? Sollte überschaubarer Aufwand sein. Mit WebGL und Co sogar ziemlich simpel im Browser machbar.
 
  • Gefällt mir
Reaktionen: CyborgBeta
CyborgBeta schrieb:
a) man sieht eigentlich immer nur eine Seite des Würfels und b) man sieht immer nur die äußere "Schicht".
Wieso das denn? Du kannst den Würfel doch aus verschiedenen Perspektiven gleichzeitig darstellen bzw. mehrere Schichten nebeneinander darstellen.
 
  • Gefällt mir
Reaktionen: CyborgBeta
Danke! Dann wird es das

zeaK schrieb:
Nicht ganz dein Problem aber sollte sich nutzen lassen für das was du vor hast.

https://stackoverflow.com/questions/69663359/convert-3d-array-to-2d-array

Wurde ja bereits angesprochen den Würfel in 2D aufzuklappen, das Ganze dann eben als entsprechendes Array.

oder das

GrumpyCat schrieb:
Mal nach OpenGL oder DirectX googeln und eine 3D-Szene draus bauen mit interaktiver Kamera? Sollte überschaubarer Aufwand sein. Mit WebGL und Co sogar ziemlich simpel im Browser machbar.

werden (mit WebGL hab ich auch schon mal etwas ausprobiert).

BeBur schrieb:
Wieso das denn? Du kannst den Würfel doch aus verschiedenen Perspektiven gleichzeitig darstellen bzw. mehrere Schichten nebeneinander darstellen.

Ich vermute, dann wäre eine um 45° nach links/rechts und um 45° nach oben geneigte Sicht/Kamera wohl am besten, weil ich dann drei Seiten sehen könnte.

Wenn die Maße 5x5x5 wären, dann brauche ich glaube ich 5 Ansichten, quasi wie Salamischeiben. ;)

Aber einige Objekte in der Box sind länglich und hochkant (zum Beispiel 4x1x1) und wenn ich die "zerschneide", dann kann ich das Objekt nicht mehr erkennen.

Hmm, vielleicht einige Objekte dann transparent machen?
 
CyborgBeta schrieb:
Die Frage ist jetzt ggf. merkwürdig, aber ich habe eine 3d Box (Würfel), die mit Gegenständen gefüllt wurde. Wie kann ich den Inhalt der Box am besten zweidimensional darstellen?

Zwei Probleme sehe ich, a) man sieht eigentlich immer nur eine Seite des Würfels und b) man sieht immer nur die äußere "Schicht".
Schneide den Würfel auf oder mache die Wände halbdurchsichtig:

so ist die Vorderfläche undurchsichtig:
Wuerfel 3D.jpg
.

Nimmt man die graubraune Vorderseite ab, sieht das so aus:

Wuerfel 3D vorne offen.jpg
.

Mit teilweise transparenten Ober- und Vorderfläche so:

Würfel 3D transparent.jpg
.

Mit aufgeschnittenen Kanten könnte das so aussehen:

Würfel aufgeschnitten.jpg
.

Erstellt mit Paintshop Pro 7.
 
  • Gefällt mir
Reaktionen: CyborgBeta
Ich denke einmal kommt es darauf an, ob das ganze a) statisch b) animiert oder c) interaktiv sein soll. Und dann kommt es noch darauf, was genau (z.B. wie viel) da drin ist. Eine gute allgemeine Lösung die statisch oder animiert ist wird es vermutlich nicht geben.
 
Also, zurzeit habe ich so etwas:

Code:
candidates      = [[2, 2, 3], [1, 2, 4], [1, 1, 1]]
available       = [0, 0, 1]
isSolved        = true
solution        =
[[13, 6, 6, 6, 6], [7, 6, 6, 6, 6], [7, 0, 0, 1, 1], [7, 0, 0, 1, 1], [7, 0, 0, 8, 8]]
[[9, 9, 2, 2, 2], [7, 14, 2, 2, 2], [7, 0, 0, 1, 1], [7, 0, 0, 1, 1], [7, 0, 0, 8, 8]]
[[9, 9, 2, 2, 2], [3, 3, 2, 2, 2], [3, 3, 12, 1, 1], [4, 4, 4, 1, 1], [4, 4, 4, 8, 8]]
[[9, 9, 5, 5, 10], [3, 3, 5, 5, 10], [3, 3, 5, 5, 10], [4, 4, 4, 15, 10], [4, 4, 4, 8, 8]]
[[9, 9, 5, 5, 10], [3, 3, 5, 5, 10], [3, 3, 5, 5, 10], [11, 11, 11, 11, 10], [11, 11, 11, 11, 16]]

Und das sieht zwar aus wie Lottozahlen, aber darunter kann sich doch keiner etwas vorstellen...

Btw. 0 bis 5 ist 1. (also Objekt 2x2x3), 6 bis 11 ist 2. und 12 bis 16 ist 3.
 
Solche 3D-Arrays kann man relativ elegant mit Volumenrendering darstellen. Sieht dann in etwa so aus:
https://www.radiantviewer.com/dicom..._dicom_viewer_3d_volume_rendering_example.png

Dabei kann man in einer Implementierung auch die Farbe und die Transparenz in Abhängigkeit von dem Roh-Wert des Voxels in den Volumendaten frei wählen. Typischerweise macht man dieses Rendering auf der GPU mit einer einfachen 3D-Textur. Wenn man länger sucht, findet man bestimmt freie Software, die das kann....
 
  • Gefällt mir
Reaktionen: CyborgBeta
Danke. Hab eine mögliche Darstellungsform gefunden:

Ein dreidimensionales Würfel-Drahtgitter mit Halbtransparenz.

So sieht es zurzeit aus (denke, man kann die einzelnen Objekte erkennen):

1700413266007.png


Ich hab dazu einfach in Java 3d auf auf ein Canvas gezeichnet. Dazu hab ich den Code von:

https://stackoverflow.com/questions/69263406/rendering-3d-objects-on-2d-canvas-using-java-awt und https://www.mamboleoo.be/articles/how-to-render-3d-in-2d-canvas (siehe besonders "Rendering 3D volumes ")

adaptiert.

Java:
import javax.swing.*;
import java.awt.*;

public class Render {
    record vec3d(float x, float y, float z) {
        public vec2d project(final float FIELD_OF_VIEW, final float PROJECTION_CENTER_X, final float PROJECTION_CENTER_Y) {
            float scaleProjected = FIELD_OF_VIEW / (FIELD_OF_VIEW + z);
            float xProjected = (x * scaleProjected) + PROJECTION_CENTER_X;
            float yProjected = (y * scaleProjected) + PROJECTION_CENTER_Y;
            return new vec2d(xProjected, yProjected);
        }
    }

    record vec2d(float x, float y) {
    }

    private static Color getColor(final int index, final int level) {
        float a = (level + 1) / 5f;
        return switch (index) {
            case 0 -> new Color(1f, 0f, 0f, a);
            case 1 -> new Color(1f, 1f, 0f, a);
            case 2 -> new Color(0f, 0f, 1f, a);
            default -> null;
        };
    }

    public Render(final int[][][] solution, final int maxCandidates) {
        int widthAndHeight = 800;

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(widthAndHeight, widthAndHeight);

        frame.add(new Canvas() {
            @Override
            public void paint(Graphics g) {
                g.setColor(Color.BLACK);
                g.fillRect(0, 0, this.getWidth(), this.getHeight());

                int len = 95;
                for (int i = 0; i < 5; i++) {
                    for (int j = 0; j < 5; j++) {
                        for (int k = 0; k < 5; k++) {
                            int x = k * len;
                            int y = j * len;
                            int z = i * len;
                            float centerX = (x + len) / 2f;
                            float centerY = (y + len) / 2f;
                            vec2d v1 = new vec3d(x, y, z).project((float) widthAndHeight, centerX, centerY);
                            vec2d v2 = new vec3d(x + len - 1, y, z).project((float) widthAndHeight, centerX, centerY);
                            vec2d v3 = new vec3d(x + len - 1, y + len - 1, z).project((float) widthAndHeight, centerX, centerY);
                            vec2d v4 = new vec3d(x, y + len - 1, z).project((float) widthAndHeight, centerX, centerY);
                            Color color = getColor(solution[i][j][k] / maxCandidates, i);
                            g.setColor(color);
                            g.drawLine((int) v1.x, (int) v1.y, (int) v2.x, (int) v2.y);
                            g.drawLine((int) v2.x, (int) v2.y, (int) v3.x, (int) v3.y);
                            g.drawLine((int) v3.x, (int) v3.y, (int) v4.x, (int) v4.y);
                            g.drawLine((int) v4.x, (int) v4.y, (int) v1.x, (int) v1.y);
                        }
                    }
                }
            }
        });

        frame.setVisible(true);
    }

    public static void main(final String[] args) {
        new Render(new int[][][]{
                {{13, 6, 6, 6, 6}, {7, 6, 6, 6, 6}, {7, 0, 0, 1, 1}, {7, 0, 0, 1, 1}, {7, 0, 0, 8, 8}},
                {{9, 9, 2, 2, 2}, {7, 14, 2, 2, 2}, {7, 0, 0, 1, 1}, {7, 0, 0, 1, 1}, {7, 0, 0, 8, 8}},
                {{9, 9, 2, 2, 2}, {3, 3, 2, 2, 2}, {3, 3, 12, 1, 1}, {4, 4, 4, 1, 1}, {4, 4, 4, 8, 8}},
                {{9, 9, 5, 5, 10}, {3, 3, 5, 5, 10}, {3, 3, 5, 5, 10}, {4, 4, 4, 15, 10}, {4, 4, 4, 8, 8}},
                {{9, 9, 5, 5, 10}, {3, 3, 5, 5, 10}, {3, 3, 5, 5, 10}, {11, 11, 11, 11, 10}, {11, 11, 11, 11, 16}},
        }, 6);
    }
}
 
Ich zumindest erkenne da rein garnichts, abgesehen von nem Haufen Quadrate. Wie das ein Würfel sein soll oder gar ein Würfel gefüllt mit Zeug (anderen Würfeln?) erschließt sich mir nicht.
 
Das ist nicht schlimm, ich erwarte von keinem ein Thema vollständig zu lesen.

Aber vielleicht ist es so besser zu erkennen:

1700416803394.png

Ergänzung ()

@BeBur Das sind doch einfach nur 5 Schichten/Querschnitte eines Würfels, die auseinandergezogen wurden und teilweise transparent, damit man noch etwas erkennen kann. Blau ist dabei zum Beispiel einfach ein 1x1x1x-Objekt usw.
 
Zuletzt bearbeitet:
CyborgBeta schrieb:
Das ist nicht schlimm, ich erwarte von keinem ein Thema vollständig zu lesen.
Na ja, diese Lösung hat fast gar nichts mit der Ausgangsfrage zu tun:
Die Frage ist jetzt ggf. merkwürdig, aber ich habe eine 3d Box (Würfel), die mit Gegenständen gefüllt wurde. Wie kann ich den Inhalt der Box am besten zweidimensional darstellen?
Ich erkenne da weder auch nur ansatzweise einen Würfel, noch eingefüllte Gegenstände. :(
 
  • Gefällt mir
Reaktionen: BeBur
Na gut, dann erkläre ich es noch einmal anders.

Es gibt folgende Quader: [2, 2, 3], [1, 2, 4], [1, 1, 1] (von jedem gibt es jeweils 6-mal)

Diese Quader sollen, ohne dass es eine Lücke gibt, in einer 5x5x5 Box/Kiste/Kasten/Truhe positioniert werden.

Dafür wäre die Abbildung oben eine mögliche Lösung, bei der Blau ein 1x1x1, Gelb ein 1x2x4 und Rot ein 2x2x3 Objekt darstellen soll.

Auf Rot und Grün zusammen habe ich verzichtet, da es schwerer zu erkennen.

Man schaut quasi von oben und von der linken unteren Seite auf diesen Quader.
 
CyborgBeta schrieb:
Na gut, dann erkläre ich es noch einmal anders.
Was heißt da noch einmal? Es ist ja nicht so, als hättest du das in diesem Thread bereits mehr als null mal erklärt.

Ganz konkret: Für einen solchen Würfel aus mit Kantenlänge fünf aus Einzelwürfeln würde ich einfach ein Bild mit den Fünf Schichten nebeneinander und Beschriftung der Schichten wählen. Statisch, einfach, übersichtlich.

Wenn es größer wird, bietet sich bspw ein Slider an, mit dem man durch die Schichten läuft, oder auch eine Animation, die das automatisch tut.

Oder natürlich einfach als drehbare 3D-Szene mit Transparenz anzeigen. (Auch die wird, wie eine digitale Landkarte, auf einem zweidimensionalen Monitor angezeigt, entspricht also der Fragestellung.)
 
  • Gefällt mir
Reaktionen: BeBur
Zurück
Oben