Problems with Vectors

Started by
16 comments, last by Driv3MeFar 17 years, 10 months ago
Hi all, I'm making a sort of 'mostly 2d' tile engine but using 3d graphics for the lot of it (nothing new to you guys I'm sure, just textured quads for the most part). For the standard 2d mode I'm just using an orthographic camera and all works as I want. For the 3d stuff I have run into a problem. I want to find a way to lock the camera's view onto a sprite irregardless of the camera's location in the scene. So irregardless of the value of the camera's eye vector I want to rotate the look vector to point at the sprite that's targeted. Vector math is a whole new area for me. I suspect this has something to do with taking the cross product of the sprite's vector and the camera's look vector but I really have no idea. I don't need anyone to spell it out step by step with commented code or anything but a general explanation to do what I'm trying to do would be awesome. ANY help is greatly appreciated. Thanks! Orphean
Advertisement
Are you using directx, or opengl?

Cause there a specific functions that generate the views via transofrmation matrix, unless of course you gnerate thme yourself

Edit: you jus generate a transformation matrix, like i said above.
A wiseman once said nothing, but no one was there to hear it.
I'm using Direct3d.

Thanks for the reply I guess I'll go lookup what I can about generating transformation matrices in the api.
Quote:Original post by orphean
I'm using Direct3d.
It sounds like what you want is a 'look at' matrix; DirectX has functions for this, but it's also fairly straightforward to generate your own. Just ask if you need further details.
Any details you're willing to part with would be fantastic! :)

Quote:Original post by orphean
Any details you're willing to part with would be fantastic! :)


the first step to constructing the lookat matrix is defining local your coordinate axis wrt your target.

to build the matrix, you'll need to provide the worlds "up" vector (typically +Y, in the directX coord system). knowing the "up" vector and the target location, construct your axis like so:

(note that after finding each of these vectors, they should be normalized)
vector vZ = target position - camera position;
vector vX = vZ (cross) up;
vY = vX (cross) vZ; <--(no need to normailze this, the magnitude of the cross product of two orthonormal vectors is always 1)

the last part of your lookat matrix (it will be a 4x4) comes from taking the inverse of the translation from the world origin to your cameras current position, which, with a little more vector math, gives you the following matrix:
(let P = cameras world position)

| vX.x, vX.y, vX.z, 0|
| vY.x, vY.y, vY.z, 0|
| vZ.x, vZ.y, vZ.z, 0|
|-(vX (dot) P), -(vY (dot) P), -(vZ (dot) P), 1|

disclaimer: my vector math is a little rusty, the matrix may be a bit off, but its something like that

edit: another way of solving this problem, which you elluded to in your first post, would be to make a vector from the camera position to the target, take the cross product of that vector with the cameras current look vector to find an axis orthogonal to both, and rotate your camera about that axis by the angle between the two vectors (as can be found with a dot product). this will accomplish the same thing as the lookat matrix, but I believe it would be a bit slower.

[Edited by - Driv3MeFar on June 11, 2006 4:57:28 AM]
"edit: another way of solving this problem, which you elluded to in your first post, would be to make a vector from the camera position to the target, take the cross product of that vector with the cameras current look vector to find an axis orthogonal to both, and rotate your camera about that axis by the angle between the two vectors (as can be found with a dot product). this will accomplish the same thing as the lookat matrix, but I believe it would be a bit slower."

This is exactly what I need. The speed-factor isn't a real issue for this application.

> would be to make a vector from the camera position to the target

Any ideas on how to accomplish this? I know the sprite's location <0,0,0> we'll say. And then we'll say the camera is at <20,30,500>. How do I make a vector from <20,30,500> to the sprite?

And... > find an axis orthogonal to both,

How do I determine axis orthogonality? :)

That is exactly what I need though, and those are my final two stumbling blocks. Thank you so much for the help everyone so far!!!! :D

Orphean

Quote:Original post by orphean
> would be to make a vector from the camera position to the target

Any ideas on how to accomplish this? I know the sprite's location <0,0,0> we'll say. And then we'll say the camera is at <20,30,500>. How do I make a vector from <20,30,500> to the sprite?


If you have two points, you can find a vector simply by subtracting the two. Geometrically, this finds you the displacement between the two points, and a vector is really just a displacement (a physics vector at least, if/when you take linear algebra, a vector is simply an element of a vector space, but I digress). So with the sample points you provided:
vector v = <0, 0, 0> - <20, 30, 500> = <-20, -30, -500>;
you will then want to normalize the vector by dividing it by its magnitude:
v /= |v|, where |v| = sqrt((-20)^2 + (-30)^2 + (-500)^2)

(Actualy, since your not building a lookAt matrix, I don't think you need to normalize, but if you wanted to, thats how you would.)

Quote:Original post by orphean
And... > find an axis orthogonal to both,

How do I determine axis orthogonality? :)


With a cross product. By definition, the cross product of two vectors is a vector perpendicular (orthogonal) to both of the origninal vectors.

The cross product of two vectors, u and v, is:
u (cross) v = (u.y * v.z - u.z * v.y)i - (u.x * v.z - u.z * v.x)j + (u.x * v.y - u.y * v.x)k
Where i = <1, 0, 0>, j = <0, 1, 0>, and k = <0, 0, 1>
Perfect.

Driv3MeFar next time I drive to the Seattle area I owe you a beer ;)

Thanks much for the help.

orphean
Quote:Original post by Anonymous Poster
Perfect.

Driv3MeFar next time I drive to the Seattle area I owe you a beer ;)

Thanks much for the help.

orphean


Don't thank me yet, wait until you get it working in code.

I will, however, take you up on the beer anytime.

Glad to help.

This topic is closed to new replies.

Advertisement