完成效果如下图所示:
鼠标移到直线上时,会在当前位置画一个小红点,移开鼠标擦除小红点
其中关键算法如下
var line = { x0: 50, y0: 50, x1: 100, y1: 100 };
//x,y为传入的鼠标坐标
function linepointNearestMouse(line, x, y) {
//线性插值
lerp = function(a, b, x) {
return (a + x * (b - a));
};
var dx = line.x1 - line.x0;
var dy = line.y1 - line.y0;
//这里的t是怎么计算出来的,用到什么公式?
var t = ((x - line.x0) * dx + (y - line.y0) * dy) / (dx * dx + dy * dy);
var lineX = lerp(line.x0, line.x1, t);
var lineY = lerp(line.y0, line.y1, t);
return ({
x: lineX,
y: lineY
});
};
function handleMousemove(e) {
e.preventDefault();
e.stopPropagation();
mouseX = parseInt(e.clientX - offsetX);
mouseY = parseInt(e.clientY - offsetY);
//如果鼠标不在线段的矩形范围内则忽略
if (mouseX < line.x0 || mouseX > line.x1) {
$hit.text("Outside");
draw(line);
return;
}
//为什么这里的linepoint就是直线上的点坐标?
var linepoint = linepointNearestMouse(line, mouseX, mouseY);
var dx = mouseX - linepoint.x;
var dy = mouseY - linepoint.y;
var distance = Math.abs(Math.sqrt(dx * dx + dy * dy));
//如果当前鼠标位置与linepoint的距离小于5,则绘制小红点
if (distance < 5) {
$hit.text("Inside the line");
draw(line, mouseX, mouseY, linepoint.x, linepoint.y);
} else {
$hit.text("Outside");
draw(line);
}
}
有疑问的地方在代码注释中标出来了,目前对于线性插值中的t参数怎么算出来的不是很清楚,好像用到向量?求大佬指导一下,谢谢了~~~
只研究到这个地方,明天有时间我再研究研究吧
谢谢大佬,根据你的提示,我从点斜式开始推导,然后得到两点式直线方程,到这一步就不知道怎么运用了,而代码中的 t
似乎是一个时间插值,可以通过它求出两点直线上的任一点坐标。最后推导出的公式和这个t的求解过程很像,但是分母没有开方,分子应该是求和,请问怎么理解呢?
@逐影: 你确定你这个题目没什么错误嘛,为什么给的两个点是(50, 50), (100, 100)但是上图显示的应该是(50, 100)和(100, 50) 才对
如果没错误的话,直线上的两点就应该是(x0, y1)和(x1, y0),这时候可以这样推导:
如果有错误的话就把y1和y0对调就可以了
@编程小白-郭旭: 大佬太厉害了,推导的过程非常严谨👍👍👍,今天弄了一天,就是没有想到
l = tL
这一步😭,
坐标是(x0,y0) = (50,50) (x1,y1) = (100,100)
给大佬追加了分数😄
另外能不能指导一下我的另一个算法问题
多标签排列避免重叠算法
非常感谢你的帮助
各位不考研可惜了