Как сделать гладкую дуговую дорожку для одной точки VEC2 в другую?Javascript

Форум по Javascript
Ответить Пред. темаСлед. тема
Anonymous
 Как сделать гладкую дуговую дорожку для одной точки VEC2 в другую?

Сообщение Anonymous »

У меня есть несколько теоретический и основанный на мнениях вопрос. Я строю небольшой генератор частиц с целью создания анимированных изображений (разработанных с использованием JS Web2D Canvas, чтобы легко загрузить полученный файл позже). Проблема заключается в том, что текущее движение от одной точки к другой (например, генератор частиц к конечной точке разрушения) является очень простым, и я хотел бы достичь чего -то более естественного. Я пробовал несколько вещей, но я хотел бы услышать мнение других людей о математических формулах или просто интересных и естественных моделях, которым нужно следовать. Ниже приведен пример того, как он работает в настоящее время, и базовый код, который я использую для путей.class Particle {
/** @type {Vec2} */
pos = { x: 0, y: 0 };

/** @type {string} */
color;

/** @type {number} */
lifespan = PARTICLE_LIFESPAN;

/** @type {Vec2[]} */
trail = [];

/** @type {number} */
trailLength = Math.floor(Math.random() * PARTICLE_MAX_LENGTH);

/** @type {number} */
targetIndex = Math.floor(Math.random() * targets.length);

/** @type {Vec2} */
target =
targets.length > 0
? targets[this.targetIndex]
: { x: Math.random() * -CANVAS_SIZE_X, y: Math.random() * CANVAS_SIZE_Y * 2 };

/** @type {number} */
spawnIndex = Math.floor(Math.random() * spawners.length);

constructor() {
// particle spawn position
this.pos.x =
spawners.length > 0
? spawners[this.spawnIndex].x
: Math.floor(Math.random() * CANVAS_SIZE_X) + 50;
this.pos.y =
spawners.length > 0
? spawners[this.spawnIndex].y
: Math.floor(Math.random() * CANVAS_SIZE_Y) - 50;

// particle color
this.color = PARTICLE_COLOR
? PARTICLE_COLOR
: `#${Math.max(0x100, Math.round(Math.random() * 0xfff))}`;

// creating trail
for (let i = 0; i < this.trailLength; ++i) {
this.trail.push({ x: this.pos.x, y: this.pos.y });
}
}

spread() {
switch (Math.round(Math.random() * 4)) {
case 0:
this.pos.x += PARTICLE_SPREAD;
break;
case 1:
this.pos.x -= PARTICLE_SPREAD;
break;
case 2:
this.pos.y += PARTICLE_SPREAD;
break;
case 3:
this.pos.y -= PARTICLE_SPREAD;
break;
}
}

/** @param {Vec2} target */
follow(target) {
this.trail.push({ x: this.pos.x, y: this.pos.y });
if (this.trail.length > this.trailLength) {
this.trail.shift();
}

if (this.pos.x target.x + 10) {
this.pos.x -= PARTICLE_VELOCITY;
}

if (this.pos.y target.y) {
this.pos.y -= PARTICLE_VELOCITY;
}

if (this.pos.x === target.x && this.pos.y === target.y) {
if (targets.length > 0) {
this.target = targets[this.targetIndex - 1];
}
}
}
}
< /code>
[рендеринговый код] < /p>
/** @param {CanvasRenderingContext2D} ctx */
function render(ctx) {
/** @type {Particle[]} */
const ps = [];

// reusable variables
let i = 0,
y = 0;

const loop = () => {
ctx.fillStyle = CANVAS_BACKGROUND_COLOR;
ctx.fillRect(0, 0, CANVAS_SIZE_X, CANVAS_SIZE_Y);

if (ps.length < PARTICLE_NUMBER) {
for (; i < PARTICLE_NUMBER - ps.length; ++i) ps.push(new Particle());
i = 0;
}

// rendering particles
for (; i < ps.length; ++i) {
ps.lifespan -= 1;

for (; y < ps.trail.length - 1; ++y) {
ctx.strokeStyle = ps.color;
ctx.beginPath();
ctx.moveTo(ps.trail[y].x, ps.trail[y].y);
ctx.lineTo(ps.trail[y + 1].x, ps.trail[y + 1].y);
ctx.stroke();
}
y = 0;

ps.spread();
ps.follow(ps.target);

if (
ps[i].lifespan CANVAS_SIZE_X + PARTICLE_MAX_LENGTH * 2 ||
ps[i].pos.y < -PARTICLE_MAX_LENGTH * 2 ||
ps[i].pos.y > CANVAS_SIZE_Y + (CANVAS_THRESHOLD + PARTICLE_MAX_LENGTH)
) {
ps.splice(i, 1);
}
}
i = 0;

// rendering targets
for (; i < targets.length; ++i) {
ctx.fillStyle = "#ffffff95";
ctx.fillRect(targets[i].x, targets[i].y, 4, 4);
ctx.fillStyle = "#fff";
ctx.fillText(`${i}`, targets[i].x + 2, targets[i].y - 6, 12);
}
i = 0;

// rendering spawnpoints
for (; i < spawners.length; ++i) {
ctx.fillStyle = "#4800c695";
ctx.fillRect(spawners[i].x, spawners[i].y, 4, 4);
ctx.fillStyle = "#0fde00ff";
ctx.fillText(`${i}`, spawners[i].x + 2, spawners[i].y - 6, 12);
}
i = 0;

window.requestAnimationFrame(loop);
};

loop();
}


Подробнее здесь: https://stackoverflow.com/questions/797 ... to-another
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Javascript»