javascript - 检查矢量/Angular 是否与区域相交

标签 javascript canvas

我想做的是:
我有两个 (x, y) 点,p1 和 p2,以及一个来自 p1 的旋转值(以弧度表示的 Angular )。 P2 还有另外两个变量,宽度和高度,我称之为 p2w 和 p2h。我想检查 p1 的 Angular 是否与 p2 的边界相交,半径为宽度和/或高度。

换句话说,如果这个 Angular “穿过”中心p2、宽度p2w和高度p2h的正方形。

为了更好地理解,这里有一个图表:
http://i.imgur.com/Y7WFD36.png

我一直在尝试做的是:

if( p1.rot > (Math.atan2(p2.y-p2h, p2.x-p2w)) 
&& p1.rot < (Math.atan2(p2.y+p2h, p2.x+p2w)) )
//There's an intersection

但如您所料,它并没有按预期工作;还有其他方法吗?

最佳答案

数学队长来救援!

你问的是一条射线是否与一个矩形相交。这是我们需要做的。

首先,使用点和矢量或点和 Angular 来定义射线。由于使用矢量更容易,让我们将 Angular 转换为矢量。使用毕达哥拉斯定理,您的 Angular phi 等于向量 n = {x: Math.cos(phi), y: Math.sin(phi)}

我将重命名您的变量以使符号更容易。我将用 p 表示你的 p1,用 r 表示你隐式定义的矩形。

现在,对于位于射线上的任意随机点 M,必须满足以下等式:

M.x = p.x + n.x * alpha (1)
M.y = p.y + n.y * alpha

对于一些真正的阿尔法。类似地,对于位于矩形内的任意随机点 M,必须满足以下不等式:

M.x >= r.x
M.x <= r.x + r.w
M.y >= r.y
M.y <= r.y + r.h

对于一个既位于射线上又位于矩形内的点,方程和不等式都必须成立。代入上述值,我们得到:

p.x + n.x * alpha >= r.x
p.x + n.x * alpha <= r.x + r.w
p.y + n.y * alpha >= r.y
p.y + n.y * alpha <= r.y + r.h

求解 alpha,我们得到:

alpha >= (r.x - p.x) / n.x
alpha <= (r.x + r.w - p.x) / n.x
alpha >= (r.y - p.y) / n.y
alpha <= (r.y + r.h - p.y) / n.y

当且仅当:

var lowerLimitX = (r.x - p.x) / n.x;
var lowerLimitY = (r.y - p.y) / n.y;
var upperLimitX = (r.x + r.w - p.x) / n.x;
var upperLimitY = (r.y + r.h - p.y) / n.y;
var minAlpha = Math.max(lowerLimitX, lowerLimitY);
var maxAlpha = Math.min(upperLimitX, upperLimitY);
var hasSolution = minAlpha<= maxAlpha;

现在,如果上面的系统有解,则必须至少有一个点同时位于射线和矩形上,换句话说,它们相交。

编辑:这是一个working demo .移动鼠标以查看结果。请注意,由于 Y 轴在 HTML Canvas API 中向下增长,因此必须交换 Y 轴的下限和上限。

编辑 2:如果您按照@pfannkuchen_gesicht 的建议关心交点(请注意,交点通常是线段,而不是点),这也很容易。正如我们已经知道的,对于交点上的点,射线方程必须成立。要自己找到点,只需将 alpha 替换为 [minAlpha; 范围内的值即可。 maxAlpha] 在 (1) 中。例如,最近的点是 p + minAlpha * n,最远的点是 p + maxAlpha * n,中间的随机点是 p +(minAlpha + Math.random() * (maxAlpha - minAlpha)) * n.

关于javascript - 检查矢量/Angular 是否与区域相交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30004165/

相关文章:

javascript - Vuejs 无法加载 svg 图片?

html - 如何解决提供极高 FPS 的 webkitRequestAnimationFrame

javascript - Canvas 正弦波方向

javascript - 使用 jquery 使用第二个提交按钮提交表单

javascript - WebGL Three.js 重复内容

javascript - 单选按钮检查绑定(bind) html5,durandal

javascript - 我想在同一张卡片中显示数据作为两列任何建议

HTML5 移动 Canvas 对象

android - 如何将 Canvas 绘图保存为图像?

elasticsearch - ElasticSearch Canvas-下拉菜单不起作用