Fondamenti di programmazione

Corso php a cura del prof. Pietro De Paolis

Grafico della funzione quadratica

y= ax2 + bx + c

Sappiamo che un funzione matematica si può rappresentare su di un sistema di assi cartesiani. Se sull'asse orizzontale delle ascisse rappresentiamo la variabile indipendente x e sull'asse verticale delle ordinate rappresentiamo il valore che assume la funzione in x, cioè y= f(x) otteniamo per ogni valore di x la coppia (x; y) che costituisce un punto del grafico della funzione. Cioè il grafico è l'insieme dei punti la cui ascissa è x e la cui ordinata è y=f(x).

Il php ha delle funzioni grafiche che abbiamo già visto, per cui lo possiamo utilizzare per il disegno del grafico della funzione su di un sistema di assi cartesiani.

Supponiamo di voler disegnare il grafico della funzione:

y= ax2 + bx + c

con a, b, c numeri reali.

Se a è diverso da zero si tratta di una parabola.

Data in particolare la equazione:

y= 4x2 + 2x + 3

il grafico sarà il seguente:

Grafico di y = 4x2+ 2x +3

Occorre dare i comandi giusti per disegnare l'immagine sullo schermo del computer.

 Schermata del programma iniziale equazione2.php

Dividiamo il programma da costruire in due programmi; un primo programma lo chiameremo equazione2.php  ed ha lo scopo di far scrivere all'utente il valore dei numeri: a, b, c e della scala da usare per il disegno del grafico della funzione.

Programma equazione2.php

Questo programma mi serve per poter consentire all'utente di cambiare i valori sia di a sia  di sia di c; questi valori verranno passati ad un secondo programma funzione4.php che eseguirà il disegno del grafico.

In html costruiremo un modulo con tre caselle di testo per inserire i tre coefficienti dell'equazione.

Con:

<form action="funzione4.php" name="modulo1">

inizio la costruzione del modulo con una istruzione form; quando il modulo verrà inviato esso richiamerà sul PC dell'utente la pagina:funzione4.php che eseguirà il disegno.

Con:

<input type="text" name="a" size="5" ... >

mi creo una casella di testo di nome a. Questo nome: a sarà l'equivalente in php di $a.

Con:

<input type="text" name="b" size="5" ...>

mi creo una casella di testo di nome b. Questo nome: b sarà l'equivalente in php di $b.

Con:

<input type="text" name="c" size="5"... >

mi creo una casella di testo di nome c. Questo nome: c sarà l'equivalente in php di $c.

Onde poter variare la scala dell'asse x con:

<input type="text" name="scalao" value="0.1" size="5" ...>

mi creo una casella di testo di nome scalao. Questo nome: scalao sarà l'equivalente in php di $scalao.

Onde poter variare la scala dell'asse y con:

<input type="text" name="scalav" value="1" size="5" ...>

mi creo una casella di testo di nome scalav. Questo nome: scalav sarà l'equivalente in php di $scalav.

Con:

<input type="Submit" value="DISEGNA GRAFICO">

mi creo il tasto di invio dei dati

Premendo questo tasto oppure premendo invio, i dati contenuti nel modulo verranno trasmessi al programma successivo cioè funzione4.php .

Con:

</form>

</html>

chiudo il modulo e chiudo la pagina in html.

Il listato completo di questo primo programma è il seguente:

<html>

<head>

<title></title>

</head>

<body background="../../../immagini/sfondo2.jpg">

<font face="Verdana" color="#FF00FF" size="5">

Programma per il disegno del grafico di una funzione quadratica</font><p align="center"><font face="Verdana" size="4" color="#FF0000">y =

ax<sup>2</sup> + bx + c</font><br></p>

<form action="funzione4.php" name="modulo1">

<div align="left">

<table border="1" cellpadding="0" width="100%"><tr>

<td width="100%">

<p align="center"><font size="4" face="Verdana">y = <input type="text" name="a" size="5" style="background-image: url('../../../immagini/sfondo3.gif'); color: #FF0000; font-size: 14 pt; font-family: Verdana">

x<sup>2</sup> + <input type="text" name="b" size="5" style="background-image: url('../../../immagini/sfondo3.gif'); color: #FF0000; font-size: 14 pt; font-family: Verdana">x +

</font><font size="4" face="Verdana"> <input type="text" name="c" size="5" style="background-image: url('../../../immagini/sfondo3.gif'); color: #FF0000; font-size: 14 pt; font-family: Verdana">

