IsPlayerFacingVehicle - my math sucks
#1

Hey guys,

Im trying to improve my logic abilities, unfortunately Im stuck...

I've read a few lines of this: https://en.wikipedia.org/wiki/Atan2

But as it's said in the subject, my math sucks, so... could somebody here make the exact picture like it's on wiki, but with player standing and looking at the point?

I've made this ... (with an inspiration from https://sampforum.blast.hk/showthread.php?tid=517551 )

PHP код:
stock IsPlayerFacingVehicle(playeridFloat:vXFloat:vY){
    new
        
Float:pX    ,
        
Float:pY    ,
        
Float:pZ    ,
        
Float:pA    ,
        
Float:aftan ,
        
str[36]
    ;
    
GetPlayerPos(playeridpXpYpZ); GetPlayerFacingAngle(playeridpA);
    if(
pX !=0.0 && pY != 0.0 && pZ != 0.0){
        
aftan atan2(pX vXpY vY);
        
format(strsizeof(str), "pX: %f, pY: %f - vX: %f, vY: %f"pXpYvXvY);                 SendClientMessage(playerid, -1str);
        
format(strsizeof(str), "AFTER TAN: %f"aftan);                                             SendClientMessage(playerid, -1str);
        
format(strsizeof(str), "FACING ANGLE: %f"pA);                                             SendClientMessage(playerid, -1str);
        
pA -= aftan;
        
format(strsizeof(str), "FACING ANGLE AFTER: %f"pA);                                     SendClientMessage(playerid, -1str);
    }
    return 
false;

It's not much of a code, but I can't continue, if I don't understand that.
Those numbers I get... What are they for?

Thanks

edit. I know what Player Pos is... Im trying to get through big bosses. And math is one of them.
Reply
#2

I’m not that good at maths too, but i think you need to find ratio between vX - playerX and vY - playerY(ratio between distance to a car X, Y coordinates). Why you need to find this ratio? Because from this you can get an angle between a player and a car. Try drawing a triangle which longest line goes from player to a car(draw them as points), two shorter triangle’s lines will be just that longest’s line x, y projection. What you are trying to find is an angle which points to a car. Now try changing those x and y projections, notice how that angle changes, you should notice that there’s some pattern here. You should notice that if you make this triangle 2x times smaller, that degree doesn’t change. So that’s why we need to use ratio between x and y somehow. Basically, that’s where tan comes from. Tangent IS a ratio between those projections(and you can get this ratio from degrees, that’s tan function for you). But atan is reverse, it’s a degree which you are searching for, you input that ratio and it outputs some degrees to you. That’s how you get degrees between player and a car. Now you have to make sure that if player faces a vehicle, your degree needs to match player facing angle, if it does, you need to decide how much that angle can differ from an angle between player and vehicle(if it differs only 1 degree, you still can say that player is facing a car)... sorry for bad english and explanation, i hope this will help at least a little xd
Reply
#3

Quote:
Originally Posted by lollypap54
Посмотреть сообщение
I’m not that good at maths too, but i think you need to find ratio between vX - playerX and vY - playerY(ratio between distance to a car X, Y coordinates). Why you need to find this ratio? Because from this you can get an angle between a player and a car. Try drawing a triangle which longest line goes from player to a car(draw them as points), two shorter triangle’s lines will be just that longest’s line x, y projection. What you are trying to find is an angle which points to a car. Now try changing those x and y projections, notice how that angle changes, you should notice that there’s some pattern here. You should notice that if you make this triangle 2x times smaller, that degree doesn’t change. So that’s why we need to use ratio between x and y somehow. Basically, that’s where tan comes from. Tangent IS a ratio between those projections(and you can get this ratio from degrees, that’s tan function for you). But atan is reverse, it’s a degree which you are searching for, you input that ratio and it outputs some degrees to you. That’s how you get degrees between player and a car. Now you have to make sure that if player faces a vehicle, your degree needs to match player facing angle, if it does, you need to decide how much that angle can differ from an angle between player and vehicle(if it differs only 1 degree, you still can say that player is facing a car)... sorry for bad english and explanation, i hope this will help at least a little xd
Reply
#4

Quote:
Originally Posted by lollypap54
Посмотреть сообщение
I’m not that good at maths too, but i think you need to find ratio between vX - playerX and vY - playerY(ratio between distance to a car X, Y coordinates). Why you need to find this ratio? Because from this you can get an angle between a player and a car. Try drawing a triangle which longest line goes from player to a car(draw them as points), two shorter triangle’s lines will be just that longest’s line x, y projection. What you are trying to find is an angle which points to a car. Now try changing those x and y projections, notice how that angle changes, you should notice that there’s some pattern here. You should notice that if you make this triangle 2x times smaller, that degree doesn’t change. So that’s why we need to use ratio between x and y somehow. Basically, that’s where tan comes from. Tangent IS a ratio between those projections(and you can get this ratio from degrees, that’s tan function for you). But atan is reverse, it’s a degree which you are searching for, you input that ratio and it outputs some degrees to you. That’s how you get degrees between player and a car. Now you have to make sure that if player faces a vehicle, your degree needs to match player facing angle, if it does, you need to decide how much that angle can differ from an angle between player and vehicle(if it differs only 1 degree, you still can say that player is facing a car)... sorry for bad english and explanation, i hope this will help at least a little xd
It's 0:45 AM here, so... I'll leave it till tomorrow.... thx
Reply
#5

Quote:
Originally Posted by KinderClans
Посмотреть сообщение
At least i tried xddd
Also, if you, OP, don’t understand what i have written here before, try watching some yt vids about this topic(tangents, triangles...), i think there are some really good ones
Reply
#6

mine is worse
Reply
#7

Quote:
Originally Posted by lollypap54
Посмотреть сообщение
I’m not that good at maths too, but i think you need to find ratio between vX - playerX and vY - playerY(ratio between distance to a car X, Y coordinates). Why you need to find this ratio? Because from this you can get an angle between a player and a car. Try drawing a triangle which longest line goes from player to a car(draw them as points), two shorter triangle’s lines will be just that longest’s line x, y projection. What you are trying to find is an angle which points to a car. Now try changing those x and y projections, notice how that angle changes, you should notice that there’s some pattern here. You should notice that if you make this triangle 2x times smaller, that degree doesn’t change. So that’s why we need to use ratio between x and y somehow. Basically, that’s where tan comes from. Tangent IS a ratio between those projections(and you can get this ratio from degrees, that’s tan function for you). But atan is reverse, it’s a degree which you are searching for, you input that ratio and it outputs some degrees to you. That’s how you get degrees between player and a car. Now you have to make sure that if player faces a vehicle, your degree needs to match player facing angle, if it does, you need to decide how much that angle can differ from an angle between player and vehicle(if it differs only 1 degree, you still can say that player is facing a car)... sorry for bad english and explanation, i hope this will help at least a little xd
Convert this into pawn language to see if it works
Reply
#8

Quote:
Originally Posted by v1k1nG
Посмотреть сообщение
Convert this into pawn language to see if it works
challenge accepted (:

----

So I tried something, I'm not great at maths, but this is the most fitting way I figured it'd be possible to do. However, this method is not accurate, there are several factors to take into consideration: the distance between the vehicle and player multiplied by the vehicle's visible ratio (zoom in, zoom out - basically), etc, etc.

Talk is cheap! Show me the code already!

pawn Код:
#include <a_samp>

main() {

  /*
   * loop the code 10 times.
   */


  for(new time = 0; time < 10; time++) {

    /*
     * assign the variables new random SA
     * coordinations for debugging.
     */


    new Float: playerPosAngle[4];

    playerPosAngle[0] = float(random((3000) - (-3000)) + -3000);
    playerPosAngle[1] = float(random((3000) - (-3000)) + -3000);
    playerPosAngle[2] = float(random((3000) - (-3000)) + -3000);
    playerPosAngle[3] = float(random(360));

    new Float: vehiclePosition[3];

    vehiclePosition[0] = float(random((3000) - (-3000)) + -3000);
    vehiclePosition[1] = float(random((3000) - (-3000)) + -3000);
    vehiclePosition[2] = float(random((3000) - (-3000)) + -3000);

    /*
     * calculate the difference between the
     * height, breadth and possible the depth
     * if needed.
     */


    new Float: breadthDiffer = floatsub(vehiclePosition[0], playerPosAngle[0]),
      Float: heightDiffer = floatsub(vehiclePosition[1], playerPosAngle[1]),
      Float: depthDiffer = floatsub(vehiclePosition[2], playerPosAngle[2]);

    /*
     * calculate the Atan2 angle between the
     * breadth and height.
     */


    new Float: angleDegrees = floatdiv(floatmul(atan2(floatsub(vehiclePosition[1], playerPosAngle[1]), floatsub(vehiclePosition[0], playerPosAngle[0])), 180.0), 3.142);

    new Float: angleRadians = atan2(floatsub(vehiclePosition[1], playerPosAngle[1]), floatsub(vehiclePosition[0], playerPosAngle[0]));

    /*
     * calculate the distance between the
     * viewing angle and the required angle
     */


    new Float: angleDiffer = floatsub(playerPosAngle[3], angleRadians);

    if(angleDiffer < 0.0)
      angleDiffer *= -1;

    /*
     * print out the logs to verify our logic.
     */


    printf("player's position: x %.0f - y %.0f - z %.0f - a %.0f", playerPosAngle[0], playerPosAngle[1], playerPosAngle[2], playerPosAngle[3]);
    printf("vehicle's position: x %.0f - y %.0f - z %.0f", vehiclePosition[0], vehiclePosition[1], vehiclePosition[2]);

    printf("coordination differ: breath %.0f - height %.0f - depth %.0f", breadthDiffer, heightDiffer, depthDiffer);

    printf("angle between points: %.0f", angleDegrees);
    printf("radians between points: %.0f", angleRadians);

    printf("angle differ: %.0f - is facing: %s", angleDiffer, (angleDiffer < 15.0)?("true"):("false"));
    print(" ");
  }
}
An example run of this script would give you something alike this:

Код:
player's position: x 143 - y -2585 - z -2522 - a 278
vehicle's position: x -1939 - y 1117 - z -2755
coordination differ: breath -2082 - height 3702 - depth -233
angle between points: 6837
radians between points: 119
angle differ: 158 - is facing: false

player's position: x -401 - y 2899 - z 2652 - a 100
vehicle's position: x 121 - y 1290 - z 1518
coordination differ: breath 522 - height -1609 - depth -1134
angle between points: -4126
radians between points: -72
angle differ: 172 - is facing: false

player's position: x -1308 - y 282 - z -2786 - a 1
vehicle's position: x 2440 - y 1067 - z -1979
coordination differ: breath 3748 - height 785 - depth 807
angle between points: 677
radians between points: 11
angle differ: 10 - is facing: true

player's position: x -444 - y 1695 - z 2726 - a 284
vehicle's position: x 2853 - y -2546 - z -787
coordination differ: breath 3297 - height -4241 - depth -3513
angle between points: -2986
radians between points: -52
angle differ: 336 - is facing: false

player's position: x 1765 - y 1832 - z -2541 - a 210
vehicle's position: x -606 - y 1975 - z 226
coordination differ: breath -2371 - height 143 - depth 2767
angle between points: 10114
radians between points: 176
angle differ: 33 - is facing: false

player's position: x 714 - y 1793 - z -2932 - a 200
vehicle's position: x 2408 - y 629 - z -1329
coordination differ: breath 1694 - height -1164 - depth 1603
angle between points: -1976
radians between points: -34
angle differ: 234 - is facing: false

player's position: x -79 - y 875 - z 1144 - a 224
vehicle's position: x 2370 - y 671 - z 818
coordination differ: breath 2449 - height -204 - depth -326
angle between points: -272
radians between points: -4
angle differ: 228 - is facing: false

player's position: x -1340 - y -1675 - z -2347 - a 240
vehicle's position: x -608 - y -817 - z -423
coordination differ: breath 732 - height 858 - depth 1924
angle between points: 2837
radians between points: 49
angle differ: 190 - is facing: false

player's position: x -1131 - y 742 - z 1971 - a 135
vehicle's position: x 314 - y 1650 - z -2243
coordination differ: breath 1445 - height 908 - depth -4214
angle between points: 1841
radians between points: 32
angle differ: 102 - is facing: false

player's position: x -1011 - y -827 - z 243 - a 62
vehicle's position: x -578 - y -2238 - z 954
coordination differ: breath 433 - height -1411 - depth 711
angle between points: -4178
radians between points: -72
angle differ: 134 - is facing: false
Reply
#9

Quote:
Originally Posted by cSharp
Посмотреть сообщение
challenge accepted (:

----

So I tried something, I'm not great at maths, but this is the most fitting way I figured it'd be possible to do. However, this method is not accurate, there are several factors to take into consideration: the distance between the vehicle and player multiplied by the vehicle's visible ratio (zoom in, zoom out - basically), etc, etc.

Talk is cheap! Show me the code already!

pawn Код:
#include <a_samp>

main() {

  /*
   * loop the code 10 times.
   */


  for(new time = 0; time < 10; time++) {

    /*
     * assign the variables new random SA
     * coordinations for debugging.
     */


    new Float: playerPosAngle[4];

    playerPosAngle[0] = float(random((3000) - (-3000)) + -3000);
    playerPosAngle[1] = float(random((3000) - (-3000)) + -3000);
    playerPosAngle[2] = float(random((3000) - (-3000)) + -3000);
    playerPosAngle[3] = float(random(360));

    new Float: vehiclePosition[3];

    vehiclePosition[0] = float(random((3000) - (-3000)) + -3000);
    vehiclePosition[1] = float(random((3000) - (-3000)) + -3000);
    vehiclePosition[2] = float(random((3000) - (-3000)) + -3000);

    /*
     * calculate the difference between the
     * height, breadth and possible the depth
     * if needed.
     */


    new Float: breadthDiffer = floatsub(vehiclePosition[0], playerPosAngle[0]),
      Float: heightDiffer = floatsub(vehiclePosition[1], playerPosAngle[1]),
      Float: depthDiffer = floatsub(vehiclePosition[2], playerPosAngle[2]);

    /*
     * calculate the Atan2 angle between the
     * breadth and height.
     */


    new Float: angleDegrees = floatdiv(floatmul(atan2(floatsub(vehiclePosition[1], playerPosAngle[1]), floatsub(vehiclePosition[0], playerPosAngle[0])), 180.0), 3.142);

    new Float: angleRadians = atan2(floatsub(vehiclePosition[1], playerPosAngle[1]), floatsub(vehiclePosition[0], playerPosAngle[0]));

    /*
     * calculate the distance between the
     * viewing angle and the required angle
     */


    new Float: angleDiffer = floatsub(playerPosAngle[3], angleRadians);

    if(angleDiffer < 0.0)
      angleDiffer *= -1;

    /*
     * print out the logs to verify our logic.
     */


    printf("player's position: x %.0f - y %.0f - z %.0f - a %.0f", playerPosAngle[0], playerPosAngle[1], playerPosAngle[2], playerPosAngle[3]);
    printf("vehicle's position: x %.0f - y %.0f - z %.0f", vehiclePosition[0], vehiclePosition[1], vehiclePosition[2]);

    printf("coordination differ: breath %.0f - height %.0f - depth %.0f", breadthDiffer, heightDiffer, depthDiffer);

    printf("angle between points: %.0f", angleDegrees);
    printf("radians between points: %.0f", angleRadians);

    printf("angle differ: %.0f - is facing: %s", angleDiffer, (angleDiffer < 15.0)?("true"):("false"));
    print(" ");
  }
}
An example run of this script would give you something alike this:

Код:
player's position: x 143 - y -2585 - z -2522 - a 278
vehicle's position: x -1939 - y 1117 - z -2755
coordination differ: breath -2082 - height 3702 - depth -233
angle between points: 6837
radians between points: 119
angle differ: 158 - is facing: false

player's position: x -401 - y 2899 - z 2652 - a 100
vehicle's position: x 121 - y 1290 - z 1518
coordination differ: breath 522 - height -1609 - depth -1134
angle between points: -4126
radians between points: -72
angle differ: 172 - is facing: false

player's position: x -1308 - y 282 - z -2786 - a 1
vehicle's position: x 2440 - y 1067 - z -1979
coordination differ: breath 3748 - height 785 - depth 807
angle between points: 677
radians between points: 11
angle differ: 10 - is facing: true

player's position: x -444 - y 1695 - z 2726 - a 284
vehicle's position: x 2853 - y -2546 - z -787
coordination differ: breath 3297 - height -4241 - depth -3513
angle between points: -2986
radians between points: -52
angle differ: 336 - is facing: false

player's position: x 1765 - y 1832 - z -2541 - a 210
vehicle's position: x -606 - y 1975 - z 226
coordination differ: breath -2371 - height 143 - depth 2767
angle between points: 10114
radians between points: 176
angle differ: 33 - is facing: false

player's position: x 714 - y 1793 - z -2932 - a 200
vehicle's position: x 2408 - y 629 - z -1329
coordination differ: breath 1694 - height -1164 - depth 1603
angle between points: -1976
radians between points: -34
angle differ: 234 - is facing: false

player's position: x -79 - y 875 - z 1144 - a 224
vehicle's position: x 2370 - y 671 - z 818
coordination differ: breath 2449 - height -204 - depth -326
angle between points: -272
radians between points: -4
angle differ: 228 - is facing: false

player's position: x -1340 - y -1675 - z -2347 - a 240
vehicle's position: x -608 - y -817 - z -423
coordination differ: breath 732 - height 858 - depth 1924
angle between points: 2837
radians between points: 49
angle differ: 190 - is facing: false

player's position: x -1131 - y 742 - z 1971 - a 135
vehicle's position: x 314 - y 1650 - z -2243
coordination differ: breath 1445 - height 908 - depth -4214
angle between points: 1841
radians between points: 32
angle differ: 102 - is facing: false

player's position: x -1011 - y -827 - z 243 - a 62
vehicle's position: x -578 - y -2238 - z 954
coordination differ: breath 433 - height -1411 - depth 711
angle between points: -4178
radians between points: -72
angle differ: 134 - is facing: false
Way too complicated. A loop even?

Look at Nero3D's post OP quoted.

Get the world angle from the player to the car (atan2 of the Player Pos - Vehicle Pos). Then get the player's facing angle (GetPlayerFacingAngle or GetPlayerCameraFrontVector + atan2).

Then you need to subtract the angles from one another, and clamp the value to [-180.0, 180.0]. The absolute value of that number is then the angle difference in degrees, you must then decide at which angle the player would be looking at/facing the car, and at which it isn't.
Reply
#10

Here :

Код:
stock IsPlayerFacingVehicle(playerid,vehicleid)
{
	if(!IsPlayerConnected(playerid)) return 0;
	new Float:pX, Float:pY, Float:pZ, Float:pAng,
		Float:X, Float:Y, Float:Z, Float:ang;

	GetVehiclePos(vehicleid, X, Y, Z);
	GetPlayerPos(playerid, pX, pY, pZ);
	GetPlayerFacingAngle(playerid, pAng);

	if( Y > pY ) ang = (-acos((X - pX) / floatsqroot((X - pX)*(X - pX) + (Y - pY)*(Y - pY))) - 90.0);
	else if( Y < pY && X < pX ) ang = (acos((X - pX) / floatsqroot((X - pX)*(X - pX) + (Y - pY)*(Y - pY))) - 450.0);
	else if( Y < pY ) ang = (acos((X - pX) / floatsqroot((X - pX)*(X - pX) + (Y - pY)*(Y - pY))) - 90.0);

	if(X > pX) 
		ang = (floatabs(floatabs(ang) + 180.0));
	else 
		ang = (floatabs(ang) - 180.0);

	if(ang - pAng < -130 || ang - pAng > 130)
		return 0;
	else
		return 1;
}
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)