/rust/registry/src/index.crates.io-1949cf8c6b5b557f/i_float-1.15.0/src/triangle.rs
Line | Count | Source |
1 | | use core::cmp::Ordering; |
2 | | use crate::fix_float::FixFloat; |
3 | | use crate::fix_vec::FixVec; |
4 | | use crate::int::point::IntPoint; |
5 | | |
6 | | pub struct Triangle; |
7 | | |
8 | | impl Triangle { |
9 | | #[inline(always)] |
10 | | pub fn area_two(p0: FixVec, p1: FixVec, p2: FixVec) -> i64 { |
11 | | (p1 - p0).cross_product(p1 - p2) |
12 | | } |
13 | | |
14 | | #[inline(always)] |
15 | | pub fn area(p0: FixVec, p1: FixVec, p2: FixVec) -> i64 { |
16 | | Self::area_two(p0, p1, p2) / 2 |
17 | | } |
18 | | |
19 | | #[inline(always)] |
20 | | pub fn fix_area(p0: FixVec, p1: FixVec, p2: FixVec) -> FixFloat { |
21 | | (p1 - p0).fix_cross_product(p1 - p2) / 2 |
22 | | } |
23 | | |
24 | | #[inline(always)] |
25 | | pub fn is_clockwise(p0: FixVec, p1: FixVec, p2: FixVec) -> bool { |
26 | | Self::area_two(p0, p1, p2) > 0 |
27 | | } |
28 | | |
29 | | #[inline(always)] |
30 | | pub fn is_cw_or_line(p0: FixVec, p1: FixVec, p2: FixVec) -> bool { |
31 | | Self::area_two(p0, p1, p2) >= 0 |
32 | | } |
33 | | |
34 | | #[inline(always)] |
35 | | pub fn is_not_line(p0: FixVec, p1: FixVec, p2: FixVec) -> bool { |
36 | | Self::area_two(p0, p1, p2) != 0 |
37 | | } |
38 | | |
39 | | #[inline(always)] |
40 | | pub fn is_line(p0: FixVec, p1: FixVec, p2: FixVec) -> bool { |
41 | | Self::area_two(p0, p1, p2) == 0 |
42 | | } |
43 | | |
44 | | #[inline(always)] |
45 | | pub fn clock_direction(p0: FixVec, p1: FixVec, p2: FixVec) -> i64 { |
46 | | Self::area_two(p0, p1, p2).signum() |
47 | | } |
48 | | |
49 | | #[inline] |
50 | | pub fn is_contain(p: FixVec, p0: FixVec, p1: FixVec, p2: FixVec) -> bool { |
51 | | let q0 = (p - p1).cross_product(p0 - p1); |
52 | | let q1 = (p - p2).cross_product(p1 - p2); |
53 | | let q2 = (p - p0).cross_product(p2 - p0); |
54 | | |
55 | | let has_neg = q0 < 0 || q1 < 0 || q2 < 0; |
56 | | let has_pos = q0 > 0 || q1 > 0 || q2 > 0; |
57 | | |
58 | | !(has_neg && has_pos) |
59 | | } |
60 | | |
61 | | #[inline] |
62 | | pub fn is_not_contain(p: FixVec, p0: FixVec, p1: FixVec, p2: FixVec) -> bool { |
63 | | let q0 = (p - p1).cross_product(p0 - p1); |
64 | | let q1 = (p - p2).cross_product(p1 - p2); |
65 | | let q2 = (p - p0).cross_product(p2 - p0); |
66 | | |
67 | | let has_neg = q0 <= 0 || q1 <= 0 || q2 <= 0; |
68 | | let has_pos = q0 >= 0 || q1 >= 0 || q2 >= 0; |
69 | | |
70 | | has_neg && has_pos |
71 | | } |
72 | | |
73 | | #[inline(always)] |
74 | 0 | pub fn area_two_point(p0: IntPoint, p1: IntPoint, p2: IntPoint) -> i64 { |
75 | 0 | let x0 = p1.x as i64 - p0.x as i64; |
76 | 0 | let y0 = p1.y as i64 - p0.y as i64; |
77 | | |
78 | 0 | let x1 = p1.x as i64 - p2.x as i64; |
79 | 0 | let y1 = p1.y as i64 - p2.y as i64; |
80 | | |
81 | 0 | x0 * y1 - x1 * y0 |
82 | 0 | } |
83 | | |
84 | | #[inline(always)] |
85 | 0 | pub fn is_clockwise_point(p0: IntPoint, p1: IntPoint, p2: IntPoint) -> bool { |
86 | 0 | Self::area_two_point(p0, p1, p2) > 0 |
87 | 0 | } |
88 | | |
89 | | #[inline(always)] |
90 | | pub fn is_cw_or_line_point(p0: IntPoint, p1: IntPoint, p2: IntPoint) -> bool { |
91 | | Self::area_two_point(p0, p1, p2) >= 0 |
92 | | } |
93 | | |
94 | | #[inline(always)] |
95 | 0 | pub fn is_line_point(p0: IntPoint, p1: IntPoint, p2: IntPoint) -> bool { |
96 | 0 | Self::area_two_point(p0, p1, p2) == 0 |
97 | 0 | } |
98 | | |
99 | | #[inline(always)] |
100 | 0 | pub fn is_not_line_point(p0: IntPoint, p1: IntPoint, p2: IntPoint) -> bool { |
101 | 0 | Self::area_two_point(p0, p1, p2) != 0 |
102 | 0 | } |
103 | | |
104 | | #[inline(always)] |
105 | 0 | pub fn clock_direction_point(p0: IntPoint, p1: IntPoint, p2: IntPoint) -> i64 { |
106 | 0 | Self::area_two_point(p0, p1, p2).signum() |
107 | 0 | } |
108 | | |
109 | | #[inline] |
110 | | pub fn is_contain_point(p: IntPoint, p0: IntPoint, p1: IntPoint, p2: IntPoint) -> bool { |
111 | | let f = FixVec::new_point(p); |
112 | | let f0 = FixVec::new_point(p0); |
113 | | let f1 = FixVec::new_point(p1); |
114 | | let f2 = FixVec::new_point(p2); |
115 | | |
116 | | let q0 = (f - f1).cross_product(f0 - f1); |
117 | | let q1 = (f - f2).cross_product(f1 - f2); |
118 | | let q2 = (f - f0).cross_product(f2 - f0); |
119 | | |
120 | | let has_neg = q0 < 0 || q1 < 0 || q2 < 0; |
121 | | let has_pos = q0 > 0 || q1 > 0 || q2 > 0; |
122 | | |
123 | | !(has_neg && has_pos) |
124 | | } |
125 | | |
126 | | #[inline] |
127 | | pub fn is_contain_point_exclude_borders(p: IntPoint, p0: IntPoint, p1: IntPoint, p2: IntPoint) -> bool { |
128 | | let f = FixVec::new_point(p); |
129 | | let f0 = FixVec::new_point(p0); |
130 | | let f1 = FixVec::new_point(p1); |
131 | | let f2 = FixVec::new_point(p2); |
132 | | |
133 | | let q0 = (f - f1).cross_product(f0 - f1); |
134 | | let q1 = (f - f2).cross_product(f1 - f2); |
135 | | let q2 = (f - f0).cross_product(f2 - f0); |
136 | | |
137 | | let has_neg = q0 < 0 || q1 < 0 || q2 < 0; |
138 | | let has_pos = q0 > 0 || q1 > 0 || q2 > 0; |
139 | | |
140 | | !(has_neg && has_pos) && q0 != 0 && q1 != 0 && q2 != 0 |
141 | | } |
142 | | |
143 | | #[inline] |
144 | | pub fn is_not_contain_point(p: IntPoint, p0: IntPoint, p1: IntPoint, p2: IntPoint) -> bool { |
145 | | let f = FixVec::new_point(p); |
146 | | let f0 = FixVec::new_point(p0); |
147 | | let f1 = FixVec::new_point(p1); |
148 | | let f2 = FixVec::new_point(p2); |
149 | | |
150 | | let q0 = (f - f1).cross_product(f0 - f1); |
151 | | let q1 = (f - f2).cross_product(f1 - f2); |
152 | | let q2 = (f - f0).cross_product(f2 - f0); |
153 | | |
154 | | let has_neg = q0 <= 0 || q1 <= 0 || q2 <= 0; |
155 | | let has_pos = q0 >= 0 || q1 >= 0 || q2 >= 0; |
156 | | |
157 | | has_neg && has_pos |
158 | | } |
159 | | |
160 | | #[inline(always)] |
161 | 0 | pub fn clock_order_point(p0: IntPoint, p1: IntPoint, p2: IntPoint) -> Ordering { |
162 | 0 | 0.cmp(&Self::area_two_point(p0, p1, p2)) |
163 | 0 | } |
164 | | } |