Нелинейные поверхности и цветовые гаммы

Визуализация графиков функций двух переменных вида z=f(x,y) - часто возникающая практическая задача. Кроме того, эти нелинейные поверхности бывают невероятно интересных, красивых форм. Их исследование само по себе - крайне занимательный и поучительный процесс. Строить графики функций двух переменных на компьютере можно различными способами. В одном из прошлых номеров "КВ" уже обсуждался этот вопрос. Тогда речь шла о тоновой визуализации с использованием различных градаций серого цвета. Монохромные изображения обладают своим неповторимым шармом, некоей внутренней загадочностью. Недаром многим людям черно-белые снимки нравятся больше, чем цветные, а черно-белая фотография сохраняет свои позиции в высоком фотоискусстве несмотря ни на какие изыски научно-технического прогресса. Тем не менее, цвет - мощнейшее изобразительное средство. Если при визуализации графика функции z=f(x,y) воспользоваться не черно-белой, а цветной палитрой, то информативность такого изображения резко возрастет.

Для воспроизведения округлых и пластичных форм нелинейных поверхностей лучше всего подходят палитры, содержащие плавные взаимопереходы различных цветовых оттенков. Использование градаций серого тона позволяет моделировать игру света и тени. Замена же монохромной шкалы тонов непрерывной цветовой гаммой, например, от темно-зеленого через ярко-желтый к ярко-красному и далее до темно-красного, позволяет резко усилить выразительность и наглядность графика.

Как известно, любой цвет формируется на экране монитора всего из трех "чистых" цветовых компонент - красного (Red), зеленого (Green) и синего (Blue). Каждый пиксел, если рассматривать экран через увеличительное стекло, состоит из трех зернышек красного, зеленого и голубого цвета. Эти зернышки могут светиться с различной интенсивностью. В зависимости от яркости свечения основных цветовых компонент, отдельные точки сливаются издалека в различные однородные цвета. Современное электронное оборудование (в режиме TrueColor) позволяет варьировать яркость свечения каждой из цветовых компонент на 256 уровнях (от 0 до 255 единиц). Таким образом, максимальное количество возможных цветовых комбинаций равно 256*256*256, что примерно составляет 16,7 миллионов цветовых оттенков.

В нашем случае для раскраски графика функции двух переменных z=f(x,y) используем палитру, содержащую различные смеси зеленого (G) и красного (R) тонов. Глубокие впадины на поверхности z будем закрашивать темно-зеленым цветом, который по мере увеличения z будет постепенно становиться все ярче, переходя в ярко-зеленый, а затем в желтый. При дальнейшем увеличении z заставим поверхность постепенно краснеть. И, наконец, самые высокие "холмы" на графике будем обозначать темным кроваво-красным тоном.

Описанное цветовое решение изображено на графике.

Его суть состоит в следующем. Исследуемый интервал значений z от минимума до максимума разбивается на четыре равные части. Все точки изображаемой поверхности, в которых значение z меньше заданного zmin, окрашиваются в темно-зеленый цвет (G=63). Далее, в первой четверти интервала, зеленая компонента постепенно возрастает от 63 до 255. При этом все остальные цвета сохраняют свои нулевые значения. Во второй четверти зеленая компонента сохраняет максимальное значение, и постепенно от 0 до 255 возрастает яркость красного цвета. Таким образом, во второй четверти ярко-зеленый цвет постепенно переходит в ярко-желтый. В третьей четверти яркость зеленого цвета падает от 255 до 0, но красный сохраняет свою максимальную интенсивность. В третьей четверти ярко-желтый постепенно переходит в чистый ярко-красный цвет. И, наконец, в последней четвертой четверти ярко-красный плавно "затухает" до мрачного темно-кровавого оттенка (R=63). И далее все точки поверхности, в которых z принимает значения больше заданного zmax, окрашиваются в темно-красный цвет.

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

