从内部的矢量和角度找到矩形的边缘
Finding the edge of a rectange from a vector and angle inside
在示例 fiddle 中:https://jsfiddle.net/krazyjakee/uazy86m4/ 您可以在显示为蓝色方块的矢量点下方拖动鼠标。您将看到这条线从矢量绘制一条路径,通过鼠标到达显示绿色方块的视口边缘,表明它已找到边缘。但是,在矢量上方,绿色方块消失了,因为它无法检测到视口的边缘。
这是我用来检测边缘的当前逻辑。
const angle = Math.atan2(mouse.y - vectorCenter.y, mouse.x - vectorCenter.x);
const cosAngle = Math.abs(Math.cos(angle));
const sinAngle = Math.abs(Math.sin(angle));
const vx = (viewport.width - vectorCenter.x) * sinAngle;
const vy = (viewport.height - vectorCenter.y) * cosAngle;
const vpMagnitude = vx <= vy ?
(viewport.width - vectorCenter.x) / cosAngle :
(viewport.height - vectorCenter.y) / sinAngle;
const viewportX = vectorCenter.x + Math.cos(angle) * vpMagnitude;
const viewportY = vectorCenter.y + Math.sin(angle) * vpMagnitude;
const viewPortEdge = {
x: viewportX,
y: viewportY,
};
请帮我弄清楚如何正确检测视口上边缘的位置。
我没有研究为什么这对于顶部会失败,因为有一种比处理角度更简单的方法。你可以通过一些简单的矢量计算得到位置。
首先,为了明确起见并防止将任何值硬编码到计算中,我扩展了您的 viewport
const viewport = {
x: 0,
y: 0,
width: window.innerWidth,
height: window.innerHeight,
get left(){ return this.x },
get right(){ return this.x + this.width },
get top(){ return this.y },
get bottom(){ return this.y + this.height },
};
现在计算:
//prevent division by 0
const notZero = v => +v || Number.MIN_VALUE;
let vx = mouse.x - vectorCenter.x;
let vy = mouse.y - vectorCenter.y;
//that's why I've extended the viewport, so I don't have to hardcode any values here
//Math.min() to check wich border I hit first, X or Y
let t = Math.min(
((vx<0? viewport.left: viewport.right) - vectorCenter.x) / notZero(vx),
((vy<0? viewport.top: viewport.bottom) - vectorCenter.y) / notZero(vy)
);
const viewPortEdge = {
x: vectorCenter.x + vx * t,
y: vectorCenter.y + vy * t,
};
所以 t
是我必须缩放 mouse
和 vectorCenter
之间的矢量以达到该特定方向上最近的边缘的因素。
在示例 fiddle 中:https://jsfiddle.net/krazyjakee/uazy86m4/ 您可以在显示为蓝色方块的矢量点下方拖动鼠标。您将看到这条线从矢量绘制一条路径,通过鼠标到达显示绿色方块的视口边缘,表明它已找到边缘。但是,在矢量上方,绿色方块消失了,因为它无法检测到视口的边缘。
这是我用来检测边缘的当前逻辑。
const angle = Math.atan2(mouse.y - vectorCenter.y, mouse.x - vectorCenter.x);
const cosAngle = Math.abs(Math.cos(angle));
const sinAngle = Math.abs(Math.sin(angle));
const vx = (viewport.width - vectorCenter.x) * sinAngle;
const vy = (viewport.height - vectorCenter.y) * cosAngle;
const vpMagnitude = vx <= vy ?
(viewport.width - vectorCenter.x) / cosAngle :
(viewport.height - vectorCenter.y) / sinAngle;
const viewportX = vectorCenter.x + Math.cos(angle) * vpMagnitude;
const viewportY = vectorCenter.y + Math.sin(angle) * vpMagnitude;
const viewPortEdge = {
x: viewportX,
y: viewportY,
};
请帮我弄清楚如何正确检测视口上边缘的位置。
我没有研究为什么这对于顶部会失败,因为有一种比处理角度更简单的方法。你可以通过一些简单的矢量计算得到位置。
首先,为了明确起见并防止将任何值硬编码到计算中,我扩展了您的 viewport
const viewport = {
x: 0,
y: 0,
width: window.innerWidth,
height: window.innerHeight,
get left(){ return this.x },
get right(){ return this.x + this.width },
get top(){ return this.y },
get bottom(){ return this.y + this.height },
};
现在计算:
//prevent division by 0
const notZero = v => +v || Number.MIN_VALUE;
let vx = mouse.x - vectorCenter.x;
let vy = mouse.y - vectorCenter.y;
//that's why I've extended the viewport, so I don't have to hardcode any values here
//Math.min() to check wich border I hit first, X or Y
let t = Math.min(
((vx<0? viewport.left: viewport.right) - vectorCenter.x) / notZero(vx),
((vy<0? viewport.top: viewport.bottom) - vectorCenter.y) / notZero(vy)
);
const viewPortEdge = {
x: vectorCenter.x + vx * t,
y: vectorCenter.y + vy * t,
};
所以 t
是我必须缩放 mouse
和 vectorCenter
之间的矢量以达到该特定方向上最近的边缘的因素。