Donut Shaped Patrol Destination Area

• Hi guys. I'm trying to make a natural looking patrol point for my AI but I really don't know the math I should be using. Here's what the area will look like.

<img src="http://puu.sh/4gCX3.png" border="0" />

I know it will involve a maximum radius and a minimum radius but I really don't know how I could designate a point within that.

• Try Construct 3

Develop games in your browser. Powerful, performant & highly capable.

Construct 3 users don't see these ads
• Just use a circular sprite object?

• ...No. It wouldn't work that way. Anyways, I found the math. Here is the solution for anyone with a similar problem.

<img src="http://puu.sh/4gNw9.png" border="0" />

If you set "Patrol Area" to a random positive number, it will go to a random circular point that as far away from the object as that random number is.

• Good to see you're solved your problem by yourself. But, as I made such an effort to draw such a nice graphic, I will post a more general info that also takes into account the diameter of the ring.

<img src="https://dl.dropboxusercontent.com/u/11182740/construct/donut.png" border="0" />

c = center

a = angle

r = radius to outer boundary

r' = radius to inner boundary

p = new point within destination zone

d = distance from r' to p

a = random(360�)

d = random(r - r')

p.x = c.x + cos(a) * (r' + d)

p.y = c.y + sin(a) * (r' + d)

• Good to see you're solved your problem by yourself. But, as I made such an effort to draw such a nice graphic, I will post a more general info that also takes into account the diameter of the ring.

<img src="https://dl.dropboxusercontent.com/u/11182740/construct/donut.png" border="0" />

c = center

a = angle

r = radius to outer boundary

r' = radius to inner boundary

p = new point within destination zone

d = distance from r' to p

a = random(360?)

d = random(r - r')

p.x = c.x + cos(a) * (r' + d)

p.y = c.y + sin(a) * (r' + d)

That's a nice graph. It helps me understand what's going on a little more, but I'm actually having a problem with something else now.

I'm trying to make the enemy go to an area that is around the player based on their current position, so if the enemy is too close to the player, he will back off. If he's too far, he gets closer. Basically, I want the enemy to move into the area around the circle by moving to and from the angle direction between the player and the enemy.

This is what I have but it's not quite working. The angle is off-set at a weird spot. <img src="http://puu.sh/4gSoq.png" border="0" /> I'd appreciate your help a second time.

• I'm not sure if I understand you right. But if so, then you have to calculate the angle FROM the enemy TO the player, not the other way round.

Scenario:

Player is at (100, 100) with a zone of radius 50. Enemy is at (250, 50)

Now the angle from the player's perspective to the enemy would be ~341.57�. But the angle you need is the one from the enemy's perspective to the player, which is ~161.57

The rule is that the first pair of coordinates in the angle expression has to be the one of whose perspective you're trying to get the angle.

angle(playerXY, enemyXY) => the angle that points towards the enemy

angle(enemyXY, playerXY) => the angle that points towards the player

But that's not all in this case. You also want to move the enemy from its current position to the proximity zone of the player, which in this case is a 50 pixel radius around the player. So you have to SUBTRACT that radius from the total distance between enemy and player.

The enemy calculation would then look something like that:

self.x + cos(angle(self.x, self.y, player.X, player.y)) * (distance(self.x, self,y, player.x, player.y) - 50)

self.y + sin(angle(self.x, self.y, player.X, player.y)) * (distance(self.x, self,y, player.x, player.y) - 50)

You would need to replace 50 by the correct radius.

• I'm not sure if I understand you right. But if so, then you have to calculate the angle FROM the enemy TO the player, not the other way round.

Scenario:

Player is at (100, 100) with a zone of radius 50. Enemy is at (250, 50)

Now the angle from the player's perspective to the enemy would be ~341.57?. But the angle you need is the one from the enemy's perspective to the player, which is ~161.57

The rule is that the first pair of coordinates in the angle expression has to be the one of whose perspective you're trying to get the angle.

angle(playerXY, enemyXY) => the angle that points towards the enemy

angle(enemyXY, playerXY) => the angle that points towards the player

But that's not all in this case. You also want to move the enemy from its current position to the proximity zone of the player, which in this case is a 50 pixel radius around the player. So you have to SUBTRACT that radius from the total distance between enemy and player.

The enemy calculation would then look something like that:

self.x + cos(angle(self.x, self.y, player.X, player.y)) * (distance(self.x, self,y, player.x, player.y) - 50)

self.y + sin(angle(self.x, self.y, player.X, player.y)) * (distance(self.x, self,y, player.x, player.y) - 50)

You would need to replace 50 by the correct radius.

Works like a charm! Thanks a ton.