Красный Зеленый Синий
0 63 0
0 127 0
0 191 0
0 255 0
63 255 0
127 255 0
191 255 0
255 255 0
255 191 0
255 127 0
255 63 0
255 0 0
191 0 0
127 0 0
63 0 0

Те же самые "фокусы" можно проделывать и с другими цветовыми переходами, например, от темно-синего к небесно-голубому и далее к зеленому и т.д. Порядок смешивания цветов можно менять произвольным образом. Важен сам принцип постепенности. Сначала нарастает (убывает) одна компонента, затем к ней постепенно присоединяется другая. Потом они могут меняться местами и т.д. Все определяется вашим художественным вкусом и интуицией.

Для построения цветных графиков функций двух переменных легко может быть адаптирована обсуждавшаяся ранее программная процедура тоновой визуализации (см. "КВ" №29). Вот ее модифицированный вариант:

DefSng X-Z
Dim Zmin As Single
Dim Zmax As Single
Dim R As Single
Dim R4 As Single
Dim Z14 As Single
Dim Z24 As Single
Dim Z34 As Single

Private Sub Screen_Click()
Dim c As Long
Dim n As Integer
Dim hx As Single
Dim hy As Single
n = 405
Xmin = Text1(0).Text
Xmax = Text1(1).Text
Ymin = Text1(2).Text
Ymax = Text1(3).Text
Zmin = Text1(4).Text
Zmax = Text1(5).Text
R = Zmax - Zmin
R4 = R / 4
Z14 = Zmin + R4
Z24 = Z14 + R4
Z34 = Z24 + R4
hx = (Xmax - Xmin) / n
hy = (Ymax - Ymin) / n
y = Ymin - hy / 2

For j = 0 To n
 x = Xmin - hx / 2
 y = y + hy
 For i = 0 To n
 x = x + hx
 z = f(x, y)
 c = SetColor(z)
 Screen.PSet (i, j), c
 Next i
Next j
End Sub

Public Function f(x As Single, y As Single) As Single
f = Sin((y ^ 3 - x ^ 2) * (x - x * y))
End Function

Public Function SetColor(z As Single) As Long
Dim t As Byte
Select Case z
 Case Is <Zmin SetColor="RGB(0," 63, 0)
 Case Zmin To Z14
 t="63" + 192 * (z Zmin) / R4
 SetColor="RGB(0," t, 0)
 Case Z14 To Z24
 t="255" * (z Z14) / R4
 SetColor="RGB(t," 255, 0)
 Case Z24 To Z34
 t="255" * (1 (z Z24) / R4)
 SetColor="RGB(255," t, 0)
 Case Z34 To Zmax
 t="63" + 192 * (1 (z Z34) / R4)
 SetColor="RGB(t," 0, 0)
 Case Is> Zmax
 SetColor = RGB(63, 0, 0)
 End Select
End Function

В начале программы добавлен расчет величины и границ подинтервалов, необходимых для дальнейших вычислений. Вместо простого определения интенсивности серого тона в текущей точке в программу добавлена функция вычисления цвета SetColor(z). Цветное изображение, полученное при помощи данной модифицированной процедуры, приведено на рисунке.

Поскольку "КВ" выходит в черно-белом формате, читателям придется поверить мне на слово, либо воспроизвести описанные вычисления на своих компьютерах самостоятельно. Уверен, что, не поленившись все это проделать, вы будете вознаграждены сторицей за свои труды открывшимися перед вашим взором многоцветными красотами виртуального мира математической нелинейности. Если же кто-то из вас найдет время поделиться результатами своих находок и экспериментов с цветом и математикой, - присылайте... Благодарю всех читателей, приславших мне свои вопросы, соображения и предложения в прошедшем году. Все они не останутся без внимания.

Андрей КОЛЕСНИКОВ,
[email protected]

Версия для печатиВерсия для печати

Номер: 

02 за 2000 год

Рубрика: 

Азбука программирования
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!