Version: 1.0
Type: Full Script
Category: Graphics
License: GNU General Public License
Description: takes a string of characters as elementary instructions and draws a pattern. see example at http://www.eldwick.org.uk/?q=node/31
<?php
header("Content-type: image/png"); // tells the browser this is an image file!
$xmax = 200; $ymax = 200;
$im = ImageCreate($xmax, $ymax);
$background_color = imagecolorallocate($im, 255, 255, 255);
$trans_color = imagecolortransparent ($im, $background_color);
$pen_color = imagecolorallocate($im, 0, 0, 0);
$xPos = intval($xmax/2); $yPos = intval($ymax/2); $bearing = 0;
$rVal = 0; $gVal = 0; $bVal = 0; $penDown = 1;
$qString = $_SERVER['QUERY_STRING'];
// convert back from url encoded characters
$qString = urldecode($qString);
// get rid of '=' and spaces
$qString = str_replace("=", "", $qString);
$qString = str_replace(" ", "", $qString);
// draw the trail defined by the query string
slug($qString);
// render the image
imagepng($im);
// destroy image
ImageDestroy($im);
////////////////////////////////////////////////////////////
// the main interpreter function
////////////////////////////////////////////////////////////
function slug($dStr) {
global $bearing; global $xPos; global $yPos; global $rVal; global $gVal; global $bVal; global $im; global $penDown; global $pen_color;
$i=0;
$dStr = strToUpper($dStr);
$sLen = strlen($dStr);
while ($i < $sLen) {
$ch = substr($dStr, $i, 1);
/////////////////////////// characters allowed ( ) L R S U D C X Y P Q 0123456789N
$i++;
switch ($ch) {
case "(": /////////////////////////////////////////////// start of bracketed string
$br = 1;
$subSlug = "";
$i--;
while ($i < $sLen) {
$i++;
$ch = substr($dStr, $i, 1);
if ($ch == "(") $br++;
if ($ch == ")") { // ie end of a bracketed string
$br--;
if ($br == 0) { // ie the matching bracket for the initial opening one - call slug() for the contents
$i++;
$n = getNumber($dStr, $i, $sLen);
for ($j=0; $j<$n; $j++) slug($subSlug); // do whatever was in the brakets n times using the slug function recursively
break;
}
}
$subSlug = $subSlug . $ch; // add this character to the bracketed string
}
break;
case "L": /////////////////////////////////////////////// change the bearing clockwise
$bearing += getNumber($dStr, $i, $sLen);
break;
case "R": /////////////////////////////////////////////// change the bearing anti-clockwise
$bearing -= getNumber($dStr, $i, $sLen);
break;
case "S": /////////////////////////////////////////////// draws a line and updates the current location
$n = getNumber($dStr, $i, $sLen);
$xTo = intval($xPos + $n*sin(deg2rad($bearing)) + 0.5);
$yTo = intval($yPos + $n*cos(deg2rad($bearing)) + 0.5);
if ($penDown == 1) ImageLine($im, $xPos, $yPos, $xTo, $yTo, $pen_color); // only draw if pen's down
$xPos = $xTo; $yPos = $yTo;
break;
case "C": /////////////////////////////////////////////// sets the colour as decimal numbers 00 to 99 ie C999999
$n = getNumber($dStr, $i, $sLen);
$rVal = intval($n/10000);
$gVal = intval(($n - 10000*$rVal)/100);
$bVal = $n - 10000*$rVal - 100*$gVal;
$pen_color = imagecolorallocate($im, intval($rVal*2.55), intval($gVal*2.55), intval($bVal*2.55));
break;
case "U": /////////////////////////////////////////////// puts the pen up
$penDown = 0;
break;
case "D": /////////////////////////////////////////////// puts the pen down
$penDown = 1;
break;
case "X": /////////////////////////////////////////////// moves to absolute x coordinates without drawing
$xPos = getNumber($dStr, $i, $sLen);
break;
case "Y": /////////////////////////////////////////////// moves to absolute y coordinates without drawing
$yPos = getNumber($dStr, $i, $sLen);
break;
case "P": /////////////////////////////////////////////// flood fill starting n pixels to the left
$n = getNumber($dStr, $i, $sLen);
$xTo = intval($xPos + $n*sin(deg2rad($bearing + 90)) + 0.5);
$yTo = intval($yPos + $n*cos(deg2rad($bearing + 90)) + 0.5);
imageFill($im, $xTo, $yTo, $pen_color);
break;
case "Q": /////////////////////////////////////////////// flood fill starting n pixels to the right
$n = getNumber($dStr, $i, $sLen);
$xTo = intval($xPos + $n*sin(deg2rad($bearing - 90)) + 0.5);
$yTo = intval($yPos + $n*cos(deg2rad($bearing - 90)) + 0.5);
imageFill($im, $xTo, $yTo, $pen_color);
break;
}
}
}
/////////////////////////////////////////////////////////////
// getNumber works along the given string till it finds a non numeric
// if there is a digit replaced by a "N" it will fill it with a random number 0-9
// $i is passed by reference to that it is picked up by the calling function at the end of the number
/////////////////////////////////////////////////////////////
function getNumber ($dStr, &$i, $endPoint) {
$n = 0;
while ($i < $endPoint) {
$ch = substr($dStr, $i, 1);
if ($ch == "N") $ch = rand(0,9);
if (is_numeric($ch)) $n = 10*$n + intval($ch);
else return($n);
$i++;
}
return($n);
}
?>