how to interpolate between two consecutive points

2019-08-30 00:01发布

I intend to have an ellipse move smoothly between the stop points while keep rotating. It'll rotate for 1sec at point (20,50), transition to (40,70) on a smooth curve (bezier or random polynomial) and rotate till 3sec and move on to (160,190)

The current issue is that it jumps between stop points rather than move smoothly.

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++
}

标签: p5.js
1条回答
成全新的幸福
2楼-- · 2019-08-30 00:40

There are a lot of different ways to do this, and which approach you take depends on exactly how you want your code to behave.

Similar to the answer to your last question, you need to show the movement between the points.

Right now you're moving directly from one point to another. You need to show the intermediate steps.

Here are a few things to look into:

  • The frameCount variable holds the current frame number. This is useful for exact timing of behaviors that you want to trigger on specific frames.
  • The millis() function returns the number of milliseconds the sketch has been running. This is useful for duration-based logic, where you want to do something after a certain number of seconds.
  • The lerp() function allows you to calculate values that change over time.
  • You could also use delta values, where you move the X and Y values by some amount each frame.

Here's an example of that last approach:

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';
        }
    }
}

But please note that this code is just an example, and there's a ton of room for improvement here. The important thing is that you need to move the scene a little bit each frame, instead of going directly from one point to another.

查看更多
登录 后发表回答