HOME OGGETTI 3D LIBRI CORSI TUTORIAL FORUM SHOP CONTATTI   LOGIN









Autore Topic: Archi sul piano  (Letto 1745 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
Archi sul piano
« il: 18 Settembre 2012, 21:13 »
Questo esercizio è una applicazione di calcolo vettoriale sul piano.

Dati due punti A=(ax,ay) e B=(bx,by) vogliamo costruire un arco per i due punti.
Per farlo occorre definire in quale posizione dell’asse relativo al segmento AB cade il centro.
Per prima cosa, pertanto, definiamo l’equazione di tale asse.
Il punto mediano M del segmento AB ha coordinate M=(mx,my)=(ax/2+bx/2, ay/2+by/2).
Il versore ortogonale al vettore AB ha coordinate:
nx=(by-ay)/ab
ny=(ax-bx)/ab
dove ab= sqr( (bx-ax)^2 +(by-ay)^2 ) è il modulo del vettore AB.
L’equazione parametrica dell’asse è pertanto:
ox=mx+h*nx
oy=my+h*ny
Notiamo che per h=0 si ottiene il punto M, è dunque evidente che h rappresenta la distanza del punto O appartenente all’asse rispetto la corda AB.   Sia dunque O il centro dell’arco. I vettori OA, OB con modulo r (incognito) pari al raggio del cerchio, descrivono l’arco.
Per costruire l’arco occorrono due valori angolari: l’angolo an compreso  tra i due vettori OA,OB e l’angolo be che forma uno di tali vettori con l’asse x.
Consideriamo il triangolo OMA:
risulta OM=h, AM=ab/2, pertanto:  tan(an/2)=ab/(2*h)  da cui si ricava:
an=2*atn( ab/(2*h) )
Sempre dal triangolo rettangolo OMA si desume:
r*cos(an/2)=h   per cui  r=h/cos(an/2)
Sia be l’angolo format dal vettore OB con l’asse x, dato che la coordinate x corrisponde alla proiezione ortogonale su detto asse, risulta:
ob*cos(be)=bx-ox
dove ob= sqr( (bx-ox)^2 +(by-oy)^2 )  è il modulo del vettore OB

In conclusione, date le coordinate ax,ay e bx,by più la distanza h da centro a corda, si costruisce l’arco con lo script:

ab=sqr( (bx-ax)^2 +(by-ay)^2 ) !modulo del vettore AB
nx=(by-ay)/ab
ny=(ax-bx)/ab !versore normale al vettore AB
an=2*atn( ab/(2*h) )!angolo tra i vettori OA,OB
r=h/cos(an/2)
ox=(bx+ax)/2+h*nx
oy=(by+ay)/2+h*ny
ob=sqr( (bx-ox)^2 +(by-oy)^2 ) !modulo del vettore OB
be=acs((bx-ox)/ob)!angolo su x del vettore OB

arc2 ox,oy,r,be,be+an

Volendo utilizzare una forma meglio traducibile nel linguaggio 3D occorre introdurre la risoluzione n e al posto di arc2 si può utilizzare la formula:

for i=0 to n
put ox+r*cos(be+an/n*i),oy+r*sin(be+an/n*i)
next i
poly2 nsp/2, 1, get (nsp)

L’esercizio viene svolto nell’oggetto:
arco per due punti.gsm

Questo esercizio è proposto come introduzione per un esercizio più complesso, ovvero costruire una linea a simmetria rotatoria formata da archi. Questa linea può poi essere inserita come contorno di una forma 3D complessa.
Iniziamo con il costruire in 2D un settore circolare di curva con ampiezza al=360/p, dove p è il numero di iterazioni in simmetria rotatoria.
Ogni fetta è composta di un arco iniziale di raggio l e ampiezza ga<al, centrato in O, centro della simmetria rotatoria. A questo arco segue un arco CB, decentrato, la cui corda ha ampiezza d. I punti C e B si trovano sullo stesso raggio uscente da O. Segue poi un ulteriore arco decentrato BA. Il punto A va a cadere sulla circonferenza di raggio l, centrata in O, per continuità. I valori h1 e h2 sono le distanze dai centri degli archi CB e BA dalle rispettive corde.

Lo script della singola fetta risulta:

p=
al=360/p
 l=
ga=      !<al
d=
h1=
h2=
n=
n1=
n2=

for i=0 to n
put l*cos(ga/n*i),l*sin(ga/n*i)
next i
poly2 n+1,1,get (nsp)

ax=l*cos(ga)
ay=l*sin(ga)
bx=(l+d)*cos(ga)
by=(l+d)*sin(ga)
h=h1
n=n1
ab=sqr( (bx-ax)^2 +(by-ay)^2 ) !modulo del vettore AB
nx=(by-ay)/ab
ny=(ax-bx)/ab !versore normale al vettore AB
an=2*atn( ab/(2*h) )!angolo tra i vettori OA,OB
r=h/cos(an/2)
ox=(bx+ax)/2+h*nx
oy=(by+ay)/2+h*ny
ob=sqr( (bx-ox)^2 +(by-oy)^2 ) !modulo del vettore OB
be=acs((bx-ox)/ob)!angolo su x del vettore OB

for i=0 to n
put ox+r*cos(be+an/n*(n-i)),oy+r*sin(be+an/n*(n-i))
next i
poly2 nsp/2,1,get (nsp)

ax=l*cos(al)
ay=l*sin(al)
bx=(l+d)*cos(ga)
by=(l+d)*sin(ga)
h=h2
n=n2
ab=sqr( (bx-ax)^2 +(by-ay)^2 ) !modulo del vettore AB
nx=(by-ay)/ab
ny=(ax-bx)/ab !versore normale al vettore AB
an=2*atn( ab/(2*h) )!angolo tra i vettori OA,OB
r=h/cos(an/2)
ox=(bx+ax)/2+h*nx
oy=(by+ay)/2+h*ny
ob=sqr( (bx-ox)^2 +(by-oy)^2 ) !modulo del vettore OB
be=acs((bx-ox)/ob)!angolo su x del vettore OB

for i=0 to n
put ox+r*cos(be+an/n*i),oy+r*sin(be+an/n*i)
next i
poly2 nsp/2,1,get (nsp)

Da notare che nel secondo poligono si è sostituito i con n-i, altrimenti la linea inverte il senso di marcia e si rompe la continuità.
Non è necessario scrivere tre volte:
poly2 nsp/2,1,get (nsp)
è sufficiente scriverlo una volta sola in fondo: in questo caso però i primi 2 loop vanno ridotti di una unità, altrimenti si ripete 2 volte l’ultimo punto, che nel loop successivo diventa il primo.
Poi basta aggiungere in testa:

for j=0 to p-1
rot2 al*j

e in coda:

next j
per avere la figura rotatoria completa.
Quando poi applicheremo lo script 2D ad un oggetto 3D occorre ricordare che pure l’ultimo loop va ridotto di una unità.

Come oggetto 3D consideriamo il cilindro modulare primitivo con facce triangolari, il cui script relativo ai vertici è il seguente: 

nz=  !numero dei piani (=numero dei circoli orizzontali -1)
nr=  !numero dei punti costituenti un circolo
r=    !raggio
ht= !altezza totale

for t=0 to nz

for i=0 to nr-1
xx= r*cos(i*360/nr)
yy= r*sin(i*360/nr)
VERT xx, yy,t*ht/nz
next i

next t

La parte intermedia può essere sostituita da qualsiasi espressione che rappresenti una curva, anche sghemba, purché sia sempre formata da nr punti. Questa curva può variare in ogni piano, quindi può dipendere anche da t:
 
for i=0 to nr-1
xx=xx(i,t)
yy=xx(i,t)
VERT xx, yy,t*ht/nz
next i

Qui vogliamo utilizzare come curva il profilo mistilineo che abbiamo appena costruita. Per evitare pasticci, occorre stare attenti, dato che la curva è inserita in un loop, ad evitare che un parametro che viene ripetuto nel loop, assuma valori indesiderati. Per cui inseriamo direttamente i valori n=n1 e n=n2 entro lo script.
Lo script 2D finale risulta:

al=360/p
ga=al*g/100


for j=0 to p-1
rot2 al*j

for i=0 to n-1
put l*cos(ga/n*i),l*sin(ga/n*i)
next i

ax=l*cos(ga)
ay=l*sin(ga)
bx=(l+d)*cos(ga)
by=(l+d)*sin(ga)
h=h1
ab=sqr( (bx-ax)^2 +(by-ay)^2 )
nx=(by-ay)/ab
ny=(ax-bx)/ab
an=2*atn( ab/(2*h) )
r=h/cos(an/2)
ox=(bx+ax)/2+h*nx
oy=(by+ay)/2+h*ny
ob=sqr( (bx-ox)^2 +(by-oy)^2 )
be=acs((bx-ox)/ob)

for i=0 to n1-1
put ox+r*cos(be+an/n1*(n1-i)),oy+r*sin(be+an/n1*(n1-i))
next i

ax=l*cos(al)
ay=l*sin(al)
bx=(l+d)*cos(ga)
by=(l+d)*sin(ga)
h=h2
ab=sqr( (bx-ax)^2 +(by-ay)^2 )
nx=(by-ay)/ab
ny=(ax-bx)/ab
an=2*atn( ab/(2*h) )
r=h/cos(an/2)
ox=(bx+ax)/2+h*nx
oy=(by+ay)/2+h*ny
ob=sqr( (bx-ox)^2 +(by-oy)^2 )
be=acs((bx-ox)/ob)

for i=0 to n2
put ox+r*cos(be+an/n2*i),oy+r*sin(be+an/n2*i)
next i

poly2 nsp/2,1,get (nsp)

del 1
next j


Anzitutto ricordiamo che l’ultimo loop va scalato di 1, per cui:
for i=0 to n2
diventa:
for i=0 to n2-1.

Ora occorre calcolare il numero di punti nr della curva, valore che andrà dichiarato prima di definire la BASE.  Tenendo conto che ogni fetta è ripetuta p volte nella simmetria rotatoria, risulta:

nr=p*(n+n1+n2)

Dato che ci troviamo nel 3D   rot2   va sostituito con   rotz.
Ogni scritta PUT va sostituita con VERT aggiungendo in coda, dopo una virgola, il valore della terza coordinata:  t*ht/nz-
Va ovviamente cancellata la riga poly2, che comunque non verrebbe letta.
A questo punto lo script dei vertici dovrebbe funzionare:

nr=p*(n+n1+n2)
al=360/p

for t=0 to nz

for j=0 to p-1
rotz al*j+dl*t

for i=0 to n-1
VERT l*cos(ga/n*i),l*sin(ga/n*i),t*ht/nz
next i

ax=l*cos(ga)
ay=l*sin(ga)
bx=(l+d)*cos(ga)
by=(l+d)*sin(ga)
h=h1
ab=sqr( (bx-ax)^2 +(by-ay)^2 )
nx=(by-ay)/ab
ny=(ax-bx)/ab
an=2*atn( ab/(2*h) )
r=h/cos(an/2)
ox=(bx+ax)/2+h*nx
oy=(by+ay)/2+h*ny
ob=sqr( (bx-ox)^2 +(by-oy)^2 )
be=acs((bx-ox)/ob)
 
for i=0 to n1-1
VERT ox+r*cos(be+an/n1*(n1-i)),oy+r*sin(be+an/n1*(n1-i)),t*ht/nz
next i

ax=l*cos(al)
ay=l*sin(al)
bx=(l+d)*cos(ga)
by=(l+d)*sin(ga)
h=h2
ab=sqr( (bx-ax)^2 +(by-ay)^2 )
nx=(by-ay)/ab
ny=(ax-bx)/ab
an=2*atn( ab/(2*h) )
r=h/cos(an/2)
ox=(bx+ax)/2+h*nx
oy=(by+ay)/2+h*ny
ob=sqr( (bx-ox)^2 +(by-oy)^2 )
be=acs((bx-ox)/ob)

for i=0 to n2-1
VERT ox+r*cos(be+an/n2*i),oy+r*sin(be+an/n2*i),t*ht/nz
next i

del 1
next j

next t

In rotz è stata aggiunta la variabile dl*t che ruota di tale angolo ogni sezione nel passare da un piano all’altro, creando una torsione.  Altrimenti sarebbe bastato fare una estrusione. Volendo fare una cosa più raffinata occorrerebbe isolare gli spigoli originariamente verticali, per potere rendere lisce le pareti fra essi compresi.
Si possono poi variare le altezze dei piani, potrebbe essere anche incurvata tutta la struttura.
In definitiva, pur essendo il procedimento complesso, non esistono limiti per le possibili variazioni e distorsioni.  Ad esempio l’angolo dl potrebbe essere a sua volta funzione di t, per cui la rotazione dei piani potrebbe non essere omogenea.

Prima di concludere mostro come isolare gli spigoli inizialmente verticali,
lo script originario prevede:

for t=0 to nz-1

for i=1 to nr
EDGE i+t*nr, i+nr+t*nr,-1,-1,0
next i

next t

Il valore nr comprende p volte la sequenza n+n1+n2, per cui nel passare da una singola all’altra (parametro j), si compie un salto di n+n1+n2, mentre il valore i all’interno della singola fetta, varia da 1 a n, poi da n+1  a  n+n1+1, infine da  n+n1+1  a  n+n1+n2.

for t=0 to nz-1

for j=0 to p-1

i=1
EDGE i+t*nr+j*(n+n1+n2), i+nr+t*nr+j*(n+n1+n2),-1,-1,0
for i=2 to n
EDGE i+t*nr+j*(n+n1+n2), i+nr+t*nr+j*(n+n1+n2),-1,-1,2
next i

i=1
EDGE i+t*nr+j*(n+n1+n2)+n, i+nr+t*nr+j*(n+n1+n2)+n,-1,-1,0
for i=2 to n1
EDGE i+t*nr+j*(n+n1+n2)+n, i+nr+t*nr+j*(n+n1+n2)+n,-1,-1,2
next i

i=1
EDGE i+t*nr+j*(n+n1+n2)+n+n1, i+nr+t*nr+j*(n+n1+n2)+n+n1,-1,0
for i=2 to n2
EDGE i+t*nr+j*(n+n1+n2)+n+n1, i+nr+t*nr+j*(n+n1+n2)+n+n1,-1,-1,2
next i

next j

next t

L'oggetto ottenuto dal cilindro, utilizzando la direttrice con simmetria rotatoria, è:
archi simm rotat.gsm
Nell'immagine si vedono alcune possibili varianti dell'oggetto.
« Ultima modifica: 18 Settembre 2012, 23:44 da marcomasetti »