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. Leetcode43. Multiply Strings字符串相乘(大数相乘)

    给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式. 示例 1: 输入: num1 = "2", num ...

  2. Java IO:为什么InputStream只能读一次

    http://zhangbo-peipei-163-com.iteye.com/blog/2021879 InputStream的接口规范就是这么设计的. /** * Reads the next b ...

  3. PHP 学习1.3

    1.展示类的继承和静态的方法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "htt ...

  4. Android——app基础

    Android Application基础 系统启动过程 APK文件介绍 APK是Android Package的缩写,即android安装包.APK 文件其实是zip 格式,但后缀名被修改为apk  ...

  5. UIImageView添加圆角

    最直接的方法就是使用如下属性设置: 1 2 3 imgView.layer.cornerRadius = 10; // 这一行代码是很消耗性能的 imgView.clipsToBounds = YES ...

  6. python2与python3爬虫中get与post对比

    python2中的urllib2改为python3中的urllib.request 四种方式对比: python2的get: # coding=utf-8 import urllib import u ...

  7. iOS 9开发小技巧

    http://www.cocoachina.com/ios/20151217/14733.html 前言 "小黄鸭"法不仅适用于debug,也适用于学习新知识.表达是最好的吸收.本 ...

  8. iOS将image转90,180,270度的方法

    http://blog.sina.com.cn/s/blog_6602ffbc0101ckx3.html 这里要分享的是将image旋转,而不是将imageView旋转,原理就是使用quartz2D来 ...

  9. 全球首个百万IOPS云盘即将商业化 阿里云推出超高性能云盘ESSD

    近日,在经过近半年的上线公测后,阿里云全球首个跨入IOPS百万时代的云盘——ESSD即将迎来商业化,单盘IOPS高达100万,这是阿里云迄今为止性能最强的企业级块存储服务. 搭配ECS云服务器使用, ...

  10. 最短路-Dijkstra算法整理

    维基说的很全面:https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm 理解: 先设置访问数组vis[]和距离数组dist[],开始时把源点(sour ...