What am I doing wrong (drawing a heart-shape mesh)?

Spent the last two and half hours. Trying to make a heart. But it feels broken.

ORIGINALLY: There’s something wrong with the way I convert points into vertices at the end of the fheart function. I haven’t figured how to fix this.

NOW: I fixed it. But it still looks really ugly.

NEW CODE: still looks bad. Please observe the changes I made, all in this section of the code.


    x = 0  -- was x = w/2
    for i = 1,16 do
        local angle = math.pi / 15 * i
        local ptx, pty = x + r * math.cos( angle ), y + r * math.sin( angle )
        table.insert ( verts, vec2(ptx, pty) )
    end
    
        -- convert points into triangles for mesh
    local tri = {}
    local center = vec2( w* .5, 0) -- was vec2(w* .75, 0)

    for i,v in ipairs(verts) do
        table.insert(tri, v)
        if i % 2 then
            table.insert(tri, center)
            table.insert(tri, verts[i+1]) -- was totally broken before
        end
    end

BELOW: OLD CODE. It was probably worse

-- Heartis
function heart  (w,h)
    local r  =  w/2
    local verts = {}
    local a = 0
    local x, y = w, h / 2
    for i = 1,16 do
        local angle = math.pi / 15 * i
        local ptx, pty = x + r * math.cos( angle ), y + r * math.sin( angle )
        table.insert ( verts, vec2(ptx, pty) )
    end

    x = w / 2
    for i = 1,16 do
        local angle = math.pi / 15 * i
        local ptx, pty = x + r * math.cos( angle ), y + r * math.sin( angle )
        table.insert ( verts, vec2(ptx, pty) )
    end
    
        -- convert points into triangles for mesh
    local tri = {}
    local center = vec2( w* .75, 0)
    for i,v in ipairs(verts) do
        table.insert(tri, v)
        if i %2 == 0 then
            table.insert(tri, center)
            table.insert(tri, v)
        end
    end

    return tri
end

function setup()
    a=mesh()
    a.vertices=heart(100,100)
    a:setColors(255,0,0)
end


function draw()
    background(40, 40, 50)
    strokeWidth(5)

    translate(490,480)
    a:draw()
end


When you convert points to triangles, you need to make sure that 2 triangles make a rectangle to completely fill the area. Think of the four points that make a rectangle and how you would connect 3 points to make one rectangle and another 3 point to make the other rectangle. The 2 rectangles form the rectangle. Here’s another formula that creates a heart.

function setup()
    tab={}
    for x=-2,2,.01 do
        y = (1-(math.abs(x)-1)^2)^0.5
        table.insert(tab,vec2(x*50+200,y*50+400))
        y = -3*(1-(math.abs(x)/2)^0.5)^0.5
        table.insert(tab,vec2(x*50+200,y*50+400))
    end
end

function draw()
    background(40, 40, 50)
    fill(255)
    for a,b in pairs(tab) do
        ellipse(b.x,b.y,3)
    end
end

Here’s a version of my above code setting a mesh.

EDIT: Added parameters to change the x,y and size values.

function setup()
    yPos=400
    size=5
    parameter.integer("xPos",0,WIDTH,300,setup1)
    parameter.integer("yPos",0,HEIGHT,400,setup1)
    parameter.integer("size",1,20,10,setup1)    
end

function setup1()
    tab={}
    for x=-20,20,.2 do
        y = (1-(math.abs(x/10)-1)^2)^0.5
        table.insert(tab,vec2(x*size+xPos,y*size*10+yPos))
        y = -3*(1-(math.abs(x/10)/2)^0.5)^0.5
        table.insert(tab,vec2(x*size+xPos,y*size*10+yPos))
    end
    tab1={}
    for z=3,#tab do
        table.insert(tab1,vec2(tab[z-2].x,tab[z-2].y))
        table.insert(tab1,vec2(tab[z-1].x,tab[z-1].y))
        table.insert(tab1,vec2(tab[z].x,tab[z].y))
    end
    m=mesh()
    m.vertices=tab1
    m:setColors(255,0,0)
end

function draw()
    background(40, 40, 50)
    m:draw()
end