1use crate::geom::*;
7
8#[derive(Clone, Copy, Debug, PartialEq)]
10#[allow(non_camel_case_types)]
11pub enum CCW {
12 ONLINE_BACK,
14 COUNTER_CLOCKWISE,
16 ON_SEGMENT,
18 CLOCKWISE,
20 ONLINE_FRONT,
22}
23
24impl CCW {
25 pub fn online_back(self) -> bool {
27 self == Self::ONLINE_BACK
28 }
29 pub fn counter_clockwise(self) -> bool {
31 self == Self::COUNTER_CLOCKWISE
32 }
33 pub fn on_segment(self) -> bool {
35 self == Self::ON_SEGMENT
36 }
37 pub fn clockwise(self) -> bool {
39 self == Self::CLOCKWISE
40 }
41 pub fn online_front(self) -> bool {
43 self == Self::ONLINE_FRONT
44 }
45
46 pub fn to_value(self) -> i32 {
52 use self::CCW::*;
53 match self {
54 ONLINE_BACK | COUNTER_CLOCKWISE => -1,
55 ON_SEGMENT => 0,
56 CLOCKWISE | ONLINE_FRONT => 1,
57 }
58 }
59}
60
61pub fn ccw(p0: Vector, p1: Vector, p2: Vector, eps: Eps) -> CCW {
63 use self::CCW::*;
64 let cr = (p1 - p0).cross(p2 - p0);
65 let d = (p1 - p0).dot(p2 - p0);
66
67 if eps.eq(cr, 0.0) {
68 if eps.lt(d, 0.0) {
69 ONLINE_BACK
70 } else if eps.gt((p2 - p0).abs(), (p1 - p0).abs()) {
71 ONLINE_FRONT
72 } else {
73 ON_SEGMENT
74 }
75 } else if eps.gt(cr, 0.0) {
76 COUNTER_CLOCKWISE
77 } else {
78 CLOCKWISE
79 }
80}