Run rustfmt
This commit is contained in:
parent
af280353cc
commit
460e0749ad
1
rustfmt.toml
Normal file
1
rustfmt.toml
Normal file
@ -0,0 +1 @@
|
|||||||
|
hard_tabs = true
|
@ -1,19 +1,25 @@
|
|||||||
|
use svg::node::element::path::Data;
|
||||||
|
use svg::node::element::Path;
|
||||||
|
use svg::node::element::{AnimateMotion, Circle, MotionPath};
|
||||||
use svg::Document;
|
use svg::Document;
|
||||||
use svg::Node;
|
use svg::Node;
|
||||||
use svg::node::element::{AnimateMotion, MotionPath, Circle};
|
|
||||||
use svg::node::element::Path;
|
|
||||||
use svg::node::element::path::Data;
|
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub(crate) fn dump_svg(points: &[(Point, &'static str)], lines: &[(Line, &'static str)], polys: &[Polygon], route1: &[Point], route2_start: Point) {
|
pub(crate) fn dump_svg(
|
||||||
|
points: &[(Point, &'static str)],
|
||||||
|
lines: &[(Line, &'static str)],
|
||||||
|
polys: &[Polygon],
|
||||||
|
route1: &[Point],
|
||||||
|
route2_start: Point,
|
||||||
|
) {
|
||||||
let mut document = Document::new()
|
let mut document = Document::new()
|
||||||
// view box at (0, -200), w*h (200, 200)
|
// view box at (0, -200), w*h (200, 200)
|
||||||
.set("viewBox", (0, -1100, 2100, 2100))
|
.set("viewBox", (0, -1100, 2100, 2100))
|
||||||
.set("xmlns:xlink", "http://www.w3.org/1999/xlink");
|
.set("xmlns:xlink", "http://www.w3.org/1999/xlink");
|
||||||
|
|
||||||
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", f64::from(p.x()))
|
||||||
@ -45,8 +51,7 @@ pub(crate) fn dump_svg(points: &[(Point, &'static str)], lines: &[(Line, &'stati
|
|||||||
let first = coords[0].x_y();
|
let first = coords[0].x_y();
|
||||||
let mut first: (f64, f64) = (first.0.into(), first.1.into());
|
let mut first: (f64, f64) = (first.0.into(), first.1.into());
|
||||||
first.1 *= -1.0;
|
first.1 *= -1.0;
|
||||||
let mut data = Data::new()
|
let mut data = Data::new().move_to(first);
|
||||||
.move_to(first);
|
|
||||||
for c in &coords[1..] {
|
for c in &coords[1..] {
|
||||||
let c = c.x_y();
|
let c = c.x_y();
|
||||||
let mut c: (f64, f64) = (c.0.into(), c.1.into());
|
let mut c: (f64, f64) = (c.0.into(), c.1.into());
|
||||||
@ -66,8 +71,7 @@ pub(crate) fn dump_svg(points: &[(Point, &'static str)], lines: &[(Line, &'stati
|
|||||||
|
|
||||||
let mut first: (f64, f64) = (route1[0].x().into(), route1[0].y().into());
|
let mut first: (f64, f64) = (route1[0].x().into(), route1[0].y().into());
|
||||||
first.1 *= -1.0;
|
first.1 *= -1.0;
|
||||||
let mut data = Data::new()
|
let mut data = Data::new().move_to(first);
|
||||||
.move_to(first);
|
|
||||||
for point in &route1[1..] {
|
for point in &route1[1..] {
|
||||||
let c = point.x_y();
|
let c = point.x_y();
|
||||||
let mut c: (f64, f64) = (c.0.into(), c.1.into());
|
let mut c: (f64, f64) = (c.0.into(), c.1.into());
|
||||||
@ -82,12 +86,14 @@ pub(crate) fn dump_svg(points: &[(Point, &'static str)], lines: &[(Line, &'stati
|
|||||||
document.append(path);
|
document.append(path);
|
||||||
|
|
||||||
let mut dot1 = Circle::new()
|
let mut dot1 = Circle::new()
|
||||||
.set("cx", 0.0)
|
.set("cx", 0.0)
|
||||||
.set("cy", 0.0)
|
.set("cy", 0.0)
|
||||||
.set("r", 25.2)
|
.set("r", 25.2)
|
||||||
.set("opacity", 0.75)
|
.set("opacity", 0.75)
|
||||||
.set("fill", "gray");
|
.set("fill", "gray");
|
||||||
let mut motion1 = AnimateMotion::new().set("dur", "2s").set("repeatCount", "indefinite");
|
let mut motion1 = AnimateMotion::new()
|
||||||
|
.set("dur", "2s")
|
||||||
|
.set("repeatCount", "indefinite");
|
||||||
let path = MotionPath::new().set("xlink:href", "#route1");
|
let path = MotionPath::new().set("xlink:href", "#route1");
|
||||||
motion1.append(path);
|
motion1.append(path);
|
||||||
dot1.append(motion1);
|
dot1.append(motion1);
|
||||||
@ -95,10 +101,9 @@ pub(crate) fn dump_svg(points: &[(Point, &'static str)], lines: &[(Line, &'stati
|
|||||||
|
|
||||||
let mut first: (f64, f64) = (route2_start.x().into(), route2_start.y().into());
|
let mut first: (f64, f64) = (route2_start.x().into(), route2_start.y().into());
|
||||||
first.1 *= -1.0;
|
first.1 *= -1.0;
|
||||||
let mut data = Data::new()
|
let mut data = Data::new().move_to(first);
|
||||||
.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::<(f64, f64)>((last.x().into(), (|x: f64| -x)(last.y().into())));
|
||||||
let path = Path::new()
|
let path = Path::new()
|
||||||
.set("id", "route2")
|
.set("id", "route2")
|
||||||
.set("fill", "none")
|
.set("fill", "none")
|
||||||
@ -107,12 +112,14 @@ pub(crate) fn dump_svg(points: &[(Point, &'static str)], lines: &[(Line, &'stati
|
|||||||
document.append(path);
|
document.append(path);
|
||||||
|
|
||||||
let mut dot1 = Circle::new()
|
let mut dot1 = Circle::new()
|
||||||
.set("cx", 0.0)
|
.set("cx", 0.0)
|
||||||
.set("cy", 0.0)
|
.set("cy", 0.0)
|
||||||
.set("r", 25.2)
|
.set("r", 25.2)
|
||||||
.set("opacity", 0.75)
|
.set("opacity", 0.75)
|
||||||
.set("fill", "gray");
|
.set("fill", "gray");
|
||||||
let mut motion1 = AnimateMotion::new().set("dur", "2s").set("repeatCount", "indefinite");
|
let mut motion1 = AnimateMotion::new()
|
||||||
|
.set("dur", "2s")
|
||||||
|
.set("repeatCount", "indefinite");
|
||||||
let path = MotionPath::new().set("xlink:href", "#route2");
|
let path = MotionPath::new().set("xlink:href", "#route2");
|
||||||
motion1.append(path);
|
motion1.append(path);
|
||||||
dot1.append(motion1);
|
dot1.append(motion1);
|
||||||
|
79
src/input.rs
79
src/input.rs
@ -5,7 +5,7 @@ use std::io::prelude::*;
|
|||||||
|
|
||||||
pub(crate) struct InputData {
|
pub(crate) struct InputData {
|
||||||
pub start: Point,
|
pub start: Point,
|
||||||
pub polys: Vec<Polygon>
|
pub polys: Vec<Polygon>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_input() -> InputData {
|
pub(crate) fn read_input() -> InputData {
|
||||||
@ -23,30 +23,87 @@ fn read_stdin() -> InputData {
|
|||||||
|
|
||||||
for _ in 0..polygon_count {
|
for _ in 0..polygon_count {
|
||||||
let line = lines.next().unwrap();
|
let line = lines.next().unwrap();
|
||||||
let numbers = line.trim().split(' ').map(|x| x.parse::<usize>().unwrap()).collect::<Vec<_>>();
|
let numbers = line
|
||||||
|
.trim()
|
||||||
|
.split(' ')
|
||||||
|
.map(|x| x.parse::<usize>().unwrap())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
let corner_count = numbers[0];
|
let corner_count = numbers[0];
|
||||||
polygons.push(Polygon::new((0..corner_count).map(|idx| ((numbers[idx*2+1] as f32).into(), (numbers[idx*2+2] as f32).into())).collect::<Vec<_>>().into(), vec![]));
|
polygons.push(Polygon::new(
|
||||||
|
(0..corner_count)
|
||||||
|
.map(|idx| {
|
||||||
|
(
|
||||||
|
(numbers[idx * 2 + 1] as f32).into(),
|
||||||
|
(numbers[idx * 2 + 2] as f32).into(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.into(),
|
||||||
|
vec![],
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let home = lines.next().unwrap().trim().split(' ').map(|x| x.parse::<f32>().unwrap().into()).collect::<Vec<_>>();
|
let home = lines
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.trim()
|
||||||
|
.split(' ')
|
||||||
|
.map(|x| x.parse::<f32>().unwrap().into())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
InputData {
|
InputData {
|
||||||
start: Point::new(home[0], home[1]),
|
start: Point::new(home[0], home[1]),
|
||||||
polys: polygons
|
polys: polygons,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn custom_input() -> InputData {
|
fn custom_input() -> InputData {
|
||||||
let mut polys = vec![];
|
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()]].into(), vec![]));
|
polys.push(Polygon::new(
|
||||||
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()]].into(), vec![]));
|
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()]].into(), vec![]));
|
[2.0.into(), 0.0.into()],
|
||||||
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()]].into(), vec![]);
|
[6.0.into(), 0.0.into()],
|
||||||
|
[6.0.into(), 6.0.into()],
|
||||||
|
[2.0.into(), 5.0.into()],
|
||||||
|
]
|
||||||
|
.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()],
|
||||||
|
]
|
||||||
|
.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()],
|
||||||
|
]
|
||||||
|
.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()],
|
||||||
|
]
|
||||||
|
.into(),
|
||||||
|
vec![],
|
||||||
|
);
|
||||||
polys.push(stick.clone());
|
polys.push(stick.clone());
|
||||||
stick = stick.translate(35.0.into(), (-20.0).into());
|
stick = stick.translate(35.0.into(), (-20.0).into());
|
||||||
polys.push(stick);
|
polys.push(stick);
|
||||||
InputData {
|
InputData {
|
||||||
start: Point::new(45.0.into(), 95.0.into()),
|
start: Point::new(45.0.into(), 95.0.into()),
|
||||||
polys
|
polys,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
143
src/main.rs
143
src/main.rs
@ -1,4 +1,3 @@
|
|||||||
use geo::*;
|
|
||||||
use geo::prelude::*;
|
use geo::prelude::*;
|
||||||
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
@ -22,7 +21,7 @@ struct RunState {
|
|||||||
/// Our current location
|
/// Our current location
|
||||||
pos: Point,
|
pos: Point,
|
||||||
/// Current location of the bus, not including any delays
|
/// Current location of the bus, not including any delays
|
||||||
bus: Point
|
bus: Point,
|
||||||
}
|
}
|
||||||
impl cmp::Eq for RunState {}
|
impl cmp::Eq for RunState {}
|
||||||
impl cmp::Ord for RunState {
|
impl cmp::Ord for RunState {
|
||||||
@ -37,7 +36,7 @@ impl cmp::PartialOrd for RunState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let bus = Point::new(0.0.into(), (-2000.0).into());
|
let bus = Point::new(0.0, -2000.0);
|
||||||
|
|
||||||
let data = input::read_input();
|
let data = input::read_input();
|
||||||
let house = data.start;
|
let house = data.start;
|
||||||
@ -46,40 +45,32 @@ fn main() {
|
|||||||
eprintln!("{:?}", polys);
|
eprintln!("{:?}", polys);
|
||||||
for p in &polys {
|
for p in &polys {
|
||||||
assert!(p.interiors.is_empty());
|
assert!(p.interiors.is_empty());
|
||||||
//assert!(p.is_convex());
|
|
||||||
}
|
}
|
||||||
let points = polys.iter().map(|x| x.exterior.0.clone()).flatten().collect::<Vec<_>>();
|
let points = polys
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.exterior.0.clone())
|
||||||
|
.flatten()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let start = RunState {
|
let start = RunState {
|
||||||
pos: house,
|
pos: house,
|
||||||
bus: bus,
|
bus: bus,
|
||||||
delay: max_possible_delay(bus, house)
|
delay: max_possible_delay(bus, house),
|
||||||
//route: vec![house],
|
|
||||||
//length: 0.0.into()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
eprintln!("# Max delay possible: {:?}", start.delay);
|
eprintln!("# Max. delay possible: {:?}", start.delay);
|
||||||
|
|
||||||
let mut states = BinaryHeap::new();
|
let mut states = BinaryHeap::new();
|
||||||
states.push(vec![start]);
|
states.push(vec![start]);
|
||||||
|
|
||||||
let mut best_delay = 0.0;
|
let mut best_delay = 0.0;
|
||||||
let mut best = vec![];
|
let mut best = vec![];
|
||||||
|
|
||||||
while states.peek().map(|x| x[0].delay > best_delay) == Some(true) {
|
while states.peek().map(|x| x[0].delay > best_delay) == Some(true) {
|
||||||
eprintln!(". {:?} states left:", states.len());
|
eprintln!(". {:?} states left:", states.len());
|
||||||
/*
|
|
||||||
if states.len() > 10 {
|
|
||||||
for s in &states {
|
|
||||||
eprintln!("{:?}", s);
|
|
||||||
}
|
|
||||||
panic!();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
let s = states.pop().unwrap();
|
let s = states.pop().unwrap();
|
||||||
let last = &s[0]; //s.last().unwrap();
|
let last = &s[0]; //s.last().unwrap();
|
||||||
eprintln!("{},{}", last.pos.x(), last.pos.y());
|
eprintln!("{},{}", last.pos.x(), last.pos.y());
|
||||||
//eprintln!("{:?}", states.peek());
|
|
||||||
|
|
||||||
// new states
|
// new states
|
||||||
let mut all = vec![];
|
let mut all = vec![];
|
||||||
@ -92,11 +83,14 @@ fn main() {
|
|||||||
let bus_next = last.bus.translate(0.0, distance(last.pos, next) * 2.0);
|
let bus_next = last.bus.translate(0.0, distance(last.pos, next) * 2.0);
|
||||||
let mut route = s.clone();
|
let mut route = s.clone();
|
||||||
//eprintln!("{},{} would go {},{}", last.pos.x(), last.pos.y(), next.x(), next.y());
|
//eprintln!("{},{} would go {},{}", last.pos.x(), last.pos.y(), next.x(), next.y());
|
||||||
route.insert(0, RunState {
|
route.insert(
|
||||||
pos: next,
|
0,
|
||||||
bus: bus_next,
|
RunState {
|
||||||
delay: max_possible_delay(bus_next, next)
|
pos: next,
|
||||||
});
|
bus: bus_next,
|
||||||
|
delay: max_possible_delay(bus_next, next),
|
||||||
|
},
|
||||||
|
);
|
||||||
all.push(route);
|
all.push(route);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,11 +111,14 @@ fn main() {
|
|||||||
if delay > best_delay {
|
if delay > best_delay {
|
||||||
// new high score!
|
// new high score!
|
||||||
let mut route = s.clone();
|
let mut route = s.clone();
|
||||||
route.insert(0, RunState {
|
route.insert(
|
||||||
pos: next,
|
0,
|
||||||
bus: next,
|
RunState {
|
||||||
delay
|
pos: next,
|
||||||
});
|
bus: next,
|
||||||
|
delay,
|
||||||
|
},
|
||||||
|
);
|
||||||
eprintln!("# New best delay {:?}", delay);
|
eprintln!("# New best delay {:?}", delay);
|
||||||
best = route;
|
best = route;
|
||||||
best.reverse();
|
best.reverse();
|
||||||
@ -137,7 +134,6 @@ fn main() {
|
|||||||
//eprintln!("-> adding all to queue");
|
//eprintln!("-> adding all to queue");
|
||||||
states.extend(all);
|
states.extend(all);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
eprintln!("d = {:?}", best_delay);
|
eprintln!("d = {:?}", best_delay);
|
||||||
let route = best;
|
let route = best;
|
||||||
@ -147,19 +143,33 @@ fn main() {
|
|||||||
}
|
}
|
||||||
let first = route.first().unwrap();
|
let first = route.first().unwrap();
|
||||||
let last = route.last().unwrap();
|
let last = route.last().unwrap();
|
||||||
let points = vec![(house, "red"), (first.bus.translate(0.0.into(), best_delay), "yellow"), (last.bus, "orange")];
|
let points = vec![
|
||||||
let lines = route.iter().map(|x| x.pos).collect::<LineString>().lines().map(|x| {
|
(house, "red"),
|
||||||
(x, "gray")
|
(first.bus.translate(0.0.into(), best_delay), "yellow"),
|
||||||
}).collect::<Vec<_>>();
|
(last.bus, "orange"),
|
||||||
|
];
|
||||||
display::dump_svg(&points, &lines, &polys, &route.iter().map(|x| x.pos).collect::<Vec<_>>(), first.bus.translate(0.0.into(), best_delay));
|
let lines = route
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.pos)
|
||||||
|
.collect::<LineString>()
|
||||||
|
.lines()
|
||||||
|
.map(|x| (x, "gray"))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
display::dump_svg(
|
||||||
|
&points,
|
||||||
|
&lines,
|
||||||
|
&polys,
|
||||||
|
&route.iter().map(|x| x.pos).collect::<Vec<_>>(),
|
||||||
|
first.bus.translate(0.0.into(), best_delay),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [a; b]
|
/// [a; b]
|
||||||
fn float_range(a: f32, b: f32) -> impl Iterator<Item = f32> {
|
fn float_range(a: f32, b: f32) -> impl Iterator<Item = f32> {
|
||||||
const STEPS: usize = 25;
|
const STEPS: usize = 25;
|
||||||
let d = b - a;
|
let d = b - a;
|
||||||
(0..=STEPS).map(move |s| a + ((s as f32) * d)/STEPS as f32)
|
(0..=STEPS).map(move |s| a + ((s as f32) * d) / STEPS as f32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn none_intersect(polys: &[Polygon], line: &Line) -> bool {
|
fn none_intersect(polys: &[Polygon], line: &Line) -> bool {
|
||||||
@ -178,12 +188,21 @@ fn none_intersect(polys: &[Polygon], line: &Line) -> bool {
|
|||||||
middle.y += line.dy() / 2.0;
|
middle.y += line.dy() / 2.0;
|
||||||
let middle: Point = middle.into();
|
let middle: Point = middle.into();
|
||||||
'poly: for p in polys {
|
'poly: for p in polys {
|
||||||
for l in p.exterior.lines().chain(vec![Line::new(p.exterior.0[0], *p.exterior.0.last().unwrap())]) {
|
for l in p.exterior.lines().chain(vec![Line::new(
|
||||||
if (l.start == line.start && l.end == line.end) || (l.start == line.end && l.end == line.start) {
|
p.exterior.0[0],
|
||||||
|
*p.exterior.0.last().unwrap(),
|
||||||
|
)]) {
|
||||||
|
if (l.start == line.start && l.end == line.end)
|
||||||
|
|| (l.start == line.end && l.end == line.start)
|
||||||
|
{
|
||||||
// point is on polygon border
|
// point is on polygon border
|
||||||
continue 'poly;
|
continue 'poly;
|
||||||
}
|
}
|
||||||
if l.start == line.start || l.end == line.end || l.start == line.end || l.end == line.start {
|
if l.start == line.start
|
||||||
|
|| l.end == line.end
|
||||||
|
|| l.start == line.end
|
||||||
|
|| l.end == line.start
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
if line.end.x > 0.0 {
|
if line.end.x > 0.0 {
|
||||||
eprintln!("skipping {:?}", l);
|
eprintln!("skipping {:?}", l);
|
||||||
@ -238,7 +257,8 @@ fn to_bus(bus: Point, start: Point) -> Vec<Point> {
|
|||||||
let c = bus.x();
|
let c = bus.x();
|
||||||
let d = bus.y();
|
let d = bus.y();
|
||||||
|
|
||||||
let v = -a.powi(2) * (3.0) + (6.0) * a * c + b.powi(2) - (2.0) * b * d - (3.0) * c.powi(2) + d.powi(2);
|
let v = -a.powi(2) * (3.0) + (6.0) * a * c + b.powi(2) - (2.0) * b * d - (3.0) * c.powi(2)
|
||||||
|
+ d.powi(2);
|
||||||
if v >= 0.0 {
|
if v >= 0.0 {
|
||||||
// v = sqrt(-3 A^2 + 6 A C + B^2 - 2 B D - 3 C^2 + D^2)
|
// v = sqrt(-3 A^2 + 6 A C + B^2 - 2 B D - 3 C^2 + D^2)
|
||||||
let v = v.sqrt();
|
let v = v.sqrt();
|
||||||
@ -246,18 +266,49 @@ fn to_bus(bus: Point, start: Point) -> Vec<Point> {
|
|||||||
let x1 = (v + 2.0 * b - 2.0 * d) / 3.0;
|
let x1 = (v + 2.0 * b - 2.0 * d) / 3.0;
|
||||||
let x2 = (-v + 2.0 * b - 2.0 * d) / 3.0;
|
let x2 = (-v + 2.0 * b - 2.0 * d) / 3.0;
|
||||||
if x1 > (0.0) && x2 > (0.0) {
|
if x1 > (0.0) && x2 > (0.0) {
|
||||||
vec![bus.translate(0.0, (2.0) * x1), bus.translate(0.0, (2.0) * x2)]
|
vec![
|
||||||
|
bus.translate(0.0, (2.0) * x1),
|
||||||
|
bus.translate(0.0, (2.0) * x2),
|
||||||
|
]
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_to_bus() {
|
fn test_to_bus() {
|
||||||
assert!(to_bus(Coordinate { x: 0.0.into(), y: 0.0.into() }.into(), Coordinate { x: 1.0.into(), y: 23.0.into() }.into()).len() == 2);
|
assert!(
|
||||||
assert_eq!(to_bus(Coordinate { x: 0.0.into(), y: 168.7601848778319.into() }.into(), Coordinate { x: 1.0.into(), y: 23.0.into() }.into()), vec![]);
|
to_bus(
|
||||||
}
|
Coordinate {
|
||||||
|
x: 0.0.into(),
|
||||||
|
y: 0.0.into()
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
Coordinate {
|
||||||
|
x: 1.0.into(),
|
||||||
|
y: 23.0.into()
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
)
|
||||||
|
.len() == 2
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
to_bus(
|
||||||
|
Coordinate {
|
||||||
|
x: 0.0.into(),
|
||||||
|
y: 168.7601848778319.into()
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
Coordinate {
|
||||||
|
x: 1.0.into(),
|
||||||
|
y: 23.0.into()
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
),
|
||||||
|
vec![]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user