Difference between revisions of "LineStippleSnippet"

Line 55: Line 55:
  
 
<source lang="lua">
 
<source lang="lua">
function dotted_line(x1, y1, x2, y2, size, interval)
+
function dottedLine(x1, y1, x2, y2, size, interval)
 
     local size = size or 5
 
     local size = size or 5
 
     local interval = interval or 2
 
     local interval = interval or 2

Revision as of 21:01, 19 December 2012

With the removal of setLineStipple in LÖVE 0.8.0 here is an alternative, based on Bresenham's Line Drawing Algorithm.

function lineStipple( x1, y1, x2, y2, dash, gap )
    local dash = dash or 10
    local gap  = dash + (gap or 10)

    local steep = math.abs(y2-y1) > math.abs(x2-x1)
    if steep then
        x1, y1 = y1, x1
        x2, y2 = y2, x2
    end
    if x1 > x2 then
        x1, x2 = x2, x1
        y1, y2 = y2, y1
    end

    local dx = x2 - x1
    local dy = math.abs( y2 - y1 )
    local err = dx / 2
    local ystep = (y1 < y2) and 1 or -1
    local y = y1
    local maxX = x2
    local pixelCount = 0
    local isDash = true
    local lastA, lastB, a, b

    for x = x1, maxX do
        pixelCount = pixelCount + 1
        if (isDash and pixelCount == dash) or (not isDash and pixelCount == gap) then
            pixelCount = 0
            isDash = not isDash
            a = steep and y or x
            b = steep and x or y
            if lastA then
                love.graphics.line( lastA, lastB, a, b )
                lastA = nil
                lastB = nil
            else
                lastA = a
                lastB = b
            end
        end

        err = err - dy
        if err < 0 then
            y = y + ystep
            err = err + dx
        end
    end
end

Here's an alternative to the alternative above. This uses the function P(t) = A + t*(B-A), where A = (x1, y1) and B = (x2, y2) to find n = length/size points and draw n lines using love.graphics.line with distance = interval*size between each line.

function dottedLine(x1, y1, x2, y2, size, interval)
    local size = size or 5
    local interval = interval or 2

    local dx = (x1-x2)*(x1-x2)
    local dy = (y1-y2)*(y1-y2)
    local length = math.sqrt(dx+dy)
    local t = size/interval

    for i = 1, math.floor(length/size) do
        if i % interval == 0 then
            love.graphics.line(x1+t*(i-1)*(x2-x1), y1+t*(i-1)*(y2-y1),
                               x1+t*i*(x2-x1), y1*t*i*(y2-y1))
        end
    end
end