Use R*-Tree to speed up polygon intersection checks 5-6x
This commit is contained in:
parent
4e182d3826
commit
6e8a6c1a94
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -5,7 +5,8 @@ name = "aufgabe1"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"geo 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"geo 0.12.0",
|
||||||
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rstar 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rstar 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
"structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"svg 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"svg 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -105,10 +106,9 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "geo"
|
name = "geo"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"geo-types 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"geo-types 0.4.1",
|
||||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rstar 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rstar 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
@ -116,7 +116,6 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "geo-types"
|
name = "geo-types"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rstar 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rstar 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -130,6 +129,11 @@ dependencies = [
|
|||||||
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.51"
|
version = "0.2.51"
|
||||||
@ -388,9 +392,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
||||||
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
||||||
"checksum float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "134a8fa843d80a51a5b77d36d42bc2def9edcb0262c914861d08129fd1926600"
|
"checksum float-cmp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "134a8fa843d80a51a5b77d36d42bc2def9edcb0262c914861d08129fd1926600"
|
||||||
"checksum geo 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8cfb3011a87e562d59a3e3e2e2595a867780ff7ad618fbb2579f03ea038961a2"
|
|
||||||
"checksum geo-types 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "909178c1a808c8d77571b92dc13cf485b827412e2078ded759942bae3563a4d4"
|
|
||||||
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||||
|
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
||||||
"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917"
|
"checksum libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "bedcc7a809076656486ffe045abeeac163da1b558e963a31e29fbfbeba916917"
|
||||||
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
|
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
|
||||||
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
||||||
|
@ -10,9 +10,10 @@ opt-level = 3
|
|||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
geo = "0.12"
|
geo = { path = "/home/arne/Documents/Code/Github/geo/geo" }
|
||||||
svg = "0.5.11"
|
svg = "0.5.11"
|
||||||
chrono = "0.4.6"
|
chrono = "0.4.6"
|
||||||
structopt = { version = "0.2", default-features = false }
|
structopt = { version = "0.2", default-features = false }
|
||||||
svgdom = "0.16.1"
|
svgdom = "0.16.1"
|
||||||
rstar = "0.2.0"
|
rstar = "0.2.0"
|
||||||
|
lazy_static = "1.3.0"
|
||||||
|
25
src/main.rs
25
src/main.rs
@ -1,13 +1,14 @@
|
|||||||
use geo::prelude::*;
|
|
||||||
|
|
||||||
use chrono::{Duration, NaiveTime};
|
use chrono::{Duration, NaiveTime};
|
||||||
|
use geo::prelude::*;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use rstar::{RTree, RTreeObject};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::BinaryHeap;
|
use std::collections::BinaryHeap;
|
||||||
use std::f64;
|
use std::f64;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
use std::sync::RwLock;
|
||||||
|
|
||||||
mod display;
|
mod display;
|
||||||
mod input;
|
mod input;
|
||||||
@ -98,6 +99,10 @@ fn main() {
|
|||||||
let data = input::read_input();
|
let data = input::read_input();
|
||||||
let house = data.start;
|
let house = data.start;
|
||||||
let polys = data.polys;
|
let polys = data.polys;
|
||||||
|
// Polygone in RTree speichern
|
||||||
|
let mut rtree = RTREE.write().unwrap();
|
||||||
|
*rtree = RTree::bulk_load(polys.clone());
|
||||||
|
drop(rtree);
|
||||||
// alle Ecken der Hindernisse bestimmen
|
// alle Ecken der Hindernisse bestimmen
|
||||||
let points = polys
|
let points = polys
|
||||||
.iter()
|
.iter()
|
||||||
@ -152,7 +157,7 @@ fn main() {
|
|||||||
// Ecke sollte nicht schon in Route sein
|
// Ecke sollte nicht schon in Route sein
|
||||||
.filter(|&&next| !state.iter().any(|p| p.pos == next))
|
.filter(|&&next| !state.iter().any(|p| p.pos == next))
|
||||||
// Weg zu dieser Ecke sollte kein Polygon schneiden
|
// Weg zu dieser Ecke sollte kein Polygon schneiden
|
||||||
.filter(|&&next| none_intersect(&polys, &Line::new(last.pos, next)))
|
.filter(|&&next| none_intersect(Line::new(last.pos, next)))
|
||||||
{
|
{
|
||||||
// Lisa könnte zu dieser Ecke rennen
|
// Lisa könnte zu dieser Ecke rennen
|
||||||
let total_distance = last.total_distance + distance(last.pos, next);
|
let total_distance = last.total_distance + distance(last.pos, next);
|
||||||
@ -179,7 +184,7 @@ fn main() {
|
|||||||
);
|
);
|
||||||
let line = Line::new(last.pos, next);
|
let line = Line::new(last.pos, next);
|
||||||
// freier Weg?
|
// freier Weg?
|
||||||
if none_intersect(&polys, &line) {
|
if none_intersect(line) {
|
||||||
let line_length = line.end_point().euclidean_distance(&line.start_point());
|
let line_length = line.end_point().euclidean_distance(&line.start_point());
|
||||||
let total_distance = last.total_distance + line_length;
|
let total_distance = last.total_distance + line_length;
|
||||||
let bus = best_bus_pos(&opt, total_distance, line.end_point());
|
let bus = best_bus_pos(&opt, total_distance, line.end_point());
|
||||||
@ -259,9 +264,15 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lazy_static!{
|
||||||
|
static ref RTREE: RwLock<RTree<Polygon>> = RwLock::new(RTree::new());
|
||||||
|
}
|
||||||
|
|
||||||
/// Schneidet die Linie keines der Polygone?
|
/// Schneidet die Linie keines der Polygone?
|
||||||
/// (Berührungen erlaubt)
|
/// (Berührungen erlaubt)
|
||||||
fn none_intersect(polys: &[Polygon], line: &Line) -> bool {
|
fn none_intersect(line: Line) -> bool {
|
||||||
|
let rtree = RTREE.read().unwrap();
|
||||||
|
let polys = rtree.locate_in_envelope_intersecting(&line.envelope());
|
||||||
let mut middle = line.start;
|
let mut middle = line.start;
|
||||||
middle.x += line.dx() / 2.0;
|
middle.x += line.dx() / 2.0;
|
||||||
middle.y += line.dy() / 2.0;
|
middle.y += line.dy() / 2.0;
|
||||||
@ -285,7 +296,7 @@ fn none_intersect(polys: &[Polygon], line: &Line) -> bool {
|
|||||||
{
|
{
|
||||||
continue; // Linie schneidet sich immer selbst
|
continue; // Linie schneidet sich immer selbst
|
||||||
}
|
}
|
||||||
if l.intersects(line) {
|
if l.intersects(&line) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user