簡單多邊形與圓相交模板

來源:互聯網
上載者:User

分5種情況,模板轉載自:http://hi.baidu.com/billdu/item/703ad4e15d819db52f140b0b

題目大意:給你個簡單多邊形,和一個圓心在原點處的圓,求這個多邊形與圓的重合部分的面積。

也就是這個意思了……

但是這看上去也太噁心了,怎麼辦?其實想一想就知道,我們平日求多邊形面積用的就是三角形剖分,所以說我們應該化繁為簡,通過求出來各三角形與圓的交,從而求出總面積。而且,剖分用的原點正好在圓心,這是很方便的一件事情。

現在問題就轉化成一個頂點在圓心的三角形了。但是這才是麻煩的開始,除去退化情況,我們應該至少考慮到以下五種情況:

(一)三角形的兩條邊全部短於半徑。

最方便了,不是嗎?

(二)三角形的兩條邊全部長於半徑,且另一條邊與圓心的距離也長於半徑。

只需要求出扇形的面積即可。

(三)三角形的兩條邊全部長於半徑,但另一條邊與圓心的距離短於半徑,並且垂足落在這條邊上。

求出扇形的面積,再減去那個弓形的面積。也就是說再挖去一個扇形,補上一個三角形。

(四)三角形的兩條邊全部長於半徑,但另一條邊與圓心的距離短於半徑,且垂足未落在這條邊上。

與上一個很像……一開始我就在這裡WA了很長時間。事實上只需求一個扇形。

(五)三角形的兩條邊一條長於半徑,另外一條短於半徑。

先求出交點,再剖成扇形和三角形求解。

 

代碼:HDU 4404

View Code

#include <iostream>#include <cstdio>#include <cmath>#include <vector>#include <cstring>#include <algorithm>#include <string>#include <set>#include <functional>#include <numeric>#include <sstream>#include <stack>#define CL(arr, val) memset(arr, val, sizeof(arr))#define REP(i, n)for((i) = 0; (i) < (n); ++(i))#define FOR(i, l, h)for((i) = (l); (i) <= (h); ++(i))#define FORD(i, h, l)for((i) = (h); (i) >= (l); --(i))#define L(x)(x) << 1#define R(x)(x) << 1 | 1#define MID(l, r)(l + r) >> 1#define Min(x, y)x < y ? x : y#define Max(x, y)x < y ? y : x#define E(x)(1 << (x))#define iabs(x) (x) < 0 ? -(x) : (x)#define OUT(x)printf("%I64d\n", x)#define lowbit(x)(x)&(-x)#define Read()freopen("data.in", "r", stdin)#define Write()freopen("data.out", "w", stdout);const double eps = 1e-10;typedef long long LL;const int inf = ~0u>>2;using namespace std;inline double max (double a, double b) { if (a > b) return a; else return b; }inline double min (double a, double b) { if (a < b) return a; else return b; }inline int fi (double a){    if (a > eps) return 1;    else if (a >= -eps) return 0;    else return -1;}class Vector{public:    double x, y;    Vector (void) {}    Vector (double x0, double y0) : x(x0), y(y0) {}    double operator * (const Vector& a) const { return x * a.y - y * a.x; }    double operator % (const Vector& a) const { return x * a.x + y * a.y; }    Vector verti (void) const { return Vector(-y, x); }    double length (void) const { return sqrt(x * x + y * y); }    Vector adjust (double len)    {        double ol = len / length();        return Vector(x * ol, y * ol);    }    Vector oppose (void) { return Vector(-x, -y); }};class point{public:    double x, y;    point (void) {}    point (double x0, double y0) : x(x0), y(y0) {}    Vector operator - (const point& a) const { return Vector(x - a.x, y - a.y); }    point operator + (const Vector& a) const { return point(x + a.x, y + a.y); }};class segment{public:    point a, b;    segment (void) {}    segment (point a0, point b0) : a(a0), b(b0) {}    point intersect (const segment& s) const    {        Vector v1 = s.a - a, v2 = s.b - a, v3 = s.b - b, v4 = s.a - b;        double s1 = v1 * v2, s2 = v3 * v4;        double se = s1 + s2;        s1 /= se, s2 /= se;        return point(a.x * s2 + b.x * s1, a.y * s2 + b.y * s1);    }    point pverti (const point& p) const    {        Vector t = (b - a).verti();        segment uv(p, p + t);        return intersect(uv);    }    bool on_segment (const point& p) const    {        if (fi(min(a.x, b.x) - p.x) <= 0 && fi(p.x - max(a.x, b.x)) <= 0 &&            fi(min(a.y, b.y) - p.y) <= 0 && fi(p.y - max(a.y, b.y)) <= 0) return true;        else return false;    }};double radius;point polygon[110];double kuras_area (point a, point b, double cx, double cy){    point ori(cx, cy);    int sgn = fi((b - ori) * (a - ori));    double da = (a - ori).length(), db = (b - ori).length();    int ra = fi(da - radius), rb = fi(db - radius);    double angle = acos(((b - ori) % (a - ori)) / (da * db));    segment t(a, b); point h, u; Vector seg;    double ans, dlt, mov, tangle;    if (fi(da) == 0 || fi(db) == 0) return 0;    else if (sgn == 0) return 0;    else if (ra <= 0 && rb <= 0) return fabs((b - ori) * (a - ori)) / 2 * sgn;    else if (ra >= 0 && rb >= 0)    {        h = t.pverti(ori);        dlt = (h - ori).length();        if (!t.on_segment(h) || fi(dlt - radius) >= 0)            return radius * radius * (angle / 2) * sgn;        else        {            ans = radius * radius * (angle / 2);            tangle = acos(dlt / radius);            ans -= radius * radius * tangle;            ans += radius * sin(tangle) * dlt;            return ans * sgn;        }    }    else    {        h = t.pverti(ori);        dlt = (h - ori).length();        seg = b - a;        mov = sqrt(radius * radius - dlt * dlt);        seg = seg.adjust(mov);        if (t.on_segment(h + seg)) u = h + seg;        else u = h + seg.oppose();        if (ra == 1) swap(a, b);        ans = fabs((a - ori) * (u - ori)) / 2;        tangle = acos(((u - ori) % (b - ori)) / ((u - ori).length() * (b - ori).length()));        ans += radius * radius * (tangle / 2);        return ans * sgn;    }}const double pi = acos(-1.0);int main (){    //freopen("data.in", "r", stdin);    int n;    double area, x, y, cx, cy;    double x0, y0, v0, th, t, g;    double vx, vy;    while(~scanf("%lf%lf%lf%lf%lf%lf%lf", &x0, &y0, &v0, &th, &t, &g, &radius)) {        if(x0 == 0 && y0 == 0 && v0 == 0 && th == 0 && t == 0 && g == 0 && radius == 0)  break;        vx = v0*cos(pi*th/180.0); vy = v0*sin(pi*th/180.0);        cx = x0 + vx*t;        cy = y0 + (vy*t - 0.5*g*t*t);        scanf("%d", &n);        for(int i = 0; i < n; ++i) {            scanf("%lf%lf", &x, &y);            polygon[i] = point(x, y);        }        area = 0;        for (int i = 0; i < n; i++)            area += kuras_area(polygon[i], polygon[(i + 1) % n], cx, cy);        printf("%.2f\n", fabs(area));    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.