Skip to content

Commit

Permalink
QuadTree LineSegment, BoundingCircle, Circle
Browse files Browse the repository at this point in the history
  • Loading branch information
davesmith00000 committed Dec 27, 2023
1 parent db3fa6d commit 92b672e
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package indigoextras.trees

import indigo.shared.collections.Batch
import indigo.shared.datatypes.Circle
import indigo.shared.datatypes.Point
import indigo.shared.datatypes.Rectangle
import indigo.shared.geometry.BoundingBox
import indigo.shared.geometry.BoundingCircle
import indigo.shared.geometry.LineSegment
import indigo.shared.geometry.Vertex

trait SpatialOps[S]:
Expand Down Expand Up @@ -52,3 +55,24 @@ object SpatialOps:
def equals(ref: Rectangle, other: Rectangle): Boolean = ref == other
def distance(ref: Rectangle, vertex: Vertex): Double = ref.toBoundingBox.sdf(vertex)
def surrounds(ref: Rectangle, bounds: BoundingBox): Boolean = ref.toBoundingBox.encompasses(bounds)

given SpatialOps[BoundingCircle] with
def bounds(ref: BoundingCircle): BoundingBox = ref.toIncircleBoundingBox
def intersects(ref: BoundingCircle, bounds: BoundingBox): Boolean = bounds.overlaps(ref)
def equals(ref: BoundingCircle, other: BoundingCircle): Boolean = ref ~== other
def distance(ref: BoundingCircle, vertex: Vertex): Double = ref.sdf(vertex)
def surrounds(ref: BoundingCircle, bounds: BoundingBox): Boolean = ref.toIncircleBoundingBox.encompasses(bounds)

given SpatialOps[Circle] with
def bounds(ref: Circle): BoundingBox = ref.toIncircleBoundingBox
def intersects(ref: Circle, bounds: BoundingBox): Boolean = bounds.overlaps(ref.toBoundingCircle)
def equals(ref: Circle, other: Circle): Boolean = ref == other
def distance(ref: Circle, vertex: Vertex): Double = ref.toBoundingCircle.sdf(vertex)
def surrounds(ref: Circle, bounds: BoundingBox): Boolean = ref.toIncircleBoundingBox.encompasses(bounds)

given SpatialOps[LineSegment] with
def bounds(ref: LineSegment): BoundingBox = ref.toBoundingBox
def intersects(ref: LineSegment, bounds: BoundingBox): Boolean = bounds.lineIntersects(ref)
def equals(ref: LineSegment, other: LineSegment): Boolean = ref ~== other
def distance(ref: LineSegment, vertex: Vertex): Double = ref.sdf(vertex)
def surrounds(ref: LineSegment, bounds: BoundingBox): Boolean = false
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package indigoextras.trees

import indigo.BoundingCircle
import indigo.Circle
import indigo.LineSegment
import indigo.Rectangle
import indigo.shared.collections.Batch
import indigo.shared.datatypes.Point
Expand Down Expand Up @@ -598,15 +601,6 @@ class QuadTreeTests extends munit.FunSuite {
(BoundingBox(0.25, 3.25, 4, 0.5), "c")
)

val expected =
QuadTree.Branch(
BoundingBox(Vertex(0, 0), Vertex(10.001, 10.001)),
QuadTree.Leaf(BoundingBox(Vertex(0, 0), Vertex(5.0005, 5.0005)), BoundingBox(2, 0, 2, 4), "b"),
QuadTree.Leaf(BoundingBox(Vertex(5.0005, 0), Vertex(5.0005, 5.0005)), BoundingBox(0.5, 0.5, 1, 1), "a"),
QuadTree.Empty(BoundingBox(Vertex(0, 5.0005), Vertex(5.0005, 5.0005))),
QuadTree.Leaf(BoundingBox(Vertex(5.0005, 5.0005), Vertex(5.0005, 5.0005)), BoundingBox(0.25, 3.25, 4, 0.5), "c")
)

assertEquals(actual.findClosestTo(Vertex(1, 3)).map(_.value), Option("c"))
assertEquals(actual.searchByLine(Vertex(0, 2), Vertex(1, 0)).map(_.value), Batch("a", "a"))
assertEquals(
Expand All @@ -616,6 +610,27 @@ class QuadTreeTests extends munit.FunSuite {
assertEquals(actual.searchByBoundingBox(BoundingBox(1.5, 2.5, 1, 1)).map(_.value), Batch("b", "c"))
}

test("BoundingCircle example") {

val actual =
QuadTree
.empty[BoundingCircle, String](5, 5)
.insert(
(BoundingCircle(1, 1, 0.5), "a"),
(BoundingCircle(3.5, 2.5, 1.5), "b"),
(BoundingCircle(2, 4, 1), "c")
)

assertEquals(actual.findClosestTo(Vertex(2, 0.5)).map(_.value), Option("a"))
assertEquals(actual.findClosestTo(Vertex(2, 2)).map(_.value), Option("b"))
assertEquals(actual.searchByLine(Vertex(0, 2), Vertex(1, 0)).map(_.value), Batch("a", "a"))
assertEquals(
actual.searchByLine(Vertex(1, 0), Vertex(3.5, 5)).map(_.value),
Batch("b", "c", "b", "c", "b", "c", "a", "b", "a", "a")
)
assertEquals(actual.searchByBoundingBox(BoundingBox(1.5, 2.5, 1, 1)).map(_.value), Batch("b", "c"))
}

test("Rectangle example") {

val actual =
Expand All @@ -627,15 +642,6 @@ class QuadTreeTests extends munit.FunSuite {
(Rectangle(0, 3, 5, 1), "c")
)

val expected =
QuadTree.Branch(
BoundingBox(Vertex(0, 0), Vertex(10.001, 10.001)),
QuadTree.Leaf(BoundingBox(Vertex(0, 0), Vertex(5.0005, 5.0005)), Rectangle(2, 0, 2, 4), "b"),
QuadTree.Leaf(BoundingBox(Vertex(5.0005, 0), Vertex(5.0005, 5.0005)), Rectangle(1, 1, 1, 1), "a"),
QuadTree.Empty(BoundingBox(Vertex(0, 5.0005), Vertex(5.0005, 5.0005))),
QuadTree.Leaf(BoundingBox(Vertex(5.0005, 5.0005), Vertex(5.0005, 5.0005)), Rectangle(0, 3, 5, 1), "c")
)

assertEquals(actual.findClosestTo(Vertex(1, 3)).map(_.value), Option("c"))
assertEquals(actual.searchByLine(Vertex(0, 2), Vertex(1, 0)).map(_.value), Batch("a", "a"))
assertEquals(
Expand All @@ -649,6 +655,48 @@ class QuadTreeTests extends munit.FunSuite {
assertEquals(actual.searchByBoundingBox(BoundingBox(1.5, 2.5, 1, 1)).map(_.value), Batch("b", "c"))
}

test("Circle example") {

val actual =
QuadTree
.empty[Circle, String](5, 5)
.insert(
(Circle(1, 1, 1), "a"),
(Circle(3, 2, 1), "b"),
(Circle(2, 4, 1), "c")
)

assertEquals(actual.findClosestTo(Vertex(2, 0.5)).map(_.value), Option("a"))
assertEquals(actual.findClosestTo(Vertex(2, 2)).map(_.value), Option("b"))
assertEquals(actual.searchByLine(Vertex(0, 2), Vertex(1, 0)).map(_.value), Batch("a", "a"))
assertEquals(
actual.searchByLine(Vertex(1, 0), Vertex(3.5, 5)).map(_.value).distinct,
Batch("c", "b", "a")
)
assertEquals(actual.searchByBoundingBox(BoundingBox(1.5, 2.5, 1, 1)).map(_.value), Batch("b", "c"))
}

test("LineSegment example".only) {

val actual =
QuadTree
.empty[LineSegment, String](5, 5)
.insert(
(LineSegment((0.5, 1.5), (1.5, 0.5)), "a"),
(LineSegment((2.5, 0.5), (3.5, 3.5)), "b"),
(LineSegment((3.5, 1.5), (1.5, 3.5)), "c")
)

assertEquals(actual.findClosestTo(Vertex(2, 0.5)).map(_.value), Option("a"))
assertEquals(actual.findClosestTo(Vertex(2, 2)).map(_.value), Option("b"))
assertEquals(actual.searchByLine(Vertex(0, 2), Vertex(1, 0)).map(_.value), Batch("a", "a"))
assertEquals(
actual.searchByLine(Vertex(1, 0), Vertex(3.5, 5)).map(_.value).distinct,
Batch("c", "b", "a")
)
assertEquals(actual.searchByBoundingBox(BoundingBox(1.5, 2.5, 1, 1)).map(_.value), Batch("b", "c"))
}

}

object SampleTree {
Expand Down

0 comments on commit 92b672e

Please sign in to comment.