Add heuristic
This commit is contained in:
parent
b0425e73ef
commit
0094cfa2d5
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,4 +1,3 @@
|
|||||||
/target
|
/target
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
tri*.svg
|
*.svg
|
||||||
world*.svg
|
|
||||||
|
@ -8,47 +8,50 @@ use std::fs;
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub(crate) fn save_tri(filename: &str, tri: Triangle<f64>) {
|
pub(crate) fn save_tri(filename: &str, tri: Triangle<f32>) {
|
||||||
fs::write(
|
fs::write(filename, generate_svg(&[tri])).unwrap();
|
||||||
filename,
|
|
||||||
generate_svg(&[tri]),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
pub(crate) fn save_world(filename: &str, world: &World) {
|
pub(crate) fn save_world(filename: &str, world: &World) {
|
||||||
fs::write(
|
fs::write(
|
||||||
filename,
|
filename,
|
||||||
generate_svg(&world.tris.iter().map(|(_idx, tri)| *tri).collect::<Vec<_>>()),
|
generate_svg(
|
||||||
)
|
&world
|
||||||
.unwrap();
|
.tris
|
||||||
|
.iter()
|
||||||
|
.map(|(_idx, tri)| *tri)
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn generate_svg(tris: &[Triangle<f64>]) -> String {
|
pub(crate) fn generate_svg(tris: &[Triangle<f32>]) -> String {
|
||||||
let mut document = Document::new()
|
let mut document = Document::new()
|
||||||
// view box at (x,y), (w,h)
|
// view box at (x,y), (w,h)
|
||||||
.set(
|
.set("viewBox", (-30.0, -30.0, 60.0, 30.0))
|
||||||
"viewBox",
|
.set("xmlns:xlink", "http://www.w3.org/1999/xlink");
|
||||||
(-30.0, -30.0, 60.0, 30.0),
|
|
||||||
)
|
|
||||||
.set("xmlns:xlink", "http://www.w3.org/1999/xlink");
|
|
||||||
|
|
||||||
for tri in tris {
|
for tri in tris {
|
||||||
let data = Data::new()
|
let data = Data::new()
|
||||||
.move_to((tri.0.x, -tri.0.y))
|
.move_to((tri.0.x, -tri.0.y))
|
||||||
.line_to((tri.1.x, -tri.1.y))
|
.line_to((tri.1.x, -tri.1.y))
|
||||||
.line_to((tri.2.x, -tri.2.y))
|
.line_to((tri.2.x, -tri.2.y))
|
||||||
.close();
|
.close();
|
||||||
document.append(Path::new()
|
document.append(
|
||||||
.set("fill", "none")
|
Path::new()
|
||||||
.set("stroke", "black")
|
.set("fill", "none")
|
||||||
.set("stroke-width", 0.4)
|
.set("stroke", "black")
|
||||||
.set("d", data));
|
.set("stroke-width", 0.4)
|
||||||
document.append(Circle::new()
|
.set("d", data),
|
||||||
.set("fill", "red")
|
);
|
||||||
.set("cx", tri.0.x)
|
document.append(
|
||||||
.set("cy", -tri.0.y)
|
Circle::new()
|
||||||
.set("r", 0.3));
|
.set("fill", "red")
|
||||||
}
|
.set("cx", tri.0.x)
|
||||||
|
.set("cy", -tri.0.y)
|
||||||
|
.set("r", 0.3),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
document.to_string()
|
document.to_string()
|
||||||
}
|
}
|
||||||
|
38
src/input.rs
38
src/input.rs
@ -3,28 +3,28 @@ use super::*;
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
|
|
||||||
pub(crate) fn read_input() -> Vec<Triangle<f64>> {
|
pub(crate) fn read_input() -> Vec<Triangle<f32>> {
|
||||||
read_stdin()
|
read_stdin()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_stdin() -> Vec<Triangle<f64>> {
|
fn read_stdin() -> Vec<Triangle<f32>> {
|
||||||
let stdin = io::stdin();
|
let stdin = io::stdin();
|
||||||
let stdin = stdin.lock();
|
let stdin = stdin.lock();
|
||||||
|
|
||||||
let mut lines = stdin.lines().map(Result::unwrap);
|
let mut lines = stdin.lines().map(Result::unwrap);
|
||||||
let tri_count = lines.next().unwrap().parse().unwrap();
|
let tri_count = lines.next().unwrap().parse().unwrap();
|
||||||
let mut tris = Vec::with_capacity(tri_count);
|
let mut tris = Vec::with_capacity(tri_count);
|
||||||
|
|
||||||
for _ in 0..tri_count {
|
for _ in 0..tri_count {
|
||||||
let line = lines.next().unwrap();
|
let line = lines.next().unwrap();
|
||||||
let n = line
|
let n = line
|
||||||
.trim()
|
.trim()
|
||||||
.split(' ')
|
.split(' ')
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.map(|x| x.parse::<f64>().unwrap())
|
.map(|x| x.parse::<f32>().unwrap())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
tris.push([[n[0],n[1]],[n[2],n[3]],[n[4],n[5]]].into());
|
tris.push([[n[0], n[1]], [n[2], n[3]], [n[4], n[5]]].into());
|
||||||
}
|
}
|
||||||
|
|
||||||
tris
|
tris
|
||||||
}
|
}
|
286
src/main.rs
286
src/main.rs
@ -1,20 +1,20 @@
|
|||||||
use geo::{Coordinate, Triangle};
|
|
||||||
use geo::prelude::*;
|
use geo::prelude::*;
|
||||||
|
use geo::{Coordinate, Triangle};
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::BinaryHeap;
|
use std::collections::BinaryHeap;
|
||||||
use std::f64;
|
use std::f32;
|
||||||
use std::f64::consts::PI;
|
use std::f32::consts::PI;
|
||||||
|
|
||||||
mod display;
|
mod display;
|
||||||
mod input;
|
mod input;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct World {
|
struct World {
|
||||||
/// Dreiecksgrundstücke
|
/// Dreiecksgrundstücke
|
||||||
tris: Vec<(usize, Triangle<f64>)>,
|
tris: Vec<(usize, Triangle<f32>)>,
|
||||||
/// Gesamtabstand
|
/// Gesamtabstand
|
||||||
width: f64,
|
width: f32,
|
||||||
}
|
}
|
||||||
impl cmp::PartialEq for World {
|
impl cmp::PartialEq for World {
|
||||||
fn eq(&self, _other: &Self) -> bool {
|
fn eq(&self, _other: &Self) -> bool {
|
||||||
@ -23,14 +23,14 @@ impl cmp::PartialEq for World {
|
|||||||
}
|
}
|
||||||
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() {
|
||||||
@ -46,67 +46,97 @@ fn main() {
|
|||||||
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 && rotated.2.y >= -0.001 && (rotated.1.y < 0.1 || rotated.2.y < 0.1) {
|
if rotated.1.y >= -0.001
|
||||||
|
&& rotated.2.y >= -0.001
|
||||||
|
&& (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.0 && rotated.2.x > 0.0 {
|
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 && rotated.1.y >= -0.001 && rotated.2.y >= -0.001 && (rotated.1.y < 0.1 || rotated.2.y < 0.1) {
|
if !added
|
||||||
|
&& rotated.1.y >= -0.001
|
||||||
|
&& rotated.2.y >= -0.001
|
||||||
|
&& (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.0 && rotated.2.x > 0.0 {
|
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 && rotated.1.y >= -0.001 && rotated.2.y >= -0.001 && (rotated.1.y < 0.1 || rotated.2.y < 0.1) {
|
if !added
|
||||||
|
&& rotated.1.y >= -0.001
|
||||||
|
&& rotated.2.y >= -0.001
|
||||||
|
&& (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.0 && rotated.2.x > 0.0 {
|
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 && rotated.1.y >= -0.001 && rotated.2.y >= -0.001 && (rotated.1.y < 0.1 || rotated.2.y < 0.1) {
|
if !added
|
||||||
|
&& rotated.1.y >= -0.001
|
||||||
|
&& rotated.2.y >= -0.001
|
||||||
|
&& (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.0 && rotated.2.x > 0.0 {
|
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 && rotated.2.y >= -0.001 && (rotated.1.y < 0.1 || rotated.2.y < 0.1) {
|
if rotated.1.y >= -0.001
|
||||||
|
&& rotated.2.y >= -0.001
|
||||||
|
&& (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.0 && rotated.2.x > 0.0 {
|
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 && rotated.1.y >= -0.001 && rotated.2.y >= -0.001 && (rotated.1.y < 0.1 || rotated.2.y < 0.1) {
|
if !added
|
||||||
|
&& rotated.1.y >= -0.001
|
||||||
|
&& rotated.2.y >= -0.001
|
||||||
|
&& (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.0 && rotated.2.x > 0.0 {
|
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 && rotated.1.y >= -0.001 && rotated.2.y >= -0.001 && (rotated.1.y < 0.1 || rotated.2.y < 0.1) {
|
if !added
|
||||||
|
&& rotated.1.y >= -0.001
|
||||||
|
&& rotated.2.y >= -0.001
|
||||||
|
&& (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.0 && rotated.2.x > 0.0 {
|
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 && rotated.1.y >= -0.001 && rotated.2.y >= -0.001 && (rotated.1.y < 0.1 || rotated.2.y < 0.1) {
|
if !added
|
||||||
|
&& rotated.1.y >= -0.001
|
||||||
|
&& rotated.2.y >= -0.001
|
||||||
|
&& (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.0 && rotated.2.x > 0.0 {
|
if rotated.1.x > -0.001 && rotated.2.x > -0.001 {
|
||||||
left_tris.push((idx, rotated));
|
left_tris.push((idx, rotated));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,58 +145,80 @@ fn main() {
|
|||||||
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_";
|
||||||
|
save_counter = 0;
|
||||||
let mut worlds = BinaryHeap::new();
|
let mut worlds = BinaryHeap::new();
|
||||||
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);
|
||||||
|
save_counter += 1;
|
||||||
worlds.push(world);
|
worlds.push(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut best = World { tris: vec![], width: f64::MAX };
|
let mut best = World {
|
||||||
|
tris: vec![],
|
||||||
|
width: f32::MAX,
|
||||||
|
};
|
||||||
let save_prefix = "world_";
|
let save_prefix = "world_";
|
||||||
let mut save_counter = 0;
|
save_counter = 0;
|
||||||
while worlds.peek().map(|x| x.width <= best.width) == Some(true) {
|
while worlds.peek().map(|x| x.width <= best.width) == Some(true) {
|
||||||
let w = worlds.pop().unwrap();
|
let w = worlds.pop().unwrap();
|
||||||
//println!("s: {:?}", w);
|
//println!("s: {:?}", w);
|
||||||
|
|
||||||
let mut new = vec![];
|
let mut new = vec![];
|
||||||
for (next_idx, next_tri) in left_tris.iter()
|
for (next_idx, next_tri) in left_tris
|
||||||
.filter(|(idx1, _tri)| w.tris.iter().all(|(idx2, _tri)| idx1 != idx2)) {
|
.iter()
|
||||||
|
.filter(|(idx1, _tri)| w.tris.iter().all(|(idx2, _tri)| idx1 != idx2))
|
||||||
|
{
|
||||||
//println!("trying {:?}", next_idx);
|
//println!("trying {:?}", next_idx);
|
||||||
let (_, last_tri) = *w.tris.last().unwrap();
|
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) {
|
let last_vertex =
|
||||||
last_tri.1
|
if last_tri.1.y > 0.01 && !(last_tri.2.y > 0.01 && last_tri.2.x > last_tri.1.x) {
|
||||||
} else {
|
last_tri.1
|
||||||
last_tri.2
|
} else {
|
||||||
};
|
last_tri.2
|
||||||
|
};
|
||||||
|
|
||||||
let mut free_angle = angle_of(last_tri, last_vertex);
|
let mut free_angle = angle_of(last_tri, last_vertex);
|
||||||
//println!("angle of {:?}: {:?}", last_vertex, free_angle);
|
//println!("angle of {:?}: {:?}", last_vertex, free_angle);
|
||||||
if last_vertex.x > 0.0 {
|
if last_vertex.x > 0.0 {
|
||||||
free_angle = 0.5*PI - free_angle;
|
free_angle = 0.5 * PI - free_angle;
|
||||||
} else {
|
} else {
|
||||||
free_angle = 0.5*PI + free_angle;
|
free_angle = 0.5 * PI + free_angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_vertex = if next_tri.1.y > 0.01 {
|
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
|
next_tri.1
|
||||||
} else {
|
} else {
|
||||||
next_tri.2
|
next_tri.2
|
||||||
};
|
};
|
||||||
let mut next_angle = angle_of(*next_tri, next_vertex);
|
let next_angle = PI - angle_of(*next_tri, next_vertex);
|
||||||
if next_vertex.x > 0.0 {
|
|
||||||
next_angle = 0.5*PI - next_angle;
|
for angle in 0..=150 {
|
||||||
} else {
|
let angle = (1.0 * angle as f32).to_radians();
|
||||||
next_angle = 0.5*PI + next_angle;
|
let next_angle = next_angle - angle;
|
||||||
}
|
let mut tri = rotate(*next_tri, angle);
|
||||||
if next_angle <= free_angle {
|
|
||||||
// easy: just rotate to fit and put it below the last triangle
|
let dx = if last_tri.intersects(&tri) {
|
||||||
|
0.005
|
||||||
|
} else {
|
||||||
|
-0.005
|
||||||
|
};
|
||||||
|
while last_tri.intersects(&tri) {
|
||||||
|
tri.0.x += dx;
|
||||||
|
tri.1.x += dx;
|
||||||
|
tri.2.x += dx;
|
||||||
|
}
|
||||||
let mut w = w.clone();
|
let mut w = w.clone();
|
||||||
w.tris.push((*next_idx, rotate(*next_tri, free_angle - next_angle)));
|
w.tris.push((*next_idx, tri));
|
||||||
//println!("new {:?} {:?} {:?}: {:?}", save_counter, free_angle, next_angle, w);
|
|
||||||
w.normalize();
|
w.normalize();
|
||||||
w.calc_width();
|
w.calc_width();
|
||||||
if save_counter < 100 {
|
if save_counter < 100 {
|
||||||
@ -175,36 +227,15 @@ fn main() {
|
|||||||
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: {}", w.width);
|
println!("new best: {}", w.width);
|
||||||
|
println!("{:?}", w.tris);
|
||||||
|
display::save_world(
|
||||||
|
&format!("{}best_{}.svg", save_prefix, save_counter),
|
||||||
|
&w,
|
||||||
|
);
|
||||||
best = w;
|
best = w;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new.push(w);
|
w.width -= (2.0 * PI - free_angle - next_angle) * 0.003 * w.tris.len() as f32;
|
||||||
}
|
|
||||||
save_counter += 1;
|
|
||||||
} else {
|
|
||||||
// "hard": move it right till it fits
|
|
||||||
print!("error: doesn't fit [S{} {}]", w.tris.len(), save_counter);
|
|
||||||
assert!(last_tri.intersects(next_tri));
|
|
||||||
let mut next_tri = *next_tri;
|
|
||||||
while last_tri.intersects(&next_tri) {
|
|
||||||
next_tri.0.x += 0.005;
|
|
||||||
next_tri.1.x += 0.005;
|
|
||||||
next_tri.2.x += 0.005;
|
|
||||||
}
|
|
||||||
let mut w = w.clone();
|
|
||||||
w.tris.push((*next_idx, next_tri));
|
|
||||||
w.normalize();
|
|
||||||
w.calc_width();
|
|
||||||
println!(" -> width = {}", w.width);
|
|
||||||
if save_counter < 100 {
|
|
||||||
display::save_world(&format!("{}{}.svg", save_prefix, save_counter), &w);
|
|
||||||
}
|
|
||||||
if w.tris.len() == count_tris {
|
|
||||||
if w.width < best.width {
|
|
||||||
println!("new best: {}", w.width);
|
|
||||||
best = w;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
new.push(w);
|
new.push(w);
|
||||||
}
|
}
|
||||||
save_counter += 1;
|
save_counter += 1;
|
||||||
@ -234,7 +265,7 @@ impl World {
|
|||||||
self.move_left(maxx);
|
self.move_left(maxx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn move_left(&mut self, amount: f64) {
|
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;
|
||||||
@ -242,55 +273,96 @@ impl World {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn calc_width(&mut self) {
|
fn calc_width(&mut self) {
|
||||||
let mut x = vec![];
|
let mut minx = f32::MIN;
|
||||||
for (_, tri) in &self.tris {
|
if (self.tris[0].1).0.y > -0.001 && (self.tris[0].1).0.y < 0.001 {
|
||||||
if tri.0.y < 0.001 && tri.0.y > -0.001 {
|
minx = max((self.tris[0].1).0.x, minx);
|
||||||
x.push(tri.0.x);
|
|
||||||
}
|
|
||||||
if tri.1.y < 0.001 && tri.1.y > -0.001 {
|
|
||||||
x.push(tri.1.x);
|
|
||||||
}
|
|
||||||
if tri.2.y < 0.001 && tri.2.y > -0.001 {
|
|
||||||
x.push(tri.2.x);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
x.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
|
if (self.tris[0].1).1.y > -0.001 && (self.tris[0].1).1.y < 0.001 {
|
||||||
self.width = x[x.len()-2] - x[1];
|
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 {
|
||||||
|
minx = max((self.tris[0].1).2.x, minx);
|
||||||
|
}
|
||||||
|
let mut maxx = f32::MAX;
|
||||||
|
if (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);
|
||||||
|
}
|
||||||
|
if (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);
|
||||||
|
}
|
||||||
|
if (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);
|
||||||
|
}
|
||||||
|
self.width = maxx - minx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rotate(mut tri: Triangle<f64>, angle: f64) -> Triangle<f64> {
|
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<f64>, point: Coordinate<f64>) -> f64 {
|
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<f64>]) -> Vec<Triangle<f64>> {
|
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((0.0, 0.0).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());
|
let n = Triangle(
|
||||||
|
(0.0, 0.0).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(),
|
||||||
|
);
|
||||||
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((0.0, 0.0).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());
|
let n = Triangle(
|
||||||
|
(0.0, 0.0).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(),
|
||||||
|
);
|
||||||
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((0.0, 0.0).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());
|
let n = Triangle(
|
||||||
|
(0.0, 0.0).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(),
|
||||||
|
);
|
||||||
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 {
|
||||||
|
if a < b {
|
||||||
|
a
|
||||||
|
} else {
|
||||||
|
b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn max(a: f32, b: f32) -> f32 {
|
||||||
|
if a > b {
|
||||||
|
a
|
||||||
|
} else {
|
||||||
|
b
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user