Algorithm 预测直线轨迹是否与矩形接触的算法?

Algorithm 预测直线轨迹是否与矩形接触的算法?,algorithm,lua,line,Algorithm,Lua,Line,我不确定在这里使用什么数学,因为我在使用数学和编码来解决这样的问题方面非常缺乏经验,所以我想知道这里是否有人可以给我一些指导或给我一些地方来看看这个特定的问题。我有单点(或球)的x和y轨迹,当它移动时,它就像一条线,从一个必须停止的位置移动,然后反弹离开(反映轨迹),进入反弹轨迹。我只需要算法给出当前坡度是否与矩形接触的真/假(布尔值)。如果需要的话,我有矩形的4个边缘点和矩形的中点。在注释中来回一些之后,这里有一个函数可能更适合OP的用途。is_intersect()函数将点在轨迹上的位置、方

我不确定在这里使用什么数学,因为我在使用数学和编码来解决这样的问题方面非常缺乏经验,所以我想知道这里是否有人可以给我一些指导或给我一些地方来看看这个特定的问题。我有单点(或球)的x和y轨迹,当它移动时,它就像一条线,从一个必须停止的位置移动,然后反弹离开(反映轨迹),进入反弹轨迹。我只需要算法给出当前坡度是否与矩形接触的真/假(布尔值)。如果需要的话,我有矩形的4个边缘点和矩形的中点。

在注释中来回一些之后,这里有一个函数可能更适合OP的用途。
is_intersect()
函数将点在轨迹上的位置、方向和四边形作为输入,如果点位于相交轨迹上,则返回true,否则返回false

pos
是包含点位置的表格,其形式如下:

pos = { x=x1, y=y1 }
quad = {{x=x1, y=y1}, {x=x2, y=y2}, {x=x3, y=y3}, {x=x4, y=y4}}

dir
是一个包含以弧度为单位的正角度的数字(0IMO
atan
是个坏主意。它很昂贵,象限调整也太难了

您可以使用
atan2
而不是
atan
来简化接受的代码,但这仍然太昂贵

你并不真正关心角度,你关心的是方向向量和从当前位置到框角的极端向量之间的角度符号

因此,交叉乘积更便宜、更简单、更适合。如果有两个向量a和b,则数量:

s = a.x * b.y - a.y * b.x
如果从a到b的锐角为正(逆时针),则为正,反之亦然

只需验证方向向量和从当前点到每个长方体角点的直线形成的锐角是否包含至少一个正结果和一个负结果

function is_intersect(pos, dir, quad)
  local n_pos, n_neg = 0, 0
  for i = 1, 4 do  
    local dx, dy = quad[i].x - pos.x, quad[i].y - pos.y
    local s = dir.x * dy - dir.y * dx
    if s > 0 then n_pos = n_pos + 1 end
    if s < 0 then n_neg = n_neg + 1 end
  end
  return n_pos > 0 and n_neg > 0
end
函数是相交的(位置、方向、四元)
本地n_pos,n_neg=0,0
对于i=1,则为4
局部dx,dy=quad[i].x-pos.x,quad[i].y-pos.y
局部s=dir.x*dy-dir.y*dx
如果s>0,则n_位置=n_位置+1结束
如果s<0,则n_neg=n_neg+1结束
结束
返回n_pos>0和n_neg>0
结束

很抱歉,我不是Lua程序员。这是使用已被接受的答案作为模式对Lua语法的最佳猜测。

从数学角度来看,您可以计算从路径上的某个点到每个角的直线斜率,并检查路径斜率是否超出此范围。非常感谢!我一定会回答同样是我的结果!还有,斜率截距形式是用于坐标还是轨迹?我不确定m_角、m_min和m_max是什么,与x_min和x_max相同。截距是默认定义的吗?另外,如果矩形不断随机移动,我应该用定义的x和y替换四边形中的x和y吗?我所说的traj是什么意思轨迹只是直线的方向,而不是坐标,坐标移动的地方就是轨迹。pos和quad需要添加到第二个算法中,对吗?更新:别介意,我看到示例中包含了所有要求,再次感谢你!还有,你是否可以详细说明确切的过程埃斯正在继续这样做,以便我可以为其他人重新创建它?我将详细说明第二个函数,它比第一个函数好得多,等我有时间的时候。它只需要一点三角函数,也许还需要一些对向量的熟悉:)谢谢,我还没有学过三角函数,但我肯定会这样做。这是一个很好的建议,对于昂贵的函数调用也有好处。我有点支持我的回答,因为OP一开始提出的问题似乎略有不同。当我需要解释象限调整时,我开始考虑改成这样(我真的忽略了)。尽管如此,我认为OP对向量和叉积并不熟悉。我确实不熟悉。@Gene--这段代码确实运行,所以猜测得很好:)注意,函数中的
dir
是一个向量,它由一个表表示,表的形式是
{x=x1,y=y1}
,而不是我函数中的角度。我已经为我的函数编写了一些简单的单元测试,并对它们进行了修改以测试您的函数。它通过了,只是没能检测出矩形角点处的斜视交点。这是因为测试
s>0
s<0
。最简单的解决方法可能是首先比较
s
,如果是,则返回
true
。我使用了
epsilon=1e-6
,所有测试都通过了。此外,在Lua,AFIK中没有
atan2
;在C中,是的。事实上,这里有math.atan2(x,y)@P.Pat--我被纠正了!我在中查看了数学库函数,但没有看到它。但现在我再看一遍,发现
atan2()
在5.3中已被弃用,但它仍然存在。
tan(A) = y/x
A = atan(y/x)
pos1 = { x = 0, y = 0 }
pos3 = { x = 3, y = 3 }
angle = math.atan(.5)
pi = math.pi
{ pass = true, args = { pos1, pi/4, rect } },
{ pass = true, args = { pos3, 5*pi/4, rect } },
{ pass = true, args = { pos3, pi + angle, rect } },
{ pass = true, args = { pos3, 3*pi/2 - angle, rect } },
{ pass = true, args = { pos3, 1.1*(pi + angle), rect} },
{ pass = false, args = { pos3, 1.1*(3*pi/2 - angle), rect } },
{ pass = false, args = { pos3, .99*(pi + angle), rect } },
{ pass = true, args = { pos3, .99*(3*pi/2 - angle), rect } }, 
{ pass = true, args = { pos3, {x=-1.01, y=-2}, rect} },
{ pass = false, args = { pos3, {x=-0.99, y=-2}, rect } },
{ pass = false, args = { pos3, {x=-2.01, y=-1}, rect } },
{ pass = true, args = { pos3, {x=-1.99, y=-1}, rect } },
s = a.x * b.y - a.y * b.x
function is_intersect(pos, dir, quad)
  local n_pos, n_neg = 0, 0
  for i = 1, 4 do  
    local dx, dy = quad[i].x - pos.x, quad[i].y - pos.y
    local s = dir.x * dy - dir.y * dx
    if s > 0 then n_pos = n_pos + 1 end
    if s < 0 then n_neg = n_neg + 1 end
  end
  return n_pos > 0 and n_neg > 0
end