Skip to main content

Crate eikonal

Crate eikonal 

Source
Expand description

eikonal — Fast Marching Method and grid routing utilities.

The crate-level solve APIs solve the eikonal equation |∇T(x)| = C(x) = 1/F(x) on 2D regular grids using a first-order upwind Fast Marching Method. The graph module provides 8-neighbor Dijkstra shortest paths for applications that need exact discrete graph paths, and terrain builds on graph routing for DEM-aware path costs.

§Core concepts

TypePurpose
CostFieldPer-cell cost/slowness (1 / speed)
SolveResultFMM arrival-time field + upwind backtrace
graph::SolveResult8-neighbor Dijkstra graph distances + shortest paths
TerrainResultTerrain-routing result with elevation profiles
TerrainConfigSlope penalty configuration

§Quick start — eikonal / FMM

use ndarray::Array2;
use eikonal::{CostField, solve};

let cost = CostField::uniform(50, 50);
let result = solve(&cost, (0, 0)).unwrap();

// FMM arrival time to far corner
let d = result.distance()[[49, 49]];
assert!(d > 0.0);

// Extract an upwind backtrace through the arrival-time field
let path = result.path_to(49, 49).unwrap();
assert_eq!(path.cells[0], (0, 0));

§Quick start — weighted grid shortest paths

use eikonal::{graph, CostField};

let cost = CostField::uniform(50, 50);
let result = graph::solve(&cost, (0, 0)).unwrap();
let path = result.path_to(49, 49).unwrap();
assert_eq!(path.cells[0], (0, 0));

§Quick start — terrain routing

use ndarray::Array2;
use eikonal::terrain::{self, TerrainConfig};

// A DEM with a hill in the center
let dem = Array2::from_shape_fn((50, 50), |(r, c)| {
    let dr = r as f64 - 25.0;
    let dc = c as f64 - 25.0;
    100.0 * (-(dr * dr + dc * dc) / 200.0).exp()
});

let config = TerrainConfig::hiking(30.0).unwrap(); // 30m cells
let result = terrain::solve(&dem, config, None, (0, 0)).unwrap();
let path = result.path_to(49, 49).unwrap();

assert!(path.surface_distance > path.projected_distance);
assert!(path.total_ascent > 0.0);

§Isochrones

use eikonal::{CostField, solve, isochrone};

let cost = CostField::uniform(30, 30);
let result = solve(&cost, (15, 15)).unwrap();
let reachable = isochrone(result.distance(), 10.0);

§Parallelism

Enable the parallel feature for Rayon-accelerated cost field construction:

[dependencies]
eikonal = { version = "0.1", features = ["parallel"] }

The FMM and graph solvers are inherently sequential priority-queue algorithms. The parallel feature currently accelerates cost field construction; isochrone extraction remains sequential.

Re-exports§

pub use cost::CostField;
pub use error::Error;
pub use error::Result;
pub use graph::solve as solve_graph;
pub use graph::solve_multi as solve_graph_multi;
pub use graph::solve_to as solve_graph_to;
pub use graph::Path as GraphPath;
pub use graph::SolveResult as GraphSolveResult;
pub use isochrone::isochrone;
pub use isochrone::isochrone_boundary;
pub use solver::solve;
pub use solver::solve_multi;
pub use solver::solve_to;
pub use solver::Path;
pub use solver::SolveResult;

Modules§

cost
error
graph
Weighted shortest paths on an 8-connected grid graph.
isochrone
solver
terrain