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 ...
随机推荐
- Leetcode671.Second Minimum Node In a Binary Tree二叉树中的第二小结点
给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0.如果一个节点有两个子节点的话,那么这个节点的值不大于它的子节点的值. 给出这样的一个二叉树,你需要输出所有节点中 ...
- 给iview项目加一个i18n国际化翻译
看了上一篇博客吗?我们就根据那一篇博客来,用里面的项目,进行我们接下来国际化翻译项目. 我们安装vue-i18n和js-cookie npm install vue-i18n npm install ...
- 使用openpyxl模块时出现错误: zipfile.BadZipFile: File is not a zip file
通过Pycharm工具新建一个xlsx文件. 再通过openpyxl模块读取该表时,报错: zipfile.BadZipFile: File is not a zip file 如下所示: 解决办法: ...
- 为Array对象添加一个去除重复项的方法
输入例子 [false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN].uniq() 输出例子 [false, true, unde ...
- socket in android
Server - JAVA package com.jim.ndkdemo; import android.net.LocalServerSocket; import android.net.Lo ...
- Android开源实战:使用MVP+Retrofit开发一款文字阅读APP
文字控 使用MVP+Retrofit开发的一款文艺APP,它是一个非常优美的文字阅读应用,界面基本上符合material design设计规范. 在该项目中,我采用的是MVP架构,该架构目前在Andr ...
- Spring → 02:开发初步
一.搭建开发环境 1.1.IDE的安装和配置 1.2.开发包的准备及开发包介绍 二.Hello World 2.1.Bean的编码 2.2.Spring配置文件编写 2.3.测试与运行 三.Sprin ...
- C++:参数
一.基础 实参是形参的初始值,对每个形参都需要穿一个能转换为它的实参 形参列表中的形参通常用逗号隔开,其中每个形参都含有一个声明符的声明 二.main(int argc, char *argv[]) ...
- Directx11教程(33) 纹理映射(3)
原文:Directx11教程(33) 纹理映射(3) 现在我们在myTutorialD3D11_5的基础上,来逐步编码实现纹理映射,之所以在myTutorialD3D11_5基础上改写,是 ...
- 学习iOS设计--iOS8的颜色、文字和布局学习
在去年,Apple针对新时代用户彻底更新了其设计语言.现在的设计语言相对之前大为简化,能够让设计师将精力集中到动画和功能上,而不是繁复的视觉细节上. 很多人都曾问过我:设计应当如何入门?成为一名优秀设 ...