Format using tabs

This commit is contained in:
Arne Keller 2019-03-29 17:35:03 +01:00
parent 62695b2fbb
commit 142b8c02e6
2 changed files with 375 additions and 374 deletions

1
rustfmt.toml Normal file
View File

@ -0,0 +1 @@
hard_tabs = true

View File

@ -11,416 +11,416 @@ mod input;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct World { struct World {
/// Dreiecksgrundstücke /// Dreiecksgrundstücke
tris: Vec<(usize, Triangle<f32>)>, tris: Vec<(usize, Triangle<f32>)>,
/// Gesamtabstand /// Gesamtabstand
width: f32, width: f32,
} }
impl cmp::PartialEq for World { impl cmp::PartialEq for World {
fn eq(&self, _other: &Self) -> bool { fn eq(&self, _other: &Self) -> bool {
unimplemented!() unimplemented!()
} }
} }
impl cmp::Eq for World {} impl cmp::Eq for World {}
impl cmp::Ord for World { impl cmp::Ord for World {
fn cmp(&self, other: &Self) -> cmp::Ordering { fn cmp(&self, other: &Self) -> cmp::Ordering {
self.width.partial_cmp(&other.width).unwrap().reverse() self.width.partial_cmp(&other.width).unwrap().reverse()
} }
} }
impl cmp::PartialOrd for World { impl cmp::PartialOrd for World {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
Some(self.cmp(other)) Some(self.cmp(other))
} }
} }
fn main() { fn main() {
let tris = input::read_input(); let tris = input::read_input();
let count_tris = tris.len(); let count_tris = tris.len();
let tris = transformations(&tris); let tris = transformations(&tris);
let save_prefix = "tri_"; let save_prefix = "tri_";
let mut save_counter = 0; let mut save_counter = 0;
let mut normalized_tris = Vec::with_capacity(tris.len() * 2); let mut normalized_tris = Vec::with_capacity(tris.len() * 2);
let mut left_tris = Vec::with_capacity(tris.len()); let mut left_tris = Vec::with_capacity(tris.len());
for (mut idx, t) in tris.into_iter().enumerate() { for (mut idx, t) in tris.into_iter().enumerate() {
idx /= 6; idx /= 6;
let prev_angle = angle_of(t, t.1); let prev_angle = angle_of(t, t.1);
let mut added = false; let mut added = false;
let rotated = rotate(t, 0.5 * PI - prev_angle); let rotated = rotate(t, 0.5 * PI - prev_angle);
if rotated.1.y >= -0.001 if rotated.1.y >= -0.001
&& rotated.2.y >= -0.001 && rotated.2.y >= -0.001
&& (rotated.1.y < 0.1 || rotated.2.y < 0.1) && (rotated.1.y < 0.1 || rotated.2.y < 0.1)
{ {
normalized_tris.push((idx, rotated)); normalized_tris.push((idx, rotated));
if rotated.1.x > -0.001 && rotated.2.x > -0.001 { if rotated.1.x > -0.001 && rotated.2.x > -0.001 {
left_tris.push((idx, rotated)); left_tris.push((idx, rotated));
} }
added = true; added = true;
} }
let rotated = rotate(rotated, PI); let rotated = rotate(rotated, PI);
if !added if !added
&& rotated.1.y >= -0.001 && rotated.1.y >= -0.001
&& rotated.2.y >= -0.001 && rotated.2.y >= -0.001
&& (rotated.1.y < 0.1 || rotated.2.y < 0.1) && (rotated.1.y < 0.1 || rotated.2.y < 0.1)
{ {
normalized_tris.push((idx, rotated)); normalized_tris.push((idx, rotated));
if rotated.1.x > -0.001 && rotated.2.x > -0.001 { if rotated.1.x > -0.001 && rotated.2.x > -0.001 {
left_tris.push((idx, rotated)); left_tris.push((idx, rotated));
} }
added = true; added = true;
} }
let rotated = rotate(t, -0.5 * PI + prev_angle); let rotated = rotate(t, -0.5 * PI + prev_angle);
if !added if !added
&& rotated.1.y >= -0.001 && rotated.1.y >= -0.001
&& rotated.2.y >= -0.001 && rotated.2.y >= -0.001
&& (rotated.1.y < 0.1 || rotated.2.y < 0.1) && (rotated.1.y < 0.1 || rotated.2.y < 0.1)
{ {
normalized_tris.push((idx, rotated)); normalized_tris.push((idx, rotated));
if rotated.1.x > -0.001 && rotated.2.x > -0.001 { if rotated.1.x > -0.001 && rotated.2.x > -0.001 {
left_tris.push((idx, rotated)); left_tris.push((idx, rotated));
} }
added = true; added = true;
} }
let rotated = rotate(rotated, PI); let rotated = rotate(rotated, PI);
if !added if !added
&& rotated.1.y >= -0.001 && rotated.1.y >= -0.001
&& rotated.2.y >= -0.001 && rotated.2.y >= -0.001
&& (rotated.1.y < 0.1 || rotated.2.y < 0.1) && (rotated.1.y < 0.1 || rotated.2.y < 0.1)
{ {
normalized_tris.push((idx, rotated)); normalized_tris.push((idx, rotated));
if rotated.1.x > -0.001 && rotated.2.x > -0.001 { if rotated.1.x > -0.001 && rotated.2.x > -0.001 {
left_tris.push((idx, rotated)); left_tris.push((idx, rotated));
} }
} }
let prev_angle = angle_of(t, t.2); let prev_angle = angle_of(t, t.2);
added = false; added = false;
let rotated = rotate(t, 0.5 * PI - prev_angle); let rotated = rotate(t, 0.5 * PI - prev_angle);
if rotated.1.y >= -0.001 if rotated.1.y >= -0.001
&& rotated.2.y >= -0.001 && rotated.2.y >= -0.001
&& (rotated.1.y < 0.1 || rotated.2.y < 0.1) && (rotated.1.y < 0.1 || rotated.2.y < 0.1)
{ {
normalized_tris.push((idx, rotated)); normalized_tris.push((idx, rotated));
if rotated.1.x > -0.001 && rotated.2.x > -0.001 { if rotated.1.x > -0.001 && rotated.2.x > -0.001 {
left_tris.push((idx, rotated)); left_tris.push((idx, rotated));
} }
added = true; added = true;
} }
let rotated = rotate(rotated, PI); let rotated = rotate(rotated, PI);
if !added if !added
&& rotated.1.y >= -0.001 && rotated.1.y >= -0.001
&& rotated.2.y >= -0.001 && rotated.2.y >= -0.001
&& (rotated.1.y < 0.1 || rotated.2.y < 0.1) && (rotated.1.y < 0.1 || rotated.2.y < 0.1)
{ {
normalized_tris.push((idx, rotated)); normalized_tris.push((idx, rotated));
if rotated.1.x > -0.001 && rotated.2.x > -0.001 { if rotated.1.x > -0.001 && rotated.2.x > -0.001 {
left_tris.push((idx, rotated)); left_tris.push((idx, rotated));
} }
added = true; added = true;
} }
let rotated = rotate(t, -0.5 * PI + prev_angle); let rotated = rotate(t, -0.5 * PI + prev_angle);
if !added if !added
&& rotated.1.y >= -0.001 && rotated.1.y >= -0.001
&& rotated.2.y >= -0.001 && rotated.2.y >= -0.001
&& (rotated.1.y < 0.1 || rotated.2.y < 0.1) && (rotated.1.y < 0.1 || rotated.2.y < 0.1)
{ {
normalized_tris.push((idx, rotated)); normalized_tris.push((idx, rotated));
if rotated.1.x > -0.001 && rotated.2.x > -0.001 { if rotated.1.x > -0.001 && rotated.2.x > -0.001 {
left_tris.push((idx, rotated)); left_tris.push((idx, rotated));
} }
added = true; added = true;
} }
let rotated = rotate(rotated, PI); let rotated = rotate(rotated, PI);
if !added if !added
&& rotated.1.y >= -0.001 && rotated.1.y >= -0.001
&& rotated.2.y >= -0.001 && rotated.2.y >= -0.001
&& (rotated.1.y < 0.1 || rotated.2.y < 0.1) && (rotated.1.y < 0.1 || rotated.2.y < 0.1)
{ {
normalized_tris.push((idx, rotated)); normalized_tris.push((idx, rotated));
if rotated.1.x > -0.001 && rotated.2.x > -0.001 { if rotated.1.x > -0.001 && rotated.2.x > -0.001 {
left_tris.push((idx, rotated)); left_tris.push((idx, rotated));
} }
} }
} }
for (_idx, t) in &normalized_tris { for (_idx, t) in &normalized_tris {
display::save_tri(&format!("{}{}.svg", save_prefix, save_counter), *t); display::save_tri(&format!("{}{}.svg", save_prefix, save_counter), *t);
save_counter += 1; save_counter += 1;
} }
let save_prefix = "start_"; let save_prefix = "start_";
save_counter = 0; save_counter = 0;
let mut worlds = BinaryHeap::new(); let mut worlds = BinaryHeap::new();
//let left_tris = vec![left_tris[1], left_tris[11], left_tris[17], left_tris[22], left_tris[28]]; //let left_tris = vec![left_tris[1], left_tris[11], left_tris[17], left_tris[22], left_tris[28]];
for t in &left_tris { for t in &left_tris {
let mut world = World { let mut world = World {
tris: vec![*t], tris: vec![*t],
width: 0.0, width: 0.0,
}; };
world.normalize(); world.normalize();
display::save_world(&format!("{}{}.svg", save_prefix, save_counter), &world); display::save_world(&format!("{}{}.svg", save_prefix, save_counter), &world);
save_counter += 1; save_counter += 1;
worlds.push(world); worlds.push(world);
} }
let mut best = World { let mut best = World {
tris: vec![], tris: vec![],
width: f32::MAX, width: f32::MAX,
}; };
let save_prefix = "world_"; let save_prefix = "world_";
save_counter = 0; save_counter = 0;
let mut counter = 0; let mut counter = 0;
let mut bins = Vec::new(); let mut bins = Vec::new();
bins.push(worlds); bins.push(worlds);
let mut progress = true; let mut progress = true;
while progress { while progress {
progress = false; progress = false;
for bin_idx in 0..bins.len() { for bin_idx in 0..bins.len() {
counter += 1; counter += 1;
if counter % 10000 == 0 { if counter % 10000 == 0 {
println!("{}/∞", counter); println!("{}/∞", counter);
} }
if bins[bin_idx].is_empty() { if bins[bin_idx].is_empty() {
continue; continue;
} }
let w = bins[bin_idx].pop().unwrap(); let w = bins[bin_idx].pop().unwrap();
//println!("working"); //println!("working");
if w.width >= best.width { if w.width >= best.width {
continue; continue;
} }
//println!("s: {:?}", w); //println!("s: {:?}", w);
/* /*
if save_counter < 1000000 { if save_counter < 1000000 {
display::save_world(&format!("{}a_{}.svg", save_prefix, save_counter), &w); display::save_world(&format!("{}a_{}.svg", save_prefix, save_counter), &w);
} }
*/ */
let save_iterations = false; let save_iterations = false;
let mut new = vec![]; let mut new = vec![];
for (next_idx, next_tri) in left_tris for (next_idx, next_tri) in left_tris
.iter() .iter()
.filter(|(idx1, _tri)| w.tris.iter().all(|(idx2, _tri)| idx1 != idx2)) .filter(|(idx1, _tri)| w.tris.iter().all(|(idx2, _tri)| idx1 != idx2))
{ {
//println!("trying {:?}", next_idx); //println!("trying {:?}", next_idx);
let (last_idx, last_tri) = *w.tris.last().unwrap(); let (last_idx, last_tri) = *w.tris.last().unwrap();
let vertex1 = last_tri.1; let vertex1 = last_tri.1;
let vertex2 = last_tri.2; let vertex2 = last_tri.2;
let free_angle = if vertex1.y > 0.001 && vertex2.y < 0.001 { let free_angle = if vertex1.y > 0.001 && vertex2.y < 0.001 {
PI - (vertex1.y / (vertex2.x - vertex1.x).abs()).atan() PI - (vertex1.y / (vertex2.x - vertex1.x).abs()).atan()
} else if vertex2.y > 0.001 && vertex1.y < 0.001 { } else if vertex2.y > 0.001 && vertex1.y < 0.001 {
PI - (vertex2.y / (vertex2.x - vertex1.x).abs()).atan() PI - (vertex2.y / (vertex2.x - vertex1.x).abs()).atan()
} else { } else {
let angle1 = let angle1 =
0.5 * PI - vertex1.x.signum() * (vertex1.x.abs() / vertex1.y).atan(); 0.5 * PI - vertex1.x.signum() * (vertex1.x.abs() / vertex1.y).atan();
let angle2 = let angle2 =
0.5 * PI - vertex2.x.signum() * (vertex2.x.abs() / vertex2.y).atan(); 0.5 * PI - vertex2.x.signum() * (vertex2.x.abs() / vertex2.y).atan();
min(angle1, angle2) min(angle1, angle2)
}; };
let vertex1 = next_tri.1; let vertex1 = next_tri.1;
let vertex2 = next_tri.2; let vertex2 = next_tri.2;
let next_angle = if vertex1.y > 0.001 && vertex2.y > 0.001 { let next_angle = if vertex1.y > 0.001 && vertex2.y > 0.001 {
let angle1 = let angle1 =
0.5 * PI + vertex1.x.signum() * (vertex1.x.abs() / vertex1.y).atan(); 0.5 * PI + vertex1.x.signum() * (vertex1.x.abs() / vertex1.y).atan();
let angle2 = let angle2 =
0.5 * PI + vertex2.x.signum() * (vertex2.x.abs() / vertex2.y).atan(); 0.5 * PI + vertex2.x.signum() * (vertex2.x.abs() / vertex2.y).atan();
min(angle1, angle2) min(angle1, angle2)
} else if vertex1.y < 0.001 { } else if vertex1.y < 0.001 {
0.5 * PI + vertex2.x.signum() * (vertex2.x.abs() / vertex2.y).atan() 0.5 * PI + vertex2.x.signum() * (vertex2.x.abs() / vertex2.y).atan()
} else { } else {
0.5 * PI + vertex1.x.signum() * (vertex1.x.abs() / vertex1.y).atan() 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()); //println!("{:?} -> {:?}: {:?} {:?}", last_idx, next_idx, free_angle.to_degrees(), next_angle.to_degrees());
let target = (next_angle - PI + free_angle).to_degrees(); let target = (next_angle - PI + free_angle).to_degrees();
let step = 40.0; let step = 40.0;
let as_f32 = |x| x as f32 * step; let as_f32 = |x| x as f32 * step;
let range = if target >= 0.0 { let range = if target >= 0.0 {
(0..=((target - 0.0001) / step) as usize) (0..=((target - 0.0001) / step) as usize)
.map(as_f32) .map(as_f32)
.chain(Some(target)) .chain(Some(target))
} else { } else {
(0..=((next_angle - 0.0001) / step) as usize) (0..=((next_angle - 0.0001) / step) as usize)
.map(as_f32) .map(as_f32)
.chain(None) .chain(None)
}; };
for angle in range { for angle in range {
//println!("angle {:?}", angle); //println!("angle {:?}", angle);
let radians = angle.to_radians(); let radians = angle.to_radians();
let next_angle = next_angle - radians; let next_angle = next_angle - radians;
let mut tri = rotate(*next_tri, radians); let mut tri = rotate(*next_tri, radians);
// "binary search"-like optimization here // "binary search"-like optimization here
for &delta in &[ for &delta in &[
/*80.0, 30.0, 10.0, 5.0,*/ 1.0, 0.6, 0.32, 0.18, 0.1, 0.06, 0.03, /*80.0, 30.0, 10.0, 5.0,*/ 1.0, 0.6, 0.32, 0.18, 0.1, 0.06, 0.03,
0.01, 0.003, 0.01, 0.003,
] { ] {
let initial_state = last_tri.intersects(&tri); let initial_state = last_tri.intersects(&tri);
let dx = if initial_state { delta } else { -delta }; let dx = if initial_state { delta } else { -delta };
while last_tri.intersects(&tri) == initial_state { while last_tri.intersects(&tri) == initial_state {
tri.0.x += dx; tri.0.x += dx;
tri.1.x += dx; tri.1.x += dx;
tri.2.x += dx; tri.2.x += dx;
} }
} }
let mut w = w.clone(); let mut w = w.clone();
w.tris.push((*next_idx, tri)); w.tris.push((*next_idx, tri));
w.normalize(); w.normalize();
w.calc_width(); w.calc_width();
if save_iterations { if save_iterations {
display::save_world(&format!("{}b_{}.svg", save_prefix, save_counter), &w); display::save_world(&format!("{}b_{}.svg", save_prefix, save_counter), &w);
} }
if w.tris.len() == count_tris { if w.tris.len() == count_tris {
if w.width < best.width { if w.width < best.width {
println!("[{}] new best: {}", save_counter, w.width); println!("[{}] new best: {}", save_counter, w.width);
//println!("{:?}", w.tris); //println!("{:?}", w.tris);
display::save_world( display::save_world(
&format!("{}best_{}.svg", save_prefix, save_counter), &format!("{}best_{}.svg", save_prefix, save_counter),
&w, &w,
); );
best = w; best = w;
} }
} else if w.width < best.width { } else if w.width < best.width {
w.width -= (2.0 * PI - free_angle - next_angle) * 0.01; w.width -= (2.0 * PI - free_angle - next_angle) * 0.01;
//if (angle > 50 && angle < 55) || (angle > 88 && angle < 92) { //if (angle > 50 && angle < 55) || (angle > 88 && angle < 92) {
//println!("{:?} -> {:?}", angle, w.width); //println!("{:?} -> {:?}", angle, w.width);
//} //}
new.push(w); new.push(w);
} }
save_counter += 1; save_counter += 1;
} }
} }
progress = true; progress = true;
if bin_idx + 1 == bins.len() { if bin_idx + 1 == bins.len() {
let mut new_bin = BinaryHeap::new(); let mut new_bin = BinaryHeap::new();
new_bin.extend(new); new_bin.extend(new);
bins.push(new_bin); bins.push(new_bin);
} else { } else {
bins[bin_idx + 1].extend(new); bins[bin_idx + 1].extend(new);
} }
} }
} }
println!("best width = {:?}", best.width); println!("best width = {:?}", best.width);
display::save_world("world_best.svg", &best); display::save_world("world_best.svg", &best);
} }
impl World { impl World {
fn normalize(&mut self) { fn normalize(&mut self) {
let mut maxx = 0.0; let mut maxx = 0.0;
for (_, tri) in &self.tris { for (_, tri) in &self.tris {
if tri.0.x > maxx && tri.0.y < 0.01 && tri.0.y > -0.01 { if tri.0.x > maxx && tri.0.y < 0.01 && tri.0.y > -0.01 {
maxx = tri.0.x; maxx = tri.0.x;
} }
if tri.1.x > maxx && tri.1.y < 0.01 && tri.1.y > -0.01 { if tri.1.x > maxx && tri.1.y < 0.01 && tri.1.y > -0.01 {
maxx = tri.1.x; maxx = tri.1.x;
} }
if tri.2.x > maxx && tri.2.y < 0.01 && tri.2.y > -0.01 { if tri.2.x > maxx && tri.2.y < 0.01 && tri.2.y > -0.01 {
maxx = tri.2.x; maxx = tri.2.x;
} }
} }
if maxx != 0.0 { if maxx != 0.0 {
self.move_left(maxx); self.move_left(maxx);
} }
} }
fn move_left(&mut self, amount: f32) { fn move_left(&mut self, amount: f32) {
for (_, tri) in &mut self.tris { for (_, tri) in &mut self.tris {
tri.0.x -= amount; tri.0.x -= amount;
tri.1.x -= amount; tri.1.x -= amount;
tri.2.x -= amount; tri.2.x -= amount;
} }
} }
fn calc_width(&mut self) { fn calc_width(&mut self) {
let mut minx = f32::MIN; let mut minx = f32::MIN;
if (self.tris[0].1).0.y > -0.001 && (self.tris[0].1).0.y < 0.001 { if (self.tris[0].1).0.y > -0.001 && (self.tris[0].1).0.y < 0.001 {
minx = max((self.tris[0].1).0.x, minx); minx = max((self.tris[0].1).0.x, minx);
} }
if (self.tris[0].1).1.y > -0.001 && (self.tris[0].1).1.y < 0.001 { if (self.tris[0].1).1.y > -0.001 && (self.tris[0].1).1.y < 0.001 {
minx = max((self.tris[0].1).1.x, minx); minx = max((self.tris[0].1).1.x, minx);
} }
if (self.tris[0].1).2.y > -0.001 && (self.tris[0].1).2.y < 0.001 { if (self.tris[0].1).2.y > -0.001 && (self.tris[0].1).2.y < 0.001 {
minx = max((self.tris[0].1).2.x, minx); minx = max((self.tris[0].1).2.x, minx);
} }
let mut maxx = f32::MAX; let mut maxx = f32::MAX;
if (self.tris[self.tris.len() - 1].1).0.y > -0.001 if (self.tris[self.tris.len() - 1].1).0.y > -0.001
&& (self.tris[self.tris.len() - 1].1).0.y < 0.001 && (self.tris[self.tris.len() - 1].1).0.y < 0.001
{ {
maxx = min((self.tris[self.tris.len() - 1].1).0.x, maxx); maxx = min((self.tris[self.tris.len() - 1].1).0.x, maxx);
} }
if (self.tris[self.tris.len() - 1].1).1.y > -0.001 if (self.tris[self.tris.len() - 1].1).1.y > -0.001
&& (self.tris[self.tris.len() - 1].1).1.y < 0.001 && (self.tris[self.tris.len() - 1].1).1.y < 0.001
{ {
maxx = min((self.tris[self.tris.len() - 1].1).1.x, maxx); maxx = min((self.tris[self.tris.len() - 1].1).1.x, maxx);
} }
if (self.tris[self.tris.len() - 1].1).2.y > -0.001 if (self.tris[self.tris.len() - 1].1).2.y > -0.001
&& (self.tris[self.tris.len() - 1].1).2.y < 0.001 && (self.tris[self.tris.len() - 1].1).2.y < 0.001
{ {
maxx = min((self.tris[self.tris.len() - 1].1).2.x, maxx); maxx = min((self.tris[self.tris.len() - 1].1).2.x, maxx);
} }
self.width = maxx - minx; self.width = maxx - minx;
} }
} }
fn rotate(mut tri: Triangle<f32>, angle: f32) -> Triangle<f32> { fn rotate(mut tri: Triangle<f32>, angle: f32) -> Triangle<f32> {
let x1 = tri.1.x; let x1 = tri.1.x;
let y1 = tri.1.y; let y1 = tri.1.y;
tri.1.x = x1 * angle.cos() - y1 * angle.sin(); tri.1.x = x1 * angle.cos() - y1 * angle.sin();
tri.1.y = x1 * angle.sin() + y1 * angle.cos(); tri.1.y = x1 * angle.sin() + y1 * angle.cos();
let x2 = tri.2.x; let x2 = tri.2.x;
let y2 = tri.2.y; let y2 = tri.2.y;
tri.2.x = x2 * angle.cos() - y2 * angle.sin(); tri.2.x = x2 * angle.cos() - y2 * angle.sin();
tri.2.y = x2 * angle.sin() + y2 * angle.cos(); tri.2.y = x2 * angle.sin() + y2 * angle.cos();
tri tri
} }
fn angle_of(_tri: Triangle<f32>, point: Coordinate<f32>) -> f32 { fn angle_of(_tri: Triangle<f32>, point: Coordinate<f32>) -> f32 {
let d = (point.x.powi(2) + point.y.powi(2)).sqrt(); let d = (point.x.powi(2) + point.y.powi(2)).sqrt();
(point.y / d).acos() (point.y / d).acos()
} }
fn transformations(tris: &[Triangle<f32>]) -> Vec<Triangle<f32>> { fn transformations(tris: &[Triangle<f32>]) -> Vec<Triangle<f32>> {
let mut new = Vec::with_capacity(tris.len() * 6); let mut new = Vec::with_capacity(tris.len() * 6);
for t in tris { for t in tris {
let n = Triangle( let n = Triangle(
(0.0, 0.0).into(), (0.0, 0.0).into(),
(t.1.x - t.0.x, t.1.y - t.0.y).into(), (t.1.x - t.0.x, t.1.y - t.0.y).into(),
(t.2.x - t.0.x, t.2.y - t.0.y).into(), (t.2.x - t.0.x, t.2.y - t.0.y).into(),
); );
new.push(n); new.push(n);
let n = [[-n.0.x, n.0.y], [-n.1.x, n.1.y], [-n.2.x, n.2.y]].into(); let n = [[-n.0.x, n.0.y], [-n.1.x, n.1.y], [-n.2.x, n.2.y]].into();
new.push(n); new.push(n);
let n = Triangle( let n = Triangle(
(0.0, 0.0).into(), (0.0, 0.0).into(),
(t.2.x - t.1.x, t.2.y - t.1.y).into(), (t.2.x - t.1.x, t.2.y - t.1.y).into(),
(t.0.x - t.1.x, t.0.y - t.1.y).into(), (t.0.x - t.1.x, t.0.y - t.1.y).into(),
); );
new.push(n); new.push(n);
let n = [[-n.0.x, n.0.y], [-n.1.x, n.1.y], [-n.2.x, n.2.y]].into(); let n = [[-n.0.x, n.0.y], [-n.1.x, n.1.y], [-n.2.x, n.2.y]].into();
new.push(n); new.push(n);
let n = Triangle( let n = Triangle(
(0.0, 0.0).into(), (0.0, 0.0).into(),
(t.0.x - t.2.x, t.0.y - t.2.y).into(), (t.0.x - t.2.x, t.0.y - t.2.y).into(),
(t.1.x - t.2.x, t.1.y - t.2.y).into(), (t.1.x - t.2.x, t.1.y - t.2.y).into(),
); );
new.push(n); new.push(n);
let n = [[-n.0.x, n.0.y], [-n.1.x, n.1.y], [-n.2.x, n.2.y]].into(); let n = [[-n.0.x, n.0.y], [-n.1.x, n.1.y], [-n.2.x, n.2.y]].into();
new.push(n); new.push(n);
} }
new new
} }
fn min(a: f32, b: f32) -> f32 { fn min(a: f32, b: f32) -> f32 {
if a < b { if a < b {
a a
} else { } else {
b b
} }
} }
fn max(a: f32, b: f32) -> f32 { fn max(a: f32, b: f32) -> f32 {
if a > b { if a > b {
a a
} else { } else {
b b
} }
} }