|
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
и получить следующую "свастику":

|
|