Водяные опыты юных физиков

Перепечатано с сокращениями

пример для статьи - volna.zip

Коснитесь двумя пальцами поверхности воды, повибрируйте ими и вы увидите картину совмещения или интерференции волн от двух источников. Меняя расстояние между пальцами, фазы колебаний пальцев и наблюдая за тенью водной поверхности на дне ванны, вы откроете для себя много нового.

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

Это и есть интерференция волн от двух когерентных источников. Так и хочется сказать, что мы видим стоячие волны, но сомневаюсь, могут ли быть стоячие волны у электромагнитного излучения, хотя может нечто подобное происходит в лазерах? Кстати здесь мы прикасаемся к чуду, предсказанному теоретиками - эти два кванта света, близнецы, получившиеся при дифракции, в дальнейшем поддерживают друг с другом связь и изменения условий распространения одного из них непонятным образом становится известным второму. Возможно, здесь заложены перспективы столь любимых фантастами передачи информации быстрее света, сверхмощных квантовых компьютеров и всяких нуль-транспортировок материи. И наши опыты пусть маленький, но шажок в этом направлении, поэтому к листингу программы отнесемся трепетно.

Dim x1(), y1(), a1(), L1()Private Sub Command1_Click()' L - дистанция' ss- шаг прорисовки' num - количество отверстий    r = 100    pi = 4 * Atn(1)    x0 = 200    y0 = 200    L = CLng(txtDistance.Text)    ampl = 250    ss = CLng(txtStep.Text)    wr = 1.01    wg = 1.005    wb = 1    num = CLng(txtNumber.Text)    scal = 2    ReDim x1(num), y1(num), a1(num), L1(num)    For u = 1 To num    x1(u) = x0 + r * Cos(2 * pi * u / num)    y1(u) = y0 + r * Sin(2 * pi * u / num)    Next u    For x = 1 To x0 * 2 Step ss    For y = 1 To y0 * 2 Step ss    qr = 0: qg = 0: qb = 0    For u = 1 To num    L1(u) = ((x - x1(u)) ^ 2 + (y - y1(u)) ^ 2 + L ^ 2) ^ 0.5 / scal * 2    qr = qr + Int(ampl * Sin(L1(u) / wr))    qg = qg + Int(ampl * Sin(L1(u) / wg))    qb = qb + Int(ampl * Sin(L1(u) / wb))    Next u    If KeyAscii = 32 Then End    qrr = qr    If qrr < 0 Then qrr = 0    qgg = qg    If qgg < 0 Then qgg = 0    qbb = qb    If qbb < 0 Then qbb = 0    col = RGB(qrr, qgg, qbb)    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

В приведенной программе переменные L - расстояние от непрозрачной стенки с отверстиями вместо кристалла до экрана, ss - шаг прорисовки и num - количество отверстий. Переменная r это радиус окружности, на которой расположены отверстия, x0 и y0 - координаты центра этой окружности. Ampl - амплитуда колебания, выбирается с учетом того, что максимальное значение каждой из трех цветовых составляющих в формате RGB(red,blue,green) равно 255.

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

(Не объяснит ли кто-нибудь появление этих шариков, похожих на капли?) А при дистанции равной нулю наоборот, все три луча приходят вместе, что дает картинку почти черно-белую

Из-за того, что некоторые картинки давали слишком мелкую рябь, пришлось ввести возможность масштабирования (переменная scal).

Как вы уже заметили, при задании n отверстий появляется подобие n-угольника, который лежит в основе всего узора, растягиваясь и повторяясь. При увеличении количества отверстий появляются "соцветия" с количеством лепестков, равным количеству отверстий.

Размышляя над программой дифракции лучей, проходящих через отверстия в экране, и аналогией с колебаниями воды, придем к плодотворной мысли - выйти из плоского изображения в трехмерное. В каждой точке экрана можно определить не только цвет лучей, но и суммарную амплитуду колебания (в произвольном масштабе) в направлении оси Z перпендикулярно плоскости экрана XY.

