Here's something I made with Freebasic using cubic splines.
I dont mind you converting the source to yabasic if you like.
' CODED FOR DREW ON THE WWW.DBFINTERACTIVE.COM FORUMS
' BY SHOCKWAVE ^ DBF ^ SURPRISE ! PRODUCTIONS.
' ELECTRICITY EFFECT.
OPTION STATIC
OPTION EXPLICIT
'#define PTC_WIN
#Include Once "tinyptc.bi"
CONST XRES = 640
CONST YRES = 480
dim shared buffer (xres * yres ) as uinteger
dim shared buffer2 (xres * yres ) as uinteger
DIM SHARED AS INTEGER XPOINTS(21)
DIM SHARED AS INTEGER YPOINTS(21)
DIM SHARED AS INTEGER CX1(21)
DIM SHARED AS INTEGER CY1(21)
DIM SHARED AS INTEGER CX2(21)
DIM SHARED AS INTEGER CY2(21)
DIM SHARED AS INTEGER OFF(21)
DIM SHARED AS INTEGER OFF2(21)
DIM SHARED AS INTEGER OFFT(21)
DIM SHARED AS INTEGER L,M
DIM SHARED AS DOUBLE GADD
dim shared cpal(500) as uinteger
dim as double rv,gv,bv
for l=1 to 500
if rv<254 then rv=rv+.5
if gv<254 then gv=gv+.75
if bv<254 then bv=bv+1
cpal(l)=rgb(int(rv),int(gv),int(bv))
next
FOR L=1 TO 21
OFF(L) = RND*100
OFF2(L) = RND*100
OFFT(L) = RND*100
NEXT
declare sub dcircle(BYVAL CX AS INTEGER , BYVAL CY AS INTEGER , BYVAL R AS INTEGER, BYVAL CLR AS INTEGER)
declare sub BEZIER(BYVAL X0 AS INTEGER ,BYVAL Y0 AS INTEGER, BYVAL X3 AS INTEGER ,BYVAL Y3 AS INTEGER ,BYVAL X1 AS INTEGER ,BYVAL Y1 AS INTEGER ,BYVAL X2 AS INTEGER ,BYVAL Y2 AS INTEGER )
DECLARE SUB ELECTRIC()
If( ptc_open( "YOU CAN IMPROVE ON THIS EASILY :p", XRES, YRES ) = 0 ) Then
End -1
End If
DO
M=1
ELECTRIC()
for L=30 to 1 step -1
dcircle(32+(M/3),(240-(M/3)),L,M*5)
dcircle(599+(M/3),(240-(M/3)),L,M*5)
M=M+1
next L
GADD=GADD+rnd*.05
FOR L=1 TO XRES*YRES
BUFFER(L)=cpal (BUFFER2(L))
if buffer2(l)>0 then buffer2(l)=buffer2(l)*.85
NEXT
PTC_UPDATE@BUFFER(0)
erase buffer
LOOP UNTIL INKEY$=CHR$(27)
END
SUB ELECTRIC()
DIM A,X,Y,RT
X=10
Y=240
FOR A=1 TO 21
XPOINTS(A)=X+(24*SIN(GADD+A+OFF(A)*5))
IF A>2 AND A<20 THEN
YPOINTS(A)=Y+(80*SIN(GADD+OFF(A)))
ELSE
YPOINTS(A)=Y
END IF
CX1(A)=X+(19*SIN(GADD+OFF2(A)/13))
CY1(A)=Y+(34*SIN(GADD+OFF2(A)/43))
CX2(A)=X+(18*COS(GADD+OFF(A)/23))
CY2(A)=Y+(14*SIN(GADD+OFF(A)/11))
X=X+31
OFFT(A)=OFFT(A)-1
IF OFFT(A)<=0 THEN
OFF(A)=RND*(100)
OFF2(A)=RND*(100)
OFFT(A)=RND*(40)
END IF
NEXT
FOR A=1 TO 20
BEZIER (XPOINTS(A),YPOINTS(A),XPOINTS(A+1),YPOINTS(A+1),CX1(A),CY1(A),CX2(A),CY2(A))
NEXT
END SUB
'
' USAGE, BEZIER(SOURCE X,SOURCE Y , DEST X , DEST Y, CONTROL X1 , CONTROL Y1 , CONTROL X2, CONTROL Y2)
'
SUB BEZIER(BYVAL X0 AS INTEGER ,BYVAL Y0 AS INTEGER, BYVAL X3 AS INTEGER ,BYVAL Y3 AS INTEGER ,BYVAL X1 AS INTEGER ,BYVAL Y1 AS INTEGER ,BYVAL X2 AS INTEGER ,BYVAL Y2 AS INTEGER )
dim as double T,t2,t3
DIM AS INTEGER L,X,Y,cx,bx,ax,cy,by,ay
dim as integer br,br2,br3
CX = 3*(X1-X0)
BX = 3*(X2-X1)-CX
AX = X3-X0-CX-BX
CY=3*(Y1-Y0)
BY=3*(Y2-Y1)-CY
AY=Y3-Y0-CY-BY
for t = 0 to 1 step .01
t3=t^3
t2=t^2
x = ax * t3 + bx * t2 + cx * t + X0
y = ay * t3 + by * t2 + cy * t + Y0
br=X+(Y*XRES)
br2=X+((Y-5)*XRES)
br3=X+((Y+5)*XRES)
IF X>31 AND X<XRES-31 THEN
buffer2(br) =buffer2(br)+40
buffer2(br2) =buffer2(br2)+20
buffer2(br3) =buffer2(br3)+20
IF buffer2(br)>500 THEN buffer2(br)=500
IF buffer2(br3)>500 THEN buffer2(br3)=500
IF buffer2(br2)>500 THEN buffer2(br2)=500
end if
next
END SUB
SUB dCIRCLE(BYVAL CX AS INTEGER , BYVAL CY AS INTEGER , BYVAL R AS INTEGER, BYVAL CLR AS INTEGER)
DIM as integer r2,cc,loopy,ww,l,SW
DIM PP AS INTEGER PTR
r2=r*r
cc=-r
for loopy = cc to r
ww = Sqr(r2-loopy*loopy)
SW = (CX+ww)-(CX-ww)
IF SW>0 THEN
PP = @BUFFER2((CX-WW)+((LOOPY+CY)*XRES))
asm
MOV EAX,DWORD PTR[CLR]
MOV ECX, [SW]
MOV EDI, [PP]
REP STOSD
end asm
END IF
next
END SUB