Hot questions for Using Lightweight Java Game Library in trigonometry

Question:

alright so im making a ai for a zombie in one of my games, but when i try to rotate the zombie so that he is facing the player everything goes out of wack. they rotate the wrong way, spin around when i get close even though the angle shouldn't change. here is some of my code: ps ignore the z, this game is 3d but im only rotating on on axis so i can code this as though it was xy.

//get camera/player yx
float PlayerYPosition = Player.getPosition().y;
float PlayerXPosition = Player.getPosition().z;
//get zombie yx
float ZombieYPosition = Zombie.getPosition().y;
float ZombieXPosition = Zombie.getPosition().z;
//get side lengths
float sideY = (CameraYPosition - ZombieYPosition);
float sideX = (CameraXPosition - ZombieXPosition);
//get angle
float angle = (float)Math.atan2(sideX,sideY);
//move decimal place out so ex: 0.90f is 90.0f
float ans = angle * 100;
//set rotation of zombie
super.setRotY(ans);

Answer:

Math.atan2 returns its value in radians, not degrees. To convert to degrees, multiply by either 180/pi or 360/(2 pi):

float ans = angle * 180 / Math.PI;

Java even has a builtin function for this, Math.toDegrees: (thanks @yshavit)

float ans = Math.toDegrees(angle);

Also, what @yshavit says in the comments: you should be using radians throughout the code. But that's perhaps too much work, or you might rely on 3rd party libraries which work with degrees.

Question:

i've literally been searching half an hour for this question and i did'nt find what i've been looking for. This is my first lwjgl program. Most of the stuff here is temporary, im just getting used to LWGJL so i can eventually turn this into a game. I'm just getting some basic functions up and running.

So basically, i want my entity to move in the direction of it's angle.

This is my movement code:

public static void moveAtAngle(Entity entity) {
    float x = entity.getX();
    float y = entity.getY();
    float xv = entity.getXV();
    float yv = entity.getYV();
    float angle = entity.getAngle();

    x += xv * Math.cos(Math.toRadians(angle - 90));
    y += yv * Math.cos(Math.toRadians(angle - 90));

    entity.setXAndY(x, y);
}

public static void move(Entity entity, float vel, float anglevel) {
    entity.setXV(entity.getXV() * vel);
    entity.setX(entity.getX() + entity.getXV());
    entity.setYV(entity.getYV() * vel);
    entity.setY(entity.getY() + entity.getYV());
    entity.setAV(entity.getAV() * anglevel);
    entity.setAngle(entity.getAngle() + entity.getAV());
}

This is my main update code:

public static void update() {
    Graphics.move(Entity.sprite, 0.95F, 0.99F);

    Graphics.moveAtAngle(Entity.sprite);

    if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
        Entity.sprite.setAV(Entity.sprite.getAV() + 0.1F);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
        Entity.sprite.setAV(Entity.sprite.getAV() - 0.1F);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
        Entity.sprite.setYV(Entity.sprite.getYV() - 1);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
        Entity.sprite.setYV(Entity.sprite.getYV() + 1);
    }
}

public static void updateGraphics() {
    glMatrixMode(GL_PROJECTION);
    glOrtho(0, SLDisplay.getWidth(), SLDisplay.getHeight(), 0, 1, -1);
    glMatrixMode(GL_MODELVIEW);

    while (!Display.isCloseRequested()) {
        update();

        glPushMatrix();
            glClear(GL_COLOR_BUFFER_BIT);
            glLoadIdentity();
            Graphics.rotate(Entity.sprite);
            Graphics.drawTriangle(Entity.sprite.getX(), Entity.sprite.getY(), 150F, (byte) 150,  (byte) 200, (byte) 255, (byte) 0);
        glPopMatrix();

        Display.update();
        Display.sync(60);
    }

    destroy(false);
}

And my rotate code just for good measures:

public static void rotate(Entity entity) {
    glTranslatef(entity.getX(), entity.getY(), 0);
    glRotatef(-entity.getAngle(), 0, 0, 1);
    glTranslatef(-entity.getX(), -entity.getY(), 0);

    if (entity.getAngle() <= 0){
        entity.setAngle(entity.getAngle() + 360);
    } else if (entity.getAngle() >= 360) {
        entity.setAngle(entity.getAngle() - 360);
    }
}

Please ask if you want to see anything else.

Thanks!


Answer:

There are two problems:

