Как растут ледяные узоры на стекле?
Всё начинается с нескольких точек кристаллизации, из которых прорастают ледяные лучики. Затем от каждого лучика появляются ветки — прямо и ±60°. Когда ветка упирается в уже имеющийся ледяной узор, её рост прекращается.
. К>Давайте в этом попробуем кое-что другое.
Я даже боюсь представить, что мы нарисуем к 2010 году
К>Как растут ледяные узоры на стекле? К>Всё начинается с нескольких точек кристаллизации, из которых прорастают ледяные лучики. Затем от каждого лучика появляются ветки — прямо и ±60°. Когда ветка упирается в уже имеющийся ледяной узор, её рост прекращается.
Что-то типа волнового алгоритма просится. Только двумерное пространство стекла топологически преобразуется — все точки проростания сводятся в одну (из нее начинается фронт волны). Т.е. расстояние между любыми такими точками равно нулю. А расстояние между остальными — минимуму из "прямого расстояния" и "расстояния через ближайшие точки проростания". Это как телепортеры на карте стратегии.
Конечно надо еще подумать насчет не дискретности пространства и переменной длины лучей.
. К>Давайте в этом попробуем кое-что другое.
К>Как растут ледяные узоры на стекле? К>Всё начинается с нескольких точек кристаллизации, из которых прорастают ледяные лучики. Затем от каждого лучика появляются ветки — прямо и ±60°. Когда ветка упирается в уже имеющийся ледяной узор, её рост прекращается.
К>Вот такая тема для скринсейвера Возьмётесь?
Что-то я не то с рекурсией делаю... rundll32 зависает при переключение скринсейверов
I'm the hero I'm back
With weapons and with magic spells
Здравствуйте, Crab, Вы писали:
C>Что-то я не то с рекурсией делаю... rundll32 зависает при переключение скринсейверов
Ну если ты всё рисуешь в одном глубоком погружении, то конечно. А кто будет оконные события обрабатывать?
Тут нужно или делать машину состояний, или многопоточное (многофиберное?) приложение.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, Crab, Вы писали:
C>>Что-то я не то с рекурсией делаю... rundll32 зависает при переключение скринсейверов
К>Ну если ты всё рисуешь в одном глубоком погружении, то конечно. А кто будет оконные события обрабатывать? К>Тут нужно или делать машину состояний, или многопоточное (многофиберное?) приложение.
Здравствуйте, Кодт, Вы писали:
К>Как растут ледяные узоры на стекле? К>Всё начинается с нескольких точек кристаллизации, из которых прорастают ледяные лучики. Затем от каждого лучика появляются ветки — прямо и ±60°. Когда ветка упирается в уже имеющийся ледяной узор, её рост прекращается.
Немного домыслено и подправлено, чтобы получилось покрасивее.
. К>Давайте в этом попробуем кое-что другое.
К>Как растут ледяные узоры на стекле? К>Всё начинается с нескольких точек кристаллизации, из которых прорастают ледяные лучики. Затем от каждого лучика появляются ветки — прямо и ±60°. Когда ветка упирается в уже имеющийся ледяной узор, её рост прекращается.
К>Вот такая тема для скринсейвера Возьмётесь?
вот :shuffle:
никак не прочитал у NeHe туториал о том, как скринсейверы делать... так-что уж exe-шником если позолите
P.S. интересно а как сделать эффект запотевшего стекла...
Здравствуйте, hemmul, Вы писали:
H>никак не прочитал у NeHe туториал о том, как скринсейверы делать...
Ищем в MSDN по строкам scrnsave.lib/scrnsave.h Надо написать 3 callback функции из которых одна это простая оконная процедура, а две другие могут быть пустыми.
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, hemmul, Вы писали:
H>>вот :shuffle:
A>У меня всё размазалось и проц на 100% загрузился. Ограничений по разрешению нет? У меня рабочее 1600х1200 — не много?
У меня всё нормально запустилось. Только ме-е-едленно. И лучики почти всегда друг-друга "пробивают" насквозь, вместо того, чтобы останавливаться.
А вообще, понятно, что идея в том голом виде, в котором она была предложена, не даёт красивой картинки... Надо её как-то развивать и домысливать. Например, случайности добавить.
Здравствуйте, XopoSHiy, Вы писали:
XSH>Здравствуйте, adontz, Вы писали:
A>>У меня всё размазалось и проц на 100% загрузился. Ограничений по разрешению нет? У меня рабочее 1600х1200 — не много?
многовато будет
XSH>У меня всё нормально запустилось. Только ме-е-едленно. И лучики почти всегда друг-друга "пробивают" насквозь, вместо того, чтобы останавливаться.
да, это точно — медленно потому что я пересечения каждого лучика со всеми отсальными по дереву проверяю (кроме его родителей и детей, но всё равно ясно что долго очень). а вот пробивают они друг друга насквозь не всегда: я сделал так, что если точка пересечения отстоит от конца луча менее чем на N поцентов — луч останавливается... если нет — продолжает ползти (т.е. это зачит, что если луч А въехал в бок лучу Б, то луч А остоновится, а Б продолжит ползти...)
XSH>А вообще, понятно, что идея в том голом виде, в котором она была предложена, не даёт красивой картинки... Надо её как-то развивать и домысливать. Например, случайности добавить.
пока -- только для единственного центра кристаллизации.
Идея такова: имеется очередь "лучиков" на связном списке. Проходимся по списку, для каждого "лучика" проверяем, не пересекся ли он с другими. Если пересекся, то корректируем его длину и отрисовываем. Если не пересекся -- то отрисовываем, а также добавляем 2 лучика (его продолжение и отпочковавшийся) в конец очереди.
Думаю, надо 1. доработать модель, выдающую случайные длины "прямого" и "отпочкованного" лучиков. 2. Сделать для нескольких центров кристаллизации 3. Что-то придумать, чтобы не тестировать текущий лучик на пересечение со всем списком, а только с той частью, где пересечение наиболее вероятно
Здравствуйте, Пономарёв Иван, Вы писали:
ПИ>новая версия :user:
ПИ>1. Подчищен код и убрана утечка памяти :shuffle: ПИ>2. Добавлена имитация возникновения новых центров кристаллизации ПИ>3. Длина лучиков стала поменьше (соответственно, лучиков стало больше и программа -- медленнее).
Несколько придирчевых замечаний:
1. Не обрабатываются оконные сообщения (Вставь куда-нибудь Application.ProcessMessages — и всё пройдёт)
2. Если на форму бросить TImage и рисовать на его канве, а не на канве формы, то рисунок будет сохраняться при перерисовке формы (т.е. после Alt+Tab, Alt+Tab)
3. Чего-то они отпочковываются только в одну сторону... смотрится как что-то закручивающееся :)
4. Центры кристалицайии не всегда в пределах окна.
5. Поставь Position у формы в какое-нибудь приличное значение, типа poScreenCenter, а то она появляется у меня где-то наполовину за краем экрана :)
6. Мне показалось, или лучики всё таки иногда пересекаются?
Как избавится от тормозов:
Первый вариант: можно использовать для хранения лучиков не простой список, а что-нибудь типа квадродерева. Но это муторно и лениво.
Второй вариант — как это у меня сделано: лучик каждый раз растёт на 1 пиксель и перед тем как пиксель поставить, он проверяет окрестность на свободность. Эта проверка — банальное сравнение цвета пикселя с цветом фона. Таким образом проверка "можно ли лучику вырасти" осуществляется за O(1), а не за O(n), как у тебя.
Для сравнения, квадродеревья дадут сложность что-то около O(log(n)) для этой операции.
PS. Я всё жду, когда же тут появится вариант, который:
а) имеет какое-нибудь отношениие к модели роста инея на стекле
б) будет красиво смотреться в качестве ScreenSaver-а.
Здравствуйте, XopoSHiy, Вы писали:
XSH>Как избавится от тормозов: XSH>Первый вариант: можно использовать для хранения лучиков не простой список, а что-нибудь типа квадродерева. Но это муторно и лениво.
так и делаем-с...
XSH>Второй вариант — как это у меня сделано: лучик каждый раз растёт на 1 пиксель и перед тем как пиксель поставить, он проверяет окрестность на свободность. Эта проверка — банальное сравнение цвета пикселя с цветом фона. Таким образом проверка "можно ли лучику вырасти" осуществляется за O(1), а не за O(n), как у тебя.
класс! где Вы раньше были?
XSH>1. Не обрабатываются оконные сообщения (Вставь куда-нибудь Application.ProcessMessages — и всё пройдёт)
Да вставлено, вставлено всё равно он ждет, когда метод отрисовки закончится. Я думаю, что в следующей версии надо выносить отрисовку в отдельную нить. Так, чтобы можно было выбрать "STOP" и "PAUSE"
XSH>2. Если на форму бросить TImage и рисовать на его канве, а не на канве формы, то рисунок будет сохраняться при перерисовке формы (т.е. после Alt+Tab, Alt+Tab)
Можно, я знаю. Но TImage -- он хранит свой битмап в памяти. Я из соображений минимизации ресурсов сделал отрисовку на форме. Ведь, если это будет скринсейвер -- то не всё ли равно?
XSH>3. Чего-то они отпочковываются только в одну сторону... смотрится как что-то закручивающееся
Да. Пока только в одну сторону. Я уже думал о том, что надо бы в обе стороны, причем сделать, как у тебя -- лучик "хранит" информацию о том, куда он почкуется, и переход на другую сторону осуществляется с малой вероятностью. Я, наверное, так сделаю в следующей версии (наряду с пунктом 1)
XSH>4. Центры кристалицайии не всегда в пределах окна.
У меня немного некорректно там передается информация о размерах окна, это я подправлю.
XSH>5. Поставь Position у формы в какое-нибудь приличное значение, типа poScreenCenter, а то она появляется у меня где-то наполовину за краем экрана
Справедливое замечание. Но делалось-то всё как? На самую что ни на есть скорую руку, лишь бы работало
XSH>6. Мне показалось, или лучики всё таки иногда пересекаются?
Нет, не показалось. Объясняю, почему. У меня программа ищет (аналитически!) для каждого лучика тот лучик, который с ним пересекается. Когда находится первый, поиск прекращается. При этом, могут существовать лучики, с которыми текущий пересекается раньше. Чтобы этого избежать, я не должен прекращать поиск на первом попавшемся лучике, а проработать всю очередь до конца. Если б то была серьёзная программа для научных исследований, я б так и сделал... А пока... пока моя прога не работает достаточно быстро, я решил забить на этот эффект.
XSH>Как избавится от тормозов: XSH>Первый вариант: можно использовать для хранения лучиков не простой список, а что-нибудь типа квадродерева. Но это муторно и лениво.
Би-дерево -- знаю, а вот квадро... Век живи -- век учись, как говорится Попробую что-нибудь на эту тему почитать. Или может напишешь в двух словах, как это (применительно к данной задаче)? На самом деле, первое, что я хочу попробовать -- это сделать список двусвязным и проходить его при поиске не с начала, а с конца. Ведь наиболее вероятно, что лучик пересекается с тем, который недавно был отрисован и находится рядом в очереди. Возможно, это так -- надо эксериментировать.
XSH>Второй вариант — как это у меня сделано: лучик каждый раз растёт на 1 пиксель и перед тем как пиксель поставить, он проверяет окрестность на свободность. Эта проверка — банальное сравнение цвета пикселя с цветом фона. Таким образом проверка "можно ли лучику вырасти" осуществляется за O(1), а не за O(n), как у тебя.
Я заметил, как у тебя сделано. Но так я делать не хочу Я хочу получить именно структуру в памяти, по которой всегда можно отрисовать узор, увеличить его до нужного масштаба...
XSH>Для сравнения, квадродеревья дадут сложность что-то около O(log(n)) для этой операции.
Можешь написать в двух словах идею?
XSH>PS. Я всё жду, когда же тут появится вариант, который: XSH>а) имеет какое-нибудь отношениие к модели роста инея на стекле XSH>б) будет красиво смотреться в качестве ScreenSaver-а.