POJ3675 Telescope(计算几何)

题意:求一个圆心在原点,半径r的圆和多边形的面积的交

思路:利用三角剖分,这题主要就是验证下模板

代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>

const double eps = 1e-8;
const double pi = acos(-1.0);

int dcmp(double x)
{
    if(x > eps) return 1;
    return x < -eps ? -1 : 0;
}

struct Point
{
    double x, y;
    Point(){x = y = 0;}
    Point(double a, double b)
    {x = a, y = b;}
    inline void read()
    {scanf("%lf%lf", &x, &y);}
    inline Point operator-(const Point &b)const
    {return Point(x - b.x, y - b.y);}
    inline Point operator+(const Point &b)const
    {return Point(x + b.x, y + b.y);}
    inline Point operator*(const double &b)const
    {return Point(x * b, y * b);}
    inline double dot(const Point &b)const
    {return x * b.x + y * b.y;}
    inline double cross(const Point &b, const Point &c)const
    {return (b.x - x) * (c.y - y) - (c.x - x) * (b.y - y);}
    inline double Dis(const Point &b)const
    {return sqrt((*this - b).dot(*this - b));}
    inline bool InLine(const Point &b, const Point &c)const//三点共线
    {return !dcmp(cross(b, c));}
    inline bool OnSeg(const Point &b, const Point &c)const//点在线段上,包括端点
    {return InLine(b, c) && (*this - c).dot(*this - b) < eps;}
};

inline double min(double a, double b)
{return a < b ? a : b;}
inline double max(double a, double b)
{return a > b ? a : b;}
inline double Sqr(double x)
{return x * x;}
inline double Sqr(const Point &p)
{return p.dot(p);}

Point LineCross(const Point &a, const Point &b, const Point &c, const Point &d)
{
    double u = a.cross(b, c), v = b.cross(a, d);
    return Point((c.x * v + d.x * u) / (u + v), (c.y * v + d.y * u) / (u + v));
}

double LineCrossCircle(const Point &a, const Point &b, const Point &r,
            double R, Point &p1, Point &p2)
{
    Point fp = LineCross(r, Point(r.x + a.y - b.y, r.y + b.x - a.x), a, b);
    double rtol = r.Dis(fp);
    double rtos = fp.OnSeg(a, b) ? rtol : min(r.Dis(a), r.Dis(b));
    double atob = a.Dis(b);
    double fptoe = sqrt(R * R - rtol * rtol) / atob;
    if(rtos > R - eps) return rtos;
    p1 = fp + (a - b) * fptoe;
    p2 = fp + (b - a) * fptoe;
    return rtos;
}

double SectorArea(const Point &r, const Point &a, const Point &b, double R)
//不大于180度扇形面积,r->a->b逆时针
{
    double A2 = Sqr(r - a), B2 = Sqr(r - b), C2 = Sqr(a - b);
    return R * R * acos((A2 + B2 - C2) * 0.5 / sqrt(A2) / sqrt(B2)) * 0.5;
}

double TACIA(const Point &r, const Point &a, const Point &b, double R)
//TriangleAndCircleIntersectArea,逆时针,r为圆心
{
    double adis = r.Dis(a), bdis = r.Dis(b);
    if(adis < R + eps && bdis < R + eps) return r.cross(a, b) * 0.5;
    Point ta, tb;
    if(r.InLine(a, b)) return 0.0;
    double rtos = LineCrossCircle(a, b, r, R, ta, tb);
    if(rtos > R - eps) return SectorArea(r, a, b, R);
    if(adis < R + eps) return r.cross(a, tb) * 0.5 + SectorArea(r, tb, b, R);
    if(bdis < R + eps) return r.cross(ta, b) * 0.5 + SectorArea(r, a, ta, R);
    return r.cross(ta, tb) * 0.5 +
        SectorArea(r, a, ta, R) + SectorArea(r, tb, b, R);
}

const int N = 505;

Point p[N];

double SPICA(int n, Point r, double R)//SimplePolygonIntersectCircleArea
{
    int i;
    double res = 0, if_clock_t;
    for(i = 0; i < n; ++ i)
    {
        if_clock_t = dcmp(r.cross(p[i], p[(i + 1) % n]));
        if(if_clock_t < 0) res -= TACIA(r, p[(i + 1) % n], p[i], R);
        else res += TACIA(r, p[i], p[(i + 1) % n], R);
    }
    return fabs(res);
}

double r;
int n;

int main() {
    while (~scanf("%lf", &r)) {
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
            p[i].read();
        printf("%.2f\n", SPICA(n, Point(0, 0), r));
    }
    return 0;
}
时间: 2024-10-17 13:56:13