</font></td></tr><tr>

<td width="100%">&nbsp</td>

</tr><tr><td width="100%">

<p align="center"><font face="Verdana" size="4">Scala x&nbsp; 1:</font> <font size="4" face="Verdana"> <input type="text" name="scalao" value="0.1" size="5" style="background-image: url('../../../immagini/sfondo3.gif'); color: #FF0000; font-size: 14 pt; font-family: Verdana">&nbsp;&nbsp;&nbsp;

Scala y&nbsp; 1:<input type="text" name="scalav" value="1" size="5" style="background-image: url('../../../immagini/sfondo3.gif'); color: #FF0000; font-size: 14 pt; font-family: Verdana">

</font></p></td></tr></table></div>

<p align="center">

<input type="Submit" value="DISEGNA GRAFICO">

</form>

</html>

programma iniziale in html equazione2.php

Una volta eseguito mi darà:

 Schermata del programma iniziale equazione2.php

 

con il quale l'utente può scrivere i trecoefficienti a,b,c e la scala orizzontale e verticale.

Programma funzione4.php

Questo secondo programma mi serve per il disegno del grafico sapendo i coefficienti a,b,c dell'equazione della funzione quadratica e la scala per i due assi.

Intanto ricordiamo che per disegnare in php occorre prima disegnare l'immagine nella memoria del server e poi mostrare l'immagine creata all'utente.

Il disegno è abbastanza delicato ed è una cosa da esperti; per cui non occorre scoraggiarsi ai primi insuccessi, ma tentare più volte fino a correggere gli errori più comuni.

Comunque noi seguiremo in ordine i seguenti passi.

1 - Il listato in php va scritto con un editor di testo, ma senza mischiare altri linguaggi o tag html; cioè il listato deve essere in puro php, iniziare con

<?php

e finire con

?>

Non usare istruzioni diverse da quelle del disegno, tipo la print; cioè la prima cosa che deve apparire sull'immagine finale deve essere la istruzione

header ("Content-type: image/png");

Questa è una istruzione delicata in quanto lo scambio di informazioni tra computer locale e server che invia l'immagine deve avvenire prima di qualunque altra istruzione; inoltre tutto quello che segue la istruzione header deve essere una istruzione di visualizzazione del disegno, altrimenti non viene visualizzata sullo schermo del pc. Per cui solo istruzioni che lavorano in memoria, che lavorano sui file, e istruzioni di disegno. Risultati non si possono vedere se non a parte, ma solo successivamente con un altro programma, magari anche salvando il disegno su un file di immagine (.pnp .jpg .gif) e poi mostrandolo insieme alle altre cose da far vedere all'utente.

2 - Creiamo una immagine a colori, cioè un foglio vuoto che ci serve da sfondo su cui disegnare:

$immagine = imagecreatetruecolor (550,300);

Salvo nella variabile $immagine questo foglio vuoto che ha la dimensione in orizzontale, pari a 550 punti (pixel dello schermo) e 300 punti in verticale. Per lo schermo l'origine degli assi, cioè 0 (0;0) è il punto più in alto a sinistra e non un punto in basso; per cui mentre l'asse x parte con lo 0 dal primo punto a sinistra e non al centro, l'asse y parte con lo 0 da sopra verso il basso.

3- Mi creo alcuni colori con cui disegnare successivamente; mi serve un colore nero con cui disegno gli assi cartesiani:

$nero = imagecolorallocate ($immagine, 0, 0, 0);

Cioè memorizzo nella varibile $nero un colore da usare per $immagine e questo colore sarà la somma dei tre colori fondamentali, cioè:

rosso =0;

giallo=0;

blu=0;

I numeri dei colori vanno da o a 255; dove 0 vuol dire che quel colore non c'è; 255 vuol dire che quel colore è al massimo di intensità.

Poi con:

$arancio = imagecolorallocate ($immagine, 250, 200,150);

Mi creo un colore arancio che memorizzo nella varibile $arancio da usare per $immagine e questo colore sarà la somma dei tre colori fondamentali, cioè:

rosso =250;

giallo=200;

blu=150;

Poi con: 

$blu = imagecolorallocate ($immagine, 0, 0,200);

Mi creo un colore blu che memorizzo nella varibile $blu da usare per $immagine e questo colore sarà la somma dei tre colori fondamentali, cioè:

