Ein simpler Plotter, der Punkte in ein 3D-Koordinatensystem zeichnet und selbige auf Wunsch verbindet. Praktisch für die Schule.
<?php
/*
Simpler 3D-Plotter
Aktion: PHP Scripte für die armen dieser Welt
Der Erlös geht für mein Pausenbrot drauf
Copyright (c) 2006 by Phillip 'Firebird' Berndt
*/
if(!isset($_POST['points']))
{
$_POST['points'] = base64_decode('
UHVua3RlIHdlcmRlbiB3aWUgaW0gTWF0aGVtYXRpa3VudGVycmljaHQgbWFya2llcnQ6CgpQKDAs
MCwwKQpRKDAsMCw0KQpSKDAsNCw0KQpSJygwLDQsMCkKUyg0LDQsNCkKVCg0LDAsNCkKVSg0LDQs
MCkKVScoNCwwLDApCgpvZGVyCgpaKDB8MHwwKQoKU28gbGFzc2VuIHNpY2ggVmVyYmluZHVuZ2Vu
IHp3aXNjaGVuIFB1bmt0ZW4gbWFsZW46CgpQPT5VJwpVJy0+VQpVLT5SJwpSJz0+UApQPT5RClUn
LT5UClUtPlMKUictPlIKUS0+UgpRLT5UClQtPlMKUy0+UgoKVmVyYmluZHVuZ2VuIG1pdCBlaW5l
bSAtIHdlcmRlbiBzdGFyaywgc29sY2hlIG1pdCBlaW5lbSA9IGxlaWNodCBnZW1hbHQuCgpTbyBs
YXNzZW4gc2ljaCBkaWUgRWluc3RlbGx1bmdlbiBtb2RpZml6aWVyZW46Cgp1bml0TGVuZ3RoPTUw
CnhBbmdsZT00NQp4QXhpc0Rldmlzb3I9Mg==
');
}
if(isset($_GET['points']))
{
// Extract commands
preg_match_all('/^([a-z0-9\']*)\s*\(\s*([0-9]+)\s*(?:,|\|)\s*([0-9]+)\s*(?:,|\|)\s*([0-9]+)\s*\)/im', $_GET['points'], $points);
preg_match_all('/^([a-z0-9\']*)\s*(-|=)>([a-z0-9\']*)/im', $_GET['points'], $connections);
preg_match_all('/^(unitLength|xAngle|xAxisDevisor)=([0-9.]+)/mi', $_GET['points'], $settings, PREG_SET_ORDER);
// Settings
$unitLength = 50;
$xAngle = 45/180*pi();
$unitLengthX = $unitLength / 2;
foreach($settings as $setting)
{
switch(strtolower($setting[1]))
{
case 'unitlength':
$unitLength = intval($setting[2]);
$unitLengthX = $unitLength / 2;
break;
case 'xangle':
$$xAngle = intval($setting[2]) / 180 * pi();
break;
case 'xaxisdevisor':
$unitLengthX = $unitLength / intval($setting[2]);
break;
}
}
// Create environment
$xMin = min(0, min($points[2])); $xMax = max(0, max($points[2])); $xMax = abs(max($xMax, $xMin)); $xMin = -$xMax;
$yMin = min(0, min($points[3])); $yMax = max(0, max($points[3])); $yMax = abs(max($yMax, $yMin)); $yMin = -$yMax;
$zMin = min(0, min($points[4])); $zMax = max(0, max($points[4])); $zMax = abs(max($zMax, $zMin)); $zMin = -$zMax;
$imageWidth = abs($yMin * $unitLength) + abs($yMax * $unitLength) + 10;
$imageHeight = abs($zMin * $unitLength) + abs($zMax * $unitLength) + 10;
$imageCenterX = $imageWidth / 2;
$imageCenterY = $imageHeight / 2;
$cs = imagecreatetruecolor($imageWidth + 9, $imageHeight + 9);
$white = imagecolorallocate($cs, 255, 255, 255);
$gray = imagecolorallocate($cs, 200, 200, 200);
$black = imagecolorallocate($cs, 0, 0, 0);
$red = imagecolorallocate($cs, 255, 0, 0);
$blue = imagecolorallocate($cs, 0, 0, 255);
$lightBlue = imagecolorallocate($cs, 200, 200, 255);
// Draw coordinate system
imagefill($cs, 0, 0, $white);
imageline($cs, $imageCenterX, 5, $imageCenterX, $imageHeight - 5, $black);
imageline($cs, $imageCenterX - 3, 8, $imageCenterX, 5, $black);
imageline($cs, $imageCenterX + 3, 8, $imageCenterX, 5, $black);
imagestring($cs, 0, $imageCenterX - 7, 2, 'Z', $black);
for($z=$zMin + 1; $z<=$zMax; $z++)
{
imageline($cs, $imageCenterX - 3, $imageCenterY + $z * $unitLength, $imageCenterX, $imageCenterY + $z * $unitLength, $black);
imagestring($cs, 0, $imageCenterX - 12, $imageCenterY + $z * $unitLength - 10, -$z, $gray);
}
imageline($cs, 5, $imageCenterY, $imageWidth - 5, $imageCenterY, $black);
imageline($cs, $imageWidth - 8, $imageCenterY + 3, $imageWidth - 5, $imageCenterY, $black);
imageline($cs, $imageWidth - 8, $imageCenterY - 3, $imageWidth - 5, $imageCenterY, $black);
imagestring($cs, 0, $imageWidth - 8, $imageCenterY - 10, 'Y', $black);
for($y=$yMin; $y<$yMax; $y++)
{
imageline($cs, $unitLength * $y + $imageCenterX, $imageCenterY + 3, $unitLength * $y + $imageCenterX, $imageCenterY, $black);
imagestring($cs, 0, $unitLength * $y + $imageCenterX + 3, $imageCenterY + 4, $y, $gray);
}
imageline($cs,
$imageCenterX + ($xMax + 2) * $unitLengthX * cos($xAngle),
$imageCenterY - ($xMax + 2) * $unitLengthX * sin($xAngle),
$imageXAxisEndX = ($imageCenterX - ($xMax + 2) * $unitLengthX * cos($xAngle)),
$imageXAxisEndY = ($imageCenterY + ($xMax + 2) * $unitLengthX * sin($xAngle)),
$black);
imageline($cs, $imageXAxisEndX + 5 * cos($xAngle - 0.5), $imageXAxisEndY - 5 * sin($xAngle - 0.5), $imageXAxisEndX, $imageXAxisEndY, $black);
imageline($cs, $imageXAxisEndX + 5 * cos($xAngle + 0.5), $imageXAxisEndY - 5 * sin($xAngle + 0.5), $imageXAxisEndX, $imageXAxisEndY, $black);
imagestring($cs, 0, $imageXAxisEndX - 5, $imageXAxisEndY - 5, 'X', $black);
for($x=$xMin; $x<=$xMax; $x++)
{
$imagePointX = $imageCenterX - $x * $unitLengthX * cos($xAngle);
$imagePointY = $imageCenterY + $x * $unitLengthX * sin($xAngle);
imageline($cs, $imagePointX, $imagePointY, $imagePointX - 3 * cos($xAngle + pi()/2), $imagePointY - 3 * cos($xAngle + pi()/2), $black);
imagestring($cs, 0, $imagePointX + 3, $imagePointY + 3, $x, $gray);
}
// Draw points
$pointPositions = Array();
for($n=0; $n<count($points[0]); $n++)
{
$coordinateX = $imageCenterX - $points[2][$n] * $unitLengthX * cos($xAngle);
$coordinateY = $imageCenterY + $points[2][$n] * $unitLengthX * sin($xAngle);
$coordinateX += $points[3][$n] * $unitLength;
$coordinateY -= $points[4][$n] * $unitLength;
imagefilledellipse($cs, $coordinateX, $coordinateY, 2, 2, $red);
imagestring($cs, 0, $coordinateX + 3, $coordinateY + 3, $points[1][$n], $red);
$pointPositions[strtolower($points[1][$n])] = array($coordinateX, $coordinateY);
}
// Draw connections
for($n=0; $n<count($connections[0]); $n++)
imageline($cs, $pointPositions[strtolower($connections[1][$n])][0], $pointPositions[strtolower($connections[1][$n])][1],
$pointPositions[strtolower($connections[3][$n])][0], $pointPositions[strtolower($connections[3][$n])][1],
$connections[2][$n] == '-' ? $blue : $lightBlue);
header('Content-type: image/png');
imagepng($cs);
die();
}
?>
<h1>Simpler 3D Plot</h1>
<form method="post">
<textarea rows="20" cols="80" name="points"><?=htmlspecialchars($_POST['points'])?></textarea><br/>
<input type="submit">
</form>
<hr/>
<img src="<?=$_SERVER['PHP_SELF']?>?points=<?=urlencode($_POST['points'])?>" alt="3D Plot"/>