| Erfahrener Benutzer
Registriert seit: 05.04.2005
Beiträge: 1.333
| Funktionsgraph-Zeichner Hallo!
Ich habe ein Problem mit diesem Script: PHP-Code: 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);
if(file_exists("log.txt")) unlink("log.txt");
$this->datei = fopen("log.txt","w");
}
// Diese Funktion rechnet strings aus, indem sie sie aufsplittet und rekursiv weiter berechnet
public function rechne($str)
{
// fwrite($this->datei,"STR: ".$str."\n");
/* berechnen von Klammern ohne buchstaben davor
if(preg_match("~([^a-zA-Z]+)\(~",$str))
{
$str = preg_replace("~(\([^()]+\)|\(.*\(.*\).*\))~Uie","'$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) ? $ergebnis / $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);
}
}
Es zeichnet Graphen aus mathematischen Funktionen. Vieles funktioniert bereits. Die Funktion "-x^2" wird beispielsweise falsch dargestellt... ich suche den Fehler schon länger, aber habe nun nur noch wenig zeit um das Script fertigzustellen. Deshalb frage ich hier ob vielleicht jemand, der ganz distanziert auf den Code schaut, den Fehler findet.
Gruß Freeaak
__________________ "Wenn du nicht weißt, was du tust: Machs mit Eleganz!"
(Murphy's Gesetze) |