immagini.php

<?php

class gf_cartesiano {
    
// dimensioni immagine totale
    
var $_x_size_;
    var 
$_y_size_;
    
// coordinate origine assi
    
var $_x0_;
    var 
$_y0_;
    
// dimensioni asse x
    
var $_xi_;
    var 
$_xf_;
    var 
$_x_axis_;
    
// dimensioni asse y
    
var $_yi_;
    var 
$_yf_;
    var 
$_y_axis_;
    
// l'immagine
    
var $image;
    
// qualche colore
    
var $white;
    var 
$black;
    var 
$red;
    var 
$blue;
    var 
$yellow;
    
// uso un po' strano perche' non settata in modo valido dal costruttore
    
var $scale;

Function 
gf_cartesiano(&$x_axis, &$y_axis)
// costruttore
{
    
// settta le dimensioni dell'immagine
    
$this->_x_size_ 480;
    
$this->_y_size_ 480;
    
// coordinate origine assi
    
$this->_x0_ 30;
    
$this->_y0_ $this->_y_size_ 30;
    
// dimensioni asse x
    
$this->_xi_ 10;
    
$this->_xf_ $this->_x_size_ $this->_xi_;
    
$this->_x_axis_ $this->_xf_ $this->_x0_ 10;
    
$x_axis $this->_x_axis_;
    
// dimensioni asse y
    
$this->_yi_ 10;
    
$this->_yf_ $this->_y_size_ $this->_yi_;
    
$this->_y_axis_ $this->_yf_ $this->_y0_ 10;
    
$y_axis $this->_y_axis_;
    
// crea lo sfondo
    
$this->image imagecreate($this->_x_size_ $this->_y_size_ );
    
// alloca i colori
    
$this->white ImageColorAllocate($this->image255,255,255);
    
$this->black ImageColorAllocate($this->image0,0,0);
    
$this->red ImageColorAllocate($this->image255,0,0);
    
$this->green ImageColorAllocate($this->image0,255,0);
    
$this->blue ImageColorAllocate($this->image0,0,255);
    
$this->magenta ImageColorAllocate($this->image255,0,255);
    
$this->yellow ImageColorAllocate($this->image255,255,0);
    
$this->darkgreen ImageColorAllocate($this->image0,100,0);
    
$this->darkorange ImageColorAllocate($this->image255,127,0);

    
// assegna un valore a caso a scale
    
$this->scale=1;

    
// ritorna il puntatore all'immagine
    
return $this->image;
}

Function 
fq_col($col)
// colora il primo quadrante
{
    
$tile imageCreateFromPNG('images/regione_amm.png');
    if (
$tile == false) { die ('Unable to open image'); }
    
imageSetTile ($this->image$tile);
//    imagefilledrectangle($this->image, 30, 20, 460, 450, $col);
    
imagefilledrectangle($this->image3020460450IMG_COLOR_TILED);
}

Function 
assi($vertici$scale)
// disegna gli assi e scrive i valori
{
    
// disegna asse x
    
imageline($this->image,$this->_xi_,$this->_y0_,$this->_xf_,$this->_y0_,$this->black);
    
// disegna frecce asse x
    
imageline($this->image,$this->_xf_-10,$this->_y0_-10,$this->_xf_,$this->_y0_,$this->black);
    
imageline($this->image,$this->_xf_-10,$this->_y0_+10,$this->_xf_,$this->_y0_,$this->black);
    
// scrivi O nell'origine
    
imagechar($this->image,3,$this->_x0_-25,$this->_y0_+10,"O",$this->black); 
    
// disegna lettere asse x e stanghette
    
imagechar($this->image,3,$this->_xf_-10,$this->_y0_+10,"x",$this->black);
    
imagechar($this->image,2,$this->_xf_,$this->_y0_+15,"1",$this->black);
    for (
$i=0$i<count($vertici); $i+=2)
        if (
$vertici[$i] > 0) {
            
$x $this->map_x ($vertici[$i], $scale);
            
imageline($this->image$x$this->_y0_$x$this->_y0_+5$this->black);
            
$lettere=number_format($vertici[$i],2,",",".");
            
imagestring($this->image3$x 10$this->_y0_+10$lettere$this->black);
        }
    
// disegna asse y
    
imageline($this->image,$this->_x0_,$this->_yi_,$this->_x0_,$this->_yf_,$this->black);
    
// disegna frecce asse y
    
imageline($this->image,$this->_x0_-10,$this->_yi_+10,$this->_x0_,$this->_yi_,$this->black);
    
imageline($this->image,$this->_x0_+10,$this->_yi_+10,$this->_x0_,$this->_yi_,$this->black);
    
// disegna lettere asse y
    
imagechar($this->image,3,$this->_x0_-25,$this->_yi_+5,"x",$this->black);
    
imagechar($this->image,2,$this->_x0_-15,$this->_yi_+10,"2",$this->black);
    for (
$i=1$i<count($vertici); $i+=2)
        if (
$vertici[$i] > 0) {
            
$y $this->map_y ($vertici[$i], $scale);
            
imageline($this->image$this->_x0_-5$y$this->_x0_$y$this->black);
            
$lettere=number_format($vertici[$i],2,",",".");
            
imagestring($this->image3$this->_x0_ 30$y$lettere$this->black);
        }
}

Function 
map_x ($vx$scale)
/* ritorna il valore della coordinata x sull'immagine corrispondente al punto 
   di coordinata vx nell'asse cartesiano, fissato il parametro di scala */
{
    return 
$this->_x0_ round($scale $vx);
}

Function 
map_y ($vy$scale)
/* ritorna il valore della coordinata y sull'immagine corrispondente al punto 
   di coordinata vy nell'asse cartesiano, fissato il parametro di scala */
{
    return 
$this->_y0_ round($scale $vy); 
}

Function 
ruota ($x$y, &$xr, &$yr$alpha)
// ruota (x, y)-(0 ,0) di un angolo alpha
{
    
$xr $x cos($alpha) - $y sin ($alpha);
    
$yr $y cos($alpha) + $x sin ($alpha);
}

Function 
line($scale$vxi$vyi$vxf$vyf$col)
/* disegna il segmento corrispondente a quello PQ fra P=(vxi, vyi) e q=(vxf, vyf) */
{
    
// calcolo nuove coordinate
    
$xi $this->map_x ($vxi$scale);
    
$xf $this->map_x ($vxf$scale);
    
$yi $this->map_y ($vyi$scale);
    
$yf $this->map_y ($vyf$scale);
    
// disegna il segmento
    
imageline($this->image,$xi,$yi,$xf,$yf,$col);
}

Function 
freccia($scale$vxi$vyi$vxf$vyf$col)
/* disegna la freccia P-Q fra P=(vxi, vyi) e q=(vxf, vyf) con ampiezza 45 gradi*/
{
    
/*             R             R __. P
              45° \                 /\  S
       Q ----------> P             / angolo di cui calcolo sin e cos
              45° /       _______ /)______________ 
                 S               Q               x
    */
    
    // calcolo nuove coordinate
    
$xi $this->map_x ($vxi$scale);
    
$xf $this->map_x ($vxf$scale);
    
$yi $this->map_y ($vyi$scale);
    
$yf $this->map_y ($vyf$scale);
    
// trasliamo P-Q nell'origine per fare i conti
    
$x $xf-$xi;
    
$y = -($yf-$yi);
    
$modulo sqrt($x*$x+$y*$y);
    
// calcola seno e coseno dell'angolo fra il segmento e l'asse x
    
if (! $modulo)
        return 
0;
    
$sin_ =  $y $modulo;
    
$cos_ =  $x $modulo;
    
// calcola gli estremi dei segmenti delle frecce
    // r rotazione di 45° del vettore di modulo 10 e direzione di Q-P
    
$this->ruota (-10 $cos_, -10 $sin_$xr$yrM_PI/6);
    
$xr += $xf;
    
$yr $yf $yr;
    
// s rotazione di -45° del vettore di modulo 10 e direzione di Q-P
    
$this->ruota (-10 $cos_, -10 $sin_$xs$ys11*M_PI/6);
    
$xs += $xf;
    
$ys $yf $ys;

    
// disegna il segmento
    
imageline($this->image,$xi,$yi,$xf,$yf,$col);
    
imagefilledpolygon($this->image, array($xr$yr$xs$ys$xf$yf), 3$col);
    
//imageline($this->image,$xr,$yr,$xf,$yf,$col);
    //imageline($this->image,$xs,$ys,$xf,$yf,$col);
}


Function 
cerchio ($scale$vx0$vy0$l$col)
/* disegna una circonferenza di raggio r pixel e centro P=(vx, vy) */
{
    
$x0 $this->map_x ($vx0$scale);
    
$y0 $this->map_y ($vy0$scale);
    
$l2=round($l/2);
    
//imagefilledellipse($this->image,$x0,$y0,$r,$r,$col); // non gestita da vecchie gd
    
imagefilledrectangle($this->image,$x0-$l2,$y0-$l2,$x0+$l2,$y0+$l2,$col);
}

Function 
ping($name)
// scrive l'immagine in formato PNG nel file di nome $name
{
    
imagepng($this->image$name);
}

Function 
plotta_disequazione($ax$ay$b$lge$scale$col)
/* disegna i segmenti corrispondenti alla dis/equazione immesssa e cancella
   la parte che non verifica la disequazione usando il colore $col */
{   // ax x + ay y lge b
    
    // costanti
    
$max $this->_x_axis_ $scale;
    
$p0x 0$p0y 0;
    
$p1x $max$p1y 0;
    
$p2x $max$p2y $max;
    
$p3x 0$p3y $max;
    if (
$ax == 0) { // ay y = b
        
$vx0 0;
        
$vx1 $max;
        
$vy0 $b $ay;
        
$vy1 $vy0;
        
// se si tratta di un'equazione, scrivi l'immagine e ritorna
        
if (! strcmp($lge"=")) {
            
$this->line($scale$vx0$vy0$vx1$vy1$col);
            return 
0;
        }
        
// si tratta di una disequazione ay y <> b
        
if( strstr ($lge">")) 
            if (
$ay>0)
                
$cancella_sotto=true;
            else
                
$cancella_sotto=false;
        else
            if (
$ay>0)
                
$cancella_sotto=false;
            else
                
$cancella_sotto=true;
        if (
$cancella_sotto) {
            if (
$vy0 0)
                
imagefilledrectangle($this->image$this->map_x(0$scale), $this->map_y($vy0$scale), $this->map_x($max$scale), $this->map_y(0$scale), $col);
        } else
            if (
$vy0 0)
                
imagefilledrectangle($this->image$this->map_x(0$scale), $this->map_y($max$scale), $this->map_x($max$scale), $this->map_y($vy0$scale), $col);
            else
                
imagefilledrectangle($this->image$this->map_x(0$scale), $this->map_y($max$scale), $this->map_x($max$scale), $this->map_y(0$scale), $col);
      return 
0;
    }
    if (
$ay) {
        
$m =  -$ax/$ay;
        
$q $b/$ay;
    } else { 
// ax x = b
      
$vx0 $b $ax;
      
$vx1 $vx0;
      
$vy0 0;
      
$vy1 $max;
        
// se si tratta di un'equazione, scrivi l'immagine e ritorna
        
if (! strcmp($lge"=")) {
            
$this->line($scale$vx0$vy0$vx1$vy1$col);
            return 
0;
        }
        
// si tratta di una disequazione
        
if( strstr ($lge">")) 
            if (
$ax>0)
                
$cancella_sx=true;
            else
                
$cancella_sx=false;
        else
            if (
$ax>0)
                
$cancella_sx=false;
            else
                
$cancella_sx=true;
        if (
$cancella_sx) {
            if (
$vx0 0)
                
imagefilledrectangle($this->image$this->map_x(0$scale), $this->map_y($max$scale), $this->map_x($vx0$scale), $this->map_y(0$scale), $col);
        } else
            if (
$vx0 0)
                
imagefilledrectangle($this->image$this->map_x($vx0$scale), $this->map_y($max$scale), $this->map_x($max$scale), $this->map_y(0$scale), $col);
            else
                
imagefilledrectangle($this->image$this->map_x(0$scale), $this->map_y($max$scale), $this->map_x($max$scale), $this->map_y(0$scale), $col);
        return 
0;
    }
    
// setta i vertici della retta ax x + ay y = b
    
if ($m >= 0
        if (
$q >= 0) {
            
$vx0 0$vy0 $q;
            if ((
$vy1 $m*$max+$q) < $max) {
                
$vx1 $max;
            } else {
                
$vy1 $max;
                
$vx1 = ($max-$q)/$m;
            }
        } else {
            
$vx0 $b/$ax$vy0 0;
            if ((
$vy1 $m*$max+$q) < $max) {
                
$vx1 $max;
            } else {
                
$vy1 $max;
                
$vx1 = ($max-$q)/$m;
            }
        }
    else { 
// m<0
        
if ($q >= 0) {
            
$vx0 0$vy0 $q;
            if ((
$vy1 $m*$max+$q) > 0) {
                
$vx1 $max;
            } else {
                
$vy1 0;
                
$vx1 $b/$ax;
            }
        }
    }

    
// se si tratta di un'equazione, scrivi l'immagine e ritorna
    
if (! strcmp($lge"=")) {
        
$this->line($scale$vx0$vy0$vx1$vy1$col);
        return 
0;
    }
    
    
// si tratta di una disequazione
    
if( strstr ($lge">")) 
        if (
$ay>0)
            
$cancella_sotto=true;
        else
            
$cancella_sotto=false;
    else
        if (
$ay>0)
            
$cancella_sotto=false;
        else
            
$cancella_sotto=true;

    if (
$m >= 0)    // m >= 0
        
if ($q >= 0) { // m, q >= 0
            
if (! $cancella_sotto) { // m, q >= 0: colora il poligono piu' alto
                
if ($vx1 == $max)
                    
$array = array($vx0$vy0$vx1$vy1$p2x$p2y$p3x$p3y);
                else
                    
$array = array($vx0$vy0$vx1$vy1$p3x$p3y);
            } else { 
// m, q >= 0: colora il poligono in basso
                
if ($vx1 == $max)
                    
$array = array($vx0$vy0$vx1$vy1$p1x$p1y$p0x$p0y);
                else
                    
$array = array($vx0$vy0$vx1$vy1$p2x$p2y$p1x$p1y$p0x$p0y);
            }
        } else { 
// m>=0, q<0
            
if (! $cancella_sotto) { // m>=0, q<0: alto
                
if ($vx1 == $max)
                    
$array = array($vx0$vy0$vx1$vy1$p2x$p2y$p3x$p3y$p0x$p0y);
                else
                    
$array = array($vx0$vy0$vx1$vy1$p3x$p3y$p0x$p0y);
            } else { 
// m>=0, q<0: basso
                
if ($vx1 == $max)
                    
$array = array($vx0$vy0$vx1$vy1$p1x$p1y);
                else
                    
$array = array($vx0$vy0$vx1$vy1$p2x$p2y$p1x$p1y);
            }
        }
    else  
// m < 0
        
if ($q >= 0) { // m < 0, q >= 0
            
if (! $cancella_sotto) { // m < 0, q >= 0: alto
                
if ($vx1 == $max)
                    
$array = array($vx0$vy0$vx1$vy1$p2x$p2y$p3x$p3y);
                else
                    
$array = array($vx0$vy0$vx1$vy1$p1x$p1y$p2x$p2y$p3x$p3y);
            } else { 
// m < 0, q >= 0: basso
                
if ($vx1 == $max)
                    
$array = array($vx0$vy0$vx1$vy1$p1x$p1y$p0x$p0y);
                else
                    
$array = array($vx0$vy0$vx1$vy1$p0x$p0y);
            }
        } else { 
// m, q < 0
            
if (! $cancella_sotto) { // m>=0, q<0: alto
                
if ($vx1 == $max)
                    
$array = array($p0x$p0y$px1$py1$p2x$p2y$p3x$p3y$p4x$p4y);
            }
        }
    if (isset (
$array)) {
        for (
$i=0$i count ($array);) {
            
$array[$i] = $this->map_x ($array[$i++], $scale);
            
$array[$i] = $this->map_y ($array[$i++], $scale);
        }
        
imagefilledpolygon($this->image$arraycount ($array) / 2$col);
        unset (
$array);
    }
}


}

class 
grafico extends gf_cartesiano {

    var 
$basename;
    var 
$middlename;
    var 
$extension ".png";
    var 
$vertici;
    var 
$grad_x;
    var 
$grad_y;

Function 
grafico ($_a$_b$_c$lge$cambia_segno_gradiente$name)
{
    
/* sostituisci in $a, $b, $c i valori agli oggetti frazione */
    
for ($i=1$i count ($_b)+1$i++) {
        
$b[$i] = $_b[$i]->value();
        for (
$j=1$j 3$j++)
            
$a[$i][$j] = $_a[$i][$j]->value();
    }
    for (
$j=1$j 3$j++)
        
$c[$j] = $_c[$j]->value();

    if (
$cambia_segno_gradiente) {
        
$this->grad_x = -$c[1];
        
$this->grad_y = -$c[2];
    } else {
        
$this->grad_x $c[1];
        
$this->grad_y $c[2];
    }

    
$this->basename $name;
    
$this->image $this->gf_cartesiano ($asse_x$asse_y);
    
$this->fq_col($this->yellow);

    
$this->trova_vertici($a$b$vertici);
    
$max $this->cerca_max($vertici)*1.1;
    if (
$asse_x >= $asse_y)
        
$asse_max $asse_x;
    else
        
$asse_max $asse_y;
    
$this->scale $asse_max $max;
    for (
$i=1$i count ($b)+1$i++)
        
$this->plotta_disequazione($a[$i][1], $a[$i][2], $b[$i], $lge[$i], $this->scale$this->white);
    for (
$i=1$i count ($b)+1$i++)
        
$this->plotta_disequazione($a[$i][1], $a[$i][2], $b[$i], "="$this->scale$this->blue);
    
$this->gradiente();
    
$this->assi($vertici$this->scale);
    
$name $this->basename $this->extension;
    
$this->ping($name);
    return 
$this->image;
}

Function 
gradiente ()
{
//    $this->freccia($this->scale, 0, 0, $this->grad_x, $this->grad_y, $this->magenta);
    
$this->freccia($this->scale00$this->grad_x$this->grad_y$this->red);
}

Function 
passo($xi$yi$xf$yf$passo, &$name)
{
    
$name $this->basename $passo;
    
$this->cerchio($this->scale$xf$yf6$this->red);
    
$this->freccia($this->scale$xi$yi$xf$yf$this->darkorange);
    
/* la perpendicolare al gradiente passante per xf, yf */
    
$this->plotta_disequazione($this->grad_x$this->grad_y, ($xf*$this->grad_x+$yf*$this->grad_y), "="$this->scale$this->green);

    
$this->ping($name".png");
}


Function 
cerca_max(&$vertici)
{

    
$max $vertici[0];
    for (
$i=1$i<count($vertici); $i++)
        if (
$vertici[$i]>$max)
            
$max $vertici[$i];
    
// $max e' il max fra le intercette e i valori di x e di y dei vertici

    
return $max;
}

Function 
trova_vertici($a$b, &$vertici)
{
    
$m count ($b);
    
// dove incidono le rette
    
for($k=0$i=1$i<$m+1$i++)
        for (
$j=$i+1$j<$m+1$j++) {
            
// le x
            
if ( $a[$i][1]*$a[$j][2] != $a[$j][1]*$a[$i][2] )
                
$vertici[$k]= ( $a[$j][2]*$b[$i]    -    $a[$i][2]*$b[$j] ) /
                         ( 
$a[$i][1]*$a[$j][2] -$a[$j][1]*$a[$i][2] );
            else
                
$vertici[$k]=0;
            
$k++;
            
// le y
            
if ($a[$i][2]!=0)
                
$vertici[$k]=( $b[$i]-$a[$i][1]*$vertici[$k-1] ) / $a[$i][2];
            else
                
$vertici[$k]=0;
            
$k++;
        }
    
// aggiungiamo intersezioni con gli assi
    
for ($i=0$i<$m+1$i++) {
            if (
$a[$i][1] != 0)
                
$vertici[$k++] = $b[$i]/$a[$i][1];
            else
                
$vertici[$k++]=0;
            if (
$a[$i][2] != 0)
                
$vertici[$k++] = $b[$i]/$a[$i][2];
            else
                
$vertici[$k++]=0;
    }

}

}
?>