This is my first attempt at some Codea goodness (so be gentle), based on some old basic stuff I once wrote.

It displays an animated SIN function in an isometric grid, with the centre of the function being touch. It supports multi touch so you can do multiple waves to look at interference patterns.

```
-- 3d sin
-- Use this function to perform your initial setup
function setup()
parameter("speed", 0, 0.5,0.1)
parameter("wavelength", -1.5,-0.25,-.7)
gridSize = 30
isoW = 20*math.cos(math.rad(30))
isoH = 20*math.sin(math.rad(30))
heights = {}
coords = {}
touches = {}
cens = {}
for x = 1,gridSize do
heights[x] = {}
coords[x] = {}
for y = 1,gridSize do
heights[x][y] = 0
coords[x][y] = {x = WIDTH/2+(x-y)*isoW, y = 50+(x+y)*isoH}
end
end
offset = 0
end
function touched(touch)
if touch.state == ENDED then
else
cens[touch.id] = { x = ((touch.x - WIDTH/2)/isoW + (touch.y-50)/isoH)/2, y = ((touch.y-50)/isoH - (touch.x - WIDTH/2)/isoW)/2, t = os.clock() }
end
for k, touch in pairs(cens) do
if os.clock() - touch.t > 1 then
cens[k] = nil
end
end
end
-- This function gets called once every frame
function draw()
for x = 1,gridSize do
for y = 1,gridSize do
heights[x][y] = 0
for k, touch in pairs(cens) do
heights[x][y] = heights[x][y] + math.sin((math.sqrt((touch.x-x)^2+(touch.y-y)^2)*wavelength)+offset)*20
end
end
end
offset = offset + speed
-- This sets a dark background color
background(40, 40, 50)
-- This sets the line thickness
noSmooth()
noStroke()
-- Do your drawing here
for x = 1,(gridSize-1) do
for y = 1,(gridSize-1) do
line(coords[x][y].x, coords[x][y].y+heights[x][y], coords[x+1][y].x, coords[x+1][y].y+heights[x+1][y])
line(coords[x][y].x, coords[x][y].y+heights[x][y], coords[x][y+1].x, coords[x][y+1].y+heights[x][y+1])
end
end
end
```