# How do I detect collisions with a circle sector against basic geometry?

For the 2D game that I'm building, I want some entities to be able to use areas of attack, such as a wedge/circle sector area of attack.

In this case, the circle sector is a pie-slice shaped section of a circle defined by:

• The circle centre coordinates
• The angle of the slice's centre
• The angle size of the slice

With this information, I can easily detect if a point is contained inside the sector.

However, I want to test for collisions with:

• Other circle sectors
• Circles (2D)
• Rectangles (2D)

How can I do this?

I believe I may have an answer, though please do point out if I'm incorrect. I'll be pasting my answers in TypeScript, leaving out the basic functions that you can find pretty easily on the web.

## Wedge-Circle Collision

This appears to be the simplest. Already knowing how to make two circles collide (test their distances from one another is less than the two radiuses), we want to do a similar test for a wedge and a circle, and then determine if the point of collision is inside the wedge:

export function wedgeAndCircleCollide(
wedge: BoundingWedge,
circle: BoundingCircle,
): boolean {
if (!circlesCollide(
boundingCircleFromWedge(wedge),
circle,
)) {
return false
}

// Determine the collision angle between the two circles for
// the wedge
const wedgeCollisionAngle = pointAngle(
wedge.center,
circle.center,
)

// Return whether the angle of collision is within the wedge's
// angles
return angleInRange(wedgeCollisionAngle, wedge.directionAngle, wedge.widthAngle)
}


## Wedge-Wedge Collision

Similarly, wedge-wedge collision adds a second step of testing if that angle is in the range of the second wedge as well:

export function wedgesCollide(bw1: BoundingWedge, bw2: BoundingWedge): boolean {
if (!circlesCollide(
boundingCircleFromWedge(bw1),
boundingCircleFromWedge(bw2),
)) {
return false
}

// Determine the collision angle between the two circles for...
//  ...wedge 1
const w1CollisionAngle = pointAngle(
bw1.center,
bw2.center,
)

// ...wedge 2
const w2CollisionAngle = pointAngle(
bw2.center,
bw1.center,
)

// If the collision angle for wedge 1 is within wedge 1's
// angle, mark it down
const collisionInW1 = angleInRange(w1CollisionAngle, bw1.directionAngle, bw1.widthAngle)

// If the collision angle for wedge 2 is within wedge 2's
// angle, mark it down
const collisionInW2 = angleInRange(w2CollisionAngle, bw2.directionAngle, bw2.widthAngle)

// Return whether the collision is in both wedge 1 and wedge 2
return collisionInW1 && collisionInW2
}


## Box-Wedge Collision

This is by far the most complicated.

The main function goes something like:

export function wedgeAndBoxCollide(wedge: BoundingWedge, box: BoundingBox) {
const circleFromWedge = boundingCircleFromWedge(wedge)

// Cheap check:
// Check that the circle is inside the rectangle. If so,
// return true
if (boundingCircleInBox(circleFromWedge, box)) {
return true
}

const boxCentreX = box.x + (box.width / 2)
const boxCentreY = box.y + (box height / 2)

const topLeft: PointTuple = [box.x, box.y]
const bottomLeft: PointTuple = [box.x, box.y + box.height]
const topRight: PointTuple = [box.x + box.width, box.y]
const bottomRight: PointTuple = [box.x + box.width, box.y + box.height]

const closestHorizontalWall: LineTuple = wedge.center.x <= boxCentreX
? [topLeft, bottomLeft]
: [topRight, bottomRight]

const closestVerticallWall: LineTuple = wedge.center.y <= boxCentreY
? [topLeft, topRight]
: [bottomLeft, bottomRight]

// Check the two most relevant walls. If there's a collision,
// return true
return wedgeCollidesWithLine(closestHorizontalWall, wedge) ||
wedgeCollidesWithLine(closestVerticallWall, wedge)
}


where wedgeCollidesWithLine() looks like:

