Кривая Серпинского на PHP
Собственно, мне понадобился наглядный пример рекурсии, для которой "линейные" (в смысле, выполняемые единственным циклом) расчёты, вроде факториала или ряда Фибоначчи, кажутся мне неудачными, а вот кривая Серпинского иллюстрирует идею рекурсии довольно ясно, особенно "лавину", начинающуюся уже с 5-6 вложений.
Ниже показаны кривые Серпинского порядков рекурсии от 1 до 5:
Конечно же, эти изображения я не рисовал, а сгенерировал оперативно написанным скриптом. Для рисования
используется библиотека GD, а интерес в коде представляют разве что отсутствующие в этой библиотеке функции для работы
с графическим курсором, привычные по Сишным или Паскалевским средам, прежде всего это
GetX
и GetY
- получение координат курсора, MoveTo
- его установка в нужную позицию рисунка и
LineTo
- проведение линии от позиции курсора до нужной точки. Функцию PutPixel
вполне заменит стандартная
для GD функция imagesetpixel
. Вот соответствующий кусочек кода:
function GetX ($x=0,$action=0) { static $cx; if (!$action) return $cx; $cx=$x; return $cx; } function GetY ($y=0,$action=0) { static $cy; if (!$action) return $cy; $cy=$y; return $cy; } function MoveTo ($x,$y) { GetX ($x,'set'); GetY ($y,'set'); } function LineTo ($img,$x2,$y2,$color) { $x1=GetX (); $y1=GetY (); if ($x1!=$x2) { //не вертикаль $a=($y2-$y1)/($x2-$x1); $b=$y1-$a*$x1; $n=abs($x2-$x1)+1; if ($x2>$x1) $dx=1; else $dx=-1; $x=$x1; for ($i=1; $i<=$n; $i++) { $y=round ($a*$x+$b); imagesetpixel ($img, $x, $y, $color); $x+=$dx; } } else { //вертикаль $n=abs($y2-$y1); if ($y2>$y1) $dy=1; else $dy=-1; $x=$x1; $y=$y1; for ($i=1; $i<=$n; $i++) { imagesetpixel ($img, $x, $y, $color); $y+=$dy; } } imagesetpixel ($img, $x, $y, $color); MoveTo ($x2,$y2); }
Скрипт можно вызывать со следующими параметрами URL ("понимается" только метод GET):
i
- порядок рекурсии, целое от 1 до 6 включительно;u
- длина штриха кривой, от 1 до 50 включительноxy
- желаемый размер картинки в пикселах, от 10 до 1000 включительно. Если размер не задан, он вычисляется по формуле$xy = round(7.2*$u*pow(2,$i-1));
, более удачную я подобрать не пытался;back
- цвет фона рисунка, должен быть передан в видеRRGGBB
, где RR, GG, BB - 16-ричные интенсивности красного, зелёного и синего от 00 до FF (от 0 до 255 десятичного) включительно, то есть, типовая система записи цвета RGB. Если передано любое значениеback
меньше 0, фон будет прозрачным. По умолчанию белый;lines
- цвет линий кривой Серпинского, также в видеRRGGBB
, по умолчанию красный.
Эти ограничения можно поменять в коде скрипта.
Пример вызова с параметрами - кривая порядка 4, чёрным по прозрачному, авторазмер
Скачать весь исходник можно на странице скрипта
P.S. не в тему. Забавно, что только вчера обсуждали проблему ошибки 500 - сервак с PHP очень любит выдавать её в ответ на единственную синтаксическую неправильность где-нибудь глубоко в недрах кода - как сегодня сам получил её дважды, отлаживая этот скрипт. Один раз, как обычно, путая в голове все языки, написал
$x1:=GetX ();
а второй раз просто поставил коммент до тега PHP:
//коммент до тега PHP - Error 500! <?php
По идее, ни то, ни другое "валить" на 500 не должно, и сейчас не завалило, когда дома проверил, но это же PHP и криво сконфигурированный Apache:)
08.05.2012, 23:42 [11276 просмотров]