[SHARE] Fake lineCapMode() for pixelated lines

Full post on kennstewayne.de

If you’ve ever wanted to paint crisp pixelated lines, you certainly used noSmooth and then wondered why it looks like chunky line-segments.

So did me too. My solution was to overlay those spaces with ellipse. But that didn’t work, since, as you all know, ellipses are always drawn smooth. Lines get sharp while in-between the segments get washed out.

Therefore I’ve overridden Codea’s line function completely! It now takes up to five arguments: line(x1, y1, x2, y2, capMode). If capMode is given, the line always gets drawn pixelated, despite the smooth() statement. But you can also use line() as you did before - in this case nothing changes to your prior experience.

capModes are same as lineCapMode: ROUND, PROJECT, SQUARE

https://gist.github.com/jack0088/c1ac4c8f09b945be0413

--# Main
-- noSmooth lineCapModes
 
function setup()
    smooth()
end
 
function draw()
    background(45)
    
    stroke(255, 0, 0)
    strokeWidth(30)
    line(30, 30, 300, 200, ROUND)
    
    stroke(255, 90, 0)
    strokeWidth(20)
    line(30, 30, 300, 200, PROJECT)
    
    stroke(255, 120, 20)
    strokeWidth(10)
    line(30, 30, 300, 200, SQUARE)
    
    stroke(0)
    strokeWidth(10)
    line(30, 120, 300, 150, ROUND) -- uses default line() with is now affected by smooth() from setup()
    
    stroke(0)
    strokeWidth(10)
    line(30, 100, 300, 130) -- uses default line() with is now affected by smooth() from setup()
end

--# lineCapMode
local _line = line
 
local function lineCap(d)
    for x = 1, d do
        y = math.sqrt(d*d - x*x)
        rect(0, 0, x, y)
    end
end
 
function line(x1, y1, x2, y2, capMode)
    local p1, p2 = vec2(x1, y1), vec2(x2, y2)
    
    pushStyle()
    pushMatrix()
    rectMode(CENTER)
    
    if capMode then
        noSmooth()
        
        local angle = math.deg(vec2(0, 1):angleBetween(p2 - p1))
        local size  = strokeWidth()
        
        if capMode == ROUND then -- default condition when smooth()!
            pushMatrix()
                translate(p1.x, p1.y)
                rotate(angle)
                lineCap(size)
            popMatrix()
                translate(p2.x, p2.y)
                rotate(angle)
                lineCap(size)
            popMatrix()
        elseif capMode == PROJECT then
            pushMatrix()
                translate(p1.x, p1.y)
                rotate(angle)
                rect(0, 0, size)
            popMatrix()
                translate(p2.x, p2.y)
                rotate(angle)
                rect(0, 0, size)
            popMatrix()
        elseif capMode == SQUARE then
            --pass condition because this is default line() behaviour when noSmooth()!
        end
    end
    
    _line(p1.x, p1.y, p2.x, p2.y)
    
    popMatrix()
    popStyle()
end


nice art!