第六节 圆

圆类

Circle getCircle(pt A, pt B, pt C)
三点确定一个圆
Circle minCover(vector<pt> &p)
求点集 p 的最小圆覆盖
db SPICA(Circle C, vector<pt> &p)
求圆 C 和多边形 p 的面积交

struct Circle {
    pt o; db r;
    Circle() {}
    Circle(pt o, db r) : o(o), r(r) {}
    Circle(db x, db y, db r) : o(pt(x, y)), r(r) {}
    db area() {
        return pi * r * r;
    }
};

Circle getCircle(pt A, pt B, pt C) {
    pt p1 = (A + B) / 2.0, p2 = (B + C) / 2.0;
    pt p3 = rotate_point(A - p1, pi / 2) + p1;
    pt p4 = rotate_point(C - p2, pi / 2) + p2;
    pt o; line_make_pt(line(p1, p3), line(p2, p4), o);
    return Circle(o, (o - A).norm());
}

Circle minCover(vector<pt> &p) {
    size_t n = p.size();
    auto shuffle = [&](vector<pt> &v) {
        for (int i = 1; i < n; i++) {
            swap(v[i], v[rand() % n]);
        }
    };
    auto PIC = [&](Circle &C, pt &p) -> bool {
        return cmp((p - C.o).norm() - C.r) <= 0;
    };
    shuffle(p);
    Circle C = Circle(p[0], 0);
    for (int i = 1; i < n; i++) if (!PIC(C, p[i])) {
        C = Circle(p[i], 0);
        for (int j = 0; j < i; j++) if (!PIC(C, p[j])) {
            C.o = (p[i] + p[j]) * 0.5;
            C.r = (p[j] - C.o).norm();
            for (int k = 0; k < j; k++) if (!PIC(C, p[k])) {
                C = getCircle(p[i], p[j], p[k]);
            }
        }
    }
    return C;
}

db LineCrossCircle(const line &l, const Circle &C, pt &p1, pt &p2) {
    pt a = l.a, b = l.b;
    pt r = C.o; db R = C.r;
    pt fp;
    line_make_pt(line(r, pt(r.x + a.y - b.y, r.y + b.x - a.x)), l, fp);
    db rtol = dis(r, fp), atob = dis(a, b);
    db rtos = pt_on_seg(fp, a, b) ? rtol : min(dis(r, a), dis(r, b));
    db fptoe = sqrt(sqr(R) - sqr(rtol)) / atob;
    if (cmp(R - rtos) <= 0) return rtos;
    p1 = fp + (a - b) * fptoe;
    p2 = fp + (b - a) * fptoe;
    return rtos;
}

db SectorArea(const pt &o, const pt &a, const pt &b, double R) {
//不大于180度扇形面积,o->a->b逆时针
    db A2 = sqr(dis(o, a)), B2 = sqr(dis(o, b)), C2 = sqr(dis(a, b));
    return sqr(R) * acos((A2 + B2 - C2) / 2 / sqrt(A2) / sqrt(B2)) / 2;
}

double TACIA(Circle &C, pt &a, pt &b) {
// TriangleAndCircleIntersectArea,逆时针,r为圆心
    pt r = C.o; db R = C.r;
    db adis = dis(r, a), bdis = dis(r, b);
    if (cmp(adis - R) <= 0 && cmp(bdis - R) <= 0) {
        return det(a - r, b - r) / 2;
    }
    pt ta, tb;
    if (pt_on_seg(r, a, b)) return 0.0;
    db rtos = LineCrossCircle(line(a, b), Circle(r, R), ta, tb);
    if (cmp(rtos - R) >= 0) return SectorArea(r, a, b, R);
    db S1 = SectorArea(r, tb, b, R), S2 = SectorArea(r, a, ta, R);
    if (cmp(adis - R) <= 0) return det(a - r, tb - r) / 2 + S1;
    if (cmp(bdis - R) <= 0) return det(ta - r, b - r) / 2 + S2;
    return det(ta - r, tb - r) / 2 + S2 + S1;
}


