Euler angles, while working on a flight simulator

Hi all, i’m quite a beginner, more in 3d level math than in coding (i’m not so confident in my english too), and i’m trying to build from scratch a working flight simulator, not with amazing graphics, just for now a 3d model of a plane and pitch black background…but the first problem i have to solve, and on which i’m spending weeks, are the controls. i have 3 angles for the plane, and i’m applying the rotation in this order, Z, X, Y, the equivalent to roll, pitch and yaw, i already tryied yaw, pitch and roll, but still nothing…i want that whenever i press one of the 6 control keys (2 for each axis) the angle of that axis changes relative to the already changed others, if i move one and then reset all works, but if i want to change multiple angles at once, the all thing go crazy! I just wanted relative rotations…

Here is my code for the plane object, full with commented failed attempts!

function Plane(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
this.upX = 0;
this.upY = 0;
this.rot = 0;
this.dim = 50;
this.color = color(255, 255, 255);

this.show = function () {
  push();
  ambientMaterial(this.color);
  translate(this.x, this.y, this.z);
  rotateZ(this.rot); //never works if not centered
  rotateX(this.upY); //works only after roll-rotateZ-this.rot
  rotateY(this.upX); //works
  ///rotateX(this.upY);
  ///rotateY(this.upX);
  ///rotateZ(this.rot);
  //rotateY(this.upX);
  //rotateX(this.upY);
  //rotateZ(this.rot);
  ellipsoid(this.dim/2, this.dim/5, this.dim, 10, 10);
  translate(0, -20, 40);
  ellipsoid(2, 20, 15, 5, 5);
  pop();
}

this.move = function () {
  this.x += cos(-this.upY)*cos(this.upX);
  this.y += sin(-this.upY);
  this.z += cos(-this.upY)*sin(this.upX);
}

this.update = function () {
  if(keyIsDown(65)) {
    this.rot -= QUARTER_PI / 32;
  }
  if(keyIsDown(68)) {
    this.rot += QUARTER_PI / 32;

  }
  if(keyIsDown(69)) {
    this.upX -= (QUARTER_PI / 32);
    //this.upY += (QUARTER_PI / 32)*sin(this.rot);
    //this.upX -= (QUARTER_PI / 32)*cos(this.upY)*cos(this.rot);
  }
  if(keyIsDown(81)) {
    this.upX += (QUARTER_PI / 32);
    //this.upY += (QUARTER_PI / 32)*sin(this.rot);
    //this.upX += (QUARTER_PI / 32)*cos(this.upY)*cos(this.rot);
  }
  if(keyIsDown(83)) {
    this.upY -= (QUARTER_PI / 32); //relative somehow to upX!
    //this.upY += (QUARTER_PI / 32)*cos(this.upX)*cos(this.rot);
    //this.upX -= (QUARTER_PI / 32)*sin(this.rot)*cos(this.upY);
    //this.rot += (QUARTER_PI / 32)*sin(this.upX)*sin(this.upY);
  }
  if(keyIsDown(87)) {
    this.upY += (QUARTER_PI / 32)*cos(this.upX); //relative somehow to upX!
    this.rot -= (QUARTER_PI / 32)*sin(this.upX);
  }
}
if(this.upY <= 0)
  this.upY = TWO_PI;
else if(this.upY >= TWO_PI)
  this.upY = 0;
if(this.upX <= 0)
  this.upX = TWO_PI;
else if(this.upX >= TWO_PI)
  this.upX = 0;
if(this.rot <= 0)
  this.rot = TWO_PI;
else if(this.rot >= TWO_PI)
  this.rot = 0;

}

NB: upX is the angle moving on X and Z axis, used for the Y axis rotation, usually called PHI, upY is THETA, the elevation above the XZ plane, which rotate on X axis, and i think should do so also on the Z one…and in the end rot is the angle moving on the XY plane which cause the Z axis rotation!
If you want to correlate them to yaw, pitch and roll:
upX -> yaw
upY -> pitch
rot -> roll

Help pleas!

Can I ask you to provide your complete code?

Sure, here is the Sketch.js:

Sketch.js
let plane;

function setup()  {
  createCanvas(windowWidth, windowHeight, WEBGL);
  strokeWeight(0.8);
  plane = new Plane(0, 0, 600);
}

function draw() {
  background(0);
  ambientLight(255);

  plane.update();
  //plane.move();
  plane.show();
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
}

This is Plane.js

