| Erfahrener Benutzer
Registriert seit: 05.04.2005
Beiträge: 1.333
| Ich nehme es einzeln auseinander... habe jetzt eingebaut, dass beim teilen überprüft wird, ob der zweite Operand != null ist und beim wurzelieren, ob der wert über null ist...
Hier der Quelltext des gesamten Scripts: PHP-Code: <?php
error_reporting(0);
header("Content-Type: image/gif");
class Graph
{
// Die Funktion __construct wird beim initialisieren eines neuen Objektes von Typ Graph ausgeführt. Hier werden die Zustandsvariablen für die Klasse Graph initialisiert.
/*
$this->img ist das Bild, auf das die Funktionskurve gezeichnet wird
$this->f ist der String, der die Funktion enthält
$this->x ist die länge der x-achse zu jeder seite
$this->y ist die länge der y-achse nach oben und unten
$this->schritt-x/y die anzahl der pixel zwischen den Einheiten
Dann mehrere Farben für die Darstellung
*/
public function __construct($funktion, $x, $y)
{
$this->img = imagecreatetruecolor(500,500);
$this->f = $funktion;
$this->x = $x;
$this->y = $y;
$this->schrittx = 250/$this->x;
$this->schritty = 250/$this->y;
$this->black = imagecolorallocate($this->img,0,0,0);
$this->white = imagecolorallocate($this->img,255,255,255);
$this->grey = imagecolorallocate($this->img,230,230,230);
$this->red = imagecolorallocate($this->img,255,0,0);
}
// Diese Funktion rechnet strings aus, indem sie sie aufsplittet und rekursiv weiter berechnet
public function rechne($str)
{
// berechnen von Klammern ohne buchstaben davor
if(preg_match("~([^a-zA-Z]+)\(~",$str))
{
$str = preg_replace("~([^a-zA-Z]*)\((.+)\)~Ue","'$1'.\$this->rechne('$2')",$str);
}
// Ersetzen von Konstanten E und PI durch die in PHP vorgegebenen Konstanten M_E und M_PI
$str = str_replace("pi",(double)M_PI,$str);
$str = str_replace("e",(double)M_E,$str);
// Nun werden Sinusfunktionen & CO berechnet. Durch einen regulären Ausdruck wird das innere der Klammern ausgefiltert und einzeln berechnet. Dann wird die spezielle Funktion (Sinus, Logarithmus, ...) auf den Wert angewandt.
$str = preg_replace("~sin\((.+)\)~Uie","round(sin(\$this->rechne('$1')),10)",$str);
$str = preg_replace("~cos\((.+)\)~Uie","round(cos(\$this->rechne('$1')),10)",$str);
$str = preg_replace("~tan\((.+)\)~Uie","round(tan(\$this->rechne('$1')),10)",$str);
$str = preg_replace("~ln\((.+)\)~Uie","round(log(\$this->rechne('$1')),10)",$str);
$str = preg_replace("~sqrt\((.+)\)~Uie","(\$this->rechne('$1') >= 0) ? round(sqrt(\$this->rechne('$1')),10) : 0",$str);
// Suchen nach einem "+"-Zeichen und Aufteilen des Strings an den passenden Stellen. Fragmente weiter rekursiv berechnen
if(strstr($str,"+"))
{
$plus = explode("+",$str);
for($i = 0; $i < count($plus); $i++)
{
$plus[$i] = $this->rechne($plus[$i]);
}
foreach($plus as $temp)
{
$ergebnis += $temp;
}
}
// Das gleiche mit "-". Vor Minus darf kein anderes Rechenzeichen stehen, da es sonst kein operator ist.
elseif(strstr($str,"-") && $str[0] != "-" && !preg_match("~[\/\*\+\^]\-~",$str))
{
$minus = explode("-",$str);
for($i = 0; $i < count($minus); $i++)
{
$minus[$i] = $this->rechne($minus[$i]);
}
$ergebnis = $minus[0];
for($i = 1; $i < count($minus); $i++)
{
$ergebnis -= $minus[$i];
}
}
// das gleiche mit "*" (Mal)
elseif(strstr($str,"*"))
{
$ergebnis = 1;
$mal = explode("*",$str);
for($i = 0; $i < count($mal); $i++)
{
$mal[$i] = $this->rechne($mal[$i]);
}
foreach($mal as $temp)
{
$ergebnis *= $temp;
}
}
// ... und geteilt durch
elseif(strstr($str,"/"))
{
$geteilt = explode("/",$str);
for($i = 0; $i < count($geteilt); $i++)
{
$geteilt[$i] = $this->rechne($geteilt[$i]);
}
$ergebnis = $geteilt[0];
for($i = 1; $i < count($geteilt); $i++)
{
$ergebnis = $geteilt[$i] != 0 ? $geteilt[$i] : "0";
}
}
// als letztes "hoch"
elseif(strstr($str,"^"))
{
$hoch = explode("^",$str);
return pow($hoch[0],$hoch[1]);
}
// wenn kein Rechenzeichen vorhanden ist, wird die Zahl einfach zurückgeben
else
{
$ergebnis = $str;
}
return $ergebnis;
}
// diese Funktion zeichnet das koordinatensystem
public function zeichneKoord()
{
imagefill($this->img,0,0,$this->white);
for($i = -$this->x; $i <= 2*$this->x; $i++)
{
imageline($this->img,$i*$this->schrittx,0,$i*$this->schrittx,500,$this->grey);
imageline($this->img,$i*$this->schrittx,248,$i*$this->schrittx,252,$this->black);
}
for($i = -$this->y; $i <= 2*$this->y; $i++)
{
imageline($this->img,0,$i*$this->schritty,500,$i*$this->schritty,$this->grey);
imageline($this->img,248,$i*$this->schritty,252,$i*$this->schritty,$this->black);
}
imageline($this->img,0,250,500,250,$this->black);
imageline($this->img,250,0,250,500,$this->black);
}
public function zeichneGraph()
// Diese funktion ersetzt x in der funktion ($this->f) für jeden wert, der angezeigt werden soll.
{
for($j = -250; $j <= 250; $j = $j + 0.1)
{
imagesetpixel($this->img,250 + $j/($this->x/$this->y), 250 - $this->rechne(str_replace("x",$j/(250/$this->y),$this->f))*(250/$this->y),$this->red);
}
}
public function rdyGraph()
// Hier wird alles ausgeführt.
{
$this->zeichneKoord();
$this->zeichneGraph();
imagegif($this->img);
}
}
// Hier die Funktion (zB. x^2), den x-achsen und y-achsen bereich eingeben
$g = new Graph($_GET['f'],$_GET['x'],$_GET['y']);
$g->rdyGraph();
?>
__________________ "Wenn du nicht weißt, was du tust: Machs mit Eleganz!"
(Murphy's Gesetze) |