Fourier Series

Messing about with Fourier Series visualisations. Adjust the values to make pretty patterns.

-- Fourier
-- by West
-- visualisation of the path taken by a Fourier Series as a complex exponential.  Top left adds and removes harmonics. Top right changes the frequency (the lower frequency takes longer to draw but has more points). The bar across the bottom sets the amplitude of each component.
--Tap in the centre to reset the trail

displayMode(FULLSCREEN_NO_BUTTONS)

-- Use this function to perform your initial setup
function setup()
    x=WIDTH/2
    y=HEIGHT*0.6
    t=0
    f=30
    a={100,50}
    bga=2
end

function draw()
    t = t + 0.0001
    fill(0,bga)
    if bga>2 then bga=bga-10 end
    rect(0,0,WIDTH,HEIGHT)
    x=WIDTH/2
    y=HEIGHT*0.6
    for i=1,#a do
        x=x+a[i]*math.sin(2*math.pi*i*f*t-math.pi/2)
        y=y+a[i]*math.cos(2*math.pi*i*f*t-math.pi/2)
    end
    sprite("Cargo Bot:Star Filled",x,y,20,20)
    for i=1,#a do
        local div=WIDTH/#a
        local  tx=div/2+(i-1)*div
        ty=0.1*HEIGHT
        if math.fmod(i,2)==0 then
            fill(30)
        else
            fill(40)
        end
        rect(tx-div/2,0,div,HEIGHT*0.2)
        fill(255)
        text(math.floor(a[i]),tx,ty)
    end
    fill(60,0,0)
    rect(0,HEIGHT*0.9,WIDTH*0.1,HEIGHT*0.1)
    fill(0,60,0)
    rect(0.1*WIDTH,HEIGHT*0.9,WIDTH*0.1,HEIGHT*0.1)
    fill(60,0,0)
    rect(0.8*WIDTH,HEIGHT*0.9,WIDTH*0.1,HEIGHT*0.1)
    fill(0,60,0)
    rect(0.9*WIDTH,HEIGHT*0.9,WIDTH*0.1,HEIGHT*0.1)
    fill(255)
    font("Copperplate-Bold")
    fontSize(40)
    text("-",WIDTH*0.05,HEIGHT*0.95)
    text("+",WIDTH*0.15,HEIGHT*0.95)
    text("f-",WIDTH*0.85,HEIGHT*0.95)
    text("f+",WIDTH*0.95,HEIGHT*0.95)
    text("Frequency:"..f,WIDTH*0.5,HEIGHT*0.95)
    
end

function touched(t)
    if t.state==ENDED then
        if t.y>0.9*HEIGHT and t.x<0.1*WIDTH then
            if #a>1 then
                table.remove(a,#a)
            end
        elseif t.y>0.9*HEIGHT and t.x<0.2*WIDTH then
            table.insert(a,0)
        elseif t.y>0.9*HEIGHT and t.x>0.9*WIDTH then
            f=f+1
        elseif t.y>0.9*HEIGHT and t.x>0.8*WIDTH then
            f=f-1
        end
    end
    for i=1,#a do
        local div=WIDTH/#a
        local  lx=(i-1)*div
        local  rx=(i)*div
        if t.x>lx and t.x<rx then
            if t.y<0.1*HEIGHT then
                a[i] = a[i] - 1
            elseif t.y<0.2*HEIGHT then
                a[i] = a[i] + 1
            else
                bga=255
            end
        end
    end
end

Now with the time series waveform included and launching with an approximation of a square wave


-- Fourier
-- by West
-- visualisation of the path taken by a Fourier Series as a complex exponential.  Top left adds and removes harmonics. Top right changes the frequency (the lower frequency takes longer to draw but has more points). The bar across the bottom sets the amplitude of each component.
--Tap in the centre to reset the trail

displayMode(FULLSCREEN_NO_BUTTONS)

-- Use this function to perform your initial setup
function setup()
    x=WIDTH/2
    y=HEIGHT*0.6
    t=0
    f=25
    a={100,0,100/3,0,100/5,0,100/7,0,100/9,0,100/11}
    bga=2
end

function draw()
    t = t + 0.0001
    fill(0,bga)
    if bga>2 then bga=bga-10 end
    rect(0,0,WIDTH,HEIGHT)
    x=WIDTH/4
    y=HEIGHT*0.6
    for i=1,#a do
        x=x+a[i]*math.cos(2*math.pi*i*f*t)
        y=y+a[i]*math.sin(2*math.pi*i*f*t)
    end
    sprite("Cargo Bot:Star Filled",x,y,20,20)
    local x2=f*0.3*WIDTH*math.fmod(t,1/f)+0.6*WIDTH
    if f<0 then
        x2 = x2 + 0.3*WIDTH
    end
    sprite("Cargo Bot:Star Filled",x2,y,20,20)
    for i=1,#a do
        local div=WIDTH/#a
        local  tx=div/2+(i-1)*div
        ty=0.1*HEIGHT
        if math.fmod(i,2)==0 then
            fill(30)
        else
            fill(40)
        end
        rect(tx-div/2,0,div,HEIGHT*0.2)
        fill(255)
        text(math.floor(a[i]),tx,ty)
    end
    fill(60,0,0)
    rect(0,HEIGHT*0.9,WIDTH*0.1,HEIGHT*0.1)
    fill(0,60,0)
    rect(0.1*WIDTH,HEIGHT*0.9,WIDTH*0.1,HEIGHT*0.1)
    fill(60,0,0)
    rect(0.8*WIDTH,HEIGHT*0.9,WIDTH*0.1,HEIGHT*0.1)
    fill(0,60,0)
    rect(0.9*WIDTH,HEIGHT*0.9,WIDTH*0.1,HEIGHT*0.1)
    fill(255)
    font("Copperplate-Bold")
    fontSize(40)
    text("-",WIDTH*0.05,HEIGHT*0.95)
    text("+",WIDTH*0.15,HEIGHT*0.95)
    text("f-",WIDTH*0.85,HEIGHT*0.95)
    text("f+",WIDTH*0.95,HEIGHT*0.95)
    text("Frequency:"..f,WIDTH*0.5,HEIGHT*0.95)
    
end

function touched(t)
    if t.state==ENDED then
        if t.y>0.9*HEIGHT and t.x<0.1*WIDTH then
            if #a>1 then
                table.remove(a,#a)
            end
        elseif t.y>0.9*HEIGHT and t.x<0.2*WIDTH then
            table.insert(a,0)
        elseif t.y>0.9*HEIGHT and t.x>0.9*WIDTH then
            f=f+1
        elseif t.y>0.9*HEIGHT and t.x>0.8*WIDTH then
            f=f-1
        end
    end
    for i=1,#a do
        local div=WIDTH/#a
        local  lx=(i-1)*div
        local  rx=(i)*div
        if t.x>lx and t.x<rx then
            if t.y<0.1*HEIGHT then
                a[i] = a[i] - 1
            elseif t.y<0.2*HEIGHT then
                a[i] = a[i] + 1
            else
                bga=255
            end
        end
    end
end