HOME OGGETTI 3D LIBRI CORSI TUTORIAL FORUM SHOP CONTATTI   LOGIN









Autore Topic: Funzioni 2D parte2  (Letto 1559 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

marcomasetti

  • Newbie
    ...sono qui da poco, il mio miglior amico è il pulsante RICERCA
  • *
  • Post: 183
Funzioni 2D parte2
« il: 03 Luglio 2012, 11:36 »
Un altro modo di tradurre nel linguaggio GDL  una funzione y=f(x)
è utilizzare la formula per il poligono 2D :

n=  !numero punti che definiscono il poligono
j1= !bit mostra contorno
j2= !bit mostra riempimento
j3= !chiudi il poligono
for i=1 to n
put  xi, yi, si
next i
POLY2_  n, j1 + 2*j2 + 4*j3, get (nsp)

Dove:
si=0   significa il segmento successivo al punto (xi,yi) è invisibile
si=1   significa il segmento successivo al punto (xi,yi) è visibile
si=-1  significa fine di un contorno: i punti successivi rappresenteranno un foro

La formula:

for i=1 to n
put  xi, yi, si
next i

memorizza in funzione di i le coordinate dei punti xi,yi ed i relativi valori di stato si.
Tali valori sono richiamati (poi cancellati dalla memoria) dal comando get (nsp),
dove nsp rappresenta il numero dei valori inseriti in put, che in questo caso sono nsp=3*n.

Per tradurre dunque una funzione y=f(x)
definita nell’intervallo delle x:  [ox, ox+L]
si scriverà:

for i=1 to n
put  ox+L/n*i, f(ox+L/n*i), 1
next i

POLY2_  n,  1,  get (nsp)

Infatti in tal modo il poligono non si chiude (j3=0)

Ad esempio l’arco di parabola, di altezza h, luce L, con asse in x=ox+L/2:
y=h-4/L^2*h*(x-ox-L/2)
definito in  [ox, ox+L]
tradotto in GDL:

for i=0 to n
put  ox+L/n*i, h-4/L^2*h*( L/n*i -L/2)^2, 1
next i
POLY2_  n+1,  1,  get (nsp)

 Altro esempio, l’onda smorzata:
y=(h-4/L^2*h*(x-ox-L/2)^2) *sin(f*360/L*(x-ox-L/2))definita in  [ox, ox+L]
con una semi-ampiezza di oscillazione massima=h , lunghezza d’onda=L, frequenza f
si traduce della curva in GDL:

for i=0 to n
x= ox+L/n*i
y=(h-4/L^2*h*(x-ox-L/2)^2) *sin(f*360/L*(x-ox-L/2))
put  x, y, 1
next i
POLY2_  n+1,  1,  get (nsp)

Come ultimo esempio presentiamo ancora l’ellisse, che essendo una curva chiusa, non può essere una funzione, ma un insieme di due funzioni.
In questo caso, però, i punti devono seguire un unico orientamento, orario od antiorario.
E’ meglio utilizzare il senso antiorario, per cui la parte bassa dell’ellisse viene scritta normalmente, mentre quella superiore segue le x decrescenti.

Dato che l’ellisse è una curva importante, ricostruiamone l’equazione:

Il cerchio di raggio a con centro in O si scrive;
x^2+y^2=a^2           (teorema di Pitagora)
y=+/-sqr(a^2-x^2)   (x<=a)
applicando una stiramento lungo y equivalente a
mul2 1,b/a
il diametro verticale 2*a diventa 2*b e si ha l’ellisse:
y= b/a*sqr(a^2-x^2)  !parte su semipiano y+
y=-b/a*sqr(a^2-x^2) ! parte su semipiano y-
traslando il tutto di (ox,oy), coordinate del nuovo centro:
y=oy+b/a*sqr(a^2-(x-ox)^2) !parte superiore
y=oy-b/a*sqr(a^2-(x-ox)^2) !parte inferiore
con intervallo di definizione: [ox-a/2, ox+a/2]

Per la traduzione in GDL utilizziamo POLY2 che non usa i valori di stato:
a=   !semiasse orizzontale
b=   !semiasse verticale
n=   !resol, numero intero
ox= !ascissa centro
oy= !ordinata centro

for i=0 to n-1
x= ox-a+2*a/n*i !Il punto di partenza ha x =ox-a e si procede verso destra
y=oy-b/a*sqr(a^2-(x-ox)^2) !parte inferiore
put  x, y
next i

for i=0 to n-1
x= ox+a-2*a/n*i !Il punto di partenza ha x =ox+a e si procede verso sinistra, i con segno -
y=oy+b/a*sqr(a^2-(x-ox)^2) !parte superiore
put  x, y
next i

FILL f

POLY2  nsp/2,  1+2+4 ,  get (nsp)

(Occorre inserire il valore 4 per chiudere il poligono, il valore 2 permette di riempirlo con FILL )

Volendo poi praticare un foro con una ellisse concentrica di semiassi a-as,b-bs,
occorrerà ripetere il punto iniziale di ogni sottopoligono,
che dovrà corrispondere a quello finale con indice -1.

for i=0 to n-1
x= ox-a+2*a/n*i !Il punto di partenza ha x =ox-a e si procede verso destra
y=oy-b/a*sqr(a^2-(x-ox)^2) !parte inferiore
put  x, y, 1
next i

for i=0 to n-1
x= ox+a-2*a/n*i !Il punto di partenza ha x=ox+a e si procede verso sinistra, i con segno -
y=oy+b/a*sqr(a^2-(x-ox)^2) !parte superiore
put  x, y, 1
next i

x= ox-a
y=oy-b/a*sqr(a^2-(x-ox)^2) !parte inferiore
put  x, y,-1 !punto corrispondente a i=0,chiusura curva antioraria esterna

!inizio ellisse interna ------------------------------------

for i=0 to n-1
x= ox+(a-sa)-2*(a-sa)/n*i !Il punto di partenza ha x=ox+(a-sa) e si procede verso sinistra
y=oy-(b-sb)/(a-sa)*sqr((a-sa)^2-(x-ox)^2) !parte inferiore
put  x, y, 1
next i

for i=0 to n-1
x= ox-(a-sa)+2*(a-sa)/n*i !Il punto di partenza ha x=ox-(a-sa) e si procede verso destra
y=oy+(b-sb)/(a-sa)*sqr((a-sa)^2-(x-ox)^2) !parte superiore
put  x, y, 1
next i

x= ox+(a-sa)
y=oy-(b-sb)/(a-sa)*sqr((a-sa)^2-(x-ox)^2) !parte inferiore
put  x, y, -1 !punto corrispondente a i=0, chiusura curva oraria interna

FILL f

POLY2_  nsp/3,  1+2+4 ,  get (nsp)

L’ellisse è stata utilizzata come esempio, volendo ottenere lo stesso risultato con i mezzi offerti dal linguaggio GDL si poteva scrivere semplicemente:

Per l’ellisse:

mul2 1, b/a
POLY2_  2, 1+2  ,xo,yo,901,   a,360,4001     !cerchio di raggio a centrato in xo,yo
del 1

I parametri :
xo, yo,    900 +s
xr, 360, 4000+s
cui è stato aggiunto rispettivamente 900 e 4000 al valore di stato,
non rappresentano più coordinate cartesiane x,y.
Nel primo caso l’indice 900 fa interpretare al calcolatore i valori xo,yo come le coordinate del centro di una circonferenza, mentre l’indice 4000 fa interpretare i primi due valori come raggio e angolo di un arco circonferenza centrato in (xo,yo) predefinito


Per l’ellisse cava:

add2 xo,yo
mul2 1, b/a
POLY2_  4, 1+2  ,0,0,901,   a,360,4001, 
                              0,0,901,   a-sa ,360,4001
del 2

Da notare, però, che non è possibile variare le proporzioni dell’ellisse interna,
dato che in realtà si tratta di cerchi schiacciati.

Costruire l’ellisse in forma cartesiana, con distribuzione in maniera uniforme delle proiezioni dei vertici sull'asse x, genera, a risoluzioni basse, angolosità sugli estremi degli assi.
E’ possibile distribuire in maniera diversa la successione dei punti, utilizzando per le x una funzione non lineare di i.  Questo accorgimento può essere utile anche per altri tipi di curve:  in tal modo però, di fatto, si esprime la curva non più come funzione cartesiana, ma in forma parametrica.
Come esempio distribuiamo le proiezioni dei punti lungo l’asse x secondo la funzione coseno, che li addensa ai margini.

for i=0 to n-1
x= ox-a*cos(180/n*i)                            !Il punto di partenza ha x=ox-a e si procede verso destra
y=oy-b/a*sqr(abs(a^2-(x-ox)^2))       !parte inferiore
put  x, y, 1  !s=0 segmento successivo invisibile,-1 punto fine sottopoligono=punto inizio
next i

for i=0 to n-1
x= ox+a*cos(180/n*i)                          !Il punto di partenza ha x=ox+a e si procede verso sinistra, i con segno -
y=oy+b/a*sqr(abs(a^2-(x-ox)^2))     !parte superiore
put  x, y, 1
next i

x= ox-a
y=oy-b/a*sqr(a^2-(x-ox)^2) !parte inferiore
put  x, y,-1 !punto corrispondente a i=0,chiusura curva antioraria esterna

!inizio ellisse interna

for i=0 to n-1
x= ox+(a-sa)*cos(180/n*i) !Il punto di partenza ha x=ox+(a-sa) e si procede verso sinistra
y=oy-(b-sb)/(a-sa)*sqr((a-sa)^2-(x-ox)^2) !parte inferiore
put  x, y, 1
next i

for i=0 to n-1
x= ox-(a-sa)*cos(180/n*i)  !Il punto di partenza ha x=ox-(a-sa) e si procede verso destra
y=oy+(b-sb)/(a-sa)*sqr((a-sa)^2-(x-ox)^2) !parte superiore
put  x, y, 1
next i

x= ox+(a-sa)
y=oy-(b-sb)/(a-sa)*sqr((a-sa)^2-(x-ox)^2) !parte inferiore
put  x, y, -1 !punto corrispondente a i=0, chiusura curva oraria interna

POLY2_  nsp/3,  1+2+4 ,  get (nsp)

Di fatto, abbiamo costruito uno script macchinoso che equivale alla forma parametrica comune dell'ellisse:

for i=0 to 2*n-1
x= ox+a*cos(180/n*i)  !Il punto di partenza ha x=ox+a e si procede verso sin, antiorario
y= oy+b*sin(180/n*i)
put  x, y, 1
next i

x= ox+a !punto di partenza: i=0
y= oy
put  x, y, -1

!inizio ellisse interna

for i=0 to 2*n-1
x= ox+(a-sa)*cos(180/n*i)  !Il punto di partenza ha x=ox+(a-sa) e si procede verso sin, orario
y= oy-(b-sb)*sin(180/n*i)
put  x, y, 1
next i

x= ox+a-sa !punto di partenza: i=0
y= oy
put  x, y, -1

POLY2_  nsp/3,  1+2+4 ,  get (nsp)
« Ultima modifica: 03 Luglio 2012, 20:24 da marcomasetti »