БлогNot. Кривая Серпинского на PHP

Кривая Серпинского на 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 [11189 просмотров]


теги: программирование ошибка графика php

К этой статье пока нет комментариев, Ваш будет первым