Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Math 如何在矩形周长中找到距离给定点最近的点?_Math_Geometry_Rectangles_Bounding Box - Fatal编程技术网

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语言编写,或者用我稍后知道的语言编写;)我真的不懂你的语言。无论如何,祝你好运。谢谢你的回答,我会接受守门员的回答。