I need some vector math help, please.

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
idlewire

I need some vector math help, please.

Post by idlewire »

I have two nodes. How can I find our if one node is facing within 30 degrees of the other one (like its field of vision ;))
rincewind
Posts: 35
Joined: Thu Mar 25, 2004 5:28 pm
Location: Germany --> Bonn

Post by rincewind »

You can use the scalar product between the two "forward" vectors. So, assuming that x=(x_1, x_2, x_3) is pointing forward for node 1 and y=(y_1, y_2, y_3) does the same for node 2, and assuming further that both x and y have length 1, the following equation is true:

Code: Select all

x_1*y_1+x_2*y_2+x_3*y_3 = cos a,
where a is the (unorientated) angle between x and y.
It has long been an axiom of mine that the little things are
infinitely the most important.
-- Sir Arthur Conan Doyle, "A Case of Identity"
Guest

Post by Guest »

rincewind is correct that you can use the scalar product (also called dot product) to find the angle, but you shouldn't use the look vectors of both nodes.
That would just tell whether they are facing the same direction, not if one can actually "see" the other.

To find out if node A is looking at node B, you need two vectors:
1) The looking direction of node A.
2) The vector from A and B.

To find the looking vector of node A: (I think it's like this)

Code: Select all

// call updateAbsoluteTransformation if you have moved it since last frame
core::vector3df getLookDirection( const scene::ISceneNode* sceneNode )
{
    const core::matrix4& mat = sceneNode->getAbsoluteTransformation();
    return core::vector3df(mat.M[0], mat.M[1], mat.M[2]);
}
Then, to determine if node A can "see" a point:

Code: Select all

bool isPointInFieldOfView( const scene::ISceneNode* A, const core::vector3df& point )
{
    core::vector3df look = getLookDirection( A );
    core::vector3df ab = point - A->getPosition();
    f32 dot = look.dotProduct( ab );

    return (dot > 0) && (dot*dot >= look.getLengthSQ()*ab.getLengthSQ()*0.75);
}
The 0.75 is there because cos30*cos30 = 0.75 - if you want another field of view, change 0.75 to the square of the cosine of that angle.

Note: I haven't tested all this; it may not work but I think it does.

(Got timeout when trying to post this - sorry if this is a double-post)
idlewire

Post by idlewire »

Thanks, I'll let you know how it goes as soon as I get it ".Netted".
idlewire

Post by idlewire »

I guess c-sharping would be a better word for it.

for mat.set_M(x,y) requires the row and column, any ideas?

Is ab the '0-360' of where the point is, in relation to the 'looker'? That would be useful to know if to turn left or right to put the node into my view.
Guest

Post by Guest »

I'm not familiar with C#, but I can take a good guess as to what it might look like.

The line that says return core::vector3df(mat.M[0], mat.M[1], mat.M[2]) makes a vector from the first column and rows 1, 2 and 3.
In short, let the column index be 0 and row index 0, 1 and 2.
So in C# it might look like this:

Code: Select all

return core::vector3df(mat.get_M(0,0), mat.get_M(0,1), mat.M(0,2));
ab is a the vector from A to B - it is in world coordinates and not angles.
The code I wrote doesn't really allow you to tell what direction to turn because it uses all 3 rotation axes.
For a simple FPS game you could make it a bit easier by using the orientation (north/south look direction) and pitch (up/down look direction).
Guest

Post by Guest »

That did it, thanks
Post Reply