Пример #1
0
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;
}
Пример #3
0
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);
}
Пример #4
0
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;
}