2016-07-15 3 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;. Если вы хотите остановить zig-zagging, установите zigzag = 0;.

Трюк - это знать, когда нужно чередовать между ± 45 °. Возможно, вы можете включить таймер переключения и сохранить ссылку на последний раз, когда вы переключались с помощью Date.now();. Вы можете проверить разницу между текущим временем и записанным временем, а затем отрицать zigzag, как только вы превысите определенное количество миллисекунд. Не забудьте записать новое время последнего переключения. Вы также можете отслеживать пройденное расстояние и использовать тот же подход, независимо от того, что работает для вас.

2

Я рекомендую расчет бокового отклонения от нормальной траектории или 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>

+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

Смежные вопросы