uva 12296 Pieces and Discs (Geometry)
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)的更多相关文章
- uva 12296 Pieces and Discs
题意: 有个矩形,左下角(0,0),左上角(L,W). 思路: 除了圆盘之外,本题的输入也是个PSLG,因此可以按照前面叙述的算法求出各个区域:只需把线段视为直线,用切割凸多边形的方法 :每次读入线段 ...
- Direct2D教程VIII——几何(Geometry)对象的运算,本系列的终结篇
目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...
- Direct2D教程III——几何(Geometry)对象
目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...
- uva 1153 顾客是上帝(贪心)
uva 1153 顾客是上帝(贪心) 有n个工作,已知每个工作需要的时间q[i]和截止时间d[i](必须在此前完成),最多能完成多少个工作?工作只能串行完成,第一项任务开始的时间不早于时刻0. 这道题 ...
- UVA 1479 Graph and Queries (Treap)
题意: 给一个无向图,再给一系列操作(以下3种),输出最后的平均查询结果. (1)D X 删除第x条边. (2)Q X k 查询与点X相连的连通分量中第k大的点的权值. (3)C X v 将点X的 ...
- UVa 210 并行程序模拟(deque)
题意: 模拟n个程序运行 格式一共有5种:var = constant(赋值):print var(打印):lock:unlock:end, 上述5种语句分别需要t1.t2.t3.t4.t5单位时间 ...
- UVa 10213 - How Many Pieces of Land ?(欧拉公式)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVA 11100 The Trip, 2007 (贪心)
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- UVa 11988 破损的键盘(链表)
原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
随机推荐
- Leetcode78. Subsets子集
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] 输出: [ [3], [1], [2 ...
- Leetcode71. Simplify Path简化路径
给定一个文档 (Unix-style) 的完全路径,请进行路径简化. 例如, path = "/home/", => "/home" path = &qu ...
- Unity 同一Text文本修改不同的字体大小和字体颜色
类似Html,在color和size对应的<>str</>中,就能修改str的相关属性, 下面的代码就是把time改为字体颜色为红色,大小为40: 而前面的"Time ...
- IntelliJ IDEA包层级结构显示方式
在开发的过程中,程序结构增多,通过树状结构看包结构目录,更加舒适. Idea默认情况下是不分层级展示包结构的 点击设置标志按钮,如下图所示 去掉Hide Empty Middle Packages的勾 ...
- 只需一步,DLA开启TableStore多元索引查询加速!
一.背景介绍 Data Lake Analytics(简称DLA)在构建第一天就是支持直接关联分析Table Store(简称OTS)里的数据,实现存储计算分离架构,满足用户基于SQL接口分析Tabl ...
- js计算精度问题(浮点数误差,大数计算出错)
https://github.com/camsong/blog/issues/9 0.1+0.2 //0.30000000000000004 1-0.9 //0.09999999999999998 9 ...
- 【JZOJ4930】【NOIP2017提高组模拟12.18】C
题目描述 给出一个H的行和W列的网格.第i行第j列的状态是由一个字母的A[i][j]表示,如下: "." 此格为空. "o" 此格包含一个机器人. " ...
- poj2195&&hdu1533 最小费用流
这题也可以用km做,我写的代码km比费用流快很多. 最小费用流: #include<stdio.h> #include<string.h> #include<math.h ...
- OFBiz 16.11.03的直接部署、eclipse部署和IDEA部署
一.在OFBiz官网下载最新的发行版本,也就是16.11.03版本. 下载地址:http://ofbiz.apache.org/download.html 点击页面Apache OFBiz 16. ...
- Liferay OSGi注解(Annotation) - 使用手册(译文)
mark过来好好用 上Neil的博客地址Liferay OSGi注解(Annotation) - 使用手册(译文) @Component是注入服务 @Reference是获取服务(在Liferay框架 ...