2016-07-15 68 views
0

我創建了一個算法來對角地移動一個粒子,它使用一個角度很好地工作。基本上,這是我所做的:如何對角線和曲折移動物體?

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

我該如何將它與鋸齒形運動相結合?

+0

你可以嘗試使用'Math.sin(Date.now())'或類似的東西改變角度。 –

+0

@SeanLeBlanc這使得角度發生變化,但隨着時間的推移,我無法讓它變得越來越小。這只是突然改變每一個新的繪製 –

回答

0

因此,假設您正在朝this.angle方向移動,並且您想沿該方向以該方向從該方向移動到±45°的方向進行鋸齒形。所有您需要做的是有一個像var zigzag = 45;這樣的變量,並在計算新職位時將zigzag加到this.angle。爲了使它成爲之字形,你需要像這樣往往否定它zigzag *= -1;。如果你想停止之字形,請設置zigzag = 0;

技巧是知道什麼時候在±45°之間交替。也許你可以讓開關計時,並保留上次使用Date.now();開關時的參考。您可以檢查當前時間和記錄時間之間的差異,然後在您超過特定毫秒數時否定zigzag。請記住記錄最後一次切換的新時間。你也可以跟蹤旅行的距離,並使用相同的方法,無論爲你工作。

2

我推薦計算從正常路徑或由

// 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給出的橫向偏差amplitude是「鋸齒狀」的週期三角波狀圖案。

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>

+0

尼斯解決方案..! – markE

+0

好的解決方案。您可能想要使用三角波函數f(t)= abs(4 *(t-floor(t + 1/2))) - 1,其中t =時間,頻率爲1,幅度範圍爲 - 1到1.還有一點非常小,與2D API相比,轉換函數是顛倒的。匹配它的'x - = sin(a)* d; y + = cos(a)* d',因此將與'ctx.rotate(a); ctx.translate(0,d);一致; – Blindman67