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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Изменение Z-order-а, хранящегося в бинарном дереве, редактор векторной графики 
V
    Опции темы
KasMP
Дата 5.7.2009, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

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



Приветствую вас, мои любимые smile !

Позволю себе написать немного больше, чем нужно для ответа на мой вопрос smile - картина получится более полной, проще будет сориентироваться...


Есть (точнее, будет) редактор векторной графики. В нем есть (будет) класс фигура и несколько его наследников (конкретных графических примитивов - линия, эллипс, прямоугольник, кривая Безье, что-то еще).

Предположим, мы
  •  прочитали несколько фигур из файла,
  •  собственные параметры каждой храним сейчас в списке/массиве/т.п. ("собственные" значит "несвязанные с другими фигурами"; т.е. это все, что нужно, чтобы нарисовать эту фигуру отдельно от других; а вот как эта фигура располагается относительно других (взять хотя бы тот же Z-order) собственные параметры не знают),
  •  нарисовали фигуры в том порядке, в котором прочитали,
  •  сохранили этот порядок в бинарное дерево.
Теперь по щелчку на какой-то фигуре мы должны начать что-то делать с ней. Короче, нам надо определить, по какой именно фигуре щелкнули (другими словами, узнать ее индекс в массиве).
Я вижу только один вариант: после любого щелчка запоминать его координаты и с учетом Z-order обходить весь массив, проверяя принадлежность координат щелчка каждой фигуре. Но ведь это нонсенс smile smile !

Помогите, пожалуйста.

Добавлено через 3 минуты и 36 секунд
Что-то название темы совсем не отражает ее суть smile smile . Не знаю, как изменить его smile.
PM MAIL   Вверх
Lazin
Дата 5.7.2009, 13:13 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



можно использовать эту структуру данных, для эффективного поиска по координатам
http://en.wikipedia.org/wiki/Quadtree
PM MAIL Skype GTalk   Вверх
KasMP
Дата 5.7.2009, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

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



Lazin, спасибо большое, посмотрю smile .
А других вариантов совсем нет smile ?
PM MAIL   Вверх
Lazin
Дата 5.7.2009, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



AFAIK, проще только метод грубой силы smile  
PM MAIL Skype GTalk   Вверх
Alexeis
Дата 5.7.2009, 22:56 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(KasMP @  5.7.2009,  20:17 Найти цитируемый пост)
А других вариантов совсем нет

  Можно проще, сделать равномерную сетку, скажем 10х10 и соответствующую ей матрицу, каждый элемент это список фигур, которые пересекают эту клетку. Соответственно по координатам мыши путем округления сразу получаем нужную клетку, дальше остается перебор внутри этой клетки. В случае сетки 10х10 объем вычислений в среднем уменьшиться в 100 раз. Скажем при 1000 фигурах, перебор в среднем будет среди 10ти фигур, при 10000 их уже будет в среднем сотня. 
  Для простого редактора этого должно быть достаточно. Я применял такой алгоритм, когда писал двумерную модель столкновения атомов. Задача была аналогичной не делать перебор n (n - 1) фигур на каждый кадр.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Lazin
Дата 5.7.2009, 23:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Alexeis, а что, если все фигуры будут пересекать одну клетку? smile 
PM MAIL Skype GTalk   Вверх
Alexeis
Дата 5.7.2009, 23:13 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(Lazin @  5.7.2009,  22:00 Найти цитируемый пост)
Alexeis, а что, если все фигуры будут пересекать одну клетку?

  Тогда будет полный перебор. Согласись это не типичный случай, тем более в случае редактора. Фигуры как-то распределены. Да и сетку можно варьировать, если площадь растет. Это не универсальное решение, зато оно проще. Если есть готовое решение Q-Tree, то конечно же лучше использовать его, но самому писать такое задача не для новичка.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Earnest
Дата 6.7.2009, 08:00 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



KasMP, не парься. Нормально написанная проверка PtInFigure занимает очень маленькое время при просмотре тысяч объектов (даже десятков тысяч). Сначала, конечно, проверь попадание точки в экстент фигуры. Пространственный индекс начинает быть нужным при 1) значительно бОльшем числе объектов 2) при необходимости реагировать, скажем, на движение мыши (а не на клики). Поверь, это было быстро еще несколько лет назад, при значительно менее мощных компьютерах. Во втором случае нужно строить пространственный индекс ребер, попавших в экран. Тогда тоже будет быстро. В смысле, не будет видимых пользователю задержек.


--------------------
...
PM   Вверх
Lazin
Дата 6.7.2009, 08:04 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Earnest, в целом согласен, но все это добро еще нужно отрендерить, для этого нужно отсечь все то, что не будет видно, без пространственного индекса это сложно сделать smile 
PM MAIL Skype GTalk   Вверх
Earnest
Дата 6.7.2009, 08:14 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Смотря какой сложности фигуры. Если это полигоны с простыми текстурами (заливками), в количестве нескольких тысяч, то все будет летать без всякого индекса. Достаточно проверки попадания в экстент. Виндоус и сам прекрасно отсекает... Я имею в виду использование GDI.
Нет, конечно, можно постараться и написать тормозной код... видела и такое smile 

Кстати, автор спрашивал только про поиск.

Добавлено через 5 минут и 34 секунды
Я это к тому, что поддержка индекса тоже кое-чего стоит, как на уровне дизайна, так и на уровне ресурсов и времени.
Скажем, точки просто рассовать по кластерам, а уже с ребрами все сильно сложнее, чего уж говорить о полилиниях-полигонах. Да еще когда все это добро постоянно меняется...
Размер кластера, кстати, тоже важно правильно выбрать - не мельчить ни в коем случае, только хуже будет.


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


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

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



Цитата(Lazin @  5.7.2009,  22:11 Найти цитируемый пост)
AFAIK, проще только метод грубой силы smile   

А я не говорила про проще smile .
Но как красиво ты назвал самый примитивный перебор user posted image !
Цитата(Alexeis @  5.7.2009,  22:56 Найти цитируемый пост)
Можно проще, сделать равномерную сетку, скажем 10х10 и соответствующую ей матрицу, каждый элемент это список фигур, которые пересекают эту клетку. Соответственно по координатам мыши путем округления сразу получаем нужную клетку, дальше остается перебор внутри этой клетки. В случае сетки 10х10 объем вычислений в среднем уменьшиться в 100 раз. Скажем при 1000 фигурах, перебор в среднем будет среди 10ти фигур, при 10000 их уже будет в среднем сотня. 

Интересный вариант с округлением smile .
Но здесь сразу же всплывают две сложно решаемые проблемы:
  • В случаях типа этого 
    user posted image
    (т.е. когда несколько фигур полностью лежат в одном квадрате сетки; пересекаются они или нет, не важно)
    мы при любом щелчке внутри квадрата всегда будем попадать только на одну фигуру - на первую в Z-order-е квадрата (в случае наложения) или на просто первую среди тех, которые лежат в квадрате; другими словами, нам будет доступна только одна фигура из квадрата сетки, до всех остальных мы никогда не сможем дотянуться.
  • Ну и неточность... Щелкаем по "пустому" месту, а попадаем в фигуру, потому что это место принадлежит квадрату сетки, в котором что-то есть.  Но это скорее не проблема, а естественная плата за экономию ресурсов и округление...

Цитата(Alexeis @  5.7.2009,  22:56 Найти цитируемый пост)
когда писал двумерную модель столкновения атомов
smile  smile
Интересно.
Цитата(Earnest @  6.7.2009,  08:00 Найти цитируемый пост)
KasMP, не парься. Нормально написанная проверка PtInFigure занимает очень маленькое время при просмотре тысяч объектов (даже десятков тысяч). Сначала, конечно, проверь попадание точки в экстент фигуры. Пространственный индекс начинает быть нужным при 1) значительно бОльшем числе объектов 2) при необходимости реагировать, скажем, на движение мыши (а не на клики). Поверь, это было быстро еще несколько лет назад, при значительно менее мощных компьютерах. Во втором случае нужно строить пространственный индекс ребер, попавших в экран. Тогда тоже будет быстро. В смысле, не будет видимых пользователю задержек. 

