[Tutorial] Vectors in SA-MP
#1

Hello. For anyone who has not studied euclidean vectors yet or simply doesn't know about them.

EDIT: This is about mathematical vectors and NOT vector sequence containers. Their implementation in PAWN can be found here.

Index
  1. What are vectors?
  2. How are they represented?
  3. Use in SA-MP
  4. Using vectors in SA-MP
  5. General mathematics about vectors
1) What are vectors?
(Magnitude is a word meaning length in geometrical sense)

Vectors are directional scalars. In layman terms, a scalar is nothing but pure magnitude without any direction.

Vectors are quantities with a defined direction. They help us, a lot, in defining the angles and inclinations of a quantity and they are a major part of mathematics.
Example - Temperature is a scalar. We know that it's 37 ° (magnitude) in the day. But do we know in what direction is the 37 ° in? No, it just is.

The exact opposite of that is a vector. Consider velocity. We know a car is going straight (direction) with a magnitude of 54 km/hr.

You can find out more about them, on this page.
2) How are they represented?
Vectors are represented in the cartesian coordinate system. (or the polar system)
This picture is the most simple picture of the three axes.


It shows us three axes, namely X, Y and Z axes with the help of which we can pinpoint ANY spot in 3D space. A vector is represented using unit vectors.
Unit vectors, namely i, j & k, are vectors in the direction of the X, Y & Z axes respectively of magnitude 1 unit.
A standard vector can be shown by -

vec = ai + bj + ck

A vector's magnitude is -
Code:
SquareRoot( (a * a) + (b * b) + (c * c) )
.......... ( 1 )
Using them, I can show a vector like:
v = 3i + 4j + 5k
means that this vector is 3 units along the X axis, 4 units along the Y axis and 5 along the Z.
u = -v
means that the vector 'u' is completely opposite in direction to 'v'.
3) Use in SA-MP
Vectors are used in SA-MP a lot without even you realising you are using them. A lot of mathematics, you are saved from in SA-MP because there is no need for handling unit vectors in SA-MP and their dot/cross products, etc.

The GTA: SA map uses blueberry as the origin - it has the co-ordinates as (0,0,0). Hence most of the times you give invalid co-ordinates or don't - or something buggy happens, you spawn there. (or fall there)
Player positions are represented by vectors in SA-MP. Suppose a player stands at (4, 6, -1) on the map.

GetPlayerPos() would return his vector logically - but it infact embeds the variables with 4, 6 and -1 respectively.
Logically, it looks like -
Code:
PlayerPos = 4i + 6j - 1k.
The resultant 'PlayerPos' vector would be a vector whose endpoint will be on (4, 6, -1). However, due to absence of a lot of maths in SA-MP, you don't have to worry about that. Just pass the variables and get the position.

The closest you come to using a vector is this - I am sure you all know this -
Code:
SquareRoot( (fX * fX) + (fY * fY) + (fZ * fZ) )
where fX, fY and fZ are the player's co-ordinates.
OR
Code:
SquareRoot( (vX * vX)  + (fY * fY) + (fZ * fZ) )
where vX, vY and vZ are vehicle velocity vectors.
You get the magnitude of the PlayerPos vector here. Refer to (1).
By magnitude - the result is the LENGTH of the vector from origin or SIMPLY the distance of the player in unit system.
4) Using vectors in SA-MP
Two functions I am going to cover in here are
  • GetPlayerLastShotVectors(..)
  • GetPlayerCameraFrontVector(..)
1) GetPlayerLastShotVectors() is a function in layman terms, that gets you the position vector of the place where the player last shot his bullet. It solely gets the position relative to the GTA: SA map unlike OnPlayerWeaponShot which gets you co-ordinates in relation to four different things. (vehicles, etc)

Examples - You can use it to create a checkpoint where ever you shoot.

pawn Code:
public OnPlayerWeaponShot(playerid, ....)
{
    new Float: X, Float: Y, Float: Z;
    GetPlayerLastShotVectors( playerid, X, Y, Z );
    // Using mapandreas to get the CORRECT Z co-ordinate.
    MapAndreas_FindZ_For2DCoord(X, Y, Z);
    CreateDynamicCP(X, Y, Z, ...);
    return 1;
}
Also, you can be very imaginative with this, create things like
  • Teleport guns
  • Gravity guns
  • Paintball guns
