# Thread: Direction between 2 Vectors

1. ## Direction between 2 Vectors

OK so i have 2 3d vector's

the first is the camera and the second is an object i want to look at, my camera system using the mouse relative position so rot.x = rad offset from 0.

So i've been trying to come up with a function to calculate the Radians from vec1 to vec2 and I just can't seem to get anything to work, can anyone save me from this task as my head is about to explode.

I have the xz rotation working fine using: rV.x := ArcTan2( targ.z - posZ, targ.x - posX ); - altho sometimes it does a full rotation reversal

but i need the y axis also to be correct, looking up or down at the object once it is facing it

2. I had this function in my old codes:
Code:
```function Angle3D(x1,y1,z1,x2,y2,z2: double): double;
var a: double;
begin
a:=(x1*x2+y1*y2+z1*z2) /
( sqrt(x1*x1+y1*y1+z1*z1) * sqrt(x2*x2+y2*y2+z2*z2) );
//if a>1 then a:=1 else if a<-1 then a:=-1;
result:=abs(arccos(a));
end;```
It looks slightly unfinished, and i was surprised i didn't clean that up for nxPascal yet. Atleast what i understand, result should always be >= 0. Sqrt insides seem fine, they are always on positive side or 0 so don't need any temp variables either. Not sure what i was thinking with the if-clause.

3. Originally Posted by User137
I had this function in my old codes:...
Your code is perfectly fine. You don't need ABS in the last line though as ArcCos returns values from 0 to Pi. Values inside SQRT will never be negative as they are elevated to square. Detailed math is explained here. As you can see, your code does exactly that - the first part of code calculates dot product and second part divides it by multiplication of two vector lengths. P.S. if a>1 check was probably due to vectors not being of unitary length, which you should normalize instead.

4. I dont think the man is looking for an angle between two vectors. He is asking for the following: given two positions (origin and target) in 3d space he needs the Yaw and Pitch values which will orient the camera looking from the origin at the target. Colin, what I think you are looking for is simply: rV.y := ArcSin(Dir.y); where Dir is a normalized direction vector (Dir := normlize(targ.x - posX, targ.y - posY, targ.z - posZ))

5. Dan, exactly the answer I needed, this is not the first time your post/replies have saved me from myself, I can't thank you enough but thank you very much

@User137, Thanks for your reply, your function will also be useful for other purposes. Thanks.

So my code so far (which works)

Code:
```//
// sets the look at target of the camera
//
procedure TCameraController.setTarget(const targ: TD3DXMatrix);
var
pos, rV: TD3DXVector3;
diff: TD3DXVector3;
begin
pos := D3DXVector3(targ._41, targ._42, targ._43);

D3DXVec3Subtract(diff, pos, position);
D3DXVec3Normalize(diff, diff);

rV := D3DXVector3(
arctan2(diff.z, diff.x),
arcsin(diff.y),
diff.z
);

D3DXVec3Lerp(rotation, rV, rotation, 0.1);
end;```
my only problem now is using the DX function MatrixLookAt for matView seems to have a rotation limit on the yaxis.

6. Originally Posted by Colin
my only problem now is using the DX function MatrixLookAt for matView seems to have a rotation limit on the yaxis.
It could be due to gimbal lock.

7. I was reading about this a few hours ago and I think you may be right, so I think I will add in some quaternion routines and see if I can solve it. Thanks

8. Glad you got it solved, although not by my tip This is how the function ended up to:
Code:
```function Angle(v1, v2: TVector): single;
begin
norm(v1.x, v1.y, v1.z);
norm(v2.x, v2.y, v2.z);
result:=arccos(dot(v1, v2));
end;```
Didn't test yet, but i realized that normalized vectors, when their length is multiplied is 1. That leaves it with just dot product.

9. Originally Posted by User137
Didn't test yet, but i realized that normalized vectors, when their length is multiplied is 1. That leaves it with just dot product.
Actually, dot product of two 3D vectors is an indirect measure of angle between them. So if you need to test some specific cases, you may omit the arccos altogether.

10. Code:
```
rV := D3DXVector3(
arctan2(diff.z, diff.x),
arcsin(diff.y),
diff.z //why do you need this?
);

D3DXVec3Lerp(rotation, rV, rotation, 0.1); // interpolating angles is almost never a good idea, I would bet that whatever trouble you are having is probably caused by this. gimbal lock is a fairly rare phenomenon in 3d graphics and doesn't happen consistently, especially not in your case.```
what I suggest you do if you want to achieve smooth camera tranitions is interpolate direction vectors. or even better - spherically interpolate rotation quaternions.

Page 1 of 2 12 Last

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•