export function wedgeCollidesWithLine(
line: LineTuple,
wedge: BoundingWedge,
): boolean {
const safeDirectionAngle = getSafeAngle(wedge.directionAngle)
const wedgeHalfAngle = getSafeAngle(wedge.widthAngle) / 2

if (
pointInWedge(line[0], wedge) ||
pointInWedge(line[1], wedge)
) {
return true
}

const lineSlope = getSlope(line)
// y = mx + b
// b = -mx + y
const perpendicularLineIntercept = (lineSlope * wedge.center.x * -1) + wedge.center.y
const perpendicularX = wedge.center.x + 10
const perpendicularY = (lineSlope * perpendicularX) + perpendicularLineIntercept

// Point-angle to box edge
// Return true if in wedge
const centreToLineIntersectionPoint = getLineIntersectionPoint(
[ wedge.center, [perpendicularX, perpendicularY] ],
line,
)

// If the distance from the line to the wedge circle
// is greater than the radius length, there's not going
// to be an intersection
if (
pointDistance(
wedge.center,
centreToLineIntersectionPoint,
) {
return false
}

if (pointInWedge(centreToLineIntersectionPoint, wedge)) {
return true
}

const safeLeftBound = getSafeAngle(safeDirectionAngle - wedgeHalfAngle)
const safeRightBound = getSafeAngle(safeDirectionAngle + wedgeHalfAngle)
// Get intersection by wedge bounds
// Is it in the given line?
const leftEdgePoint: PointTuple = [
wedge.center.x + getLengthDirX(
safeLeftBound,
),
wedge.center.y + getLengthDirY(
safeLeftBound,
),
]
const leftIntersectionPoint = getLineIntersectionPoint(
[wedgeCentre, leftEdgePoint],
line,
)

const rightEdgePoint: PointTuple = [
wedge.center.x + getLengthDirX(
safeRightBound,
),
wedge.center.y + getLengthDirY(
safeRightBound,
),
]
const rightIntersectionPoint = getLineIntersectionPoint(
[wedgeCenter, rightEdgePoint],
line,
)

// Check if the intersections with the wedge bounds
// are within the wedge: if not, the wedge is not facing
// the line, and thus no collision occurs
return pointInWedge(leftIntersectionPoint, wedge) ||
pointInWedge(rightIntersectionPoint, wedge)
}


The idea here being:

• If there's a collision with a corner, it's a collision
• For each relevant edge:
• Get the distance to the edge
• Get the point-angle between the wedge and the box edge
• Determine if the line from the wedge to the edge is in the wedge
• If not, extend the "wings" of the wedge, and see if they collide with the line at all. If they do, determine if that collision is inside the wedge bounds.
• Shape collision problems tend to have lots of non-obvious edge cases. I suspect that at least your wedge-wedge collision is not correct - does it deal with the case of two narrow wedges making a cross shape without the points or edges overlapping? Jun 13, 2023 at 7:07
• You're absolutely right... neither the wedge-wedge nor wedge-circle account for this. I'll need to take another look with this specifically in mind. This would likely account for some errors I've been seeing so far... Jun 13, 2023 at 15:04

I have used this method when I want to my Enemy attack my Player when the Player go into the Enemy's attack area.

using UnityEngine;

public class EnemyCombat : EnemyCombat
{
public Transform attackPoint;
public float attackRange;
private Collider2D[] hitPlayer;
// Starthas Attackedbefore the first frame update
void Start()
{

}

// Update is called once per frame
void Update()
{
Attack_FollowCharacter();
}
private void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(attackPoint.position, attackRange);   //Use need to use this to visually the area, for this it will draw a circle with the attackPoint is the center of the circle
}
private void Attack_FollowCharacter()
{
hitPlayer = Physics2D.OverlapCircleAll(attackPoint.position, attackRange, playerLayer);  //Check the Player if they go into attack area
foreach (Collider2D player in hitPlayer)
{
//Write your code if Player went into
}
}


If anything hard to understand few free to respond

• This does not seem to address the "sector" part of the question - it tests against an entire disc, all 360 degrees of it, instead of one pie slice with a limited angle. May 3, 2023 at 13:25
• link you may find solution in this May 3, 2023 at 13:49
• This handles drawing an arc, not performing collision/overlap tests on it. May 3, 2023 at 13:51