diff --git a/rustworkx-core/src/planar/lr_planar.rs b/rustworkx-core/src/planar/lr_planar.rs index cdd1b546ab..a76c0afc8d 100644 --- a/rustworkx-core/src/planar/lr_planar.rs +++ b/rustworkx-core/src/planar/lr_planar.rs @@ -704,7 +704,7 @@ where /// # Example: /// ```rust /// use rustworkx_core::petgraph::graph::UnGraph; -/// use rustworkx_core::planar::{is_planar, LRState}; +/// use rustworkx_core::planar::{is_planar_for_layout, LRState}; /// /// let grid = UnGraph::<(), ()>::from_edges(&[ /// // row edges @@ -713,9 +713,9 @@ where /// (0, 3), (3, 6), (1, 4), (4, 7), (2, 5), (5, 8), /// ]); /// let mut lr_state = LRState::new(&grid); -/// assert!(is_planar(&grid, Some(&mut lr_state))) +/// assert!(is_planar_for_layout(&grid, Some(&mut lr_state))) /// ``` -pub fn is_planar(graph: G, state: Option<&mut LRState>) -> bool +pub fn is_planar_for_layout(graph: G, state: Option<&mut LRState>) -> bool where G: GraphProp + NodeCount @@ -753,3 +753,40 @@ where true } + +/// Check if an undirected graph is planar. +/// +/// A graph is planar iff it can be drawn in a plane without any edge +/// intersections. +/// +/// The planarity check algorithm is based on the +/// Left-Right Planarity Test: +/// +/// [`Ulrik Brandes: The Left-Right Planarity Test (2009)`](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.217.9208) +/// +/// # Example: +/// ```rust +/// use rustworkx_core::petgraph::graph::UnGraph; +/// use rustworkx_core::planar::is_planar; +/// +/// let grid = UnGraph::<(), ()>::from_edges(&[ +/// // row edges +/// (0, 1), (1, 2), (3, 4), (4, 5), (6, 7), (7, 8), +/// // col edges +/// (0, 3), (3, 6), (1, 4), (4, 7), (2, 5), (5, 8), +/// ]); +/// assert!(is_planar(&grid)) +/// ``` +pub fn is_planar(graph: G) -> bool +where + G: GraphProp + + NodeCount + + EdgeCount + + IntoEdges + + IntoNodeIdentifiers + + NodeIndexable + + Visitable, + G::NodeId: Hash + Eq + Ord, +{ + is_planar_for_layout(graph, None) +} diff --git a/rustworkx-core/src/planar/mod.rs b/rustworkx-core/src/planar/mod.rs index d6fe1f4e69..a7e5ca0209 100644 --- a/rustworkx-core/src/planar/mod.rs +++ b/rustworkx-core/src/planar/mod.rs @@ -14,4 +14,4 @@ pub mod lr_planar; -pub use lr_planar::{is_planar, LRState}; +pub use lr_planar::{is_planar, is_planar_for_layout, LRState}; diff --git a/rustworkx-core/tests/test_planar.rs b/rustworkx-core/tests/test_planar.rs index fd1cd672ee..8a4fa97b7f 100644 --- a/rustworkx-core/tests/test_planar.rs +++ b/rustworkx-core/tests/test_planar.rs @@ -13,7 +13,7 @@ //! Test module for planar graphs. use rustworkx_core::petgraph::graph::UnGraph; -use rustworkx_core::planar::{is_planar, LRState}; +use rustworkx_core::planar::{is_planar_for_layout, LRState}; #[test] fn test_simple_planar_graph() { @@ -31,7 +31,7 @@ fn test_simple_planar_graph() { (5, 7), ]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert!(res) } @@ -54,7 +54,7 @@ fn test_planar_grid_3_3_graph() { (5, 8), ]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert!(res) } @@ -76,7 +76,7 @@ fn test_planar_with_self_loop() { (4, 5), ]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert!(res) } @@ -113,7 +113,7 @@ fn test_goldner_harary_planar_graph() { (10, 11), ]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert!(res) } @@ -121,7 +121,7 @@ fn test_goldner_harary_planar_graph() { fn test_multiple_components_planar_graph() { let graph = UnGraph::<(), ()>::from_edges(&[(1, 2), (2, 3), (3, 1), (4, 5), (5, 6), (6, 4)]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert!(res) } @@ -129,7 +129,7 @@ fn test_multiple_components_planar_graph() { fn test_planar_multi_graph() { let graph = UnGraph::<(), ()>::from_edges(&[(0, 1), (0, 1), (0, 1), (1, 2), (2, 0)]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert!(res) } @@ -147,7 +147,7 @@ fn test_k3_3_non_planar() { (2, 5), ]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert_eq!(res, false) } @@ -166,7 +166,7 @@ fn test_k5_non_planar() { (3, 4), ]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert_eq!(res, false) } @@ -188,7 +188,7 @@ fn test_multiple_components_non_planar() { (8, 6), ]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert_eq!(res, false) } @@ -208,7 +208,7 @@ fn test_non_planar() { (4, 7), ]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert_eq!(res, false) } @@ -227,7 +227,7 @@ fn test_planar_graph1() { (1, 7), ]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert!(res) } @@ -253,7 +253,7 @@ fn test_non_planar_graph2() { (2, 8), ]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert_eq!(res, false) } @@ -276,6 +276,6 @@ fn test_non_planar_graph3() { (5, 13), ]); let mut lr_state = LRState::new(&graph); - let res = is_planar(&graph, Some(&mut lr_state)); + let res = is_planar_for_layout(&graph, Some(&mut lr_state)); assert_eq!(res, false) } diff --git a/src/layout/planar.rs b/src/layout/planar.rs index bac91ba3db..457136e04e 100644 --- a/src/layout/planar.rs +++ b/src/layout/planar.rs @@ -20,7 +20,7 @@ use crate::iterators::Pos2DMapping; use crate::layout::embedding::{create_embedding, embedding_to_pos, PlanarEmbedding}; use crate::StablePyGraph; use rustworkx_core::dictmap::*; -use rustworkx_core::planar::{is_planar, LRState}; +use rustworkx_core::planar::{is_planar_for_layout, LRState}; /// If a graph is planar, create a set of position coordinates for a planar /// layout that can be passed to a drawer. @@ -38,7 +38,7 @@ pub fn planar_layout( // First determine if the graph is planar. let mut lr_state = LRState::new(graph); - if !is_planar(graph, Some(&mut lr_state)) { + if !is_planar_for_layout(graph, Some(&mut lr_state)) { Err(GraphNotPlanar::new_err("The input graph is not planar.")) // If planar, create the position coordinates.