2) GetPlayerCameraFrontVector(..) is a very powerful function. It gives a vector 'v' relative to your POSITION of magnitude unit length in the direction of the player facing angle.

When the vector received is added to GetPlayerCameraPos(..) then you get the ACTUAL position of the 'v' in relation to the GTA - SA map. This map may explain it.

Example usage -Create a NPC, and then detect if a player's looking at it.

Using psuedo - code!
pawn Code:
new NPC = createNpc(...);
SetNPCPos(2, 3, 5);
CreateDynamicSphere(2, 3, 5, /* size of sphere */, 10);

public OneSecondTimer(..)
{
    new Float: x, Float: y, Float: z,  
        Float: cX, Float: cY, Float: cZ;
    GetPlayerCameraPos(playerid, x, y, z );
    GetPlayerCameraFrontVector(playerid, cX, cY, cZ);
    x += cX;
    y += cY;
    z += cZ;
    // x y z now contain co-ords of point where player is looking
    if( IsPointInRangeOf( x, y, z, 2, 3, 5 ) )
    {
        // Player is looking at the NPC
    }
    return 1;
}
So there you are! Many useful things you can do with it!
5) General mathematics regarding vectors
1) Magnitude of a vector
v = ai + bj + ck
Code:
is  √ (a*a) + (b*b) + (c*c)
2) Two vectors' cross product resultant is a vector perpendicular to the original vector.
3) Dot product gives you a single number (psuedovector - too long to explain here, see wikipedia)
4) Vectors can be used to denote things like velocity, acceleration or position, etc.
5) Difference of two vectors gives a vector joining the end points of the original two vectors.
6) Angle between two vectors -
Code:
a) Find magnitude of each vector (Let the magnitudes be M1 & M2)
	b) Get dot product of the vectors (Let the dot product be 'D')
	c) cos θ = D/M1 * M2
	d) Use acos to get the angle.
Can be used in scenarios like getting angle between two player's angle's and then creating an arrow pointing towards the opposite player.
7) More to come.

So that's all! Vectors are an important part of game designing. Also, designing stuff to use vectors is difficult on computers. Probably needs actually pen and paper-ing stuff and then programming. So respect Kalcor for giving us great functions because he's not only got to be a good programmer but also a good mathematician. Though, a good coder should be a good mathematician.

If there are any mistakes, do tell.
Thank you.
Reply
#2