rosso =0;

giallo=0;

blu=200;

Poi con: 

$rosso = imagecolorallocate ($immagine, 255, 0,0);

Mi creo un colore rosso che memorizzo nella varibile $rosso da usare per $immagine e questo colore sarà la somma dei tre colori fondamentali, cioè:

rosso =255;

giallo=0;

blu=0;

Una volta che dispongo di un foglio su cui disegnare e dei 4 colori che ho cselto di utilizzare inizio a disegnare sul foglio, ma sempre in memoria, in quanto i risultati non li vedrò se non alla fine del disegno.

4 - Ora mi disegno uno sfondo colorato invece del colore nero, in quanto lo ritengo più gradito.

imagefilledrectangle ($immagine, 0,0, 550, 300, $arancio);

Cioè mi disegno un rettangolo colorato del colore $arancio a partire dal punto superiore dello schermo, di coordinate (0;0) fino al punto inferiore destro di coordinate (550; 300).

A questo punto se volessi vedere il lavoro svolto in memoria dovrei inserire una istruzione:

header ("Content-type: image/png");

seguita da:

imagepng ($immagine);

La istruzione 

header ("Content-type: image/png");

indica il tipo di immagine; nel nostro caso abbiamo scelto il formato png; mentre:

imagepng ($immagine);

mostra all'utente l'immagine che ho memorizzato in formato png nella variabile $immagine.

Vedrò:

Rettangolo colorato

Il listato completo, infatti, è ora:

<?php

$immagine = imagecreatetruecolor (550,300);

$nero = imagecolorallocate ($immagine, 0, 0, 0);

$arancio = imagecolorallocate ($immagine, 250, 200,150);

$blu = imagecolorallocate ($immagine, 0, 0,200);

$rosso = imagecolorallocate ($immagine, 255, 0,0);

imagefilledrectangle ($immagine, 0,0, 550, 300, $arancio);

// mostro il grafico sulla pagina

header ("Content-type: image/png");

imagepng ($immagine);

// cancello il grafico in memoria

imagedestroy ($immagine);

?>

Rettangolo colorato funzione21.php

Notiamo la istruzione:

imagedestroy ($immagine);

che cancella l'immagine dalla memoria per evitare che la memoria del server si riempia. Essa va messa sempre alla fine di tutti i disegni.

5 - Ora mi disegno un sistema di assi cartesiani ortogonali; con la istruzione

imageline ($immagine, 10, 150, 500, 150, $nero);

tiro una linea che parte dal punto (10;150) e arriva al punto (500;150); cioè una linea orrizzontale di colore $nero al centro dello schermo.

Con la istruzione:

imageline ($immagine, 250, 10, 250, 300, $nero);

tiro una linea verticale, di colore $nero, che parte dal punto (250;10) e arriva al punto (250;300). 

Con le istruzioni:

imageline ($immagine, 500, 150, 490, 145, $nero);

imageline ($immagine, 500, 150, 490, 155, $nero);

imageline ($immagine, 250, 10, 245, 20, $nero);

imageline ($immagine, 250, 10, 255, 20, $nero);

tiro quattro piccoli segmenti obliqui, a forma di freccia,  sugli estremi degli assi onde indicare il verso positivo dei due assi x e y.

Con le istruzioni:

imagestring ($immagine, 5, 490, 125, "x", $blu);

imagestring ($immagine, 5, 270, 10, "y", $blu);

scrivo x sull'asse delle x ed y sull'asse delle y con un carettere avente dimensione 5 e colore $blu, nei punti (490;125) e (270;10).

Con le istruzioni:

$a = $_GET['a'];

$b = $_GET['b'];

$c = $_GET['c'];

$scalao = $_GET['scalao'];

$scalav = $_GET['scalav'];

salvo nella  variabile php $a il valore di a;  in $b il valore di b; in $c il valore di c; in $scalao il valore di scalao; in $scalav il valore di scalav;.

Ora per poter scrivere una didascalia del grafico devo tenere conto di diversi casi che si possono avere dei termine a,b,c.

Memorizzo nella variabile $descrizione il testo da scrivere sul grafico come didascalia.

Con:

$descrizione="Grafico di y = ".$a;

imagestring ($immagine, 5, 250, 280, $descrizione, $blu);

scrivo:

Grafico di y= a

Con:

