Skip to content

Commit

Permalink
[orx-quadtree] add quadtree module (#174)
Browse files Browse the repository at this point in the history
  • Loading branch information
ricardomatias authored Feb 26, 2021
1 parent 8d6b82a commit 5b0a6f3
Show file tree
Hide file tree
Showing 7 changed files with 395 additions and 1 deletion.
22 changes: 22 additions & 0 deletions orx-quadtree/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# orx-quadtree

An extension for creating a [Quadtree](https://en.wikipedia.org/wiki/Quadtree) for points. A quadtree is a spatial
partioning tree structure meant to provide fast spatial queries such as nearest points within a range.

## Example

```kotlin
val box = Rectangle.fromCenter(Vector2(400.0), 750.0)

val quadTree = Quadtree<Vector2>(box) { it }

for (point in points) {
quadTree.insert(point)
}

val nearestQuery = quadTree.nearest(points[4], 20.0)
```

### Author

Ricardo Matias / [@ricardomatias](https://github.com/ricardomatias)
19 changes: 19 additions & 0 deletions orx-quadtree/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
sourceSets {
demo {
java {
srcDirs = ["src/demo/kotlin"]
compileClasspath += main.getCompileClasspath()
runtimeClasspath += main.getRuntimeClasspath()
}
}
}

dependencies {
demoImplementation("org.openrndr:openrndr-core:$openrndrVersion")
demoImplementation("org.openrndr:openrndr-extensions:$openrndrVersion")
demoImplementation(project(":orx-noise"))
demoRuntimeOnly("org.openrndr:openrndr-gl3:$openrndrVersion")
demoRuntimeOnly("org.openrndr:openrndr-gl3-natives-$openrndrOS:$openrndrVersion")

demoImplementation(sourceSets.getByName("main").output)
}
55 changes: 55 additions & 0 deletions orx-quadtree/src/demo/kotlin/DemoQuadTree01.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.rectangleBatch
import org.openrndr.extensions.SingleScreenshot
import org.openrndr.extra.noise.Random
import org.openrndr.extra.noise.gaussian
import org.openrndr.math.Vector2
import org.openrndr.shape.Rectangle
import quadtree.Quadtree

fun main() {
application {
configure {
width = 800
height = 800
title = "QuadTree"
}
program {
if (System.getProperty("takeScreenshot") == "true") {
extend(SingleScreenshot()) {
this.outputFile = System.getProperty("screenshotPath")
}
}

val box = Rectangle.fromCenter(Vector2(400.0), 750.0)

val points = (0 until 1_000).map {
Vector2.gaussian(box.center, Vector2(95.0), Random.rnd)
}

val quadTree = Quadtree<Vector2>(box) { it }

for (point in points) {
quadTree.insert(point)
}

val batch = drawer.rectangleBatch {
this.fill = null
this.stroke = ColorRGBa.GRAY
this.strokeWeight = 0.5
quadTree.batch(this)
}

extend {
drawer.clear(ColorRGBa.BLACK)

drawer.rectangles(batch)

drawer.fill = ColorRGBa.PINK.opacify(0.7)
drawer.stroke = null
drawer.circles(points, 5.0)
}
}
}
}
82 changes: 82 additions & 0 deletions orx-quadtree/src/demo/kotlin/DemoQuadTree02.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.rectangleBatch
import org.openrndr.extensions.SingleScreenshot
import org.openrndr.extra.noise.Random
import org.openrndr.extra.noise.gaussian
import org.openrndr.math.Vector2
import org.openrndr.shape.Rectangle
import quadtree.Quadtree

fun main() {
application {
configure {
width = 800
height = 800
title = "QuadTree"
}
program {
if (System.getProperty("takeScreenshot") == "true") {
extend(SingleScreenshot()) {
this.outputFile = System.getProperty("screenshotPath")
}
}

val box = Rectangle.fromCenter(Vector2(400.0), 750.0)

val points = (0 until 100).map {
Vector2.gaussian(box.center, Vector2(95.0), Random.rnd)
}

val quadTree = Quadtree<Vector2>(box) { it }

for (point in points) {
quadTree.insert(point)
}

val selected = points[3]
val radius = 40.0

val nearestQuery = quadTree.nearest(selected, radius)

val batch = drawer.rectangleBatch {
this.fill = null
this.stroke = ColorRGBa.GRAY
this.strokeWeight = 0.5
quadTree.batch(this)
}

extend {
drawer.clear(ColorRGBa.BLACK)

drawer.rectangles(batch)

drawer.fill = ColorRGBa.PINK.opacify(0.7)
drawer.stroke = null
drawer.circles(points, 5.0)

nearestQuery?.let { (nearest, neighbours, nodes) ->
drawer.stroke = null
drawer.fill = ColorRGBa.YELLOW.opacify(0.2)

for (node in nodes) {
node.draw(drawer)
}

drawer.fill = ColorRGBa.GREEN.opacify(0.7)
drawer.circles(neighbours, 5.0)

drawer.fill = ColorRGBa.RED.opacify(0.9)
drawer.circle(nearest, 5.0)

drawer.fill = ColorRGBa.PINK
drawer.circle(selected, 5.0)

drawer.stroke = ColorRGBa.PINK
drawer.fill = null
drawer.circle(selected, radius)
}
}
}
}
}
Loading

0 comments on commit 5b0a6f3

Please sign in to comment.