Pers.narod.ru. PHP. Спиральные коврики из чисел |
Чиркая вот эту заметку, вспомнил о сделанном ещё в детстве "открытии" - все числа, набранные на клавиатуре калькулятора
"прямоугольником", делятся без остатка на 11, например, 1397, 5632, 4631 и т.д. Прямоугольник может быть и с одной "нулевой" стороной, вроде 7997, и даже вовсе "вырожденным", например, 4444. Более того, тем же свойством обладают и числа, полученные аналогичным проходом по диагоналям клавиатуры, такие как 1991, 6886, 6842 или 3773. Неизвестно почему это навело меня на мысль, что обходом по спирали можно нанести на картинку точки-числа, подчиняющиеся какому-нибудь общему свойству, например, являющиеся простыми, кратные тем же 11 и т.д.
Ну а вечером сразу же выбрал время проверить, не люблю такие вещи откладывать.
Вот простые числа, не превышающие 160000, вписанные в спираль:
Не правда ли, чувствуется закон распределения, пусть и не такой примитивный как для чисел, кратных 11:
(тело функции simple
заменено оператором return ($n%11);
).
Для создания таких картинок можно было найти что-то явно побыстрее PHP, но ничего подходящего под рукой не было... вот полный текст скрипта:
<?php set_time_limit (45); //Лимит времени выполнения function get_rgb_from_hex ($hex) { //Цвет RRGGBB (Hex) в массив (r,g,b) десятичные $rgb=array(); for ($i=0; $i<6; $i+=2) $rgb[]=hexdec(substr($hex,$i,2)); return $rgb; } function simple ($n) { //Проверка положительного числа на простоту - неоптимальна! if ($n<4) return true; if ($n%2==0) return false; $n2=floor($n/2); for ($i=3; $i<$n2; $i+=2) if ($n%$i==0) return false; return true; } //Обработка параметров $params = array ('xy','back','lines','d','cw'); while (list($num,$var) = each($params)) { if (!empty($_GET[$var])) $$var = intval($_GET[$var]); else $$var=0; } if (!$xy) $xy = 400; if ($xy<10) $xy=10; if ($xy>1000) $xy=1000; // Размер стороны картинки 10-1000 $dir=0; if ($d>-1 and $d<4) $dir=$d; //Направление первого шага $transparent=false; //Прозрачность $rback=$gback=$bback=255; if (isset($_GET['back'])) { //Цвет фона RRGGBB, если меньше 0 - прозрачный $back=htmlspecialchars(trim($_GET['back'])); if (preg_match("#^[0-9A-Fa-f]{6}$#",$back)) list ($rback,$gback,$bback) = get_rgb_from_hex ($back); else if (intval($back)<0) $transparent=true; } $rlines=$glines=$blines=0; if (isset($_GET['lines'])) { //Цвет линий RRGGBB $lines=htmlspecialchars(trim($_GET['lines'])); if (preg_match("#^[0-9A-Fa-f]{6}$#",$lines)) list ($rlines,$glines,$blines) = get_rgb_from_hex ($lines); } //Отрисовка if (!extension_loaded('gd')) die('Cannot initialize GD library'); $img = @imagecreatetruecolor($xy, $xy) or die ('Cannot initialize new GD image stream'); $back = imagecolorallocate($img,$rback,$gback,$bback); $lines = imagecolorallocate($img,$rlines,$glines,$blines); imagefilledrectangle ($img, 0, 0, $xy, $xy, $back); if ($transparent) imagecolortransparent($img, $back); $x=$y=round($xy/2); $step=1; $k=0; $cnt=1; $xy2=$xy*$xy; do { switch ($dir) { case 0: $dx=1; $dy=0; break; //0 - вправо case 1: $dx=0; $dy=-1; break; //1 - вверх case 2: $dx=-1; $dy=0; break; //2 - влево case 3: $dx=0; $dy=1; break; //3 - вниз } for ($s=1; $s<=$step; $s++) { if ($x>-1 and $x<$xy and $y>-1 and $y<$xy) { if (simple($cnt)) imagesetpixel ($img, $x, $y, $lines); $cnt++; } $x+=$dx; $y+=$dy; } if ($cw) { //крутить спираль по часовой $dir--; if ($dir==-1) $dir=3; } else { $dir++; if ($dir==4) $dir=0; } $k++; if ($k==2) { $step++; $k=0; } } while ($cnt<$xy2); //Вывод header ('Content-Type: image/gif'); imagepng ($img); imagedestroy($img); ?>
Скрипт довольно медленный и не несёт ничего нового, так что онлайн себе не ставлю :) Эффективнее простые числа на PHP ищутся здесь.
Реагирует на следующие параметры, переданные в URL (методом GET
):
xy
- размер картинки в пикселах по горизонтали и вертикали, в тексте ограничение от 10 до 1000 включительно, по умолчанию 400
back
- цвет фона в виде RRGGBB
, где R
, G
, B
- 16-ричные цифры, по умолчанию белый. Любое значение меньше нуля делает фон прозрачным
lines
- цвет точек в таком же виде RRGGBB
, по умолчанию чёрный
d
- направление первого шага, 0 - вправо, 1 - вверх, 2 - влево, 3 - вниз, по умолчанию вправо
cw
- любое ненулевое значение параметра приводит к отрисовке спирали по часовой стрелке, а не против (по умолчанию).
Например, скрипт можно вызвать так:
http://ВАШ_URL/spiral_of_prime_numbers.php?xy=100&back=000000&lines=FFFFFF&d=2&cw
и получить следующую "свастику":
гостевая; E-mail |