<?php

/*
 * Random Line Generator 2.0 - PHP edition
 *
 * Copyright (c) 2007 Sabre <http://crindigo.com>
 *
 * http://www.opensource.org/licenses/mit-license.php
 */

if (!isset($_REQUEST['submit'])) {
    
// show HTML form
    
echo <<<HTML
<html>
<head>
    <title>Random Line Generator</title>
</head>
<body>
    <form action="RandomLine.php" method="post">
    <strong>Start Point X (0-499)</strong>
        <input type="text" name="startX" value="250" /><br />
    <strong>Start Point Y (0-499)</strong>
        <input type="text" name="startY" value="250" /><br />
    <strong>Initial line angle (0-360)</strong>
        <input type="text" name="angle" value="0" /><br />
    <strong>Minimum length for lines (1-100)</strong>
        <input type="text" name="lengthMin" value="10" /><br />
    <strong>Maximum length for lines (1-100)</strong>
        <input type="text" name="lengthMax" value="15" /><br />
    <strong>Angle deviation left bound (-180-180)</strong>
        <input type="text" name="angleMin" value="-30" /><br />
    <strong>Angle deviation right bound (-180-180)</strong>
        <input type="text" name="angleMax" value="30" /><br />
    <strong>Number of lines to draw (1-1000)</strong>
        <input type="text" name="lineCount" value="500" /><br />
    <strong>Line Colors (separate with spaces, max 30)</strong>
        <input type="text" name="lineColor" value="#FFFF00 #FF0000 #00FF00" size="60" /><br />
    <strong>Line Color Selection (if multiple line colors)</strong>
        <input type="radio" name="colorSelect" value="random" id="csrandom" checked="checked" /><label for="csrandom"> Random</label>
        <input type="radio" name="colorSelect" value="alt" id="csalt" /><label for="csalt"> Cycle</label><br />
    <strong><label for="aa">Anti-Alias Lines</label></strong>
        <input type="checkbox" name="antiAlias" value="1" id="aa" /><br />
    <strong>Background Color</strong>
        <input type="text" name="bgColor" value="#000000" /><br />
    <input type="submit" name="submit" value="Generate" />
    <p><a href="randomline.html">Animated JS/Canvas version</a></p>
</body>
</html>
HTML;
        
    exit;
}

class 
RandomLine
{
    private
        
$startPoint,
        
$firstAngle,
        
$lineLength,
        
$angleRand,
        
$loopCount,
        
$lineColors,
        
$lineColorSelect,
        
$lineWidth,
        
$antiAlias,
        
$bgColor,
        
$image;
    
    public function 
__construct()
    {
        
$this->startPoint = array($this->bound((int) $_REQUEST['startX'], 0499),
                                  
$this->bound((int) $_REQUEST['startY'], 0499));
        
$this->firstAngle $this->bound((int) $_REQUEST['angle'],  0360);
        
$this->lineLength = array($this->bound((int) $_REQUEST['lengthMin'], 1100),
                                  
$this->bound((int) $_REQUEST['lengthMax'], 1100));
        
$this->angleRand  = array($this->bound((int) $_REQUEST['angleMin'], -180180),
                                  
$this->bound((int) $_REQUEST['angleMax'], -180180));
        
$this->loopCount  $this->bound((int) $_REQUEST['lineCount'], 11000);
        
$this->lineColors $this->cleanLineColor($_REQUEST['lineColor']);
        
$this->lineColorSelect $_REQUEST['colorSelect'];
        
//$this->lineWidth  = $this->bound((int) $_REQUEST['lineWidth']);
        
$this->antiAlias  = isset($_REQUEST['antiAlias']);
        
$this->bgColor    $this->cleanColor($_REQUEST['bgColor']);
        
        
// start image
        
$this->image imageCreateTrueColor(500500);
        
imageFill($this->image00$this->hexToInt($this->bgColor));
        
imageAntiAlias($this->image$this->antiAlias);
    }
    
    private function 
bound($val$min$max)
    {
        return 
min(max($val$min), $max);
    }
    
    private function 
cleanColor($col)
    {
        
$col preg_replace('/[^a-f0-9]/i'''$col);
        if (
strlen($col) != 6) {
            
$col '000000';
        }
        return 
$col;
    }
        
    private function 
cleanLineColor($cols)
    {
        
$col preg_replace('/<font color=(\'|")(#[a-f0-9]{6})(\'|")>(.+?)<\/font>/i''$2 '$cols);
        
$col preg_replace('/<span style=(\'|")color:\s*(#[a-f0-9]{6})(\'|")>(.+?)<\/span>/i''$2 '$col);
        
$col preg_replace('/\s+/'' '$col);
        
$col trim($col);
        
        if (
strpos($col' ') !== false) {
            
$rawColors preg_split('/\s+/'$col, -1PREG_SPLIT_NO_EMPTY);
            if (
sizeof($rawColors) > 30) {
                
$rawColors array_slice($rawColors030);
            }
            
$colors = array();
            foreach (
$rawColors AS $c) {
                
$colors[] = $this->cleanColor($c);
            }
            return 
$colors;
        }
        else {
            return 
$this->cleanColor($col);
        }
    }
    
    private function 
linePiece($orig_x$orig_y$angle$length$color)
    {
        
$x1 $orig_x;
        
$y1 $orig_y;
        
$x2 $x1 round(cos(deg2rad($angle)) * $length);
        
$y2 $y1 round(sin(deg2rad($angle)) * $length);
    
        
imageLine($this->image$x1$y1$x2$y2$color);
        return array(
$x2$y2);
    }
    
    private function 
hexToInt($hexcol)
    {
        
$r hexdec(substr($hexcol02));
        
$g hexdec(substr($hexcol22));
        
$b hexdec(substr($hexcol42));
        
        return (
$r << 16) | ($g << 8) | $b;
    }
    
    private function 
getLineColor()
    {
        static 
$colorPos;
        if (
is_array($this->lineColors)) {
            if (
$this->lineColorSelect == 'random') {
                return 
$this->hexToInt($this->lineColorsmt_rand(0sizeof($this->lineColors) - 1) ]);
            }
            else {
                
$pos $colorPos;
                if (++
$colorPos >= sizeof($this->lineColors)) {
                    
$colorPos 0;
                }
                return 
$this->hexToInt($this->lineColors[$pos]);
            }
        }
        else {
            return 
$this->hexToInt($this->lineColors);
        }
    }

    public function 
render()
    {
        
$angle $this->firstAngle;
        
$x     $this->startPoint[0];
        
$y     $this->startPoint[1];

        for (
$i 0$i $this->loopCount$i++) {
            
$length mt_rand($this->lineLength[0], $this->lineLength[1]);
            
$color  $this->getLineColor();
            
            list(
$x$y) = $this->linePiece($x$y$angle$length$color);
            
            
// if anything's out of bounds, do some wrapping work.
            
if ($x OR $x 499 OR $y OR $y 499) {
                if (
$x 0) {    // x out to the left
                    
$x += 500;
                }
                else if (
$x 499) {    // x out to the right
                    
$x -= 500;
                }
                
                if (
$y 0) {    // y out to the top
                    
$y += 500;
                }
                else if (
$y 499) {    // y out to the bottom
                    
$y -= 500;
                }
                
// reverse angle to point line back to edge on wrap
                
$this->linePiece($x$y$angle 180$length$color);
            }
            
            
$angle += mt_rand($this->angleRand[0], $this->angleRand[1]);
        }
        
        
header('Content-type: image/png');
        
imagePNG($this->image);
        
imageDestroy($this->image);
    }
}

$line = new RandomLine;
$line->render();

?>