7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
  1. Code
  2. Games

Vector Regions: Hiding From a Field of View

Scroll to top
Read Time: 15 mins

Previously, we explored the approach of using vector regions to implement the field of view of a turret. Troops approached the turret on open field and no hindrances lay between them. Now suppose there is a hinderance, say a wall, that obscures the visibility of troop from turret; how should we implment that? This tutorial suggest an approach to tackle this issue.

Final Result Preview

Let's take a look at the final result we will be working towards. Click on the turret at the bottom of the stage to start the simulation.

Step 1: The Basic Concept

Field of view of turret and attempts to obscure its view.Field of view of turret and attempts to obscure its view.Field of view of turret and attempts to obscure its view.

So here's what we try to achieve in this tutorial. Observe the image above. The turret can see the trooper unit if it's within turret's field of view (top). Once we place a wall in between the turret and the trooper, the trooper's visibility is shielded from turret.

Step 2: Recap

Troops within visible range.

First of all, let's do a little revision. Say the vector of turret's line of sight is P and the vector from turret to trooper is Q. The trooper is visible to the turret if:

  • Angle between P and Q is less than the angle of view (in this case 30° on both sides)
  • Magnitude of P is more than Q

Step 3: Approach Overview

A brief pseudo-code of the approach.

Above is the pseudo-code for the approach we shall undertake. Determining whether the trooper is within the turret's field of view (FOV) is explained in Step 2. Now let's get to determining whether the trooper is behind a wall.

We shall use vector operations to achieve this. I'm sure by the mention of this, the dot product and cross product quickly come to mind. We shall make a little detour to revise these two vector operations just to make sure everyone's able to follow.

Step 4: Dot and Cross Product between Vectors

Dot and cross products of A & B

Let's revisit the vector operations: dot product and cross product. This is not a Math class, and we have covered these in more detail before, but still, it's good to refresh our memory on the workings so I've included the image above. The diagram shows "B dot A" operation (top right corner) and "B cross A" operation (bottom right corner).

More important are the equations of these operations. Take a look at the image below. |A| and |B| refer to the scalar magnitude of each vector - the length of the arrow. Note that the dot product relates to the cosine of the angle between the vectors, and the cross product relates to the sine of the angle between the vectors.

Formulas of dot and cross products

Step 5: Sine and Cosine

Drilling further into the topic, Trigonometry comes to play: the sine and cosine. Im sure these graphs rekindle fond memories (or agonies). Do click on the buttons on Flash presentation below to view those graphs with different units (degrees or radians).

Note that these wave forms are continuous and repetitive. For example, you can cut and paste the sine wave into the negative range to get something like below.

Two portions of sine wave.

Step 6: Summary of Values

Degree Sine of degree Cosine of degree
-180 0 -1
-90 -1 0
0 0 1
90 1 0
180 0 -1

The table above shows the cosine and sine values corresponding to specific degrees. You'll notice the positive sine graph covers 0° to 180° range and positive cosine graph covers -90° to 90°. We shall relate these values to the dot product and cross product later.

Step 7: Geometric Interpretation of Dot Product

So how can all these be useful? To cut to the chase, the dot product is a measure of how parallel the vectors are whereas cross product is a measure of how orthogonal the vectors are.

Interpretation on geometry

Lets deal with the dot product first. Recall the formula for the dot product, as mentioned in Step 4. We can determine the whether result is positive or negative just by looking at the cosine of the angle sandwiched between the two vectors. Why? Because the magnitude of a vector is always positive. The only parameter left to dictate the sign of the result is the cosine of the angle.

Again, recall that positive cosine graph covers -90° - 90°, as in Step 6. Therefore, the dot product of A with any of the vecotrs L, M, N, O above will produce a positive value, because the angle wedged between A and any of those vectors is within -90° and 90°! (To be precise, the positive range is more like -89° - 89° because both -90° and 90° produces cosine values of 0, which brings us to the next point.) The dot product between A and P (given P is perpendicular to A) will produce 0. The rest I think you can already guess: the dot product of A with K, R, or Q will produce a negative value.

By using the dot product, we can split the area on our stage into two regions. The dot product of the vector below with any point that lies inside of the "x"-marked region will produce a positive value, whereas the dot product with those in the "o"-marked region will produce negative values.

Dot region divides area into two.

Step 8: Geometric Interpretation of Cross Product

Let's move on to the cross product. Remember that the cross product relates to the sine of angle sandwiched between the two vectors. The positive sine graph covers a range of 0° to 180°; the negative range covers 0° to -180°. The image below summarises these points.

Positive and negative cross product.

So, looking again at the diagram from Step 7, the cross product between A and K, L, or M will produce positive values, while the cross product between A and N, O, P, or Q will produce negative values. The cross product between A and R will produce 0, as sine of 180° is 0.

To clarify further, the cross product of vector between any point that lies in the "o"-marked region below will be positive, whereas those in "x"-marked region will be negative.

Cross region divides area into 2.

One point to take note of is that, unlike the dot product, the cross product is sequence sensitive. This means results of AxB and BxA will be different in terms of direction. So as we write our program, we need to be precise when choosing which vector to be compared against.

(Note: These concepts explained apply to 2D Cartesian space.)

