简单几何(圆与多边形公共面积) UVALive 7072 Signal Interference (14广州D)

题目传送门

题意:一个多边形,A点和B点,满足PB <= k * PA的P的范围与多边形的公共面积。

分析:这是个阿波罗尼斯圆。既然是圆,那么设圆的一般方程:(x + D/2) ^ 2 + (y + E/2) ^ 2 = (D ^ 2 + E ^ 2 - 4 * F)  / 4,通过PB == PA * k解方程来求解圆心以及半径。然后就是套模板啦,上海交大的红书。

/************************************************
* Author        :Running_Time
* Created Time  :2015/11/9 星期一 11:51:27
* File Name     :D.cpp
 ************************************************/

#include <bits/stdc++.h>
using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 5e2 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-10;
const double PI = acos (-1.0);
int dcmp(double x)  {
    if (fabs (x) < EPS)   return 0;
    else    return x < 0 ? -1 : 1;
}
struct Point    {
    double x, y;
    Point ()    {}
    Point (double x, double y) : x (x), y (y) {}
    Point operator + (const Point &r) const {       //向量加法
        return Point (x + r.x, y + r.y);
    }
    Point operator - (const Point &r) const {
        return Point (x - r.x, y - r.y);
    }
    Point operator * (double p) const {       //向量乘以标量
        return Point (x * p, y * p);
    }
    Point operator / (double p) const {       //向量除以标量
        return Point (x / p, y / p);
    }
    bool operator < (const Point &r) const  {
        return x < r.x || (x == r.x && y < r.y);
    }
    bool operator == (const Point &r) const {
        return dcmp (x - r.x) == 0 && dcmp (y - r.y) == 0;
    }
};
typedef Point Vector;
Point read_point(void)  {
    double x, y;    scanf ("%lf%lf", &x, &y);
    return Point (x, y);
}
double polar_angle(Vector V)    {
    return atan2 (V.y, V.x);
}
double dot(Point a, Point b)    {
    return a.x * b.x + a.y * b.y;
}
double cross(Point a, Point b)  {
    return a.x * b.y - a.y * b.x;
}
double length(Vector V) {
    return sqrt (dot (V, V));
}
double my_sqrt(double x)    {
    return sqrt (max (0.0, x));
}

Point ps[N];
double r, k;
double x1, y1, x2, y2;
int n;

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

struct  Line    {
    Point p;
    Vector v;
    double r;
    Line () {}
    Line (const Point &p, const Vector &v) : p (p), v (v) {
        r = polar_angle (v);
    }
    Point point(double a)   {
        return p + v * a;
    }
};

struct Circle   {
    Point c;
    double r;
    Circle () {}
    Circle (Point c, double r) : c (c), r (r) {}
    Point point(double a)   {
        return Point (c.x + cos (a) * r, c.y + sin (a) * r);
    }
};

int line_cir_inter(Line L, Circle C, double &t1, double &t2, vector<Point> &P)    {
    double a = L.v.x, b = L.p.x - C.c.x, c = L.v.y, d = L.p.y - C.c.y;
    double e = a * a + c * c, f = 2 * (a * b + c * d), g = b * b + d * d - C.r * C.r;
    double delta = f * f - 4 * e * g;
    if (dcmp (delta) < 0)   return 0;
    if (dcmp (delta) == 0)  {
        t1 = t2 = -f / (2 * e); P.push_back (L.point (t1));
        return 1;
    }
    t1 = (-f - sqrt (delta)) / (2 * e);
    t2 = (-f + sqrt (delta)) / (2 * e);
    if (t1 > t2)    swap (t1, t2);
    if (dcmp (t1) > 0 && dcmp (t1 - 1) < 0) P.push_back (L.point (t1));
    if (dcmp (t2) > 0 && dcmp (t2 - 1) < 0) P.push_back (L.point (t2));
    return (int) P.size ();
}

double sector_area(Point a, Point b)    {
    double theta = polar_angle (a) - polar_angle (b);
    while (dcmp (theta) <= 0)   theta += 2 * PI;
    while (theta > 2 * PI)  theta -= 2 * PI;
    theta = min (theta, 2 * PI - theta);
    return r * r * theta / 2;
}

double cal(Point a, Point b)    {
    double t1, t2;
    bool ina = dcmp (length (a) - r) < 0;
    bool inb = dcmp (length (b) - r) < 0;
    if (ina && inb) return fabs (cross (a, b)) / 2.0;
    vector<Point> p;
    int num = line_cir_inter (Line (a, b - a), Circle (Point (0, 0), r), t1, t2, p);
    if (ina)    return sector_area (b, p[0]) + fabs (cross (a, p[0])) / 2.0;
    if (inb)    return sector_area (p[0], a) + fabs (cross (p[0], b)) / 2.0;
    if (num == 2)   return sector_area (a, p[0]) + sector_area (p[1], b) + fabs (cross (p[0], p[1])) / 2.0;
    return sector_area (a, b);
}

double cir_poly_area()  {
    double ret = 0;
    for (int i=0; i<n; ++i) {
        int sgn = dcmp (cross (ps[i], ps[i+1]));
        if (sgn != 0)   {
            ret += sgn * cal (ps[i], ps[i+1]);
        }
    }
    return ret;
}