POJ3675 Telescope(计算几何)的相关文章

POJ3675 Telescope 圆和多边形的交

POJ3675 用三角剖分可以轻松搞定,数据也小 随便AC. #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm> #include<queue> #include<vector> using namespace std; const doub

【转】[专题学习][计算几何]

原文地址:http://www.cnblogs.com/ch3656468/archive/2011/03/02/1969303.html 基本的叉积.点积和凸包等东西就不多说什么了,网上一搜一大堆,切一些题目基本熟悉了就差不多了. 一些基本的题目可以自己搜索,比如这个blog:http://blog.sina.com.cn/s/blog_49c5866c0100f3om.html 接下来,研究了半平面交,思想方法看07年朱泽园的国家队论文,模板代码参考自我校大牛韬哥: http://www.o

计算几何题目分类

转载 一.基础题目 1.1 有固定算法的题目 A, 最近点对问题最近点对问题的算法基于扫描线算法.ZOJ 2107    Quoit Design    典型最近点对问题POJ    3714    Raid    变种最近点对问题 B,最小包围圆最小包围圆的算法是一种增量算法,期望是O(n).ZOJ    1450    Minimal Circle  HDU    3007    Buried memory C,旋转卡壳POJ 3608    Bridge Across Islands   

!HDU 4380 三角屋内有奇数个宝藏的三角形有多少个-计算几何-(向量叉乘&amp;线段与点的关系&amp;暴力枚举)

题意:小明要买三座房子,这三个房子构成一个三角形,已知n个房子的坐标,任何三个房子都不在一条直线上,又已知有m个宝藏的坐标,问房子构成的三角形内有奇数个宝藏的三角形有多少个.数据范围:n(3~100),m(1~1000) 分析: 简单的计算几何.记住这题的做法. 三角形内的点的个数=上面的线段下面的点的个数 -- 下面两条线段下面的点的个数(或者下面一条线段减上面两条线段,看具体位置情况,所以直接取绝对值就好) n个点有n(n-1)/2条线段,不超过1W,枚举每条线段,再枚举每个宝藏的坐标(10

Opengl绘制计算几何库CGAL三角剖分结果的Demo

Ubuntu下改编了一个用CGAL计算输入点的三角剖分,并用OpenGL显示结果的C++程序. 该Demo可作为一个计算几何及绘图的框架. 代码如下: //编译命令:g++ spatial_sort.cpp -lglut -lGL -lGLU -lCGAL -lCGAL_Core -lgmp #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>   #include <CGAL/Triangulation_eucl

Ubuntu下安装cgal4.5.2计算几何库

摘要:cgal是一个开源的计算几何库, 博文记录了其编译.安装和使用方法. 1 库下载 站点:http://www.cgal.org/ 下载:https://gforge.inria.fr/frs/download.php/file/34514/CGAL-4.5.2.zip 2 解压缩.编译与安装 shell下进入解压文件夹 1)库配置文件生成命令: cmake . 提示缺少gmp和mpfr库 安装缺少的库: sudo apt-get install libgmp-dev libmpfr-dev

UVA 11178 Morley&#39;s Theorem 计算几何

计算几何: 最基本的计算几何,差积  旋转 Morley's Theorem Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Description Problem D Morley's Theorem Input: Standard Input Output: Standard Output Morley's theorem states that that the line

计算几何导论

计算几何 计算几何是一门兴起于二十世纪七十年代末的计算机科学的一个分支,主要研究解决几何问题的算法.在现代工程和数学领域,计算几何在图形学.机器人技术.超大规模集成电路设计和统计等诸多领域有着十分重要的应用. 计算几何问题的输入一般是关于一组几何对象的描述,如一组点.一组线段,或者一个多边形的按逆时针顺序排列的一组顶点.输出常常是对有关这些对象的问题的回答,如是否直线相交,是否为一个新的几何对象,如顶点集合的凸包. 本文将介绍一些平面上的计算几何算法.在这些算法中,每个输入对象都是一组点{p1,

HDU 6206 Apple ( 高精度 &amp;&amp; 计算几何 &amp;&amp; 三点构圆求圆心半径 )

题意 : 给出四个点,问你第四个点是否在前三个点构成的圆内,若在圆外输出"Accepted",否则输出"Rejected",题目保证前三个点不在一条直线上. 分析 : 简单的计算几何问题,如果能够知道圆心和半径(Radius)以及第四个点和圆心的距离(Distance),我们就能够判断第四个点是否在圆外,例如Distance > Radius则在圆外.三点构圆 的圆心和半径是能够推导出公式的 (参考==> http://blog.csdn.net/dea