Спасибо smile ! Поразбираюсь с PtInFigure...
Но что такое "экстент" smile? Пожалуйста, пишите английские термины английскими буквами... Я еще не привыкла к ним настолько сильно smile. 
Цитата(Earnest @  6.7.2009,  08:14 Найти цитируемый пост)
Кстати, автор спрашивал только про поиск.

Мммм... На всякий случай уточню: после нажатия левой кнопки (и определения фигуры, по которой щелкнули) мышка потащит фигуру куда-нибудь и там оставит (отпустили кнопку). Т.е. движение все-таки есть. Но как я понимаю, от массива объектов нам действительно нужен только поиск, выбор одного объекта, изменение его собственных параметров (новое местоположение) и изменение Z-order всего того, что связано с перемещением.
PM MAIL   Вверх
Alexeis
Дата 6.7.2009, 22:28 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



Цитата(KasMP @  6.7.2009,  20:34 Найти цитируемый пост)
(т.е. когда несколько фигур полностью лежат в одном квадрате сетки; пересекаются они или нет, не важно)
мы при любом щелчке внутри квадрата всегда будем попадать только на одну фигуру - на первую в Z-order-е квадрата (в случае наложения) или на просто первую среди тех, которые лежат в квадрате; другими словами, нам будет доступна только одна фигура из квадрата сетки, до всех остальных мы никогда не сможем дотянуться.

  Не будет такого. Все проверки остаются, только уменьшается список того что проверять, остается только список этой клетки, а он меньше во много раз. Большой перебор заменяется маленьким.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
KasMP
Дата 6.7.2009, 22:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 586
Регистрация: 8.8.2006

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



Цитата(Alexeis @  6.7.2009,  22:28 Найти цитируемый пост)
Не будет такого. Все проверки остаются, только уменьшается список того что проверять, остается только список этой клетки, а он меньше во много раз. Большой перебор заменяется маленьким. 

Упс, как все просто smile .
Т.е. получается 2 этапа перебора, причем на первом многое (очень многое) отсекается. Понятно все. Хороший способ, вполне подходящий smile . Благодарю smile.

Посмотрим еще smile ...

Добавлено через 3 минуты и 26 секунд
Цитата(Earnest @  6.7.2009,  08:14 Найти цитируемый пост)
Смотря какой сложности фигуры. Если это полигоны с простыми текстурами (заливками), в количестве нескольких тысяч,

Это будут самые простые граф.примитивы - эллипсы, прямоугольники (даже не многоугольники!), прямые, кривые, ... . И их количество в самом страшном случае не превысит 30 smile smile .

P.S.. Кстати, у меня возникает мысль, что решение проблемы кроется больше не в WinAPI, а в алгоритмах...
PM MAIL   Вверх
Lazin
Дата 6.7.2009, 22:54 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



Цитата(KasMP @  6.7.2009,  22:38 Найти цитируемый пост)
И их количество в самом страшном случае не превысит 30

тогда забудь все что мы тут написали и
Цитата(Earnest @  6.7.2009,  08:00 Найти цитируемый пост)
не парься

и делай все простым перебором smile 
PM MAIL Skype GTalk   Вверх
Earnest
Дата 7.7.2009, 07:25 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(KasMP @  6.7.2009,  23:38 Найти цитируемый пост)
И их количество в самом страшном случае не превысит 30

Тогда можно делать в цикле раз 100 (ну, чтобы точно не ошибиться) smile 
Никто не заметит...
Экстент - это прямоугольник со сторонами, параллельными координатным осям, описанный вокруг фигуры. Extent(s). Извини, если не точно выразилась, привыкла я эту хрень так называть. Вычисляется просто, можно хранить вместе с фигурой и проверка PtInRect очень простая и быстрая (если прямоугольник нормализован, т.е. left <= right и top <= bottom).... Функция "PtInFigure" - фигуральное выражение, для каждой фигуры надо писать свою проверку, и хорошо бы с учетом точности попадания.



--------------------
...
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.0612 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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