Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Оптимизация выделения 
V
    Опции темы
TGrey
Дата 28.1.2010, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Здравствуйте. Снова вернусь к своему приложению и хочу посоветоваться на счет выделения.
На данный момент выделение происходило только кликом непосредственно по элементу. Что по сути вызывало ряд мат. формул и в случае выполнения условия выделяло объект. Потом же было решено сделать еще прямоугольное выделение, как в виндовсе. Сделать - сделал. Рисуется точечным карандашом прямоугольник. Но вот дальше выделение происходит по старому методу проверкой Х и У координат. Тобишь крутит 2 цикла от меньшего Х к большему и тоже самое по У и так проверяет каждый пиксель. По сути то оно выделяет, все нормально. Но чем больше прямоугольник, тем больше нужно проверить и это сказывается на ЦП. Чем больше я выделяю область тем больше прыгает ЦП. Конечно на секунду, но все равно заметно. А если увеличить еще кол-во объектов, то будет туго.
Может есть предложения, как это можно оптимизировать, ускорить процесс с наименьшей нагрузкой на ЦП.

Пока же вызывается вот эта функция
Код

void TrySelect( int fx, int fy, int sx, int sy )
{
    bool nextel=false, issel=false;
    for(int i=0; i < d.elements.size(); i++)
    {
        for(int y=0; y < d.selected.size(); y++)    //Skip selected
        {
            if( d.elements[i] == d.selected[y] )
            {
                issel = true;
                break;
             }
                
        }

        if( issel )
        {
            issel = false;
            continue;
        }

        for(int k=fx; k<=sx; k++)
        {
            for(int l=fy; l<= sy; l++)
            {
                if( d.elements[i]->OnClick(k, l) == false )
                {
                    if( d.elements[i]->type == 1 && static_cast<IConductor*>(d.elements[i])->NextCond != NULL )
                    {    
                        /**/
                        IConductor *tmp = static_cast<IConductor*>(d.elements[i])->NextCond;
                        do
                        {
                            if( tmp->OnClick(k, l) == true )
                            {
                                nextel = true;
                                break;
                            }
                            tmp = tmp->NextCond;
                        }while( tmp != NULL );
                    }
                }
                else
                {
                    nextel = true;
                }
                if( nextel )
                    break;
            }
            if( nextel )
                break;
        }
        nextel = false;
    }
}


Ну и как я сказал оно так и выходит, если несколько элементов то ЦП до 20-30 прыгает, а если сделать все 10 и больше то и до 90 доходит и несколько секунд надо ждать пока разтупит.

Это сообщение отредактировал(а) TGrey - 28.1.2010, 15:56
PM MAIL   Вверх
GremlinProg
Дата 28.1.2010, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



упрости: для каждой фигуры храни или считай "окаймляющий прямоугольник" - габариты фигуры, по сути,
а при проверке вхождения фигуры в выделение, пересекай оба этих прямоугольника (IntersectRect)

если результатом пересечения будет пустой прямоугольник, значит фигура не входит в выделение, иначе - входит

в случае пересечения, IntersectRect вернет TRUE


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 28.1.2010, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



То есть вот так? Обрамлять фигуру и вызывать для ВЫДЕЛЕНИЯ и для объекта функцию Пересечения?
А как она внутри работает? Может тоже начинает координаты перебирать?)

Присоединённый файл ( Кол-во скачиваний: 11 )
Присоединённый файл  olol.jpg 43,86 Kb
PM MAIL   Вверх
GremlinProg
Дата 29.1.2010, 06:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



физически, на холсте можно и не обрамлять, а так, виртуально - все верно рисуешь
Цитата(TGrey @  28.1.2010,  19:39 Найти цитируемый пост)
А как она внутри работает? Может тоже начинает координаты перебирать?)

не начнет: http://www.google.ru/search?q=%D0%B0%D0%BB...%B8%D1%81%D0%BA
smile

Это сообщение отредактировал(а) GremlinProg - 29.1.2010, 06:40


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 29.1.2010, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Не ну это понятное дело, что на холсте не буду. Это чтобы полностью быть уверенным, что я верно понял.
Спасибо сейчас попробую и доложу о результатах!
PM MAIL   Вверх
TGrey
Дата 29.1.2010, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Получилась такая ситуация. Пока прикрепил прямоугольники только к круглым объектам, но результат таков, что память скачет меньше, около 20%, но я посмотрел, что выделения я по прежнему использую функцию OnClick которая делает математические расчеты, что не так плохо, как первый раз, поскольку теперь клик происходит четко по объекту, что сокращает вызов этих функций до кол-ва самих объектов. Но я так подумал, что это бессмысленно, снова рассчитывать клик, сделал еще одну виртуальную функцию Select которая только устанавливает флаги выделения и выполняет функции с расчетом, что выделение произошло 100%. Но память, что-то всеравно до 20% прыгала. Я посмотрел, что при отрисовке выделяющего прямоугольника все сильно моргает. Закоментировав эту часть ЦП держится на 0%. Пока программа не использует задний буффер для прорисовки, поэтому видимо такие глюки.
В общем сам способ помог smile . Спасибо.
PM MAIL   Вверх
TGrey
Дата 29.1.2010, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Да, наверно поспешил.
user posted image
Провод рисуется изгибами, значит его нужно полностью заключить в прямоугольник.
Вот и получается, что если выделять, как на рисунке синим цветом, то выделение проходит, хоть не должно.

Это сообщение отредактировал(а) TGrey - 29.1.2010, 15:01
PM MAIL   Вверх
Earnest
Дата 29.1.2010, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



TGrey, разные объекты нужно находить по разному. Общий подход такой: 
1) Хранишь охватывающий прямоугольник для каждого объекта - для ускорения: первая проверка - попадание точки в этот экстентю Или наличие пересечения экстента с прямоугольником выделения.
2) Дальше (если в прямоугольник попали) нужно вызывать функцию, свою для каждого типа объекта, скажем вирт. функция HitTest. Для прямоугольника она тривиальна (собственно, уже выполнена при проверке экстента). Для провода это - поиск пересечения каждого сегмента с прямоугольником. И т.д.


--------------------
...
PM   Вверх
TGrey
Дата 29.1.2010, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Ну вот я и думаю, что такой способ будет работать только с круглыми объектами, которые даже при повороте не изменяет форму, а остальное нужно искать по пересечениям.
Пойду искать формулы.
PM MAIL   Вверх
TGrey
Дата 30.1.2010, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



В общем решил делать след. образом: Сперва проверять точки на линии, находятся ли они внутри прямоугольника, если так - выделять. Если по точкам ничего не выделило, тогда использую формулы пересечения двух прямых, линии и каждой части прямоугольника. Пока работает и ЦП не грузит.
PM MAIL   Вверх
GremlinProg
Дата 30.1.2010, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(TGrey @  30.1.2010,  17:45 Найти цитируемый пост)
В общем решил делать след. образом: Сперва проверять точки на линии, находятся ли они внутри прямоугольника, если так - выделять. Если по точкам ничего не выделило, тогда использую формулы пересечения двух прямых, линии и каждой части прямоугольника. Пока работает и ЦП не грузит.

со сложными объектами работай как с совокупностью простых: ломаная - набор отрезков, вот и работай со всеми ее отрезками,
отрезок же - простой объект

если хоть один отрезок пересекает выделение, значит пересекает и вся ломаная


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
TGrey
Дата 31.1.2010, 00:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: 1
Всего: 1



Да уже именно так и сделал.

Это сообщение отредактировал(а) TGrey - 31.1.2010, 00:30
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0542 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.