在 JavaScript Canvas 中沿线移动点
假设我有一条线的坐标(25,35 45,65, 30,85 - 这将是一条由两部分组成的线)。我需要每帧沿着该线以恒定距离移动一个点(汽车)。我该怎么做?
Let's say that I have the coordinates of a line (25,35 45,65, 30,85 - It would be a two part line). I need to move a point (car) along that line at a constant distance every frame. How can I do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
嘿,所以你的 2 条线的坐标为 (25,35) (45,65) (30,85),你想要移动的点将被放置在这些坐标的第一个 (25,35) 处,您希望它向第二个坐标 (45,65)(第一条线段的末端)移动。
第一步是获取点将要移动的方向,方向是点位置与目标位置之间的角度。要找到这个角度,您可以使用 Math.atan2(),将目标位置 Y - 点位置 Y 作为第一个参数传入,将第二个参数传入
目标位置X - 点位置X
。现在获取该角度的正弦和余弦,正弦是沿 Y 轴移动的值,余弦是在 X 轴上移动的量。将正弦和余弦乘以每帧要移动的距离。
好的,现在剩下要做的就是设置重绘方法,在每次调用时将正弦添加到点的 Y 位置,将余弦添加到点的 X 位置。检查该点是否已到达目的地,然后执行相同的过程以移向第二条线段的末端。
Hey, so you have the coordinates (25,35) (45,65) (30,85) for your 2 lines, The point you want to move is going to be placed at the first of these coordinates (25,35) and you want it to move towards the second coordinate (45,65) (the end of the first line segment).
The first step is to get the orientation in which the point is going to move, the orientation is the angle between the point position and the target position. To find this angle you can use the
Math.atan2()
, passing in as the first argument thetarget position Y - the point position Y
, and as the second argument thetarget position X - the point position X
.Now get the Sine and Cosine of that angle, the Sine is the value to move along the Y axis, and the Cosine is how much to move on the X axis. Multiply the sine and cosine by the distance you want to move each frame.
Ok, what is left do to now is just setup the redraw method where you add the sine to the point's Y position and the cosine to the point's X position at each call. Check if the point has arrived to it's destination then do the same process to move towards the end of the second line segment.
晚了 8 年,但有人可能会发现这很有用。这种方法要快得多,因为它不使用 atan、cos、sin 和平方根等都很慢的东西。
将百分比作为 0 到 1 之间的值传递,其中 0 是行的开头,1 是行的结尾。
8 years too late but someone may find this useful. This method is far faster given it doesn't uses stuff like atan, cos, sin and square root of which all are slow.
Pass percentage as value between 0 and 1 where 0 is start of the line and 1 being the end.
考虑这条线 (25,35 45,65)。从开始到结束的向量是(20, 30)。要沿该方向移动点 (x,y),我们只需添加该向量即可:
V = (20, 30)
(x,y) => (x+20,y+30)。
如果我们从行的开头开始,我们就会到达行尾。
但这一步太大了。我们想要更小但方向相同的东西,所以我们将向量乘以 0.1:
V = (2, 3)
(x,y) => (x+2,y+3)=> (x+4,y+6)=> ...
归一化很方便,即使其长度为1,我们通过除以它的长度来实现:
V => V/|V| = (2,3)/sqrt(22 + 32) = (7.21, 10.82)
然后您可以将其乘以您想要的任何步长。
Consider the line (25,35 45,65). The vector from the beginning to the end is (20, 30). To move a point (x,y) in that direction, we could just add that vector:
V = (20, 30)
(x,y) => (x+20, y+30).
If we start at the beginning of the line, we'll arrive at the end.
But that's too big a step. We want something smaller but in the same direction, so we multiply the vector by, say, 0.1:
V = (2, 3)
(x,y) => (x+2, y+3) => (x+4, y+6) => ...
It's convenient to normalize, that is to make its length 1, which we do by dividing by its length:
V => V/|V| = (2,3)/sqrt(22 + 32) = (7.21, 10.82)
Then you can just multiply that by whatever step size you want.
有时,如何将数学公式转换为代码并不是那么明显。以下是沿直线移动点指定距离的函数的实现。它使用矢量表示法:
以及没有
Vector
类的版本:Sometimes it's not so obvious how to translate a mathematical formula into a code. The following is an implementation of a function which moves a point specified distance along a line. It uses vector notation:
And a version without
Vector
class: