From 78fc841e6a761d2ddb168ee5493e1de6e9b3aab6 Mon Sep 17 00:00:00 2001 From: Arne Keller Date: Sat, 23 Mar 2019 17:25:15 +0100 Subject: [PATCH] Fix heuristic --- src/main.rs | 74 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3bb8668..4fc77ff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -148,6 +148,7 @@ fn main() { let save_prefix = "start_"; save_counter = 0; let mut worlds = BinaryHeap::new(); + let left_tris = vec![left_tris[1], left_tris[11], left_tris[17], left_tris[23], left_tris[28]]; for t in &left_tris { let mut world = World { tris: vec![*t], @@ -169,43 +170,55 @@ fn main() { let w = worlds.pop().unwrap(); //println!("s: {:?}", w); + display::save_world(&format!("{}a_{}.svg", save_prefix, save_counter), &w); + let save_iterations = save_counter == 713; + let mut new = vec![]; for (next_idx, next_tri) in left_tris .iter() .filter(|(idx1, _tri)| w.tris.iter().all(|(idx2, _tri)| idx1 != idx2)) { //println!("trying {:?}", next_idx); - let (_, last_tri) = *w.tris.last().unwrap(); - let last_vertex = - if last_tri.1.y > 0.01 && !(last_tri.2.y > 0.01 && last_tri.2.x > last_tri.1.x) { - last_tri.1 - } else { - last_tri.2 - }; + let (last_idx, last_tri) = *w.tris.last().unwrap(); - let mut free_angle = angle_of(last_tri, last_vertex); - //println!("angle of {:?}: {:?}", last_vertex, free_angle); - if last_vertex.x > 0.0 { - free_angle = 0.5 * PI - free_angle; - } else { - free_angle = 0.5 * PI + free_angle; - } + let vertex1 = last_tri.1; + let vertex2 = last_tri.2; - let next_vertex = if next_tri.1.y < 0.001 && next_tri.1.y > -0.001 { - next_tri.2 - } else if next_tri.2.y < 0.001 && next_tri.2.y > -0.001 { - next_tri.1 - } else if next_tri.1.x < next_tri.2.x { - next_tri.1 + let free_angle = if vertex1.y > 0.001 && vertex2.y < 0.001 { + PI - (vertex1.y / (vertex2.x - vertex1.x).abs()).atan() + } else if vertex2.y > 0.001 && vertex1.y < 0.001 { + PI - (vertex2.y / (vertex2.x - vertex1.x).abs()).atan() } else { - next_tri.2 + let angle1 = 0.5 * PI - vertex1.x.signum() * (vertex1.x.abs() / vertex1.y).atan(); + let angle2 = 0.5 * PI - vertex2.x.signum() * (vertex2.x.abs() / vertex2.y).atan(); + min(angle1, angle2) }; - let next_angle = PI - angle_of(*next_tri, next_vertex); - for angle in 0..=150 { - let angle = (1.0 * angle as f32).to_radians(); - let next_angle = next_angle - angle; - let mut tri = rotate(*next_tri, angle); + let vertex1 = next_tri.1; + let vertex2 = next_tri.2; + + let next_angle = if vertex1.y > 0.001 && vertex2.y > 0.001 { + let angle1 = 0.5 * PI + vertex1.x.signum() * (vertex1.x.abs() / vertex1.y).atan(); + let angle2 = 0.5 * PI + vertex2.x.signum() * (vertex2.x.abs() / vertex2.y).atan(); + min(angle1, angle2) + } else if vertex1.y < 0.001 { + 0.5 * PI + vertex2.x.signum() * (vertex2.x.abs() / vertex2.y).atan() + } else { + 0.5 * PI + vertex1.x.signum() * (vertex1.x.abs() / vertex1.y).atan() + }; + //println!("{:?} -> {:?}: {:?} {:?}", last_idx, next_idx, free_angle.to_degrees(), next_angle.to_degrees()); + let target = next_angle - PI + free_angle; + let as_f32 = |x| x as f32; + let range = if target >= 0.0 { + (0..=(target-0.0001).to_degrees() as usize).map(as_f32).chain(Some(target)) + } else { + (0..=(next_angle-0.0001).to_degrees() as usize).map(as_f32).chain(None) + }; + + for angle in range { + let radians = angle.to_radians(); + let next_angle = next_angle - radians; + let mut tri = rotate(*next_tri, radians); let dx = if last_tri.intersects(&tri) { 0.005 @@ -221,12 +234,12 @@ fn main() { w.tris.push((*next_idx, tri)); w.normalize(); w.calc_width(); - if save_counter < 100 { - display::save_world(&format!("{}{}.svg", save_prefix, save_counter), &w); + if save_iterations { + display::save_world(&format!("{}b_{}.svg", save_prefix, save_counter), &w); } if w.tris.len() == count_tris { if w.width < best.width { - println!("new best: {}", w.width); + println!("[{}] new best: {}", save_counter, w.width); println!("{:?}", w.tris); display::save_world( &format!("{}best_{}.svg", save_prefix, save_counter), @@ -236,6 +249,9 @@ fn main() { } } else { w.width -= (2.0 * PI - free_angle - next_angle) * 0.003 * w.tris.len() as f32; + //if (angle > 50 && angle < 55) || (angle > 88 && angle < 92) { + //println!("{:?} -> {:?}", angle, w.width); + //} new.push(w); } save_counter += 1;