69 void addNode(
const T &node) { nodes_.push_back(node); }
75 void addEdge(
const U &edge) { edges_.push_back(edge); }
98 auto f = edge.getFrom().getPosition();
99 auto t = edge.getTo().getPosition();
101 if (isDuplicate(f, t))
104 if (crossesAnyEdge(f, t))
107 edges_.push_back(edge);
124 std::vector<T> nodes_;
125 std::vector<U> edges_;
138 static long long orient(
const std::pair<int, int> &A,
139 const std::pair<int, int> &B,
140 const std::pair<int, int> &C) {
141 return static_cast<long long>(B.first - A.first) * (C.second - A.second) -
142 static_cast<long long>(B.second - A.second) * (C.first - A.first);
153 static bool onSegment(
const std::pair<int, int> &A,
154 const std::pair<int, int> &B,
155 const std::pair<int, int> &C) {
156 return std::min(A.first, B.first) <= C.first &&
157 C.first <= std::max(A.first, B.first) &&
158 std::min(A.second, B.second) <= C.second &&
159 C.second <= std::max(A.second, B.second);
170 bool isDuplicate(
const std::pair<int, int> &f,
171 const std::pair<int, int> &t)
const {
172 return std::any_of(edges_.begin(), edges_.end(), [&](
auto const &e) {
173 auto p = e.getFrom().getPosition();
174 auto q = e.getTo().getPosition();
175 return (p == f) && (q == t);
190 bool segmentCrosses(
const std::pair<int, int> &f,
191 const std::pair<int, int> &t,
192 const std::pair<int, int> &q1,
193 const std::pair<int, int> &q2)
const {
194 if (q1 == f || q1 == t || q2 == f || q2 == t)
197 long long o1 = orient(f, t, q1);
198 long long o2 = orient(f, t, q2);
199 long long o3 = orient(q1, q2, f);
200 long long o4 = orient(q1, q2, t);
202 if (((o1 > 0 && o2 < 0) || (o1 < 0 && o2 > 0)) &&
203 ((o3 > 0 && o4 < 0) || (o3 < 0 && o4 > 0)))
206 if (o1 == 0 && onSegment(f, t, q1))
208 if (o2 == 0 && onSegment(f, t, q2))
210 if (o3 == 0 && onSegment(q1, q2, f))
212 if (o4 == 0 && onSegment(q1, q2, t))
225 bool crossesAnyEdge(
const std::pair<int, int> &f,
226 const std::pair<int, int> &t)
const {
227 return std::any_of(edges_.begin(), edges_.end(), [&](
auto const &e) {
228 auto q1 = e.getFrom().getPosition();
229 auto q2 = e.getTo().getPosition();
230 return segmentCrosses(f, t, q1, q2);