Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   алгоритм прилипания панелек при перетаскивании (http://www.flasher.ru/forum/showthread.php?t=178573)

anmelegov 24.04.2012 17:30

алгоритм прилипания панелек при перетаскивании
 
Вложений: 1
есть некий интерфейс с панельками, которые можно перетаскивать драг эн дропом, я хочу сделать так чтобы панельки "прилипали" друг к другу, а не наезжали друг на друга... каритнка
Вложение 27910
красным цветом показано как сейчас, синим как я хочу сделать. По идее алгоритм простой, но к концу рабочего дня что-то уже совсем не думается...

Добавлено через 2 минуты
П.С. точка 0,0 панелек в левом верхнем углу

wvxvw 24.04.2012 21:23

Я бы делал сетку и записывал в нее свободные/занятые ячейки. Каждая панелька имела бы заданый размер в ячейках сетки. Чтобы проверить помещается ли панелька ничего лучше обычного перебора всех ячеек сетки не придумать, если минимальный размер панели = одна ячейка. Алгоритм поиска положения ближжайшего к текущему неподходящему наверное проще всего сделать имитируя физику т.е. "прикладывая силу" двигать панельку в каком-то направлении, пока ее нельзя полностью поместить. Почти наверняка есть более сложные алгоритмы как разместить объект на сетке, но почти так же наверняка они более сложные. В общем, этот класс проблем известен как http://en.wikipedia.org/wiki/Packing_problem

expl 24.04.2012 22:15

ИМХО какая сетка, зачем сетка?
- Задаемся допуском TOLERATE, начиная с которого всё будет прилипать;
- берем таскаемую панельку;
- гоним циклом по всем остальным (сложность линейная, не квадратичная - ничего страшного);
- смотрим i-ю панельку если Math.abs(panelI.x - draggedPanel.x) < TOLERATE - то делаем draggedPanel.x = panelI.x и прекращаем перебор;
- снова перебираем панельнки, но делаем то же самое уже для y-координаты.
Вот вобщем-то и всё. Только лучше дополнительно учесть, что если Math.abs(panelI.x - draggedPanel.x) < TOLERATE, но по y панельнки друг друга не перекрывают - то ничего делать не нужно.

Wolsh 24.04.2012 23:47

Оторвать не сможешь.

Aquahawk 24.04.2012 23:53

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

Wolsh 24.04.2012 23:53

Строго говоря задача нерешаема, так как нет никакой гарантии, что есть вообще свободное место, в которое панель поместится, не перекрывая ни одну другую панель. Следовательно необходимо при перегруппировке решать и этот конфликт – то есть перемещать еще и остальные панели, чтобы освободить место для таскаемой. И всё это – только при заданном условии, что площадь всех панелей меньше площади экрана.

Aquahawk 24.04.2012 23:54

А обнаружение столкновений для прямоугольников оси стороны которых параллельны осям придумно уже много очень быстрых алгоритмов, AABB и прочие деревья.

Добавлено через 2 минуты
Я так понимаю в начальных условиях панельки как-то расположены и юзер тащит мышкой панель, и надо чтоб она прилепалаи объезжала имеющиеся. В таком случае просто пытаемся помещать панель туда куда юзер указывает курсором, чекаем коллизии и потом резолвим двигая только одну панель, ту которую юзер тащит, а то что она при этом может выехать за границы экрана, так я не вижу в этом особого криминала.

expl 25.04.2012 00:07

Цитата:

Оторвать не сможешь.
Чтой-то вдруг? Пользователь оттащил больше чем на допуск - отлепилось. Их же не надо прилепленными таскать, насколько я понял.

Wolsh 25.04.2012 00:44

А, ну если снепить только по отпускании, это конечно проще.
Но попробуйте рассматривать не идеальные ситуации, а возможные.
Как бы в этом задача программиста – сделать не так чтобы нечто работало при соблюдении 100500 идеальных условий, а чтобы работало в случае 100500 враждебных.
Вот на картинке топикстартера представьте что синий прямоугольник УЖЕ там стоит, а красную панельку вот в этом месте отпустили. Куда ей бедной прыгать?
Эта ситуация похожа на надуманную, или она будет происходить в 80% случаев?

anmelegov 25.04.2012 12:05

кароче проще забить да?

Добавлено через 5 минут
ладно, а если не учитывать перекрытие других панелек и прилипать только к той, по которой первым срабатывает хитТест, то какой самый простой способ?


Часовой пояс GMT +4, время: 15:59.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.