This is the long due fifth article in this series. If you aren’t comfortable with vectors, you might want to take a look at the first four articles in this series before: Introduction, Vectors 101, Geometrical Representation of Vectors, Operations on Vectors.

This cheat sheet will list several common geometrical problems found in games, and how to solve them with vector math.

## Complete list of basic vector operations

But first, a little review.

For this, I assume that you have a vector class readily available. This is mostly 2D-focused, but everything works the same for 3D, except for differences concerning vector product, which I will assume to return just a scalar in the 2D case, representing the “z” axis. Any case that only applies to 2D or 3D will be pointed out.

Strictly speaking, a point is not a vector – but a vector can be used to represent the distance from the origin (0, 0) to the point, and so, it is perfectly reasonable to just use vectors to represent positions as if they were points.

I expect the class to give you access to each of the components, and to the following operations (using C++ style notation, including operator overloading – but it should be easy to translate to any other language of your choice). If a given operation is not available, you can still do it manually, either by extending the class or creating a “VectorUtils” class. The examples below are usually for 2D vectors – but 3D is usually simply a matter of adding the z coordinate following the pattern of x and y.

Returns the sum of the two vectors. (In a language without operator overloading, this will probably be called add(). Similarly for the next few ones.)*Vector2f operator+(Vector2f vec):*

*a + b = Vector2f(a.x + b.x, a.y + b.y);*Returns the difference between the two vectors.*Vector2f operator-(Vector2f vec):*

*a – b = Vector2f(a.x – b.x, a.y – b.y);*Returns the component-wise multiplication of the vectors.*Vector2f operator*(Vector2f vec):*

*a * b = Vector2f(a.x * b.x, a.y * b.y);*Returns the component-wise division of the vectors.*Vector2f operator/(Vector2f vec):*

*a / b = Vector2f(a.x / b.x, a.y / b.y);*: Returns the vector with all components multiplied by the scalar parameter.*Vector2f operator*(float scalar)*

*a * s = Vector2f(a.x * s, a.y * s);*

s * a =*Vector2f(a.x * s, a.y * s);*Returns the vector with all components divided by the scalar parameter.:*Vector2f operator/(float scalar)*

*a / s = Vector2f(a.x / s, a.y / s);*: Returns the dot product between the two vectors.*float dot(Vector2f vec)*

*a.dot(b) = a.x * b.x + a.y * b.y;*: (2D case) Returns the z component of the cross product of the two vectors augmented to 3D.*float cross(Vector2f vec)*

*a.cross(b) = a.x * b.y – a.y * b.x;*: (3D case) Returns the cross product of the two vectors.*Vector3f cross(Vector3f vec)*

*a.cross(b) = Vector3f(a.y * b.z – a.z * b.y, a.z*b.x – a.x*b.z, a.x*b.y – a.y*b.x);*: Returns the length of the vector.*float length()*

*a.length() = sqrt(a.x * a.x + a.y * a.y);*Returns the square of the length of the vector. Useful when you just want to compare two vectors to see which is longest, as this avoids computing square roots**float squaredLength()**:

*a.squaredLength() = a.x * a.x + a.y * a.y;*: Returns a vector pointing on the same direction, but with a length of 1.*float unit()*

*a.unit() = a / a.length();*Returns the vector rotated 90 degrees left. Useful for computing normals. (Assumes that y axis points up, otherwise this is turnRight)**Vector2f turnLeft()**:

*a.turnLeft = Vector2f(-a.y, a.x);*Returns the vector rotated 90 degrees right. Useful for computing normals. (Assumes that y axis points up, otherwise this is turnLeft)**Vector2f turnRight()**:

*a.turnRight = Vector2f(a.y, -a.x);***Vector2f rotate(float angle)**: Rotates the vector by the specified angle. This is an extremely useful operation, though it is rarely found in Vector classes. Equivalent to multiplying by the 2×2 rotation matrix.

*a.rotate(angle) = Vector2f(a.x * cos(angle) – a.y * sin(angle), a.x * sin(angle) + a.y * cos(angle));*Returns the angle that the vector points to.*float angle():*

*a.angle() = atan2(a.y, a.x);*

## Simple cases – warming up

### Case #01 – Distance between two points

You probably know that this is done with the Pythagorean theorem, but the vectorial way is simpler. Given two vectors *a* and *b*:

float distance = (a-b).length();

### Case #02 – Alignment

