Antipodal Points
An iterator that yields every antipodal pairs.
struct Antipodes<T> {
i: usize,
p: T,
q: T,
p1: T,
q1: T,
}
impl<'a, T> Iterator for Antipodes<std::iter::Peekable<T>>
where
T: Iterator<Item = &'a (i32, i32)> + Clone,
{
type Item = ((i32, i32), (i32, i32));
fn next(&mut self) -> Option<Self::Item> {
if self.i == 0 {
return None;
}
self.i -= 1;
let p = **self.p.peek()?;
let p1 = **self.p1.peek()?;
let q = **self.q.peek()?;
let q1 = **self.q1.peek()?;
if cross(p, p1, q) < cross(p, p1, q1) {
self.q = self.q1.clone();
Some((**self.p.peek()?, *self.q1.next()?))
} else {
self.p = self.p1.clone();
Some((*self.p1.next()?, **self.q.peek()?))
}
}
}
impl<'a> Antipodes<std::iter::Peekable<std::iter::Cycle<std::slice::Iter<'a, (i32, i32)>>>> {
fn from_hull(hull: &'a [(i32, i32)]) -> Self {
let mut base = hull.iter().cycle().peekable();
let mut p = base.clone();
base.next();
let mut p1 = base.clone();
let mut q = base.clone();
base.next();
let mut q1 = base;
let pp = **p.peek().unwrap();
let pp1 = **p1.peek().unwrap();
while cross(pp, pp1, **q.peek().unwrap()) < cross(pp, pp1, **q1.peek().unwrap()) {
q = q1.clone();
q1.next();
}
let i = hull.len();
Self { i, p, p1, q, q1 }
}
}
// Less => cw
// Greater => ccw
fn turn(a: (i32, i32), b: (i32, i32), c: (i32, i32)) -> std::cmp::Ordering {
cross(a, b, c).cmp(&0)
}
fn cross((ax, ay): (i32, i32), (bx, by): (i32, i32), (cx, cy): (i32, i32)) -> i64 {
let abx = (bx - ax) as i64;
let aby = (by - ay) as i64;
let bcx = (cx - bx) as i64;
let bcy = (cy - by) as i64;
abx * bcy - aby * bcx
}