void init(void) {
    double D = (2 * x2 - 2 * sqr (k) * x1) / (1 - sqr (k));
    double E = (2 * y2 - 2 * sqr (k) * y1) / (1 - sqr (k));
    double F = (sqr (k*x1)+sqr (k*y1)-sqr (x2)-sqr(y2)) / (1 - sqr (k));
    double x0 = D / 2, y0 = E / 2;
    r = sqrt (F + sqr (D)/4 + sqr (E)/4);
    for (int i=0; i<n; ++i) {
        ps[i].x -= x0;  ps[i].y -= y0;
    }
    ps[n] = ps[0];
}

int main(void)    {
    int cas = 0;
    while (scanf ("%d%lf", &n, &k) == 2)    {
        for (int i=0; i<n; ++i) {
            ps[i] = read_point ();
        }
        scanf ("%lf%lf", &x1, &y1);
        scanf ("%lf%lf", &x2, &y2);
        init ();
        printf ("Case %d: %.10f\n", ++cas, fabs (cir_poly_area ()));
    }

   //cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";

    return 0;
}

  

时间: 2024-10-13 06:21:51

简单几何(圆与多边形公共面积) UVALive 7072 Signal Interference (14广州D)的相关文章

[hihoCoder1231 2015BeijingOnline]求圆与多边形公共部分的周长

题意:如题 思路:离散.如果多边形与圆交点小于2个则说明它们的关系是包含关系,然后判断是谁包含谁并得到答案,否则将所有交点求出来,相当于将多变形的边切成了很多条元边,对每条元边,有两种情况 在圆内,答案加上此边长 在圆外,答案加上此边相对于圆心的"有向转弧" #include <bits/stdc++.h> using namespace std; #ifndef ONLINE_JUDGE #include "local.h" #endif #defin

hdu5130Signal Interference(圆与多边形相交面积模板)

#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include

HDU 3982 半平面交+圆与多边形面积交

Harry Potter and J.K.Rowling Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 685    Accepted Submission(s): 210 Problem Description In July 31st, last month, the author of the famous novel seri

bjfu1235 两圆公共面积

给定两个圆,求其覆盖的面积,其实也就是求其公共面积(然后用两圆面积和减去此值即得最后结果). 我一开始是用计算几何的方法做的,结果始终不过.代码如下: /* * Author : ben */ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <

Gym - 101208J 2013 ACM-ICPC World Finals J.Pollution Solution 圆与多边形面积交

题面 题意:给你一个半圆,和另一个多边形(可凹可凸),求面积交 题解:直接上板子,因为其实这个多边形不会穿过这个半圆,所以他和圆的交也就是和半圆的交 打的时候队友说凹的不行,不是板题,后面想想,圆与多边形面积交本来就是拆成有向三角形做的,所以无论凹凸了 1 #include<bits/stdc++.h> 2 #define inf 1000000000000 3 #define M 100009 4 #define eps 1e-12 5 #define PI acos(-1.0) 6 usi

poj 2546(两圆公共面积)

Circular Area Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5682   Accepted: 2225 Description Your task is to write a program, which, given two circles, calculates the area of their intersection with the accuracy of three digits after

HDU 4793 Collision + HDU 4798 Skycity 简单几何

HDU 4793 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4793 题意:给一个以(0,0)为圆心半径为R的圆形区域,中间放着一个(0,0)为圆心半径为Rm的圆盘,在坐标(x,y)处(严格在圆形区域外)放着一枚半径为r的硬币,运动方向和速度为(vx,vy),在运动中碰到圆盘时,会按碰撞问题反弹(圆盘是固定不动的),问硬币会在圆形区域里呆多长时间(硬币只要有一点点在圆形区域里就记为硬币在圆形区域内). 思路:首先先计算出硬币在移动过程中如果不与圆盘

Python下opencv使用笔记(二)(简单几何图像绘制)

简单几何图像一般包括点.直线.矩阵.圆.椭圆.多边形等等.首先认识一下opencv对像素点的定义.图像的一个像素点有1或者3个值,对灰度图像有一个灰度值,对彩色图像有3个值组成一个像素值,他们表现出不同的颜色. 那么有了点才能组成各种多边形. (一)首先绘制直线 函数为:cv2.line(img,Point pt1,Point pt2,color,thickness=1,line_type=8 shift=0) 有值的代表有默认值,不用给也行.可以看到这个函数主要接受参数为两个点的坐标,线的颜色

多边形的面积

目录 第1章多边形的面积    1 1.1 三角形面积    1 1.2 多边形面积    2 1.3 递推公式    3 1.4 精度评定    4 第2章坡面面积    6 2.1 坡面面积    6 2.2 模型验算    7 第1章多边形的面积 1.1 三角形面积 xy平面内,有三角形123,如下图所示: 图1.1 借助矢量叉积和点积,这个三角形的面积公式非常简单: 这个面积是有符号的:1.2.3逆时针排列,则面积为正:1.2.3顺时针排列,则面积为负.这是对右手系的总结,如果从背面看这