PDA

View Full Version : Some angles maths.


Audiophr3ak
25/02/2013, 08:22 AM
Im trying to find out the most efficient way to detect angles correlation bewteen two players. For example we have 4 sides for our player (FRONT, BACK, LEFT, RIGHT) and we got another player attacking him with his own angle. So the task is to detect from which side our first player is beign attacked. Any ideas?

http://img834.imageshack.us/img834/8852/schemer.jpg

Variant 1:
public OnPlayerTakeDamage(playerid, issuerid, Float:amount, weaponid)
{
if(issuerid != INVALID_PLAYER_ID)
{
new Float:pangle; GetPlayerFacingAngle(playerid, pangle);
new Float:iangle; GetPlayerFacingAngle(issuerid, iangle);
if(((pangle + 225) >= (iangle + 225)) && ((pangle - 225) <= (iangle - 225))) SendClientMessage(playerid, 0xFFFFFFAA, "FRONT");
if(((pangle + 45) >= (iangle + 45)) && ((pangle - 45) <= (iangle - 45))) SendClientMessage(playerid, 0xFFFFFFAA, "BACK");
if(((pangle + 135) >= (iangle + 135)) && ((pangle - 135) <= (iangle - 135))) SendClientMessage(playerid, 0xFFFFFFAA, "LEFT");
if(((pangle + 315) >= (iangle + 315)) && ((pangle - 315) <= (iangle - 315))) SendClientMessage(playerid, 0xFFFFFFAA, "RIGHT");
}
return 1;
}
Variant 2:
public OnPlayerTakeDamage(playerid, issuerid, Float:amount, weaponid)
{
if(issuerid != INVALID_PLAYER_ID)
{
new Float:pangle; GetPlayerFacingAngle(playerid, pangle);
new Float:iangle; GetPlayerFacingAngle(issuerid, iangle);
new Float:result = pangle - iangle;
if(result >= 315 && result <= 45) SendClientMessage(playerid, 0xFFFFFFAA, "BACK");
else if(result >= 45 && result <= 135) SendClientMessage(playerid, 0xFFFFFFAA, "LEFT");
else if(result >= 135 && result <= 225) SendClientMessage(playerid, 0xFFFFFFAA, "FRONT");
else if(result >= 225 && result <= 315) SendClientMessage(playerid, 0xFFFFFFAA, "RIGHT");
}
return 1;
}

RajatPawar
25/02/2013, 08:25 AM
GetPlayerFacingAngle of target and GetPlayerFacingAngle of Shooter, then you can assign str vals to angles between 0 - 90, so on. Say 0 - 90 Is front, and so on. But I basically do not know how the angles are assigned, I mean what is the axis, horizontal to the player or cutting through him!

Audiophr3ak
25/02/2013, 08:33 AM
We need to compare player's angle with shooter's angle. For example a range of player's angle +45/-45 = FRONT (Basically each side is 90 degrees). So if shooter's angle matches with this range - the attack is coming from the BACK. And so on. The problem is the code is too long.

detter
25/02/2013, 09:10 AM
1st you have to find player 1 (p1) and player 2 (p2) position !
2st find vector from p2 to p1 ---> |AB| = sqRot( (x2 - x1)^2 + (y2-y1)^2 )

x2 = p1X ; y2 = p1Y
x1 = p2X ; y1 = p2Y

when you have that ,you need to find distance between players
you do it like this ; x2 - x1 = B

then you have to find angle -> cos alpha = B/AB
then you invert cos and that is your angle

edit: i think when your y is negative you have to do this 360 - angle = your real angle


i'm not 100% sure but i tryed it with 2 diffrent position and it looks fine...

Babul
25/02/2013, 11:35 AM
the atan2 function is exactly what you need, it does all the maths:

new Float:Pos0[3],Pos1[3];
GetPlayerPos(player0,Pos0[0],Pos0[1],Pos0[2]);
GetPlayerPos(player1,Pos1[0],Pos1[1],Pos1[2]);
new Float:DiffX=Pos0[0]-Pos1[0];
new Float:DiffX=Pos0[1]-Pos1[1];
new Angle=atan2(DiffX,DiffY);//maybe you need to swap all Pos0 with Pos1
new Quadrant=floatround((Angle-45)/4,floatround_floor);