Firstly, Your problem is that you are technically using two directions at once to move your object. 1. You have an angle 2. You have vx and vy which is technically a vector with a direction.

Here are two methods using either of them :

Assuming 0 degrees is positive x

Keep angle

If you want to keep your angle variable you would need to have a general speed variable and then do this for each time you update the x and y:

float radAngle = Math.toRadians(angle);
x += speed * cos(radAngle); 
y += speed * sin(radAngle);

Keep velocities

This method required only using the trig functions each time the velocities change but it also uses the expensive sqrt function with the trigonometry functions. You would need to use vx and vy only. For updates you only would need to do this:

x += vx;
y += vy;

And then for setting vx and vy:

public void setAngle(float angle){
     angle = Math.toRadians(angle);
     float speed = Math.sqrt(vx * vx + vy * vy); //magnitude of movement vector
     vx = speed * Math.cos(angle);
     vy = speed * Math.sin(angle);
}

The second problem is this code:

 glTranslatef(entity.getX(), entity.getY(), 0); 
 glRotatef(-entity.getAngle(), 0, 0, 1);    
 glTranslatef(-entity.getX(), -entity.getY(), 0); 

You will only need to translate it by its x and y why values once as it's x and y values are calculated according to the angle already. (You also seem to be moving the object back to it's original position with the negative translate)

And most java and lwjgl methods will require radians not degrees, so you would need to put

Math.toRadians(angle);

Into glRotate (why a negative before your angle I do not know though)

Question:

I have been wrecking my brain trying to figure out this problem I have. I have a cuboid, its rotation on all 3 axis in relation to the world from its center (it's on 3D space), the cuboid's center's position and the scale of the cube in all axis (width, height and depth). I need to find the coordinates of all of the vertices of the cuboid. While browsing the internet, I only found examples for the 2D cases, and couldn't figure out how to advance to 3D space. Can anyone help me please? I will use it in a game engine made with LWJGL (Light Weight Java Game Library).

Edit: (for @httpdigest):

public Vector3f[] getExtents(){

    Matrix4f m = new Matrix4f();

    m.translate(getPosition());
    m.rotate(getRotation().x, new Vector3f(1, 0, 0));
    m.rotate(getRotation().y, new Vector3f(0, 1, 0));
    m.rotate(getRotation().z, new Vector3f(0, 0, 1));
    m.scale(new Vector3f(getScaleX(), getScaleY(), getScaleZ()));
    Vector3f[] corners = new Vector3f[8];
    for (int i = 0; i < corners.length; i++) {
        int x = i % 2 * 2 - 1;
        int y = i / 2 % 2 * 2 - 1;
        int z = i / 4 % 2 * 2 - 1;
        Vector4f corner = Matrix4f.transform(m, new Vector4f(x, y, z, 1), null);
        corners[i] = new Vector3f(corner.x, corner.y, corner.z);
    }
    return corners;
}

This still isn't accurate, can anyone spot the problem?

Edit: Solution: The angles needed to be in radians, thanks for the support!


Answer:

If you are using LWJGL you can also use JOML, in which case the following is probably what you might want:

import org.joml.*;
public class CubePositions {
  public static void main(String[] args) {
    /* Cuboid center position */
    float px = 10, py = 0, pz = 0;
    /* Euler angles around x, y and z */
    float ax = 0, ay = 0, az = (float) java.lang.Math.PI / 2.0f;
    /* Scale factor for x, y und z */
    float sx = 1, sy = 3, sz = 1;
    /* Build transformation matrix */
    Matrix4f m = new Matrix4f()
        .translate(px, py, pz) // <- translate to position
        .rotateXYZ(ax, ay, az) // <- rotation about x, then y, then z
        .scale(sx, sy, sz);    // <- scale
    /* Compute cube corners and print them */
    Vector3f[] corners = new Vector3f[8];
    for (int i = 0; i < corners.length; i++) {
      int x = i % 2 * 2 - 1;
      int y = i / 2 % 2 * 2 - 1;
      int z = i / 4 % 2 * 2 - 1;
      corners[i] = m.transformPosition(x, y, z, new Vector3f());
      System.out.println(String.format(
          "Corner (%+d, %+d, %+d) = %s",
          x, y, z, corners[i]));
    }
  }
}

It computes a transformation matrix M = T * Rx * Ry * Rz * S given the center position, Euler rotations around x, then y and then z and the given scaling factors of the unit axes, and then transforms the positions of the unit cube corners by that matrix via P' = M * P.