Fix various warnings and improve performance

This commit is contained in:
Arne Keller 2019-03-29 23:20:34 +01:00
parent 0be8aef479
commit affe26209f
4 changed files with 44 additions and 43 deletions

View File

@ -7,6 +7,7 @@ edition = "2018"
[profile.release]
codegen-units = 1
opt-level = 3
panic = "abort"
[dependencies]
geo = "0.12"

View File

@ -74,7 +74,7 @@ pub(crate) fn dump_latex_code(route: &[RunState], polys: &[Polygon]) {
println!("\\end{{tikzpicture}}");
}
pub(crate) fn dump_route(house: Point, polys: &[Polygon], route: &Vec<RunState>) {
pub(crate) fn dump_route(house: Point, polys: &[Polygon], route: &[RunState]) {
let (points, lines, route1, route2_start) = gen_params(house, route);
print!(
"{}",
@ -82,7 +82,7 @@ pub(crate) fn dump_route(house: Point, polys: &[Polygon], route: &Vec<RunState>)
);
}
pub(crate) fn save_svg(filename: &str, house: Point, polys: &[Polygon], route: &Vec<RunState>) {
pub(crate) fn save_svg(filename: &str, house: Point, polys: &[Polygon], route: &[RunState]) {
let (points, lines, route1, route2_start) = gen_params(house, route);
fs::write(
filename,
@ -91,9 +91,10 @@ pub(crate) fn save_svg(filename: &str, house: Point, polys: &[Polygon], route: &
.unwrap();
}
#[allow(clippy::type_complexity)]
fn gen_params(
house: Point,
route: &Vec<RunState>,
route: &[RunState],
) -> (
Vec<(Point, &'static str)>,
Vec<(Line, &'static str)>,
@ -135,8 +136,8 @@ pub(crate) fn generate_svg(
for circle in points.iter().map(|(p, color)| {
Circle::new()
.set("cx", f64::from(p.x()))
.set("cy", f64::from(-p.y()))
.set("cx", p.x())
.set("cy", -p.y())
.set("r", dot_radius)
.set("opacity", 0.5)
.set("fill", *color)
@ -145,8 +146,8 @@ pub(crate) fn generate_svg(
}
for path in lines.iter().map(|(l, color)| {
let data = Data::new()
.move_to((f64::from(l.start.x), f64::from(-l.start.y)))
.line_to((f64::from(l.end.x), f64::from(-l.end.y)))
.move_to((l.start.x, -l.start.y))
.line_to((l.end.x, -l.end.y))
.close();
Path::new()
@ -161,13 +162,11 @@ pub(crate) fn generate_svg(
for path in polys.iter().map(|poly| {
let coords = &poly.exterior().0;
let first = coords[0].x_y();
let mut first: (f64, f64) = (first.0.into(), first.1.into());
let mut first = coords[0].x_y();
first.1 *= -1.0;
let mut data = Data::new().move_to(first);
for c in &coords[1..] {
let c = c.x_y();
let mut c: (f64, f64) = (c.0.into(), c.1.into());
let mut c = c.x_y();
c.1 *= -1.0;
data = data.line_to(c);
}
@ -182,12 +181,11 @@ pub(crate) fn generate_svg(
document.append(path);
}
let mut first: (f64, f64) = (route1[0].x().into(), route1[0].y().into());
let mut first: (f64, f64) = (route1[0].x(), route1[0].y());
first.1 *= -1.0;
let mut data = Data::new().move_to(first);
for point in &route1[1..] {
let c = point.x_y();
let mut c: (f64, f64) = (c.0.into(), c.1.into());
let mut c = point.x_y();
c.1 *= -1.0;
data = data.line_to(c);
}
@ -212,11 +210,11 @@ pub(crate) fn generate_svg(
dot1.append(motion1);
document.append(dot1);
let mut first: (f64, f64) = (route2_start.x().into(), route2_start.y().into());
let mut first = (route2_start.x(), route2_start.y());
first.1 *= -1.0;
let mut data = Data::new().move_to(first);
let last = route1.last().unwrap();
data = data.line_to::<(f64, f64)>((last.x().into(), (|x: f64| -x)(last.y().into())));
data = data.line_to((last.x(), -last.y()));
let path = Path::new()
.set("id", "route2")
.set("fill", "none")

View File

@ -61,49 +61,49 @@ fn _custom_input() -> InputData {
let mut polys = vec![];
polys.push(Polygon::new(
vec![
[2.0.into(), 0.0.into()],
[6.0.into(), 0.0.into()],
[6.0.into(), 6.0.into()],
[2.0.into(), 5.0.into()],
[2.0, 0.0],
[6.0, 0.0],
[6.0, 6.0],
[2.0, 5.0],
]
.into(),
vec![],
));
polys.push(Polygon::new(
vec![
[1.0.into(), 20.0.into()],
[2.0.into(), 20.0.into()],
[2.0.into(), 23.0.into()],
[1.0.into(), 23.0.into()],
[1.0, 20.0],
[2.0, 20.0],
[2.0, 23.0],
[1.0, 23.0],
]
.into(),
vec![],
));
polys.push(Polygon::new(
vec![
[1.0.into(), 25.0.into()],
[2.0.into(), 25.0.into()],
[2.0.into(), 28.0.into()],
[1.0.into(), 28.0.into()],
[1.0, 25.0],
[2.0, 25.0],
[2.0, 28.0],
[1.0, 28.0],
]
.into(),
vec![],
));
let mut stick = Polygon::new(
vec![
[1.0.into(), 115.0.into()],
[2.0.into(), 115.0.into()],
[2.0.into(), 130.0.into()],
[1.0.into(), 130.0.into()],
[1.0, 115.0],
[2.0, 115.0],
[2.0, 130.0],
[1.0, 130.0],
]
.into(),
vec![],
);
polys.push(stick.clone());
stick = stick.translate(35.0.into(), (-20.0).into());
stick = stick.translate(35.0, -20.0);
polys.push(stick);
InputData {
start: Point::new(45.0.into(), 95.0.into()),
start: Point::new(45.0, 95.0),
polys,
}
}

View File

@ -2,7 +2,6 @@ use geo::prelude::*;
use chrono::{Duration, NaiveTime};
//#[macro_use] extern crate structopt;
use structopt::StructOpt;
use std::cmp;
@ -37,7 +36,7 @@ struct Opt {
bus: f64,
}
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, Copy, PartialEq)]
struct RunState {
/// Theoretisch mögliche Wartezeit
delay: f64,
@ -59,15 +58,17 @@ impl cmp::PartialOrd for RunState {
}
fn main() {
// Kommandozeilen-Argumente einlesen
let opt = Opt::from_args();
// 30 km/h -> 8.3 m/s
// Geschwindigkeiten in m/s umrechnen
let bus_speed = opt.bus / 3.6;
let lisa_speed = opt.lisa / 3.6;
// Zeitpunkt basierend auf Wartezeit in Sekunden berechnen
// Startzeitpunkt berechnen
let calc_time = |total_distance, y| {
NaiveTime::from_hms(7, 30, 0)
- Duration::seconds(((total_distance * 2.0 - y) / bus_speed) as i64)
};
// Ankuftszeit berechnen
let calc_end_time = |total_distance, y| {
calc_time(total_distance, y) + Duration::seconds((total_distance / lisa_speed) as i64)
};
@ -81,15 +82,17 @@ fn main() {
.iter()
.map(|x| x.exterior().0.clone())
.flatten()
.map(Point::from)
.collect::<Vec<_>>();
// Startzustand: Lisa ist an ihrem Haus, Bus noch nicht losgefahren
// Startzustand: Lisa ist an ihrem Haus, zurückgelegte Distanz ist Null
let start = RunState {
pos: house,
delay: max_possible_delay(&opt, 0.0, house),
total_distance: 0.0,
};
// bestmöglicher Fall: Lisa geht direkt zum Bus
let meeting_point = Point::new(0.0, house.y() + (opt.lisa/opt.bus).asin().tan() * house.x());
eprintln!(
"Theoretisches Maximum: {:?}",
@ -120,13 +123,12 @@ fn main() {
let mut all = vec![];
// versuche, zu jeder anderen Ecke zu gehen
for next in points
for &next in points
.iter()
// Ecke sollte nicht schon in Route sein
.filter(|next| !state.iter().any(|p| p.pos == (**next).into()))
.map(|x| Point::from(*x))
.filter(|&&next| !state.iter().any(|p| p.pos == next))
// Weg zu dieser Ecke sollte kein Polygon schneiden
.filter(|next| none_intersect(&polys, &Line::new(last.pos, *next)))
.filter(|&&next| none_intersect(&polys, &Line::new(last.pos, next)))
{
// Lisa könnte zu dieser Ecke rennen
let total_distance = last.total_distance + distance(last.pos, next);