geo.2d.ccw

geo.2d.ccw.rs

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum CCW {
    FRONT, BACK, RIGHT, LEFT, ON
}

fn ccw(l: Line, p: Point) -> CCW {
    use CCW::*;
    fn equal(x: f64, y: f64) -> bool { (x - y).abs() < 0.00001 }
    let dif = p - l.0;
    let dir = l.1 - l.0;
    if equal(0.0, dir.0) {
        if equal(0.0, dif.0) {
            let k = dif.1 / dir.1;
            if k > 1.0 { FRONT }
            else if k < 0.0 { BACK }
            else { ON }
        } else if dir.det(dif) > 0.0 {
            LEFT
        } else {
            RIGHT
        }
    } else {
        let k = dif.0 / dir.0;
        if equal(dir.1 * k, dif.1) {
            if k > 1.0 { FRONT }
            else if k < 0.0 { BACK }
            else { ON }
        } else {
            if dir.det(dif) > 0.0 {
                LEFT
            } else {
                RIGHT
            }
        }
    }
}
fn main() {

    let p = Point(1.0, 2.0);
    let q = Point(2.0, 0.0);
    let l = Line(p, q);

    trace!(ccw(l, p)); // ON
    trace!(ccw(l, q)); // ON
    trace!(ccw(l, Point(1.5, 1.0))); // ON
    trace!(ccw(l, Point(3.0, -2.0))); // FRONT
    trace!(ccw(l, Point(0.0, 4.0))); // BACK
    trace!(ccw(l, Point(0.0, 0.0))); // RIGHT
    trace!(ccw(l, Point(10.0, 0.0))); // LEFT

}

geo.2d.ccw.cc

enum CCW {
  FRONT,
  BACK,
  RIGHT,
  LEFT,
  ON
};

CCW ccw(L&l, P&p) {
  P u = l[0];
  P v = l[1];

  P dif = p - u;
  P dir = v - u;

  if (eq(0, dir.first)) {
    if (eq(0, dif.first)) {
      Real k = dif.second / dir.second;
      if (k > 1.0) return FRONT;
      if (k < 0.0) return BACK;
      return ON;
    } else {
      if (det(dir, dif) > 0.0) {
        return LEFT;
      }
      return RIGHT;
    }
  }

  Real k = dif.first / dir.first;
  if (eq(dir.second * k, dif.second)) {
    if (k > 1.0) return FRONT;
    if (k < 0.0) return BACK;
    return ON;
  } else {
    if (det(dir, dif) > 0.0) {
      return LEFT;
    }
    return RIGHT;
  }
}