如何沿对角线和锯齿形移动对象

How to move an object diagonally and in zigzag?

本文关键字:移动 对象 锯齿形 何沿 对角线      更新时间:2023-09-26

我创建了一个算法来对角线移动粒子,它使用角度工作得很好。基本上,这就是我所做的:

this.x += this.speed * Math.cos(this.angle * Math.PI / 180);
this.y += this.speed * Math.sin(this.angle * Math.PI / 180);
this.draw();

如何将其与锯齿形机芯相结合?

我建议计算与正常路径或amplitude的横向偏差,由下式给出

// Triangle wave at position t with period p:
function amplitude(t, p) {
  t %= p;
  return t > p * 0.25 ? t < p * 0.75 ? p * 0.5 - t : t - p : t;
}

其中t将设置为行进路径的长度,p是"之字形"三角波形态的周期。

给定振幅和前一个位置,我们现在可以通过按照原始代码的描述向前移动,然后将横向偏差添加到我们的位置来轻松计算下一个位置:

  var amplitude = amplitude(distance, p) - this.amplitude(previous_distance, p);
  this.x += amplitude * Math.sin(this.angle * Math.PI/180);
  this.y -= amplitude * Math.cos(this.angle * Math.PI/180);
一个

包含两个可移动对象的完整示例,一个"正常"移动,另一个遵循"锯齿形"模式:

function Movable(x, y, speed, angle, period) {
  this.x = x;
  this.y = y;
  this.speed = speed;
  this.angle = angle;
  this.period = period;
  this.distance = 0;
}
Movable.prototype.moveDiagonal = function() {
  this.distance += this.speed;
  this.x += this.speed * Math.cos(this.angle * Math.PI / 180);
  this.y += this.speed * Math.sin(this.angle * Math.PI / 180);
}
Movable.prototype.amplitudeZigZag = function() {
  var p = this.period, d = this.distance % p;
  return d > p * 0.25 ? d < p * 0.75 ? p * 0.5 - d : d - p : d;
}
Movable.prototype.moveZigZag = function() {
  var amplitude1 = this.amplitudeZigZag();
  this.moveDiagonal();
  var amplitude2 = this.amplitudeZigZag();
  
  var amplitude = amplitude2 - amplitude1;
  this.x -= amplitude * Math.sin(this.angle * Math.PI/180);
  this.y += amplitude * Math.cos(this.angle * Math.PI/180);
}
Movable.prototype.draw = function(context) {
  context.beginPath();
  context.arc(this.x, this.y, 1, 0, 2 * Math.PI);
  context.stroke();
}
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var m1 = new Movable(0, 0, 2, 0, 50);
var m2 = new Movable(0, 0, 2, 0, 50);
for (var i = 0; i < 1000; ++i) {
  m1.angle += Math.cos(i * Math.PI/180);
  m2.angle += Math.cos(i * Math.PI/180);
  m1.moveDiagonal();
  m2.moveZigZag();
  m1.draw(context);
  m2.draw(context);
}
<canvas id="canvas" width="600" height="200"></canvas>

假设您正在向this.angle方向移动,并且您希望在该方向上曲折地从该方向左右移动±45°。 您需要做的就是在计算新仓位时有一个像 var zigzag = 45; 这样的变量,并向this.angle添加zigzag。 要使其呈锯齿形,您需要像这样经常否定它zigzag *= -1;. 如果要停止锯齿形,请设置为 zigzag = 0;

诀窍是知道何时在 ±45° 之间交替。 也许您可以对开关进行定时,并保留对上次使用 Date.now(); 切换时间的引用。 您可以检查当前时间和记录时间之间的差异,然后在超过一定毫秒数后否定zigzag。 只要记得记录上次开关的新时间。 您还可以跟踪行进距离并使用相同的方法,无论哪种方法对您有用。