На пользовательском контроле У меня есть серия светодиодных объектов, которые должны быть включены в соответствии с данным GraphicsPath
(например, см. Рисунок ниже). В настоящее время я использую graphicsPath.IsVisible(ledPoint)
, однако, поскольку у меня много светодиодов, итерация через все они могут быть очень медленными, особенно если путь сложный (например, обратный путь в примере).Улучшение хитов в Winforms; любая альтернатива GraphicsPath.IsVisible?
Есть ли у вас какие-либо идеи относительно чего-то более умного для ускорения итерации? Если это слишком сложно, чтобы привести пример, это может привести к перенаправлению меня к соответствующим ресурсам. Пожалуйста, учтите, что элемент управления находится в GDI +, реинжиниринг в другой движок не является вариантом.
EDIT
на моем компьютере (i7 3,6 ГГц), когда в качестве GraphicsPath
Я только простой прямоугольник 100х100 пикселей, а затем я вычислить обратную на моем контроле, который размером от 500x500 пикселей (следовательно, итоговый GraphicsPath
будет прямоугольником 500x500 с «отверстием» 100x100), для тестирования 6000 светодиодов занимает около 1,5 секунд, что слишком сильно повлияет на работу пользователя.
После Мэтью Уотсон ответ, я детализацией больше на моем примере:
//------ 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);
На моем компьютере у меня есть ~ 725ms на первом тесте и ~ 5000 мс на секунду. И это довольно простой путь. GraphicsPath
генерируется движением мыши пользователя, и пользователь может выполнять несколько комбинаций путей (инвертирование, объединение, пересечение, я использую для этого GPC). Следовательно, тестирование на инверсию путем тестирования отрицания GraphicsPath.IsVisible()
может быть сложным.
inversePath
вернулся из Utility.CombinePath
довольно проста и имеет следующие пункты (слева PathPoints
, справа PathTypes
):
Что является источником GraphicsPath? Также: в чем же проблема? Это слишком медленно? Сколько у вас путей? Вы не можете кэшировать свои хиты в списке или словаре? – TaW
Я сделал несколько тестов, см. Мои правки. Я не могу кэшировать, потому что GraphicsPath постоянно меняется –
В дополнение к ответу Matthews: Как создаются те постоянно изменяющиеся GraphicsPaths? – TaW