# Check if target is within attacking angle

This topic is 2952 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello guys, Im making a small action rpg, building its base at the moment
I've got
* An attacking character
* A n/s/w/e orientation and a defined position within a matrix
* An attack range
* An angle of attack
* A target point

I want to find out if the target point is withing the attacking area, defined by a direction, opening angle and range.

Could any one give me any algorithm idea?

Sorry if this is in the wrong session.

##### Share on other sites
You can use the dot product of the two position vectors to find the angle between them.

##### Share on other sites
Quote:
 Original post by Dom_152You can use the dot product of the two position vectors to find the angle between them.
The dot product of the two position vectors won't give you any useful information. Do you mean the dot product of the attacking character's forward vector and the (normalized) vector to the target?

##### Share on other sites
Quote:
 Original post by jykDo you mean the dot product of the attacking character's forward vector and the (normalized) vector to the target?

What exactly do you mean? I can possibly find the angle between the two points and use that and the distance?

This is confusing me, I'm not really being able to understand properly how to do it.

##### Share on other sites
You can find the angle between two 2-d vectors as follows:
float signed_angle(vector2 v1, vector2 v2){    return atan2(perp_dot(v1, v2), dot(v1, v2));}
The input vectors need not be unit length. (The only requirement is that neither of them has a magnitude that is zero or near zero.)

You can then determine whether the target is within the field of view as follows:
vector2 diff = target.position - character.position;float angle = abs(signed_angle(character.forward, diff));return angle <= field_of_view / 2;

##### Share on other sites
Quote:
Original post by jyk
Quote:
 Original post by Dom_152You can use the dot product of the two position vectors to find the angle between them.
The dot product of the two position vectors won't give you any useful information. Do you mean the dot product of the attacking character's forward vector and the (normalized) vector to the target?

Agreed. You'd need the forward vector of the attacker. And the thread asks for the angle. To get the angle you would need to use arc-cosine of the dot product.

// Pseudo-codevector3 diff = attacker.pos - other.pos;diff.normalize();float dot = attackerFwd.Dot(diff);float angle = acos(dot); // Note: make sure dot is between -1 or 1.

##### Share on other sites
Yes, sorry about that. That is what I was thinking in my head but I clearly did not communicate that!

##### Share on other sites
The easiest to solve is the question "is the target within range?" and that's found using the pythagorean theorem.

To keep this simple we'll define the vectors for the entities' position.

Player -> (p.x, p.y) = p
Enemy -> (e.x, e.y) = e

And the range is just a float
Range -> r

if ((e - p).LengthSquared() < r * r)
{
// Within range
}

If you want you can expand it out to:
if ((e.x - p.x) * (e.x - p.x) + (e.y - p.y) * (e.y - p.y) < r * r)
{
// Within range
}

Now we want to find if the enemy is within a given angle. The dot product can be used:
angleBetweenTwoVectors = acos((a.x * b.x + a.y * b.y) / (a.Length() * b.Length());

First we need to define N,S,W,E. Assuming x and y are positive right and down respectively then:
N -> (0, -1)
S -> (0, 1)
W -> (-1, 0)
E -> (1, 0)
We'll call this direction.

So we have one of the vectors given to us. The other one is created from (e - p). It can be thought of as the vector starting at p and going to e. Since the direction vector is already a unit vector (length of 1) then to find the angle plus or minus between them we can do:

angleBetweenDirectionAndPlayerToEnemy = acos((direction.x * (e.x - p.x) + direction.y * (e.y - p.y)) / sqrt((e.x - p.x) * (e.x - p.x) + (e.y - p.y) * (e.y - p.y)));

This is easier if you have a vector library:
angleBetweenDirectionAndPlayerToEnemy = Math.Acos(Vector2.Dot(direction, (e - p)) / (e - p).Length());

So yeah then you just do:

if (Math.Acos(Vector2.Dot(direction, (e - p)) / (e - p).Length()) < angleOfAttack)
{
// Within angle of attack
}

Put them together like:
if ((e - p).LengthSquared() < r * r && Math.Acos(Vector2.Dot(direction, (e - p)) / (e - p).Length()) < angleOfAttack)
{
// Player can attack the enemy
}

// edit hmm I must have had this open before replying. Anyway I had a cool example I used to give out when people asked this question:
Turret. Your problem seems more tile based though :P

##### Share on other sites
Quote:
 Original post by lordikon*** Source Snippet Removed ***
I'd actually recommend using atan2() rather than acos() (as shown above), as it does not require that the input vectors be unit length, and is a little more stable and robust. (In particular, it eliminates the need for clamping the dot product output to the range [-1, 1] to compensate for potential numerical error.)

##### Share on other sites
Quote:
 Original post by SirisianNow we want to find if the enemy is within a given angle. The dot product can be used:
Similarly, I'd recommend using atan2() rather than acos().

Another option would be to pre-compute and cache the cosine of half the field of view, and then simply compare the dot product of the forward vector and the normalized vector to the target to this value.

1. 1
2. 2
JoeJ
20
3. 3
4. 4
frob
12
5. 5

• 13
• 19
• 13
• 20
• 13
• ### Forum Statistics

• Total Topics
632194
• Total Posts
3004692

×