long double area(polygon_t &polygon) { if (polygon.size() < 3) return 0; long positive_term = 0, negative_term = 0; for (unsigned i = 0; i < polygon.size() - 1; i++) { positive_term += polygon[i].first * polygon[i + 1].second; negative_term += polygon[i].second * polygon[i + 1].first; } positive_term += polygon.back().first * polygon[0].second; negative_term += polygon.back().second * polygon[0].first; return fabsl((positive_term - negative_term) / 2.0); }
polygon_t merge(const polygon_t &polygon1, const polygon_t &polygon2) { int i = 0; int j = 0; polygon_t merged; while (i < polygon1.size() | j < polygon2.size()) { if (POLAR_ORDER(polygon1[i], polygon2[j])) { merged.push_back(polygon1[i]); ++i; } else { merged.push_back(polygon2[j]); ++j; } } return merged; }
bool inside_polygon(polygon_t &polygon, point_t point) { if (polygon.size() == 0) return false; for (polygon_t::iterator p = polygon.begin(); p < polygon.end(); p++) if (*p == point) return true; if (polygon.size() == 1) return false; long double total_area = area(polygon); long double sub_area = 0; for (unsigned i = 0; i < polygon.size(); i++) { point_t a = point; point_t b = polygon[i]; point_t c = polygon[(i + 1) % polygon.size()]; sub_area += fabsl((a.first * b.second + b.first * c.second + c.first * a.second) - (a.second * b.first + b.second * c.first + c.second * a.first)) / 2.0; } return (fabsl(total_area - sub_area) < 1e-10L); }
long double minimum_enclosing_circle(polygon_t &convex_hull) { if (convex_hull.size() <= 1) return 0; if (convex_hull.size() == 2) return distance_square(convex_hull[0], convex_hull[1]) / 4.0; point_t s_a = convex_hull[0]; point_t s_b = convex_hull[1]; while (1) { long double alpha = 100; point_t v; for (polygon_t::iterator p = convex_hull.begin(); p != convex_hull.end(); p++) { if (*p == s_a || *p == s_b) continue; long double a = angle(*p, s_a, s_b); if (a < alpha) { alpha = a; v = *p; } } if (alpha >= M_PI / 2) return distance_square(s_a, s_b) / 4.0; // printf("s_a:(%ld, %ld) s_b:(%ld, %ld) v:(%ld, %ld)\n", s_a.first, s_a.second, s_b.first, s_b.second, v.first, v.second); // printf("angle v-s_a-s_b: %Lf\n", angle(s_a, v, s_b)); if (angle(s_a, v, s_b) >= M_PI / 2) { s_a = v; continue; } // printf("angle v-s_b-s_a: %Lf\n", angle(s_b, v, s_a)); if (angle(s_b, v, s_a) >= M_PI / 2) { s_b = v; continue; } /* v, s_a, s_b */ fpoint_t center = find_center(v, s_a, s_b); // printf("center: %Lf, %Lf\n", center.first, center.second); // printf("%Lf = %Lf, %Lf\n", distance_square(center, v), distance_square(center, s_a), distance_square(center, s_b)); return distance_square(center, v); } }
bool isInside(polygon_t polygon, point_t p) { auto n = polygon.size(); if (n < 3) return false; point_t extreme = {INF, p.second}; int count = 0, i = 0; do { int next = (i + 1) % n; if (doIntersect(polygon[i], polygon[next], p, extreme)) { if (orientation(polygon[i], p, polygon[next]) == 0) return onSegment(polygon[i], p, polygon[next]); count++; } i = next; } while (i != 0); return count & 1; }