Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ itertools = "0.14.0"
num-traits = "0.2.19"
rand = "0.9.1"
rand_chacha = "0.9.0"
nannou = "0.19.0"
nannou_egui = "0.19.0"

[workspace]
members = [
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,9 @@ assert_eq!(results.len(), 2);
To run the `nannou` app, run `cargo run --bin visualize`.

![](assets/vis.gif)

# Features

There is a feature `nannou` on `quadtree` that provides:
- calling `regions()` on a QuadTree to return all regions stored under all sub-trees, useful for debug/visualisation
- provide Into/From between `quadtree::Region` and `nannou::geom::Rect`
6 changes: 5 additions & 1 deletion quadtree/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ eyre.workspace = true
itertools.workspace = true
num-traits.workspace = true
rand.workspace = true
ordered-float = {version= "5.0.0", features=["serde"]}
ordered-float = { version = "5.0.0", features = ["serde"] }
rand_chacha.workspace = true
serdev = "0.2.0"
nannou = {workspace = true, optional = true}

[features]
nannou = ["dep:nannou"]

[dev-dependencies]
serde_json = "1.0.140"
1 change: 1 addition & 0 deletions quadtree/src/quadtree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ impl<const N: usize, V: Storable<V, N>> QuadTree<N, V> {
}

/// Returns all regions
#[cfg(feature = "nannou")]
pub fn regions(&self) -> Vec<Region<N>> {
let mut regions = vec![self.region.clone()];

Expand Down
29 changes: 29 additions & 0 deletions quadtree/src/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,35 @@ impl<const N: usize> Query<N> for Region<N> {
}
}

#[cfg(feature = "nannou")]
impl From<&Region<2>> for nannou::geom::Rect {
fn from(region: &Region<2>) -> Self {
// Convert the region to a Rect
nannou::geom::Rect::from_corners(
nannou::geom::pt2(
*region.intervals()[0].start() as f32,
*region.intervals()[1].start() as f32,
),
nannou::geom::pt2(
*region.intervals()[0].end() as f32,
*region.intervals()[1].end() as f32,
),
)
}
}

#[cfg(feature = "nannou")]
impl From<nannou::geom::Rect> for Region<2> {
fn from(rect: nannou::geom::Rect) -> Self {
Region::new(&[
Interval::try_new(rect.left() as f64, rect.right() as f64)
.expect("valid Rect produces valid x-axis"),
Interval::try_new(rect.bottom() as f64, rect.top() as f64)
.expect("valid Rect produces valid y-axis"),
])
}
}

/// Demonstrates region containment with correct and incorrect point dimensions.
///
/// This compiles:
Expand Down
6 changes: 3 additions & 3 deletions visualize/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ version = "0.1.0"
edition = "2024"

[dependencies]
quadtree = {path = "../quadtree"}
quadtree = {path = "../quadtree", features=["nannou"]}
rand.workspace = true
eyre.workspace = true
nannou = "0.19.0"
nannou_egui = "0.19.0"
nannou.workspace = true
nannou_egui.workspace = true
27 changes: 4 additions & 23 deletions visualize/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ extern crate nannou;
use std::collections::HashSet;
use std::num::NonZeroUsize;

use eyre::{Context, Result};
use eyre::Result;

use nannou::Draw;
use nannou::geom::Rect;
use nannou_egui::Egui;
use quadtree::QuadTree;
use quadtree::point::Point;
use quadtree::region::Region;
use quadtree::{interval::Interval, point::Point};
use rand::SeedableRng;
use rand::rngs::StdRng;

Expand Down Expand Up @@ -39,12 +39,7 @@ pub struct Model {
impl Model {
pub fn try_new(egui: Egui, rect: Rect) -> Result<Self> {
// Create a region from the Rect
let region = Region::new(&[
Interval::try_new(rect.left() as f64, rect.right() as f64)
.context("converting rect to Interval")?,
Interval::try_new(rect.bottom() as f64, rect.top() as f64)
.context("converting rect to Interval")?,
]);
let region: Region<2> = rect.into();
Ok(Self {
egui,
points: Vec::new(),
Expand Down Expand Up @@ -121,7 +116,7 @@ impl Model {

// Draw the quadtree regions
for region in qt.regions().iter() {
let rect = region_to_rect(region);
let rect: Rect = region.into();
draw.rect()
.xy(rect.xy())
.wh(rect.wh())
Expand All @@ -131,17 +126,3 @@ impl Model {
}
}
}

fn region_to_rect(region: &Region<2>) -> Rect {
// Convert the region to a Rect
Rect::from_corners(
pt2(
*region.intervals()[0].start() as f32,
*region.intervals()[1].start() as f32,
),
pt2(
*region.intervals()[0].end() as f32,
*region.intervals()[1].end() as f32,
),
)
}