如何在p5.js中用平滑曲线在两个连续点之间进行插值

时间:2018-11-18 17:24:18

标签: p5.js

我打算使椭圆在停止点之间平稳移动,同时保持旋转。它将在(20,50)点旋转1秒,在平滑曲线(贝塞尔曲线或随机多项式)上过渡到(40,70),旋转到3秒,然后移至(160,190)

当前问题是它在停止点之间跳跃而不是平稳移动。

var angle=0;
var x=[20,40,160] // x coordinates for stop points
var y=[50,70,190] // y coordinates for stop points
var t=[1000,2000,4000] // time for stop points
var i=0;

function setup() {
  createCanvas(400, 400);
}

function draw() {
    background(220);
    frameRate(30);
    translate(x[i],y[i]);
    rotate(angle);


  if (millis() >= t[i] & millis() < t[i+1]){
    i+=1
  }

  fill(0);
  ellipse(0,0, 20, 80);
    angle++
}

1 个答案:

答案 0 :(得分:0)

执行此操作的方法有很多,而采用哪种方法则取决于代码的行为方式。

类似于您的last question的答案,您需要在两点之间显示运动

现在,您正在直接从一个点移动到另一个点。您需要显示中间步骤。

这里有几件值得研究的东西:

  • frameCount变量保存当前帧号。这对于要在特定帧上触发的行为的准确计时很有用。
  • millis()函数返回草图已运行的毫秒数。这对于基于持续时间的逻辑很有用,在这种情况下,您需要在一定数量的秒后执行一些操作。
  • lerp()函数可让您计算随时间变化的值。
  • 还可以使用增量值,在其中每帧将X和Y值移动一定量。

这是最后一种方法的示例:

var circleX = 20;
var circleY = 20;
var mode = 'move right';

function setup() {
    createCanvas(400, 400);
}

function draw() {
    background(200);
    ellipse(circleX, circleY, 20, 20);

    if (mode == 'move right') {
        circleX++;
        if (dist(circleX, circleY, 380, 20) < 1) {
            mode = 'move down';
        }
    } else if (mode == 'move down') {
        circleY++;
        if (dist(circleX, circleY, 380, 380) < 1) {
            mode = 'move left';
        }
    } else if (mode == 'move left') {
        circleX--;
        if (dist(circleX, circleY, 20, 380) < 1) {
            mode = 'move up';
        }
    } else if (mode == 'move up') {
        circleY--;
        if (dist(circleX, circleY, 20, 20) < 1) {
            mode = 'move right';
        }
    }
}

但是请注意,这段代码只是一个示例,这里还有很多改进的余地。重要的是,您需要在每一帧中稍微移动场景,而不是直接从一个点移动到另一个点。