use super::find_cycles::*;
use togo::prelude::*;
#[cfg(test)]
mod basic_tangent_tests {
use super::*;
#[test]
fn test_simple_arc_tangent_calculation() {
let start_point = point(5.0, 0.0);
let end_point = point(0.0, 5.0);
let center = point(0.0, 0.0);
let arc_segment = arc(start_point, end_point, center, 5.0);
let tangents = arc_segment.tangents();
println!("Start tangent: ({}, {})", tangents[0].x, tangents[0].y);
println!("End tangent: ({}, {})", tangents[1].x, tangents[1].y);
let start_mag = (tangents[0].x * tangents[0].x + tangents[0].y * tangents[0].y).sqrt();
let end_mag = (tangents[1].x * tangents[1].x + tangents[1].y * tangents[1].y).sqrt();
assert!((start_mag - 1.0).abs() < 0.1, "Start tangent should be approximately normalized");
assert!((end_mag - 1.0).abs() < 0.1, "End tangent should be approximately normalized");
assert!(tangents[0].x.abs() + tangents[0].y.abs() > 0.5, "Start tangent should be non-zero");
assert!(tangents[1].x.abs() + tangents[1].y.abs() > 0.5, "End tangent should be non-zero");
}
#[test]
fn test_arc_vs_line_segment_cycle() {
let arcs = vec![
arc(point(5.0, 0.0), point(0.0, 5.0), point(0.0, 0.0), 5.0),
arcseg(point(0.0, 5.0), point(-5.0, 0.0)),
arcseg(point(-5.0, 0.0), point(0.0, -5.0)),
arcseg(point(0.0, -5.0), point(5.0, 0.0)),
];
let cycles = find_non_intersecting_cycles(&arcs);
assert!(!cycles.is_empty(), "Should find cycle with mixed arc types");
for cycle in &cycles {
assert!(cycle.len() >= 3, "Each cycle should have at least 3 arcs");
}
}
#[test]
fn test_semicircle_cycle() {
let arcs = vec![
arc(point(-3.0, 0.0), point(3.0, 0.0), point(0.0, 0.0), 3.0),
arc(point(3.0, 0.0), point(-3.0, 0.0), point(0.0, 0.0), 3.0),
];
let cycles = find_non_intersecting_cycles(&arcs);
if !cycles.is_empty() {
assert!(cycles[0].len() >= 2, "Circle should have at least 2 arcs");
}
}
#[test]
fn test_line_segments_only_still_work() {
let arcs = vec![
arcseg(point(0.0, 0.0), point(1.0, 0.0)),
arcseg(point(1.0, 0.0), point(1.0, 1.0)),
arcseg(point(1.0, 1.0), point(0.0, 1.0)),
arcseg(point(0.0, 1.0), point(0.0, 0.0)),
];
let cycles = find_non_intersecting_cycles(&arcs);
assert_eq!(cycles.len(), 1, "Should find exactly one square cycle");
assert_eq!(cycles[0].len(), 4, "Square should have 4 sides");
}
#[test]
fn test_multiple_arcs_radiating_from_vertex() {
let vertex = point(0.0, 0.0);
let arcs = vec![
arcseg(vertex, point(10.0, 0.0)), arcseg(vertex, point(0.0, 10.0)), arcseg(vertex, point(-10.0, 0.0)), arcseg(vertex, point(0.0, -10.0)), arcseg(point(10.0, 0.0), point(0.0, 10.0)),
arcseg(point(0.0, 10.0), point(-10.0, 0.0)),
arcseg(point(-10.0, 0.0), point(0.0, -10.0)),
arcseg(point(0.0, -10.0), point(10.0, 0.0)),
];
let cycles = find_non_intersecting_cycles(&arcs);
for cycle in &cycles {
assert!(cycle.len() >= 3, "Each cycle should have at least 3 arcs");
}
}
#[test]
fn test_tangent_based_rightmost_selection() {
let vertex = point(0.0, 0.0);
let arcs = vec![
arc(vertex, point(2.0, 2.0), point(2.0, 0.0), 2.0),
arcseg(vertex, point(0.0, 3.0)),
arcseg(point(2.0, 2.0), point(0.0, 3.0)),
];
let cycles = find_non_intersecting_cycles(&arcs);
for cycle in &cycles {
assert!(cycle.len() >= 3, "Each cycle should have at least 3 arcs");
}
}
}
#[cfg(test)]
mod regression_tests {
use super::*;
#[test]
fn test_original_functionality_preserved() {
let arcs = vec![
arcseg(point(0.0, 0.0), point(1.0, 0.0)),
arcseg(point(1.0, 0.0), point(0.5, 1.0)),
arcseg(point(0.5, 1.0), point(0.0, 0.0)),
];
let cycles = find_non_intersecting_cycles(&arcs);
assert_eq!(cycles.len(), 1, "Should find exactly one triangle cycle");
assert_eq!(cycles[0].len(), 3, "Triangle should have 3 sides");
}
#[test]
fn test_premature_edge_marking_fix() {
let arcs = vec![
arcseg(point(0.0, 0.0), point(1.0, 1.0)), arcseg(point(1.0, 1.0), point(2.0, 0.0)), arcseg(point(2.0, 0.0), point(1.0, -1.0)), arcseg(point(1.0, -1.0), point(0.0, 0.0)), ];
let cycles = find_non_intersecting_cycles(&arcs);
assert_eq!(cycles.len(), 1, "Should find exactly one cycle");
assert_eq!(cycles[0].len(), 4, "Cycle should have 4 edges");
}
#[test]
fn test_complex_intersection_still_works() {
let arcs = vec![
arcseg(point(0.0, 0.0), point(1.0, 0.0)),
arcseg(point(1.0, 0.0), point(1.0, 1.0)),
arcseg(point(1.0, 1.0), point(0.0, 1.0)),
arcseg(point(0.0, 1.0), point(0.0, 0.0)),
arcseg(point(1.0, 0.0), point(2.0, 0.0)),
arcseg(point(2.0, 0.0), point(2.0, 1.0)),
arcseg(point(2.0, 1.0), point(1.0, 1.0)),
];
let cycles = find_non_intersecting_cycles(&arcs);
assert!(!cycles.is_empty(), "Should find cycles in figure-8 pattern");
for cycle in &cycles {
assert!(cycle.len() >= 3, "Each cycle should have at least 3 arcs");
}
}
}