Plane.js
function Plane(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.upX = 0;
    this.upY = 0;
    this.rot = 0;
    this.dim = 50;
    this.color = color(255, 255, 255);

    this.show = function () {
      push();
      ambientMaterial(this.color);
      translate(this.x, this.y, this.z);
      rotateZ(this.rot); //never works if not centered
      rotateX(this.upY); //works only after roll-rotateZ-this.rot
      rotateY(this.upX); //works
      ///rotateX(this.upY);
      ///rotateY(this.upX);
      ///rotateZ(this.rot);
      //rotateY(this.upX);
      //rotateX(this.upY);
      //rotateZ(this.rot);
      ellipsoid(this.dim/2, this.dim/5, this.dim, 10, 10);
      translate(0, -20, 40);
      ellipsoid(2, 20, 15, 5, 5);
      pop();
    }

    this.move = function () {
      this.x += cos(-this.upY)*cos(this.upX);
      this.y += sin(-this.upY);
      this.z += cos(-this.upY)*sin(this.upX);
    }

    this.update = function () {
      if(keyIsDown(65)) {
        this.rot -= QUARTER_PI / 32;
      }
      if(keyIsDown(68)) {
        this.rot += QUARTER_PI / 32;

      }
      if(keyIsDown(69)) {
        this.upX -= (QUARTER_PI / 32);
        //this.upY += (QUARTER_PI / 32)*sin(this.rot);
        //this.upX -= (QUARTER_PI / 32)*cos(this.upY)*cos(this.rot);
      }
      if(keyIsDown(81)) {
        this.upX += (QUARTER_PI / 32);
        //this.upY += (QUARTER_PI / 32)*sin(this.rot);
        //this.upX += (QUARTER_PI / 32)*cos(this.upY)*cos(this.rot);
      }
      if(keyIsDown(83)) {
        this.upY -= (QUARTER_PI / 32); //relative somehow to upX!
        //this.upY += (QUARTER_PI / 32)*cos(this.upX)*cos(this.rot);
        //this.upX -= (QUARTER_PI / 32)*sin(this.rot)*cos(this.upY);
        //this.rot += (QUARTER_PI / 32)*sin(this.upX)*sin(this.upY);
      }
      if(keyIsDown(87)) {
        this.upY += (QUARTER_PI / 32)*cos(this.upX); //relative somehow to upX!
        this.rot -= (QUARTER_PI / 32)*sin(this.upX);
      }
    }
    if(this.upY <= 0)
      this.upY = TWO_PI;
    else if(this.upY >= TWO_PI)
      this.upY = 0;
    if(this.upX <= 0)
      this.upX = TWO_PI;
    else if(this.upX >= TWO_PI)
      this.upX = 0;
    if(this.rot <= 0)
      this.rot = TWO_PI;
    else if(this.rot >= TWO_PI)
      this.rot = 0;
  }

Here is the HTML index:

Index
<!DOCTYPE html>
<html>
<div>
  <p style="font-size:32pt" id="score"></p>
</div>
<head>
    <meta charset="UTF-8">
    <title>Motion engine game 3D</title>
    <script src="p5.js" type="text/javascript"></script>
    <script src="p5.dom.js" type="text/javascript"></script>
    <script src="Sketch.js" type="text/javascript"></script>
    <script src="Plane.js" type="text/javascript"></script>
</head>
<style>
    body {
        padding: 0px;
        margin: 0px;
    }
    canvas {
        vertical-align: top;
        position: absolute;
        z-index: -1;
    }
    div {
      position: absolute;
      left: 50px;
      top: 0px;
      text-align: center;
      color: green;
    }
</style>
<body>
</body>
</html>

I hope this will be usefull!

I tested your code, all seems to work as intended, so this seems more of an issue with expectations vs reality. If I understand correctly, you want the yaw-keys to always make the plane rotate “left-to-right”; in other words you want the rotations to always move the plane the same way from the viewers perspective, is that correct?

No, right the opposite ahah, i want it to move correctly from the plane’s prospective…so for example:
if i at first set upX, the yaw, at QUARTER_PI, and then press W, the key to move down the plane’s head, the plane must move down his head on his before rotated X axis (or ZY plane of rotation), but id doesn’s, instead it rotate onto the original YZ plane (x axis), moving in a strange way, not so phiscally acceptable…what i want is to have the camera in place, and the plane flying around (with the plane.move function enable) just like a plane in the sky seen by a man on the ground, which is controlling it!

(As a debug system, maybe you shuld draw 3 torus with similar internal and external radius simulating the 3 rotation axis, that should help you understand…or look at this http://www.ctralie.com/Teaching/COMPSCI290/Materials/EulerAnglesViz/, it doesn’t work as i want because the roll works every time as i imagine it, but if i first roll and than pitch or yaw, they doesn’t work anymore realive to the plane’s shaft…if i yaw and then pitch it works, but the reverse thing doesn’t…)

Ah, that really helps to visualize what you want!

I fiddled around with it and put some sliders on an openprocessing sketch, to help visualize it.
I’m going to admit, this is territory I’m not that familiar with, but maybe this sketch will help.

https://www.openprocessing.org/sketch/588837

I did some googling and ran across this article I learned something new!

1 Like

Amazing, that thing work as i wanted almost in everything, i only noticed that after a yaw or pitch, the roll gets messy…but still a great improvement on mine one! I also am reading the article you attached, and i think is what i was looking for!
This isn’t my usual cup o tee too ahah, but a satysfaing thing when works, thank you far all your help, i’ll post again if i’ll discover something new, or developing a full working thing, just in order to remain in touch!

I can’t believe missed this part! I thought you wanted something completely different :man_facepalming:

Haha, I’m so glad I could help, because I’ve been trying to get it to work like the example you linked.

Definitely update the thread when you get it working :smile: