旋转一条线看鼠标用线性插值会导致跳跃

问题描述 投票:0回答:1

早些时候,我试图找出如何使用 p5.js 围绕枢轴旋转一条线,我稍微修改了一下代码,使用

atan2
函数使线指向鼠标。它工作得很好,我决定看看如果我使用线性插值 (
lerp
) 来使动画看起来更平滑,会是什么样子。奇怪的是,这条线似乎一旦经过某个点,就会跳到另一边,而不是仅仅移动到该点。

这是我遇到问题的代码:

let angle = 0;

let rot = 0;

function setup() {
  createCanvas(600, 300);
}

function draw() {
  let v1 = createVector(width / 2 - 50, height / 2);
  let v2 = createVector(width / 2 + 50, height / 2);

  background(255);
  stroke(0);
  strokeWeight(4);

  rot = lerp(rot, atan2(mouseY - v1.y, mouseX - v1.x), 0.1);

  push();
  translate(v1.x, v1.y);
  rotate(rot);
  translate(-v1.x, -v1.y);
  let r0 = line(v1.x, v1.y, v2.x, v2.y);
  strokeWeight(10);
  let p1 = point(v1.x, v1.y);
  let p2 = point(v2.x, v2.y);
  pop();
}

怎样才能让这个动画看起来流畅,没有奇怪的跳跃?

javascript geometry p5.js lerp
1个回答
0
投票

问题是因为

atan
返回
-Math.PI
+Math.PI
之间的值,因此在表达式
target_angle = atan2(mouseY - v1.y, mouseX - v1.x)
的线性插值失败的地方存在跳跃。

这就是为什么,为了使当前

rot
target_angle
之间的路径最短,我们应该对两者之间的差异进行归一化,以便覆盖其
abs
值的距离应小于
Math.PI
(半圆)

let angle = 0;

let rot = 0;

function setup() {
  createCanvas(600, 300);
}

function draw() {
  let v1 = createVector(width / 2 - 50, height / 2);
  let v2 = createVector(width / 2 + 50, height / 2);

  background(255);
  stroke(0);
  strokeWeight(4);


  let target = atan2(mouseY - v1.y, mouseX - v1.x);

  while (target - rot > Math.PI) {
    target -= 2 * Math.PI;
  }

  while (target - rot < -Math.PI) {
    target += 2 * Math.PI;
  }

  rot = lerp(rot, target, 0.1);

  push();
  translate(v1.x, v1.y);
  rotate(rot);
  translate(-v1.x, -v1.y);
  let r0 = line(v1.x, v1.y, v2.x, v2.y);
  strokeWeight(10);
  let p1 = point(v1.x, v1.y);
  let p2 = point(v2.x, v2.y);
  pop();
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.