Grafy goniometrických funkcí
Před nedávnem jsme ve škole dělali goniometrické
funkce a vše co k nim patří. Proto jsem si udělal pomůcku
díky, které jsme měl vždy úkol hotový. Chvíli jsem na tom pracoval –
fungují tam i posuvy, ale boužel jsem neudělal dynamické měřítko. A to
z jednoho prostého důvodu: nenapadlo mě, že by mohla nastat taková
situace, že by se graf mohl posouvat po ose x do mínusu(do prava). Takže
boužel dokážet zobrazovat graf jen od –360° do + 360°. Většině lidem,
kteří jsou ve 2. ročníku střední školy se toto může hodit.
Skript umí posuvy po osách, kromě výše zmíněné chyby, umí vykreslit
funkce: sinus, kosinus, tangens, kotangens,
sekans, kosekans. Zvýrazněné tučně umí zobrazit dobře ty ostatní trochu
blbnou. Opravit by to šlo, ale nechce se mi to dělat
. Celý skript je psaný v PHP jako třída. Dávám ho sem jako
„opensource“. Tak snad se někomu bude hodit.
Kód ukazky
<?php
include "./trigonometric.class.php";
$trigonometricFunction = new trigonometricFunction("Grafy goniometrických funkcí");
$trigonometricFunction->addColor(array(82, 208, 235));
$trigonometricFunction->addColor(array(128, 255, 20));
$trigonometricFunction->addColor(array(128, 55, 100));
$trigonometricFunction->addColor(array(175, 54, 54));
$trigonometricFunction->addColor(array(10, 111, 150));
$trigonometricFunction->addColor(array(195, 14, 214));
$trigonometricFunction->addFunction("f:y=cos(2*x)-1");
$trigonometricFunction->addFunction("f:y=sin(2*x)+1");
$trigonometricFunction->addFunction("f:y=cos(x+360)+1");
$trigonometricFunction->addFunction("f:y=sin(x+360)-1");
?>
Kód třídy
<?php
/*
* Martin Bumba 2007
* Grafy goniometrických funkcí - opensource
*/
function tg($x) {
return tan($x);
}
function cotg($x) {
return @(cos($x)/sin($x));
}
function sec($x) {
return (1/cos($x));
}
function cosec($x) {
return @(1/sin($x));
}
class trigonometricFunction {
var $width = 800;
var $height = 640;
var $name = "Graf goniometrické funkce";
var $fontPath = "/home/www/evil666.net/subdomains/www/examples/trigonometric/";
var $fontFile = "tahoma.ttf";
var $antialias = 1; //1 - antialias is turned off ; 2 -> 10 - antialias step (turned on)
var $image;
var $border = 14;
var $backgroundColor = array(255, 255, 255);
var $titleColor = array(110, 110, 110);
var $borderColor = array(210, 210, 210);
var $borderTop = 12;
var $functions = array();
var $functionColors; /*array(
array(82, 208, 235),
array(150, 108, 235)
); */
function __construct($name = false, $width = false, $height = false) {
if(!empty($name)) {
$this->name = $this->encodeString(htmlspecialchars($name));
}
if(!empty($width) AND is_numeric($width)) {
$this->width = round($width);
}
if(!empty($height) AND is_numeric($height)) {
$this->height = round($height);
}
}
private function encodeString($input) {
$UTFtable = array( "Č"=>268, "č"=>269,
"Ď"=>270, "ď"=>271,
"Ě"=>282, "ě"=>283,
"Ň"=>327, "ň"=>328,
"Ř"=>344, "ř"=>345,
"Š"=>352, "š"=>353,
"Ť"=>356, "ť"=>357,
"Ů"=>366, "ů"=>367,
"Ž"=>381, "ž"=>382);
$output = "";
for($i=0; $i < strlen($input); $i++) {
if ($UTFtable[$vstup_str[$i]]) {
$output .= "&#" . $UTFtable[$input[$i]] . ";";
}
else {
$output .= $input[$i];
}
}
return $output;
}
public function changeFont($newFontFile = false) {
if(preg_match('/.*?\.ttf/sim', $newFontFile) AND file_exists($this->fontPath . str_replace(array("/", "\\"), "", $newFontFile))) {
$this->fontFile = $newFontFile;
}
}
private function drawAxis($color, $pointColor, $fontColor, $labels) {
$jumper = (($this->width - (2 * $this->border))/2)/360;
#Axis X
$x_x1 = $this->border;
$x_x2 = $this->width - $this->border;
$x_y = ($this->height + $this->borderTop) / 2 ;
imageLine($this->image, $x_x1, $x_y, $x_x2, $x_y, $color);
$xWidth = $this->width - 2 * $this->border;
$xLabel = -round(round($xWidth / 20) / 2);
for($i = 0; $i <= 720; $i = $i + 5) {
$pointHeight = 2;
if($i % 30 == 0 ) {
$label = -360 + $i; //"π"
if(strlen($label) == 3) {
$label = " " . $label;
}
elseif(strlen($label) == 2 AND $label>0) {
$label = " " . $label;
}
$pointHeight = 5;
imageTtfText($this->image, 8, 0, $this->border + $i * $jumper - 14, $x_y + 20, $fontColor, $this->fontPath . $this->fontFile, $label. "°");
}
imageLine($this->image, $this->border + $i * $jumper, $x_y - $pointHeight, $this->border + $i * $jumper, $x_y + $pointHeight, $color);
}
#Axis Y
$y_x = $this->width/2;
$y_y1 = $this->border + $this->borderTop;
$y_y2 = $this->height - $this->border;
$this->axisYtopY = $y_y1;
$this->axisYbottomY = $y_y2;
imageLine($this->image, $y_x, $y_y1, $y_x, $y_y2, $color);
$yHeight = $this->height - 2 * $this->border - $this->borderTop;
$yLabel = round(round($yHeight / 100) / 2);
for($i = 0; $i <= $yHeight; $i++) {
$pointWidth = 2;
if($i % 50 == 0) {
$labelHelper = "";
$pointWidth = 5;
if(strlen($yLabel) == 1) {
$labelHelper = " ";
}
elseif(strlen($yLabel) == 2) {
$labelHelper = " ";
}
if($yLabel != 0) imageTtfText($this->image, 8, 0, $y_x - 25, $this->border + $this->borderTop + $i + 4, $fontColor, $this->fontPath . $this->fontFile, $labelHelper . $yLabel);
$yLabel -= 0.5;
}
if($i % 5 == 0 ) {
imageLine($this->image, $y_x - $pointWidth, $this->border + $this->borderTop + $i, $y_x + $pointWidth, $this->border + $this->borderTop + $i, $color);
}
}
}
public function addFunction($function = false) {
$function = strtolower(str_replace(" ", "", htmlspecialchars($function)));
if(preg_match('/f:y=(.*?)\((.*?)\)(.*)/sim', $function, $matches)) {
if($matches[1]=="sin" OR $matches[1]=="cos" OR $matches[1]=="tg" OR $matches[1]=="cotg" OR $matches[1]=="sec" OR $matches[1]=="cosec") {
if(!empty($matches[2])) {
$this->functions[] = array("fullFunction" => $matches[0], "function" => $matches[1], "argument" => htmlspecialchars($matches[2]), "argument_2" => htmlspecialchars($matches[3]));
}
}
}
}
private function drawFunctions($colors) {
$y = ($this->height + $this->borderTop) / 2;
$jumper = (($this->width - (2 * $this->border))/2)/360;
$f = 0;
$feed = 0;
foreach($this->functions AS $function) {
$x = $this->width / 2;
if($feed_e = explode('+', $function["argument"])) {
$feed = $feed_e[1];
}
if($feed_e = explode('-', $function["argument"])) {
$feed -= $feed_e[1];
}
if(!empty($feed)) {
$x += $feed * (-1 ) * $jumper;
$function["argument"] = $feed_e[0];
}
for($i=0;$i<=360;$i++) {
$now_argument = str_replace("x", $i, $function["argument"]);
eval("\$now_argument = ".$now_argument.";");
$y_value = $function["function"](deg2rad($now_argument));
if($y_value OR $y_value==0) {
if(!empty($function["argument_2"])) {
eval("\$y_value = ".$y_value." ".$function["argument_2"].";");
}
$y_value = 100 * round(-1 * $y_value ,2);
$rew = 1;
if($now_argument<0) {
$rew = -1;
}
if($i!=0) {
imageSetThickness($this->image, 1);
imageLine($this->image, $x + $i * $jumper -1, $y + $back_y_value, $x + $i * $jumper, $y + $y_value, $colors[$f]);
imageSetThickness($this->image, 1);
}
$back_y_value = $y_value;
}
}
$f++;
if(count($colors) == $f) $f = 0;
}
}
private function getColors($colors) {
$output_colors = array();
foreach($colors AS $color) {
$output_colors[] = imageColorAllocate($this->image, $color[0], $color[1], $color[2]);
}
return $output_colors;
}
public function addColor($color) {
if(!empty($color)) {
$this->functionColors[] = array($color[0], $color[1], $color[2]);
}
return true;
}
private function labelColor($x, $y, $size, $color, $border_color) {
$points = Array(
$x, $y,
$x + $size, $y,
$x + $size, $y + $size,
$x, $y + $size
);
$border_size = 1;
ImageLine($this->image, $x - $border_size, $y - $border_size, $x + $size + $border_size, $y - $border_size, $border_color);
ImageLine($this->image, $x - $border_size, $y, $x - $border_size , $y + $size + $border_size, $border_color);
ImageLine($this->image, $x, $y + $size + $border_size, $x + $size + $border_size , $y + $size + $border_size, $border_color);
ImageLine($this->image, $x + $size + $border_size, $y + $size + $border_size, $x + $size + $border_size, $y, $border_color);
ImageFilledPolygon($this->image, $points, 4, $color);
}
private function drawLegend($colors) {
$stepLegend = 15;
$width = 150;
$xLegend = $this->width - $width - 1;
$yLegend = $this->height - $stepLegend * count($this->functions) - 1;
$points = Array(
$xLegend, $yLegend,
$xLegend, $yLegend + $stepLegend * count($this->functions),
$xLegend + $width, $yLegend + $stepLegend * count($this->functions),
$xLegend + $width, $yLegend
);
ImageFilledPolygon($this->image, $points, 4, imageColorAllocate($this->image, $this->backgroundColor[0], $this->backgroundColor[1], $this->backgroundColor[2]));
ImagePolygon($this->image, $points, 4, imageColorAllocate($this->image, $this->borderColor[0], $this->borderColor[1], $this->borderColor[2]));
$f = 0;
$xLegend += 5;
$yLegend += 5;
foreach($this->functions AS $function) {
$this->labelColor($xLegend, $yLegend, 6, $colors[$f], imageColorAllocate($this->image, $this->borderColor[0], $this->borderColor[1], $this->borderColor[2]));
ImageTtfText($this->image, 8, 0, $xLegend+10, $yLegend+7, imageColorAllocate($this->image, $this->titleColor[0], $this->titleColor[1], $this->titleColor[2]), $this->fontPath . $this->fontFile, $this->encodeString($function["fullFunction"]));
$yLegend += $stepLegend;
$f++;
if(count($colors) == $f) $f = 0;
}
}
function __destruct() {
header("Content-type: image/png");
$this->width = $this->width * $this->antialias;
$this->height = $this->height * $this->antialias;
$this->image = ImageCreateTrueColor($this->width, $this->height);
$white = imageColorAllocate($this->image, 255, 255, 255);
$black = imageColorAllocate($this->image, 0, 0, 0);
$gray = imageColorAllocate($this->image, 120, 120, 120);
imageFill($this->image, 0, 0, imageColorAllocate($this->image, $this->backgroundColor[0], $this->backgroundColor[1], $this->backgroundColor[2]));
$this->drawAxis($black, $black, $gray, false);
$this->drawFunctions($this->getColors($this->functionColors));
$this->drawLegend($this->getColors($this->functionColors));
$titleTtfBox = ImageTtfbbox (14, 0, $this->fontPath . $this->fontFile, $this->encodeString($this->name));
$titleWidth = $titleTtfBox[2] - $titleTtfBox[0];
$xTitle = round((($this->width)-$titleWidth)/2);
ImageTtfText($this->image, 14, 0, $xTitle, 16, imageColorAllocate($this->image, $this->titleColor[0], $this->titleColor[1], $this->titleColor[2]), $this->fontPath . $this->fontFile, $this->encodeString($this->name));
imagePNG($this->image);
imageDestroy($this->image);
}
}
?>
[1] Cynebeald
Takova technicka poznamka – nestaci ze nekam napises ze je neco „opensource“ protoze ta definice je tak siroka ze v podstate vubec nic neznamena (podobne jako pouhe oznaceni „freeware“ nic neznamena).
Takze bych ti doporucil projit si nektery konkretni opensource licence a nejakou vybrat (pro jednoduchost treba licenci typu creative commons) protoze do ty doby si s tim muze kazdej delat co chce.
A asi by to taky chtelo si projit pravidla ceskyho pravopisu, z ty prvni vety by si nekdo moh myslet ze jsi holka
Zasláno před 1518 dny | Odpovědět
Na komentář reagoval [2] Martin
[2] Martin
[1] Cynebeald: Ano máš pravdu asi bude vhodnější dát tomu licenci GPL. Jo za chyby se omlouvám, čeština nikdy nebyla má silná stránka
. Ta první věta už by měla byt ok
.
Zasláno před 1518 dny | Odpovědět
Na komentář reagoval [3] Cynebeald
[3] Cynebeald
[2] Martin: No, GPL licence je pro mnoho pripadu pouziti zase prilis restriktivni. Napriklad to znamena, ze tu tridu nemuze nikdo pouzit v programu ktery neni sam o sobe GPL, coz muze (ale nemusi) byt to co chces. Mimo jine to znamena, ze ten kod neni mozny pouzit ani v jinym opensource programu pokud ma treba BSD nebo Apache licenci.
Neni opensource jako opensource
Zasláno před 1518 dny | Odpovědět
Na komentář reagoval [4] Martin
[4] Martin
[3] Cynebeald: :D Tak mi řekni co mám zvolit jako licenci?
Zasláno před 1518 dny | Odpovědět