如何根据矢量和角度计算视口的边缘?

时间:2018-02-04 11:34:36

标签: javascript geometry angle

首先,我邀请您查看此演示,以便我可以使用此问题中的元素作为参考:https://jsfiddle.net/krazyjakee/01rqec1e/2/

如果在演示中移动鼠标,可以看到红色点跟随蓝色方块边缘限制的鼠标。这完全符合这种逻辑。

const mouse = {
    x: e.pageX,
    y: e.pageY,
};

const target = block.getBoundingClientRect();
const targetCenter = {
    x: Math.floor(target.left + (target.width / 2)),
    y: Math.floor(target.top + (target.height / 2)),
};

const angle = Math.atan2(mouse.y - targetCenter.y, mouse.x - targetCenter.x);

const cosAngle = Math.abs(Math.cos(angle));
const sinAngle = Math.abs(Math.sin(angle));

const magnitude = target.width / 2 * sinAngle <= target.height / 2 * cosAngle ?
    target.width / 2 / cosAngle :
    target.height / 2 / sinAngle;

const targetEdge = {
    x: targetCenter.x + Math.cos(angle) * magnitude,
    y: targetCenter.y + Math.sin(angle) * magnitude,
};

然后我取结果并使用它来查找视口边缘上的最近点:

const viewportMagnitude = {
    x: (viewport.width / target.width),
    y: (viewport.height / target.height),
};

const viewPortEdge = {
    x: (targetEdge.x - target.left) * viewportMagnitude.x,
    y: (targetEdge.y - target.top) * viewportMagnitude.y,
};

但是,如果您想象从蓝色正方形的中心,通过红点和鼠标的线,它不会与视口边缘的绿色方块对齐。我需要调整什么来使绿色方块与红色方块和鼠标对齐?

1 个答案:

答案 0 :(得分:0)

当广场未居中(并且视口不是方形)时,似乎您的viewportMagnitude方法无法正常工作

所以你可以使用另一种方法。

x0,y0是光线起点 - 这里是targetCenter.x,targetCenter.y
x1,y1和x2,y2是视口的角坐标 - 在这里,我认为,0,0和宽度,高度

corrected JS test

//preliminary
const x0 = targetCenter.x; 
const y0 = targetCenter.y; 

const x1 = 0;
const y1 = 0;

const x2 = viewport.width;
const y2 = viewport.height;

const vx = mouse.x - x0;
const vy = mouse.y - y0;

vx = mouse.x - x0
vy = mouse.y - y0

//ray equations (parametric form, t is parameter):
//just for reference, they do not take part in calculations
//x = x0 + vx * t
//y = y0 + vy * t

//potential border positions    
if vx > 0 then
   ex = x2
else
   ex = x1

if vy > 0 then
   ey = y2
else
   ey = y1

 //check for horizontal/vertical directions
if vx = 0 then
return cx = x0,  cy = ey,

if vy = 0 then
    return cx = ex, cy = y0


//in general case find times of intersections with horizontal and vertical edge line
  tx = (ex - x0) / vx
  ty = (ey - y0) / vy

 //and get intersection for smaller parameter value
 if tx <= ty then 
    return cx = ex, cy = y0 + tx * vy
 else
    return cx = x0 + ty * vx,  cy = ey