Format using tabs
This commit is contained in:
parent
62695b2fbb
commit
142b8c02e6
1
rustfmt.toml
Normal file
1
rustfmt.toml
Normal file
@ -0,0 +1 @@
|
|||||||
|
hard_tabs = true
|
748
src/main.rs
748
src/main.rs
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user