бесплатный юрист онлайн по земельным вопросам.

Паскаль - Уроки - Создание рогатой гусеницы

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

Итак, компилируем приведенную ниже программу на TMT Pascal 3.50:

(***********************************************)
(* Рогатая гусеница *)
(* Автор алгоритма: Евгений Скляревский (VB) *)
(* ------------------------------------------- *)
(* Адаптация для TMT Pascal: *)
(* Валерий Вотинцев *)
(* MS-DOS 32-bit protected mode *)
(* Win32 Console application *)
(* Win32 GUI *)
(***********************************************)
uses CRT, Math, Graph;
var
 i,j: integer;
 t, s: extended;
 ia,ja, RR, RR0, RR1: extended;
 x, y, z: extended;
 X1, Y1, X2, Y2, xx, yy: LongInt;
 red, green, blue: byte;

begin
 SetSVGAMode(800,600,16,LFBorBanked); // Установка графического режима
 if GraphResult<>grOk then begin // Проверка результата
 Writeln('Mode not supported..');
 Halt(0);
 end;
 xx := 400; // Начало по Х
 yy := 300; // Начало по Y
 RR := 260; // Радиус в плоскости XZ
 RR1 := 60; // Радиус "тела" тора
 For i := 0 To 719 do begin
 ia := i / 2.0; // Каждый шаг - пол-градуса
 For j := 0 To 719 do begin
 ja := j / 2; // Каждый шаг - пол-градуса
 t := ia * Pi / 180; // Угловой параметр для большого круга
 s := ja * Pi / 180; // Угловой параметр для малого круга
{1a} RR0 := RR1;
{1b} {RR0 := RR1 + 60 * IntPower(Sin(2 * t),2);}
{1c} {RR0 := RR1 + 60 * IntPower(Sin(2 * t),2) +
 60 * IntPower(Sin(8 * s),24) * IntPower(Sin(16 * t),24);}
{1d} {RR0 := RR1 + 60 * IntPower(Sin(16 * s),24) * IntPower(Sin(32 * t),24);}
{1e} {RR0 := RR1 + 60 * IntPower(Sin(4 * s),24) * IntPower(Sin(8 * t),24);}
 X := RR * Cos(t) + RR0 * Cos(s);
 Y := RR0 * Sin(s);
{2a} z := RR * Sin(t) + RR0 * Cos(s);
{2b} {z := RR * Sin(2 * t) + RR0 * Cos(s);}
 // Переводим координаты в плоскость экрана
 X1 := trunc(X - z * Cos(Pi / 3) * 0.5);
 Y1 := trunc(Y - z * Sin(Pi / 3) * 0.5);

 red := trunc(RR0 * 255) div trunc(RR1 + 60); // Красный
 green := trunc(255 * ia / 10) mod 255; // Зеленый
 blue := trunc(0.1 * ia * ja) mod 255; // Синий
 if (i = 0) and (j = 0) then begin
 red := 0; // Чтобы начальную линию
 green := 0; // не было видно,
 blue := 0; // нарисуем ее черным цветом
 end;
 Line (X1 + xx, Y1 + yy, X2 + xx, Y2 + yy, RGBColor(red, green, blue));
 X2 := X1;
 Y2 := Y1;
 end;
 end;
 ReadKey; // Ждем нажатия клавиши
 CloseGraph;
end.
В программе мы запустили два цикла: с переменной j (угловой параметр s для прорисовки малого круга с радиусом RR1) и переменной i (угловой параметр t для вращения малого круга в плоскости XZ радиусом RR). Проекцию оси Z направим под углом 60 градусов к оси X, а для перевода объемной картинки в плоскость экрана используем переменные X1 и Y1. Если в приведенном тексте программы мы оставим все как есть, то на экране появится обычный тор.


Обратите внимание на его расцветку, она задается переменными red, green и blue. В приведенном примере красный цвет пропорционален текущему радиусу малого круга и проявляется только на <вздутиях> и рожках, зеленый пропорционален i, что дает поперечные полосы, а синий зависит от произведения i * j и проявляется в виде голубых полосок.

Насмотревшись на скромный и унылый тор, подумаем, как бы его деформировать.
При вычислении z умножим t на 2 в синусе. Это <перехлестнет> тор, и он приобретет форму восьмерки.
Для этого закомментируйте строку, помеченнную как {2a}, и раскомментируйте строку {2b}.


Теперь внесем <искажения> при вычислении RR0 за счет добавления еще одного слагаемого:
 RR0 = RR1 + 60·Sin(2t)2
Мы получим картинку с "утолщениями", явно претендующую на то, чтобы Зигмунд Фрейд предлагал ее своим пациентам для диагностики психических отклонений.
Закомментируйте строку {1a} и уберите комментарий со строки {1b}.


Опыты со слагаемым RR1 наиболее эффектны - попробуйте поменять множитель при синусе (60), множитель при t и показатель степени, в которую возводится синус (второй параметр функции IntPower). Вы будете вознаграждены появлением на экране загадочных существ. Однако подбираемся к главному - еще более усложним формулу вычисления для RR0, а именно добавим еще одно слагаемое с произведением синусов в разных степенях:
 RR0 = RR1 + 60·Sin(2t)2 + 60·(Sin(8s))24·Sin(16t)24
Чтобы "запустить" эту формулу, раскомментируйте строку {1c}.

Первое слагаемое с RR1 дает уже рассмотренные нами утолщения "туловища", а вот второе - рожки на торе, или, точнее, уже на гусенице. Причем множитель при s дает количество рожек на малом круге, множитель при t - на большом круге, показатели степени определяют плавность или крутизну рожек, а передний числовой множитель (60) - их высоту.
Давайте сделаем нашу гусеницу "более лохматой". Для этого раскомментирум строку {1d}.


Теперь уменьшим количество рожек вдоль длины тела гусеницы
(раскомментируйте строку {1e}).

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


Автор: Евгений Скляревский
Copyright © 2006-09.