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