Una curva, espressa in forma cartesiana y=y(x) o in forma parametrica: x=x(u),y(v) può essere tradotta nel linguaggio GDL, ad esempio, con la formula:
for i=1 to n
x=x(i)
y=y(i)
put x, y, si
next i
POLY2_ nsp/3, j1 + 2*j2 + 4*j3, get (nsp)
Tuttavia, essendo Archicad un programma 3D, l’utilità di una curva risiede nel fatto che può essere utilizzata per creare superfici o volumi.
Un modo semplice per generare un oggetto 3D da una curva è darle uno spessore poi estruderla.
Se la curva è una funzione y=y(x), il modo più semplice per darle uno spessore è traslarla, creando due curve uguali e parallele che vanno poi unite. Le due curve non dovranno tagliarsi, cosa che non può avvenire se la traslazione è nel senso dell’asse y. Una delle due curve deve essere scritta in senso inverso, altrimenti il poligono generato si intreccia.
Come esempio prendiamo la sinusoide inscritta in una parabola:
for i=0 to n
x= ox+L/n*i !intervallo di definizione da i=0 a i=n: [ ox, ox+L ]
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_ nsp/3, 1, get (nsp)
Posto lo spessore =s, la parte alta, traslata e riscritta nel senso opposto a x, risulta:
for i=0 to n
x= ox+L -L/n*i
y=(h-4/L^2*h*(x-ox-L/2)^2) *sin(f*360/L*(x-ox-L/2)) +s
put x, y, 1
next i
POLY2_ nsp/3, 1, get (nsp)
Unendo le due curve si ottiene il poligono richiesto:
for i=0 to n
x= ox+L/n*i !intervallo di definizione da i=0 a i=n: [ ox, ox+L ]
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
for i=0 to n
x= ox+L -L/n*i
y=(h-4/L^2*h*(x-ox-L/2)^2) *sin(f*360/L*(x-ox-L/2)) +s
put x, y, 1
next i
POLY2_ nsp/3, 7, get (nsp)
Se invece lo spostamento risulta definito dal vettore (sa,sb), la funzione y=f(x) diventerà:
s= ! spessore
al= ! angolo rispetto verticale
sa= s*sin(al)
sb= s*cos(al)
for i=0 to n
x= ox+L/n*i !intervallo di definizione da i=0 a i=n: [ ox, ox+L ]
y=f(x)
put x-sa/2, y-sb/2, 1
next i
for i=0 to n
x= ox+L -L/n*i
y=f(x)
put x+sa/2, y+sb/2, 1
next i
POLY2_ nsp/3, 7, get (nsp)
Costruendo in tal modo lo spessore, questo non risulterà uniforme, perché varierà con la curva, assottigliandosi nelle parti con maggiore pendenza.
Per avere uno spessore uniforme occorre che il vettore di traslazione della seconda curva sia sempre orientato in senso normale alla curva stessa.
Dato un vettore (a,b), lo stesso vettore ruotato di 90° diventa (-b,a),
Definita la funzione y=f(x), nel punto (xo,f(xo)),
il versore tangente è dato da:
1/sqr(1 + Df(xo)^2)*( 1, Df(xo) )
dove Df(x) è la derivata prima della funzione f(x).
Pertanto il versore normale alla curva y=f(x) in (xo,f(xo)) è definito dalla formula:
1/sqr(1 + Df(xo)^2)*(- Df(xo),1 )
Se invece la curva è descritta in forma parametrica:
x=x(u)
y=y(u)
il versore tangente è dato da:
1/sqr( Dx(u) ^2, Dy(u)^2 )* ( Dx(u), Dy(u) )
dove Dx(u), Dy(u) sono le derivate prime rispetto u delle funzioni x(u),y(u).
Pertanto il versore normale alla curva (x(u),y(u)) è definito dalla formula:
1/sqr( Dx(u) ^2+Dy(u)^2 )* ( -Dy(u), Dx(u) )
La curva con spessore s nel linguaggio GDL si può allora scrivere:
for i=0 to n
x= ox+L/n*i !intervallo di definizione da i=0 a i=n: [ ox, ox+L ]
y=f(x)
dy=Df(x)
put x-.5*s/sqr(1 + dy^2)*dy, y+.5*s/sqr(1 + dy^2), 1 ! versore normale1/sqr(1 +df^2)*( - df, 1 )
next i
for i=0 to n
x= ox+L/n*i !intervallo di definizione da i=0 a i=n: [ ox, ox+L ]
y=f(x)
dy=Df(x)
put x+.5*s/sqr(1 + dy^2)*dy, y-.5*s/sqr(1 + dy^2), 1 ! versore normale1/sqr(1 +df^2)*( - df, 1 )
next i
POLY2_ nsp/3, 7, get (nsp)
Ricordando che per y=h-a*x^2 risulta Dy=-2*a*x, applichiamo la formula all’arco di parabola di larghezza L,
con asse in x=0:
for i=0 to n
x= L/2-L/n*i !intervallo di definizione da i=0 a i=n: [-L/2, L/2 ]
y= h-a*x^2
dy=-2*a*x
put x-.5*s/sqr(1 + dy^2)*dy, y+.5*s/sqr(1 + dy^2), 1
next i
for i=0 to n
x= -L/2+L/n*i !intervallo di definizione da i=0 a i=n: [-L/2, L/2 ]
y= h-a*x^2
dy=-2*a*x
put x+.5*s/sqr(1 + dy^2)*dy, y-.5*s/sqr(1 + dy^2), 1
next i
POLY2_ nsp/3, 7, get (nsp)
Le derivate delle funzioni sinusoidali espresse in radianti valgono:
y=cos(x) Dy=D( cos(x) )=-sin(x)
y=sin(x) Dy=D( sin(x) )= cos(x)
Nello script GDL, però, le funzioni trigonometriche sono espresso in gradi, per cui, di fatto, ad esempio sin(x) rappresenta la funzione sinus dilatata nel senso delle x di 360/(2*pi), dato che il periodo non è più 2*pi ma appunto 360. Infatti: y=sin(x) con x in gradi equivale a
y=sin(xrad*2*pi/360) dove xrad è l’angolo espresso in radianti.
La derivata prima di y=sin(xrad): Dy=D(sin(xrad))=cos(xrad)
per cui la derivata composta: Dy=D(sin(xrad*2*pi/360))=2*pi/360*cos(xrad*2*pi/360)
ovvero in gradi: D( sin(x) )= 2*pi/360*cos(x)
e analogamente: D( cos(x) )=- 2*pi/360*sin(x)
Per un arco di ellisse centrata in O di angolo al centro ac:
x=a*cos(u)
y=b*sin(u) con u entro [ 0, ac ]
Dx=a*2*pi/360*cos(u)
Dy=b*2*pi/360*sin(u)
!inizio script: inserire parametri a,b,n,ac oltre a tipo retino e penne
for i=0 to n
u= ac-ac/n*i !intervallo di definizione da i=0 a i=n: [ac, 0 ]
x=a*cos(u)
y=b*sin(u)
dx=-a*2*pi/360*sin(u) !versore normale 1/sqr( dx^2+dy^2 )* ( -dy, dx )
dy=b*2*pi/360*cos(u)
put x-.5*s/ sqr( dx^2+dy^2 )*dy, y+.5*s/ sqr( dx^2+dy^2 )*dx, 1
next i
for i=0 to n
u= ac/n*i !intervallo di definizione da i=0 a i=n: [0, ac ]
x=a*cos(u)
y=b*sin(u)
dx=-a*2*pi/360*sin(u)
dy=b*2*pi/360*cos(u)
put x+.5*s/ sqr( dx^2+dy^2 )*dy, y-.5*s/ sqr( dx^2+dy^2 )*dx, 1
next i
fill f !f=tipo retino
pen pc !pc=penna contorno
POLY2_B nsp/3, 7,
pr,ps, !pr=penna retino, ps=penna colore sfondo
get (nsp)
Nel caso in cui calcolare la funzione derivata fosse troppo problematico, si può sostituire il vettore normale con il vettore ortogonale al segmento successivo di curva, in questo caso deve essere definita la curva anche per i=n+1:
for i=0 to n
u= u2-(u2-u1)/n*i !intervallo di definizione da i=0 a i=n: [u2, u1 ],supponendo u2>u1
uu=u2-(u2-u1)/n*(i-1) !il punto successivo è i-1, perchè i ha segno-
x=x(u)
y=y(u)
xx=x(uu)
yy=y(uu)
dx=xx-x
dy=yy-y
put x-.5*s/ sqr( dx^2+dy^2 )*dy, y+.5*s/ sqr( dx^2+dy^2 )*dx, 1
next i
for i=0 to n
u= u1+(u2-u1)/n*i !intervallo di definizione da i=0 a i=n: [u1, u2 ]
uu=u1+(u2-u1)/n*(i+1)
x=x(u)
y=y(u)
xx=x(uu)
yy=y(uu)
dx=xx-x
dy=yy-y
put x+.5*s/ sqr( dx^2+dy^2 )*dy, y-.5*s/ sqr( dx^2+dy^2 )*dx, 1
next i
POLY2_ nsp/3, 7, get (nsp)
Come esempio per verificare la formula utilizziamo la semplice funzione seno, definita in [0, 2*pi]
!inizio script, definire i parametri n=resol, s=spessore
for i=0 to n
u= 2*pi/n*i
x=u
y=sin(u/pi*180)
put x,y, 1
next i
POLY2_ nsp/3, 1, get (nsp) !curva semplice
for i=0 to n
u= 2*pi -2*pi /n*i
uu=2*pi -2*pi /n*(i-1)
x=u
y=sin(u/pi*180)
xx=uu
yy=sin(uu/pi*180)
dx=xx-x
dy=yy-y
put x-.5*s/ sqr( dx^2+dy^2 )*dy, y+.5*s/ sqr( dx^2+dy^2 )*dx, 1
next i
for i=0 to n
u= 2*pi/n*i
uu= 2*pi/n *(i+1)
x=u
y=sin(u/pi*180)
xx=uu
yy=sin(uu/pi*180)
dx=xx-x
dy=yy-y
put x+.5*s/ sqr( dx^2+dy^2 )*dy, y-.5*s/ sqr( dx^2+dy^2 )*dx, 1
next i
POLY2_ nsp/3, 7, get (nsp) !curva con spessore, fine script
Trasformare gli scripts 2D in scripts 3D è molto semplice, basta sostituire POLY2_ con PRISM_ o con EXTRUDE.
Naturalmente occorreranno alcune modifiche ed aggiunte. In particolare gli indici dopo i vertici non hanno lo stesso significato in 2D e in 3D, talvolta sono inversi, cioè laddove 1 significa mostrare gli spigoli in 2D, in 3D può significare nasconderli. Di caso in caso occorre consultare la guida, ma la costruzione per i punti è la medesima.