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] [profile.release]
codegen-units = 1 codegen-units = 1
opt-level = 3 opt-level = 3
panic = "abort"
[dependencies] [dependencies]
geo = "0.12" geo = "0.12"

View File

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

View File

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

View File

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