Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Function plotter

edited May 2012 in Code Sharing Posts: 85

It's my first Codea program. You can zoom and pan with your fingers. The grid can be deactivated. You can write your own functions in "function fn(x)".


function fn(x)     return math.sin(x*2) + math.sin(x) end function setup()     center=vec2(WIDTH/2,HEIGHT/2)     pos=vec2(0,0)     size=100     touches = {}     lineCapMode(2)     --noSmooth()     iparameter("Grid",0,1,1)     --watch("myW") end function draw()     local fnI, prevI, prevFnI, move, dist     left=fromScreen(vec2(0,0))     right=fromScreen(vec2(WIDTH,0))     top=fromScreen(vec2(0,HEIGHT))     bottom=fromScreen(vec2(0,0))     background(0, 0, 0, 255)          drawAxis()              --draw function     stroke(101, 239, 18, 255)     strokeWidth(4)     prevI = nil     for i = left.x, right.x, (right.x-left.x)/700 do         fnI = fn(i)         if (prevI~=nil) then myLine(vec2(i,fnI),vec2(prevI,prevFnI)) end         prevI = i         prevFnI = fnI     end          --zooming and moving     n = nbTouches()     if(n==1) then         move = vec2(CurrentTouch.prevX-CurrentTouch.x,CurrentTouch.prevY-CurrentTouch.y)         pos = pos - move/size         zooming=false     elseif(n==2) then         if (zooming==true) then             size=size0*distanceBetweenFingers()/dist0             move = vec2(CurrentTouch.prevX-CurrentTouch.x,CurrentTouch.prevY-CurrentTouch.y)             pos = pos - move/size         else             zooming=true             dist0=distanceBetweenFingers()             size0=size         end     else         zooming=false         end end function touched(touch)     if touch.state == ENDED then         touches[touch.id] = nil     else         touches[touch.id] = touch     end end function nbTouches()     local n     n=0     for i,j in pairs(touches) do         n = n + 1     end     return n end function distanceBetweenFingers()     local v, sign     v=vec2(0,0)     sign=1     for i,j in pairs(touches) do         v=v+vec2(j.x,j.y)*sign         sign=-1     end     return v:len() end function toScreen(v)     return center + (v + pos) * size end function fromScreen(v)     return (v - center) / size - pos end function myLine(va,vb)     local v1,v2     v1 = toScreen(va)     v2 = toScreen(vb)     line(v1.x,v1.y,v2.x,v2.y) end function drawAxis()     local v,i     stroke(38, 0, 255, 255)     strokeWidth(4)     i=fromScreen(vec2(60,0)).x - fromScreen(vec2(0,0)).x     i=nearestInterval(i)          for x=math.floor(left.x/i)*i,right.x,i do         v=toScreen(vec2(x,0))         gridVerLine(v.x)         line(v.x,v.y+5,v.x,v.y-5)         text(x,v.x-15,v.y-10)     end     for y=math.floor(bottom.y/i)*i,top.y,i do         v=toScreen(vec2(0,y))         gridHorLine(v.y)         line(v.x+5,v.y,v.x-5,v.y)         text(y,v.x-15,v.y-10)     end     stroke(38, 0, 255, 255)     strokeWidth(4)     myLine(vec2(-1000000,0),vec2(1000000,0))     myLine(vec2(0,-1000000),vec2(0,1000000)) end function gridVerLine(x)     if (Grid == 0) then return end     pushStyle()     stroke(92, 87, 99, 255)     line(x,0,x,HEIGHT)     popStyle() end function gridHorLine(y)     if (Grid == 0) then return end     pushStyle()     stroke(92, 87, 99, 255)     line(0,y,WIDTH,y)     popStyle() end function nearestInterval(n)     local i1, i2, i3     i=1     i2=2.5     i3=5          while true do         if(n>i and n<i*10)then break         elseif(n<i) then i=i/10         else i=i*10         end     end     if (n>i and n<i2*i) then return(i)     elseif (n>i2*i and n<i3*i) then return(i2*i)     else return(i3*i)     end end

BTW, how can I insert images in my posts?

Tagged:

Comments

  • Posts: 85

    I have a problem with my program. When I print the labels of the axis in intervals of 0.1 the maths of Codea don't seem to work well. Look at this code:

        i=0.1
        x=-1
        for n=1,11 do
            x = x + i
            print(x)
        end
    

    It should print:
    -0.9
    -0.8
    -0.7
    -0.6
    -0.5
    -0.4
    -0.3
    -0.2
    -0.1
    0
    0.1

    Instead it prints:
    -0.9
    -0.8
    -0.7
    -0.6
    -0.5
    -0.4
    -0.3
    -0.2
    -0.0999999
    7.45058e-08
    0.1

    Any ideas?

  • Posts: 80

    Good work, nice Tool you made!

    Your problem could have st. to do with the internal number type? Maybe theres a rounding function to solve this? Does'nt look like you've done something wrong...

  • Posts: 115

    Nice work, pepinganos. Thanks for sharing. I learn a lot from people like you posting code.

  • SimeonSimeon Admin Mod
    Posts: 5,613

    @pepinganos that's one of the problems with floating point number representations. The binary form of 0.1 in floating point is an infinitely repeating sequence — so it gets rounded to the nearest decimal representation, which can become 0.0999999 due to rounding errors through multiple additions. (It's not specific to Codea, it's just how 32bit floating point works on most CPUs.)

  • Posts: 85

    Thank you for your answers. I've tried the same loop with these values with much worse errors when the x aproches zero:

        i=0.1
        x=-4
        for n=1,42 do
            x = x + i
            print(x)
        end
    

    How can I include videos and pictures in posts?

Sign In or Register to comment.