Benutzer mit den meisten Antworten
Suche so etwas wie DrawClosedCurve um die Objekte im GraphicsPath

Frage
-
Antworten
-
- Frank schrieb: Wenn man eine engere Umrandung haben möchte, wäre das Aussehen zu klären, wenn sich die Figuren zum Beispiel nicht überschneiden.
Die GDI+ Flat API stellt dafür bereits eine Methode dafür zur Verfügung, dann quasi die Semantik der minimalsten Fläche benutzt (wie: GdipWindingModeOutline), die kann man auch von C# aus nutzen (in C++ übrigens über GraphicsPath.Outline() zugänglich). Hier ein Beispiel:
using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; namespace WinGraphicsDemo { public partial class Form1 : Form { public Form1() { InitializeComponent(); Width = 400; Height = 400; } private void Form1_Paint(object sender, PaintEventArgs e) { GraphicsPath gp = new GraphicsPath(); gp.AddEllipse(new Rectangle(50, 50, 100, 100)); gp.AddRectangle(new Rectangle(130, 70, 140, 140)); Graphics g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; g.DrawPath(Pens.DarkBlue, gp); UmrissZeichnen(e, gp); gp.Dispose(); } [DllImport(@"gdiplus.dll")] public static extern int GdipWindingModeOutline( HandleRef href, IntPtr matrix, float flatness); Pen umrissFarbe = new Pen(Color.FromArgb(200, Color.Yellow), 5); void UmrissZeichnen(PaintEventArgs e, GraphicsPath pfad) { HandleRef href = new HandleRef(pfad, (IntPtr)pfad.GetType().GetField("nativePath", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(pfad)); GdipWindingModeOutline(href, IntPtr.Zero, 0.25F); e.Graphics.DrawPath(umrissFarbe, pfad); } } }
ciao Frank- Als Antwort vorgeschlagen Thorsten Gudera Sonntag, 29. Mai 2011 10:23
- Als Antwort markiert wolfgangh Montag, 30. Mai 2011 06:38
Alle Antworten
-
Hallo Wolfgang,eine rechteckige Umrandung aller Gebilde kannst Du zum Beispiel folgendermaßen erreichen:
using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace WinGraphicsDemo { public partial class Form1 : Form { public Form1() { InitializeComponent(); Width = 400; Height = 400; } Pen umrissFarbe = new Pen(Brushes.Yellow, 5); private void Form1_Paint(object sender, PaintEventArgs e) { GraphicsPath gp = new GraphicsPath(); gp.AddEllipse(new Rectangle(50, 50, 100, 100)); gp.AddRectangle(new Rectangle(130, 70, 140, 140)); Graphics g = e.Graphics; g.DrawRectangle(umrissFarbe, Rectangle.Truncate(gp.GetBounds())); g.DrawPath(Pens.DarkBlue, gp); gp.Dispose(); } } }
----------------
Wenn man eine engere Umrandung haben möchte, wäre das Aussehen zu klären, wenn sich die Figuren zum Beispiel nicht überschneiden.
ciao Frank -
Hallo,
das Problem ist, was soll gemacht werden, wenn die Objekte im path sich nicht überschneiden? Sollen dan zwei, oder mehr, Linien/Kurven gezeichnet werden? Wenn die Objekte zusammenhängen - und die umschließende Kurve nicht intelligent sein soll, dann kannst Du mit folgendem ein wenig herumexperimentieren:
public partial class Form1 : Form { GraphicsPath _gPath = null; public Form1() { InitializeComponent(); this.Width *= 2; this.Height *= 2; GraphicsPath gPath = new GraphicsPath(); gPath.AddEllipse(new RectangleF(12, 12, 124, 224)); gPath.AddEllipse(new RectangleF(212, 12, 124, 224)); //wäre nicht verbunden //gPath.AddRectangle(new RectangleF(this.ClientRectangle.Width + 112, 212, 124, 44)); gPath.AddRectangle(new RectangleF(112, 212, 124, 44)); //wäre verbunden //gPath.AddEllipse(this.ClientRectangle); _gPath = gPath; this.Paint += new PaintEventHandler(Form1_Paint); this.FormClosing += new FormClosingEventHandler(Form1_FormClosing); } void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (_gPath != null) _gPath.Dispose(); } private void Form1_Paint(object sender, PaintEventArgs e) { GraphicsPath gP = (GraphicsPath)_gPath.Clone(); GraphicsPath gP2 = (GraphicsPath)_gPath.Clone(); gP2.FillMode = FillMode.Winding; //geweiteten Path zeichnen using (Pen p = new Pen(Color.Black, 2)) { gP.Widen(p); e.Graphics.DrawPath(p, gP); } //"normalen" Path mit Hintergrundfarbe füllen using(SolidBrush b = new SolidBrush(this.BackColor)) e.Graphics.FillPath(b, gP2); gP.Dispose(); gP2.Dispose(); } }
Viele Grüße,
Thorsten
-
- Frank schrieb: Wenn man eine engere Umrandung haben möchte, wäre das Aussehen zu klären, wenn sich die Figuren zum Beispiel nicht überschneiden.
Die GDI+ Flat API stellt dafür bereits eine Methode dafür zur Verfügung, dann quasi die Semantik der minimalsten Fläche benutzt (wie: GdipWindingModeOutline), die kann man auch von C# aus nutzen (in C++ übrigens über GraphicsPath.Outline() zugänglich). Hier ein Beispiel:
using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; namespace WinGraphicsDemo { public partial class Form1 : Form { public Form1() { InitializeComponent(); Width = 400; Height = 400; } private void Form1_Paint(object sender, PaintEventArgs e) { GraphicsPath gp = new GraphicsPath(); gp.AddEllipse(new Rectangle(50, 50, 100, 100)); gp.AddRectangle(new Rectangle(130, 70, 140, 140)); Graphics g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; g.DrawPath(Pens.DarkBlue, gp); UmrissZeichnen(e, gp); gp.Dispose(); } [DllImport(@"gdiplus.dll")] public static extern int GdipWindingModeOutline( HandleRef href, IntPtr matrix, float flatness); Pen umrissFarbe = new Pen(Color.FromArgb(200, Color.Yellow), 5); void UmrissZeichnen(PaintEventArgs e, GraphicsPath pfad) { HandleRef href = new HandleRef(pfad, (IntPtr)pfad.GetType().GetField("nativePath", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(pfad)); GdipWindingModeOutline(href, IntPtr.Zero, 0.25F); e.Graphics.DrawPath(umrissFarbe, pfad); } } }
ciao Frank- Als Antwort vorgeschlagen Thorsten Gudera Sonntag, 29. Mai 2011 10:23
- Als Antwort markiert wolfgangh Montag, 30. Mai 2011 06:38
-
guten Morgen,
um die offene Frage noch zu klären: die entstehende Figur hat eine geschlossenen Randlinie und hat innen keine "Löcher".
Die gesuchte .NET-Funktion gibt es wohl dazu nicht, aber der Vorschlag von Frank leistet das laut Beschreibung (habs noch nicht ausprobiert).
Allen besten Dank für die Antworten
Wolfgang