p5.js - 如何将图像与路线相关联进行旋转

6

我已经创建了两个点之间的路线,设置了一个跟随路径动画的图像。我想为每条路线正确旋转图像。不幸的是,似乎沿Y轴跟踪出了线路。我应该如何传递正确的参数?是否可以根据线路动态调整角度?

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/p5@1.3.0/lib/p5.js"></script>

1个回答

3

那段代码难以阅读,那些过长的变量名并没有起到帮助作用...

在旋转时你没有计算角度,你需要这么做,使用简单的公式 Math.atan2( 即可旋转至正确方向。

此外,在你的逻辑中我没有看到你朝着正确的方向移动,虽然有条件,但你应该使用 Math.sinMath.cos 沿着角度移动。

以下是一个可行的示例:

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/p5@1.3.0/lib/p5.js"></script>

如果您有任何问题,请告诉我。


您还可以询问是否可以动态调整角度......当然可以,这里有一个例子。

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/p5@1.3.0/lib/p5.js"></script>
<input type="range" min="-314" max="314" value="0" id="slider">


@mimelaine,您好。 - Helder Sepulveda
抱歉,但现在计时器不起作用了。如我在问题中所述,脚本需要在规定的时间内按照路线行驶。谢谢! - mimelaine
@mimelaine 是的,为了让我的示例代码更简单,我去掉了计时器的部分,只演示了图像旋转... 正如你在问题中展示的那样,你知道如何使用计时器,你所要做的就是将我的示例中的公式合并到你的项目中。 - Helder Sepulveda
明白了,只是我的变量理解有误。再次感谢。 - mimelaine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接