计算几何二维模板
来源:互联网 发布:纳什 数据库 编辑:程序博客网 时间:2024/05/16 09:01
以POJ1127作为例题分析模板
/** 题意: 这道题目问的是:给你一些线段,求出哪些线段是相连的,哪些是不相连的。相连包括间接相连, 即这两条线段本身不直接相连,而是通过其它线段的连接而间接相连。解决这道题目的关键要解决两个问题: 1.判断两条线段是否直接相连,即它们相交与否,这是一个几何问题; 2.如果某两条线段不相交,那么它们是否通过其它线段的连接而间接相连。如果把相连的线段看做是一个集合, 这个问题变成判断这两条线段是否处于同一个集合中,我们可以用并查集这个数据结构去解决这个问题。 关键:判断两个线段是否有交点(交点在线段上) 有两个思路 1.快速排斥试验和跨立试验 /** bool isIntersect(Point p1,Point p2,Point q1,Point q2) { ///快速排斥 - 两条线段所构成的矩形有相交 if(max(p1.x,p2.x)<min(q1.x,q2.x)||max(q1.x,q2.x)<min(p1.x,p2.x)||max(p1.y,p2.y)<min(q1.y,q2.y)||max(q1.y,q2.y)<min(p1.y,p2.y)) return 0; ///跨立试验 如果 p1p2 跨立 q1q2 则 p1-q1,p2-q1一定在q2 - q1两侧 同理 q1-p1,q2-p1 在 p2 - p1 两侧 if(dot(q2 - q1,p1 - q1)*dot(q2 - q1,p2 - q1)<=0 && dot(p2 - p1,q1 - p1)*dot(p2 - p1,q2 - p1)<=0) return 1; else return 0; } 2.求交点,判断交点在两条线段上 || 平行的时候要特殊判断是否有重合 /** if(平行) // 两条线段向量 det 外积 == 0 { 特殊判断下是否存在重合 bool flag = online(ben[i].a,ben[j])||online(ben[i].b,ben[j])||online(ben[j].a,ben[i])||online(ben[j].b,ben[i]); return flag; } else //相交 { 通过等分定理利用外积求出的面积比=线段比 => 交点 判断交点是否同时满足在两条线段上online(交点,line a) && online(交点,line b); }*/#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>using namespace std;const double eps = 1e-10;const double pi = acos(-1.0);int cmp(double x,double b){ if(fabs(x - b) < eps) return 0; if(x > b) return 1; return -1;}struct point{ double x,y; point() {} point(double a,double b):x(a),y(b){} void input() { scanf("%lf%lf",&x,&y); } friend point operator + (const point &a,const point &b){ return point(a.x+b.x,a.y+b.y); } friend point operator - (const point &a,const point &b){ return point(a.x-b.x,a.y-b.y); } friend bool operator == (const point &a,const point &b){ return !cmp(a.x,b.x) && !cmp(a.y,b.y); } friend point operator * (const point &a,const double &b){ return point(a.x*b,a.y*b); } friend point operator * (const double &a,const point &b){ return point(a*b.x,a*b.y); } friend point operator / (const point &a,const double &b){ return point(a.x/b,a.y/b); } double norm() { return sqrt(x*x + y*y); }};double det(const point &a,const point &b){ return a.x * b.y - a.y * b.x;}double dot(const point &a,const point &b){ return a.x*b.x + a.y*b.y;}double dist(const point &a,const point &b){ return (a - b).norm();}point rotate_point(const point &p,double angle){ double tx = p.x,ty = p.y; return point(tx * cos(angle) - ty * sin(angle),tx * sin(angle) + ty * cos(angle));}struct line{ point a,b; line() {} line(point x,point y):a(x),b(y){} void input(){ a.input(); b.input(); }};line point_make_line(const point &a,const point &b){ return line(a,b);}double dis_point_segment(const point &p,const line &s){ if(cmp(dot(p-s.a,s.b-s.a),0) < 0) return dist(p,s.a); if(cmp(dot(p-s.b,s.a-s.b),0) < 0) return dist(p,s.b); return fabs(det(s.a-p,s.b-p) / dist(s.a,s.b));}void pointprojline(const point &p,const line &s,point &cp){ double r = dot(p-s.a,s.b-s.a) / dot(s.b-s.a,s.b-s.a); cp = s.a + r * (s.b - s.a);}bool pointonsegment(const point &p,const line &s){ return cmp(det(p-s.a,s.b-s.a),0) == 0 && cmp(dot(p-s.a,p-s.b),0) <=0;}bool parallel(const line &x,const line &y){ return !cmp(det(x.a - x.b,y.a - y.b),0);}bool line_make_point(const line &x,const line &y,point &res){ if(parallel(x,y)) return false; double s1 = det(x.a - y.a,y.b - y.a); double s2 = det(x.b - y.a,y.b - y.a); res = (s1 * x.b - s2 * x.a) / (s1 - s2); return true;}line move_d(const line &x,const double &len){ point d = x.b - x.a; d = d / d.norm(); d = rotate_point(d,pi / 2); return line(x.a + d * len,x.b + d * len);}const int maxn = 20;line ben[maxn];/// Union findint pnt[maxn],urank[maxn];void initunion() { memset(pnt,0,sizeof(pnt)); memset(urank,0,sizeof(urank)); for(int i=0;i<maxn;i++) pnt[i] = i , urank[i] = 0;}int ufind(int x) { if(x!=pnt[x]) pnt[x] = ufind(pnt[x]); return pnt[x];}void umerge(int x,int y) { if(urank[x = ufind(x)] > urank[ y = ufind(y) ]) pnt[y] = x; else { pnt[x] = y; urank[y] += (urank[x] == urank[y]); }}int main(){ int n; while(~scanf("%d",&n),n) { initunion(); memset(ben,0,sizeof(ben)); for(int i=1;i<=n;i++) ben[i].input(); point temp; for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if(line_make_point(ben[i],ben[j],temp) && pointonsegment(temp,ben[i]) && pointonsegment(temp,ben[j])) umerge(i,j); else { bool flag = pointonsegment(ben[i].a,ben[j]) || pointonsegment(ben[i].b,ben[j]) ||pointonsegment(ben[j].a,ben[i]) || pointonsegment(ben[j].b,ben[i]); if(flag) umerge(i,j); } } } int u,v; while(scanf("%d%d",&u,&v),u+v) { u = ufind(u); v = ufind(v); if ( u == v) cout<<"CONNECTED"<<endl; else cout<<"NOT CONNECTED"<<endl; } } return 0;}
阅读全文
0 0
- 二维计算几何模板
- 二维计算几何模板
- 计算几何二维模板
- 二维计算几何模板整
- 二维计算几何模板整理
- 二维计算几何模板整理
- 计算几何模板(二维)
- 大白二维计算几何模板
- 计算几何 || 二维基础模板
- 计算几何 || 圆 二维模板
- 二维计算几何通用模板
- 二维计算几何模板--圆
- 二维计算几何模板整理
- 计算几何 - 二维几何基础 (模板)
- poj3304Segments+计算几何(二维几何模板)
- uva11178(二维几何计算模板)
- 二维计算几何模板(点,线)
- 二维计算几何模板--多边形/凸包
- 数据结构 第6,7,9章 章节测验 错误总结
- 访问服务器,入参是json串,调用接口偶尔会出现404错误
- linux文件服务器apache2的搭建,并支持远程访问
- 显卡矿机各型号显卡以太坊算力
- 简化的插入排序
- 计算几何二维模板
- 子类化QListWidget实现自定义拖拽功能.
- 【ECS】云上应用上的安全
- 解决“Dynamic Web Module 3.0 requires Java 1.6 or newer.”而不影响tomcat 8.0--连咸鱼都能学会
- 第6章 接口与实现
- centos安装phpmyadmin
- Glide 内存溢出
- C语言中的未初始化变量的值
- 解决跨域问题的八种方案