Last active
December 23, 2020 09:17
-
-
Save ZakBlystone/49ab52dd92326f83f861884289333f3d to your computer and use it in GitHub Desktop.
GLua code for drawing circles and arcs with thickness
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Circles and Arcs (CC0 Public Domain, free to use in whatever you want) | |
-- Created by: Zachary Blystone ( [email protected] ) | |
-- Vertex cache to prevent table allocations during draw operations | |
local vertCache = {} | |
for i=1, 256 do vertCache[i] = { x = 0, y = 0, u = 0, v = 0, } end | |
-- Localized functions | |
local math_rad = math.rad | |
local math_pi = math.pi | |
local math_cos = math.cos | |
local math_sin = math.sin | |
local math_min = math.min | |
local math_max = math.max | |
local surface_DrawPoly = surface.DrawPoly | |
-- surface.DrawCircle | |
-- centerX, centerY the center of the circle | |
-- radius the size of the circle | |
-- angle [0] the rotation of the circle (noticable if you have a small number of vertices) | |
-- numVerts [50] the number of vertices (corners) on the circle | |
function surface.DrawCircle(centerX,centerY,radius,angle,numVerts) | |
numVerts = math_min(numVerts or 50, 256) | |
local temp = nil | |
-- Setup angles and rotation | |
local increment = 2 * math_pi / numVerts | |
local angle = math_rad(angle or 0) | |
local cos = math_cos(increment) | |
local sin = math_sin(increment) | |
local x = math_cos(angle) | |
local y = math_sin(angle) | |
for i=1, numVerts do | |
-- Set the vertex | |
local v = vertCache[i] | |
v.x = centerX + x * radius | |
v.y = centerY + y * radius | |
v.u = (x + 1) * .5 | |
v.v = (y + 1) * .5 | |
-- Rotate the current frame by increment | |
temp = x * cos - y * sin | |
y = x * sin + y * cos | |
x = temp | |
end | |
-- Put a 'notch' in the vertex cache so only these vertices are drawn | |
temp = vertCache[numVerts+1] | |
vertCache[numVerts+1] = nil | |
surface_DrawPoly( vertCache ) | |
-- Restore vertex cache | |
vertCache[numVerts+1] = temp | |
end | |
-- surface.DrawArc | |
-- centerX, centerY the center of the arc | |
-- radius the inner boundary of the arc | |
-- thickness [10] defines how thick the arc is | |
-- startAngle [0] the angle the arc should start from | |
-- endAngle [360] the angle the arc should end up at | |
-- numSegments [50] the number of segments (corners) the arc should have | |
function surface.DrawArc(centerX,centerY,radius,thickness,startAngle,endAngle,numSegments) | |
numSegments = math_max(numSegments or 50, 1) | |
local temp = nil | |
-- Setup angles and rotation | |
local angle = math_rad(startAngle or 0) | |
local sweep = math_rad(endAngle or 360) - angle | |
local increment = sweep / numSegments | |
local cos = math_cos(increment) | |
local sin = math_sin(increment) | |
local x = math_cos(angle) | |
local y = math_sin(angle) | |
local invSegments = 1 / numSegments | |
-- Gather vertices from cache | |
local v0 = vertCache[1] | |
local v1 = vertCache[2] | |
local v2 = vertCache[3] | |
local v3 = vertCache[4] | |
-- Negative thickness pushes the radius inward | |
if thickness < 0 then | |
radius = radius + thickness | |
thickness = -thickness | |
end | |
local outer = radius + (thickness or 10) | |
-- Put a 'notch' in the cache so only these vertices are drawn | |
local prevCache = vertCache[5] | |
vertCache[5] = nil | |
-- Each segment is 4 vertices | |
for i=1, numSegments do | |
-- Set vertices for this segment | |
v0.x = centerX + x * outer | |
v0.y = centerY + y * outer | |
v0.u = (i-1) * invSegments | |
v0.v = 0 | |
v3.x = centerX + x * radius | |
v3.y = centerY + y * radius | |
v3.u = (i-1) * invSegments | |
v3.v = 1 | |
-- Rotate the current frame by increment | |
temp = x * cos - y * sin | |
y = x * sin + y * cos | |
x = temp | |
-- Set vertices for the next segment | |
v1.x = centerX + x * outer | |
v1.y = centerY + y * outer | |
v1.u = i * invSegments | |
v1.v = 0 | |
v2.x = centerX + x * radius | |
v2.y = centerY + y * radius | |
v2.u = i * invSegments | |
v2.v = 1 | |
surface_DrawPoly( vertCache ) | |
end | |
-- Restore vertex cache | |
vertCache[5] = prevCache | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment