http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3717

  暴力计算几何。 用切割多边形的方法,将初始的矩形划分成若干个多边形,然后对于每一个圆判断有哪些多边形是与其相交的。面积为0的多边形忽略。

  对于多边形与圆相交,要主意圆在多边形内的情况。

代码如下:

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm> using namespace std; const double EPS = 1e-;
const double PI = acos(-1.0);
template <class T> T sqr(T x) { return x * x;}
struct Point {
double x, y;
Point() {}
Point(double x, double y) : x(x), y(y) {}
} ;
typedef Point Vec;
Vec operator + (Vec a, Vec b) { return Vec(a.x + b.x, a.y + b.y);}
Vec operator - (Vec a, Vec b) { return Vec(a.x - b.x, a.y - b.y);}
Vec operator * (Vec a, double p) { return Vec(a.x * p, a.y * p);}
Vec operator / (Vec a, double p) { return Vec(a.x / p, a.y / p);}
inline int sgn(double x) { return (x > EPS) - (x < -EPS);}
bool operator < (Point a, Point b) { return sgn(a.x - b.x) < || sgn(a.x - b.x) == && a.y < b.y;}
bool operator == (Point a, Point b) { return sgn(a.x - b.x) == && sgn(a.y - b.y) == ;} inline double dotDet(Vec a, Vec b) { return a.x * b.x + a.y * b.y;}
inline double crossDet(Vec a, Vec b) { return a.x * b.y - a.y * b.x;}
inline double dotDet(Point o, Point a, Point b) { return dotDet(a - o, b - o);}
inline double crossDet(Point o, Point a, Point b) { return crossDet(a - o, b - o);}
inline double vecLen(Vec x) { return sqrt(dotDet(x, x));}
inline Vec vecUnit(Vec x) { return x / vecLen(x);}
inline Vec normal(Vec x) { return Vec(-x.y, x.x) / vecLen(x);}
inline bool onSeg(Point x, Point a, Point b) { return sgn(crossDet(x, a, b)) == && sgn(dotDet(x, a, b)) < ;} int segIntersect(Point a, Point c, Point b, Point d) {
Vec v1 = b - a, v2 = c - b, v3 = d - c, v4 = a - d;
int a_bc = sgn(crossDet(v1, v2));
int b_cd = sgn(crossDet(v2, v3));
int c_da = sgn(crossDet(v3, v4));
int d_ab = sgn(crossDet(v4, v1));
// cout << a_bc << ' ' << b_cd << ' ' << c_da << ' ' << d_ab << endl;
if (a_bc * c_da > && b_cd * d_ab > ) return ;
if (onSeg(b, a, c) && c_da) return ;
if (onSeg(c, b, d) && d_ab) return ;
if (onSeg(d, c, a) && a_bc) return ;
if (onSeg(a, d, b) && b_cd) return ;
return ;
} Point lineIntersect(Point P, Vec v, Point Q, Vec w) {
Vec u = P - Q;
double t = crossDet(w, u) / crossDet(v, w);
return P + v * t;
} struct Poly {
vector<Point> pt;
Poly() { pt.clear();}
~Poly() {}
Poly(vector<Point> &pt) : pt(pt) {}
Point operator [] (int x) const { return pt[x];}
int size() { return pt.size();}
double area() {
double ret = 0.0;
for (int i = , sz = pt.size(); i < sz; i++) {
ret += crossDet(pt[i], pt[(i + ) % sz]);
}
return fabs(ret / 2.0);
}
} ; Poly cutPoly(Poly &poly, Point a, Point b) {
Poly ret = Poly();
int n = poly.size();
for (int i = ; i < n; i++) {
Point c = poly[i], d = poly[(i + ) % n];
if (sgn(crossDet(a, b, c)) >= ) ret.pt.push_back(c);
if (sgn(crossDet(b - a, c - d)) != ) {
Point ip = lineIntersect(a, b - a, c, d - c);
if (onSeg(ip, c, d)) ret.pt.push_back(ip);
}
}
return ret;
} bool isIntersect(Point a, Point b, Poly &poly) {
for (int i = , sz = poly.size(); i < sz; i++) {
if (segIntersect(a, b, poly[i], poly[(i + ) % sz])) return true;
}
return false;
} struct Circle {
Point c;
double r;
Circle() {}
Circle(Point c, double r) : c(c), r(r) {}
} ; inline bool inCircle(Point a, Circle c) { return vecLen(c.c - a) < c.r;}
bool lineCircleIntersect(Point s, Point t, Circle C, vector<Point> &sol) {
Vec dir = t - s, nor = normal(dir);
Point mid = lineIntersect(C.c, nor, s, dir);
double len = sqr(C.r) - dotDet(C.c - mid, C.c - mid);
if (sgn(len) < ) return ;
if (sgn(len) == ) {
sol.push_back(mid);
return ;
}
Vec dis = vecUnit(dir);
len = sqrt(len);
sol.push_back(mid + dis * len);
sol.push_back(mid - dis * len);
return ;
} bool segCircleIntersect(Point s, Point t, Circle C) {
vector<Point> tmp;
tmp.clear();
if (lineCircleIntersect(s, t, C, tmp)) {
if (tmp.size() < ) return false;
for (int i = , sz = tmp.size(); i < sz; i++) {
if (onSeg(tmp[i], s, t)) return true;
}
}
return false;
} vector<Poly> cutPolies(Point s, Point t, vector<Poly> polies) {
vector<Poly> ret;
ret.clear();
for (int i = , sz = polies.size(); i < sz; i++) {
Poly tmp;
tmp = cutPoly(polies[i], s, t);
if (tmp.size() >= && tmp.area() > EPS) ret.push_back(tmp);
tmp = cutPoly(polies[i], t, s);
if (tmp.size() >= && tmp.area() > EPS) ret.push_back(tmp);
}
return ret;
} int ptInPoly(Point p, Poly &poly) {
int wn = , sz = poly.size();
for (int i = ; i < sz; i++) {
if (onSeg(p, poly[i], poly[(i + ) % sz])) return -;
int k = sgn(crossDet(poly[(i + ) % sz] - poly[i], p - poly[i]));
int d1 = sgn(poly[i].y - p.y);
int d2 = sgn(poly[(i + ) % sz].y - p.y);
if (k > && d1 <= && d2 > ) wn++;
if (k < && d2 <= && d1 > ) wn--;
}
if (wn != ) return ;
return ;
} bool circlePoly(Circle C, Poly &poly) {
int sz = poly.size();
if (ptInPoly(C.c, poly)) return true;
// cout << "~~ " << sz << endl;
for (int i = ; i < sz; i++) {
// cout << poly[i].x << ' ' << poly[i].y << endl;
if (inCircle(poly[i], C)) return true;
// cout << i << endl;
}
for (int i = ; i < sz; i++) {
if (segCircleIntersect(poly[i], poly[(i + ) % sz], C)) return true;
// cout << i << endl;
}
return false;
} vector<double> circlePolies(Circle C, vector<Poly> &polies) {
vector<double> ret;
ret.clear();
for (int i = , sz = polies.size(); i < sz; i++) {
if (circlePoly(C, polies[i])) ret.push_back(polies[i].area());
}
return ret;
} const double dir[][] = { {0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}}; int main() {
// freopen("in", "r", stdin);
// freopen("out", "w", stdout);
double L, W;
int n, m;
while (cin >> n >> m >> L >> W && (n + m + L + W > EPS)) {
vector<Poly> cur;
cur.push_back(Poly());
for (int i = ; i < ; i++) {
cur[].pt.push_back(Point(L * dir[i][], W * dir[i][]));
}
Point p[];
for (int i = ; i < n; i++) {
for (int j = ; j < ; j++) {
cin >> p[j].x >> p[j].y;
}
cur = cutPolies(p[], p[], cur);
}
// cout << cur.size() << endl;
Circle C = Circle();
for (int i = ; i < m; i++) {
cin >> C.c.x >> C.c.y >> C.r;
vector<double> tmp = circlePolies(C, cur);
sort(tmp.begin(), tmp.end());
cout << tmp.size();
for (int j = , sz = tmp.size(); j < sz; j++) {
printf(" %.2f", tmp[j]);
}
cout << endl;
}
cout << endl;
}
return ;
}

——written by Lyon

uva 12296 Pieces and Discs (Geometry)的更多相关文章

  1. uva 12296 Pieces and Discs

    题意: 有个矩形,左下角(0,0),左上角(L,W). 思路: 除了圆盘之外,本题的输入也是个PSLG,因此可以按照前面叙述的算法求出各个区域:只需把线段视为直线,用切割凸多边形的方法 :每次读入线段 ...

  2. Direct2D教程VIII——几何(Geometry)对象的运算,本系列的终结篇

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  3. Direct2D教程III——几何(Geometry)对象

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  4. uva 1153 顾客是上帝(贪心)

    uva 1153 顾客是上帝(贪心) 有n个工作,已知每个工作需要的时间q[i]和截止时间d[i](必须在此前完成),最多能完成多少个工作?工作只能串行完成,第一项任务开始的时间不早于时刻0. 这道题 ...

  5. UVA 1479 Graph and Queries (Treap)

    题意: 给一个无向图,再给一系列操作(以下3种),输出最后的平均查询结果. (1)D X 删除第x条边. (2)Q X k  查询与点X相连的连通分量中第k大的点的权值. (3)C X v  将点X的 ...

  6. UVa 210 并行程序模拟(deque)

    题意: 模拟n个程序运行 格式一共有5种:var = constant(赋值):print var(打印):lock:unlock:end, 上述5种语句分别需要t1.t2.t3.t4.t5单位时间 ...

  7. UVa 10213 - How Many Pieces of Land ?(欧拉公式)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  8. UVA 11100 The Trip, 2007 (贪心)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  9. UVa 11988 破损的键盘(链表)

    原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

随机推荐

  1. windows 下 解决 go get 或 dep init 更新不了问题

    首先你安装了Shadowsocks 并设置相应的代理,能够访问google等境外网站. 打开dos命令行窗口执行 如下图 这样你就能执行go get 或dep等命令,下载被墙的包了.以上方法为临时方法 ...

  2. WPF Popup实现拖动

    问题一.popup总是置顶,遮挡其他窗口 最近发现popup设置打开后,总是会遮挡其他窗口,而我们只想让它仅仅在应用程序的上一层即可,并不像让它在最上面 解决方案是继承Popup重新定义控件Popup ...

  3. python 类属性、静态方法与类方法

    1. 类属性 1.1 定义 在类中方法外通过属性名 = 属性值定义的属性 访问方式: 类名.属性名 对象名.属性名 class Student: cls_id = 102 stu = Student( ...

  4. mac Chrome 快捷键

    从windows迁移到mac,会发现快捷键真的变了,这里先吹一下mac OS天下第一 另外没有bar确实也提高了效率,这一点还是值的 其实程序员最常用的是检查,windows下是F12,默认F12会被 ...

  5. 手把手0基础项目实战(一)——教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)...

    原文:手把手0基础项目实战(一)--教你搭建一套可自动化构建的微服务框架(SpringBoot+Dubbo+Docker+Jenkins)... 本文你将学到什么? 本文将以原理+实战的方式,首先对& ...

  6. 洛谷 P1073 最优贸易 最短路+SPFA算法

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例 输出样例 说明 思路 AC代码 题面 题目链接 P1073 最优贸易 题目描述 C国有 $ n $ 个大城市和 ...

  7. ubuntu上安装字体

    # fc-list # sudo apt-get -y install fontconfig xfonts-utils # sudo cp       XXX.ttf        /usr/shar ...

  8. Polyfill简介

    1.什么是Polyfill? Polyfill是一个js库,主要抚平不同浏览器之间对js实现的差异.比如,html5的storage(session,local), 不同浏览器,不同版本,有些支持,有 ...

  9. Spring → 02:开发初步

    一.搭建开发环境 1.1.IDE的安装和配置 1.2.开发包的准备及开发包介绍 二.Hello World 2.1.Bean的编码 2.2.Spring配置文件编写 2.3.测试与运行 三.Sprin ...

  10. Directx11教程(43) 纹理映射(13)-动态纹理映射

    原文:Directx11教程(43) 纹理映射(13)-动态纹理映射      本篇教程中,我们将在前面基于光照的地形与水面程序里面加上纹理映射,而且我们会基于时间动态改变水面的纹理坐标,实现水面纹理 ...