Problem mit GraphicsPath FillMode

  • C#

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Problem mit GraphicsPath FillMode

    Moin Leute.
    Ist es denkbar, dass die Property GraphicsPath.FillMode nur bei in sich geschlosenen Kurven funktioniert?
    Folgende Testsituation:
    Ich stelle zwei sich überlappende Quadrate dar und variiere den FillMode: { FillMode.Winding, FillMode.Alternate }.
    Werden die Quadrate dem GraphicsPath mit AddRectangle() hinzugefügt, ist alles in Ordnung.
    Wird eines mit AddRectangle() und das andere mit AddPolygon() hinzugefügt, erfolgt die Darstellung ausschließlich mit FillMode.Alternate.
    CheckBox1 wechselt die Befüllung des GraphicsPaths zwischen AddRectangle() und AddPolygon().
    CheckBox2 wechselt die Darstellung zwischen FillMode.Winding und FillMode.Alternate.
    Form mit 2 CheckBoxen und einer PictureBox:
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Drawing;
    3. using System.Drawing.Drawing2D;
    4. using System.Windows.Forms;
    5. namespace Zeigerinstrument
    6. {
    7. public partial class Form1 : Form
    8. {
    9. private GraphicsPath Path1;
    10. private GraphicsPath Path2;
    11. public Form1()
    12. {
    13. this.InitializeComponent();
    14. this.Path1 = new GraphicsPath();
    15. this.Path2 = new GraphicsPath();
    16. this.checkBox1_CheckedChanged(this.checkBox1, EventArgs.Empty);
    17. }
    18. private void checkBox1_CheckedChanged(object sender, EventArgs e)
    19. {
    20. this.Path1.Reset();
    21. if (this.checkBox1.Checked)
    22. {
    23. this.Path1.AddRectangle(new Rectangle(new Point(0, 0), new Size(150, 150)));
    24. }
    25. else
    26. {
    27. PointF[] array = new PointF[5];
    28. array[0] = new PointF(0f, 0f);
    29. array[1] = new PointF(0f, 150f);
    30. array[2] = new PointF(150f, 150f);
    31. array[3] = new PointF(150f, 0f);
    32. array[4] = new PointF(0f, 0f);
    33. this.Path1.AddPolygon(array);
    34. }
    35. this.Path1.AddRectangle(new Rectangle(new Point(100, 100), new Size(150, 150)));
    36. this.pictureBox1.Invalidate();
    37. }
    38. private void pictureBox1_Paint(object sender, PaintEventArgs e)
    39. {
    40. this.Path2.Reset();
    41. this.Path2.AddPath(this.Path1, false);
    42. this.Path2.FillMode = this.checkBox2.Checked ? FillMode.Winding : FillMode.Alternate;
    43. e.Graphics.FillPath(Brushes.Black, this.Path2);
    44. }
    45. private void checkBox2_CheckedChanged(object sender, EventArgs e)
    46. {
    47. this.pictureBox1.Invalidate();
    48. }
    49. }
    50. }

    Laut Beschreibung müsste bei aktiver CheckBox2 unabhängig von CheckBox1 alles gefüllt sein, dem ist aber nicht so.
    Lässt sich das iwie lösen?
    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!
    @korni What :?:
    Falls Du .AddLines() gemeint haben solltest, get beides nicht.
    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!

    korni schrieb:

    Das hat bei mir im Test eine Veränderung gebracht
    Also noch mal zum Gegenstand des Problems:

    Quellcode

    1. [ ] sei eine nicht gecheckte CheckBox
    2. [x] sei eine gecheckte CheckBox
    3. -------
    4. CB1 CB2 (CheckBox)
    5. [x] [ ] - in Ordnung
    6. [x] [x] - in Ordnung
    7. [ ] [ ] - in Ordnung
    8. [ ] [x] - nicht in Ordnung
    Ist CB1 nicht aktiv, hat CB2 keine Auswirkung auf die Darstellung.
    Das widerspricht der Beschreibung.
    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!
    @korni Die Reihenfolge beim Aufbau des Arrays hat keine Auswirkung auf die Darstellung.
    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!
    @korni Ja, es ist so.
    Ich versteh die Welt nicht mehr.
    Der Compilerschalter false funktioniert, true hingegen nicht. ?( :S

    C#-Quellcode

    1. #if false //true //
    2. array[0] = new PointF(0f, 0f);
    3. array[1] = new PointF(0f, 150f);
    4. array[2] = new PointF(150f, 150f);
    5. array[3] = new PointF(150f, 0f);
    6. array[4] = new PointF(0f, 0f);
    7. #else
    8. array[4] = new PointF(0f, 0f);
    9. array[3] = new PointF(0f, 150f);
    10. array[2] = new PointF(150f, 150f);
    11. array[1] = new PointF(150f, 0f);
    12. array[0] = new PointF(0f, 0f);
    13. #endif
    Ich hatte eben den Verdacht, dass die Richtung des Polygons Ursache sei und habe im #else Zweig die Indizes von 0-4 eingetragen, das ging nicht, wohl aber im #if-Zweig.
    Das ist absolut unverständlich.
    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!
    FillMode Enum

    The Winding mode considers the direction of the path segments at each
    intersection. It adds one for every clockwise intersection, and
    subtracts one for every counterclockwise intersection. If the result is
    nonzero, the point is considered inside the fill or clip area. A zero
    count means that the point lies outside the fill or clip area.

    A figure is considered clockwise or counterclockwise based on the order in which the segments of the figure are drawn.


    Das Beispiel deines Eingangsposts besitzt 2 Schnittpunkte und du zeichnest es gegen den Uhrzeigersinn.
    @Fakiz Ja, das ist mir nach dem Post auch klar geworden. ;)
    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!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()