Problem beim Zeichnen mehrerer Layer



  • Hallo,

    ich bastel gerade an einem kleinen Spielprogramm, mit dem ich Teile für Brettspiele erzeugen kann. Ein Teil (Tile) ist ein Sechseck, das zwei Seiten über eine Linie verbindet, und weil es schön sein soll, sollen die Linien einen Rahmen haben. Diese Linien stellen Verbindungen dar, die sich kreuzen können oder Brücken, wobei eine Verbindung unter der anderen verläuft. Meine Idee war, Verbindungen, die sich nicht kreuzen, als eigene Layer zu zeichnen. Dazu zeichne ich zuerst den Rahmen (zB. mit Pen Width 60) und anschließend den Kern (mit Penwidth 54), damit habe ich 3 Einheiten Rahmen um den Kern gezeichnet. Das funktioniert so lange, wie beide Layer wirklich getrennt sind. Jetzt gibt´s aber noch komplexere Tiles, wo die Layer an einer Stelle getrennt sind und an einer anderen aber eine Verbindung haben.
    Und da, wo beide Layer verbunden sind, funktioniert mein Ansatz nicht mehr, weil Rahmenteile des weiter oben liegenden Layers Verbindungen trennen, die eigentlich zusammengehören.
    Und weil ein Bild mehr sagt als tausend Worte: Veranschaulichung.
    Hat da jemand eine Idee, wie man sowas hinbekommt?

    Das Tile wird durch eine XML Dokument beschrieben, das ein Parser in seine Bestandteile zerlegt und daraus Tile Elemente erzeugt. Beim dem Tile im Beispiel gibt es drei Elemente (Pseudocode):

    <track>
       <segment type="Straight" start="north" end="south" Layer="0"/>
       <segment type="NarrowCurve" start="south" end="southwest" Layer="0"/>
       <segment type="Straight" start="southwest" end="northeast" Layer="1"/>
    </track>
    

    Nach diesem Schema sollen einige zig-Tiles beschrieben werden.
    Ich hoffe, ihr versteht, was ich meine 😉



  • Das scheint mir zwar fast zu trivial, aber vielleicht hilft es dem Verständnis:
    Erst alle Rahmen zeichnen und erst dann die Inhalte?



  • Das Problem hier ist dass die grafische Überschneidung nur manchmal eine logische Überschneidung ist. Nämlich dann wenn sie an den "Anschlussstellen" an den Rändern passiert. Weil die Verbindungen sich dort einen Anschluss "teilen", d.h. wenn zwei Verbindungen von der selben Anschlusstelle in unterschiedliche Richtungen weggehen, dann gibt's dort eine Abzweigung. Nicht aber in der Mitte. Wenn dort zwei Verbindungen sich kreutzen, dann ist dort wenn ich das richtig verstehe keine Kreutzung erwünscht, sondern eine
    Verbindungen die "über" die andere geht, ohne dass man abbiegen könnte.

    Ich fürchte das wird so einfach nicht zu lösen sein.

    Das einzige was mir einfällt wäre jedes Tile in 2 Bereiche aufzusplitten: einen runden in der Mitte und den äusseren Bereich. Dann kann man für beide Bereiche die Layer unterschiedliche sortieren. Ist aber schon ein Hack, und funktioniert natürlich nur so lange wie die Regel "in der Mitte gibt es keine Kreuzungen" hält.



  • @Jockelx
    Ne, das funktioniert leider nicht, denn wenn ich erst alle Rahmen zeichne und dann die Strecken würden sich im verlinkten Beispiel die Strecken in der Mitte kreuzen.
    Siehe obere Reihe

    @hustbaer
    Auch das ist nicht so einfach, in dem Beispiel ist die Kreuzung in der Mitte. Gibt nochn Haufen anderer Tiles, wo Kreuzungen irgendwo sind. Siehe Bild oben, untere Reihe.

    Hatte gehofft, dass ich einfach nur zu doof bin und irgendwer sagt : "Du bist doch doof, das geht so:" 😉



  • Nicht doch. Du bist doch nicht doof.



  • Nicht sicher, ob das allgemeingültig geht. Aber in dem Beispiel kommt es doch tatsächlich nur auf die Reihenfolge an.

    Du hast dich jetzt entschieden so zu zeichnen: Rahmen, Rahmen, Kern, Kern, Rahmen, Rahmen

    Wenn du unter Beibehaltung der selben Teile stattdessen macht: Rahmen, Rahmen, Kern, Rahmen, Rahmen, Kern, Kern

    sollte das richtige Teil rauskommen, oder nicht?

    (Also: Rahmen senkrechte Linie, Rahmen kurve, Kern senkrechte Linie, Rahmen schräge Linie, Kern von den beiden verbliebenen in beliebiger Reihenfolge)

    Instinktiv würde ich aber vermuten, dass man nicht immer eine Reihenfolge findet bei der es zu keinen Problemen kommt.

    Edit: Ggf. musss man auch Schritte mehrmals ausführen, um die "Abhängigkeiten" richtig hinzukriegen. Könnte mir vorstellen, dass man dafür einen Algo entwickeln kann ... man müsste das halt mal mit mehr Beispielen durchtesten



  • @DocShoe sagte in Problem beim Zeichnen mehrerer Layer:

    @hustbaer
    Auch das ist nicht so einfach, in dem Beispiel ist die Kreuzung in der Mitte. Gibt nochn Haufen anderer Tiles, wo Kreuzungen irgendwo sind. Siehe Bild oben, untere Reihe.

    Hatte gehofft, dass ich einfach nur zu doof bin und irgendwer sagt : "Du bist doch doof, das geht so:" 😉

    Öh.
    Wie hättest du dir vorgestellt dass das einfach gehen hätte sollen?
    Ich meine, das kann nicht einfach gehen.
    Also nicht mit den ganzen Fällen die du in https://ibb.co/9HbcZXR zeigst.



  • Wäre es evtl. besser, zunächst keine Abgrenzungen zu zeichnen und dies erst später mit einem Floodfill zu machen, der die Grenzen mitzeichnet?
    Diese Punkte könnten gespeichert werden und anschließend mit einem Weichzeichner bearbeitet werden.
    Das würde dann so aussehen (der Einfachheit halber jetzt natürlich auf das komplette Bild):
    https://i.imgur.com/ZPBfIDP.png



  • @yahendrik Also wie ich das verstanden habe...
    Er will ja an manchen Stellen die Ränder, weil halt nicht alle Überschneidungen auch Kreuzungen/Abzweigungen sind im Sinn dass man die Strasse wechseln könnte. Dort wo man "abbiegen" kann soll kein Rand sein, wo man nicht abbiegen kann soll ein Rand sein.



  • @hustbaer
    Genau, bis auf die Tatsache, dass die Straßen Gleise sind 😉

    Im Grunde gibt es drei verschiedene Segmenttypen: Gerade, weite Kurve und enge Kurve. Dabei können drei unterschiedliche Kreuzungstypen auftreten: Gerade-Gerade (1 Kombination, immer Zentrum), Gerade-weite Kurve (6 Kombinationen) und Weite Kurve-Weite Kurve (6 Kombinationen). Ich muss wahrscheinlich alle Segment parsen und gucken, ob und wo sie sich kreuzen. Wenn es Kreuzungen gibt (Überschneidung auf unterschiedlichen Layern) muss ich die einzelnen Kreuzungsbereiche neu zeichnen. Dann könnte ich tatsächlich erst alle Rahmen zeichnen, dann die Strecken und zum Schluss die Kreuzungen. Werd´ das über die Feiertage mal umsetzen.

    Danke an alle für die Anregungen.



  • Wäre es nicht einfach einfacher nicht in Layern zu zeichnen und am Ende dann noch die Brücken drauf? Dann könnte man (optional) für die Brücke auch noch ein spezielle Grafik einführen, damit sich das nicht nur durch eine schmale weiße Linien unterscheidet. Wenn das nicht geht, würde ich die einzelnen Segmente nochmal unterteilen, z.B. die Gerade über das Sechseck in Anfang, Mitte, Ende. So das man für jedes Stück einzeln entscheiden kann, ob es im selber Layer wie eine anderes Segment ist oder darüber. Aktuell kann man so eine Reihenfolge ja gar nicht festlegen für solche Sonderfälle wie man auf https://ibb.co/9HbcZXR in der unteren Reihe sieht.



  • @TGGC
    Ich möchte das auch nicht zu kompliziert machen, die Bearbeitung sieht so aus, dass der Benutzer (genauer: ich) XML schreiben muss. Da stecke ich lieber etwas mehr Arbeit in die Logik, damit die selbständig erkennt, wo sich zwei Segmente kreuzen bevor ich für verschiedene Tiles mehr XML brauche.
    Beispiel:

    <tile>
       <track>
          <segment start="N" end="S" layer="0"/>
          <segment start="SE" end="NW" layer="1">
       </track>
    </tile>
    

    Aus den Infos erkenne ich, dass es zwei Geraden sind, die sich in der Mitte des Tile kreuzen. Da sie in unterschiedlichen Layern liegen weiß ich, dass ich für das zweite Segment eine Brück zeichnen muss, weil es über dem ersten liegt. Ist natürlich etwas Arbeit, alle möglichen Kreuzungspunkte zu finden und entsprechend zu behandeln.

    Zur Info: Hier ist eine Liste, der Tiles die es gibt. 😉



  • Es spricht ja nichts dagegen, Logik zu schreiben, die das macht. Aber der User muss es dann trotzdem erstmal angeben. Und das geht mit der Layer Logik nicht. Angenommen, du hast 3 Segmente, die etwa so angeordnet sind:

    \       /
     \A   B/
    ---------
       \ /
        X
       / \
      /   \
    
    

    Bei A und B sind die Segmente verbunden und bei X ist eine Brücke. Wie soll das mit deinem Layerkonzept gehen? Teilst du das irgendwie in Layer auf, fehlt entweder bei A oder B die Verbindung. Offensichtlich muss eine Bahnstrecke nämlich nicht komplett in einem Layer laufen sondern kann den Layer wechseln. Du musst diesen Sonderfall irgendwie behandeln.



  • @TGGC

    Wenn ich im ersten Schritt alle Rahmen zeichne und im zweiten Schritt alle Strecken ist ggf. alles mit allem verbunden (Layer werden in diesen Schritten ignoriert). Im dritten Schritt bestimme ich die Kreuzungspunkte anhand der Layer, das müsste doch eigentlich ausreichen. Damit würden die Segmente, die nicht verbunden sein sollten, wieder getrennt. Die Layer werden dann nur noch für die Bestimmung der Kreuzungspunkte gebraucht.



  • Alles schön und gut - aber zum dritten Mal : man kann nicht in allen Konfigurationen die Brücken und Kreuzungspunkte korrekt unterscheiden aus den Layern.

    Und dann landest du halt bei meinem Vorschlag: Layer komplett weglassen und dafür Brücken explizit angeben oder einzelne Linien müssen den Layer abschnittsweise wechseln können.



  • Sorry, verstehe ich nicht.
    Gib mir doch bitte mal ein Beispiel, wo´s nicht funktioniert.



  • @TGGC sagte in Problem beim Zeichnen mehrerer Layer:

    Angenommen, du hast 3 Segmente, die etwa so angeordnet sind:

    \       /
     \A   B/
    ---------
       \ /
        X
       / \
      /   \
    
    

    Bei A und B sind die Segmente verbunden und bei X ist eine Brücke. Wie soll das mit deinem Layerkonzept gehen? Teilst du das irgendwie in Layer auf, fehlt entweder bei A oder B die Verbindung.



  • Das geht mit meinem Ansatz:

    Vorgehen in Bildform: Tile

    <tile>
       <track>
          <segment start="NW" end="NE" layer="0"/> <!-- Segment 1: Weite Kurve Nordwesten -> Nordosten, liegt unten-->
          <segment start="NE" end="SW" layer="0"/> <!-- Segment 2: Gerade Nordosten -> Südwesten, liegt unten-->
          <segment start="NW" end="SE" layer="1"/> <!-- Segment 3: Gerade Nordwesten -> Südosten, liegt oben -->
       </track>
    </tile>
    

    Test Segment 1 mit Segment 2: gleicher Layer, nix zu tun
    Test Segment 1 mit Segment 3: unterschiedliche Layer, aber keine Kreuzung (obwohl sich die Strecken beim Startpunkt überlappen)
    Test Segment 2 mit Segment 3: unterschiedliche Layer, Kreuzung in der Mitte des Tiles, da sich Geraden nur in der Mitte kreuzen können -> Brücke über Segment 2 zeichnen, da Segment 3 drüber liegt

    Vermutlich stellen wir uns unter "Layer" unterschiedliche Dinge vor. Ich meine mit Layer die Z-Koordinate, das hat mit dem Zeichnen selbst nix mehr zu tun.



  • Wie funktioniert https://ibb.co/9HbcZXR rechts unten? Oder generell irgendeiner von den unteren.

    Das Problem mit dem Layer, was ich bisher sehe ist, wenn alle Verbindungen miteinander verbunden sind indirekt d.h. du kann von jedem Segment in ein anderes irgendwie kommen ... aber eben nicht alle direkt miteinander verbunden sind.

    Sprich Auffahrten. Wie realisiert du Auffahrten, die ja von einer Layer in ein anderes Layer übergehen, wenn ich das richtig sehe.



  • @Leon0402

    <tile>
       <track>
          <segment start="NW" end="NE" layer="0"/> <!-- Segment 1: Weite Kurve Nordwesten -> Nordosten, liegt unten-->
          <segment start="NE" end="SW" layer="0"/> <!-- Segment 2: Gerade Nordosten -> Südwesten, liegt unten-->
          <segment start="SW" end="SE" layer="0"/> <!-- Segment 3: Weite Kurve Südwesten -> Südosten, liegt unten-->
          <segment start="NW" end="SE" layer="1"/> <!-- Segment 4: Gerade Nordwesten -> Südosten, liegt oben -->
       </track>
    </tile>
    

    Test Segment 1 mit Segment 2: gleicher Layer, nix zu tun
    Test Segment 1 mit Segment 3: gleicher Layer, nix zu tun
    Test Segment 1 mit Segment 4: unterschiedliche Layer, aber keine Kreuzung

    Test Segment 2 mit Segment 3: gleicher Layer, nix zu tun
    Test Segment 2 mit Segment 4: unterschiedliche Layer, Kreuzung in der Mitte des Tiles: Brücke über Segment 2 zeichnen, da Segment 4 drüber liegt

    Test Segment 3 mit Segment 4: unterschiedliche Layer, aber keine Kreuzung

    Hier die passenden Schritte dazu, hab die Zwischenschritte weggelassen.


Anmelden zum Antworten