#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Show a bandlimited Dirac comb.

I think I may have gotten something wrong here, because adding more
harmonics doesn’t shrink the envelope of the waves, it just increases
the apparent frequency of the oscillations.

...but I think that’s probably because you need *all* the harmonics, at which
point it does indeed give you a single-cycle impulse.

"""
from pygame import *
import Numeric

init()
screen = display.set_mode((0, 0)) # , FULLSCREEN)
ww, hh = screen.get_size()
xx = 0
font_size = 24
font = font.Font(None, font_size)

while True:
    ev = event.poll()
    if ev.type in (QUIT, MOUSEBUTTONDOWN):
        break
    elif ev.type == MOUSEMOTION:
        xx, yy = ev.pos
    elif ev.type == NOEVENT:
        pix_xs = Numeric.arange(ww)
        xs = (pix_xs - ww/2) / ((ww/2) / Numeric.pi)
        harmonics = range(1 + xx)
        scale = hh/2 - yy
        cs = sum(Numeric.cos(xs * ii) for ii in harmonics)
        pointlist = zip(pix_xs, hh/2 - cs * scale)

        #sins = sum(Numeric.sin(xs * ii) for ii in harmonics)
        
        formulas = []
        current_formula = '%d * (' % scale
        for harmonic in harmonics:
            if harmonic != 0:
                current_formula += ' + '
            current_formula += 'cos %dx' % harmonic
            if harmonic % 12 == 11:
                formulas.append(current_formula)
                current_formula = ''
        current_formula += ')'
        formulas.append(current_formula)

        screen.fill(0)

        texty = font_size / 2
        for formula in formulas:
            screen.blit(font.render(formula, 1, Color('red')), (font_size/2,
                                                                texty))
            texty += font_size
            
        draw.aalines(screen, Color('white'), False, pointlist)
        #draw.aalines(screen, Color('White'), False, zip(pix_xs,
        #                                                hh/4 - sins * scale))
        draw.line(screen, Color(64,64,64,255), (0, hh/2), (ww-1, hh/2))
        display.flip()

