Drawing an arc

Is there any way I can draw an arc?
I want to draw some angles and having a function that draws an arc would be very helpful.

PS: sorry for bad english, english is not my first language.

Hi Ghabriel,

Not as far as I know. An arc/ part circle or bezier curve would be a great addition to Codea.

By the way you English is excellent.

Brig_G

:slight_smile:

You could draw an arc if you clip an ellipse…

Like this (paste in draw() in a new project)


    noFill()
    clip(WIDTH/2,HEIGHT/2,200,200)
    ellipse(WIDTH/2, HEIGHT/2,400)
    clip()

That means you define that you only draw a part of the ellipse…

I’ve faked drawing an arc in my code by drawing a load of ellipses. I draw the arc to an image as I presume this is cheaper to draw repeatedly.

    ARC_IMAGE = image(180,180)
    setContext(ARC_IMAGE)
    ellipseMode(CENTER)
    
    fill(255,0,0,255)
    noStroke()
    local cos = math.cos
    local sin = math.sin
    local rad = math.rad
        for i = 0,45 do
            local angle = i*90
            local x = 55 * cos( rad(angle) )
            local y = 55 * sin( rad(angle) )
            ellipse(x+90,y+90,10,10)
        end
    
    setContext()

“By the way you English is excellent.”

I lolled. Was that intentional? :slight_smile:

I have some code for rendering bezier curves. I’ll dig it out later (it’s buried in a project so I’ll need to extract the code into something easy to use independently).

function vecline(dva,dvb)
va = dva *size --+ offset
vb = dvb * size --+ offset
    line(va.x,va.y,vb.x,vb.y)
end



    
    
        
            
                function jointlimb(pointa,pointb,lengthlimit,leanr,multiplier,curves)
                    if curves == nil then
                        curves = 1
                        end
                        
                        if multiplier == nil then
                        curves = 1
                        end
                        
                     arc =   -pointa + pointb
                    if arc:len() > lengthlimit then
                        arc = arc:normalize() * lengthlimit
                        curves = 0
                        else
                        offset = ((lengthlimit - arc:len()))*arc:normalize():rotate90()/2
                        
                        end
                        
                        arcdraw = arc/(curves+1)
                        
                        if curves == 0 then
                            
                            vecline(pointa,pointa+arcdraw)
                            else
                                curvepart=(curves+1)/2
                                pointe = pointa
                                pointd = pointe
                            for i=0,curves+1 do
                                quadslide=(1-(1-(i/(curvepart)))^2)
                                pointc = pointa + arcdraw*(i)
                                pointc = pointc + offset*quadslide*multiplier 
            + leanr*arcdraw*quadslide*curvepart/2
                            
                                if math.floor(i/2) == i/2 then
                                    pointe = pointc
                                    else
                                        pointd= pointc
                                        end
                                        vecline(pointd,pointe)
                    end
                    end
end

Hi @peteroyle,

Nah, that wasn’t intenshinul, just my keyboard dyslexia!!!

Andrew, any code on curves or arcs would be appreciated - thanks.

Bri_G

:slight_smile:

Below is a Codea version 1.5 suggestion, making use of an example shader:


--
-- Arc
--

supportedOrientations(LANDSCAPE_ANY)
function setup()
    cx, cy = WIDTH / 2, HEIGHT / 2
    parameter.integer("width", 1, 100, 40)
    parameter.integer("radius", 100, WIDTH / 2, 200)
    parameter.integer("startAngle", -180, 180, -130)
    parameter.integer("endAngle", -180, 180, 130)
    stroke(118, 223, 25)
end

function draw()
    background(64)
    strokeWidth(width)
    arc(cx, cy, radius, startAngle, endAngle)
end

function arc(x, y, radius, a1, a2)
    local m = mesh()
    m:addRect(x, y, radius * 2, radius * 2)
    m.shader = shader("Patterns:Arc")
    m.shader.size = (1 - strokeWidth()/radius) * 0.5
    m.shader.color = color(stroke())
    m.shader.a1 = math.rad(a1)
    m.shader.a2 = math.rad(a2)
    m:draw()
end

(sigh) Alright, well this is the Questions section of the forum, and I’d been asking about arcs before. I like the arc function provided, and have reworked it slightly in the code below which lets you draw a simple two-part pie chart, with customisable colours, fraction of one colour and the other, and radius.

What I do not understand, still, is why the code doesn’t also display a blue semicircle over the pie chart. I took the code I’d written to try using the Arc shader, and then used @mpilgrem’s arc function, then tried to make my construction and invocation of the mesh and shader match. And I still don’t see my mesh. What am I missing here?

Thanks in advance,
Richard

-- Shader Pie Chart

-- Use this function to perform your initial setup
displayMode(STANDARD)

function setup()
    parameter.number("Fraction",0,1,0.5)
    parameter.number("Radius",10,HEIGHT/2,250)
    parameter.color("PartOne",255,255,0)
    parameter.color("PartTwo",255,0,0)

    mymesh = mesh()
    
    rIdx = mymesh:addRect(WIDTH/2, HEIGHT/2, Radius*2, Radius*2)
    mymesh.shader = shader("Patterns:Arc")
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color
    background(40, 40, 50)

    -- This sets the line thickness
    strokeWidth(5)
   -- rotate(90)
    local cx,cy, radius, startAngle, endAngle
    cx = WIDTH/2
    cy = HEIGHT/2
    strokeWidth(Radius)
    stroke(PartOne)
    startAngle = -180
    endAngle = 360*Fraction-180
    arc(cx, cy, Radius, startAngle, endAngle)
    stroke(PartTwo)
    startAngle = endAngle
    endAngle = 180
    arc(cx, cy, Radius, startAngle, endAngle)
    
    -- Configure out custom uniforms for the ripple shader
    -- Attempt to draw a blue semicircle using a standalone, re-used mesh. 
    mymesh.shader.size = 0.5
    mymesh.shader.color = color(0,0,255)
    mymesh.shader.a1 = 0.0
    mymesh.shader.a2 = math.pi/2    
    -- Draw the mesh
    mymesh:draw()
end

--
-- Arc
--

function arc(x, y, radius, a1, a2)
    local m = mesh()
    m:addRect(x, y, radius * 2, radius * 2)
    m.shader = shader("Patterns:Arc")
    m.shader.size = (1 - strokeWidth()/radius) * 0.5
    m.shader.color = color(stroke())
    m.shader.a1 = math.rad(a1)
    m.shader.a2 = math.rad(a2)
    m:draw()
end