First off a little background: In my game, the player character (and many of the enemies) can face and move in any of 8 predetermined directions: north, south, east, west, and all the interval in between. To help keep track of this, I have 8 static vectors representing each direction, and they are shared between different components as necessary.
I’ve sucessfully implemented key handling to be able to compute which of the eight directions to make the character face. Now, what I want to implement, is a way for the character to rotate from any given current facing direction, to the new direction. The player should also rotate in the smaller angle (e.g. if the player is facing west, and needs to face northwest, it should only rotate 45 degrees clockwise, and not 315 degrees counter-clockwise.)
I figured the best way to implement this type of system would be to check the angle (or rotation ammount) between the current direction, and the new one, and if it is 180 degrees or less rotate one way, otherwise, rotate in the opposite direction. I’ve tried using Vector3f.angleBetween(), but given two points, it will return the same (inside) angle no matter which order they’re tested in.
Ideally I’d like a method where given any two points I could get a distinct rotation ammount given different starting and ending points. Example:
Vector3f north = new Vector3f( 0, 0, 1),
east = new Vector3f(-1, 0, 0);
/* Theoretical method. Assumes counter clockwise only /
checkRotationBetween(north, east); / => 90 degrees /
checkRotationBetween(east, north); / => 270 degrees */
I’ve been trying to study up on linear algebra and the such to help me be able to solve these problems on my own, but alas progress is slow, so if anyone could give me some ideas and help getting up to speed that’d be great. Thanks in advance!
Since you are basically using only 2 dimensions (x and z), you can use Vector2f which has a method called smallestAngleBetween().
I think you could do something like this.
float n = Math.atan2(north.getX(), north.getZ());
float e = Math.atan2(east.getX(), east.getZ());
float angle = e - n;
angle = angle * 360 / (Math.PI*2); //If you want it in degrees
This will give you the angle with values between -180 to +180 degrees.
Well between any give two vectors it should be possible to create a Quaternion that represents a*Quaterion = b
I’m not sure, but maybee in the Quaterion methods there is one usefull.