2021-04-10 16:32:58 (UTC-03:00)
Marcel Rodrigues <marcelgmr@gmail.com>
add radius (width) to lines
diff --git a/surf.lua b/surf.lua index f7db899..b4eb13f 100644 --- a/surf.lua +++ b/surf.lua @@ -31,8 +31,6 @@ function BitMap:inside(x, y) end function BitMap:_index_shift_mask(x, y) - -- TODO: only check bounds in user-facing methods, for performance - assert(self:inside(x, y)) local index = y * self.t + math.floor(x / 8) local shift = (7-x) % 8 local mask = lshift(1, shift) @@ -40,11 +38,13 @@ function BitMap:_index_shift_mask(x, y) end function BitMap:pget(x, y) + if not self:inside(x, y) then return 0 end local index, shift, mask = self:_index_shift_mask(x, y) return rshift(band(self.p[index], mask), shift) end function BitMap:pset(x, y, v) + if not self:inside(x, y) then return end local index, shift, mask = self:_index_shift_mask(x, y) local byte = self.p[index] if v > 0 then @@ -68,18 +68,52 @@ function BitMap:vline(x, y, h, v) end end -function BitMap:line(x0, y0, x1, y1, v) +function BitMap:disk(cx, cy, r, v) + if r == 0 then + self:pset(cx, cy, v) + return + end + local x, y, d = r, 0, 1-r + while x >= y do + self:hline(cx-x, cy+y, 2*x, v) + self:hline(cx-y, cy+x, 2*y, v) + self:hline(cx-x, cy-y, 2*x, v) + self:hline(cx-y, cy-x, 2*y, v) + y = y + 1 + if d <= 0 then + d = d + 2*y + 1 + else + x = x - 1 + d = d + 2*(y-x) + 1 + end + end +end + +function BitMap:line(x0, y0, x1, y1, v, r) + r = r or 0 if x1 == x0 then + local x, y, h if y1 > y0 then - self:vline(x0, y0, y1 - y0) + x, y, h = x0, y0, y1-y0 else - self:vline(x0, y1, y0 - y1) + x, y, h = x0, y1, y0-y1 + end + self:vline(x, y, h, v) + for i = 1, r do + self:vline(x-i, y, h, v) + self:vline(x+i, y, h, v) end elseif y1 == y0 then + local x, y, w if x1 > x0 then - self:hline(x0, y0, x1 - x0) + x, y, w = x0, y0, x1-x0 else - self:hline(x1, y0, x0 - x1) + x, y, w = x1, y0, x0-x1 + end + self:hline(x, y, w, v) + for i = 1, r do + self:hline(x, y-i, w, v) + self:hline(x, y+i, w, v) end else local dx, dy = x1-x0, y1-y0 @@ -88,10 +122,10 @@ function BitMap:line(x0, y0, x1, y1, v) local e = 0 local x, y = x0, y0 while x ~= x1 do - self:pset(x, y, v) + self:disk(x, y, r, v) e = e + de while e >= 0.5 do - self:pset(x, y, v) + self:disk(x, y, r, v) y = y + sy e = e - 1 end @@ -100,23 +134,6 @@ function BitMap:line(x0, y0, x1, y1, v) end end -function BitMap:disk(cx, cy, r, v) - local x, y, d = r, 0, 1-r - while x >= y do - self:hline(cx-x, cy+y, 2*x, v) - self:hline(cx-y, cy+x, 2*y, v) - self:hline(cx-x, cy-y, 2*x, v) - self:hline(cx-y, cy-x, 2*y, v) - y = y + 1 - if d <= 0 then - d = d + 2*y + 1 - else - x = x - 1 - d = d + 2*(y-x) + 1 - end - end -end - function BitMap:save_pbm(fname) local pbm = io.open(fname, "wb") pbm:write("P4\n", self.w, " ", self.h, "\n")