Drawing a Polygon with a fill.

Hey guys,

I've done a google search but haven't found anything. I'm not sure whether or not I have completely skipped something here. In the API section and docs they have display.newRect(), I just want to know if there's a way you can define each corner with x and y values.

Hope I made sense,

Thanks

Here's a simple polygon fill method that I found and tweaked a bit for Corona use... (credit for the fill function goes to eyece for his forum post Here)

This function finds all the points on a pixel by pixel basis that can be connected with a line, not sure if it works for complex polys, but seems to work fine for simple ones for sure.

Basically I took this and tweaked the following:

  • can pass in the color to be set for the fill
  • can pass in an xoffset and a yoffset so you can re-use poly definitions (IE see the star)
  • This may work for what you are talking about...allthough it's probably better performance to just use an image for this purpose I had to look this up once you posed the question on how to fill LOL

    Here's the code with a rectangle example as well...

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    
    function paintPoly(poly, xoffset, yoffset, rgba)
     
            n = #poly
     
            miny = poly[1].y
            maxy = poly[1].y
            
            for i = 2, n do
                    miny = math.min(miny, poly[i].y)
                    maxy = math.max(maxy, poly[i].y)
            end
            
            for y = miny, maxy do
                    
                    ints = {}
                    int = 0
                    last = n
                    
                    for i = 1, n do
                            
                            y1 = poly[last].y
                            y2 = poly[i].y
                            if y1 < y2 then
                                    x1 = poly[last].x
                                    x2 = poly[i].x
                                    if (y >= y1) and (y < y2) then
                                            int = int + 1
                                            ints[int] = math.floor((y-y1) * (x2-x1) / (y2-y1) + x1)
                                    end
                            elseif y1 > y2 then
                                    x1 = poly[last].x
                                    x2 = poly[i].x
                                    if (y >= y2) and (y < y1) then
                                            int = int + 1
                                            ints[int] = math.floor((y-y2) * (x1-x2) / (y1-y2) + x2)
                                    end
                            end
                            last = i
                    end
                    
                    ---[[
                    i = 1
                    while i < int do
                            line = display.newLine(ints[i] + xoffset, y + yoffset, ints[i+1] + xoffset, y + yoffset)
                            line:setColor( rgba[1], rgba[2], rgba[3], rgba[4] )
                            i = i + 2
                    end             
                    --]]
                    
                    
            end
            
            
    end
     
    colors = {  {128,255,255,255}, {255,128,255,255}, {255,255,255,255}}
     
    myStar = {
            {x=0,y=-110},
            {x=27,y=-35},
            {x=105,y=-35},
            {x=43,y=16},
            {x=65,y=90},
            {x=0,y=45},
            {x=-65,y=90},
            {x=-43,y=15},
            {x=-105,y=-35},
            {x=-27,y=-35},
            {x=0,y=-110},
    }
     
    myRectangle = {
       {x=40,y=100},
       {x=180,y=100},
       {x=180,y=50},
       {x=40,y=50},
    }
     
     
    paintPoly(myStar, 160, 240, colors[1])
    paintPoly(myStar, 180, 260, colors[2])
    paintPoly(myRectangle, 0, 0, colors[3])

    Thanks heaps croisened! Going to try it out now :)

    Thanks for the useful snippet!

    I modified it a little, as it uses only globals, which is absolutely horrible, but otherwise code is perfectly fine. So I just redeclared variables with 'local', localized Corona functions that are called inside a loop for faster access and added a group to put lines into, so that you can just delete the group and lines will be removed automatically as well.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    
    local function paintPoly(poly, xoffset, yoffset, rgba)
     
        local newLine = display.newLine
        local math_floor = math.floor
        local math_min = math.min
        local math_max = math.max
        local polyGroup = display.newGroup()
     
        local n = #poly
     
        local minY = poly[1].y
        local maxY = poly[1].y
     
        for i = 2, n do
            minY = math_min(minY, poly[i].y)
            maxY = math_max(maxY, poly[i].y)
        end
     
        for y = minY, maxY do
     
            local ints = {}
            local int = 0
            local last = n
     
            for i = 1, n do
                local y1 = poly[last].y
                local y2 = poly[i].y
                if y1 < y2 then
                    local x1 = poly[last].x
                    local x2 = poly[i].x
                    if (y >= y1) and (y < y2) then
                        int = int + 1
                        ints[int] = math_floor((y - y1) * (x2 - x1) / (y2 - y1) + x1)
                    end
                elseif y1 > y2 then
                    local x1 = poly[last].x
                    local x2 = poly[i].x
                    if (y >= y2) and (y < y1) then
                        int = int + 1
                        ints[int] = math_floor((y - y2) * (x1 - x2) / (y1 - y2) + x2)
                    end
                end
                last = i
            end
     
            local i = 1
            while i < int do
                local line = newLine(ints[i] + xoffset, y + yoffset, ints[i + 1] + xoffset, y + yoffset)
                polyGroup:insert(line)
                line:setColor(rgba[1], rgba[2], rgba[3], rgba[4])
                i = i + 2
            end
        end
     
        return polyGroup
    end

    nice workaround! thanx for sharing!

    a star is not a simple polygon, because it's not a convex one

    if it works for a star, it might as well work for all closed polygons

    i tried this hourglass looking shape:
    hg={{x=100,y=100},{x=200,y=100},{x=100,y=200},{x=200,y=200}}
    no problems

    views:2051 update:2011/11/8 8:33:25
    corona forums © 2003-2011