# Problem aligning a model to an arbitrary vector

This topic is 3813 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I've been struggling with this problem for a while now, so any help would be greatly appreciated. Basically, I'm trying to align a model in 3D to any given vector direction. For example, the model's starting direction is (1, 0, 0) and I'd like to be able to say "face (1, 1, 1)" and the model would be drawn facing (1, 1, 1). Right now I'm using D3DXMatrixRotationAxis() to create an arbitrary axis to rotate about giving it the model's starting direction, (1, 0, 0), and the ending direction I want it to face. I then take the acos of the dot product between the starting vector and the ending vector to get the amount to rotate by. I have a check for the zero vector, so I don't think that's an issue. The issue I'm having is that sometimes I will tell the model to look (0, 0, 1) and it will look (0, 0, -1) for instance. I think the problem comes from not knowing if I should be rotating CW or CCW, but I can't for the life of me figure out how to get that information. Some code if it helps:
void CreateArrow(vector3 pos, vector3 dir)
{
// the arrow starts facing (1, 0, 0)
vector3 start(1, 0, 0);
vector3 RotAxis;

// take the cross product of the starting vector with the new vector, result in RotAxis
D3DXVec3Cross(RotAxis, &start, &dir);

if (RotAxis == vector3(0, 0, 0)) // check for zero vector
RotAxis = vector3(0, 0, 1);

// normalize to easily get the angle between vectors
D3DXVec3Normalize(&dir, &dir);

// get the angle between the starting vector and the new vector
float angle = acos(D3DXVec3Dot(&start, &dir));
}


Thanks

##### Share on other sites
Quote:
 The issue I'm having is that sometimes..

The basic principle looks okay, MightyXL, except for the "zero" check of the RotAxis. If RotAxis==(0,0,0), then angle = 0 and you're done.

Can you provide more info on what the values are that "sometimes" give you a result you don't like?

##### Share on other sites
It would probably be faster for you to just make a matrix and transform by it.
Starting with the direction you want it to look (at), construct the matrix

Matrix.at = at;
Matrix.up = GlobalUp (ie. 0,1,0)
Matrix.left = Matrix.at cross Matrix.up
Matrix.up = Matrix.at cross Matrix.left

then multiply that matrix into your current transform before drawing your model, and it will insure that the global at (1,0,0) of your model now faces in the direction you wanted

##### Share on other sites
Quote:
Original post by Buckeye
Quote:
 The issue I'm having is that sometimes..

The basic principle looks okay, MightyXL, except for the "zero" check of the RotAxis. If RotAxis==(0,0,0), then angle = 0 and you're done.

Can you provide more info on what the values are that "sometimes" give you a result you don't like?

Thanks for the quick response.

The specific vectors that seem to be giving me trouble are (0, 0, 1) and (0, 0, -1). They point in the exact opposite directions. I stepped through my code in the debugger, and it seems to be giving me the correct results, so now I'm still confused.

I give it a direction (0, 0, 1).
It computes the cross product of (1, 0, 0) cross (0, 0, 1) = (0, -1, 0) correctly.
It then gives me an angle of 90 degrees, but for some reason the arrow ends up pointing toward the camera instead of away from it.

The camera is centered at position (0, 0, 0) looking down the z axis (0, 0, 1).

##### Share on other sites
I'm not sure what you mean by the "arrow." Are you drawing a line in space, or rendering a mesh?

If you believe in your calculation, then the problem is elsewhere - some tranformation you do or don't make, or some assumption you've made that's invalid.

For instance, is the untransformed shape of your arrow or model pointing (0,0,1) like you assume in your calc? That is, whatever you create to display as an arrow must be created pointing (0,0,1).

Maybe if you post the code you use to render the object, we could get a better idea where the problem lies.

##### Share on other sites
I'll also note that if you are sticking with your way of rotating the object, all you need to do is get the sign of your angle
by doing
sign ( (start cross dir) dot rotaxis )
and then you have angle * sign, and it should rotate you in the correct direction

##### Share on other sites
sign ( (start cross dir) dot rotaxis ), in this case, will always be 1, I think.

Since rotaxis == start cross dir, the dot of a vector with itself is always 1.

##### Share on other sites
whoops. I was thinking too fast. trying to get you a "to the left or right" sign, but since you can't garentee that you are rotating
with respect to the global up, you unfortunatly can't pick something as simple as cross.y to find out the direction you are turning.

Still, i sugest you just build the new coordinate matrix as I sugested, and multiply by that.

##### Share on other sites
Another thing, MightyXL, just a guess - when you do the rotation, remember you're only changing the direction. For ordinary rotation stuff, like cameras, etc., one maintains a known "up" vector. I'm thinking that the result of a rotation-about-an-axis may or may not give you an "up" for the model you like as the model's local "up" vector will change implicitly with the rotation.

##### Share on other sites
Wow, wasn't expecting so much help, especially on the first day. Thanks again Buckeye and KulSeran.

I would like to try the method you suggested about building another matrix to transform my 3D model by, but I'm having a hard time implementing it. I think I understand the concept well enough, but unfortunately I'm fairly new to using matrices and any sort of 3D DirectX. Right now all I do is loop through all of my objects and apply the following matrix to each object:

iter is just an iterator to my list of objects.

      world = Matrix::CreateScale(iter->Motion->Scale) *              Matrix::CreateRotationAxis(iter->Motion->RotAxis, iter->Motion->Angle) *               Matrix::CreateTranslation(iter->Motion->Position);              iter->Drawable->Draw(world);

I know this is more of an issue with my lack of knowledge, so I understand if it's too much to ask, but should I be putting the at, up, and left vectors into my new matrix as column vectors? I'll try to see what kind of information I can find about matrices online.

Thanks again.

1. 1
2. 2
3. 3
Rutin
15
4. 4
5. 5

• 13
• 26
• 10
• 11
• 9
• ### Forum Statistics

• Total Topics
633734
• Total Posts
3013590
×