Step 9: Demo Application

To reinforce your understanding, I've placed here a little application to let you play with. Click on the blue ball at the top of stage and drag it around. As you move, the text box value will update depending on which operation you have chosen (dot or cross product between the static arrow with the one you control).

You may observe one oddity with the cross product's inverted direction. The region on top is negative and the bottom is positive, in contrast with our explanation in previous step. Well, this is due to the y-axis being inverted in Flash coordinate space compared to Cartesian coordinate space; it points down, whereas traditionally mathematicians take it as pointing upwards.

Step 10: Defining Regions

Now that you have understood the concept of regions, let's do a little practice. We shall divide our space into four quadrants: A1, A2, B1, B2.

Space divided into 4 regions.

I've tabulated the results to check for below. "Vector" here refers to the arrow in the image above. "Point" refers to any coordinate in the specified region. The vector divides the stage into four main areas, where the dividers (dotted lines) extend to infinity.

Region Vector on diagram cross product with point Vector on diagram dot product with point
A1 (+), because of Flash coordinate space (+)
A2 (+) (-)
B1 (-), because of Flash coordinate space (+)
B2 (-) (-)

Step 11: Regions Divided

Here's the Flash presentation showcasing the ideas as explained in step 10. Right click on stage to pop the context menu and select the region you would like to see highlighted.

Step 12: Implementation

Here's the ActionScript implementation of the concept explained in Step 10. Feel free to view the whole piece of code in the source download, as AppLine.as.

Step 13: Shielded Visibility

Having understood the geometrical interpretations of dot product and cross product, we shall apply it to our scenario. The Flash presentation above shows variations of the same scenario and summarises the conditions applied to a trooper shielded by a wall yet inside the turret's FOV. You can scroll through the frames using the arrow buttons.

The following explanations are based upon the 2D Flash coordinate space. In Frame 1, a wall is placed between the turret and the trooper. Let A and B be the vectors from the turret to the tail and the head of the wall's vector, respectively. Let C be the vector of the wall, and D be the vector from the tail of the wall to the trooper. Finally, let Q be the vector from the turret to the trooper.

I have tabulated the resulting conditions below.

Location Cross Product
Troop is in front of wall C x D > 0
Troop is behind wall C x D < 0

This is not the only condition applicable, because we also need to restrict the trooper to within the dotted lines on both sides. Check out frames 2-4 to see the next set of conditions.

Location Cross Product
Troop is within the sides of the wall. Q x A < 0, Q x B > 0
Troop is to the left of the wall Q x A > 0, Q x B > 0
Troop is to the right of the wall Q x A < 0, Q x B < 0

I think my fellow readers can now choose the appropriate conditions to determine whether the trooper is hidden from view or not. Bear in mind that this set of conditions are evaluated after we found troop to be within turret's FOV (refer to step 3).

Step 14: Actionscript Implementation

The initial state of the application.

Here's the ActionScript implementation of the concepts explained in Step 13. The image above shows the initial vector of the wall, C. Click and drag the red button below and move it around to see the area shielded. You may view the full source code in HiddenSector.as.

Okay, I hope you have experimented with the red ball, and if you are observant enough you might have noticed an error. Note there is no area shielded as the red button moves to the left of the other end of the wall, thus inverting the wall vector to point to left instead of right. The solution is in the next step.

However, before that let's look at an important ActionScript snippet here in HiddenSector.as:

Step 15: Direction of Wall

To solve this issue, we need to know whether the wall vector is pointing to the left or the right. Let's say we have a reference vector, R, that's always pointing to the right.

Direction of vector Dot Product
Wall is pointing to right (same side as R) w . R > 0
Wall is pointing to left (opposite side of R) w . R < 0

Of course, there are other ways around this problem but I figure it's an opportunity to utilise concepts expressed in this tutorial, so there you go.

Step 16: Actionscript Tweaks

Below is a Flash presentation which implements the correction explained in Step 15. After you have played with it, scroll down to check the ActionScript tweaks.

The changes from the previous implementation are highlighted. Also, the sets of condition are redefined according to the wall direction:

Check out the full source in HiddenSector2.as.

Step 17: Set Up the Wall

Now we shall patch our work onto Scene1.as from the previous tutorial. First, we shall set up our wall.

We initiate the variables,

...then draw the wall for the first time,

...and redraw on each frame, because the graphics.clear() call is somewhere in behaviourTurret():

Step 18: Interaction with Wall

Troops will interact with the wall as well. As they collide with the wall, they will slide along the wall. I will not try to go into details of this as it has been documented extensively in Collision Reaction Between a Circle and a Line Segment. I encourage readers to check that out for further explanation.

The following snippet lives in the function behaviourTroops().

Step 19: Checking Troopers' "Hidden-ness"

Finally, we come to the meat of this tutorial: setting up the condition and checking whether troopers are behind the wall and therefore shielded from turret visibility. I have highlighted the important patch codes:

Check out the full code in Scene1_2.as.

Step 20: Lauch the Application

Finally, we can sit back and check out the patch in action. Hit Ctrl + Enter to see the results of your work. I have included a copy of the working Flash presentation below. Click on the turret at the bottom of the stage to start the simulation.

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.