Nicely explained. (I just gave a brief read to it, I'll read it better tomorrow)
Reply
#3

Quote:
Originally Posted by FireCat
View Post
Nicely explained. (I just gave a brief read to it, I'll read it better tomorrow)
Thank you. I'm surely going to expand this to trigonometric operations because there is a lack of documentation/tutorials on how to mess with co-ordinates and get cool things done. (like alerting a player of a pickpocket currently picking his wallet only if the victim looks at the pickpocket, etc..)
Reply
#4

Nice, well explained!
Reply
#5

A common missconception is that the magnitude of a vector is it's components summed to the square. That's actually the module (or absolute) of the vector. The magnitude is the vector itself. Vector can be measured in many different ways. Also vectors are usually represented in their components form (A,B,C)

(You can have in a vector (31.5, 35є, 14.5), or (35.1є, 180є, 14.2) which would then be converted to the cartesian form with a simple calculation using cos, sin & tan functions)

There's also equillibrants, resultants for each vector. The actual formula for the module is √ (A)І + √ (B)І + √ ©І which is the same to say as √((A)І + (B)І + ©І)

Squaring the powered vectors components is actually to get the non negative values (or absolute value/module) out and remain only with positive numbers that will always lead to a positive result.

Mathematically you can explain this since two positive or negative numbers multiplied between eachother will always result in a positive; X*X are the same numbers and share the same sign, so if X is negative it will be (-X)*(-X) which will result always in a positive number, and that is a property of the powers too, any number powered into a pair exponent always results in a positive number. (X*X = XІ).

If you do this with every component of the vector, you'll get the resultant which is the vector in it's module value, and what is actually measured.

When threating with vectors it should be good to explain where the values you're using come from so you can understand how to apply them.


(Theres also a side vector 'i' which always equals 1 but that's going very deep already :P)
Reply
#6

Quote:
Originally Posted by CuervO
View Post
The actual formula for the module is √ (A)І + √ (B)І + √ ©І which is the same to say as √((A)І + (B)І + ©І)
Thanks for the rest, but AFAIK - this is wrong.

A vector (v = 2i + 3j + 4j) would have different magnitudes then - 9 units and 5.38 units!
Reply
#7

Quote:
Originally Posted by Rajat_Pawar
View Post
Thanks for the rest, but AFAIK - this is wrong.
That means my university engineering textbook for Mathematician Analysis I is wrong?!!; You basically use Pythagorean theorem; I'm not trying to be an smart ass, this guide is incredibly useful, but.... you know.

Module, Absolute, Length, are all synonims and that's what that formula gets.

Taken straight from the book:

There are physical properties which to be measured it is necessary to define it's direction, intensity and some times point of origin. These kind of magnitudes are called vectorians and they can be sorted in oriented segments. Among them we can mention the magnitudes of force, velocity, acceleration, etc.

Each one of these oriented segments receive the name of vectors. They are represented geometrically as rectal segments directed in the three different spaces.

Given a point P ∈ ℝ and a point O ∈ ℝ, we will cover the trhee dimensions:

Unidimensional vectors:

Code:
       i
  ------>------------------------- X
O                                   P
→ OP = Xp (Xp ∈ ℝ)
(X ∈ ℝ) is defined as component X of a vector.

→ |OP| = √(A)І
Which is redundant

--

Bidimensional Vectors




→ OP = Xp i + Yp j ⇔ (Xp, Yp) ⇔ (Xp ^ Yp defined as components)
(X,Y ∈ ℝ)

To calculate the module of this vector we apply Pythagorean theorem:
→ |OP| = √( (Xp)І + (Yp)І )

--

Tridimensional vector (Can't really reproduce the vector position so let's just make a square out of it that represents the OP vector)



→ OP = Xp i + Yp j + Zp k ⇔ (Xp, Yp, Zp) ⇔ (Xp ^ Yp ^ Zp defined as components).
(X,Y,Z ∈ ℝ)

Module:
→ |OP| = √((Xp)І + (Yp)І + (Zp)І)


onclusions:

- A vector (→) is used to measure magnitudes which requiere direction and intensity.
- The intensity of a vector (module |→|) is the sum of all it's components powered to the second and then root squared again.
- It's direction will be determined by it's symbol (+,-)
- There's a versor (aka unit vector) which will share the direction of the vector and will have a module of 1
(|i| = 1, |k| = 1, |j| = 1)


Counter examples.

Quote:

Unit vectors, namely i, j & k, are vectors in the direction of the X, Y & Z axes respectively of magnitude 1 unit.

Their length is not always 1 unit. Their module is.

Quote:

A vector is represented using unit vectors.

Not always, as shown previously.

Quote:

A vector's magnitude is - SquareRoot( (a * a) + (b * b) + (c * c) )

A vector magnitude is what it is measuring. A vector's magnitude can either be force, direction, intensity, etc. What you calculate by that is it's module against the origin, that's why the examples used OP, O stands for Origin and P for Point. Origin is threated as the origin of coordinates within the cartesian axis map (Ordered Triplet (0,0,0)); you can calculate different modules by using the differences.

You can see that →O = →(0,0,0) there for it wont affect the module.
If →O where to be anything else, for example: →O = →(15,-14,2) then the differences between the point and the origin must be calculated.

√((Xp-Xo)І + (Yp-Yo)І + (Zp-Zo)І)
(X,Y,Z ∈ ℝ)

Once again, I am not trying to prove myself smartass but there are missconceptions which on a deep level could mess your methods completely. For this guide this shouldn't even be worth mentioning, but it is always great to learn something new!
Reply
#8

Yes, I am still correct though, no offense! You said that the individual square roots of squares is equal to the magnitude.. which is not true. Look at my first post and what I quoted.. Good one though for some extra information!, thanks! : )
Reply
#9

Correct. |x| is module, mod of x or absolute value of x: taken to make sure that the magnitude X remains positive!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)