Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - _vince

Pages: [1] 2
1
Programs / Canonical Logarithm
« on: February 08, 2022, 09:13:32 am »
Code: [Select]
defdbl a-z
dim shared pi as double
pi = 4*atn(1)

sw = 800
sh = 600

screen _newimage(sw, sh, 32)

zoom = 100

a = 0.5
k = 0.09

sx = 2
sy = 1

tx = a*exp(k*16)*cos(16) + sx
ty = a*exp(k*16)*sin(16) + sy

x = a*exp(k*0)*cos(0) + sx - tx
y = a*exp(k*0)*sin(0) + sy - ty

r = sqr(x*x + y*y)
arg = _atan2(y, x)

for tt = r to 0 step -1
xl = tt*cos(arg)
yl = tt*sin(arg)

for yy=0 to sh
for xx=0 to sw
u = (xx - sw/2)/zoom
v = (sh/2 - yy)/zoom

cdiv uu, vv, u - xl, v - yl, u + xl, v + yl
clog uu, vv, uu, vv

mm = sqr(uu*uu + vv*vv)
aa = (pi + _atan2(vv, uu))/(2*pi)
pset (xx, yy), hrgb(aa, mm)
next
next

sleep
next

dim pp(5)
pp(5) = 0
pp(4) = 7
pp(3) = 10
pp(2) = 12
pp(1) = 15
pp(0) = 15.9

for ttt= 0 to 5
tt = pp(ttt)
for yy=0 to sh
for xx=0 to sw
u = (xx - sw/2)/zoom
v = (sh/2 - yy)/zoom

uu = 0
vv = 0
for t=tt to 16 step 0.1
x = a*exp(k*t)*cos(t) + sx - tx
y = a*exp(k*t)*sin(t) + sy - ty

cdiv p, q, 1, 0, x - u, y - v

dx = a*exp(k*t)*(k*cos(t) - sin(t))
dy = a*exp(k*t)*(k*sin(t) + cos(t))

cmul p, q, p, q, dx, dy

uu = uu + 0.1*p
vv = vv + 0.1*q
next

for t=16 - 0.1 to tt step -0.1
x =-a*exp(k*t)*cos(t) - sx + tx
y =-a*exp(k*t)*sin(t) - sy + ty

cdiv p, q, 1, 0, x - u, y - v

dx = a*exp(k*t)*(k*cos(t) - sin(t))
dy = a*exp(k*t)*(k*sin(t) + cos(t))

cmul p, q, p, q, dx, dy

uu = uu + 0.1*p
vv = vv + 0.1*q
next

cmul uu, vv, uu, vv, 0, -1/(2*pi)

mm = sqr(uu*uu + vv*vv)
aa = (pi + _atan2(vv, uu))/(2*pi)
pset (xx, yy), hrgb(aa, mm)
next
next

sleep
next

sleep
system

function hrgb&(h, m)
r =  0.5 - 0.5*sin(2*pi*h - pi/2)
    g = (0.5 + 0.5*sin(2*pi*h*1.5 - pi/2)) * -(h < 0.66)
    b = (0.5 + 0.5*sin(2*pi*h*1.5 + pi/2)) * -(h > 0.33)

    n = 128

    mm = m*10000 mod 500
p = abs((h*n) - int(h*n))

rr = 200*r - 0.15*mm - 35*p
gg = 200*g - 0.15*mm - 35*p
bb = 200*b - 0.15*mm - 35*p

if rr < 0 then rr = 0
if gg < 0 then gg = 0
if bb < 0 then bb = 0

hrgb& = _rgb(rr, gg, bb)
end function

function cosh#(x as double)
    cosh# = 0.5*(exp(x) + exp(-x))
end function

function sinh#(x as double)
    sinh# = 0.5*(exp(x) - exp(-x))
end function

'u + iv = (x + iy)^(a + ib)
sub cexp(u, v, xx, yy, aa, bb)
x = xx
y = yy
a = aa
b = bb
   
    lnz = x*x + y*y
   
    if lnz = 0 then
        u = 0
        v = 0
    else
        lnz = 0.5*log(lnz)
        argz = atan2(y, x)
       
        mag = exp(a*lnz - b*argz)
        ang = a*argz + b*lnz
       
        u = mag*cos(ang)
        v = mag*sin(ang)
    end if
end sub

'u + iv = (x + iy)*(a + ib)
sub cmul(u, v, xx, yy, aa, bb)
x = xx
y = yy
a = aa
b = bb
    u = x*a - y*b
    v = x*b + y*a
end sub

'u + iv = (x + iy)/(a + ib)
sub cdiv(u, v, xx, yy, aa, bb)
x = xx
y = yy
a = aa
b = bb

    d = a*a + b*b
    u = (x*a + y*b)/d
    v = (y*a - x*b)/d
end sub

sub clog(u, v, xx, yy)
x = xx
y = yy

    lnz = x*x + y*y
   
    if lnz = 0 then
        u = 0
        v = 0
    else
u = 0.5*log(lnz)
v = _atan2(y, x)
end if
end sub

2
Programs / Curves
« on: February 01, 2022, 04:35:33 pm »
Code: [Select]
deflng a-z
dim shared sw, sh
sw = 1024
sh = 600
dim shared pi as double
pi = 4*atn(1)

screen _newimage(sw, sh, 32)

dim as long n, r, mx, my, mb, omx, omy
n = 0
redim x(n) as long, y(n) as long

r = 5
do
getmouse mx, my, mb

if mb = 1 then
n = 1
redim _preserve x(n)
redim _preserve y(n)

x(0) = mx - sw/2
y(0) = sh/2 - my

pset (mx, my)
do while mb = 1
getmouse mx, my, mb

line -(mx, my), _rgb(30,30,30)

if (mx - omx)^2 + (my - omy)^2 > r^2 then
circlef mx, my, 3, _rgb(30,30,30)
omx = mx
omy = my

x(n) = mx - sw/2
y(n) = sh/2 - my
n = n + 1
redim _preserve x(n)
redim _preserve y(n)
end if

_display
_limit 50
loop

'close the contour
'x(n) = x(0)
'y(n) = y(0)
'n = n + 1
'redim _preserve x(n)
'redim _preserve y(n)


'redraw spline
'pset (sw/2 + x(0), sh/2 - y(0))
'for i=0 to n
'line -(sw/2 + x(i), sh/2 - y(i)), _rgb(255,0,0)
'circlef sw/2 + x(i), sh/2 - y(i), 3, _rgb(255,0,0)
'next

dim as double bx, by, t, bin
pset (sw/2 + x(0), sh/2 - y(0))
for t=0 to 1 step 0.0001
bx = 0
by = 0

for i=0 to n
bin = 1
for j=1 to i
bin = bin*(n - j)/j
next

bx = bx + bin*((1 - t)^(n - 1 - i))*(t^i)*x(i)
by = by + bin*((1 - t)^(n - 1 - i))*(t^i)*y(i)
next

line -(sw/2 + bx, sh/2 - by), _rgb(255,0,0)
next
end if

_display
_limit 50
loop until _keyhit = 27
system

sub getmouse (mx as long, my as long, mb as long)
do
mx = _mousex
my = _mousey
mb = -_mousebutton(1)
loop while _mouseinput
end sub
 
sub circlef(x as long, y as long, r as long, c as long)
dim as long x0, y0, e
        x0 = r
        y0 = 0
        e = -r
 
        do while y0 < x0
                if e <=0 then
                        y0 = y0 + 1
                        line (x - x0, y + y0)-(x + x0, y + y0), c, bf
                        line (x - x0, y - y0)-(x + x0, y - y0), c, bf
                        e = e + 2*y0
                else
                        line (x - y0, y - x0)-(x + y0, y - x0), c, bf
                        line (x - y0, y + x0)-(x + y0, y + x0), c, bf
                        x0 = x0 - 1
                        e = e - 2*x0
                end if
        loop
        line (x - r, y)-(x + r, y), c, bf
end sub


 
caligpro3.PNG

3
Programs / Removable singularity
« on: January 13, 2022, 05:23:42 am »
what happens when you take a function f(x), multiply it by (x-1) then divide by (x-1)? Would it be infinity at x=1? 

g(x) = f(x)*(x-1)/(x-1).  what is g(1)?

Try it out with the mouse:

Code: QB64: [Select]
  1. const sw = 800
  2. const sh = 600
  3.  
  4. pi = 4*atn(1)
  5.  
  6. screen _newimage(sw, sh, 32)
  7.  
  8.         do
  9.                 mx = _mousex
  10.                 my = _mousey
  11.                 mbl = _mousebutton(1)
  12.                 mbr = _mousebutton(2)
  13.                 mw = mw + _mousewheel
  14.         loop while _mouseinput
  15.  
  16.         for yy=0 to sh
  17.         for xx=0 to sw
  18.                         u = (xx - sw/2)*0.01
  19.                         v = (sh/2 - yy)*0.01
  20.  
  21.  
  22.                         cmul uu, vv, u - (mx - sw/2)*0.01, v - (sh/2 - my)*0.01, u + 0.707, v - 0.707
  23.                         cdiv x, y, uu, vv, u - 1, v
  24.  
  25.  
  26.                 m = sqr(x*x + y*y)
  27.                 a = (pi + _atan2(y, x))/(2*pi)
  28.  
  29.                 pset (xx, yy), hrgb&(a, m)
  30.  
  31.         next
  32.         next
  33.  
  34.         _display
  35.         _limit 60
  36.  
  37.  
  38.  
  39. function hrgb&(h, m)
  40.         r =  0.5 - 0.5*sin(2*pi*h - pi/2)
  41.     g = (0.5 + 0.5*sin(2*pi*h*1.5 - pi/2)) * -(h < 0.66)
  42.     b = (0.5 + 0.5*sin(2*pi*h*1.5 + pi/2)) * -(h > 0.33)
  43.  
  44.         dim n as long
  45.     n = 16
  46.    
  47.     mm = m*500 mod 500
  48.         p = abs((h*n) - int(h*n))
  49.  
  50.         rr = 255*r - 0.15*mm - 35*p
  51.         gg = 255*g - 0.15*mm - 35*p
  52.         bb = 255*b - 0.15*mm - 35*p
  53.  
  54.         if rr < 0 then rr = 0
  55.         if gg < 0 then gg = 0
  56.         if bb < 0 then bb = 0
  57.  
  58.         hrgb& = _rgb(rr, gg, bb)
  59.  
  60.  
  61. 'u + iv = (x + iy)*(a + ib)
  62. sub cmul(u, v, xx, yy, aa, bb)
  63.         x = xx
  64.         y = yy
  65.         a = aa
  66.         b = bb
  67.  
  68.     u = x*a - y*b
  69.     v = x*b + y*a
  70.  
  71. 'u + iv = (x + iy)/(a + ib)
  72. sub cdiv(u, v, xx, yy, aa, bb)
  73.         x = xx
  74.         y = yy
  75.         a = aa
  76.         b = bb
  77.  
  78.     d = a*a + b*b
  79.     u = (x*a + y*b)/d
  80.     v = (y*a - x*b)/d
  81.  

a singularity and two zeros
 
sngthere.png


singularity removed with the mouse
 
sngremoved.png

