假设我有一条线的坐标(25,35 45,65, 30,85 - 它是由两部分构成的),我需要在每个帧上以恒定距离沿着该线移动一个点(汽车)。我应该如何实现这个功能?
你有两条线的坐标 (25,35) (45,65) (30,85),你想移动的点会被放置在这些坐标中的第一个位置 (25,35),并希望它向第二个坐标 (45,65)(第一条线段的末端)移动。
第一步是确定点要移动的方向,方向是点位置和目标位置之间的角度。为了找到这个角度,你可以使用 Math.atan2()
,将目标位置 Y - 点位置 Y 作为第一个参数传入,将目标位置 X - 点位置 X 作为第二个参数传入。
var Point = {X: 25, Y: 35};
var Target = {X:45, Y:65};
var Angle = Math.atan2(Target.Y - Point.Y, Target.X - Point.X);
现在获取该角度的正弦值和余弦值,正弦值是沿Y轴移动的值,而余弦值是沿X轴移动的值。将正弦值和余弦值乘以每帧要移动的距离。
var Per_Frame_Distance = 2;
var Sin = Math.sin(Angle) * Per_Frame_Distance;
var Cos = Math.cos(Angle) * Per_Frame_Distance;
好的,现在要做的就是设置重新绘制方法,在每次调用时将正弦添加到点的Y位置,将余弦添加到点的X位置。检查点是否已经到达目的地,然后对第二条线段的末端执行相同的过程以向其移动。
虽然晚了8年,但有人可能会觉得这很有用。这种方法更快,因为它不使用atan、cos、sin和平方根等缓慢的函数。
function getPositionAlongTheLine(x1, y1, x2, y2, percentage) {
return {x : x1 * (1.0 - percentage) + x2 * percentage, y : y1 * (1.0 - percentage) + y2 * percentage};
}
通过率作为0到1之间的数值,其中0是线的起点,1是终点。
var xy = getPositionAlongTheLine(100, 200, 500, 666, 0.5);
console.log(xy.x, xy.y);
Math.sqrt(X*X + Y*Y)
。 因此,(20,30)的长度为Math.sqrt(20*20 + 30*30)
,(20,30)规范化后将变为(20 / length, 30 / length)
。 - Deltafunction travel(x, y, dx, x1, y1, x2, y2)
{
var point = new Vector(x, y),
begin = new Vector(x1, y1),
end = new Vector(x2, y2);
return end.sub(begin).norm().mul(dx).add(point);
}
class Vector
{
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
}
clone() {
return new this.constructor(this.x, this.y);
}
add(v) {
this.x += v.x;
this.y += v.y;
return this;
}
sub(v) {
this.x = this.x - v.x;
this.y = this.y - v.y;
return this;
}
mul(x) {
this.x *= x;
this.y *= x;
return this;
}
div(x) {
this.x /= x;
this.y /= x;
return this;
}
get mag() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
norm() {
var mag = this.mag;
if (mag > 0) {
this.div(mag);
}
return this;
}
}
另外还有一种没有使用 Vector
类的版本:
function travel(x, y, dx, x1, y1, x2, y2)
{
var a = {x: x2 - x1, y: y2 - y1},
mag = Math.sqrt(a.x*a.x + a.y*a.y);
if (mag == 0) {
a.x = a.y = 0;
}
else {
a.x = a.x/mag*dx;
a.y = a.y/mag*dx;
}
return {x: x + a.x, y: y + a.y};
}