From 0248339898ed7c6f25dca5ae10458a8fee969c47 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Fri, 17 Jun 2022 23:15:09 -0700 Subject: more precise shape selection It's important that the error be additive rather than multiplicative, otherwise the area grows asymmetrically along a line. Hopefully freehand drawings will work more intuitively now. --- drawing.lua | 17 +++++++++++++++++ geom.lua | 25 ++++++++++++++++++------- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/drawing.lua b/drawing.lua index 7ebf177..e191767 100644 --- a/drawing.lua +++ b/drawing.lua @@ -4,6 +4,8 @@ geom = require 'geom' require 'drawing_tests' +Show_nearby = false + -- All drawings span 100% of some conceptual 'page width' and divide it up -- into 256 parts. function Drawing.draw(line) @@ -28,6 +30,17 @@ function Drawing.draw(line) return end + if Show_nearby then + love.graphics.setColor(1,0.75,0.75) + for y=0,127 do + for x=0,255 do + if geom.on_any_shape(x,y, line) then + love.graphics.circle('fill', Drawing.pixels(x)+Margin_left, Drawing.pixels(y)+line.y, 2) + end + end + end + end + local mx,my = Drawing.coord(pmx-Margin_left), Drawing.coord(pmy-line.y) for _,shape in ipairs(line.shapes) do @@ -370,6 +383,10 @@ function Drawing.mouse_released(x,y, button) end function Drawing.keychord_pressed(chord) + if chord == 'C-a' then + Show_nearby = not Show_nearby + return + end if chord == 'C-p' and not App.mouse_down(1) then Current_drawing_mode = 'freehand' elseif App.mouse_down(1) and chord == 'l' then diff --git a/geom.lua b/geom.lua index 4dc2e3a..6baee93 100644 --- a/geom.lua +++ b/geom.lua @@ -1,5 +1,15 @@ local geom = {} +function geom.on_any_shape(x,y, drawing) + for _,shape in ipairs(drawing.shapes) do + assert(shape) + if geom.on_shape(x,y, drawing, shape) then + return true + end + end + return false +end + function geom.on_shape(x,y, drawing, shape) if shape.mode == 'freehand' then return geom.on_freehand(x,y, drawing, shape) @@ -14,20 +24,21 @@ function geom.on_shape(x,y, drawing, shape) if y1 > y2 then y1,y2 = y2,y1 end - return y >= y1*0.95 and y <= y2*1.05 + return y >= y1-2 and y <= y2+2 elseif p1.y == p2.y then if y ~= p1.y then return false end local x1,x2 = p1.x, p2.x if x1 > x2 then x1,x2 = x2,x1 end - return x >= x1*0.95 and x <= x2*1.05 + return x >= x1-2 and x <= x2+2 end elseif shape.mode == 'polygon' or shape.mode == 'rectangle' or shape.mode == 'square' then return geom.on_polygon(x,y, drawing, shape) elseif shape.mode == 'circle' then local center = drawing.points[shape.center] - return geom.dist(center.x,center.y, x,y) == shape.radius + local dist = geom.dist(center.x,center.y, x,y) + return dist > shape.radius*0.95 and dist < shape.radius*1.05 elseif shape.mode == 'arc' then local center = drawing.points[shape.center] local dist = geom.dist(center.x,center.y, x,y) @@ -65,24 +76,24 @@ function geom.on_line(x,y, drawing, shape) p2 = shape.p2 end if p1.x == p2.x then - if math.abs(p1.x-x) > 5 then + if math.abs(p1.x-x) > 2 then return false end local y1,y2 = p1.y,p2.y if y1 > y2 then y1,y2 = y2,y1 end - return y >= y1 and y <= y2 + return y >= y1-2 and y <= y2+2 end -- has the right slope and intercept local m = (p2.y - p1.y) / (p2.x - p1.x) local yp = p1.y + m*(x-p1.x) - if yp < 0.95*y or yp > 1.05*y then + if yp < y-2 or yp > y+2 then return false end -- between endpoints local k = (x-p1.x) / (p2.x-p1.x) - return k > -0.05 and k < 1.05 + return k > -0.005 and k < 1.005 end function geom.on_polygon(x,y, drawing, shape) -- cgit 1.4.1-2-gfad0