How to draw a smooth series of line segments? Also, an arc() function

I am trying to write an arc() function which will permit me - eventually - to draw segments of circles by specifying any of a few different determining features. The function will use the current stroke, strokeWidth, etc., and I am trying to make it very similar in behaviour to functions such as ellipse or rect.

My question comes: Why does a series of contiguous line segments come out very faint when drawn with smooth() on? If I choose noSmooth(), then I get some odd artefacts in the drawing, though the arc is drawn in the correct colour. What am I not understanding or accounting for in the behaviour of lineCapMode and smooth?

Thank you in advance for advice. I will post an updated version of the code below when the other arcModes are implemented - and if I an figure out how to make the code work properly at all.

Richard

-- Arc

-- Code to implement a simple arc() function, along with an arcMode() function
-- Author: Richard Martin-Nielsen, January 2013
-- Licence: CC0 - http://creativecommons.org/publicdomain/zero/1.0/ - except for portion from Reefwing 
Software
-- Version: 0.1 - only one arc mode implemented, problems with smoothness


THREEPOINTS = 1
POINTCENTREPOINT = 2
CENTRERADIUSARC = 3

arcModeVal = CENTRERADIUSARC
function arcMode(newMode)
    if newMode ~= nil then
        arcModeVal = newMode
    else
        return arcModeVal
    end
end

-- from ReefWing software's Math.lua
-- can be deleted if ReefWing software's utility library is imported
--
function math.cart(distance, angleInDegrees, originX, originY)
    local oX = originX or 0
   local oY = originY or 0
   local angleInRadians = math.rad(angleInDegrees)
    local dx = math.cos(angleInRadians)*distance
    local dy = math.sin(angleInRadians)*distance
   -- Functions may return multiple results in Lua.
   return dx+oX, dy+oY
end

function arc(...)
    local cx, cy, startT, endT, incrT, radius
    if arcModeVal == CENTRERADIUSARC then
        cx = arg[1] or 0
        cy = arg[2] or 0
        radius = arg[3] or 25
        startT = arg[4] or 0
        endT = arg[5] or math.pi/2
        while endT < startT do endT = endT + 2*math.pi end
        --incrT = math.pi/(60) -- for now , draw every degree
        if radius > 0 then
            incrT = 1 / (radius*ContentScaleFactor)
        else
            incrT = math.pi/180
        end
        local currentT = startT
        pushStyle()
        lineCapMode(PROJECT)
        --lineCapMode(SQUARE)
        --noSmooth()
        while currentT < endT-incrT do
            local sx,sy,ex,ey
            sx,sy = math.cart(radius,math.deg(currentT),cx,cy)
            ex,ey = math.cart(radius,math.deg(currentT+incrT),cx,cy)
            line(sx,sy,ex,ey)
            currentT = currentT + incrT
        end
        if currentT < endT then
            local sx,sy,ex,ey
            sx,sy = math.cart(radius,math.deg(currentT),cx,cy)
            ex,ey = math.cart(radius,math.deg(endT),cx,cy)
            line(sx,sy,ex,ey)
        end
        popStyle()
        return      
    elseif arcModeVal == THREEPOINTS then
        print("THREEPOINTS not implemented yet")
        return
    elseif arcModeVal == POINTCENTREPOINT then
        local sx,sy,cx,cy,ex,ey,rad,startT,endT
        print("POINTCENTREPOINT not implemented yet")
        return
    else
        print("unrecognized arcMode "..arcModeVal)
        return
    end
end     
    
-- Use this function to perform your initial setup
function setup()
    print("Arc: draws an arc based on the specified centre of the circle, the radius, and the start and end points as specified in radians.")
    parameter("CentreX",0,WIDTH,WIDTH/2)
    parameter("CentreY",0,HEIGHT,HEIGHT/2)
    parameter("Radius",0,WIDTH,WIDTH/4)
    parameter("StartT",-math.pi*2,2*math.pi,0)
    parameter("EndT",-math.pi*2,2*math.pi,math.pi/3)
    parameter("StrokeWidth",1,40,5)
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(0, 0, 0, 255)
    -- This sets the line thickness
    stroke(255, 0, 0, 255)
    strokeWidth(StrokeWidth)

    -- Do your drawing here
    --arc(50,50,25,0,math.rad(90))
    
    --arcMode()
    arc(CentreX,CentreY,Radius,StartT,EndT)
end


Codea 1.5 will come with some evolution and corrections on line bugs. Maybe you should wait for this release before you dig too much into this?

I would recommend making your arc into a mesh. Lines get expensive and getting the overlaps right is tricky.

I made a mesh arc function somewhere, I’ll find it for you…

here

Thanks to everyone for comments and suggestions and referrals. I’m going to put my project on hold for 1.5, but will look for a work-around.

It’s nice to have it confirmed that I’m not the only one who decided to write a mesh class to draw curved lines. Mine isn’t so clean that I’d want to share it, but I think this reflects how many of us are using Codea to experiment and explore. I think I may adapt my line/arc mesh to try the smoothing I’ve seen in someone else’s code, and then rewrite the arc function to use it for now.

Perhaps fairly typically, I have about five things I’d like to change about my current main project. Smooth curves is generally ranking about number six… And then I’ve another two things I’m fiddling with.