Log In  


Thick line drawing routine (as a reply to @JadeLombax Twitter).

Cart #rabogemeri-0 | 2020-07-29 | Code ▽ | Embed ▽ | No License
8

Manual:

linefill x0 y0 x1 y1 r [col]
draw a 2*r pixel wide line
note: r must be >= 0.5 to produce meaningful results
note: the code uses sub-pixel precision rasterization, allowing smooth movement

Example:

-- 4 pixel wide white line
linefill(45,34,67,96,2,7)
8


Looks nice, I'll have to try and figure out how it works. You said this is a reply to something from me on Twitter?


sorry - pseudo mixup! Was looking for @spellcaster i


The code is neat, the only "issue" I had is that I can't find a combination of values where the thick line and a circfill can agree on the same size. Besides that, it's perfect.


not a surprise - I don’t use the same rounding as native pico8 functions.
if you want an exact match, strip the ‘sub-pixel’ part from my code.
(but at the cost of a lot more pixel jerkiness)


That's why I placed "issue" it in quotes :)

I tinkered aground with it a bit, and found something that n should work well for the idea I have in mind.


the linefill code can be easily extended to draw arbitrary convex polygons. You can draw joints with the same pixel rules


Thanks for this. I realised I needed a thick line routine and this is perfect.


about 5 years late to this thread lol

mainly did this to practice token reduction, but i got bored and managed to reduce the token count of this routine by 52 (265 to 213)

the function works the exact same with a few optimizations, some fast math, and a removal of the if(d<0.001) return statement, since i have yet to notice any problems without it.

function linefill(ax, ay, bx, by, r, c)
  if (c) color(c)
  -- modify bx, by directly
  bx, by = bx - ax, by - ay
  -- more token-efficient distance calculation: https://www.lexaloffle.com/bbs/?pid=168322#p
  local s = sin(atan2(bx, by))
  local d = abs(s == 0 and bx or by / s)
  local ca, sa, spans = bx / d, -by / d, {}
  local x0, y0 = ax + r * sa, ay + r * ca
  for i = 1, 4 do
    -- s table removed in favor of calculating u and v in the loop itself
    local u, v = i % 3 ~= 1 and d or 0, r * sgn(i - 3)
    local x1, y1 = ax + u * ca + v * sa, ay - u * sa + v * ca
    local _x1, _y1 = x1, y1
    if (y0 > y1) x0, y0, x1, y1 = x1, y1, x0, y0
    local dx = (x1 - x0) / (y1 - y0)
    if (y0 < 0) x0 -= y0 * dx y0 = -1
    local a = y0 \ 1 + 1
    -- sub-pix shift
    x0 += (a - y0) * dx
    for y = a, min(y1 \ 1, 127) do
      -- open span?
      local span = spans[y]
      if (span) rectfill(x0, y, span, y) else spans[y] = x0
      x0 += dx
    end
    x0, y0 = _x1, _y1
  end
end

this isn't me trying to one-up you or anything, i was just a bit bored :P really nice function overall!



[Please log in to post a comment]