login

<     >

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")