Game Development Stack Exchange is a question and answer site for professional and independent game developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

So I'm modding a 3D game, my goal is to place a label on the screen pointing to the unit's direction. I'm getting the horizontal angle by projecting these vectors in a plane, like this:

private double getXAxisAngle(EntityPlayer player,EntityPlayer player2){

    double meYaw = player2.rotationYaw;
    double meX = player2.posX;
    double meZ = player2.posZ;
    double playerX =  player.posX -meX;
    double playerZ =  player.posZ-meZ;
    double yawX = Math.cos(Math.toRadians(meYaw));
    double yawY = Math.sin(Math.toRadians(meYaw));
    double dist = getDist(playerX,playerZ);
    playerX = playerX / dist;
    playerZ = playerZ / dist;
    dist = getDist(yawX,yawY); //get the vector magnitude
    yawX = yawX / dist;
    yawY = yawY / dist;
    double angle1 = Math.toDegrees(Math.atan2(yawY, yawX));
    double angle2 = Math.toDegrees(Math.atan2(playerZ, playerX));
    double angle = angle1-angle2;
            angle+=90; //So when it's facing the other unit it becomes 0
    if(angle > 180)
    else if(angle < -180)
        angle += 360;

    return angle;

This function gives me an angle between 0/-180 and 0/+180, depending on which side I'm facing then I get this angle and transform into a coord into the screen like this:

private double angleXToPosition(double angle,FontRenderer fontrenderer,String label)
    ScaledResolution scaledresolution =
        new ScaledResolution(mc.gameSettings, mc.displayWidth, mc.displayHeight);

    double width = scaledresolution.getScaledWidth();

    double namePosX =
        (int)(angle * ((width / 2 - (fontrenderer.getStringWidth(label) / 2)) / 50)) +
        width / 2 - (fontrenderer.getStringWidth(label) / 2);

    //If the angle is bigger then 50 the label sticks on the side of the screen
    if (angle > 50)
        namePosX = width - (fontrenderer.getStringWidth(label));
    else if (angle < -50)
        namePosX = 0; //Same as above

    return namePosX;

And it works until this, the label moves perfectly to the sides, accompanying the unit position on the screen, but now I'm trying to make the label move up and down and the same functions doesn't work, and I can't figure this out.

Some info: the pitch of the player when facing the sky is -90 and when facing the ground is 90.

share|improve this question

migrated from Sep 3 '11 at 23:46

This question came from our site for professional and enthusiast programmers.

How about simply setting x <- 0 & y <- 0, then x <- z; Calculate angle between these two new vectors – Peter Ølsted Sep 4 '11 at 8:21

first of all I'm curious about this part :

double namePosX =
    (int)(angle * ((width / 2 - (fontrenderer.getStringWidth(label) / 2)) / 50)) +
    width / 2 - (fontrenderer.getStringWidth(label) / 2);

are you sure you have to multiply angle by some value? we usually first compute sin or cos of the angle!

after that I suggest you change your angle computing functions to these ones (it's just a sudo code):

void getAxisAngle(EntityPlayer a, EntityPlayer b, out double yaw, out double pitch)
    double deltaX = a.posX - b.posX;
    double deltaY = a.posY - b.posY;
    double deltaZ = a.posZ - b.posZ;
    yaw = atan2(deltaY,deltaX);
    pitch = asin(deltaZ / sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ));

both atan2 and asin are already defined in math libraries so you just have to find them in your standard language library. there is a slim chance that you can't find atan2, if that's the case you have to create your own version of atan2 using atan.

sidenote : * atan = arctangent * asin = arcsine

share|improve this answer
The first code you quoted is used to parse the angle i get from the getXAxisAngle function to the position in the screen, this is how it works, (angle * ((width / 2 - (fontrenderer.getStringWidth(label) / 2)) / 50)) this part gives me the amount i have to move the label in the screen, i.e.: i start the game looking at the other unit so the angle is 0 using 0 in this function i'll get 180 which is the center of the screen minus the half of the length of the string i'm drawing. The second code you don't mention the yaw, which i need because the angle i need is between my view and the other unit. – Rodrigo Cavalcante Sep 4 '11 at 14:51
horizentalAngle I'm computing is the yaw value you are looking for, I just couldn't remember word "yaw" at the time posting my answer. – Ali.S Sep 4 '11 at 15:08
Still, the code doesn't take into account my view direction, i think i wasn't clear, sorry, what i want is the angle between the viewing of the player i'm playing and another player – Rodrigo Cavalcante Sep 4 '11 at 16:28

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.