little explanation:
- get each players position - thats clear, i guess.
- calculate the Difference on X- and Y axis. this step is trivial, the result gets used once only.
- the atan2 function gives an angle as result, ranging from 0.0 to 360.0.
- angle-45 is the offset, since you want to the first quadrant to start at -45 degrees. upto 45 (-45+90) degrees, the result of dividing the angle (ranging from -45 to 45) will result in 0, from 45 to 135, the result will be 1 etc.
the floatround is required in order to use the resulting quadrant as a pointer into an array like

new QuadrantString[4][]={
"North","East","South","West"
};

...so you can simply use QuadrantString[Quadrant].

its worth mentioning that youll fact some trouble at getting the proper angles. play with the DiffX and Y formulas, maybe you need to swap players like DiffX=Pos1[1]-Pos0[1];
or you may need to change the Quadrant formula by changing the offset: (Angle+45) instead of -45.

i know the solution is not exactly what you want, its more like an exercise to get used to vector calculations...

Audiophr3ak
25/02/2013, 11:55 AM
Babul, your code can only detect North attack... Something wrong probably.

I've made some easier code for front-back attack detection, trying to improve it for left-right:

if(issuerid != INVALID_PLAYER_ID)
{
new Float:pangle; GetPlayerFacingAngle(playerid, pangle);
new Float:iangle; GetPlayerFacingAngle(issuerid, iangle);
pangle -= iangle;
if((pangle < 90) && (pangle > -90)) ApplyAnimation(playerid,"PED","KO_skid_back",4,0,1,1,1,0,1);
else ApplyAnimation(playerid,"PED","KO_skid_front",4,0,1,1,1,0,1);
}

Babul
25/02/2013, 12:08 PM
its more a hint than a solution, and is meant to avoid the if-else checks. one idea is to let print you out some gametexts leading you into the right direction. iam using a similar code somewhere btw, and there it worked. i cant find it atm lol

Audiophr3ak
25/02/2013, 12:10 PM
Thanks for help anyway :) I'll try to add checking logs and tune it a bit to make it work correctly.

Some notes:
1) atan2 gives a result ranging from 0 to 180 and from 0 to -180;
2) quadrant gives high values (like 30 and so on);

Babul
26/02/2013, 11:26 AM
oh, thats what i was missing: if the angles' range goes from -180.0 to 180.0, then simply add 180.0, therefore the result will range from 0.0 to 360.0. now iam unsure about if you need to reverse the rotation by multiplying by -1 or not.. try it if it rotates counterclockwise!
concerning the high values: indeed you get high results ranging upto 90, cause i did a "mini"mistake.
dont divide by 4, but by 90: 360/90=4 (quadrants).
quadrant 0 should now range from 0.0 to 90.0, thats where the -45 degrees come in again. good luck!

PabloDiCostanzo
26/02/2013, 11:36 AM
You habe more help HERE! (http://wiki.sa-mp.com/wiki/GetPlayerFacingAngle)

Audiophr3ak
26/02/2013, 12:01 PM
You habe more help HERE! (http://wiki.sa-mp.com/wiki/GetPlayerFacingAngle)
Seriously?
http://images3.wikia.nocookie.net/__cb20070526081822/uncyclopedia/images/thumb/1/15/CaptainobviousChooseOption.jpg/200px-CaptainobviousChooseOption.jpg

PabloDiCostanzo
26/02/2013, 12:49 PM
Seriously?
http://images3.wikia.nocookie.net/__cb20070526081822/uncyclopedia/images/thumb/1/15/CaptainobviousChooseOption.jpg/200px-CaptainobviousChooseOption.jpg



Yeah, seriously, click in that link. -.-

Audiophr3ak
26/02/2013, 02:18 PM
Yeah, seriously, click in that link. -.-
Dude, your "jokes" are stupid. I'm looking for an advanced formula and you just posting a wiki link... Your scripting "knowledge" makes no sence. This isn't the right place for rising your posts/reputation.