Sign in to follow this  
Doublefris

Simple question concering rotation.

Recommended Posts

Doublefris    316

Hello fellows of gamedev.net. I've been struggling with a bit of a problem on my AI.

 

Me and a friend are working on a space game. Our use-case is a basic kind of AI that will stop and turn to the player when the player comes near.
The problem as follows:

How do I find the (target) angular velocity that will rotate a ship towards a given point?

 

The knee-jerk solution would be to create a look-at rotation matrix, but this isn't an option. The ship must be rotated indirectly by changing it's target velocity. 

I have looked in the book "Artificial Intelligence for Games, Second Edition", from page 180 and on, however this example use quaternions, not matrices like we do.

 

I guess the basic idea would be to align the ships z-axis with the vector between the two ships, however I don't know how to achieve this( my math skills are lacking sad.png )

 

thanks in advance! 

Edited by Doublefris

Share this post


Link to post
Share on other sites
deftware    1778

 I wrote this function for an aimbot project for a popular online game over a decade ago:

 

void VecToAngles( const float *forward, float *angles )
{
	float	tmp, yaw, pitch;
	
	if (forward[1] == 0 && forward[0] == 0)
	{
		yaw = 0;
		if (forward[2] > 0)
			pitch = 90;
		else
			pitch = 270;
	}
	else
	{
		yaw = (atan2(forward[1], forward[0]) * 180 / 3.14159);

		if (yaw < 0)
			yaw += 360;

		tmp = sqrt (forward[0]*forward[0] + forward[1]*forward[1]);
		
		pitch = (atan2(forward[2], tmp) * 180 / 3.14159);
	}
	
	angles[0] = pitch;
	angles[1] = yaw;
	angles[2] = 0;
}

 

 

 

 The rest is history.

Share this post


Link to post
Share on other sites
Doublefris    316

This should probably be moved to "Math & Physiscs".

Why don't you use quaternions for this computation? It's much easier to do that way.

 

The main reason is our code base doen't have support for quaternions as of now. Furthermore I have never used quaternions before and therefore am not really comfortable with them. Anyway, do you really think the only suitable solution would be quaternions?

Share this post


Link to post
Share on other sites
alvaro    21246

The main reason is our code base doen't have support for quaternions as of now. Furthermore I have never used quaternions before and therefore am not really comfortable with them. Anyway, do you really think the only suitable solution would be quaternions?

No, I don't think it's the only solution, but it's probably the easiest. If you stick to representing attitudes as matrices, figuring out the most natural transition between two attitudes involves some heavy math.

Share this post


Link to post
Share on other sites

How do I find the (target) angular velocity that will rotate a ship towards a given point?

You can calculate the target angular velocity vector by taking the cross product of the current direction and the desired direction, and scaling according to the desired rotation speed.  That leaves the question of the ship's roll when it reaches the destination, though - if you care about that, this problem becomes more complicated.

Share this post


Link to post
Share on other sites
Doublefris    316

How do I find the (target) angular velocity that will rotate a ship towards a given point?

You can calculate the target angular velocity vector by taking the cross product of the current direction and the desired direction, and scaling according to the desired rotation speed.  That leaves the question of the ship's roll when it reaches the destination, though - if you care about that, this problem becomes more complicated.

 

this is a very nice solution smile.png seems to be working well so far. As for the roll, I think it's fine to have spaceship gravitate towards an 'up' vector, or I'll just figure something out :)

Edited by Doublefris

Share this post


Link to post
Share on other sites
Doublefris    316

The main reason is our code base doen't have support for quaternions as of now. Furthermore I have never used quaternions before and therefore am not really comfortable with them. Anyway, do you really think the only suitable solution would be quaternions?

No, I don't think it's the only solution, but it's probably the easiest. If you stick to representing attitudes as matrices, figuring out the most natural transition between two attitudes involves some heavy math.

 

Say, if we were to implement quatornions, what would be the basic steps used to get an angular velocity? Find the angular displacement vector that is the lowest?

Share this post


Link to post
Share on other sites
alvaro    21246

Say, if we were to implement quatornions, what would be the basic steps used to get an angular velocity? Find the angular displacement vector that is the lowest?

You would take the logarithm of the ratio of the target attitude and the current attitude. This is a quaternion whose real part is 0; the other three components give you the angular velocity that, when applied for 1 second, will convert the current attitude into the target attitude.
#include <iostream>
#include <boost/math/quaternion.hpp>

typedef boost::math::quaternion<double> Q;

int main() {
  Q a(0.0, 1.0, 0.0, 0.0);
  Q b(0.0, 0.0, 1.0, 0.0);

  Q ratio = b / a;
  double scale = std::acos(ratio.R_component_1());
  Q log_of_ratio(0.0,
                 scale * ratio.R_component_2(),
                 scale * ratio.R_component_3(),
                 scale * ratio.R_component_4());

  std::cout << log_of_ratio << '\n';
}

Edited by Álvaro

Share this post


Link to post
Share on other sites
Doublefris    316

So I got it to work in XNA and it works beatifully, however using my own quaternion class or directx's quaternions the spaceship keeps 'flipping over' when you get behind on the Z axis it seems.  Is there something specific I'm doing wrong?

 

my basic algorithm is : 

 

 

Quaternion q1 = (shipforward, 0.0f)

Quaternion q2 = (shipposition - LookAtPosition, 0.0f)

 

then get the angular velocity using the method you described. weird thing is it works very well in XNA but trying to port it to my c++ engine keeps bringing this annoying bug.

 

A reason I thought of is that my division operator is wrong? what is the exact implementation of the division operator here?

Edited by Doublefris

Share this post


Link to post
Share on other sites

What problems with flipping are you having?

 

If you set up a quaternion with just a vector part and the w part being 0 you get a 180 degree rotation around the axis specified in the imaginary part... probably not what you want.

 

If flipping means you interpolate "the long way round" you can get rid of that by doing a dot product (in 4d) of the 2 quaternions and negating one if the dot product is negative.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this