Clsnum = CLng(txtNumber.Text)scal = CLng(txtScale.Text)    DrawWidth = 2    r = 100    pi = 4 * Atn(1)    x0 = 200    y0 = 200    L = CLng(txtDistance.Text)    ampl = 555 / num    ss = CLng(txtStep.Text)    wr = 1.01    wg = 1.005    wb = 1    num = CLng(txtNumber.Text)    ReDim x1(num), y1(num), a1(num), L1(num)    For u = 1 To num    x1(u) = x0 + r * Cos(2 * pi * u / num)    y1(u) = y0 + r * Sin(2 * pi * u / num)    Next u    xx1 = 0: yy1 = 0    For y = 1 To y0 * 2 Step ss    For x = 1 To x0 * 2 Step ss    qr = 0: qg = 0: qb = 0: z = 0    For u = 1 To num    L1(u) = -((x - x1(u)) ^ 2 + (y - y1(u)) ^ 2 + L ^ 2) ^ 0.5 / scal * 2    qr = qr + Int(ampl * Sin(L1(u) / wr))    qg = qg + Int(ampl * Sin(L1(u) / wg))    qb = qb + Int(ampl * Sin(L1(u) / wb))    z = z + ampl * Sin(L1(u)) / 5    Next u    If KeyAscii = 32 Then End    qrr = Abs(qr): qgg = Abs(qg): qbb = Abs(qb)    col = RGB(qrr, qgg, qbb)    xx = x * Cos(pi / 12) + z * Sin(pi / 12): yy = y + z * Cos(pi / 12)    If x > 1 Then Line (xx, yy)-(xx1, yy1), col    xx1 = xx: yy1 = yy    Next x    Next y

Для прорисовки нашей трехмерной модели в аксонометрии приведем расчетные оси X,Y и Z (локальной системы координат) к абсолютной системе координат нашего экрана, не того виртуального, а реального монитора. Локальная ось X пустим под 150 к горизонтали, ось Z под 150 к вертикали, ось Y оставим без изменения - по вертикали, то есть отклонения по локальной оси Z проектируются на абсолютные X и Y. Все эти значения можно менять, получая новые и новые картины.

Раскраску наших волн оставили без изменения - как при дифракции. Меняя масштаб, количество отверстий и расстояние до экрана вы будете получать картины невиданной красоты - радужные торты, марсианские пейзажи и объемные орнаменты. Поверхности рисуются плавными линиями, а те, в свою очередь, состоят из отрезков ломанных линий, проводимых от текущей рассчитываемой точки (xx,yy) к предыдущей посчитанной точке (xx1,yy1). В конце каждого цикла текущая точка "становится" предыдущей, вспомогательные координаты xx1 и yy1 получают значения xx и yy соответственно. Этот прием используется при рисовании трехмерных поверхностей и других геометрических моделей.

Радуга

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

Cls      pi = 4 * Atn(1)      wr = 15      wg = 12      wb = 14      DrawWidth = 4      For Ll = 1 To 500 Step 3      For r = 1 To 200 Step 5      fi = Atn(r / Ll)      red = 255 * ((Sin(fi * wr - pi / 8)) ^ 2)      green = 255 * ((Sin(fi * wg - pi / 8)) ^ 2)      blue = 255 * ((Sin(fi * wb - pi / 8)) ^ 2)      Circle (200, 200), r, RGB(red, green, blue)      Next r      Next Ll  

Примечание: Скриншот не приводится. Но, поверьте, картинка завораживает

Учитывая, что радужная картина зависит от расстояния между отверстием и экраном и не хочется пропустить какой-либо красивый вариант, будем менять это расстояние в цикле (переменная L1) от 1 до 500. Это позволит наблюдать на экране концентрические радужные круги, растущие от центра с постоянным изменением раскраски. Учтите, что если вы захотите сделать скриншот меняющихся радужных колец, то у вас всегда будет запоминаться последняя картинка, не зависимо от того, в какой момент вы нажимали Alt+Print Screen. Дело в том, что пока работает цикл и рисуется картинка, Visual Basic "берет на себя" все события Windows, все внешние команды откладываются до завершения цикла. Чем-то эти картинки похожи на радужную оболочку глаза, которая, как известно, содержит полную информацию об организме. А может, это монитор смотрит на нас с вами, причешитесь и улыбнитесь на всякий случай.

Реклама