Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

p5.js - how to rotate image related to the route

I've created a route from two points, set an image that follow the line animation between them. I'd like to rotate the image in the correct angle for every route. Unfortunately it seems follow the Y axis out of the line. How should I pass the correct params? It's possible to adjust dinamically the angle, relate to the line?

let Xz                     = 400;
let Yz                     = 400;

let img_nave;
let img_nave_width;
let img_nave_height;
let sfondo_canvas;

let longitudine_partenza_nave     = 404.2;
let latitudine_partenza_nave      = 296.4;
let longitudine_destinazione_nave = 275.8;
let latitudine_destinazione_nave  = 179.6;

let longitudine_attuale_nave = longitudine_partenza_nave;
let latitudine_attuale_nave  = latitudine_partenza_nave;

let timer = 3600;
let canvas;
let t              = 0;
let etichetta_nave = null;

function preload() {

    img_nave      = loadImage('https://i.imgur.com/ZX2AA5X.png');
    sfondo_canvas = loadImage('https://i.imgur.com/z31o9jV.jpg');

}

function setup() {

    canvas = createCanvas(800, 800);
    frameRate(30);

    etichetta_nave = createButton('Perla nera');

}

function draw() {

    if(etichetta_nave) etichetta_nave.remove();

    let d = int(dist(longitudine_partenza_nave, latitudine_partenza_nave, longitudine_destinazione_nave, latitudine_destinazione_nave));

    background(sfondo_canvas);
    noFill();
    stroke(0);
    strokeWeight(10);
    point(longitudine_partenza_nave, latitudine_partenza_nave);
    stroke(0,0,0);
    point(longitudine_destinazione_nave, latitudine_destinazione_nave);
    stroke(255,0,0);

    if(longitudine_attuale_nave != longitudine_destinazione_nave) {

        if(longitudine_destinazione_nave > longitudine_partenza_nave) longitudine_attuale_nave = longitudine_attuale_nave + (d / timer);
        else longitudine_attuale_nave = longitudine_attuale_nave - (d / timer);

    } else longitudine_attuale_nave = longitudine_destinazione_nave;

    if(latitudine_attuale_nave != latitudine_destinazione_nave) {

        if(latitudine_destinazione_nave > latitudine_partenza_nave) latitudine_attuale_nave = latitudine_attuale_nave + (d / timer);
        else latitudine_attuale_nave = latitudine_attuale_nave - (d / timer);

    } else latitudine_attuale_nave = latitudine_destinazione_nave;

    if(longitudine_attuale_nave != longitudine_destinazione_nave ||
        latitudine_attuale_nave != latitudine_destinazione_nave) {

        line(longitudine_partenza_nave, latitudine_partenza_nave, longitudine_attuale_nave, latitudine_attuale_nave);

    }

    img_nave_width  = 95.75;
    img_nave_height = 57;
    push();
    translate(Xz / 2, Yz / 2);
    rotate(PI / 180 * 45);
    imageMode(CENTER);

    // visualizzo la nave
    image(img_nave, (longitudine_attuale_nave - (img_nave_width / 2)), (latitudine_attuale_nave - (img_nave_height / 2)), img_nave_width, img_nave_height);
    pop();


    etichetta_nave.position((longitudine_attuale_nave + 20), (latitudine_attuale_nave - 10));

    t++;

    if(t >= timer) noLoop();

}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>
like image 318
mimelaine Avatar asked Mar 16 '21 14:03

mimelaine


1 Answers

That code was hard to read, those long variable names do not help...

On the rotation you are not calculating an angle, you need to do that, the formula is simple using Math.atan2( once you get that you can rotate in the correct direction.

Also in your logic I do not see you moving in the right direction there are conditions there but you should be using Math.sin & Math.cos to move in the direction of the angle.

Below is a working example:

let img_nave;
let attuale = {x: 50,  y: 50};
let partenza = {x: 50,  y: 50};
let destinazione = {x: 500,  y: 100};
let angle = Math.atan2(destinazione.y- attuale.y, destinazione.x - attuale.x)

function preload() {
  img_nave = loadImage('https://i.imgur.com/ZX2AA5X.png');
}

function setup() {
  let canvas = createCanvas(600, 180);
  frameRate(30);
}

function draw() {
  background(255)
  strokeWeight(8);
  point(partenza.x, partenza.y);
  stroke(0, 0, 0);
  point(destinazione.x, destinazione.y);
  stroke(255, 0, 0);

  if (dist(destinazione.x, destinazione.y, attuale.x, attuale.y) > 5) {    
    attuale.x += Math.cos(angle)
    attuale.y += Math.sin(angle)
  }
  line(partenza.x, partenza.y, attuale.x, attuale.y);

  push();
  translate(attuale.x, attuale.y);
  rotate(angle + Math.PI);
  imageMode(CENTER);
  image(img_nave, 0, 0, 90, 50);
  pop();
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>

Let me know if you have any questions


You also ask if is possible to adjust dynamically the angle ... sure you can, here is an example

let img_nave;
let attuale = {x: 50,  y: 50};
let angle = 0

var slider = document.getElementById("slider");
slider.oninput = function() {
  angle = this.value/100;
}

function preload() {
  img_nave = loadImage('https://i.imgur.com/ZX2AA5X.png');
}

function setup() {
  let canvas = createCanvas(600, 180);
  frameRate(30);
}

function draw() {
  background(255)
  strokeWeight(8);

  attuale.x += Math.cos(angle)
  attuale.y += Math.sin(angle)

  push();
  translate(attuale.x, attuale.y);
  rotate(angle + Math.PI);
  imageMode(CENTER);
  image(img_nave, 0, 0, 90, 50);
  pop();
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js"></script>
<input type="range" min="-314" max="314" value="0" id="slider">
like image 75
Helder Sepulveda Avatar answered Oct 06 '22 00:10

Helder Sepulveda