GRAFICA
IN
JAVA
PER
DISEGNARE
FIGURE
GEOMETRICHE
Domenico
Sacc
1.
Utilizzo
delloggetto
graphics
Nel
package
System
personalizzato
per
il
corso
disponibile
loggetto
graphics
che
include
alcuni
metodi
elementari
di
grafica.
A
tale
scopo
viene
automaticamente
messo
a
disposizione
un
pannello
(cio
una
specie
di
terminale
grafico)
in
cui
vengono
visualizzate
le
operazioni
di
grafica
-
il
pannello
abilitato
sia
nel
caso
che
il
programma
venga
lanciato
come
una
classica
applicazione
Java
sia
nel
caso
di
esecuzione
come
applet.
Il
pannello
un
rettangolo
suddiviso
in
un
numero
prefissato
di
punti
(chiamati
pixel).
Esso
pu
essere
considerato
una
matrice
di
pixel
con
(dimY
+1)
righe
e
(dimX
+1)
colonne
la
numerazione
parte
da
0.
Le
coordinate
dei
quattro
vertici
del
pannello
sono:
(0,
0)
vertice
in
alto
a
sinistra
(0,
dimY)
vertice
in
basso
a
sinistra
(dimX,
0)
vertice
in
alto
a
destra
(dimX,
dimY)
vertice
in
basso
a
destra.
I
comandi
per
conoscere
le
dimensioni
del
pannello
sono:
[Link]
():
restituisce
la
larghezza
(width)
totale
dellarea
grafica
(in
pixel)
come
intero
[Link]
():
restituisce
laltezza
(height)
totale
dellarea
grafica
(in
pixel)
come
intero.
Si
noti
che
nel
caso
il
programma
sia
lanciato
come
applicazione
Java,
la
dimensione
del
pannello
prefissata
(ma
pu
essere
modificata
in
corso
di
utilizzo)
mentre
nel
caso
sia
lanciata
come
applet
essa
dipende
dallo
spazio
indicato
nella
pagina
html
per
lapplet:
<applet code="[Link]" archive="[Link]" height="500" width="800">
Nellesempio
dimY
500
pixel
e
dimX
800
pixel.
Il
comando
per
disegnare
una
linea
tra
due
punti
del
pannello
il
seguente:
[Link]
(
int
x1,
int
y1,
int
x2,
int
y2
):
disegna
il
segmento
che
unisce
i
punti
di
coordinate
(x1,
y1)
ed
(x2,
y2).
La
linea
viene
disegnata
con
il
colore
corrente.
Allinizio
del
programma
il
colore
corrente
quello
di
default
(tipicamente
il
nero).
E
possibile
rendere
corrente
un
colore
diverso
tramite
il
comando:
[Link]
(Color
col):
viene
reso
corrente
il
colore
col.
Per
utilizzare
questo
metodo
occorre
importare
il
package
[Link].
Il
parametro
cc
pu
assumere
uno
dei
seguenti
valori:
[Link]
(nero),
[Link]
(blu),
[Link]
(ciano),
Color.DARK_GRAY
(grigio
scuro),
[Link]
(grigio),
Color.LIGHT_GRAY
(grigio
chiaro),
[Link]
(verde),
[Link]
(magenta),
[Link]
(arancio),
[Link]
(rosa),
[Link]
(rosso),
[Link]
(bianco),
[Link]
(giallo).
Questa
porzione
di
codice
disegna
in
nero
i
4
lati
del
pannello,
poi
in
blu
le
due
mediane
ed,
infine,
in
rosso
le
due
diagonali:
import [Link]; import [Link]; import [Link]; import [Link]; public class Prova_graphics extends SystemApplet { public static void main(String[] args) { int dimX = [Link]();
int dimY = [Link](); [Link]([Link]); [Link](0, 0, 0, dimY); // lato verticale a sinistra [Link](dimX, 0, dimX, dimY); // lato verticale a destra [Link](0, 0, dimX, 0); // lato orizzontale in alto [Link](0, dimY, dimX, dimY); // lato orizzontale in basso [Link]([Link]); [Link](dimX/2, 0, dimX/2, dimY); // mediana orizzontale [Link](0, dimY/2, dimX, dimY/2); // mediana verticale [Link]([Link]); [Link](0, 0, dimX, dimY); // diagonale dallalto verso il basso [Link](dimX, 0, 0, dimY); // diagonale dal basso verso lalto } }
Per
ripulire
il
pannello,
va
utilizzato
il
comando:
[Link]
(
).
E
possibile
scrivere
stringhe
di
testo
con
il
comando:
[Link]
(String
str,
int
x,
int
y):
scrive
la
stringa
str
in
orizzontale
a
partire
dal
punto
di
coordinate
(x,
y).
E
possibile
disegnare
rettangoli,
eventualmente
colorati,
con
i
comandi:
[Link]
(int
x,
int
y,
int
width,
int
height,
int
arcWidth,
int
arcHeight):
disegna
il
rettangolo
di
base
width
e
altezza
height
il
cui
vertice
superiore
sinistro
posto
nel
punto
di
coordinate
(x,y).
I
parametri
arcWidth
e
arcHeight
possono
essere
utilizzati
per
arrotondare
gli
angoli
(porre
a
0
questi
due
parametri
per
non
arrotondare
gli
angoli).
[Link]
(int
x,
int
y,
int
width,
int
height,
int
arcWidth,
int
arcHeight):
disegna
un
rettangolo
con
le
caratteristiche
del
comando
precedente
e
lo
colora
utilizzando
il
colore
corrente.
Sono
disponibili
ulteriori
comandi
per
disegnare
ellissi,
cerchi,
archi,
spezzate
e
poligoni.
Per
dettagli
consultare
la
guida
alluso
del
package
System.
2.
Disegno
di
una
parabola
Vogliamo
disegnare
una
parabola
descritta
dallequazione
Y
=
a
X2
+
b
X
+
c
cio
con
asse
parallela
allasse
Y.
Ricordiamo
che
il
vertice
della
parabola
(-b/2a;
(b2-4ac)/4a
)
e
la
concavit
rivolta
verso
lalto
se
a
>
0
e
verso
il
basso
se
a
<
0.
Ad
esempio
la
parabola
Y
=
X2
X
6
ha
la
concavit
rivolta
verso
lalto
in
quanto
a
=
1
>
0
mentre
la
parabola
Y
=
2X2
+3
ha
concavit
rivolta
verso
il
basso:
Il
metodo
main
consiste
nella
lettura
dei
dati
della
parabola,
nella
scrittura
dei
suoi
dati
(vertice
e
intersezioni
con
gli
assi)
e
una
sessione
interattiva
in
cui
viene
chiesto
se
si
vuole
disegnare
la
parabola
e,
in
caso
positivo,
in
quale
range
dellasse
X.
Il
main
il
seguente:
public static void main(String[] args) { [Link]("Disegno di una parabola y = ax^2+bx+c"); // lettura parametri a, b e c della parabola letturaParabola(); // scrittura vertice e intersezione della parabola con gli assi scritturaParabola(); // sessione interattiva per il disegno della parabola [Link]("Vuoi disegnare la parabola [s/n]?"); char comando = [Link]([Link]()); boolean inizio = true; while ( comando == 'S' ) { if (inizio ) { dimX = [Link](); dimY = [Link](); // vectorY memorizza un valore di Y per ogni punto di X vectorY = new double[dimX+1]; } inizio = false; // Lettura area di disegno: Xmin e Xmax letturaRangeX (); discretizzaPuntiParabola(); disegnaAssi(); disegnaParabola(); [Link]("Disegno di altra porzione della parabola [s/n]?"); comando = [Link]([Link]()); } [Link]("bye"); }
Come
si
vede,
il
metodo
molto
astratto
in
quanto
fa
un
utilizzo
ampio
di
metodi
la
sua
lettura
immediata
in
quanto
i
dettagli
implementativi
sono
rinviati
alla
scrittura
dei
vari
metodi.
Inoltre
sono
utilizzate
le
seguenti
variabili
statiche:
dimX,
dimY
e
vectorY.
Va
precisato
luso
della
variabile
booleana
inizio:
essa
serve
per
dimensionare
solo
la
prima
volta
vectorY.
Mostriamo
ora
la
scrittura
dei
metodi
letturaParabola
e
scritturaParabola.
static void letturaParabola() { do { [Link]("Inserisci a: ");
a = [Link](); [Link]("Inserisci b: "); b = [Link](); [Link]("Inserisci c: "); c = [Link](); if ( a== 0 && b==0) [Link]("Errore: a e b entrambi 0"); } while ( a == 0 && b == 0 ); } static void scritturaParabola() { double D = b*b-4*a*c; // discriminante if ( a!=0 ) { // parabola non degenere [Link]("Coordinate del Vertice"); [Link]("X = " + -b/(2*a)); [Link]("; Y = " + -D/(4*a)); if ( D > 0 ) { [Link]("2 intersezioni con asse X"); double rD = [Link](D); // radice quadrata del discriminante double x1 = (-b-rD)/(2*a), x2 = (-b+rD)/(2*a); [Link]("X1 = " + x1 ); [Link]("; X2 = " + x2 ); } else if ( D < 0 ) [Link]("Nessuna intersezione con asse X"); else { [Link]("1 intersezione con asse X"); [Link]("X = " + (-b/(2*a)) ); } } else { [Link]("Parabola degenere: retta"); [Link]("Intersezione con asse X"); [Link]("X = " + (-c/b) ); } [Link]("Intersezione con asse Y"); [Link]("Y = " + c ); }
I
tuoi
metodi
fanno
entrambi
utilizzo
delle
variabili
di
tipo
double
a,
b,
c:
esse
vengono
dichiarate
di
tipo
statico
in
modo
che
possano
essere
condivise.
Decidiamo
di
dichiarare
di
tipo
statico
anche
reader,
che
viene
utilizzato
anche
dal
metodo
letturaRangeX
che
legge
lintervallo
delle
X
in
cui
disegnare
la
parabola:
static void letturaRangeX ( ) { [Link]("Lettura area di disegno: Xmin e Xmax"); do { [Link]("Inserisci Xmin: "); rangeX[0] = [Link](); [Link]("Inserisci Xmax: "); rangeX[1] = [Link](); if ( rangeX[1]<= rangeX[0]) [Link]("Errore: Xmax <= Xmin"); } while ( rangeX[1] <= rangeX[0] ); }
Larray
rangeX,
che
memorizza
gli
estremi
dellintervallo
di
disegno,
definito
come
variabile
statica
in
quanto
condiviso
da
altri
metodi,
tra
cui
discretizzaPuntiParabola :
static void discretizzaPuntiParabola() { scaleFactorX = ( rangeX[1] - rangeX[0])/dimX; vectorY[0]=getOrdinata(rangeX[0]); vectorY[dimX]=getOrdinata(rangeX[1]); for (int i=1; i < dimX; i++ ) vectorY[i]=getOrdinata(rangeX[0]+scaleFactorX*i); rangeY[0]=trovaMinimo(vectorY); rangeY[1]=trovaMassimo(vectorY); scaleFactorY = ( rangeY[1] - rangeY[0])/dimY; // il vertice viene leggermente spostato dal bordo if ( a > 0 ) // concavit verso lalto rangeY[0] -= 10*scaleFactorY; else if ( a < 0 ) // concavit verso il basso rangeY[1] += 10*scaleFactorY; // se a != 0 viene ricalcolato il fattore di scala if ( a != 0 ) scaleFactorY = ( rangeY[1] - rangeY[0])/dimY; }
Il
metodo
innanzitutto
acquisisce
il
numero
di
punti
dimX
disponibili
per
il
disegno
nella
direzione
X
e
il
numero
dimY
nella
direzione
Y
come
avevamo
gi
scritto,
queste
variabili
sono
dichiarate
statiche.
Viene
quindi
calcolato
il
fattore
di
scala
in
direzione
X
in
modo
che
il
rangeX
da
disegnare
sia
discretizzato
nei
dimX
punti
a
disposizione.
In
corrispondenza
con
ciascuno
di
tali
punti
X
viene
memorizzato
il
valore
del
corrispondente
Y
(ordinata)
sulla
base
dellequazione
della
parabola
le
ordinate
sono
memorizzate
su
un
apposito
vettore
statico
vectorY
con
tanti
elementi
quanti
sono
i
punti
discretizzati
nella
dimensione
X.
Viene
quindi
calcolato
il
fattore
di
scala
per
la
direzione
Y
sulla
base
del
valore
minimo
e
massimo
delle
ordinate
tale
fattore
viene
un
po
spostato
per
evitare
di
dover
schiacciare
il
vertici
sul
bordo
del
disegno.
I
metodi
trovaMassimo
e
trovaMinimo
sono
semplici
metodi
per
cercare
rispettivamente
massimo
e
minimo
in
un
vettore
visto
il
loro
carattere
di
metodi
standard,
abbiamo
preferito
non
fare
uso
in
essi
di
variabili
statiche:
static double trovaMinimo ( double [] V ) { double minimo = V[0]; for ( int i = 1; i < [Link]; i++ ) if ( V[i] < minimo ) minimo = V[i]; return minimo; } static double trovaMassimo ( double [] V ) { double massimo = V[0]; for ( int i = 1; i < [Link]; i++ ) if ( V[i] > massimo ) massimo = V[i]; return massimo; }
Per
ottimizzare
il
codice
avremmo
anche
potuto
utilizzare
un
unico
metodo
che
calcolo
minimo
e
massimo
contemporaneamente:
static double[] double [] minMax[0] for ( int trovaMinimoMassimo ( double [] V ) { minMax = new double[2]; = minMax[1] = V[0]; i = 1; i < [Link]; i++ )
if ( else
V[i] < minMax[0] ) minMax[0] = V[i];
if ( V[i] > minMax[\] ) minMax[1] = V[i]; return minMax; }
Le
seguenti
due
istruzioni
in
discretizzaPuntiParabola:
rangeY[0]=trovaMinimo(vectorY); rangeY[1]=trovaMassimo(vectorY);
vanno
allora
sostituite
dalla
seguente
unica
istruzione:
rangeY=trovaMinimoMassimo(vectorY);
Il
metodo
getOrdinata
utilizza
un
parametro
formale
per
passare
lascissa
in
corrispondenza
della
quale
calcolare
lordinata
e
le
variabili
statiche
che
memorizzano
i
coefficienti
dellequazione
della
parabola:
public static double getOrdinata (double ascissa) {
return a*ascissa*ascissa+b*ascissa+c;
}
Il
metodo
disegna
assi
valuta
se
allinterno
del
range
X,
dato
in
input,
e
del
range
Y
calcolato,
ricadono
gli
assi
X
e
Y
e,
nel
caso,
li
disegna.
public static void disegnaAssi() { [Link](); [Link]([Link]); // Asse Y if ( rangeX[0] <= 0 && rangeX[1]>=0 ) [Link](getPuntoAscissa(0), 0, getPuntoAscissa(0), dimY); // Asse X if ( rangeY[0] <= 0 && rangeY[1]>=0 ) [Link](0, getPuntoOrdinata(0), dimX, getPuntoOrdinata(0)); }
Per
il
disegno
dei
due
assi,
va
individuata
la
posizione
dellorigine
tramite
opportuna
scalatura
delle
ascisse
con
il
metodo
getPuntoAscissa
e
delle
ordinate
con
il
metodo
getPuntoOrdinata
(poich
le
ordinate
vanno
dallalto
verso
il
basso,
esse
vanno
ribaltate
sottraendole
a
dimY
in
modo
da
riportarle
dal
basso
verso
lalto)
:
public static int getPuntoOrdinata ( double v ) { return dimY - (int) [Link]((v-rangeY[0])/scaleFactorY); } public static int getPuntoAscissa ( double v ) { return (int) [Link]((v-rangeX[0])/scaleFactorX); }
Il
disegno
della
parabola
effettuato
dal
metodo
disegnaParabola
che
non
fa
altro
che
raccordare
con
delle
linee
tutti
i
dimX
punti
della
parabola,
equamente
intervallati
sulle
ascisse,
tramite
opportuna
scalatura
delle
ordinate
con
il
metodo
getPuntoOrdinata:
public static void disegnaParabola( ) { [Link]([Link]);
for(int i=0;i< dimX-1;i++){ [Link](i, getPuntoOrdinata(vectorY[i]), i+1, getPuntoOrdinata(vectorY[i+1])); } }
Per
concludere,
presentiamo
di
seguito
la
classe
Parabola
che
contiene
le
variabili
statiche
e
i
metodi
(che
per
brevit
non
vengono
riportati
nuovamente):
public class Parabola { // variabili globali statiche (visibili da tutti i metodi) static int dimX, dimY; // numero di punti nelle due direzioni static double a, b, c; // coefficienti dell'equazione della parabola // range (valori min e max) nella direzione X static double [] rangeX = new double[2]; // range (valori min e max) nella direzione Y static double [] rangeY = new double[2]; static double scaleFactorX, scaleFactorY; // fattori di scala nelle 2 direzioni static double [] vectorY; // valori di Y per ogni punto X del range static Scanner reader = new Scanner([Link]); // seguono le definizioni di tutti i metodi }
3.
Applicazione
del
disegno
di
una
parabola:
diagrammi
dei
momenti
e
dei
tagli
in
una
trave
poggiata
con
carico
distribuito
Consideriamo
una
trave
di
una
certa
lunghezza
L
(misurata
in
metri)
poggiata
ai
due
estremi
su
appositi
appoggi
A
e
B
non
solidali
con
essa
(ad
esempio
un
ponticello
poggiato
sopra
due
sponde
laterali)
su
cui
grava
un
carico
distribuito
q,
misurato
in
kg
/
m.
La
trave
scarica
sui
due
appoggi
A
e
B
una
forza
totale
verso
il
basso
Q
pari
a
q
*
L.
Pertanto
essa
dovr
essere
equilibrata
da
due
forze
verso
lalto
agli
appoggi
Va
e
Vb,
cio
Va
+
Vb
=
q
*
L.
Considerata
la
simmetria
Va
=
Vb
=
q
*
L
/
2.
La
trave
ai
due
estremi
quindi
sollecitata
da
una
forza
verticale
chiamata
taglio
mentre
non
esiste
alcun
momento
(cio
sollecitazione
a
rotazione)
in
quanto
la
trave
non
incastrata
agli
estremi
ma
libera
di
ruotare
(e
quindi
non
subisce
alcun
momento).
E
interessante
conoscere
le
sollecitazioni
(taglio
e
momento)
su
ogni
sezione
della
trave,
ad
esempio
ad
una
qualsiasi
distanza
x
dallestremo
A.
Separiamo
i
due
pezzi
di
trave
"tagliati
"
dalla
sezione
a
distanza
x,
e
applichiamo
ad
esse
le
azioni
che
si
scambiavano
quando
erano
unite.
Esse
sono:
una
forza
parallela
alla
sezione,
che
viene
detta
taglio
e
indicata
con
T,
una
forza
perpendicolare
alla
sezione,
che
viene
detto
sforzo
normale
ed
indicato
con
N
e
da
un
momento
flettente
che
viene
indicato
con
M.
Ovviamente,
gli
sforzi
che
il
tratto
di
destra
esercita
sul
tratto
di
trave
di
sinistra
sono
uguali
e
contrari
agli
sforzi
che
il
tratto
di
sinistra
esercita
su
quello
di
destra
(azioni
mutue).
Per
calcolare
tali
azioni,
vanno
scritte
le
3
equazioni
di
equilibrio:
equilibrio
alla
traslazione
verticale,
equilibrio
alla
traslazione
orizzontale
ed
equilibrio
alla
rotazione,
ovviamente,
possiamo
scrivere
tali
equazioni
di
equilibrio,
dopo
avere
calcolato
le
reazioni
vincolari
Va
e
Vb
.
Assumendo
che
non
ci
sia
sollecitazione
orizzontale
(cio
la
trave
non
sollecitata
alla
traslazione
orizzontale),
dobbiamo
scrivere
due
equazioni
di
equilibrio:
traslazione
verticale
e
rotazione.
Considerando
il
tratto
di
sinistra
della
trave
di
lunghezza
x,
abbiamo
le
seguenti
equazioni:
EQUAZIONE
DEL
TAGLIO:
T(x)
=
Va
q
*
x,
cio
alla
distanza
x
dallappoggio
A,
vi
una
spinta
verso
il
basso
che
deve
controbilanciare,
insieme
alla
porzione
di
carico
distribuito
q
sulla
tratta
x,
la
forza
verso
lalto
Va.
Poich
Va
=
q
*
L
/
2,
lequazione
del
taglio
diventa:
T(x)
=
q
*
x
+
q
*
L
/
2
Tale
equazione
rappresenta
una
retta
che
nellintervallo
[0,
L]
costituisce
il
diagramma
dei
tagli
sulla
trave.
Tale
diagramma
ha
il
seguente
formato:
Allestremo
A,
il
taglio
ha
valore
q
*
L
/
2,
convenzionalmente
di
segno
positivo;
a
met
trave
il
taglio
0;
allestremo
B
ha
valore
q
*
L
/
2.
Dato
un
qualsiasi
x
nellintervallo
[0,
L],
possibile
calcolare
il
valore
del
taglio
tramite
il
diagramma.
EQUAZIONE
DEL
MOMENTO:
M(x)
=
Va
*
x
q
*
x
*
x
/
2,
cio
alla
distanza
x
dallappoggio
A,
vi
una
rotazione
causata
dalla
forza
in
A
moltiplicata
per
il
braccio
x,
spinta
verso
il
basso
che
deve
controbilanciare,
insieme
al
momento
generato
dalla
porzione
di
carico
distribuito
q
sulla
tratta
x,
il
momento
generato
dalla
forza
Va
moltiplicata
per
il
braccio
x.
Si
noti
che
il
momento
generato
dal
carico
distribuito
va
calcolato
sostituendo
il
carico
distribuito
con
un
carico
concentrato
q
*
x
posto
alla
distanza
x
/
2.
Poich
Va
=
q
*
L
/
2,
lequazione
del
momento
diventa:
M(x)
=
(q/2)
x
2
+
(q
*
L
/
2)
x
Tale
equazione
rappresenta
una
parabola
che
nellintervallo
[0,
L]
costituisce
il
diagramma
dei
momenti
sulla
trave.
Tale
diagramma
ha
il
seguente
formato:
Ai
due
estremi
A
e
B,
il
momento
nullo;
esso
ha
il
valore
massimo
di
q
*
L2
/
8
al
centro
della
trave
(cio
per
x
=
L
/
2),
convenzionalmente
di
segno
positivo;
a
met
trave
il
taglio
0;
allestremo
B
ha
valore
q
*
L
/
2.
Dato
un
qualsiasi
x
nellintervallo
[0,
L],
possibile
calcolare
il
valore
del
momento
tramite
il
diagramma.
Passiamo
ora
a
presentare
un
programma
che
chiede
in
input
la
dimensione
L
della
trave
(in
metri)
e
il
carico
distribuito
q
(in
kg
/
m),
calcola
le
reazioni
Va
e
Vb,
lequazione
della
parabola
dei
momenti,
quella
della
retta
dei
tagli,
disegna
i
diagrammi
dei
momenti
e
dei
tagli
e
poi
chiede
interattivamente
se
calcolare
le
sollecitazioni
in
qualche
punto
x
della
trave
per
ogni
valore
introdotto,
vengono
restituiti
i
valori
del
momento
e
del
taglio
e
viene
tracciata
sui
diagramma
la
posizione
di
x.
Il
metodo
main
il
seguente:
public static void main(String[] args) { [Link]("Diagrammi dei momenti e tagli di una trave poggiata"); // lettura lunghezza e carico distribuito della trave letturaTrave(); // scrittura reazioni agli appoggi, momento massimo e // equazioni di taglio e momento scritturaMomentoTaglio(); dimX = [Link](); dimY = [Link](); vectorY_M = new double[dimX+1]; // un valore del momento per ogni X vectorY_T = new double[dimX+1]; // un valore del taglio per ogni X // disegno dei diagrammi dei momenti e dei tagli [Link](); disegnaTrave(); discretizzaPuntiMomentiTagli(); disegnaMomento(); disegnaAsseTaglio(); disegnaTaglio(); // sessione interattiva per il calcolo del momento e taglio in un punto [Link]("Momento e taglio in un punto [s/n]?"); char comando = [Link]([Link]()); boolean inizio=true; while ( comando == 'S' ) { if ( !inizio ) { [Link](); disegnaTrave(); discretizzaPuntiMomentiTagli(); disegnaMomento(); disegnaAsseTaglio(); disegnaTaglio(); }; inizio=false; double x = leggiAscissaPunto(); calcolaMomentoTaglioPunto(x); disegnaAssePunto(x); [Link]("Momento e taglio in un altro punto [s/n]?");
comando = [Link]([Link]()); }; [Link]("bye");
}
La
variabile
booleana
inizio
serve
per
evitare
di
ridisegnare
i
diagrammi
allinizio;
successivamente
vanno
ridisegnati
per
rimuovere
la
traccia
della
sezione
x
disegnata
al
passo
precedente.
Lo
schema
del
programma
molto
simile
a
quello
del
disegno
di
una
parabola.
In
questo
caso
dobbiamo
disegnare
sia
una
parabola
che
una
retta
contemporaneamente
pertanto
dividiamo
larea
di
disegno
in
due
parti:
in
alto
il
diagramma
dei
momenti
e
in
basso
quello
dei
tagli.
Si
noti
che,
essendo
la
retta
un
caso
degenere
della
parabola,
possiamo
riutilizzare
lo
stesso
codice.
Abbiamo
per
bisogno
di
due
vettori
in
cui
memorizzare
le
ordinate
della
parabola
e
quelle
della
retta:
vectorY_M
e
vectorY_T.
Lasciamo
allo
studente
il
compito
di
scrivere
i
metodi
e
la
classe,
che
comunque
riportata
sul
sito
del
corso.
4.
Disegno
di
una
iperbole
Vogliamo
disegnare
una
iperbole
con
asintoti
paralleli
agli
assi
e
con
centro
di
simmetria
traslato
rispetto
allorigine
degli
assi,
descritta
dallequazione
Y
=
(aX+b)/(cX+d)
con
c
0
e
ad
bc.
Il
centro
di
simmetria
ha
coordinate
(-b/a,
b/d).
In
figura
la
rappresentazione
grafica
di
una
iperbole
con
centro
di
simmetria
(2,2):
Il
metodo
main
consiste
nella
lettura
dei
dati
delliperbole,
nella
scrittura
dei
suoi
dati
(centro
di
simmetria
dove
si
intersecano
i
due
asintoti
e
le
intersezioni
con
gli
assi)
e
una
sessione
interattiva
in
cui
viene
chiesto
se
si
vuole
disegnare
la
parabola
e,
in
caso
positivo,
in
quale
range
dellasse
X.
Il
main
il
seguente:
public static void main(String[] args) { [Link]("Disegno di una iperbole y = (ax+b)/(cx+d)"); // lettura parametri a, b, c, d dell'iperbole letturaIperbole(); // scrittura centro simmetria e intersezione dell'iperbole con gli assi scritturaIperbole(); // sessione interattiva per il disegno della parabola [Link]("Vuoi disegnare l'iperbole [s/n]?"); char comando = [Link]([Link]()); while ( comando == 'S' ) { // Lettura area di disegno: Xmin e Xmax letturaRangeX (); discretizzaPuntiIperbole();
10
disegnaAssi();
Lasciamo
allo
studente
il
compito
di
scrivere
i
metodi
e
la
classe,
che
comunque
riportata
sul
sito
del
corso.
E
importante
sottolineare
che
in
prossimit
dellasintoto
verticale
le
ordinate
delliperbole
diventano
estremamente
elevati
in
valore
assoluto,
per
cui
la
operazioni
di
scalatura
potrebbero
schiacciare
sullasse
X
i
valori
delle
altre
ordinate.
Per
ridurre
questo
inconveniente,
nel
caso
che
un
valore
di
X
disti
dallasintoto
verticale
meno
di
met
del
passo
di
discretizzazione,
esso
viene
distanziato
a
met
del
passo.
Tale
tecnica
implementata
dal
seguente
metodo
public static double getOrdinata (double ascissa) { if ( ascissa <= X_CS && ascissa > X_CS-deltaX/2) ascissa = ascissa -deltaX/2; else if ( ascissa > X_CS && ascissa < X_CS+deltaX/2) ascissa = ascissa +deltaX/2; return (a*ascissa+b)/(c*ascissa+d); }
Lasintoto
verticale
passa
per
il
punto
con
ascissa
X_CS.
Se
lascissa
x
per
cui
va
calcolata
lordinata
molto
vicino
allasintoto,
essa
va
spostata
a
sinistra
o
a
destra
per
mantenerla
lontana
dallassintoto
di
almeno
mezzo
passo.
11