Sometimes, you want to align an image by its center. Sometimes, by its top-left corner. Or sometimes, by its top-center point. More generally, you can do alignment using a vector whose two components go from 0 to 1 (or even beyond, if you’d like), giving you full control of alignment.

// imgPos, imgSize and align are all Vector2f Vector2f drawPosition = imgPos + imgSize * align

### Case #03 – Parametric Line Equation

Two points define a line, but it can be tricky to do much with this definition. A better way to work with a line is its parametric equation: one point (“*P0″*) and a direction vector (“*dir”*).

Vector2f p0 = point1; Vector2f dir = (point2 - point1).unit();

With this, you can, for example, get a point 10 units away by simply doing:

Vector2f p1 = p0 + dir * 10;

### Case #04 – Midpoint and interpolation between points

Say you have vectors *p0* and *p1*. The midpoint between them is simply *(p0+p1)/2*. More generally, the line segment defined by *p0* and *p1* can be generated by varying *t* between 0 and 1 in the following linear interpolation:

Vector2f p = (1-t) * p0 + t * p1;

At *t = 0*, you get *p0; *at *t = 1*, you get *p1*; at *t = 0.5*, you get the midpoint, etc.

### Case #05 – Finding the normal of a line segment

You already know how to find the direction vector of a line segment (case #03). The normal vector is a 90 degree rotation of that, so just call *turnLeft()* or *turnRight()* on it!

## Projections using the Dot Product

The dot product has the incredibly useful property of being able to compute the length of a vector’s projection along the axis of another. To do this, you need the vector that you’ll project (“*a*“) and a unit vector (so make sure that you call *unit()* on it first!) representing the direction (“*dir*“). The length is then simply *a.dot(dir)*. For example, if you have *a = (3, 4)* and *dir = (1, 0)*, then *a.dot(dir) = 3*, and you can tell that this is correct, because (1, 0) is the direction vector of the x axis. In fact, *a.x* is always equivalent to *a.dot(Vector2f(1, 0))*, and *a.y* is equivalent to *a.dot(Vector2f(0, 1))*.

Because the dot product between *a* and *b* is also defined as *|a||b|cos(alpha)* (where alpha is the angle between the two), the result will be 0 if the two vectors are perpendicular, positive if the angle between them is less than 90, and negative if greater. This can be used to tell if two vectors point in the same general direction.

If you multiply the result of that dot product by the direction vector itself, you get the vector projected along that axis – let’s call that “*at*” (t for tangent). If you now do *a – at*, you get the part of the vector that is perpendicular to the *dir* vector – let’s call that “*an*” (n for normal). *at + an = a*.

### Case #06 – Determining direction closest to dir

Say that you have a list of directions represented as unit vectors, and you want to find which of them is the closest to *dir*. Simply find the largest dot product between *dir* and a vector in the list. Likewise, the smallest dot product will be the direction farthest away.

### Case #07 – Determining if the angle between two vectors is less than alpha

Using the equation above, we know that the angle between two vectors *a *and* b *will be less than alpha if the dot product between their unit vectors is less than cosine of alpha.

bool isLessThanAlpha(Vector2f a, Vector2f b, float alpha) { return a.unit().dot(b.unit()) < cos(alpha); }

### Case #08 – Determining which side of a half-plane a point is on

Say that you have an arbitrary point in space, *p0*, and a direction (unit) vector, *dir*. Imagine that an infinite line goes by *p0*, perpendicular to *dir*, dividing the plane in two, the half-plane that *dir* points to, and the half-plane that it does not point to. How do I tell whether a point *p* is in the side pointed to by *dir*? Remember that dot product is positive when the angle between vectors is less than 90 degrees, so just project and check against that:

bool isInsideHalfPlane(Vector2f p, Vector2f p0, Vector dir) { return (p - p0).dot(dir) >= 0; }

### Case #09 – Forcing a point to be inside a half-plane

Similar to the case above, but instead of just checking, we’ll grab the projection and, if less than 0, use it to move the object -projection along dir, so it’s on the edge of the half-plane.

Vector2f makeInsideHalfPlane(Vector2f p, Vector2f p0, Vector dir) { float proj = (p - p0).dot(dir); if (proj >= 0) return p; else return p - proj * dir; }

### Case #10 – Checking~~/forcing~~ a point inside a convex polygon

A convex polygon can be defined to be the intersection of several half-planes, one for each edge of the polygon. Their *p0* is either vertex of the edge, and their *dir* is the edge’s inner-facing normal vector (e.g., if you wind clockwise, that’d be the *turnRight()* normal). A point is inside the polygon if and only if it’s inside all the half-planes. ~~Likewise, you can force it to be inside the polygon (by moving to the closest edge) by applying the ~~ [ops, this actually only works if all angles are >= 90 degrees]*makeInsideHalfPlane* algorithm with every half-plane.

### Case #11 – Reflecting a vector with a given normal

Pong-like game. Ball hits a sloped wall. You know the ball’s velocity vector and the wall’s normal vector (see case #05). How do you reflect it realistically? Simple! Just reflect the ball’s normal velocity, and preserve its tangential velocity.

Vector2f vel = getVel(); Vector2f dir = getWallNormal(); // Make sure this is a unit vector Vector2f velN = dir * vel.dot(dir); // Normal component Vector2f velT = vel - velN; // Tangential component Vector2f reflectedVel = velT - velN;

For more realism, you can multiply velT and velN by constants representing friction and restitution, respectively.

### Case #12 – Cancelling movement along an axis

Sometimes, you want to restrict movement in a given axis. The idea is the same as above: decompose in a normal and tangential speed, and just keep tangential speed. This can be useful, for example, if the character is following a rail.

## Rotations

### Case #13 – Rotating a point around a pivot

If used to represent a point in space, the *rotate()* method will rotate that point around the origin. That might be interesting, but is limiting. Rotating around an arbitrary *pivot* vector is simple and much more useful – simply subtract the *pivot* from it, as if translating so the origin IS the *pivot*, then rotate, then add the *pivot* back:

Vector2f rotateAroundPivot(Vector2f p, Vector2f pivot) { return (pos - pivot).rotate(angle) + pivot; }

### Case #14 – Determining which direction to turn towards

Say that you have a character that wants to rotate to face an enemy. He knows his direction, and the direction that he should be facing to be looking straight at the enemy. But should he turn left or right? The *cross* product provides a simple answer: *curDir.cross(targetDir)* will return positive if you should turn left, and negative if you should turn right (and 0 if you’re either facing it already, or 180 degrees from it).

## Other Geometric Cases

Here are a few other useful cases that aren’t that heavily vector-based, but useful:

### Case #15 – Isometric world to screen coordinates

Isometric game. You know where the (0, 0) of world is on the screen (let’s call that point *origin* and represent it with a vector), but how do you know where a given world (x, y) is on the screen? First, you need two vectors determining the coordinate base, a new x and y axes. For a typical isometric game, they can be *bx = Vector2f(2, 1)* and *by = Vector2f(-2, 1) *– They don’t necessarily have to be unit vectors. From now, it’s straightforward:

Vector2f p = getWorldPoint(); Vector2f screenPos = bx * p.x + by * p.y + origin;

Yes, it’s that simple.

### Case #16 – Isometric screen to world coordinates

Same case, but now you want to know which tile the mouse is over. This is more complicated. Since we know that *(x’, y’) = (x * bx.x + y * by.x, x * bx.y + y * by.y) + origin*, we can first subtract origin, and then solve the linear equation. Using Cramer’s Rule, except that we’ll be a little clever and use our 2D cross-product (see definition at the beginning of the article) to simplify things:

Vector2f pos = getMousePos() - origin; float demDet = bx.cross(by); float xDet = pos.cross(by); float yDet = bx.cross(pos); Vector2f worldPos = Vector2f(xDet / demDet, yDet / demDet);

And now you don’t need to do that ugly find-rectangle-then-lookup-on-bitmap trick that I’ve seen done several times before.

## Hindstudys

/ 2017-10-25You Can Check Here All University Time Table 2018

## Putlocker

/ 2017-11-10This is so great and I absolutely appreciate you sharing your experience.

## BPUT Result

/ 2017-11-21Thanks for the information it’s really useful for me.

## word cookies answersaz

/ 2018-01-16I dont really appreciate your post

## word cookies answersaz

/ 2018-01-16Why my comment no appear??

## All Exams Result

/ 2018-02-20Great article that is furnished on this web page.

## Full Movies

/ 2018-03-08Fastest way to watch new movies online and free on 123Movies.in.net We have more than 65000 Movies Simply to enjoy any movies you want. 123Movies

## driving directions

/ 2018-03-09Hi, this weekend is nice in favor of me, for the reason that this time i am reading this enormous informative article here at my residence.

## Kizi 4 online

/ 2018-03-24Very good and useful programming vector codes, thanks a lot you are great.

## sanjay kumar

/ 2018-03-27I must say that post is great for new user like me who want to learn something about education portal.

## kiran negi

/ 2018-04-03Thanks for the information it’s really useful for me

## Obat mata minus

/ 2018-04-05Trans and non-binary people rightly push the ingrained, stubborn and unhelpful gender norms in both society and the workplace. The workplace is a very binary place and I always ask myself why this is. In my opinion it’s partly due to historic and legacy reasons, although with millennials viewing gender as a spectrum we will see the challenge to de-genderise the workplace increase …

## GeetaSukh Abhishek

/ 2018-05-01Nice page Check Latest Govt. Jobs Recruitment

## GeetaSukh Abhishek

/ 2018-05-01Check Latest Govt. Jobs Recruitment

## Answer Key 2018

/ 2018-05-02Great article that is furnished on this web page.

## AMIT

/ 2018-05-02Latest Job notification in NRHMNRHM MP Recruitment 2018

## Alka Talwar

/ 2018-05-02I trust it’s a great job the board is doing and it must be cheered. Each course taken for more prominence’s benefit of individuals is a decent one.

## amit

/ 2018-05-03Check employment notification in NRHMPunjab NRHM Recruitment 2018

## RSMSSB Computer Answer Key 2018

/ 2018-05-05Nice Blog Thanks for sharing such useful details with us.

## RSMSSB Answer Key 2018

/ 2018-05-05Thank you for all the help and links that you have provided on this blogpost.

## Result 2018

/ 2018-05-05Thanks for your article, it gave me a lot of new and useful information.

## latest govt jobs

/ 2018-05-25Thank you

## corbett treat resort

/ 2018-05-30good tourist travel site Jeep Safari at Jhirna Zone in Corbett Park

## fresh job alerts Sarkari Naukri

/ 2018-05-30good post recruitment 2018 IBPS jobs

## cbse 10 results 2018

/ 2018-05-31Thank you for all the help and links pbse board 10 results 2018

## yoga poses health benefit

/ 2018-06-16thanks for sharing this with us.

## online apply Voter Id Card Registration

/ 2018-06-28I like what I see so i am just following you. Look forward to looking over your web page

## Chirurgie esthetique Tunisie : Docteur Mahmoud

/ 2018-07-02Docteur Hichem Mahmoud vous propose une gamme de prix pas chers opérations de liposuccion, abdominoplastie, blépharoplastie, augmentation mammaire, réduction mammaire, lifting visage, injection Botox, injection acide hyaluronique, cryolipolyse et d’autres opérations simples ou invasives à des prix imbattables. http://www.docteur-hichem-mahmoud.com/le-docteur-hichem-mahmoud/

## happy wheels

/ 2018-07-06Thanks for sharing this helpful article.

## Travel Nearby

/ 2018-07-27This is a wonderful article, Given so much info in it, You can see travel nearby best tourist place Best Honeymoon Destination in this page.

Weekend Gateways Near Pune

## helmet heroes

/ 2018-08-05First of all I want to say excellent blog! I had a quick question in which I’d like to ask if you don’t mind.

I was curious to know how you center yourself and clear your head before writing.

I’ve had difficulty clearing my mind in getting

my ideas out. I do enjoy writing however

it just seems like the first 10 to 15 minutes are usually lost simply just trying to

figure out how to begin. Any ideas or hints? Cheers!

## Modicare marketing business

/ 2018-08-11Your website is lovingly serviced and saved as much as date. So it should be, thanks for sharing this with us.

i also found some helpful sites like yours. Modicare Products

## Avishek

/ 2018-08-15I am very glad to see this page. Check RSMSSB LDC Syllabus 2018

## Avishek

/ 2018-08-17I am very glad to see this page. Download RSMSSB LDC Admit Card 2018 Details

## uprocento sesxebi

/ 2018-09-27sesxebii

## Mycrickethighlights

/ 2018-10-07This is not a bhatti

## Mycrickethighlights

/ 2018-10-07This is not a bhatti, You must take precautions

## keshav singh

/ 2018-12-29with the help of cheat i always win in the game your cheat is awesome

## RRB Bhubaneswar Group D Result 2019

/ 2019-02-18Nice Post

## chirurgie esthetique Tunisie

/ 2019-03-19good

## chirurgie esthetique Tunisie

/ 2019-03-26super article

## lisa

/ 2019-04-10I am also not a fan of buttercream frosting and always substitute for a cream cheese frosting. I’ll always use the buttercream recipe add-ins though. Love this idea and am excited to see what comes next.

## Results Alertac

/ 2019-04-13Thanks for the information it’s really useful for me