Skip to content

Commit

Permalink
Fixed #705: Circles and Rectangles agree on overlap
Browse files Browse the repository at this point in the history
  • Loading branch information
davesmith00000 committed Apr 13, 2024
1 parent 6f0e0e8 commit af0a068
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ final case class Circle(position: Point, radius: Int) derives CanEqual:

def encompasses(other: Circle): Boolean =
Circle.encompassing(this, other)
def encompasses(other: Rectangle): Boolean =
Circle.encompassing(this, other)

def overlaps(other: Circle): Boolean =
Circle.overlapping(this, other)
Expand Down Expand Up @@ -142,6 +144,8 @@ object Circle:

def encompassing(a: Circle, b: Circle): Boolean =
a.position.distanceTo(b.position) <= Math.abs(a.radius) - Math.abs(b.radius)
def encompassing(a: Circle, b: Rectangle): Boolean =
b.corners.forall(a.contains)

def overlapping(a: Circle, b: Circle): Boolean =
a.toBoundingCircle.overlaps(b.toIncircleBoundingBox)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ final case class Rectangle(position: Point, size: Size) derives CanEqual:

def encompasses(other: Rectangle): Boolean =
Rectangle.encompassing(this, other)
def encompasses(other: Circle): Boolean =
Rectangle.encompassing(this, other)

def overlaps(other: Rectangle): Boolean =
Rectangle.overlapping(this, other)
Expand Down Expand Up @@ -253,6 +255,8 @@ object Rectangle:

def encompassing(a: Rectangle, b: Rectangle): Boolean =
b.x >= a.x && b.y >= a.y && (b.width + (b.x - a.x)) <= a.width && (b.height + (b.y - a.y)) <= a.height
def encompassing(a: Rectangle, b: Circle): Boolean =
encompassing(a, b.toIncircleRectangle)

def overlapping(a: Rectangle, b: Rectangle): Boolean =
a.toBoundingBox.overlaps(b.toBoundingBox)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ final case class BoundingBox(position: Vertex, size: Vertex) derives CanEqual:

def encompasses(other: BoundingBox): Boolean =
BoundingBox.encompassing(this, other)
def encompasses(other: BoundingCircle): Boolean =
BoundingBox.encompassing(this, other)

def overlaps(other: BoundingBox): Boolean =
BoundingBox.overlapping(this, other)
Expand Down Expand Up @@ -287,6 +289,8 @@ object BoundingBox:

def encompassing(a: BoundingBox, b: BoundingBox): Boolean =
b.x >= a.x && b.y >= a.y && (b.width + (b.x - a.x)) <= a.width && (b.height + (b.y - a.y)) <= a.height
def encompassing(a: BoundingBox, b: BoundingCircle): Boolean =
encompassing(a, b.toIncircleBoundingBox)

def overlapping(a: BoundingBox, b: BoundingBox): Boolean =
Math.abs(a.center.x - b.center.x) < a.halfSize.x + b.halfSize.x &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ final case class BoundingCircle(position: Vertex, radius: Double) derives CanEqu

def encompasses(other: BoundingCircle): Boolean =
BoundingCircle.encompassing(this, other)
def encompasses(other: BoundingBox): Boolean =
BoundingCircle.encompassing(this, other)

def overlaps(other: BoundingCircle): Boolean =
BoundingCircle.overlapping(this, other)
Expand Down Expand Up @@ -214,12 +216,14 @@ object BoundingCircle:

def encompassing(a: BoundingCircle, b: BoundingCircle): Boolean =
a.position.distanceTo(b.position) <= Math.abs(a.radius) - Math.abs(b.radius)
def encompassing(a: BoundingCircle, b: BoundingBox): Boolean =
b.corners.forall(a.contains)

def overlapping(a: BoundingCircle, b: BoundingCircle): Boolean =
a.position.distanceTo(b.position) < Math.abs(a.radius) + Math.abs(b.radius)

def overlapping(a: BoundingCircle, b: BoundingBox): Boolean =
Math.abs(b.sdf(a.position)) <= Math.abs(a.radius)
b.contains(a.position) || Math.abs(b.sdf(a.position)) <= Math.abs(a.radius)

def lineIntersects(boundingCircle: BoundingCircle, line: LineSegment): Boolean =
Math.abs(line.sdf(boundingCircle.position)) <= boundingCircle.radius
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ class CircleTests extends munit.FunSuite {
assert(!c1.encompasses(c2))
}

test("encompasses rectangle") {
assert(Rectangle(0, 0, 160, 160).encompasses(Circle(Point(100, 100), 5)))
assert(!Circle(Point(100, 100), 5).encompasses(Rectangle(100, 100, 5, 5)))

assert(!Rectangle(100, 100, 5, 5).encompasses(Circle(Point(90, 90), 20)))
assert(Circle(Point(100, 100), 20).encompasses(Rectangle(100, 100, 5, 5)))
}

test("overlaps") {
val c1 = Circle(Point(20, 20), 10)
val c2 = Circle(Point(25, 25), 10)
Expand All @@ -38,6 +46,14 @@ class CircleTests extends munit.FunSuite {
assert(!(c1 overlaps c3))
}

test("overlaps rectangle (encompasses)") {
assert(Rectangle(0, 0, 160, 160).overlaps(Circle(Point(100, 100), 5)))
assert(Circle(Point(100, 100), 5).overlaps(Rectangle(0, 0, 160, 160)))

assert(Rectangle(100, 100, 5, 5).overlaps(Circle(Point(90, 90), 20)))
assert(Circle(Point(90, 90), 20).overlaps(Rectangle(100, 100, 5, 5)))
}

test("moveBy | moveTo") {
val c = Circle(Point(20, 20), 10)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,22 @@ class RectangleTests extends munit.FunSuite {
assert(Rectangle.overlapping(a, b))
}

test("overlaps circle (encompasses)") {
assert(Rectangle(0, 0, 160, 160).overlaps(Circle(Point(100, 100), 5)))
assert(Circle(Point(100, 100), 5).overlaps(Rectangle(0, 0, 160, 160)))

assert(Rectangle(100, 100, 5, 5).overlaps(Circle(Point(90, 90), 20)))
assert(Circle(Point(90, 90), 20).overlaps(Rectangle(100, 100, 5, 5)))
}

test("encompasses circle") {
assert(Rectangle(0, 0, 160, 160).encompasses(Circle(Point(100, 100), 5)))
assert(!Circle(Point(100, 100), 5).encompasses(Rectangle(100, 100, 5, 5)))

assert(!Rectangle(100, 100, 5, 5).encompasses(Circle(Point(90, 90), 20)))
assert(Circle(Point(100, 100), 20).encompasses(Rectangle(100, 100, 5, 5)))
}

test("Expand should be able to expand in size by a given amount") {
val a = Rectangle(10, 10, 20, 20)
val b = Rectangle(0, 10, 100, 5)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,22 @@ class BoundingBoxTests extends munit.FunSuite {
assert(b.overlaps(c) == false)
}

test("overlaps BoundingCircle (encompasses)") {
assert(BoundingBox(0, 0, 160, 160).overlaps(BoundingCircle(Vertex(100, 100), 5)))
assert(BoundingCircle(Vertex(100, 100), 5).overlaps(BoundingBox(0, 0, 160, 160)))

assert(BoundingBox(100, 100, 5, 5).overlaps(BoundingCircle(Vertex(90, 90), 20)))
assert(BoundingCircle(Vertex(90, 90), 20).overlaps(BoundingBox(100, 100, 5, 5)))
}

test("encompasses BoundingCircle") {
assert(BoundingBox(0, 0, 160, 160).encompasses(BoundingCircle(Vertex(100, 100), 5)))
assert(!BoundingCircle(Vertex(100, 100), 5).encompasses(BoundingBox(100, 100, 5, 5)))

assert(!BoundingBox(100, 100, 5, 5).encompasses(BoundingCircle(Vertex(90, 90), 20)))
assert(BoundingCircle(Vertex(100, 100), 20).encompasses(BoundingBox(100, 100, 5, 5)))
}

test("overlaps LineSegment") {
val b = BoundingBox(Vertex(0, 0), Vertex(500))
val l = LineSegment((-1.0, -1.0), (10.0, 10.0))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ class BoundingCircleTests extends munit.FunSuite {
assert(c.overlaps(l))
}

test("overlaps BoundingBox (encompasses both ways)") {
assert(BoundingBox(0, 0, 160, 160).overlaps(BoundingCircle(Vertex(100, 100), 5)))
assert(BoundingCircle(Vertex(100, 100), 5).overlaps(BoundingBox(0, 0, 160, 160)))

assert(BoundingBox(100, 100, 5, 5).overlaps(BoundingCircle(Vertex(90, 90), 20)))
assert(BoundingCircle(Vertex(90, 90), 20).overlaps(BoundingBox(100, 100, 5, 5)))
}

test("moveBy | moveTo") {
val c = BoundingCircle(Vertex(20, 20), 10)

Expand Down

0 comments on commit af0a068

Please sign in to comment.