Auf einem benutzerdefinierten Steuerelement habe ich eine Reihe von LED-Objekten, die gemäß einer gegebenen GraphicsPath
eingeschaltet werden sollten (z. B. siehe Bild unten). Derzeit verwende ich graphicsPath.IsVisible(ledPoint)
, aber da ich viele LEDs habe, kann die Iteration durch alle von ihnen sehr langsam sein, besonders wenn der Pfad komplex ist (z. B. die Umkehrung des Pfads in dem Beispiel).Verbesserte Treffertests in Winforms; eine Alternative zu GraphicsPath.IsVisible?
Hat jemand von Ihnen eine Idee zu etwas schlauer, um Iteration zu beschleunigen? Wenn es zu komplex ist, um ein Beispiel zu geben, kann es sinnvoll sein, mich zu geeigneten Ressourcen umzuleiten. Bitte beachten Sie, dass das Steuerelement in GDI + ist und ein Reengineering in eine andere Engine keine Option ist.
EDIT
auf meinem PC (i7 3,6 GHz), wenn sie als GraphicsPath
I 100x100 Pixel nur ein einfaches Rechteck haben und dann berechnen ich die inverse auf meiner Kontrolle, das ist Größe von etwa 500x500 Pixel (daher wird die resultierende GraphicsPath
wird ein 500x500 Rechteck mit einem "Loch" von 100x100), um 6000 LEDs zu testen dauert etwa 1,5 Sekunden, die zu viel beeinflussen Benutzererfahrung.
Nach Matthew Watson Antwort, ich bin mehr auf meinem Beispiel Detaillierung:
//------ Base path test
GraphicsPath path = new GraphicsPath();
path.AddRectangle(new Rectangle(100, 100, 100, 100));
var sw = System.Diagnostics.Stopwatch.StartNew();
for (int x = 0; x < 500; ++x)
for (int y = 0; y < 500; ++y)
path.IsVisible(x, y);
Console.WriteLine(sw.ElapsedMilliseconds);
//------ Inverse path test
GraphicsPath clipRect = new GraphicsPath();
clipRect.AddRectangle(new Rectangle(0, 0, 500, 500));
GraphicsPath inversePath = Utility.CombinePath(path, clipRect, CombineMode.Complement);
sw.Restart();
for (int x = 0; x < 500; ++x)
for (int y = 0; y < 500; ++y)
inversePath.IsVisible(x, y);
Console.WriteLine(sw.ElapsedMilliseconds);
Auf meinem PC habe ich ~ 725ms auf den ersten Test und ~ 5000 ms auf dem zweiten. Und das ist nur ein ziemlich einfacher Weg. Die GraphicsPath
wird durch Mausbewegungen des Benutzers generiert, und der Benutzer kann mehrere Pfade kombinieren (Invertierung, Vereinigung, Schnittpunkt, .. Ich verwende dafür GPC). Daher kann das Testen auf Inversion durch Testen der Negation von GraphicsPath.IsVisible()
schwierig sein.
Die inversePath
kehrte von Utility.CombinePath
ist ganz einfach und hat Punkten nach (links PathPoints
, rechts PathTypes
):
Was ist die Quelle des GraphicsPath? Auch: Was genau ist das Problem? Ist es wirklich zu langsam? Wie viele Wege hast du? Können Sie ihre Treffer nicht in einer Liste oder einem Wörterbuch zwischenspeichern? – TaW
Ich habe einen Test gemacht, siehe meine Änderungen. Ich kann nicht zwischenspeichern, da sich GraphicsPath kontinuierlich ändert –
Zusätzlich zu Matthews Antwort: Wie entstehen diese sich ständig ändernden GraphicsPaths? – TaW