简体   繁体   中英

Moving an object on a path using p5.js

I'm trying to write a code that mimics what happens in this video in an HTML canvas.

My code differs in that each time the page loads or is refreshed, the radiuses of the two circles are randomly generated. I need the "planets" to travel at the same speed along the circumferences of their respective circles.

I'm using the p5.js to draw to the canvas. Is there something in p5.js that draws an object according to a path, in my case a path that is a circle?

I've looked through the references and came across vectors but I don't quite understand what they do.

My code so far:

var w = window.innerWidth;
var h = window.innerHeight;
var r1, r1;
var d;
var x1, x2, y1, y2;
var angle = Math.PI / 4;

function setup() {
    // canvas setup
    createCanvas(w, h);
    background(255);
    angleMode(RADIANS);

    // randomly generated radiuses 
    r1 = Math.floor(Math.random() * (h/2-300)) + 300;
    r2 = Math.floor(Math.random() * (200-100)) + 100;

    // drawing the two ellipses
    ellipseMode(CENTER);
    noFill();
    ellipse(w/2, h/2, r1*2, r1*2);
    ellipse(w/2, h/2, r2*2, r2*2);

}

function draw() {

    // points on the circles
    x1 = (r1 * (Math.cos(angle))) + (w/2);
    y1 = (h/2) - (r1 * (Math.sin(angle)));
    x2 = (r2 * (Math.cos(angle))) + (w/2);
    y2 = (h/2) - (r2 * (Math.sin(angle)));

    // drawing two circles at those points
    ellipseMode(CENTER);
    noStroke();
    fill('rgb(140, 140, 140)');
    ellipse(x1, y1, 20, 20);
    ellipse(x2, y2, 20, 20);

    // randomly generated color for the line
    var r = random(0, 255);
    var g = random(0, 255);
    var b = random(0, 255);
    stroke(r, g, b);
    strokeWeight(1);
    // drawing the line that connects the two points
    line(x1, y1, x2, y2);

    // animation????
    angle = angle + (10 * (Math.PI / 180));

}

The problem with the last line is that it creates evenly spaces lines , not the pattern that is created in the video.

If the two planets move with the same angle increment they will always retain a relationship causing an evenly spaced line between them.

In order for a line connected between them to cross the center they have to have different incremental values. You would have to maintain two different angle values as well as step (or speed) per angle.

For the example in the video the speed ratio is 1:2.247 based on a real-world relationship between earth and Venus' day-ratio around the sun. Since they differ in speed the line between them will now cross over and produce the pentagram-ish pattern.

I don't know P5.js so I have added a plain JavaScript example below which can be considered pseudo code in case P5 is a requirement. From that you will be able to see how to calculate the two positions at variable speeds.

Example

折断

 var ctx = c.getContext("2d"), ratio = 2.247, // earth:venus ratio 1:2.247 angle1 = 0, // planet 1 current angle angle2 = 0, // planet 2 current angle dlt = 0.05, // angle step (speed) radius1 = 150, // radius path for planet 1 radius2 = 100, // radius path for planet 2 cx = c.width*0.5, // center canvas cy = c.height*0.5, t = 503; // abort animation per # of frames ctx.strokeStyle = "rgba(0,120,255,0.5)"; (function loop() { var x1, y1, x2, y2; x1 = cx + Math.cos(angle1) * radius1; // current (x,y) for planet 1 y1 = cy + Math.sin(angle1) * radius1; x2 = cx + Math.cos(angle2) * radius2; // current (x,y) for planet 2 y2 = cy + Math.sin(angle2) * radius2; ctx.beginPath(); // draw line ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); angle1 += dlt; // increase angle planet 1 angle2 += dlt * ratio; // increase angle planet 2 per ratio if (t--) requestAnimationFrame(loop) })()
 <canvas id=c height=300></canvas>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM