Math 如何在矩形周长中找到距离给定点最近的点?
这是一个语言不可知的问题。给定一个矩形的尺寸为Math 如何在矩形周长中找到距离给定点最近的点?,math,geometry,rectangles,bounding-box,Math,Geometry,Rectangles,Bounding Box,这是一个语言不可知的问题。给定一个矩形的尺寸为l、t、w、h(左、上、宽、高)和一个点x、y,如何在矩形周长上找到离该点最近的点 我试着用Lua来解决这个问题,但任何其他语言都可以。到目前为止,这是我最大的努力: local function nearest(x, a, b) if a <= x and x <= b then return x elseif math.abs(a - x) < math.abs(b - x) then return a
l、t、w、h
(左、上、宽、高)和一个点x、y
,如何在矩形周长上找到离该点最近的点
我试着用Lua来解决这个问题,但任何其他语言都可以。到目前为止,这是我最大的努力:
local function nearest(x, a, b)
if a <= x and x <= b then
return x
elseif math.abs(a - x) < math.abs(b - x) then
return a
else
return b
end
end
local function getNearestPointInPerimeter(l,t,w,h, x,y)
return nearest(x, l, l+w), nearest(y, t, t+h)
end
最近的局部函数(x,a,b)
如果a设C1、C2、C3、C4为矩形的顶点
从给定的点A开始,画两条线
垂直于矩形的边。设B1、B2、B3、B4
是它们与由
矩形的边(其中一些Bk也可能重合
e、 g.如果A=某些k的Ck)。您的解决方案是Bk
或者其中一个点Ck,只需暴力检查8个点
(同样,这8个点中的某些点可能重合,但这并不重要)。
这一次,我试图捕捉该点朝向矩形任意一侧的最小距离
local abs, min, max = math.abs, math.min, math.max
local function clamp(x, lower, upper)
return max(lower, min(upper, x))
end
local function getNearestPointInPerimeter(l,t,w,h, x,y)
local r, b = l+w, t+h
x, y = clamp(x, l, r), clamp(y, t, b)
local dl, dr, dt, db = abs(x-l), abs(x-r), abs(y-t), abs(y-b)
local m = min(dl, dr, dt, db)
if m == dt then return x, t end
if m == db then return x, b end
if m == dl then return l, y end
return r, y
end
另一种可能的算法(类似于我的第一个答案)可以在这里找到——来自Dinre的算法
看起来很简单,实际上这是我第一个答案的简化版(也许更好)
找到距离给定点A最近的两个矩形顶点Ci和Cj
找到从A到线(Ci,Cj)的垂直线与线(Ci,Cj)相交的点M
您的解决方案是Ci或Cj或M
在我看来,这适用于所有情况(无论点A位于平面中的何处)。您正在寻找类似的东西吗?
灵感来源于《守门员守则》:
local function getNearestPointInPerimeter(l,t,w,h, x,y)
-- x axis increases to the right
-- y axis increases down
local r = l + w
local b = t + h
local inside = true -- unless later proven otherwise
-- if the point (x,y) is outside the rectangle,
-- push it once to the nearest point on the perimeter, or
-- push it twice to the nearest corner.
if x < l then x = l; inside = false; end
if x > r then x = r; inside = false; end
if y < t then y = t; inside = false; end
if y > b then y = b; inside = false; end
-- if the point (x,y) is inside the rectangle,
-- push it once to the closest side.
if inside then
local dt = math.abs (y - t)
local db = math.abs (y - b)
local dl = math.abs (x - l)
local dr = math.abs (x - r)
if dt <= db and dt <= dl and dt <= dr then
y = t
elseif db <= dl and db <= dr then
y = b
elseif dl <= dr then
x = l
else
x = r
end
end
return x,y
end
本地函数getNearestPointInPerimeter(l、t、w、h、x、y)
--x轴向右增加
--y轴向下增加
局部r=l+w
局部b=t+h
local inside=真——除非后来证明为其他
--如果点(x,y)位于矩形外,
--将其推一次到周界上最近的点,或
--将其推两次到最近的拐角处。
如果xr,则x=r;内=假;结束
如果yb,则y=b;内=假;结束
--如果点(x,y)位于矩形内,
--将其推到最近的一侧一次。
如果在里面的话
局部dt=math.abs(y-t)
本地db=math.abs(y-b)
本地dl=math.abs(x-l)
本地dr=math.abs(x-r)
如果dt感谢您的提问和回答!这是我选择的答案的python翻译版本,以防有人需要。唯一的自定义零件是使用lambda的钳位内嵌函数定义
我在带有Qt的QRect和QPoint的GUI中成功地使用了它,以确保QGraphcsView中显示了一些内容
def getNearestPointInPerimeter(自身、左侧、顶部、宽度、高度、x、y):
右=左+宽
底部=顶部+高度
钳位=λ值,最小值,最大值:最大值(最小值,最大值,最小值)
x=夹具(x,左,右)
y=夹具(y、顶部、底部)
dl=防抱死制动系统(x-左)
dr=abs(x-右)
dt=abs(y-顶部)
db=绝对值(y-底部)
m=最小值(分升、降、差、分贝)
如果m==dt:
结果=(x,顶部)
elif m==db:
结果=(x,底部)
elif m==dl:
结果=(左,y)
其他:
结果=(右,y)
返回结果
有些或全部可能也不存在,考虑矩形0,0,1,1和2,2OK,我编辑了我的答案,我相信这是可行的。我只需要证明:)这应该不会太难,除非我的直觉捉弄了我。是的,好吧,如果你把平面分成9个扇区(如果你延长矩形的边),并且考虑a点可能位于哪里(在哪个扇区),那么证明就很简单了.我真的更喜欢那些不需要强迫所有可能的候选人的东西。这段代码将用于我正在构建的库(碰撞检测)的时间关键路径中,因此时间至关重要。@mornfall不存在-不。我指的是这些Bk-由矩形边确定的线的交点,而不是边本身。不幸的是,它不存在。您的算法返回最近角点的坐标。周界中最近的点并不总是其中一个角。我用另一种算法编辑了我的答案。我用一些数值测试了它,它似乎工作得很好。对不起,我认为它不工作。我得到的是非常随机的值——有时甚至在矩形本身之外。你使用了哪些值?我尝试了内部和外部的点,对我来说,我认为我修复了这个错误。如果不是真的更好,请回复。这是一个很好的选择。我相信这就是@Keeper在他的回答中所做的(隐含的)事情。我没有看这段代码。很可能是这样。如果使用此算法,实现应该很简单。我可以用Java或C语言编写,或者用我稍后知道的语言编写;)我真的不懂你的语言。无论如何,祝你好运。谢谢你的回答,我会接受守门员的回答。