@@ -24,21 +24,23 @@ fn dist(a: Point<f64>, b: Point<f64>) -> f64 {
2424///
2525/// <https://github.com/sameer/raster2svg>
2626/// <https://www.mdpi.com/2076-3417/9/19/3985/pdf>
27- pub fn minimize_travel_time ( strokes : Vec < Stroke > ) -> Vec < Stroke > {
27+ pub fn minimize_travel_time ( strokes : Vec < Stroke > , starting_point : [ f64 ; 2 ] ) -> Vec < Stroke > {
2828 if strokes. len ( ) <= 1 {
2929 return strokes;
3030 }
31- let path = nearest_neighbor_greedy ( strokes) ;
32- local_improvement_with_tabu_search ( & path)
31+ let the_starting_point : Point < f64 > = Point :: new ( starting_point[ 0 ] * 96.0 /25.4 , starting_point[ 1 ] * 96.0 /25.4 ) ;
32+
33+ let path = nearest_neighbor_greedy ( strokes, the_starting_point) ;
34+ local_improvement_with_tabu_search ( & path, the_starting_point)
3335}
3436
3537/// Greedy nearest-neighbour ordering with flips.
3638///
3739/// Repeatedly chooses the [Stroke] or [Stroke::reversed] closest to the current point until none remain.
38- fn nearest_neighbor_greedy ( mut remaining : Vec < Stroke > ) -> Vec < Stroke > {
40+ fn nearest_neighbor_greedy ( mut remaining : Vec < Stroke > , the_starting_point : Point < f64 > ) -> Vec < Stroke > {
3941 let mut result = Vec :: with_capacity ( remaining. len ( ) ) ;
4042 // TODO: this assumption may be incorrect? depends on the GCode begin sequence, which this can't account for.
41- let mut pos = Point :: zero ( ) ;
43+ let mut pos : Point < f64 > = the_starting_point ;
4244
4345 while !remaining. is_empty ( ) {
4446 let mut best_idx = 0 ;
@@ -129,9 +131,9 @@ fn reverse_and_flip(strokes: &mut [Stroke]) {
129131/// - TwoOpt and LinkSwap reversals also flip each stroke in the reversed range.
130132/// - Relocate tries both the normal and reversed orientation of the moved stroke.
131133/// - Distances are `f64` Euclidean rather than squared integers.
132- fn local_improvement_with_tabu_search ( path : & [ Stroke ] ) -> Vec < Stroke > {
134+ fn local_improvement_with_tabu_search ( path : & [ Stroke ] , the_starting_point : Point < f64 > ) -> Vec < Stroke > {
133135 let mut best = path. to_owned ( ) ;
134- let mut best_sum: f64 = stroke_distances ( & best) . iter ( ) . sum ( ) ;
136+ let mut best_sum: f64 = stroke_distances ( & best) . iter ( ) . sum :: < f64 > ( ) + dist ( the_starting_point , best [ 0 ] . start_point ( ) ) ;
135137
136138 let mut current = best. clone ( ) ;
137139 let mut current_distances = stroke_distances ( & current) ;
@@ -279,8 +281,8 @@ fn local_improvement_with_tabu_search(path: &[Stroke]) -> Vec<Stroke> {
279281 // 2 = [first_start, last_end]: both
280282 let candidates = [
281283 ( 0usize , dist ( from, last_end) ) ,
282- ( 1usize , dist ( first_start, to) ) ,
283- ( 2usize , dist ( first_start, last_end) ) ,
284+ ( 1usize , dist ( first_start, to) + dist ( the_starting_point , to ) - dist ( the_starting_point , first_start ) ) ,
285+ ( 2usize , dist ( first_start, last_end) + dist ( the_starting_point , last_end ) - dist ( the_starting_point , first_start ) ) ,
284286 ] ;
285287 let ( opt, best_new_dist) = candidates
286288 . into_iter ( )
@@ -319,14 +321,8 @@ fn local_improvement_with_tabu_search(path: &[Stroke]) -> Vec<Stroke> {
319321 }
320322 }
321323
322- let prev_sum = current_sum;
323324 current_distances = stroke_distances ( & current) ;
324- current_sum = current_distances. iter ( ) . sum :: < f64 > ( ) ;
325-
326- debug_assert ! (
327- prev_sum > current_sum - f64 :: EPSILON ,
328- "operator={operator:?} prev={prev_sum} current={current_sum}"
329- ) ;
325+ current_sum = current_distances. iter ( ) . sum :: < f64 > ( ) +dist ( the_starting_point, current[ 0 ] . start_point ( ) ) ;
330326
331327 if current_sum < best_sum {
332328 best = current. clone ( ) ;
0 commit comments