It really is just basic trigonometry. Sin and Cos are really the only things you need to understand. I try and remember this formula when working with relative coordinates:
PHP код:
X = OriginX + (sin(angle) * OffsetY + cos(angle) * OffsetX);
Y = OriginY + (cos(angle) * OffsetY - sin(angle) * OffsetX);
The red dot in the centre is the player's position or the origin of whatever you're calculating from. The blue dots are the four corners or points of the rectangle, respectively in the order: (minx, miny), (minx, maxy), (maxx, miny), (maxx, maxy).
As SA-MP angles work counter-clockwise, all you have to do beforehand is either subtract the angle from 360 degrees or simply make the angle negative. Here's an example of how you would achieve this:
PHP код:
CMD:test(playerid, params[])
{
new
Float:OffsetX,
Float:OffsetY
;
if(sscanf(params, "ff", OffsetX, OffsetY))
return SendClientMessage(playerid, -1, "USAGE: /test [offset X] [offset Y]");
new
Float:PlayerX, // Player's X coordinate (OriginX)
Float:PlayerY, // Player's Y coordinate (OriginY)
Float:PlayerZ,
Float:PlayerA, // Player's facing angle (angle)
Float:Vertices[4][2] // The corners/vertices of the rectangle. There are 4 corners with 2 coordinates (X and Y) each, hence the [4][2].
;
GetPlayerPos(playerid, PlayerX, PlayerY, PlayerZ); // Store the player's position. Z coordinate is only really needed for the objects. It doesn't need to be used in the calculations.
GetPlayerFacingAngle(playerid, PlayerA); // Store the player's facing angle.
new
Float:sin = floatsin(-PlayerA, degrees), // You don't have to do this, but it saves calculating the same thing over and over and helps readability.
Float:cos = floatcos(-PlayerA, degrees) // Again, not necessary.
;
// Now for the calculations for each point.
// Point 1 (MinX, MinY)
Vertices[0][0] = PlayerX + sin * -OffsetY + cos * -OffsetX;
Vertices[0][1] = PlayerY + cos * -OffsetY - sin * -OffsetX;
// Point 2 (MinX, MaxY)
Vertices[1][0] = PlayerX + sin * OffsetY + cos * -OffsetX;
Vertices[1][1] = PlayerY + cos * OffsetY - sin * -OffsetX;
// Point 3 (MaxX, MinY)
Vertices[2][0] = PlayerX + sin * -OffsetY + cos * OffsetX;
Vertices[2][1] = PlayerY + cos * -OffsetY - sin * OffsetX;
// Point 4 (MaxX, MaxY)
Vertices[3][0] = PlayerX + sin * OffsetY + cos * OffsetX;
Vertices[3][1] = PlayerY + cos * OffsetY - sin * OffsetX;
CreateObject(19122, Vertices[0][0], Vertices[0][1], PlayerZ, 0.0, 0.0, 0.0); // Blue
CreateObject(19123, Vertices[1][0], Vertices[1][1], PlayerZ, 0.0, 0.0, 0.0); // Green
CreateObject(19124, Vertices[2][0], Vertices[2][1], PlayerZ, 0.0, 0.0, 0.0); // Red
CreateObject(19125, Vertices[3][0], Vertices[3][1], PlayerZ, 0.0, 0.0, 0.0); // Yellow
return 1;
}
This will place a bollard on each corner of the theoretical rectangle with the offsets that you specify. When working with 'MinX', the X offset is negative, and positive when working with 'MaxX'. When working with 'MinY', the Y offset is negative, and positive when working with 'MaxY'.
In terms of checking whether a certain point is inside that rectangle? Well... that's a whole other issue...
http://math.stackexchange.com/questi...de-a-rectangle
http://mathforum.org/library/drmath/view/54386.html
http://stackoverflow.com/questions/3...in-a-rectangle
Now someone call Nero_3D, he has some work to do with converting this to pawn.