Finding the angle between the player and an object
by Neil Marshall · in Torque Game Engine · 09/07/2003 (8:50 am) · 14 replies
Is there any easy way to find the angle between an object in the world and the direction that the player is looking?
So if the object is to the right of the player, the formula will say... the object is 13 degrees to the right.
The info that I have is the objects location, the players location and rotation.
I think I can brute force this by making triangles and subtracting angles, but there has got to be a better way.
So if the object is to the right of the player, the formula will say... the object is 13 degrees to the right.
The info that I have is the objects location, the players location and rotation.
I think I can brute force this by making triangles and subtracting angles, but there has got to be a better way.
#2
Below is how I have it currently implemented and it seems to be giving me numbers that I don't know how to use. They are +/-800 or something.
I'm sure I'm doing something wrong, I just don't know what. :)
09/09/2003 (7:10 pm)
What kind of rotation variable is v1 supposed to supply? Just the default rotation vector in torque, radians, or degrees?Below is how I have it currently implemented and it seems to be giving me numbers that I don't know how to use. They are +/-800 or something.
I'm sure I'm doing something wrong, I just don't know what. :)
//( p2 - p1 ) dot v1
deltaPos.x = mCheckpointPosition.x - cameraPos.x;
deltaPos.y = mCheckpointPosition.y - cameraPos.y;
deltaPos.z = mCheckpointPosition.z - cameraPos.z;
finalRot.x = deltaPos.x * cameraRot.x;
finalRot.y = deltaPos.y * cameraRot.y;
finalRot.z = deltaPos.z * cameraRot.z;
Con::printf(":: Rotate %f %f %f", finalRot.x, finalRot.y, finalRot.z);
#3
v1 is a vector, normalize the players velocity for the direction he is facing.
09/10/2003 (5:48 pm)
No no...dot is dot produtct not multiply.v1 is a vector, normalize the players velocity for the direction he is facing.
#4
%TY = %target.getyposition;
%SY = %source.getyposition;
%TX = %target.getxposition;
%SX = %source.getxposition;
%TZ = %target.getzposition;
%SZ = %source.getzposition;
%PY = %SY - %TY;
%PX = %SX - %TX;
%PZ = %SZ - %TZ;
%target.player.setVelocity("%TX %TY %TZ");
08/19/2005 (1:08 pm)
I'm trying to use this to get one player move towards another I'm not sure if it well help It doesn't even work because there is no such thing as Getyposition you also need to defing %target and %source before hand.%TY = %target.getyposition;
%SY = %source.getyposition;
%TX = %target.getxposition;
%SX = %source.getxposition;
%TZ = %target.getzposition;
%SZ = %source.getzposition;
%PY = %SY - %TY;
%PX = %SX - %TX;
%PZ = %SZ - %TZ;
%target.player.setVelocity("%TX %TY %TZ");
#5
// Find the rotation of the two vectors, used for which half
//of the screen the player is on,
%crossProduct = VectorCross(%muzzleFlatVector, %positionFlatVector);
%rotation = GetWord(%crossProduct, 2);
*this rotation will give a vector and unless the vectors have no z value then you will need a different
way to tell which side of the screen an object may be on
//Angle between the two vectors
//angle = arccos(v1v2 / |v1||v2|)
%posX = GetWord(%posVec, 0);
%muzX = GetWord(%muzVec, 0);
%posY = GetWord(%posVec, 1);
%muzY = GetWord(%muzVec, 1);
%muzzleFlatVector = %muzX SPC %muzY SPC "0";
%positionFlatVector = %posX SPC %posY SPC "0";
%muzzleVectorLength = VectorLen(%muzzleFlatVector);
%positionVectorLength = VectorLen(%positionFlatVector);
%dotProduct = VectorDot(%muzzleFlatVector, %positionFlatVector);
%radians = mAcos(%dotProduct / %lengthMultiplied);
%angle = mRadToDeg(%radians);
01/01/2006 (1:42 pm)
Angle = arccos(v1v2 / |v1||v2|) This is the formula to find the angle between two vectors. In order to find out which side say a person is compare to your eye or muzzle vector which I believe are the same then you need to use this formula: rotation = v1xv2, If the number is positive then it is on once side, and if it is negative the other. I can not remember off hand which is which but a simple print and some experimentation will figure it out. Also note that just using this logic may not fix the problem. It will give you the angle between the vectors not the angle between them horizontally. To do this all you need to do is use the first formula but flatten the vertical values, which is simply setting them to 0. I will also include some sample code from script that I used in something similar.// Find the rotation of the two vectors, used for which half
//of the screen the player is on,
%crossProduct = VectorCross(%muzzleFlatVector, %positionFlatVector);
%rotation = GetWord(%crossProduct, 2);
*this rotation will give a vector and unless the vectors have no z value then you will need a different
way to tell which side of the screen an object may be on
//Angle between the two vectors
//angle = arccos(v1v2 / |v1||v2|)
%posX = GetWord(%posVec, 0);
%muzX = GetWord(%muzVec, 0);
%posY = GetWord(%posVec, 1);
%muzY = GetWord(%muzVec, 1);
%muzzleFlatVector = %muzX SPC %muzY SPC "0";
%positionFlatVector = %posX SPC %posY SPC "0";
%muzzleVectorLength = VectorLen(%muzzleFlatVector);
%positionVectorLength = VectorLen(%positionFlatVector);
%dotProduct = VectorDot(%muzzleFlatVector, %positionFlatVector);
%radians = mAcos(%dotProduct / %lengthMultiplied);
%angle = mRadToDeg(%radians);
#6
I'm also trying to do this but the player always rotate to somewhere else rather than the correct target direction. :(
02/01/2009 (7:09 pm)
Then how to rotate the player to that angle?I'm also trying to do this but the player always rotate to somewhere else rather than the correct target direction. :(
#7
i need a function to tell the player how far he has to turn to look at a object.
I just need it for x and y but not z.
Something like:
function getTurnDist(%me, %obj)
Then have it return to turn right(+) or left(-) a certain number of degrees.
Thanks,
Skylar.
03/13/2009 (1:13 pm)
Can someone shine light on this? i need a function to tell the player how far he has to turn to look at a object.
I just need it for x and y but not z.
Something like:
function getTurnDist(%me, %obj)
Then have it return to turn right(+) or left(-) a certain number of degrees.
Thanks,
Skylar.
#9
To get the angle from the player's eye direction to the object:
Hope this helped!
This basically gets the angle difference of the player's eye direction and the direction from the player to the object.
03/14/2009 (6:32 pm)
Working code may also help :-)function getVectorAngle(%vec1, %vec2)
{
%vec1n = VectorNormalize(%vec1);
%vec2n = VectorNormalize(%vec2);
%vdot = VectorDot(%vec1n, %vec2n);
%angle = mACos(%vdot);
// convert to degrees and return
%degangle = mRadToDeg(%angle);
return %degangle;
}To get the angle from the player's eye direction to the object:
%angle = getVectorAngle([player id].getEyeVector(),VectorSub([object].getPosition(),[player id].getPosition()));
Hope this helped!
This basically gets the angle difference of the player's eye direction and the direction from the player to the object.
#10
03/14/2009 (6:55 pm)
Good post Bryce. I believe there's a whole load of similar basic code on angle and target finding in the Killer Kork resource.
#11
03/14/2009 (7:19 pm)
This is the type of collaboration that is fun to see. Code examples, great explanations of how and whys. Even if the question is not immediately pertanit, one can still gleam something from reading the thread.
#12
03/14/2009 (7:49 pm)
@Steve: My example was taken from Killer Kork, actually! The math functions in that code are incredibly useful, I recommend it to anyone.
#13
but note that it will not distinguish between a player to the left and a player to the right. ie, it returns the size of the angle between vec1 and vec2, but not the direction of the angle.
for example, consider these vectors:
A = [ 0, 1] (straight up )
B = [ 1, 0] (straight right)
C = [-1, 0] (straight left )
A DOT B = 0, so acos() = 90 degrees.
A DOT C = 0, so acos() = 90 degrees.
to account for this, what i typically do is create a vector perpendicular to the second vector, DOT that with the first vector, and flip the sign of the angle depending on the sign of that second DOT.
note that this is easy with two dimensions, but gets a little tricky in three, but i think this thread is mainly interested in the 2D case.
so i would modify the code to something like:
to do this in three dimensions you would need to introduce an "up" vector, and rotate vec2 around that. the code above is equivelant to assuming the "up" vector is [0, 0, 1].
03/16/2009 (10:32 am)
the code snippet above is good for some things,but note that it will not distinguish between a player to the left and a player to the right. ie, it returns the size of the angle between vec1 and vec2, but not the direction of the angle.
for example, consider these vectors:
A = [ 0, 1] (straight up )
B = [ 1, 0] (straight right)
C = [-1, 0] (straight left )
A DOT B = 0, so acos() = 90 degrees.
A DOT C = 0, so acos() = 90 degrees.
to account for this, what i typically do is create a vector perpendicular to the second vector, DOT that with the first vector, and flip the sign of the angle depending on the sign of that second DOT.
note that this is easy with two dimensions, but gets a little tricky in three, but i think this thread is mainly interested in the 2D case.
so i would modify the code to something like:
function get2DVectorAngle(%vec1, %vec2)
{
%vec1n = VectorNormalize(%vec1);
%vec2n = VectorNormalize(%vec2);
%vec3Perp = getWord(%vec2, 1) SPC (-1 * getWord(%vec2, 0)); // x gets y, y gets -x.
%vdot = VectorDot(%vec1n, %vec2n);
%angle = mACos(%vdot);
%pdot = VectorDot(%vec1n, %vec2Perp);
if (%pdot < 0)
{
%angle *= -1;
}
// convert to degrees and return
%degangle = mRadToDeg(%angle);
return %degangle;
}to do this in three dimensions you would need to introduce an "up" vector, and rotate vec2 around that. the code above is equivelant to assuming the "up" vector is [0, 0, 1].
#14
05/01/2010 (9:46 pm)
For anyone who finds this in the future, the above post's code has a typo, %vec2Perp should read %vec3Perp. :)
Torque 3D Owner Pat Wilson
Object position = p2
Players direction = v1
( p2 - p1 ) dot v1
Should do it.
I just woke up and am hung over, I blame that if it's wrong.