db SPICA(Circle C, vector<pt> &p) {
// SimplePolygonIntersectCircleArea
    size_t n = p.size();
    db res = 0;
    for (int i = 0; i < n; i++) {
        int flag = cmp(det(p[i] - C.o, p[nex(i)] - C.o));
        if (flag < 0) res -= TACIA(C, p[nex(i)], p[i]);
        else res += TACIA(C, p[i], p[nex(i)]);
    }
    return fabs(res);
}

int main(int argc, const char * argv[]) {
    int n; db r;
    while (~scanf("%lf", &r)) {
        scanf("%d", &n);
        vector<pt> p(n);
        for (int i = 0; i < n; i++) p[i].input();
        printf("%.2f\n", SPICA(Circle(0, 0, r), p));
    }
    return 0;
}

圆的面积并

SP8073 CIRU

#include <bits/stdc++.h>
using namespace std;
typedef double db;
const int N = 1005;
const db eps = 1e-5;
typedef db func(db);
int n;

struct Circle {
    db x, y, r;
    bool operator < (const Circle &a) const {
        return r < a.r;
    }
}c[N];

struct Line {
    db l, r;
    bool operator < (const Line &a) const {
        return l < a.l;
    }
}seg[N];

db sqr(db x) {
    return x * x;
}

map<db, db> ma;
db f(db x) {
    if (ma[x]) return ma[x];
    static Line l[N]; int tot = 0;
    for (int i = 1; i <= n; i++) {
        db delta = sqr(c[i].r) - sqr(c[i].x - x);
        if (delta < eps) continue;
        delta = sqrt(delta);
        l[++tot] = Line{c[i].y - delta, c[i].y + delta};
    }
    sort(l + 1, l + 1 + tot);
    db res = 0, lst = -1e9;
    for (int i = 1; i <= tot; i++) {
        const Line &now = l[i];
        if (now.l > lst) {
            res += now.r - now.l; lst = now.r;
        }
        else if (now.r > lst) {
            res += now.r - lst; lst = now.r;
        }
    }
    return ma[x] = res;
}

db simpson(db l, db r, func f) {
    db mid = (l + r) / 2;
    return (f(l) + 4 * f(mid) + f(r)) * (r - l) / 6;
}
db asr(db l, db r, db eps, db A, func f) {
    db mid = (l + r) / 2;
    db L = simpson(l, mid, f), R = simpson(mid, r, f);
    if (fabs(L + R - A) <= 15 * eps) return L + R + (L + R - A) / 15;
    return asr(l, mid, eps / 2, L, f) + asr(mid, r, eps / 2, R, f);
}
db asr(db l, db r, db eps, func f) {
    return asr(l, r, eps, simpson(l, r, f), f);
}

int main(int argc, const char * argv[]) {
    scanf("%d", &n);
    db l = 1e15, r = -1e15;
    for (int i = 1; i <= n; i++) {
        scanf("%lf%lf%lf", &c[i].x, &c[i].y, &c[i].r);
        l = min(l, c[i].x - c[i].r);
        r = max(r, c[i].x + c[i].r);
    }

    sort(c + 1, c + 1 + n);
    int tmp = 0;
    for (int i = 1; i <= n; i++) {
        int flag = 1;
        for (int j = i + 1; j <= n; j++) {
            if (sqr(c[i].x - c[j].x) + sqr(c[i].y - c[j].y) <= sqr(c[j].r - c[i].r)) {
                flag = 0; break;
            }
        }
        if (flag) c[++tmp] = c[i];
    }
    n = tmp;

    for (int i = 1; i <= n; i++) {
        seg[i] = Line{c[i].x - c[i].r, c[i].x + c[i].r};
    }
    sort(seg + 1, seg + 1 + n);
    db res = 0, lst = -1e9;
    for (int i = 1; i <= n; i++) {
        const Line &now = seg[i];
        if (now.l > lst) {
            res += asr(now.l, now.r, eps, f); lst = now.r;
        }
        else if (now.r > lst) {
            res += asr(lst, now.r, eps, f); lst = now.r;
        }
    }
    printf("%.3f\n", res);
    return 0;
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