hdu-1154 Cutting a Polygon(计算几何综合应用,多模板)
2016-04-26 22:50
567 查看
题目链接:点击打开链接
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 663 Accepted Submission(s): 175
Problem Description
Given is a simple but not necessarily convex polygon. Given is also a line in the plane. If the polygon is cut along the line then we may get several smaller polygons. Your task is to find the length of the cut, that is the total length of the segments in the
intersection of the line and the polygon.
Input
Input consists of a number of cases. The data of each case appears on a number of input lines, the first of which contains two non negative integers n and m giving the number of the vertices of the polygon and the number of cutting lines to consider, 3 ≤ n
≤ 1000. The following n lines contain coordinates of the vertices of the polygon; each line contains the x and y coordinates of a vertex. The vertices are given either in clockwise or counterclockwise order. Each of the following m lines of input contains
four numbers; these are x and y coordinates of the two points defining the cutting line. If a vertex of the polygon is closer than 10e-8 to the cutting line then we consider that the vertex lies on the cutting line.
Input is terminated by a line with n and m equal to 0.
Output
For each cutting line, print the total length of the segments in the intersection of the line and the polygon defined for this test case, with 3 digits after the decimal point. Note: the perimiter of a polygon belongs the polygon.
The picture above illustrates the first cutting line for the polygon from the sample.
Sample Input
9 5
0 0
0 2
1 1
2 2
3 1
4 2
5 1
6 2
6 0
-1 2 7.5 1
0 1 6 1
0 1.5 6 1.5
0 2 6 1
0 0 0 2
0 0
Sample Output
2.798
6.000
3.000
2.954
2.000
题意:求直线与多边形的公共长度。
思路:详细请看代码注释
代码:
Cutting a Polygon
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 663 Accepted Submission(s): 175
Problem Description
Given is a simple but not necessarily convex polygon. Given is also a line in the plane. If the polygon is cut along the line then we may get several smaller polygons. Your task is to find the length of the cut, that is the total length of the segments in the
intersection of the line and the polygon.
Input
Input consists of a number of cases. The data of each case appears on a number of input lines, the first of which contains two non negative integers n and m giving the number of the vertices of the polygon and the number of cutting lines to consider, 3 ≤ n
≤ 1000. The following n lines contain coordinates of the vertices of the polygon; each line contains the x and y coordinates of a vertex. The vertices are given either in clockwise or counterclockwise order. Each of the following m lines of input contains
four numbers; these are x and y coordinates of the two points defining the cutting line. If a vertex of the polygon is closer than 10e-8 to the cutting line then we consider that the vertex lies on the cutting line.
Input is terminated by a line with n and m equal to 0.
Output
For each cutting line, print the total length of the segments in the intersection of the line and the polygon defined for this test case, with 3 digits after the decimal point. Note: the perimiter of a polygon belongs the polygon.
The picture above illustrates the first cutting line for the polygon from the sample.
Sample Input
9 5
0 0
0 2
1 1
2 2
3 1
4 2
5 1
6 2
6 0
-1 2 7.5 1
0 1 6 1
0 1.5 6 1.5
0 2 6 1
0 0 0 2
0 0
Sample Output
2.798
6.000
3.000
2.954
2.000
题意:求直线与多边形的公共长度。
思路:详细请看代码注释
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; #define N 1010 #define eps 1e-8 struct Node { double x,y; } p ,q[N*10]; int n; bool cmp(Node a,Node b)//排序,从左到右,从下到上 { if(abs(a.x-b.x)<eps) return a.y<b.y; return a.x<b.x; } double dist(Node a,Node b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double mulit(Node a,Node c,Node b)//向量ac与向量ab叉乘 { return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x); } int check(Node a,Node b,Node c,Node d)//判断直线ab与线段cd是否相交 { if(mulit(a,c,b)*mulit(a,d,b)<=0) return 1; return 0; } Node get_point(Node a,Node b,Node c,Node d)//求直线ab与线段cd的交点(已证明直线与线段相交,则可以当做两直线) { Node ret=a; double t=((a.x-c.x)*(c.y-d.y)-(a.y-c.y)*(c.x-d.x)) /((a.x-b.x)*(c.y-d.y)-(a.y-b.y)*(c.x-d.x)); ret.x+=(b.x-a.x)*t; ret.y+=(b.y-a.y)*t; return ret; } int checkss(Node a,Node c,Node d)//判断点a是否在线段cd上 { if(mulit(a,c,d)!=0) return 0; if((a.x<c.x&&a.x<d.x)||(a.x>c.x&&a.x>d.x)) return 0; if((a.y<c.y&&a.y<d.y)||(a.y>c.y&&a.y>d.y)) return 0; return 1; } int isI(Node a,Node b,Node c,Node d)//判断线段ab和线段cd是否相交(互跨) { if(mulit(a,c,b)*mulit(a,d,b)<=0&&mulit(c,a,d)*mulit(c,b,d)<=0) return 1; return 0; } int checks(Node a)//判断点a是否在多边形内 { Node b=a,c,d; b.x=1e15; int num=0; for(int i=0;i<n;i++) { c=p[i]; d=p[i+1]; if(checkss(a,c,d)) return 1; if(abs(c.y-d.y)<eps) continue; if(checkss(c,a,b)) { if(c.y>d.y) num++; } else if(checkss(d,a,b)) { if(d.y>c.y) num++; } else if(isI(a,b,c,d)) { num++; } } return num%2; } double get_len(Node a,Node b)//求直线与多边形的公共面积 { Node c,d; int cnt=0; for(int i=0; i<n; i++) //求出直线与多边形各边的交点 { c=p[i]; d=p[i+1]; if(abs(mulit(a,b,c))<eps&&abs(mulit(a,b,d))<eps) { q[cnt++]=c; q[cnt++]=d; } else if(check(a,b,c,d)) q[cnt++]=get_point(a,b,c,d); } if(cnt==0) return 0.0; sort(q,q+cnt,cmp); int t=1; for(int i=1; i<cnt; i++) { c=q[i]; d=q[i-1]; if(!(abs(c.x-d.x)<eps&&abs(c.y-d.y)<eps)) q[t++]=q[i]; }//去重 double sum=0.0; for(int i=1; i<t; i++) { c.x=(q[i].x+q[i-1].x)*0.5; c.y=(q[i].y+q[i-1].y)*0.5; if(checks(c)) sum+=dist(q[i],q[i-1]); } return sum; } int main() { int m; Node a,b; while(~scanf("%d %d",&n,&m)&&n&&m) { for(int i=0; i<n; i++) scanf("%lf %lf",&p[i].x,&p[i].y); p =p[0]; for(int i=0; i<m; i++) { scanf("%lf %lf %lf %lf",&a.x,&a.y,&b.x,&b.y); printf("%.3lf\n",get_len(a,b)); } } return 0; }
相关文章推荐
- 仿Google应用动态隐藏显示状态栏
- django开发备忘
- Django:之CMDB资源系统
- POJ 1042 Gone Fishing(模拟+贪心)
- Codeforces Round #340 (Div. 2)E - XOR and Favorite Number(Mo's algorithm)
- 线性模型(1):Perceptron Learning Algorithm (PLA)
- beego api
- Introduction to x265 Rate Control Algorithm
- django的class Meta
- GO语言编程-顺序编程之变量
- go 简介学习
- <<wherego>>项目
- [Graduation]《WhereGo》工作计划安排-1
- Django model字段类型清单
- Django模型的Field Types总结
- go语言安装与设置
- HDU 4341 - Gold miner
- go语言特点
- mac上安装google tesseract-ocr
- django admin ModelForm field 验证