4
Programs / Lorenz system in color
« on: January 13, 2022, 03:31:11 am »
Lorenz system ( https://en.wikipedia.org/wiki/Lorenz_system ) flattened out to color domain.  Each pixel (x,y) becomes a particle (x,y,z) with random z and we colour it based on how long it takes to get to the center of the 'butterfly' using a poor Euler's method.  This image can be zoomed and explored

Code: [Select]
defdbl a-z

const sw = 640
const sh = 480

dim shared mx,my,mbl,mbr,mw

dim u as double, v as double
dim uu as double, vv as double
dim xx as double, yy as double
dim x0 as double, y0 as double
dim z as double, zz as double
z = 1
zz = 0.1

dim p1 as long
p1 = _newimage(sw, sh, 32)
screen _newimage(sw, sh, 32)

redraw = -1
iter = 500

dim c(100) as long, cc as long

for i=0 to 100
        if i < iter/6 then
                r = 155
                g = (i mod (iter/6))*(255/(iter/6))
                b = 0
        elseif i < 2*iter/6 then
                r = 155 - (i mod (iter/6))*(255/(iter/6))
                g = 155
                b = 0
        elseif i < 3*iter/6 then
                r = 0
                g = 155
                b = (i mod (iter/6))*(255/(iter/6))
        elseif i < 4*iter/6 then
                r = 0
                g = 155 - (i mod (iter/6))*(255/(iter/6))
                b = 155
        elseif i < 5*iter/6 then
                r = (i mod (iter/6))*(255/(iter/6))
                g = 0
                b = 155
        else
                r = 155
                g = 0
                b = 155 - (i mod (iter/6))*(255/(iter/6))
        end if
        c(i) = _rgb(r, g, b)
next

ppp=28
sss=10
bbb=8/3
zzz=0.456
hh=0.01

do
        mw = 0
        getmouse

        if redraw then
                for yy = 0 to sh-1
                for xx = 0 to sw-1
                        u = 0
                        v = 0

                        x = (xx - sw/2)*z + x0
                        y = (yy - sh/2)*z + y0
z2 = zzz

                        for i = 0 to iter
x = x + hh*sss*(y - x)
y = y + hh*(x*(ppp - z2) - y)
z2=z2 + hh*(x*y - bbb*z2)

                                if (x*x + y*y) < 2 then exit for
                        next

                        if i > iter then
                                pset(xx, yy), _rgb(0,0,0)
                        else
                                pset(xx, yy), c(i mod 100)
                        end if
                next
                next

                'locate 1,1
                'print "iter =";iter
                _title str$(iter)

                _dest p1
                _putimage , 0
                _dest 0

                _putimage , p1
                _autodisplay

                redraw = 0
        end if

        if mw < 0 then
                zz = zz + 0.01
        elseif mw > 0 then
                if zz > 0.01 then zz = zz - 0.01
        end if

        'draw box
        if omx <> mx or omy <> my or mw <> 0 then
                _putimage , p1
                line (mx - (sw*zz/2), my - (sh*zz/2))-step(sw*zz,sh*zz),_rgb(255,255,255),b
                _autodisplay

                omx = mx
                omy = my
        end if

        if mbl then
                do
                        getmouse
                loop while mbl

                x0 = x0 + (mx - sw/2)*z
                y0 = y0 - (sh/2 - my)*z
                z = z*zz

                iter = iter + 50

                redraw = -1
        elseif mbr then
                do
                        getMouse
                loop while mbr

                x0 = x0 + (mx - sw/2)*z
                y0 = y0 - (sh/2 - my)*z
                z = z/zz
                redraw = -1
        end if

        k = _keyhit
        if k = 43 then
                iter = iter + 50
                redraw = -1
        elseif k = 45 then
                if iter > 50 then iter = iter - 50
                redraw = -1
        end if

loop until k = 27
system

sub getmouse ()
        do
                mx = _mousex
                my = _mousey
                mbl = _mousebutton(1)
                mbr = _mousebutton(2)
                mw = mw + _mousewheel
        loop while _mouseinput
end sub

'u + iv = (x + iy) ^ (a + ib)
sub cexp (u as double, v as double, x as double, y as double, a as double, b as double)
        dim mag as double, arg as double
        dim lnz as double, argz as double

        lnz = 0.5*log((x*x + y*y)+0.00001)
        argz = _atan2(y, x)

        mag = exp(a*lnz - b*argz)
        arg = a*argz + b*lnz

        u = mag * cos(arg)
        v = mag * sin(arg)
end sub


 
lzfrac.PNG

5
Programs / Sliding Window
« on: January 11, 2022, 05:53:29 am »
On the topic of music visualizers, you can see the effect of windowing

(this wasn't optimized for visualization -- everything is calculated on the fly. it ran okay on my modern laptop)

Code: [Select]
'defdbl a-z

const sw = 2048
const sh = 600

dim shared pi as double
pi = 4*atn(1)

declare sub rfft(xx_r(), xx_i(), x_r(), n)

dim x_r (sw-1), x_i (sw-1)
dim xx_r(sw-1), xx_i(sw-1)

dim st_x_r (512-1), st_x_i (512-1)
dim st_xx_r(512-1), st_xx_i(512-1)

dim st_x_r2 (512-1), st_x_i2 (512-1)
dim st_xx_r2(512-1), st_xx_i2(512-1)

dim t as double

'create signal consisting of three sinewaves in RND noise
for i=0 to sw/3-1
x_r(i) = 100*sin(2*pi*(sw*1000/44000)*i/sw) + (100*rnd - 50)
next
for i=sw/3 to 2*sw/3-1
x_r(i) = 100*sin(2*pi*(sw*2000/44000)*i/sw) + (100*rnd - 50)
next
for i=2*sw/3 to sw-1
x_r(i) = 100*sin(2*pi*(sw*8000/44000)*i/sw) + (100*rnd - 50)
next


screen _newimage(sw/2, sh, 32),,1,0

'plot signal
pset (0, sh/4 - x_r(0))
for i=0 to sw/2 - 1
line -(i, sh/4 - x_r(i*2)), _rgb(70,0,0)
next
line (0, sh/4)-step(sw,0), _rgb(255,0,0),,&h5555

color _rgb(255,0,0)
_printstring (0, 0), "2048 samples of three sine waves (1 kHz, 2 kHz, 8 kHz) in RND noise sampled at 44 kHz"


rfft xx_r(), xx_i(), x_r(), sw

'plot its fft
'pset (0, 70+3*sh/4 - 0.005*sqr(xx_r(0)*xx_r(0) + xx_i(0)*xx_i(0)) )
for i=0 to sw/2
pset (i*2, 70 + 3*sh/4), _rgb(70,70,0)
line -(i*2, 70+3*sh/4 - 0.005*sqr(xx_r(i)*xx_r(i) + xx_i(i)*xx_i(i)) ), _rgb(70,70,0)
next
line (0, 70+3*sh/4)-step(sw,0), _rgb(255,255,0),,&h5555

color _rgb(70,70,0)
_printstring (0, sh/2), "its entire FFT first half"
color _rgb(70,0,0)
_printstring (0, sh/2 + 16), "rectangular short time FFT"
color _rgb(0,70,0)
_printstring (0, sh/2 + 32), "gaussian short time FFT"


screen ,,0,0
pcopy 1,0

mx = 0
do
do
mx = _mousex
my = _mousey
mbl = _mousebutton(1)
mbr = _mousebutton(2)
mw = mw + _mousewheel
loop while _mouseinput

pcopy 1,0


'draw windows
if mx > sw/2-256 then mx = sw/2 - 256 - 1
if mx < 0 then mx = 0

'''rectangular window
line (mx,1)-step(256,sh/4 - 1),_rgb(255,0,0),b

'''gaussian window
z = (0 - 256/2)/(128/2)
pset (mx, sh/4 - (sh/4)*exp(-z*z/2))
for i=0 to 256
z = (i - 256/2)/(128/2)
line -(mx + i, sh/4 - (sh/4)*exp(-z*z/2)),_rgb(0,255,0)
next


'take it's windowed short time FFT
for i=0 to 512-1
'rectangular window -- do nothing
st_x_r(i) = x_r(mx*2 + i)

'gaussian window -- smooth out the edges
z = (i - 512/2)/(256/2)
st_x_r2(i) = x_r(mx*2 + i)*exp(-z*z/2)
next

'''plot signal rectangular
pset (mx, sh/4 - st_x_r(0))
for i=0 to 256 -1
line -(mx + i, sh/4 - st_x_r(i*2)), _rgb(255,0,0)
next
line (0, sh/4)-step(sw,0), _rgb(255,0,0),,&h5555

'''plot signal gaussian
pset (mx, sh/4 - st_x_r2(0))
for i=0 to 256 -1
line -(mx + i, sh/4 - st_x_r2(i*2)), _rgb(0,255,0)
next
line (0, sh/4)-step(sw,0), _rgb(255,0,0),,&h5555


rfft st_xx_r(), st_xx_i(), st_x_r(), 512
rfft st_xx_r2(), st_xx_i2(), st_x_r2(), 512


'plot its short time fft rectangular
pset (0, 70+3*sh/4 - 0.005*sqr(st_xx_r(0)*st_xx_r(0) + st_xx_i(0)*st_xx_i(0)) )
for i=0 to 128
'pset (i*8, 70 + 3*sh/4), _rgb(256,256,0)
line -(i*8, 70+3*sh/4 - 0.005*sqr(st_xx_r(i)*st_xx_r(i) + st_xx_i(i)*st_xx_i(i)) ), _rgb(256,0,0)
next

'''parabolic tone finder
dim max as double, d as double
max = 0
m = 0
for i=0 to 256
d = sqr(st_xx_r(i)*st_xx_r(i) + st_xx_i(i)*st_xx_i(i))
if d > max then
max = d
m = i
end if
next

dim c as double
dim u_r as double, u_i as double
dim v_r as double, v_i as double

u_r = st_xx_r(m - 1) - st_xx_r(m + 1)
u_i = st_xx_i(m - 1) - st_xx_i(m + 1)
v_r = 2*st_xx_r(m) - st_xx_r(m - 1) - st_xx_r(m + 1)
v_i = 2*st_xx_i(m) - st_xx_i(m - 1) - st_xx_i(m + 1)
c = (u_r*v_r + u_i*v_i)/(v_r*v_r + v_i*v_i)

color _rgb(70,70,0)
_printstring (sw/4, sh/2), "spectral parabolic interpolation tone detector"
color _rgb(255,0,0)
_printstring (sw/4, sh/2 + 16), "f_peak = "+str$((m + c)*44000/512)+" Hz"

i = m
pset ((i + c)*8, 70 + 3*sh/4), _rgb(256,256,0)
line -((i + c)*8, sh ), _rgb(256,0,0)



'plot its short time fft gaussian
pset (0, 70+3*sh/4 - 0.005*sqr(st_xx_r2(0)*st_xx_r2(0) + st_xx_i2(0)*st_xx_i2(0)) )
for i=0 to 128
'pset (i*8, 70 + 3*sh/4), _rgb(256,256,0)
line -(i*8, 70+3*sh/4 - 0.005*sqr(st_xx_r2(i)*st_xx_r2(i) + st_xx_i2(i)*st_xx_i2(i)) ), _rgb(0,256,0)
next

'''parabolic tone finder
max = 0
m = 0
for i=0 to 256
d = sqr(st_xx_r2(i)*st_xx_r2(i) + st_xx_i2(i)*st_xx_i2(i))
if d > max then
max = d
m = i
end if
next

u_r = st_xx_r2(m - 1) - st_xx_r2(m + 1)
u_i = st_xx_i2(m - 1) - st_xx_i2(m + 1)
v_r = 2*st_xx_r2(m) - st_xx_r2(m - 1) - st_xx_r2(m + 1)
v_i = 2*st_xx_i2(m) - st_xx_i2(m - 1) - st_xx_i2(m + 1)
c = (u_r*v_r + u_i*v_i)/(v_r*v_r + v_i*v_i)

color _rgb(0,256,0)
_printstring (sw/4, sh/2 + 32), "f_peak = "+str$((m + c)*44000/512)+" Hz"

i = m
pset ((i + c)*8, 70 + 3*sh/4), _rgb(0,256,0)
line -((i + c)*8, sh ), _rgb(0,256,0)


_display
_limit 30
loop until _keyhit=27
system


sub rfft(xx_r(), xx_i(), x_r(), n)
dim w_r as double, w_i as double, wm_r as double, wm_i as double
dim u_r as double, u_i as double, v_r as double, v_i as double

log2n = log(n/2)/log(2)

for i=0 to n/2 - 1
rev = 0
for j=0 to log2n - 1
if i and (2^j) then rev = rev + (2^(log2n - 1 - j))
next

xx_r(i) = x_r(2*rev)
xx_i(i) = x_r(2*rev + 1)
next

for i=1 to log2n
m = 2^i
wm_r = cos(-2*pi/m)
wm_i = sin(-2*pi/m)

for j=0 to n/2 - 1 step m
w_r = 1
w_i = 0

for k=0 to m/2 - 1
p = j + k
q = p + (m \ 2)

u_r = w_r*xx_r(q) - w_i*xx_i(q)
u_i = w_r*xx_i(q) + w_i*xx_r(q)
v_r = xx_r(p)
v_i = xx_i(p)

xx_r(p) = v_r + u_r
xx_i(p) = v_i + u_i
xx_r(q) = v_r - u_r
xx_i(q) = v_i - u_i

u_r = w_r
u_i = w_i
w_r = u_r*wm_r - u_i*wm_i
w_i = u_r*wm_i + u_i*wm_r
next
next
next

xx_r(n/2) = xx_r(0)
xx_i(n/2) = xx_i(0)

for i=1 to n/2 - 1
xx_r(n/2 + i) = xx_r(n/2 - i)
xx_i(n/2 + i) = xx_i(n/2 - i)
next

dim xpr as double, xpi as double
dim xmr as double, xmi as double

for i=0 to n/2 - 1
xpr = (xx_r(i) + xx_r(n/2 + i)) / 2
xpi = (xx_i(i) + xx_i(n/2 + i)) / 2

xmr = (xx_r(i) - xx_r(n/2 + i)) / 2
xmi = (xx_i(i) - xx_i(n/2 + i)) / 2

xx_r(i) = xpr + xpi*cos(2*pi*i/n) - xmr*sin(2*pi*i/n)
xx_i(i) = xmi - xpi*sin(2*pi*i/n) - xmr*cos(2*pi*i/n)
next

'symmetry, complex conj
'for i=0 to n/2 - 1
' xx_r(n/2 + i) = xx_r(n/2 - 1 - i)
' xx_i(n/2 + i) =-xx_i(n/2 - 1 - i)
'next
end sub


 
sw1.PNG


6
Programs / Driving Game
« on: December 13, 2021, 12:21:44 pm »
Use "," key to go left and "." key to go right

Code: [Select]
CLS
s = 0
cr = 0
c = 7
l = 1
w = 15
1 r = l + w
IF l = 1 THEN n = 1
IF l = 25 THEN n = 0
IF n = 1 THEN l = l + 1
IF n = 0 THEN l = l - 1
'FOR k = 0 TO 4000
'NEXT k
_DELAY 0.5
a$ = INKEY$
IF a$ = "." THEN c = c + 1
IF a$ = "," THEN c = c - 1
PRINT TAB(l); "!"; TAB(c); "*"; TAB(r); "!"
IF c = l OR c = r THEN 2
IF a$ = "." OR a$ = "," THEN s = s + 1
GOTO 1
2 PRINT "***crash***"
cr = cr + 1
IF cr < 5 THEN 1
PRINT "score:"; s
PRINT "game over"
END

7
Programs / Domain Coloring
« on: August 15, 2020, 02:13:58 pm »
A kind of method for plotting complex functions:
https://en.wikipedia.org/wiki/Domain_coloring

So pretty I had to share this
Code: [Select]
defdbl a-z
dim shared pi as double
pi = 4*atn(1)

const sw = 800
const sh = 600

declare function hrgb(h as double, m as double)

screen _newimage(sw, sh, 32)


'dim as double x, y, u, v, m, a, uu, vv, x0, y0

dim p as string

for j=0 to 7
for yy=0 to sh
for xx=0 to sw
        select case j
        case 0
                u = (xx - sw/2)*0.015
                v = (sh/2 - yy)*0.015

                x = u
                y = v

                p = "z"
        case 1
                u = (xx - sw/2)*0.01 + 2
                v = (sh/2 - yy)*0.01

                x = exp(u)*cos(v)
                y = exp(u)*sin(v)

                p = "exp(z)"
        case 2
                u = (xx - sw/2)*0.015
                v = (sh/2 - yy)*0.015

                x = sin(u)*_cosh(v)
                y = cos(u)*_sinh(v)

                p = "sin(z)"
        case 3
                u = (xx - sw/2)*0.005 - 0.5
                v = (sh/2 - yy)*0.005
                x0 = u
                y0 = v
                for i=0 to 0
                        uu = u*u - v*v + x0
                        vv = 2*u*v + y0

                        u = uu
                        v = vv
                next
                x = u
                y = v

                p = "f(z) = z^2 + c"
        case 4
                u = (xx - sw/2)*0.005 - 0.5
                v = (sh/2 - yy)*0.005
                x0 = u
                y0 = v
                for i=0 to 1
                        uu = u*u - v*v + x0
                        vv = 2*u*v + y0

                        u = uu
                        v = vv
                next
                x = u
                y = v

                p = "f(f(z))"
        case 5
                u = (xx - sw/2)*0.005 - 0.5
                v = (sh/2 - yy)*0.005
                x0 = u
                y0 = v
                for i=0 to 3
                        uu = u*u - v*v + x0
                        vv = 2*u*v + y0

                        u = uu
                        v = vv
                next
                x = u
                y = v

                p = "f(f(f(f(z))))"
        case 6
                u = (xx - sw/2)*0.005 - 0.5
                v = (sh/2 - yy)*0.005
                x0 = u
                y0 = v
                for i=0 to 9
                        uu = u*u - v*v + x0
                        vv = 2*u*v + y0

                        u = uu
                        v = vv
                next
                x = u
                y = v

                p = "f(f(f(f(f(f(f(f(f(f(z))))))))))"
case 7
u = (xx - sw/2)*0.0015
v = (sh/2 - yy)*0.0015

x = sin(u/(u*u + v*v))*_cosh(-v/(u*u + v*v))
y = cos(u/(u*u + v*v))*_sinh(-v/(u*u + v*v))

p = "sin(1/z)"
        end select

        m = sqr(x*x + y*y)
        a = (pi + _atan2(y, x))/(2*pi)

        pset (xx, yy), hrgb(a, m)

        locate 1,1: ? p
next
next

sleep
next

system

function hrgb(h as double, m as double)
'dim as double r, g, b, mm

r = 0.5 - 0.5*sin(2*pi*h - pi/2)
    g = (0.5 + 0.5*sin(2*pi*h*1.5 - pi/2)) * -(h < 0.66)
    b = (0.5 + 0.5*sin(2*pi*h*1.5 + pi/2)) * -(h > 0.33)

mm = (m*100 mod 100)*0.01

if ((m*2*pi*100 mod 2*pi*100) < 50) or ((h*2*pi*100 mod 4*2*pi) < 6) then
'hrgb = _rgb(0,0,0)
hrgb = _rgb(15*r, 155*g, 155*b)
else
hrgb = _rgb(255*r, 255*g, 255*b)
end if
end function

8
Programs / Rotozoom with bilinear interpolation
« on: May 02, 2020, 11:41:33 pm »
I've recently used this algorithm in the shapes demo and wanted to try it on an image, it is supposed to improve the appearance of a rotated image. This code is inefficient because it calculates many unnecessary pixels, I may fix this later.

Code: [Select]
deflng a-z

'const sw = 800
'const sh = 600

dim shared pi as double
pi = 4*atn(1)

img = _loadimage("leopardx.jpg", 32)
w = _width(img)
h = _height(img)

dim zoom as double
dim a as double
zoom = 2.5

a = 2*sqr(w*w/4 + h*h/4)*zoom

if h < a then h = a

screen _newimage(w + a*2, h, 32)

_putimage (0,0), img

dim rot as double
do
        rot = rot + 0.1

        line (w, 0)-step(a*2, a),_rgb(0,0,0),bf
        rotzoom img, w + a/2, a/2, rot, zoom
        rotzoomb img, w + a + a/2, a/2, rot, zoom

        _display
        _limit 30
loop until _keyhit = 27

sleep
system

sub rotzoomb(img, x0, y0, rot as double, zoom as double)
        dim a as double
        dim xx as double, yy as double
        dim dx as double, dy as double

        w = _width(img)
        h = _height(img)

        if zoom = 0 then zoom = 1
        a = 2*sqr(w*w/4 + h*h/4)*zoom

        _source img

        for y=0 to a
        for x=0 to a
                xx = (x - a/2)*cos(rot)/zoom - (y - a/2)*sin(rot)/zoom + w/2
                yy = (x - a/2)*sin(rot)/zoom + (y - a/2)*cos(rot)/zoom + h/2

                if (int(xx) >=0 and int(xx) < w - 1 and int(yy) >= 0 and int(yy) < h - 1) then
                        tl = point(int(xx), int(yy))
                        tr = point(int(xx) + 1, int(yy))
                        bl = point(int(xx), int(yy) + 1)
                        br = point(int(xx) + 1, int(yy) + 1)

                        dx = xx - int(xx)
                        dy = yy - int(yy)

                        r = _round((1 - dy)*((1 - dx)*  _red(tl) + dx*  _red(tr)) + dy*((1 - dx)*  _red(bl) + dx*  _red(br)))
                        g = _round((1 - dy)*((1 - dx)*_green(tl) + dx*_green(tr)) + dy*((1 - dx)*_green(bl) + dx*_green(br)))
                        b = _round((1 - dy)*((1 - dx)* _blue(tl) + dx* _blue(tr)) + dy*((1 - dx)* _blue(bl) + dx* _blue(br)))

                        pset (x0 - a/2 + x, y0 - a/2 + y), _rgb(r, g, b)

                elseif (int(xx) >=0 and int(xx) < w - 1 and int(yy) >= 0 and int(yy) < h - 1) then
                        pset (x0 - a/2 + x, y0 - a/2 + y), point(int(xx), int(yy))
                end if
        next
        next
end sub


sub rotzoom(img, x0, y0, rot as double, zoom as double)
        dim a as double

        w = _width(img)
        h = _height(img)

        if zoom = 0 then zoom = 1
        a = 2*sqr(w*w/4 + h*h/4)*zoom

        _source img

        for y=0 to a
        for x=0 to a
                xx = (x - a/2)*cos(rot)/zoom - (y - a/2)*sin(rot)/zoom + w/2
                yy = (x - a/2)*sin(rot)/zoom + (y - a/2)*cos(rot)/zoom + h/2

                if ((xx) >= 0 and (xx) < w and (yy) >=0 and (yy) < h) then
                        pset (x0 - a/2 + x, y0 - a/2 + y), point(int(xx), int(yy))
                end if
        next
        next
end sub

9
Programs / Angle Pong
« on: March 07, 2020, 02:01:44 am »
Move the mouse left right up down to change position and angle, self explanatory

Code: [Select]
deflng a-z
const sw = 640
const sh = 480
dim shared pi as double
pi = 4*atn(1)

declare sub circlef(x, y, r, c)

dim a as double
dim b as double, d as double
dim p as double, q as double
dim cx as double, cy as double
dim vx as double, vy as double
dim vxx as double, vyy as double
cx = sw/2
cy = sh/4
vx = 0
vy = 1
r = 15

rebound = -1
ball = 0

screen 12
do

        if cx < r then
                vx = -vx
                rebound = -1
        end if
        if cx > sw - r then
                vx = -vx
                rebound = -1
        end if
        if cy < r then
                vy = -vy
                rebound = -1
        end if
        if cy > sh - r then
                cx = sw/2
                cy = sh/4
                vx = 0
                vy = 1
                rebound = -1
                ball = ball + 1
        end if

        cx = cx + vx
        cy = cy + vy

        do
                mx = _mousex
                my = _mousey
        loop while _mouseinput

        line (0,0)-(sw,sh),0,bf

        x = mx
        y = 395
        if mx < 80 then x = 80
        if mx > sw - 80 then x = sw - 80
        a = (my - sh/2)/(1.1*sh/2)*(pi/2)
        line (x, y)-step(80*cos(a), 80*sin(a))
        line (x, y)-step(-80*cos(a), -80*sin(a))

        if rebound then
        'if a >= 0 and vx <=0 or a < 0 and vx >= 0 then
                q = sin(a)*cos(a + pi/2) - cos(a)*sin(a + pi/2)
                if q <> 0 then
                        p = cy*cos(a) - cx*sin(a) - y*cos(a) + x*sin(a)
                        d = p/q
                        b = (cx + d*cos(a + pi/2) - x)/cos(a)
                        if abs(b) < 80 then
                                'line (cx, cy)- step(d*cos(a + pi/2), d*sin(a + pi/2)), 12
                                if d < r then
                                        vxx = vx*cos(2*a) + vy*sin(2*a)
                                        vyy = vx*sin(2*a) - vy*cos(2*a)
                                        vx = vxx
                                        vy = vyy
                                        rebound = 0
                                end if
                        end if
                end if
        'end if
        end if

        circlef cx, cy, r, 15

        locate 1,1: ? ball
        'locate 1,1: ? a*180/pi
        _display
        _limit 200
loop until _keyhit = 27
sleep
system

sub circlef(x, y, r, c)
        x0 = r
        y0 = 0
        e = -r

        do while y0 < x0
                if e <=0 then
                        y0 = y0 + 1
                        line (x - x0, y + y0)-(x + x0, y + y0), c, bf
                        line (x - x0, y - y0)-(x + x0, y - y0), c, bf
                        e = e + 2*y0
                else
                        line (x - y0, y - x0)-(x + y0, y - x0), c, bf
                        line (x - y0, y + x0)-(x + y0, y + x0), c, bf
                        x0 = x0 - 1
                        e = e - 2*x0
                end if
        loop
        line (x - r, y)-(x + r, y), c, bf
end sub

10
Programs / Re: Math Puzzle
« on: February 28, 2020, 04:43:28 pm »
Note: This message is awaiting approval by a moderator.
Quite silly, you are subtracting the number from a slightly modified version of that number, intuitive that it could cancel out, hardly a trick. I guess the 'trick' is sticking a bunch of 2's in there that cancel out to hide the fact that you're doing a mere addition to the original number

((x + 5)*2 - 2)/2 - x = ((x + 5) - 1) - x = x + 4 - x = 4

11
Programs / Fast Fourier Transform
« on: November 30, 2019, 02:34:17 pm »
A fast algorithm for computing the DFT for N=2^k

To use in your own programs you just need SUB fft or SUB rfft if dealing with real only signals.
i.e.:
Code: QB64: [Select]
  1. const n = 512
  2.  
  3. pi = 4*atn(1)
  4.  
  5. dim x_r(n-1), x_i(n-1)
  6. dim xx_r(n-1), xx_i(n-1)
  7.  
  8. 'create signal
  9. for i=0 to n-1
  10.         x_r(i) = 100*sin(2*pi*62.27*i/n) + 25*cos(2*pi*132.27*i/n)
  11.         x_i(i) = 0
  12.  
  13. fft xx_r(), xx_i(), x_r(), x_i(), n
  14.  

SUB fft
x_r, x_i is the input signal real and complex values, must be arrays of size n
xx_r, xx_i must also be arrays of size n and will contain output
Code: QB64: [Select]
  1. sub fft(xx_r(), xx_i(), x_r(), x_i(), n)
  2.         dim w_r as double, w_i as double, wm_r as double, wm_i as double
  3.         dim u_r as double, u_i as double, v_r as double, v_i as double
  4.  
  5.         log2n = log(n)/log(2)
  6.  
  7.         'bit rev copy
  8.         for i=0 to n - 1
  9.                 rev = 0
  10.                 for j=0 to log2n - 1
  11.                         if i and (2^j) then rev = rev + (2^(log2n - 1 - j))
  12.                 next
  13.  
  14.                 xx_r(i) = x_r(rev)
  15.                 xx_i(i) = x_i(rev)
  16.         next
  17.  
  18.  
  19.         for i=1 to log2n
  20.                 m = 2^i
  21.                 wm_r = cos(-2*pi/m)
  22.                 wm_i = sin(-2*pi/m)
  23.  
  24.                 for j=0 to n - 1 step m
  25.                         w_r = 1
  26.                         w_i = 0
  27.  
  28.                         for k=0 to m/2 - 1
  29.                                 p = j + k
  30.                                 q = p + (m \ 2)
  31.  
  32.                                 u_r = w_r*xx_r(q) - w_i*xx_i(q)
  33.                                 u_i = w_r*xx_i(q) + w_i*xx_r(q)
  34.                                 v_r = xx_r(p)
  35.                                 v_i = xx_i(p)
  36.  
  37.                                 xx_r(p) = v_r + u_r
  38.                                 xx_i(p) = v_i + u_i
  39.                                 xx_r(q) = v_r - u_r
  40.                                 xx_i(q) = v_i - u_i
  41.  
  42.                                 u_r = w_r
  43.                                 u_i = w_i
  44.                                 w_r = u_r*wm_r - u_i*wm_i
  45.                                 w_i = u_r*wm_i + u_i*wm_r
  46.                         next
  47.                 next
  48.         next
  49.  

SUB rfft
This is about 2x faster than above fft if dealing with only real values
x_r is the input signal, must be an array of size n
xx_r, xx_i must also be arrays of size n and will contain output
Since in the real FFT the second half of the output are complex conjugates of the first half, you may wish to not compute the second half and remove the last 4 lines in this SUB. I left it in just in case.
Code: QB64: [Select]
  1. sub rfft(xx_r(), xx_i(), x_r(), n)
  2.         dim w_r as double, w_i as double, wm_r as double, wm_i as double
  3.         dim u_r as double, u_i as double, v_r as double, v_i as double
  4.  
  5.         log2n = log(n/2)/log(2)
  6.  
  7.         for i=0 to n/2 - 1
  8.                 rev = 0
  9.                 for j=0 to log2n - 1
  10.                         if i and (2^j) then rev = rev + (2^(log2n - 1 - j))
  11.                 next
  12.  
  13.                 xx_r(i) = x_r(2*rev)
  14.                 xx_i(i) = x_r(2*rev + 1)
  15.         next
  16.  
  17.         for i=1 to log2n
  18.                 m = 2^i
  19.                 wm_r = cos(-2*pi/m)
  20.                 wm_i = sin(-2*pi/m)
  21.  
  22.                 for j=0 to n/2 - 1 step m
  23.                         w_r = 1
  24.                         w_i = 0
  25.  
  26.                         for k=0 to m/2 - 1
  27.                                 p = j + k
  28.                                 q = p + (m \ 2)
  29.  
  30.                                 u_r = w_r*xx_r(q) - w_i*xx_i(q)
  31.                                 u_i = w_r*xx_i(q) + w_i*xx_r(q)
  32.                                 v_r = xx_r(p)
  33.                                 v_i = xx_i(p)
  34.  
  35.                                 xx_r(p) = v_r + u_r
  36.                                 xx_i(p) = v_i + u_i
  37.                                 xx_r(q) = v_r - u_r
  38.                                 xx_i(q) = v_i - u_i
  39.  
  40.                                 u_r = w_r
  41.                                 u_i = w_i
  42.                                 w_r = u_r*wm_r - u_i*wm_i
  43.                                 w_i = u_r*wm_i + u_i*wm_r
  44.                         next
  45.                 next
  46.         next
  47.  
  48.         xx_r(n/2) = xx_r(0)
  49.         xx_i(n/2) = xx_i(0)
  50.  
  51.         for i=1 to n/2 - 1
  52.                 xx_r(n/2 + i) = xx_r(n/2 - i)
  53.                 xx_i(n/2 + i) = xx_i(n/2 - i)
  54.         next
  55.  
  56.         dim xpr as double, xpi as double
  57.         dim xmr as double, xmi as double
  58.  
  59.         for i=0 to n/2 - 1
  60.                 xpr = (xx_r(i) + xx_r(n/2 + i)) / 2
  61.                 xpi = (xx_i(i) + xx_i(n/2 + i)) / 2
  62.  
  63.                 xmr = (xx_r(i) - xx_r(n/2 + i)) / 2
  64.                 xmi = (xx_i(i) - xx_i(n/2 + i)) / 2
  65.  
  66.                 xx_r(i) = xpr + xpi*cos(2*pi*i/n) - xmr*sin(2*pi*i/n)
  67.                 xx_i(i) = xmi - xpi*sin(2*pi*i/n) - xmr*cos(2*pi*i/n)
  68.         next
  69.  
  70.         'symmetry, complex conj
  71.         for i=0 to n/2 - 1
  72.                 xx_r(n/2 + i) = xx_r(n/2 - 1 - i)
  73.                 xx_i(n/2 + i) =-xx_i(n/2 - 1 - i)
  74.         next
  75.  

As an example FYI, here is a direct unoptimized DFT for comparison. It is much slower but can be used with any n
Code: QB64: [Select]
  1. sub dft(xx_r(), xx_i(), x_r(), x_i(), n)
  2.         for i=0 to n-1
  3.                 xx_r(i) = 0
  4.                 xx_i(i) = 0
  5.                 for j=0 to n-1
  6.                         xx_r(i) = xx_r(i) + x_r(j)*cos(2*pi*i*j/n) + x_i(j)*sin(2*pi*i*j/n)
  7.                         xx_i(i) = xx_i(i) - x_r(j)*sin(2*pi*i*j/n) + x_i(j)*cos(2*pi*i*j/n)
  8.                 next
  9.         next
  10.  

if you wish to take the inverse FFT then do the following to get back x_r and x_i from xx_r and xx_i. I chose not to include a inverse flag in the sub for my own reasons, it should be easy enough to modify above SUBs to add an inverse option if you so wish.
Code: QB64: [Select]
  1. 'inverse fft
  2. for i=0 to n-1
  3.         xx_i(i) = -xx_i(i)
  4.  
  5. fft x_r(), x_i(), xx_r(), xx_i(), n
  6.  
  7. for i=0 to n-1
  8.         x_r(i) = x_r(i)/n
  9.         x_i(i) = x_i(i)/n
  10.  

Here is a basic example using and plotting all the SUBs:
Code: QB64: [Select]
  1. 'defdbl a-z
  2.  
  3. const sw = 1024
  4. const sh = 600
  5.  
  6. 'pi = 2*asin(1)
  7. pi = 4*atn(1)
  8.  
  9. declare sub rfft(xx_r(), xx_i(), x_r(), n)
  10. declare sub fft(xx_r(), xx_i(), x_r(), x_i(), n)
  11. declare sub dft(xx_r(), xx_i(), x_r(), x_i(), n)
  12.  
  13.  
  14. dim x_r(sw-1), x_i(sw-1)
  15. dim xx_r(sw-1), xx_i(sw-1)
  16.  
  17. for i=0 to sw-1
  18.         x_r(i) = 100*sin(2*pi*62.27*i/sw) + 25*cos(2*pi*132.27*i/sw)
  19.         x_i(i) = 0
  20.  
  21.  
  22. 'screenres sw, sh, 32
  23. screen _newimage(sw, sh, 32)
  24.  
  25. pset (0, sh/4 - x_r(0))
  26. for i=0 to sw-1
  27.         line -(i, sh/4 - x_r(i)), _rgb(100,100,100)
  28.  
  29. dft xx_r(), xx_i(), x_r(), x_i(), sw
  30. pset (0, 3*sh/4 - 0.1*sqr(xx_r(0)*xx_r(0) + xx_i(0)*xx_i(0)) ), _rgb(0,255,0)
  31. for i=0 to sw - 1
  32.         line -(i, 3*sh/4 - 0.1*sqr(xx_r(i)*xx_r(i) + xx_i(i)*xx_i(i)) ), _rgb(0,255,0)
  33. line (0, 3*sh/4)-step(sw,0), _rgb(0,255,0),,&h5555
  34.  
  35. t = timer
  36. for i=0 to 50
  37. fft xx_r(), xx_i(), x_r(), x_i(), sw
  38. locate 1,1
  39. print "50x fft ";timer - t
  40.  
  41. pset (0, 50+3*sh/4 - 0.1*sqr(xx_r(0)*xx_r(0) + xx_i(0)*xx_i(0)) ), _rgb(255,0,0)
  42. for i=0 to sw - 1
  43.         line -(i, 50+3*sh/4 - 0.1*sqr(xx_r(i)*xx_r(i) + xx_i(i)*xx_i(i)) ), _rgb(255,0,0)
  44. line (0, 50+3*sh/4)-step(sw,0), _rgb(255,0,0),,&h5555
  45.  
  46.  
  47. for i=0 to sw-1
  48.         xx_r(i) = 0
  49.         xx_i(i) = 0
  50.  
  51. t = timer
  52. for i=0 to 50
  53. rfft xx_r(), xx_i(), x_r(), sw
  54. locate 2,1
  55. print "50x rfft ";timer - t
  56.  
  57. pset (0, 100+3*sh/4 - 0.1*sqr(xx_r(0)*xx_r(0) + xx_i(0)*xx_i(0)) ), _rgb(255,255,0)
  58. for i=0 to sw - 1
  59.         line -(i, 100+3*sh/4 - 0.1*sqr(xx_r(i)*xx_r(i) + xx_i(i)*xx_i(i)) ), _rgb(255,255,0)
  60. line (0, 100+3*sh/4)-step(sw,0), _rgb(255,255,0),,&h5555
  61.  
  62.  
  63.  
  64. sub rfft(xx_r(), xx_i(), x_r(), n)
  65.         dim w_r as double, w_i as double, wm_r as double, wm_i as double
  66.         dim u_r as double, u_i as double, v_r as double, v_i as double
  67.  
  68.         log2n = log(n/2)/log(2)
  69.  
  70.         for i=0 to n/2 - 1
  71.                 rev = 0
  72.                 for j=0 to log2n - 1
  73.                         if i and (2^j) then rev = rev + (2^(log2n - 1 - j))
  74.                 next
  75.  
  76.                 xx_r(i) = x_r(2*rev)
  77.                 xx_i(i) = x_r(2*rev + 1)
  78.         next
  79.  
  80.         for i=1 to log2n
  81.                 m = 2^i
  82.                 wm_r = cos(-2*pi/m)
  83.                 wm_i = sin(-2*pi/m)
  84.  
  85.                 for j=0 to n/2 - 1 step m
  86.                         w_r = 1
  87.                         w_i = 0
  88.  
  89.                         for k=0 to m/2 - 1
  90.                                 p = j + k
  91.                                 q = p + (m \ 2)
  92.  
  93.                                 u_r = w_r*xx_r(q) - w_i*xx_i(q)
  94.                                 u_i = w_r*xx_i(q) + w_i*xx_r(q)
  95.                                 v_r = xx_r(p)
  96.                                 v_i = xx_i(p)
  97.  
  98.                                 xx_r(p) = v_r + u_r
  99.                                 xx_i(p) = v_i + u_i
  100.                                 xx_r(q) = v_r - u_r
  101.                                 xx_i(q) = v_i - u_i
  102.  
  103.                                 u_r = w_r
  104.                                 u_i = w_i
  105.                                 w_r = u_r*wm_r - u_i*wm_i
  106.                                 w_i = u_r*wm_i + u_i*wm_r
  107.                         next
  108.                 next
  109.         next
  110.  
  111.         xx_r(n/2) = xx_r(0)
  112.         xx_i(n/2) = xx_i(0)
  113.  
  114.         for i=1 to n/2 - 1
  115.                 xx_r(n/2 + i) = xx_r(n/2 - i)
  116.                 xx_i(n/2 + i) = xx_i(n/2 - i)
  117.         next
  118.  
  119.         dim xpr as double, xpi as double
  120.         dim xmr as double, xmi as double
  121.  
  122.         for i=0 to n/2 - 1
  123.                 xpr = (xx_r(i) + xx_r(n/2 + i)) / 2
  124.                 xpi = (xx_i(i) + xx_i(n/2 + i)) / 2
  125.  
  126.                 xmr = (xx_r(i) - xx_r(n/2 + i)) / 2
  127.                 xmi = (xx_i(i) - xx_i(n/2 + i)) / 2
  128.  
  129.                 xx_r(i) = xpr + xpi*cos(2*pi*i/n) - xmr*sin(2*pi*i/n)
  130.                 xx_i(i) = xmi - xpi*sin(2*pi*i/n) - xmr*cos(2*pi*i/n)
  131.         next
  132.  
  133.         'symmetry, complex conj
  134.         for i=0 to n/2 - 1
  135.                 xx_r(n/2 + i) = xx_r(n/2 - 1 - i)
  136.                 xx_i(n/2 + i) =-xx_i(n/2 - 1 - i)
  137.         next
  138.  
  139. sub fft(xx_r(), xx_i(), x_r(), x_i(), n)
  140.         dim w_r as double, w_i as double, wm_r as double, wm_i as double
  141.         dim u_r as double, u_i as double, v_r as double, v_i as double
  142.  
  143.         log2n = log(n)/log(2)
  144.  
  145.         'bit rev copy
  146.         for i=0 to n - 1
  147.                 rev = 0
  148.                 for j=0 to log2n - 1
  149.                         if i and (2^j) then rev = rev + (2^(log2n - 1 - j))
  150.                 next
  151.  
  152.                 xx_r(i) = x_r(rev)
  153.                 xx_i(i) = x_i(rev)
  154.         next
  155.  
  156.  
  157.         for i=1 to log2n
  158.                 m = 2^i
  159.                 wm_r = cos(-2*pi/m)
  160.                 wm_i = sin(-2*pi/m)
  161.  
  162.                 for j=0 to n - 1 step m
  163.                         w_r = 1
  164.                         w_i = 0
  165.  
  166.                         for k=0 to m/2 - 1
  167.                                 p = j + k
  168.                                 q = p + (m \ 2)
  169.  
  170.                                 u_r = w_r*xx_r(q) - w_i*xx_i(q)
  171.                                 u_i = w_r*xx_i(q) + w_i*xx_r(q)
  172.                                 v_r = xx_r(p)
  173.                                 v_i = xx_i(p)
  174.  
  175.                                 xx_r(p) = v_r + u_r
  176.                                 xx_i(p) = v_i + u_i
  177.                                 xx_r(q) = v_r - u_r
  178.                                 xx_i(q) = v_i - u_i
  179.  
  180.                                 u_r = w_r
  181.                                 u_i = w_i
  182.                                 w_r = u_r*wm_r - u_i*wm_i
  183.                                 w_i = u_r*wm_i + u_i*wm_r
  184.                         next
  185.                 next
  186.         next
  187.  
  188. sub dft(xx_r(), xx_i(), x_r(), x_i(), n)
  189.         for i=0 to n-1
  190.                 xx_r(i) = 0
  191.                 xx_i(i) = 0
  192.                 for j=0 to n-1
  193.                         xx_r(i) = xx_r(i) + x_r(j)*cos(2*pi*i*j/n) + x_i(j)*sin(2*pi*i*j/n)
  194.                         xx_i(i) = xx_i(i) - x_r(j)*sin(2*pi*i*j/n) + x_i(j)*cos(2*pi*i*j/n)
  195.                 next
  196.         next
  197.  

A common use for FFT is filtering unwanted frequencies. The following example demonstrates this, with screenshots attached
Code: QB64: [Select]
  1. 'defdbl a-z
  2.  
  3. const sw = 512
  4. const sh = 600
  5.  
  6. 'pi = 2*asin(1)
  7. pi = 4*atn(1)
  8.  
  9. declare sub fft(xx_r(), xx_i(), x_r(), x_i(), n)
  10.  
  11.  
  12. dim x_r(sw-1), x_i(sw-1)
  13. dim xx_r(sw-1), xx_i(sw-1)
  14.  
  15. for i=0 to sw-1
  16.         'x_r(i) = 100*sin(2*pi*62.27*i/sw) + 25*cos(2*pi*132.27*i/sw)
  17.         x_r(i) = 100*sin(0.08*i) + 25*cos(i)
  18.         x_i(i) = 0
  19.  
  20.  
  21. 'screenres sw, sh, 32
  22. screen _newimage(sw*2, sh, 32)
  23.  
  24. 'plot input signal
  25. pset (0, sh/4 - x_r(0))
  26. for i=0 to sw-1
  27.         line -(i, sh/4 - x_r(i)), _rgb(255,0,0)
  28. line (0, sh/4)-step(sw,0), _rgb(255,0,0),,&h5555
  29. color _rgb(255,0,0)
  30. _printstring (0,0), "input signal"
  31.  
  32. fft xx_r(), xx_i(), x_r(), x_i(), sw
  33.  
  34. 'plot its fft
  35. pset (0, 50+3*sh/4 - 0.01*sqr(xx_r(0)*xx_r(0) + xx_i(0)*xx_i(0)) ), _rgb(255,255,0)
  36. for i=0 to sw/2
  37.         line -(i*2, 50+3*sh/4 - 0.01*sqr(xx_r(i)*xx_r(i) + xx_i(i)*xx_i(i)) ), _rgb(255,255,0)
  38. line (0, 50+3*sh/4)-step(sw,0), _rgb(255,255,0),,&h5555
  39.  
  40.  
  41. 'set unwanted frequencies to zero
  42. for i=50 to sw/2
  43.         xx_r(i) = 0
  44.         xx_i(i) = 0
  45.         xx_r(sw - i) = 0
  46.         xx_i(sw - i) = 0
  47.  
  48. 'plot fft of filtered signal
  49. pset (sw, 50+3*sh/4 - 0.01*sqr(xx_r(0)*xx_r(0) + xx_i(0)*xx_i(0)) ), _rgb(255,255,0)
  50. for i=0 to sw/2
  51.         line -(sw + i*2, 50+3*sh/4 - 0.01*sqr(xx_r(i)*xx_r(i) + xx_i(i)*xx_i(i)) ), _rgb(0,155,255)
  52. line (sw, 50+3*sh/4)-step(sw,0), _rgb(0,155,255),,&h5555
  53.  
  54. 'take inverse fft
  55. for i=0 to sw-1
  56.         xx_i(i) = -xx_i(i)
  57.  
  58. fft x_r(), x_i(), xx_r(), xx_i(), sw
  59.  
  60. for i=0 to sw-1
  61.         x_r(i) = x_r(i)/sw
  62.         x_i(i) = x_i(i)/sw
  63.  
  64.  
  65. 'plot filtered signal
  66. pset (sw, sh/4 - x_r(0))
  67. for i=0 to sw-1
  68.         line -(sw + i, sh/4 - x_r(i)), _rgb(0,255,0)
  69. line (sw, sh/4)-step(sw,0), _rgb(0,255,0),,&h5555
  70.  
  71. color _rgb(0,255,0)
  72. _printstring (sw,0), "filtered signal"
  73.  
  74.  
  75. sub fft(xx_r(), xx_i(), x_r(), x_i(), n)
  76.         dim w_r as double, w_i as double, wm_r as double, wm_i as double
  77.         dim u_r as double, u_i as double, v_r as double, v_i as double
  78.  
  79.         log2n = log(n)/log(2)
  80.  
  81.         'bit rev copy
  82.         for i=0 to n - 1
  83.                 rev = 0
  84.                 for j=0 to log2n - 1
  85.                         if i and (2^j) then rev = rev + (2^(log2n - 1 - j))
  86.                 next
  87.  
  88.                 xx_r(i) = x_r(rev)
  89.                 xx_i(i) = x_i(rev)
  90.         next
  91.  
  92.  
  93.         for i=1 to log2n
  94.                 m = 2^i
  95.                 wm_r = cos(-2*pi/m)
  96.                 wm_i = sin(-2*pi/m)
  97.  
  98.                 for j=0 to n - 1 step m
  99.                         w_r = 1
  100.                         w_i = 0
  101.  
  102.                         for k=0 to m/2 - 1
  103.                                 p = j + k
  104.                                 q = p + (m \ 2)
  105.  
  106.                                 u_r = w_r*xx_r(q) - w_i*xx_i(q)
  107.                                 u_i = w_r*xx_i(q) + w_i*xx_r(q)
  108.                                 v_r = xx_r(p)
  109.                                 v_i = xx_i(p)
  110.  
  111.                                 xx_r(p) = v_r + u_r
  112.                                 xx_i(p) = v_i + u_i
  113.                                 xx_r(q) = v_r - u_r
  114.                                 xx_i(q) = v_i - u_i
  115.  
  116.                                 u_r = w_r
  117.                                 u_i = w_i
  118.                                 w_r = u_r*wm_r - u_i*wm_i
  119.                                 w_i = u_r*wm_i + u_i*wm_r
  120.                         next
  121.                 next
  122.         next
  123.  


Another common thing seems to be wanting to find an exact frequency of a signal. The following demonstrates calculating the frequency of a sine corrupted in noise and applying bin to frequency correction for extra accuracy, screenshot attached.
Code: QB64: [Select]
  1. 'defdbl a-z
  2.  
  3. const sw = 1024
  4. const sh = 600
  5.  
  6. 'pi = 2*asin(1)
  7. pi = 4*atn(1)
  8.  
  9. declare sub rfft(xx_r(), xx_i(), x_r(), n)
  10.  
  11. dim x_r(sw-1), x_i(sw-1)
  12. dim xx_r(sw-1), xx_i(sw-1)
  13.  
  14. for i=0 to sw-1
  15.         x_r(i) = 100*sin(2*pi*(sw*2000/44000)*i/sw) + (100*rnd - 50)
  16.  
  17.  
  18. 'screenres sw, sh, 32
  19. screen _newimage(sw, sh, 32)
  20.  
  21. 'plot signal
  22. pset (0, sh/4 - x_r(0))
  23. for i=0 to sw-1
  24.         line -(i, sh/4 - x_r(i)), _rgb(255,0,0)
  25. line (0, sh/4)-step(sw,0), _rgb(255,0,0),,&h5555
  26.  
  27. _printstring (0, 0), "2000 kHz signal with RND noise sampled at 44 kHz in 1024 samples"
  28.  
  29.  
  30. rfft xx_r(), xx_i(), x_r(), sw
  31.  
  32. 'plot its fft
  33. pset (0, 50+3*sh/4 - 0.005*sqr(xx_r(0)*xx_r(0) + xx_i(0)*xx_i(0)) ), _rgb(255,255,0)
  34. for i=0 to sw/2
  35.         line -(i*2, 50+3*sh/4 - 0.005*sqr(xx_r(i)*xx_r(i) + xx_i(i)*xx_i(i)) ), _rgb(255,255,0)
  36. line (0, 50+3*sh/4)-step(sw,0), _rgb(255,255,0),,&h5555
  37.  
  38.  
  39. 'find peak
  40. max = 0
  41. m = 0
  42. for i=0 to sw/2
  43.         d = 0.01*sqr(xx_r(i)*xx_r(i) + xx_i(i)*xx_i(i))
  44.         if d > max then
  45.                 max = d
  46.                 m = i
  47.         end if
  48.  
  49. _printstring (0, sh/2), "m_peak ="+str$(m)
  50. _printstring (0, sh/2 + 16), "f_peak = m_peak * 44 kHz / 1024 samples = "+str$(m*44000/1024)+" Hz"
  51.  
  52. 'apply frequency correction, only works for some signals
  53. dim u_r as double, u_i as double
  54. dim v_r as double, v_i as double
  55.  
  56. u_r = xx_r(m - 1) - xx_r(m + 1)
  57. u_i = xx_i(m - 1) - xx_i(m + 1)
  58. v_r = 2*xx_r(m) - xx_r(m - 1) - xx_r(m + 1)
  59. v_i = 2*xx_i(m) - xx_i(m - 1) - xx_i(m + 1)
  60. c = (u_r*v_r + u_i*v_i)/(v_r*v_r + v_i*v_i)
  61.  
  62. _printstring (0, sh/2 + 2*16), "f_corrected = "+str$((m+c)*44000/1024)+" Hz"
  63.  
  64.  
  65.  
  66. sub rfft(xx_r(), xx_i(), x_r(), n)
  67.         dim w_r as double, w_i as double, wm_r as double, wm_i as double
  68.         dim u_r as double, u_i as double, v_r as double, v_i as double
  69.  
  70.         log2n = log(n/2)/log(2)
  71.  
  72.         for i=0 to n/2 - 1
  73.                 rev = 0
  74.                 for j=0 to log2n - 1
  75.                         if i and (2^j) then rev = rev + (2^(log2n - 1 - j))
  76.                 next
  77.  
  78.                 xx_r(i) = x_r(2*rev)
  79.                 xx_i(i) = x_r(2*rev + 1)
  80.         next
  81.  
  82.         for i=1 to log2n
  83.                 m = 2^i
  84.                 wm_r = cos(-2*pi/m)
  85.                 wm_i = sin(-2*pi/m)
  86.  
  87.                 for j=0 to n/2 - 1 step m
  88.                         w_r = 1
  89.                         w_i = 0
  90.  
  91.                         for k=0 to m/2 - 1
  92.                                 p = j + k
  93.                                 q = p + (m \ 2)
  94.  
  95.                                 u_r = w_r*xx_r(q) - w_i*xx_i(q)
  96.                                 u_i = w_r*xx_i(q) + w_i*xx_r(q)
  97.                                 v_r = xx_r(p)
  98.                                 v_i = xx_i(p)
  99.  
  100.                                 xx_r(p) = v_r + u_r
  101.                                 xx_i(p) = v_i + u_i
  102.                                 xx_r(q) = v_r - u_r
  103.                                 xx_i(q) = v_i - u_i
  104.  
  105.                                 u_r = w_r
  106.                                 u_i = w_i
  107.                                 w_r = u_r*wm_r - u_i*wm_i
  108.                                 w_i = u_r*wm_i + u_i*wm_r
  109.                         next
  110.                 next
  111.         next
  112.  
  113.         xx_r(n/2) = xx_r(0)
  114.         xx_i(n/2) = xx_i(0)
  115.  
  116.         for i=1 to n/2 - 1
  117.                 xx_r(n/2 + i) = xx_r(n/2 - i)
  118.                 xx_i(n/2 + i) = xx_i(n/2 - i)
  119.         next
  120.  
  121.         dim xpr as double, xpi as double
  122.         dim xmr as double, xmi as double
  123.  
  124.         for i=0 to n/2 - 1
  125.                 xpr = (xx_r(i) + xx_r(n/2 + i)) / 2
  126.                 xpi = (xx_i(i) + xx_i(n/2 + i)) / 2
  127.  
  128.                 xmr = (xx_r(i) - xx_r(n/2 + i)) / 2
  129.                 xmi = (xx_i(i) - xx_i(n/2 + i)) / 2
  130.  
  131.                 xx_r(i) = xpr + xpi*cos(2*pi*i/n) - xmr*sin(2*pi*i/n)
  132.                 xx_i(i) = xmi - xpi*sin(2*pi*i/n) - xmr*cos(2*pi*i/n)
  133.         next
  134.  
  135.         'symmetry, complex conj
  136.         for i=0 to n/2 - 1
  137.                 xx_r(n/2 + i) = xx_r(n/2 - 1 - i)
  138.                 xx_i(n/2 + i) =-xx_i(n/2 - 1 - i)
  139.         next
  140.  

12
QB64 Discussion / Pattern Challenge 2
« on: July 02, 2019, 03:21:05 pm »
In spirit of bplus's thread, I challenge you to draw the attached image.  The only rule is that it has to be a fully re-sizable vector image that doesn't lose detail with change in size (ie no bitmaps/putimage).  Bonus points if you can make the circles and widths variable size. I will be very impressed if someone pulls this off!

13
Programs / PENtrIS
« on: October 11, 2018, 05:42:37 pm »
An extension of tetris to pentominos as described here https://en.wikipedia.org/wiki/Pentomino

I've never actually played this variant before other then this very program so not sure how playable and balanced it is, I am able to get several lines with a bit of luck.  Suggestions such as which pieces to add/remove, board size, etc are welcome.  Edit: fixed lines not being cleared issue

Code: QB64: [Select]
  1. deflng a-z
  2.  
  3. dim shared piece(17, 2, 4)
  4. dim shared piece_color(17)
  5. dim shared size, sw, sh
  6.  
  7. size = 35
  8. sw = 11
  9. sh = 25
  10.  
  11. redim shared board(sw - 1, sh - 1)
  12.  
  13. piece(0,0,0)=0: piece(0,1,0)=1: piece(0,2,0)=0
  14. piece(0,0,1)=0: piece(0,1,1)=1: piece(0,2,1)=0
  15. piece(0,0,2)=0: piece(0,1,2)=1: piece(0,2,2)=0
  16. piece(0,0,3)=0: piece(0,1,3)=1: piece(0,2,3)=0
  17. piece(0,0,4)=0: piece(0,1,4)=1: piece(0,2,4)=0
  18.  
  19. piece(1,0,0)=0: piece(1,1,0)=0: piece(1,2,0)=0
  20. piece(1,0,1)=0: piece(1,1,1)=0: piece(1,2,1)=0
  21. piece(1,0,2)=0: piece(1,1,2)=1: piece(1,2,2)=1
  22. piece(1,0,3)=1: piece(1,1,3)=1: piece(1,2,3)=0
  23. piece(1,0,4)=0: piece(1,1,4)=1: piece(1,2,4)=0
  24.  
  25. piece(2,0,0)=0: piece(2,1,0)=0: piece(2,2,0)=0
  26. piece(2,0,1)=0: piece(2,1,1)=0: piece(2,2,1)=0
  27. piece(2,0,2)=1: piece(2,1,2)=1: piece(2,2,2)=0
  28. piece(2,0,3)=0: piece(2,1,3)=1: piece(2,2,3)=1
  29. piece(2,0,4)=0: piece(2,1,4)=1: piece(2,2,4)=0
  30.  
  31. piece(3,0,0)=0: piece(3,1,0)=0: piece(3,2,0)=0
  32. piece(3,0,1)=0: piece(3,1,1)=1: piece(3,2,1)=0
  33. piece(3,0,2)=0: piece(3,1,2)=1: piece(3,2,2)=0
  34. piece(3,0,3)=0: piece(3,1,3)=1: piece(3,2,3)=0
  35. piece(3,0,4)=1: piece(3,1,4)=1: piece(3,2,4)=0
  36.  
  37. piece(4,0,0)=0: piece(4,1,0)=0: piece(4,2,0)=0
  38. piece(4,0,1)=0: piece(4,1,1)=1: piece(4,2,1)=0
  39. piece(4,0,2)=0: piece(4,1,2)=1: piece(4,2,2)=0
  40. piece(4,0,3)=0: piece(4,1,3)=1: piece(4,2,3)=0
  41. piece(4,0,4)=0: piece(4,1,4)=1: piece(4,2,4)=1
  42.  
  43. piece(5,0,0)=0: piece(5,1,0)=0: piece(5,2,0)=0
  44. piece(5,0,1)=0: piece(5,1,1)=0: piece(5,2,1)=0
  45. piece(5,0,2)=1: piece(5,1,2)=1: piece(5,2,2)=0
  46. piece(5,0,3)=1: piece(5,1,3)=1: piece(5,2,3)=0
  47. piece(5,0,4)=0: piece(5,1,4)=1: piece(5,2,4)=0
  48.  
  49. piece(6,0,0)=0: piece(6,1,0)=0: piece(6,2,0)=0
  50. piece(6,0,1)=0: piece(6,1,1)=0: piece(6,2,1)=0
  51. piece(6,0,2)=0: piece(6,1,2)=1: piece(6,2,2)=1
  52. piece(6,0,3)=0: piece(6,1,3)=1: piece(6,2,3)=1
  53. piece(6,0,4)=0: piece(6,1,4)=1: piece(6,2,4)=0
  54.  
  55. piece(7,0,0)=0: piece(7,1,0)=0: piece(7,2,0)=0
  56. piece(7,0,1)=0: piece(7,1,1)=1: piece(7,2,1)=0
  57. piece(7,0,2)=0: piece(7,1,2)=1: piece(7,2,2)=0
  58. piece(7,0,3)=1: piece(7,1,3)=1: piece(7,2,3)=0
  59. piece(7,0,4)=1: piece(7,1,4)=0: piece(7,2,4)=0
  60.  
  61. piece(8,0,0)=0: piece(8,1,0)=0: piece(8,2,0)=0
  62. piece(8,0,1)=0: piece(8,1,1)=1: piece(8,2,1)=0
  63. piece(8,0,2)=0: piece(8,1,2)=1: piece(8,2,2)=0
  64. piece(8,0,3)=0: piece(8,1,3)=1: piece(8,2,3)=1
  65. piece(8,0,4)=0: piece(8,1,4)=0: piece(8,2,4)=1
  66.  
  67. piece(9,0,0)=0: piece(9,1,0)=0: piece(9,2,0)=0
  68. piece(9,0,1)=0: piece(9,1,1)=0: piece(9,2,1)=0
  69. piece(9,0,2)=1: piece(9,1,2)=1: piece(9,2,2)=1
  70. piece(9,0,3)=0: piece(9,1,3)=1: piece(9,2,3)=0
  71. piece(9,0,4)=0: piece(9,1,4)=1: piece(9,2,4)=0
  72.  
  73. piece(10,0,0)=0: piece(10,1,0)=0: piece(10,2,0)=0
  74. piece(10,0,1)=0: piece(10,1,1)=0: piece(10,2,1)=0
  75. piece(10,0,2)=0: piece(10,1,2)=0: piece(10,2,2)=0
  76. piece(10,0,3)=1: piece(10,1,3)=0: piece(10,2,3)=1
  77. piece(10,0,4)=1: piece(10,1,4)=1: piece(10,2,4)=1
  78.  
  79. piece(11,0,0)=0: piece(11,1,0)=0: piece(11,2,0)=0
  80. piece(11,0,1)=0: piece(11,1,1)=0: piece(11,2,1)=0
  81. piece(11,0,2)=0: piece(11,1,2)=0: piece(11,2,2)=1
  82. piece(11,0,3)=0: piece(11,1,3)=0: piece(11,2,3)=1
  83. piece(11,0,4)=1: piece(11,1,4)=1: piece(11,2,4)=1
  84.  
  85. piece(12,0,0)=0: piece(12,1,0)=0: piece(12,2,0)=0
  86. piece(12,0,1)=0: piece(12,1,1)=0: piece(12,2,1)=0
  87. piece(12,0,2)=0: piece(12,1,2)=0: piece(12,2,2)=1
  88. piece(12,0,3)=0: piece(12,1,3)=1: piece(12,2,3)=1
  89. piece(12,0,4)=1: piece(12,1,4)=1: piece(12,2,4)=0
  90.  
  91. piece(13,0,0)=0: piece(13,1,0)=0: piece(13,2,0)=0
  92. piece(13,0,1)=0: piece(13,1,1)=0: piece(13,2,1)=0
  93. piece(13,0,2)=0: piece(13,1,2)=1: piece(13,2,2)=0
  94. piece(13,0,3)=1: piece(13,1,3)=1: piece(13,2,3)=1
  95. piece(13,0,4)=0: piece(13,1,4)=1: piece(13,2,4)=0
  96.  
  97. piece(14,0,0)=0: piece(14,1,0)=0: piece(14,2,0)=0
  98. piece(14,0,1)=0: piece(14,1,1)=1: piece(14,2,1)=0
  99. piece(14,0,2)=1: piece(14,1,2)=1: piece(14,2,2)=0
  100. piece(14,0,3)=0: piece(14,1,3)=1: piece(14,2,3)=0
  101. piece(14,0,4)=0: piece(14,1,4)=1: piece(14,2,4)=0
  102.  
  103. piece(15,0,0)=0: piece(15,1,0)=0: piece(15,2,0)=0
  104. piece(15,0,1)=0: piece(15,1,1)=1: piece(15,2,1)=0
  105. piece(15,0,2)=0: piece(15,1,2)=1: piece(15,2,2)=1
  106. piece(15,0,3)=0: piece(15,1,3)=1: piece(15,2,3)=0
  107. piece(15,0,4)=0: piece(15,1,4)=1: piece(15,2,4)=0
  108.  
  109. piece(16,0,0)=0: piece(16,1,0)=0: piece(16,2,0)=0
  110. piece(16,0,1)=0: piece(16,1,1)=0: piece(16,2,1)=0
  111. piece(16,0,2)=0: piece(16,1,2)=1: piece(16,2,2)=1
  112. piece(16,0,3)=0: piece(16,1,3)=1: piece(16,2,3)=0
  113. piece(16,0,4)=1: piece(16,1,4)=1: piece(16,2,4)=0
  114.  
  115. piece(17,0,0)=0: piece(17,1,0)=0: piece(17,2,0)=0
  116. piece(17,0,1)=0: piece(17,1,1)=0: piece(17,2,1)=0
  117. piece(17,0,2)=1: piece(17,1,2)=1: piece(17,2,2)=0
  118. piece(17,0,3)=0: piece(17,1,3)=1: piece(17,2,3)=0
  119. piece(17,0,4)=0: piece(17,1,4)=1: piece(17,2,4)=1
  120.  
  121. screen _newimage(sw*size, sh*size, 32)
  122.  
  123. piece_color(0) = _rgb(255,0,0)
  124. piece_color(1) = _rgb(255,145,0)
  125. piece_color(2) = _rgb(255,200,211)
  126. piece_color(3) = _rgb(0,255,220)
  127. piece_color(4) = _rgb(0,230,255)
  128. piece_color(5) = _rgb(0,170,10)
  129. piece_color(6) = _rgb(0,250,20)
  130. piece_color(7) = _rgb(128,230,0)
  131. piece_color(8) = _rgb(80,150,0)
  132. piece_color(9) = _rgb(0,200,0)
  133. piece_color(10) = _rgb(50,160,170)
  134. piece_color(11) = _rgb(50,110,175)
  135. piece_color(12) = _rgb(50,50,175)
  136. piece_color(13) = _rgb(110,50,175)
  137. piece_color(14) = _rgb(210,0,255)
  138. piece_color(15) = _rgb(110,0,130)
  139. piece_color(16) = _rgb(255,0,140)
  140. piece_color(17) = _rgb(170,0,100)
  141.  
  142.  
  143. redraw = -1
  144.  
  145. speed = 2
  146. lines = 0
  147. pause = 0
  148. putpiece = 0
  149. startx = (sw - 4)/2
  150.  
  151. pn = int(rnd*18)
  152. px = startx
  153. py = -2
  154. rot = 0
  155.  
  156. title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  157. _title title$
  158.  
  159. t = timer
  160.  
  161.         if (timer - t) > (1/speed) and not pause then
  162.                 if valid(pn, px, py + 1, rot) then py = py + 1 else putpiece = -1
  163.  
  164.                 t = timer
  165.                 redraw = -1
  166.         end if
  167.  
  168.         if putpiece then
  169.                 if valid(pn, px, py, rot) then
  170.                         n = place(pn, px, py, rot)
  171.                         if n then
  172.                                 lines = lines + n
  173.                                 title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  174.                                 _title title$
  175.                         end if
  176.                 end if
  177.  
  178.                 pn = int(rnd*18)
  179.                 px = startx
  180.                 py = -2
  181.                 rot = 0
  182.  
  183.                 putpiece = 0
  184.                 redraw = -1
  185.  
  186.                 if not valid(pn, px, py, rot) then
  187.                         for y=0 to sh-1
  188.                                 for x=0 to sw-1
  189.                                         board(x, y) = 0
  190.                                 next
  191.                         next
  192.                         lines = 0
  193.                         title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  194.                         _title title$
  195.                 end if
  196.         end if
  197.  
  198.         if redraw then
  199.                 line (0,0)-(sw*size, sh*size),_rgb(0,0,0),bf
  200.                 for y=0 to sh - 1
  201.                         for x=0 to sw - 1
  202.                                 if board(x, y) <> 0 then
  203.                                         line (x*size, y*size)-step(size-2, size-2), piece_color(board(x, y)-1), bf
  204.                                 else
  205.                                         line (x*size, y*size)-step(size-2, size-2), _rgb(50,50,50), b
  206.                                 end if
  207.                         next
  208.                 next
  209.  
  210.                 for y=0 to 4
  211.                         for x=0 to 2
  212.                                 rotate xx, yy, x, y, pn, rot
  213.                                 if piece(pn, x, y) then line ((px + xx)*size, (py + yy)*size)-step(size-2, size-2), piece_color(pn), bf
  214.                         next
  215.                 next
  216.  
  217.                 _display
  218.                 redraw = 0
  219.         end if
  220.  
  221.         k = _keyhit
  222.         if k then
  223.                 shift = _keydown(100304) or _keydown(100303)
  224.                 select case k
  225.                 case 18432 'up
  226.                         if valid(pn, px, py, (rot + 1) mod 4) then rot = (rot + 1) mod 4
  227.                         pause = 0
  228.                 case 19200 'left
  229.                         if shift then
  230.                                 for xx=0 to sw-1
  231.                                         if not valid(pn, px - xx, py, rot) then exit for
  232.                                 next
  233.                                 px = px - xx + 1
  234.                         else
  235.                                 if valid(pn, px - 1, py, rot) then px = px - 1
  236.                         end if
  237.                         pause = 0
  238.                 case 19712 'right
  239.                         if shift then
  240.                                 for xx=px to sw-1
  241.                                         if not valid(pn, xx, py, rot) then exit for
  242.                                 next
  243.                                 px = xx - 1
  244.                         else
  245.                                 if valid(pn, px + 1, py, rot) then px = px + 1
  246.                         end if
  247.                         pause = 0
  248.                 case 20480, 32 'down
  249.                         if shift or k = 32 then
  250.                                 for yy=py to sh-1
  251.                                         if not valid(pn, px, yy, rot) then exit for
  252.                                 next
  253.                                 py = yy - 1
  254.                                 putpiece = -1
  255.                         else
  256.                                 if valid(pn, px, py + 1, rot) then py = py + 1
  257.                         end if
  258.                         pause = 0
  259.                 case 112 'p
  260.                         pause = not pause
  261.                 case 13 'enter
  262.                         for y=0 to sh-1
  263.                                 for x=0 to sw-1
  264.                                         board(x, y) = 0
  265.                                 next
  266.                         next
  267.                         pn = int(rnd*17)
  268.                         px = startx
  269.                         py = -2
  270.                         rot = 0
  271.                         putpiece = 0
  272.                         lines = 0
  273.                         title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  274.                         _title title$
  275.                 case 43, 61 'plus
  276.                         if speed < 100 then
  277.                                 speed = speed + 1
  278.                                 title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  279.                                 _title title$
  280.                         end if
  281.                 case 95, 45
  282.                         if speed > 1 then
  283.                                 speed = speed - 1
  284.                                 title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  285.                                 _title title$
  286.                         end if
  287.                 case 27
  288.                         exit do
  289.                 end select
  290.  
  291.                 redraw = -1
  292.         end if
  293.  
  294.  
  295. sub rotate(xx, yy, x, y, pn, rot)
  296.         select case pn
  297.         case 0
  298.                 rot_new = rot mod 2
  299.         case else
  300.                 rot_new = rot
  301.         end select
  302.  
  303.         select case rot_new
  304.         case 0
  305.                 xx = x
  306.                 yy = y
  307.         case 1
  308.                 if pn = 0 then
  309.                         xx = y - 1
  310.                         yy = 3 - x
  311.                 elseif pn = 14 or pn = 15 then
  312.                         xx = y - 1
  313.                         yy = 3 - x
  314.                 else
  315.                         xx = y - 2
  316.                         yy = 4 - x
  317.                 end if
  318.         case 2
  319.                 if pn = 14 or pn = 15 then
  320.                         xx = 2 - x
  321.                         yy = 4 - y
  322.                 else
  323.                         xx = 2 - x
  324.                         yy = 6 - y
  325.                 end if
  326.         case 3
  327.                 if pn = 14 or pn = 15 then
  328.                         xx = 3 - y
  329.                         yy = x + 1
  330.                 else
  331.                         xx = 4 - y
  332.                         yy = x + 2
  333.                 end if
  334.         end select
  335.  
  336. function valid(pn, px, py, rot)
  337.         for y=0 to 4
  338.                 for x=0 to 2
  339.                         rotate xx, yy, x, y, pn, rot
  340.                         if py + yy >= 0 then
  341.                                 if piece(pn, x, y) then
  342.                                         if (px + xx >= sw) or (px + xx < 0) then
  343.                                                 valid = 0
  344.                                                 exit function
  345.                                         end if
  346.                                         if (py + yy >= sh) then
  347.                                                 valid = 0
  348.                                                 exit function
  349.                                         end if
  350.                                         'if (py >= 0) then
  351.                                         if board(px + xx, py + yy) then
  352.                                                 valid = 0
  353.                                                 exit function
  354.                                         end if
  355.                                         'end if
  356.                                 end if
  357.                         end if
  358.                 next
  359.         next
  360.  
  361.         valid = -1
  362.  
  363. function place(pn, px, py, rot)
  364.         lines = 0
  365.  
  366.         for y=0 to 4
  367.                 for x=0 to 2
  368.                         rotate xx, yy, x, y, pn, rot
  369.                         if py + yy >= 0 then if piece(pn, x, y) then board(px + xx, py + yy) = pn + 1
  370.                 next
  371.         next
  372.  
  373.         'clear lines
  374.         for y=py-5 to py+5
  375.                 if y>=0 and y<sh then
  376.                         clr = -1
  377.                         for x=0 to sw - 1
  378.                                 if board(x, y) = 0 then
  379.                                         clr = 0
  380.                                         exit for
  381.                                 end if
  382.                         next
  383.  
  384.                         if clr then
  385.                                 lines = lines + 1
  386.                                 for yy=y to 1 step -1
  387.                                         for x=0 to sw-1
  388.                                                 board(x, yy) = board(x, yy-1)
  389.                                         next
  390.                                 next
  391.                         end if
  392.                 end if
  393.         next
  394.  
  395.         place = lines
  396.  

14
Programs / Tetris
« on: September 24, 2018, 04:06:21 pm »
clean and simple tetris implementation. you can change variables size, sw, and sh for custom board sizes.

controls:
* arrow keys: movement, up: rotate
* shift + left/right/down: hard left/right/drop
* spacebar: hard drop
* +/-: change speed
* p: pause
* Enter: restart
* Esc: quit

Code: QB64: [Select]
  1. deflng a-z
  2.  
  3. dim shared piece(6, 3, 1)
  4. dim shared piece_color(6)
  5. dim shared size, sw, sh
  6.  
  7. size = 35
  8. sw = 10
  9. sh = 20
  10.  
  11. redim shared board(sw - 1, sh - 1)
  12.  
  13. piece(0,0,0)=0: piece(0,1,0)=1: piece(0,2,0)=1: piece(0,3,0)=0
  14. piece(0,0,1)=0: piece(0,1,1)=1: piece(0,2,1)=1: piece(0,3,1)=0
  15. piece(1,0,0)=1: piece(1,1,0)=1: piece(1,2,0)=1: piece(1,3,0)=1
  16. piece(1,0,1)=0: piece(1,1,1)=0: piece(1,2,1)=0: piece(1,3,1)=0
  17. piece(2,0,0)=0: piece(2,1,0)=0: piece(2,2,0)=1: piece(2,3,0)=1
  18. piece(2,0,1)=0: piece(2,1,1)=1: piece(2,2,1)=1: piece(2,3,1)=0
  19. piece(3,0,0)=0: piece(3,1,0)=1: piece(3,2,0)=1: piece(3,3,0)=0
  20. piece(3,0,1)=0: piece(3,1,1)=0: piece(3,2,1)=1: piece(3,3,1)=1
  21. piece(4,0,0)=0: piece(4,1,0)=1: piece(4,2,0)=1: piece(4,3,0)=1
  22. piece(4,0,1)=0: piece(4,1,1)=0: piece(4,2,1)=1: piece(4,3,1)=0
  23. piece(5,0,0)=0: piece(5,1,0)=1: piece(5,2,0)=1: piece(5,3,0)=1
  24. piece(5,0,1)=0: piece(5,1,1)=1: piece(5,2,1)=0: piece(5,3,1)=0
  25. piece(6,0,0)=0: piece(6,1,0)=1: piece(6,2,0)=1: piece(6,3,0)=1
  26. piece(6,0,1)=0: piece(6,1,1)=0: piece(6,2,1)=0: piece(6,3,1)=1
  27.  
  28. screen _newimage(sw*size, sh*size, 32)
  29.  
  30. piece_color(0) = _rgb(0,200,0)
  31. piece_color(1) = _rgb(200,0,0)
  32. piece_color(2) = _rgb(156,85,211)
  33. piece_color(3) = _rgb(219,112,147)
  34. piece_color(4) = _rgb(0,100,250)
  35. piece_color(5) = _rgb(230,197,92)
  36. piece_color(6) = _rgb(0,128,128)
  37.  
  38.  
  39. redraw = -1
  40.  
  41. speed = 10
  42. lines = 0
  43. pause = 0
  44. putpiece = 0
  45. startx = (sw - 4)/2
  46.  
  47. pn = int(rnd*7)
  48. px = startx
  49. py = 1
  50. rot = 0
  51.  
  52. title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  53. _title title$
  54.  
  55. t = timer
  56.  
  57.         if (timer - t) > (1/speed) and not pause then
  58.                 if valid(pn, px, py + 1, rot) then py = py + 1 else putpiece = -1
  59.  
  60.                 t = timer
  61.                 redraw = -1
  62.         end if
  63.  
  64.         if putpiece then
  65.                 if valid(pn, px, py, rot) then
  66.                         n = place(pn, px, py, rot)
  67.                         if n then
  68.                                 lines = lines + n
  69.                                 title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  70.                                 _title title$
  71.                         end if
  72.                 end if
  73.  
  74.                 pn = int(rnd*7)
  75.                 px = startx
  76.                 py = 0
  77.                 rot = 0
  78.  
  79.                 putpiece = 0
  80.                 redraw = -1
  81.  
  82.                 if not valid(pn, px, py, rot) then
  83.                         for y=0 to sh-1
  84.                                 for x=0 to sw-1
  85.                                         board(x, y) = 0
  86.                                 next
  87.                         next
  88.                         lines = 0
  89.                         title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  90.                         _title title$
  91.                 end if
  92.         end if
  93.  
  94.         if redraw then
  95.                 line (0,0)-(sw*size, sh*size),_rgb(0,0,0),bf
  96.                 for y=0 to sh - 1
  97.                         for x=0 to sw - 1
  98.                                 if board(x, y) <> 0 then
  99.                                         line (x*size, y*size)-step(size-2, size-2), piece_color(board(x, y)-1), bf
  100.                                 else
  101.                                         line (x*size, y*size)-step(size-2, size-2), _rgb(50,50,50), b
  102.                                 end if
  103.                         next
  104.                 next
  105.  
  106.                 for y=0 to 1
  107.                         for x=0 to 3
  108.                                 rotate xx, yy, x, y, pn, rot
  109.                                 if piece(pn, x, y) then line ((px + xx)*size, (py + yy)*size)-step(size-2, size-2), piece_color(pn), bf
  110.                         next
  111.                 next
  112.  
  113.                 _display
  114.                 redraw = 0
  115.         end if
  116.  
  117.         k = _keyhit
  118.         if k then
  119.                 shift = _keydown(100304) or _keydown(100303)
  120.                 select case k
  121.                 case 18432 'up
  122.                         if valid(pn, px, py, (rot + 1) mod 4) then rot = (rot + 1) mod 4
  123.                         pause = 0
  124.                 case 19200 'left
  125.                         if shift then
  126.                                 for xx=0 to sw-1
  127.                                         if not valid(pn, px - xx, py, rot) then exit for
  128.                                 next
  129.                                 px = px - xx + 1
  130.                         else
  131.                                 if valid(pn, px - 1, py, rot) then px = px - 1
  132.                         end if
  133.                         pause = 0
  134.                 case 19712 'right
  135.                         if shift then
  136.                                 for xx=px to sw-1
  137.                                         if not valid(pn, xx, py, rot) then exit for
  138.                                 next
  139.                                 px = xx - 1
  140.                         else
  141.                                 if valid(pn, px + 1, py, rot) then px = px + 1
  142.                         end if
  143.                         pause = 0
  144.                 case 20480, 32 'down
  145.                         if shift or k = 32 then
  146.                                 for yy=py to sh-1
  147.                                         if not valid(pn, px, yy, rot) then exit for
  148.                                 next
  149.                                 py = yy - 1
  150.                                 putpiece = -1
  151.                         else
  152.                                 if valid(pn, px, py + 1, rot) then py = py + 1
  153.                         end if
  154.                         pause = 0
  155.                 case 112 'p
  156.                         pause = not pause
  157.                 case 13 'enter
  158.                         for y=0 to sh-1
  159.                                 for x=0 to sw-1
  160.                                         board(x, y) = 0
  161.                                 next
  162.                         next
  163.                         pn = int(rnd*7)
  164.                         px = startx
  165.                         py = 0
  166.                         rot = 0
  167.                         putpiece = 0
  168.                         lines = 0
  169.                         title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  170.                         _title title$
  171.                 case 43, 61 'plus
  172.                         if speed < 100 then
  173.                                 speed = speed + 1
  174.                                 title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  175.                                 _title title$
  176.                         end if
  177.                 case 95, 45
  178.                         if speed > 1 then
  179.                                 speed = speed - 1
  180.                                 title$ = "lines="+ltrim$(str$(lines))+",speed="++ltrim$(str$(speed))
  181.                                 _title title$
  182.                         end if
  183.                 case 27
  184.                         exit do
  185.                 end select
  186.  
  187.                 redraw = -1
  188.         end if
  189.  
  190. sub rotate(xx, yy, x, y, pn, rot)
  191.         select case pn
  192.         case 0
  193.                 rot_new = 0
  194.         case 1 to 3
  195.                 rot_new = rot mod 2
  196.         case 4 to 6
  197.                 rot_new = rot
  198.         end select
  199.  
  200.         select case rot_new
  201.         case 0
  202.                 xx = x
  203.                 yy = y
  204.         case 1
  205.                 xx = y + 2
  206.                 yy = 2 - x
  207.         case 2
  208.                 xx = 4 - x
  209.                 yy = 1 - y
  210.         case 3
  211.                 xx = 2 - y
  212.                 yy = x - 1
  213.         end select
  214.  
  215. function valid(pn, px, py, rot)
  216.         for y=0 to 1
  217.                 for x=0 to 3
  218.                         rotate xx, yy, x, y, pn, rot
  219.                         if py + yy >= 0 then
  220.                                 if piece(pn, x, y) then
  221.                                         if (px + xx >= sw) or (px + xx < 0) then
  222.                                                 valid = 0
  223.                                                 exit function
  224.                                         end if
  225.                                         if (py + yy >= sh) then
  226.                                                 valid = 0
  227.                                                 exit function
  228.                                         end if
  229.                                         if (py >= 0) then
  230.                                         if board(px + xx, py + yy) then
  231.                                                 valid = 0
  232.                                                 exit function
  233.                                         end if
  234.                                         end if
  235.                                 end if
  236.                         end if
  237.                 next
  238.         next
  239.  
  240.         valid = -1
  241.  
  242. function place(pn, px, py, rot)
  243.         lines = 0
  244.  
  245.         for y=0 to 1
  246.                 for x=0 to 3
  247.                         rotate xx, yy, x, y, pn, rot
  248.                         if py + yy >= 0 then if piece(pn, x, y) then board(px + xx, py + yy) = pn + 1
  249.                 next
  250.         next
  251.  
  252.         'clear lines
  253.         for y=py-1 to py+2
  254.                 if y>=0 and y<sh then
  255.                         clr = -1
  256.                         for x=0 to sw - 1
  257.                                 if board(x, y) = 0 then
  258.                                         clr = 0
  259.                                         exit for
  260.                                 end if
  261.                         next
  262.  
  263.                         if clr then
  264.                                 lines = lines + 1
  265.                                 for yy=y to 1 step -1
  266.                                         for x=0 to sw-1
  267.                                                 board(x, yy) = board(x, yy-1)
  268.                                         next
  269.                                 next
  270.                         end if
  271.                 end if
  272.         next
  273.  
  274.         place = lines
  275.  

15
QB64 Discussion / interesting plot
« on: July 23, 2018, 07:12:33 pm »
Code: QB64: [Select]
  1. deflng a-z
  2. for u=0 to 640
  3.         uu=2.8 + 1.2*u/640
  4.         for x=0 to 480
  5.                 xx = x/480
  6.                 for i=0 to 500
  7.                         xx = uu*xx*(1-xx)
  8.                 next
  9.                 pset(u,480*(1-xx))
  10.         next
  11.  
  12.  

Pages: [1] 2