GraphicsPath.AddPath - was geht?

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von Artentus.

    GraphicsPath.AddPath - was geht?

    Hallo mal wieder.

    Unter Direct2D lassen sich Geometries auf diese vier Varianten miteinander kombinieren:
    sharpdx.org/documentation/api/…pdx-direct2d1-combinemode
    Meine Frage ist jetzt, welche davon lassen sich mit dem GDI+-GraphicsPath nachbauen? Ich weiß, dass es die FillMode-Eigenschaft gibt, jedoch verstehe ich nicht, was da was ist (Erklärung auf MSDN ist mir zu kompliziert :P ). Außerdem sind es sowieso nur zwei Möglichkeiten, bekomme ich damit überhaupt die oben genannten vier zusammen?
    @Artentus:: Das würde ich einfach mal ausprobieren.
    Im wesentlichen geht es darum, festzustellen, ob bei einem Liniengewirr ausgehend von einem "inneren" Punkt in einem Segment festzustellen, ob ein anderes Segment innen oder außen ist.
    Ein Kreuzgitter müsste dann mit Alternate zu Schachbrett-like befüllt werden (ohne das getestet zu haben).
    Der Unterschied dürfte signifikant sein, wenn Du krummlinige Segmente befüllst, da könnte ich mir vorstellen, dass es auf verschiedenen Wegen unterschiedliche Innen-Außen-Resultate gibt, als wenn Du in der Zeichenebene in der 3. (z-)Dimension Segmente überspringst.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich hab schon ein bisschen rumprobiert. Solange man nur zwei GraphicsPaths zusammenfügt, dann entspricht Winding Union und Alternate Xor (sofern ich das beurteilen kann). Mit dem Kreuzgitter solltest du also recht haben. Aber wenn man mehrere Paths zusammenfügt, dann werden sich die ursprünglichen irgendwie gemerkt und dann kommt immer was ganz anderes bei raus, als ich erwartet hatte.
    Irgendwie funktioniert Direct2D aber auch nicht immer so, wie ichs gerne hätte, alles ziemlich verzwickt (auch aufgrund mangelnder Dokumentation der möglichen Fälle bei beiden APIs). :P
    Was für Strukturen willst Du denn ausfüllen?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Jetzt speziell, woran ichs gemerkt hab, das war so ein Zahnrad. So siehts mit Direct2D aus (korrekt):

    Und so siehts mit GDI+ aus:


    Code kann ich schlecht posten, sind einige tausend Zeilen (GameUtils), aber es passiert beide male nacheinander folgendes:
    1. Die Zähne des Zahnrades erstellen -> funktioniert bei beiden.
    2. Den Kreis hinzufügen, bei D2D mittels Union und bei GDI mittels Winding -> funktioniert bei beiden.
    3. Das Loch in der Mitte vom Path entfernen, bei D2D mit Xor und bei GDI mit Alternate -> funktioniert bei D2D aber nicht bei GDI (ist auch der Beweis, dass Alternate nicht Xor entspricht).
    Ich konnte jetzt immerhin schon das Problem lokalisieren. Winding ist tatsächlich wie Union und Alternate tatsächlich wie Xor, nur wird bei dem Graphicspath mit dem Setzen der Eigenschaft das Schema für alle Operationen übernommen, da offensichtlich nicht sofort ausgewertet wird, sondern die zwei kombinierten Pfade gespeichert werden und dann erst bei DrawPath ausgewertet wird, was wie gezeichnet wird. Anders als bei Direct2D, denn dort wird offensichtlich sofot die Änderung angewendet und spätere Änderungen der Eigenschaft haben somit keinen Effekt mehr darauf.
    Jetzt ist nur das Problem, dass ich überhaupt keine Ahnung habe, wie oder ob man das überhaupt lösen kann.
    Eine kurze OT-Frage: Wofür zeichnest du das Zahnrad? Ich frage nur, weil ich aus dem Maschinenbau komme und sehe, dass das keine "richtige" Verzahnung ist. Wenn es sich nämlich um ein möglichst realistisches Spiel handeln sollte und nicht einfach irgendwelche Icons für Buttons o.Ä. wäre eine reell existierende Verzahnung besser(Evolventenverzahnung oder gleich die Zykloidenverzahnung).
    Ok, ich bin zu dem Schluss gekommen, dass der GraphicsPath das nicht kann. Die Region-Klasse kann es aber, und deshalb hab ich es jetzt kurzerhand so gelöst, dass parallel ein GraphicsPath und eine Region erstellt werden, und für Draw dann der Path und für Fill die Region verwendet werden (Draw gibts für REgions leider nicht, sonst könnte ich auf dem Path ganz verzichten). Jetzt gibt es nur ein Problem, Graphics.FillRegion() unterstützt offensichtlich kein Antialiasing, was dann schon ein bisschen blöd aussieht. Ich würde es trotzdem so lassen, der GDI-Renderer ist sowieso nicht empfohlen, aber wenns einen Workaround geben würde fände ich das trotzdem toll.