local enumerations = require 'enumerations' local twintree = require 'twintree' local step = coroutine.wrap( twintree.buildIncremental ) local a = enumerations.Dyad() local b = enumerations.SternBrocot() step( a, b ) --Use LOVE for plotting. local love = assert( love ) local canvas = love.graphics.newCanvas() local numMapped, pointList = 0 local function new() pointList = step() numMapped = #pointList / 2 end local cx, cy = 0.0, 0.0 local zoomFactor = 1 local function zoom( out ) cx = cx + 0.5 * ( out - 1 ) / ( out * zoomFactor ) cy = cy + 0.5 * ( out - 1 ) / ( out * zoomFactor ) zoomFactor = zoomFactor * out love.graphics.setLineWidth( 0.005 / zoomFactor ) end local function paint() if not pointList then return end numMapped = #pointList / 2 local type = type --Make sure the whole point list consists of numbers! --We use the __call metamethod in non-number elements to coerce to numbers. --TODO: make this more generic, maybe amenable to FFI types. for i = 1, #pointList do if type( pointList[i] ) ~= 'number' then pointList[i] = pointList[i]( pointList[i] ) end end --print( "Points: " ) --for i = 1, #pointList - 1, 2 do -- print(pointList[i], pointList[i + 1] ) --end love.graphics.setCanvas( canvas ) love.graphics.clear() love.graphics.print( ("%d\n%4.2f\n%4.2f\n%4.2f"):format( numMapped, cx, cy, zoomFactor ) ) love.graphics.push() love.graphics.scale( love.graphics.getWidth(), love.graphics.getHeight() ) love.graphics.translate( 0, 1 ) love.graphics.scale( 1, -1 ) love.graphics.scale( zoomFactor, zoomFactor ) love.graphics.translate( -cx, -cy ) love.graphics.setColor( 1, 1, 1, 0.3 ) love.graphics.line( 0,0, 1,0 ) love.graphics.line( 0,0, 0,1 ) love.graphics.line( 0, 0, 1, 1 ) love.graphics.line( pointList ) love.graphics.setColor( 1, 0, 0, 0.1 * zoomFactor ) love.graphics.points( pointList ) love.graphics.pop() love.graphics.setCanvas() end function love.wheelmoved( x, y ) zoom( ( y > 0 ) and 1.01 or 0.99 ) paint() end function love.mousepressed() --pointList = twintree.flat( twintree.build( 10000, a, b ) ) --numMapped = #pointList / 2 paint() end function love.draw() love.graphics.setCanvas() love.graphics.setColor( 1, 1, 1, 1 ) love.graphics.draw( canvas ) end function love.update( dt ) local repaint = false if love.keyboard.isScancodeDown "r" then repaint = true; new() end if love.keyboard.isScancodeDown "a" then repaint = true; cx = cx - dt * 0.1 / math.sqrt( zoomFactor ) end if love.keyboard.isScancodeDown "d" then repaint = true; cx = cx + dt * 0.1 / math.sqrt( zoomFactor ) end if love.keyboard.isScancodeDown "w" then repaint = true; cy = cy + dt * 0.1 / math.sqrt( zoomFactor ) end if love.keyboard.isScancodeDown "s" then repaint = true; cy = cy - dt * 0.1 / math.sqrt( zoomFactor ) end if love.keyboard.isScancodeDown "q" then repaint = true; zoom( 1 + dt ) end if love.keyboard.isScancodeDown "e" then repaint = true; zoom( 1 - dt ) end if love.keyboard.isScancodeDown "space" then repaint = true; pointList = twintree.flat( twintree.build( 10000, a, b ) ) end if repaint then return paint() end end function love.keypressed( key, code, isrepeat) return paint() end function love.load() pointList = twintree.flat( twintree.build( 10000, a, b ) ) numMapped = #pointList / 2 love.graphics.setPointSize( 3 ) love.graphics.setLineWidth( 0.005 ) paint() end