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

Пузыри и сотовая связь

Мыльный пузырь, пожалуй, самое восхитительное
и самое изысканное явление природы.

Марк Твен

Из многих замечательных и до конца не изученных свойств воды самым потрясающим является, конечно же, эффект поверхностного натяжения. Благодаря ему струйка из крана становится тоньше и разрывается, роса на траве выпадает в виде капелек, а пылинки держатся на поверхности лужи. Пена и пузыри — фантастические объекты, они привлекательны не только с эстетической точки зрения, но и тем, что тянут за собой шлейф занимательных задач.

Часто бывает, увидишь картинку, придумаешь алгоритм, а идея не отпускает. Так вот и с пузырями. Суть в том, что на плоскости случайным образом задаются точки, и из них, как из центров, строятся окружности с увеличивающимися радиусами и уменьшающейся яркостью. В каждой точке плоскости цвет берется от окружности с большей яркостью, т.е. от ближайшей. На картинке получается нечто похожее на взбитую пену.


Программа рисования пузырей несложная. Задается их количество, случайным образом выбираются координаты, потом в цикле проходятся все точки плоскости с определением расстояния до ближайшего центра, и соответственно этому расстоянию уменьшается яркость. Небольшое замечание: предварительно экран стоит перевести в режим 24-битного представления цвета.


Увеличив количество пузырей до 100 или 200, получим пену, похожую на легкие или какие-то другие объекты явно биологического происхождения.

Продолжая увеличивать количество пузырей, мы заставим их тесниться и уплотняться, в связи с чем возникают интересные вопросы. Сколько соседей в среднем у каждого пузыря и как эта величина зависит от плотности размещения? Влияют ли скорость уменьшения яркости и рост радиуса на вид пены (на количество соседних пузырей)? Нет ли здесь каких-нибудь фрактальных закономерностей, связанных с размерностью объектов, и если да, то как определить фрактальную размерность пузырей? Или еще — интересно, мыльная пена такая же, как пивная, или ее параметры зависят от коэффициента поверхностного натяжения?

А при чем здесь, спросите вы, сотовая связь? Очень просто. Мобильный телефон с помощью компьютера выбирает антенну, от которой идет самый сильный сигнал, обычно она оказывается ближайшей. При перемещении телефона его сопровождение передается от одной антенны к другой, с самым сильным сигналом для данной точки. Лучшей иллюстрации этого процесса, чем наша картинка с пузырями, не найти.

Приступим к делу. Создадим форму с кнопкой «Пуск». Присвоим свойству формы ScaleMode значение Pixel.

Private Sub Command1_Click()
Dim vc(), yc(), r()
Cls
Randomize (Timer)
xmax = 650
ymax = 530
v = 5 ' Количество пузырей, передается из формы
ss=6 ' Шаг движения по x  и y, передается из формы
ReDim xc(v), yc(v), r(v)
For i = 1 To v
   xc(i) = Rnd * xmax
   yc(i) = Rnd * ymax
Next i

For x = 5 To xmax Step ss
 For y = 5 To ymax Step ss
  For q = 1 To v
   r(q) = ((xc(q) - x) ^ 2 + (yc(q) - y) ^ 2) ^ 0.5
  Next q
For k = 1 To v - 1
For j = 1 To v - 1
If r(j) > r(j + 1) Then
  uu = r(j)
r(j) = r(j + 1) r(j + 1) = uu End If Next j, k red = 255 - Int(r(1)) green = 255 - Int(r(1) * 1.3) blue = 255 - Int(r(1) * 1.1) If red < 0 Then red = 0 If green < 0 Then green = 0 If blue < 0 Then blue = 0 Col = RGB(red, green, blue) If ss > 1 Then Line (x, y)-Step(ss, ss), Col, BF If ss = 1 Then PSet (x, y), Col Next y Next x End Sub

Процедура обработки нажатия кнопки «Пуск», запускающая процесс появления пены, проста и прозрачна. Количество пузырей, точнее, размерность массивов (переменная v), в которых расположены координаты центров и радиуса, передается из формы. Причем массив сначала объявляется пустым, а позже оператором Redim задается его размерность. Цикл с переменной i задает центры пузырей случайным образом. Для того чтобы при каждом запуске датчик случайных чисел давал разные значения, привяжем его к текущему времени — Randomize(timer). В цикле с переменной q по теореме Пифагора вычисляем для каждой точки с координатами x и y расстояние до каждого из центров пузырей r(q), чтобы выбрать наименьший из них. Выбор происходит в циклах с переменными k и j. Разберетесь, как они работают — получите удовольствие от приобщения к классике программирования: сортировке элементов массива методом пузырьков. (Это не каламбур, название метода не имеет отношения к теме статьи, просто с каждым проходом цикла меньшие числа «всплывают вверх». Вообще, переменная uu и присвоение ей значения r(j+1) нужны только в случае сохранения всего массива для дальнейшей работы, нас же интересует только наименьшее значение r(1), поэтому цикл можно сократить на две строки, имеющие, скорее, методический смысл.)

Получив минимальный радиус для текущей точки, можно приступать к формированию цвета — это и есть изюминка всей затеи. Каждая составляющая rgb-функции цвета уменьшается пропорционально радиусу. Меняя коэффициенты и максимальное значение, равное в примере 255, на меньшее, можно получать различные оттенки пены и регулировать контрастность рисунка.


Скачать пример

Программа предоставляет безграничный простор для экспериментов. Попробуйте сделать так, чтобы яркость не уменьшалась с удалением от центра пузыря, а увеличивалась, и вы будете поражены получившейся картиной. Попробуйте при вычислении радиуса поменять показатель степени с 0,5 на 0,55 или 0,45 (поэтому мы и не воспользовались функцией Sqr). Попробуйте вместо формулы r2=x2+y2 применить r2=x2-y2, чтобы получить нечто гиперболическое… А бесконечные игры с цветами, шагом и количеством пузырей... Естественно, что с уменьшением шага рисования и увеличением количества пузырей время рисования возрастает, т.к. в каждой точке рисунка проверяются расстояния до всех центров пузырей, а любые попытки оптимизировать алгоритм лишь замедлят работу программы. А что если разукрасить пузыри — каждый в свой цвет? Тут придется поработать, ведь нужно не только задать массив цветов для каждого пузыря и заполнить его случайным образом, но и, отслеживая соответствие каждой точки плоскости ближайшему центру, запоминать еще его цвет. Это непросто, потому что при выборе наименьшего радиуса его индекс в массиве теряется. Задача, конечно, решаемая, и если вы с ней справитесь, то будете сторицей вознаграждены получившейся картиной. Экран заполняется разноцветными шариками, как в моделях сложных молекул, или одинокими фонариками — в зависимости от ваших настроек.

Вот и все. Как ни странно, нам удалось связать вместе пену, Visual Basic и мобильники. Отладка программы и попутные опыты доставят вам массу удовольствия. Задание на дом: научите пену бурлить, чтобы некоторые пузыри лопались, а соседи занимали их место. Да, и не забудьте выложить изображения на свой сайт… Созерцание пузырей рождает прекрасные мысли, недоступные в обыденной суете. Может, в этом и состоит их предназначение? Поразмышляйте об этом на досуге.

Реклама


Для писем: rusproject@mail.ru
© 2002 А.Климов