use eight anchor points to adjust bbox

Including the vertices and the midpoints on each edge of the rectangle.
pull/2/merge
chrox 11 years ago
parent 7117cb8710
commit e1d4b1f160

@ -22,4 +22,39 @@ function math.oddEven(number)
end
end
function tmin_max(tab, func, op)
if #tab == 0 then return nil, nil end
local index, value = 1, tab[1]
for i = 2, #tab do
if func then
if func(value, tab[i]) then
index, value = i, tab[i]
end
elseif op == "min" then
if value > tab[i] then
index, value = i, tab[i]
end
elseif op == "max" then
if value < tab[i] then
index, value = i, tab[i]
end
end
end
return index, value
end
--[[
Return the minimum element of a table.
The optional argument func specifies a one-argument ordering function.
]]--
function math.tmin(tab, func)
return tmin_max(tab, func, "min")
end
--[[
Return the maximum element of a table.
The optional argument func specifies a one-argument ordering function.
]]--
function math.tmax(tab, func)
return tmin_max(tab, func, "max")
end

@ -110,22 +110,39 @@ function BBoxWidget:onAdjustScreenBBox(ges, rate)
local upper_right = Geom:new{ x = bbox.x1, y = bbox.y0}
local bottom_left = Geom:new{ x = bbox.x0, y = bbox.y1}
local bottom_right = Geom:new{ x = bbox.x1, y = bbox.y1}
local corners = {upper_left, upper_right, bottom_left, bottom_right}
table.sort(corners, function(a,b)
return a:distance(ges.pos) < b:distance(ges.pos)
local upper_center = Geom:new{ x = (bbox.x0 + bbox.x1) / 2, y = bbox.y0}
local bottom_center = Geom:new{ x = (bbox.x0 + bbox.x1) / 2, y = bbox.y1}
local right_center = Geom:new{ x = bbox.x1, y = (bbox.y0 + bbox.y1) / 2}
local left_center = Geom:new{ x = bbox.x0, y = (bbox.y0 + bbox.y1) / 2}
local anchors = {
upper_left, upper_center, upper_right,
left_center, right_center,
bottom_left, bottom_center, bottom_right,
}
local _, nearest = math.tmin(anchors, function(a,b)
return a:distance(ges.pos) > b:distance(ges.pos)
end)
if corners[1] == upper_left then
--DEBUG("nearest anchor", nearest)
if nearest == upper_left then
upper_left.x = ges.pos.x
upper_left.y = ges.pos.y
elseif corners[1] == bottom_right then
elseif nearest == bottom_right then
bottom_right.x = ges.pos.x
bottom_right.y = ges.pos.y
elseif corners[1] == upper_right then
elseif nearest == upper_right then
bottom_right.x = ges.pos.x
upper_left.y = ges.pos.y
elseif corners[1] == bottom_left then
elseif nearest == bottom_left then
upper_left.x = ges.pos.x
bottom_right.y = ges.pos.y
elseif nearest == upper_center then
upper_left.y = ges.pos.y
elseif nearest == right_center then
bottom_right.x = ges.pos.x
elseif nearest == bottom_center then
bottom_right.y = ges.pos.y
elseif nearest == left_center then
upper_left.x = ges.pos.x
end
self.screen_bbox = {
x0 = upper_left.x,

Loading…
Cancel
Save