| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Оптимизация выделения |
| Автор: TGrey 28.1.2010, 15:51 | ||
| Здравствуйте. Снова вернусь к своему приложению и хочу посоветоваться на счет выделения. На данный момент выделение происходило только кликом непосредственно по элементу. Что по сути вызывало ряд мат. формул и в случае выполнения условия выделяло объект. Потом же было решено сделать еще прямоугольное выделение, как в виндовсе. Сделать - сделал. Рисуется точечным карандашом прямоугольник. Но вот дальше выделение происходит по старому методу проверкой Х и У координат. Тобишь крутит 2 цикла от меньшего Х к большему и тоже самое по У и так проверяет каждый пиксель. По сути то оно выделяет, все нормально. Но чем больше прямоугольник, тем больше нужно проверить и это сказывается на ЦП. Чем больше я выделяю область тем больше прыгает ЦП. Конечно на секунду, но все равно заметно. А если увеличить еще кол-во объектов, то будет туго. Может есть предложения, как это можно оптимизировать, ускорить процесс с наименьшей нагрузкой на ЦП. Пока же вызывается вот эта функция
Ну и как я сказал оно так и выходит, если несколько элементов то ЦП до 20-30 прыгает, а если сделать все 10 и больше то и до 90 доходит и несколько секунд надо ждать пока разтупит. |
| Автор: GremlinProg 28.1.2010, 17:22 |
| упрости: для каждой фигуры храни или считай "окаймляющий прямоугольник" - габариты фигуры, по сути, а при проверке вхождения фигуры в выделение, пересекай оба этих прямоугольника (IntersectRect) если результатом пересечения будет пустой прямоугольник, значит фигура не входит в выделение, иначе - входит в случае пересечения, IntersectRect вернет TRUE |
| Автор: TGrey 28.1.2010, 17:39 |
| То есть вот так? Обрамлять фигуру и вызывать для ВЫДЕЛЕНИЯ и для объекта функцию Пересечения? А как она внутри работает? Может тоже начинает координаты перебирать?) |
| Автор: TGrey 29.1.2010, 13:21 |
| Не ну это понятное дело, что на холсте не буду. Это чтобы полностью быть уверенным, что я верно понял. Спасибо сейчас попробую и доложу о результатах! |
| Автор: TGrey 29.1.2010, 14:40 |
| Получилась такая ситуация. Пока прикрепил прямоугольники только к круглым объектам, но результат таков, что память скачет меньше, около 20%, но я посмотрел, что выделения я по прежнему использую функцию OnClick которая делает математические расчеты, что не так плохо, как первый раз, поскольку теперь клик происходит четко по объекту, что сокращает вызов этих функций до кол-ва самих объектов. Но я так подумал, что это бессмысленно, снова рассчитывать клик, сделал еще одну виртуальную функцию Select которая только устанавливает флаги выделения и выполняет функции с расчетом, что выделение произошло 100%. Но память, что-то всеравно до 20% прыгала. Я посмотрел, что при отрисовке выделяющего прямоугольника все сильно моргает. Закоментировав эту часть ЦП держится на 0%. Пока программа не использует задний буффер для прорисовки, поэтому видимо такие глюки. В общем сам способ помог |
| Автор: TGrey 29.1.2010, 15:01 |
Да, наверно поспешил.![]() Провод рисуется изгибами, значит его нужно полностью заключить в прямоугольник. Вот и получается, что если выделять, как на рисунке синим цветом, то выделение проходит, хоть не должно. |
| Автор: Earnest 29.1.2010, 21:14 |
| TGrey, разные объекты нужно находить по разному. Общий подход такой: 1) Хранишь охватывающий прямоугольник для каждого объекта - для ускорения: первая проверка - попадание точки в этот экстентю Или наличие пересечения экстента с прямоугольником выделения. 2) Дальше (если в прямоугольник попали) нужно вызывать функцию, свою для каждого типа объекта, скажем вирт. функция HitTest. Для прямоугольника она тривиальна (собственно, уже выполнена при проверке экстента). Для провода это - поиск пересечения каждого сегмента с прямоугольником. И т.д. |
| Автор: TGrey 29.1.2010, 21:44 |
| Ну вот я и думаю, что такой способ будет работать только с круглыми объектами, которые даже при повороте не изменяет форму, а остальное нужно искать по пересечениям. Пойду искать формулы. |
| Автор: TGrey 30.1.2010, 15:45 |
| В общем решил делать след. образом: Сперва проверять точки на линии, находятся ли они внутри прямоугольника, если так - выделять. Если по точкам ничего не выделило, тогда использую формулы пересечения двух прямых, линии и каждой части прямоугольника. Пока работает и ЦП не грузит. |
| Автор: GremlinProg 30.1.2010, 20:48 | ||
со сложными объектами работай как с совокупностью простых: ломаная - набор отрезков, вот и работай со всеми ее отрезками, отрезок же - простой объект если хоть один отрезок пересекает выделение, значит пересекает и вся ломаная |
| Автор: TGrey 31.1.2010, 00:30 |
| Да уже именно так и сделал. |