@@ -1543,7 +1543,7 @@ impl Diagram {
15431543 return best_points;
15441544 }
15451545
1546- for candidate in generate_axis_detours ( from, to, from_bounds , to_bounds ) {
1546+ for candidate in generate_orthogonal_routes ( from, to, self . direction ) {
15471547 if evaluate_candidate_route (
15481548 self ,
15491549 edge,
@@ -1562,6 +1562,27 @@ impl Diagram {
15621562 }
15631563 }
15641564
1565+ if !found_perfect {
1566+ for candidate in generate_axis_detours ( from, to, from_bounds, to_bounds) {
1567+ if evaluate_candidate_route (
1568+ self ,
1569+ edge,
1570+ edge_id,
1571+ from,
1572+ to,
1573+ node_bounds,
1574+ existing_routes,
1575+ existing_label_bounds,
1576+ candidate,
1577+ & mut best_metric,
1578+ & mut best_points,
1579+ ) {
1580+ found_perfect = true ;
1581+ break ;
1582+ }
1583+ }
1584+ }
1585+
15651586 if found_perfect {
15661587 return best_points;
15671588 }
@@ -2103,6 +2124,105 @@ fn generate_axis_detours(
21032124 candidates
21042125}
21052126
2127+ fn generate_orthogonal_routes ( from : Point , to : Point , direction : Direction ) -> Vec < Vec < Point > > {
2128+ let dx = to. x - from. x ;
2129+ let dy = to. y - from. y ;
2130+
2131+ if dx. abs ( ) < 1e-3_f32 || dy. abs ( ) < 1e-3_f32 {
2132+ return Vec :: new ( ) ;
2133+ }
2134+
2135+ let vertical_stub = compute_orthogonal_stub ( dy) ;
2136+ let horizontal_stub = compute_orthogonal_stub ( dx) ;
2137+
2138+ let mut routes = Vec :: new ( ) ;
2139+
2140+ let vertical_first = build_orthogonal_route ( from, to, dx, dy, vertical_stub, horizontal_stub, true ) ;
2141+ let horizontal_first = build_orthogonal_route ( from, to, dx, dy, vertical_stub, horizontal_stub, false ) ;
2142+
2143+ match direction {
2144+ Direction :: TopDown | Direction :: BottomTop => {
2145+ routes. push ( vertical_first) ;
2146+ routes. push ( horizontal_first) ;
2147+ }
2148+ Direction :: LeftRight | Direction :: RightLeft => {
2149+ routes. push ( horizontal_first) ;
2150+ routes. push ( vertical_first) ;
2151+ }
2152+ }
2153+
2154+ routes
2155+ }
2156+
2157+ fn compute_orthogonal_stub ( delta : f32 ) -> f32 {
2158+ let span = delta. abs ( ) ;
2159+ if span >= EDGE_ORTHO_MIN_STUB * 2.0 {
2160+ EDGE_ORTHO_MIN_STUB
2161+ } else {
2162+ span * 0.5
2163+ }
2164+ }
2165+
2166+ fn build_orthogonal_route (
2167+ from : Point ,
2168+ to : Point ,
2169+ dx : f32 ,
2170+ dy : f32 ,
2171+ vertical_stub : f32 ,
2172+ horizontal_stub : f32 ,
2173+ vertical_first : bool ,
2174+ ) -> Vec < Point > {
2175+ let mut points = Vec :: new ( ) ;
2176+
2177+ if vertical_first {
2178+ let v_sign = if dy >= 0.0 { 1.0 } else { -1.0 } ;
2179+ let h_sign = if dx >= 0.0 { 1.0 } else { -1.0 } ;
2180+
2181+ if vertical_stub > 1e-2_f32 {
2182+ points. push ( Point {
2183+ x : from. x ,
2184+ y : from. y + v_sign * vertical_stub,
2185+ } ) ;
2186+ }
2187+
2188+ points. push ( Point {
2189+ x : from. x ,
2190+ y : to. y ,
2191+ } ) ;
2192+
2193+ if horizontal_stub > 1e-2_f32 {
2194+ points. push ( Point {
2195+ x : to. x - h_sign * horizontal_stub,
2196+ y : to. y ,
2197+ } ) ;
2198+ }
2199+ } else {
2200+ let h_sign = if dx >= 0.0 { 1.0 } else { -1.0 } ;
2201+ let v_sign = if dy >= 0.0 { 1.0 } else { -1.0 } ;
2202+
2203+ if horizontal_stub > 1e-2_f32 {
2204+ points. push ( Point {
2205+ x : from. x + h_sign * horizontal_stub,
2206+ y : from. y ,
2207+ } ) ;
2208+ }
2209+
2210+ points. push ( Point {
2211+ x : to. x ,
2212+ y : from. y ,
2213+ } ) ;
2214+
2215+ if vertical_stub > 1e-2_f32 {
2216+ points. push ( Point {
2217+ x : to. x ,
2218+ y : to. y - v_sign * vertical_stub,
2219+ } ) ;
2220+ }
2221+ }
2222+
2223+ points
2224+ }
2225+
21062226fn format_points ( points : & [ ( f32 , f32 ) ] ) -> String {
21072227 points
21082228 . iter ( )
0 commit comments