if ($a) imagestring ($immagine, 3, 419, 277, "2", $blu);

if ($a) imagestring ($immagine, 5, 410, 280, "x", $blu);

se a esiste scriverà:

x2

Se, invece, a è nullo il termine x2 viene omesso.

Con:

if($b<0) $descrizione =$b."x";

if($b>0) $descrizione ="+ ".$b."x";

if($b==0) $descrizione =" ";

imagestring ($immagine, 5, 435, 280, $descrizione, $blu);

se b è diverso da zero scriverà:

+bx oppure -bx 

Infine con:

if($c<0) $descrizione=" ".$c;

if($c>0) $descrizione=" + ".$c;

if($c==0) $descrizione=" ";

imagestring ($immagine, 5, 480, 280, $descrizione, $blu);

scrivo il valore di $descrizione nel punto (480;280) col colore $blu e con dimensione del carattere uguale a 5.

Per poter variare la scala in base ai valori dei tre coefficienti utilizzo:

if($scalao!=0) $scalax=1/$scalao;

if($scalav!=0) $scalay=1/$scalav;

if($scalao==0) $scalax=1;

if($scalav==0) $scalay=1;

Cioè metto in $scalax il valore 1/$scalao se è diverso da zero; altrimenti metto il valore 1.

Analogamnete metto in $scalay il valore 1/$scalav se è diverso da zero; altrimenti metto il valore 1.

Con:

$max=25;

$incre=0.05;

stabilisco il valore massimo dei punti per calcolare il valore di y solo in alcuni punti. Tali punti partono da -25 fino a +25 con un incremento di 0.05 tra un punto e il successivo. Questi valori incidono sulla definizione del grafico disegnato.

Con:

// orizzontale

for($t=50; $t<500; $t+=50){

imageline ($immagine, $t, 145, $t, 155, $nero);

$testo=($t-250)/$scalax;

imagestring ($immagine, 4,$t-10, 158, $testo, $blu);

};

traccio dei segmenti verticali sull'asse x e scrivo i valori corrispondenti in base alla scala scelta dall'utente.

Con:

// verticale

for($t=50; $t<300; $t+=50){

imageline ($immagine, 245, $t, 255, $t, $nero);

$testo=(150-$t)/$scalay;

if($t!=150) imagestring ($immagine, 4,258, $t-8, $testo, $blu);

};

traccio dei segmenti orizzontali sull'asse y e scrivo i valori corrispondenti in base alla scala scelta dall'utente.

 

6- Completo il lavoro disegnando il grafico della funzione

y= ax2 + bx + c

sul sistema di assi cartesiani. Uso una istruzione for:

for ($t=-$max; $t<$max; $t+=$incre) {

$y=$a*$t*$t + $b*$t +$c;

imagestring ($immagine, 3, 247+$t*$scalax, 140-$y*$scalay, ".", $rosso);

};

Per disegnare il grafico uso la istruzione imagestring che scrive del testo in un punto prestabilito; il testo da scrivere è un punto, cioè ".", di colore $rosso e di dimensione 3.

Le coordinate del punto in cui verrà disegnato "." variano al variare di un contatore $t; $t parte dal valore - $max = -25; viene incrementato di $incre=0.05 per ogni ciclo e il ciclo viene ripetuto finchè $t non raggiunge il valore di $max = 25.

Poiché il sistema di assi dello schermo rispetto al sistema di assi da noi disegnato è traslato, cioè lo zero origine degli assi non è coincidente, occorre che la posizione del punto in cui verrà disegnato sia traslata in senso orizzontale di 250 e in senso verticale di 150. Si è scelto in orizzontale 247 invece di 250 e in verticale  140 invece di 150 per correggere il fatto che il "." si trova verso il basso e verso destra e non al centro.

La coordinata y la preparo con:

$y=$a*$t*$t + $b*$t +$c;

Cioè moltiplico il coefficiente a contenuto in $a per la x2 variabile contenuta nel contatore $t; poi aggiungo il valore di b moltiplicato per x e poi c.

Poi con:

imagestring ($immagine, 3, 247+$t*$scalax, 140-$y*$scalay, ".", $rosso);

disegno il grafico prendendo come ascissa il valore di $t moltiplicato per la scala $scalax, e come ordinata il valore di $y moltiplicato per la scala $scalay.

 

A questo punto eseguendo funzione4.php vedremo:

Grafico di y = 4x2+ 2x +3

 

Il listato completo è:

<?php

$immagine = imagecreatetruecolor (550,300);

$nero = imagecolorallocate ($immagine, 0, 0, 0);

$arancio = imagecolorallocate ($immagine, 250, 200,150);

$blu = imagecolorallocate ($immagine, 0, 0,200);

$rosso = imagecolorallocate ($immagine, 255, 0,0);

imagefilledrectangle ($immagine, 0,0, 550, 300, $arancio);

// tiro asse orizzontale

imageline ($immagine, 10, 150, 500, 150, $nero);

// tiro asse verticale

imageline ($immagine, 250, 10, 250, 300, $nero);

// disegno frecce sui due assi

imageline ($immagine, 500, 150, 490, 145, $nero);

imageline ($immagine, 500, 150, 490, 155, $nero);

imageline ($immagine, 250, 10, 245, 20, $nero);

imageline ($immagine, 250, 10, 255, 20, $nero);

// memorizzo i dati del programma equazione2.php

$a = $_GET['a'];

$b = $_GET['b'];

$c = $_GET['c'];

$scalao = $_GET['scalao'];

$scalav = $_GET['scalav'];

 

// scrivo x y

imagestring ($immagine, 5, 490, 125, "x", $blu);

imagestring ($immagine, 5, 260, 10, "y", $blu);

// scrivo grafico

$descrizione="Grafico di y = ".$a;

imagestring ($immagine, 5, 250, 280, $descrizione, $blu);

if ($a) imagestring ($immagine, 3, 419, 277, "2", $blu);

if ($a) imagestring ($immagine, 5, 410, 280, "x", $blu);

if($b<0) $descrizione =$b."x";

if($b>0) $descrizione ="+ ".$b."x";

if($b==0) $descrizione =" ";

imagestring ($immagine, 5, 435, 280, $descrizione, $blu);

if($c<0) $descrizione=" ".$c;

if($c>0) $descrizione=" + ".$c;

if($c==0) $descrizione=" ";

imagestring ($immagine, 5, 480, 280, $descrizione, $blu);

// disegno il grafico

if($scalao!=0) $scalax=1/$scalao;

if($scalav!=0) $scalay=1/$scalav;

if($scalao==0) $scalax=1;

if($scalav==0) $scalay=1;

$max=25;

$incre=0.05;

// disegno scala orizzontale e verticale

// orizzontale

for($t=50; $t<500; $t+=50){

imageline ($immagine, $t, 145, $t, 155, $nero);

$testo=($t-250)/$scalax;

imagestring ($immagine, 4,$t-10, 158, $testo, $blu);

};

// verticale

for($t=50; $t<300; $t+=50){

imageline ($immagine, 245, $t, 255, $t, $nero);

$testo=(150-$t)/$scalay;

if($t!=150) imagestring ($immagine, 4,258, $t-8, $testo, $blu);

};

//disegno grafico

for ($t=-$max; $t<$max; $t+=$incre) {

$y=$a*$t*$t + $b*$t +$c;

imagestring ($immagine, 3, 247+$t*$scalax, 140-$y*$scalay, ".", $rosso);

};

 

//imagepng ($immagine,"y=4x2+2x+3.png");

imagepng ($immagine);

imagedestroy ($immagine);

?>

Listato completo di Grafico di y = ax2+bx+c

Notiamo che volendo salvare l'immagine in un file, onde poterla riutilizzare si può usare:

imagepng ($immagine,"y=4x2+2x+3.png");

che salva l'immagine che si trova in memoria cioè $immagine in un file di nome: y=4x2+2x+3.png in formato png.

Occorre, per curiosità, fare distinzione tra:

funzione4.php che è un listato che disegna ogni volta l'immagine e  y=4x2+2x+3.png che mostra una immagine salvata in formato png.

Osservazioni

Questo programma ha anche il pregio di poter variare la scala del disegno sia in senso orizzontale che in senso verticale, onde mettere meglio in risalto alcuni punti di particolare interesse del grafico disegnato.

febbraio 2006

Corso di programmazione in PHP

Dizionario php

 

prof. Pietro De Paolis

Indice Scuola Elettrica - generico


Scuola Elettrica



 

Altre applicazioni


Mappa per tipo di scuola

 

Indice di tutte le pagine del sito


Guida per navigare


Richiesta informazioni


Scuola Elettrica