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 ...
随机推荐
- 洛谷P1832 A+B Problem(再升级) [2017年4月计划 动态规划03]
P1832 A+B Problem(再升级) 题目背景 ·题目名称是吸引你点进来的 ·实际上该题还是很水的 题目描述 ·1+1=? 显然是2 ·a+b=? 1001回看不谢 ·哥德巴赫猜想 似乎已呈泛 ...
- SaaS launch Kit成回收宝和友盟云合作纽带,帮助提升3倍上云效率
导语:叶飞表示,全球二手手机市场未来几年将发生巨大变革, 回收宝正进行积极布局.与阿里云开展紧密技术合作,回收宝期待成为这一变革的引领者. 7月26日,在阿里云上海峰会上,阿里云了发布SaaS生态战略 ...
- 考试总结 模拟27(W)
心得:太弱了,T1问题:理解错了题,矿石可以放到同一处,,太弱了,小凯的疑惑,没什么印象T2问题:拆式子T3问题:换根dp的思想模拟9T1+T2
- Ajax--art-template + 调用天气接口
一.实现原理: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- void 运算符
void 是 javascript 的操作符,意思是:只执行表达式,但没有返回值.该表达式会被计算但是不会在当前文档处装入任何内容,void其实是javascript中的一个函数,接受一个参数,返回值 ...
- TypeScript类型检查机制
类型推断 指不需要指定变量的类型,TS编译器可以根据某些规则自动推断出类型. 什么时候会有类型推断? 声明变量时没有指定类型 函数默认参数 函数返回值 ...... let a; // 这时自动推断为 ...
- 总体<导学>
有一些奇奇怪怪的数据集 波士顿房价数据集 使用sklearn.datasers.load_boston 加载相关的数据集 重要参数 return_X_y 表示是否返回target (价格) 默认为Fa ...
- HTML-DOM实例——实现带样式的表单验证
HTML样式 基于table标签来实现页面结构 <form id="form1"> <h2>增加管理员</h2> <table&g ...
- Thrift源码分析(一)-- 基本概念
我所在的公司使用Thrift作为基础通信组件,相当一部分的RPC服务基于Thrift框架.公司的日UV在千万级别,Thrift很好地支持了高并发访问,并且Thrift相对简单地编程模型也提高了服务地开 ...
- ESP8266 支持浮点运算吗?
ESP8266 支持浮点运算吗? 可以说支持,也可以说不支持. 说不支持的原因是因为 ESP8266 内部没有 FPU,无法使用硬件计算. 说支持的意思是可以使用软件进行浮点运算,但是会很慢很慢,如果 ...