Lasso tool

Here is my latest code example. This is similar to the lasso tool in most photo editors. I’m displaying the largest sprite that’s available in Codea and drawing 50 random dots on it just to give it more color. You can change the sprite to whatever you have in your Dropbox. Drag your finger in a circle, triangle, square or anything else to create an area to cut. Keep it small to begin with because the larger the lasso area, the longer it will take. Once you lift your finger, the cut image will be created and appear at the top of the screen. You can then drag the cut area around the screen. I didn’t add any code to paste the image back into the original image. One thing that I’m puzzled by is that some cut images have a thin black border while sometimes they don’t. @letaief, this may be what you were asking about that got me started on this program. Use the replay button to restart the program.

EDIT: I just realized I’m not including the first point. I have to figure out what’s wrong.
EDIT: Fixed. Added function highLow. I wasn’t checking the first point for being high, low. Whole program replaced with new one.


displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT)

function setup()
    pointDist=30    -- don't draw lasso points closer than 30 pixels to last one
    
    lowX=WIDTH    -- high, low lasso x,y boundary area
    highX=0
    lowY=HEIGHT
    highY=0
    
    vertex={}    -- table of x,y verticies
    cutColor={}    -- table of cut color value
    cutXY={}    -- table of cut x,y position
    
    cx=WIDTH/2    -- initial x,y point of cut area
    cy=HEIGHT-200
        
    drawLasso=true
    img=readImage("SpaceCute:Background")
    setContext(img)
    
    -- draw random dots on image
    for z=1,50 do
        fill(255,0,0,150)
        ellipse(math.random(img.width),math.random(img.height),20,20)
    end
end

function draw()
    local x; local y; local z
    local r; local g; local b; local a
    
    background(40, 40, 50)   
    
    -- draw lasso on sprite image 
    if drawLasso then
        sprite(img,img.width/2,img.height/2)
        fill(255)
        for z=1,#vertex do            
            ellipse(vertex[z].x,vertex[z].y,2,2)
        end      
    end
    
    -- determine points inside of polygon         
    if calcInside then
        for x=lowX,highX do
            for y=lowY,highY do 
                check(x,y)
                if val==1 then
                    table.insert(cutXY,vec2(x,y))
                    r,g,b,a=img:get(x,y)
                    table.insert(cutColor,vec4(r,g,b,a))                  
                end
            end
        end 
        calcInside=false
        createCut=true
    end 
       
    -- create image cut by lasso
    if createCut then
        img2=image(highX-lowX,highY-lowY)
        fill(255)
        for z=1,#cutXY do
            r=cutColor[z].x
            g=cutColor[z].y
            b=cutColor[z].z
            a=cutColor[z].a
            img2:set(cutXY[z].x-lowX,cutXY[z].y-lowY,r,g,b,a)            
        end
        createCut = false
        drawLasso=false
        showCut=true        
    end
    
    -- draw image that was cut and move around original image
    if showCut then
        sprite(img,img.width/2,img.height/2) 
        sprite(img2,cx,cy)           
    end  
end

function check(px,py)    -- check if points px, py are within polygon boundary
    local b1; local b2; local b3
    local z; local pe
    local a1; local a2
    
    pe=#vertex    -- last point index
    val=-1
    for z=1,#vertex do
        a1=false
        if vertex[z].y>py then
            a1=true
        end
        a2=false
        if vertex[pe].y>py then         
            a2=true
        end
        b1=vertex[pe].x-vertex[z].x
        b2=py-vertex[z].y
        b3=(vertex[pe].y-vertex[z].y)
        if a1~=a2 and px<(b1*b2/b3+vertex[z].x) then        
            val = val * -1
        end
        pe=z     -- next index
    end 
end

function touched(t)
    -- move cut area around screen
    if showCut then
        if t.state==MOVING then
            cx=t.x
            cy=t.y
        end
        return
    end
    
    -- draw points for lasso
    if t.state==BEGAN then
        table.insert(vertex,vec2(t.x,t.y))
        highLow(t.x,t.y)
    elseif t.state==MOVING then
            -- calculate distance from last point
            v1=vertex[#vertex]
            v2=vec2(t.x,t.y)
            d=v1:dist(v2)
            -- don't allow points too close to last one
            if d>pointDist then
                table.insert(vertex,vec2(t.x,t.y))
                highLow(t.x,t.y)
            end
    end
    
    -- done drawing lasso
    if t.state==ENDED then
        calcInside=true
    end
end

function highLow(x,y)
    -- save high, low x,y values of lasso
    if x<lowX then
        lowX=x
    end
    if x>highX then
        highX=x
    end
    if y<lowY then
        lowY=y
    end
    if y>highY then
        highY=y
    end   
end             

Fixed error in program and replaced it with a new version. See original text above.

Perfect, you are the Big Brother of new Codea developpers .@dave1707

Everytime any one needs help you are here. Thanks a lot.