HDU1154求线段在多边形内长度
来源:互联网 发布:记忆力训练 知乎 编辑:程序博客网 时间:2024/06/01 07:23
/******************************************************************题意:多边形有n个顶点,输入m条直线,分别输出它们在多边形内的长度,边界也算算法:求出直线与多边形的所有交点,排序后,判断每一段线段是否在多边形内(判断中点是否在多边形内),求和。*******************************************************************/#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;struct Point{ double x; double y;} p[1001], px[10001];int n;double eps=1e-8;int cmp(Point a, Point b){ if(abs(a.x-b.x)<eps) return a.y<b.y; return a.x<b.x;}double dist(Point a,Point b)//求距离{ return sqrt((a.x - b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double direction(Point pi,Point pj,Point pk){ return (pk.x-pi.x)*(pj.y-pi.y)-(pj.x-pi.x)*(pk.y-pi.y);}bool on_segment(Point pi,Point pj,Point pk)//判断点pk时候在线段pi, pj上{ if(direction(pi, pj, pk)==0) { if(pk.x>=min(pi.x,pj.x)&&pk.x<=max(pi.x,pj.x)&&pk.y>=min(pi.y,pj.y)&&pk.y<=max(pi.y,pj.y)) return true; } return false;}bool segments_intersect(Point p1,Point p2,Point p3,Point p4)//判断线段是否相交{ double d1=direction(p3,p4,p1); double d2=direction(p3,p4,p2); double d3=direction(p1,p2,p3); double d4=direction(p1,p2,p4); if(d1*d2<0&&d3*d4<0) return true; else if(d1==0&&on_segment(p3,p4,p1)) return true; else if(d2==0&&on_segment(p3,p4,p2)) return true; else if(d3==0&&on_segment(p1,p2,p3)) return true; else if(d4==0&&on_segment(p1,p2,p4)) return true; return false;}Point intersection(Point a1, Point a2, Point b1, Point b2)//计算线段交点{ Point ret = a1; double t = ((a1.x - b1.x) * (b1.y - b2.y) - (a1.y - b1.y) * (b1.x - b2.x)) / ((a1.x - a2.x) * (b1.y - b2.y) - (a1.y - a2.y) * (b1.x - b2.x)); ret.x += (a2.x - a1.x) * t; ret.y += (a2.y - a1.y) * t; return ret;}int InPolygon(Point a)//判断点是否在多边形的内部{ int i; Point b,c,d; b.y=a.y; b.x=1e15;//定义射线 int flag=0; int count=0; for(i=0; i<n; i++) { c = p[i]; d = p[i + 1]; if(on_segment(c,d,a))//该点在多边形的一条边上 return 1; if(abs(c.y-d.y)<eps) continue; if(on_segment(a,b,c))//和顶点相交的情况,如果y值较大则取 { if(c.y>d.y) count++; } else if(on_segment(a,b,d))//和顶点相交的情况,如果y值较大则取 { if(d.y>c.y) count++; } else if(segments_intersect(a,b,c,d))//和边相交 count++; } return count%2;//当L和多边形的交点数目C是奇数的时候,P在多边形内,是偶数的话P在多边形外。}bool Intersect(Point s,Point e,Point a,Point b){ return direction(e,a,s)*direction(e,b,s)<=0;}//所在直线相交double calculate(Point s,Point e){ int i,j,k=0; double sum; Point a,b,temp; for(i=0; i<n; i++) //遍历所有点计算交点 { a=p[i]; b=p[i+1]; if(abs(direction(e,a,s))<eps&&abs(direction(e,b,s))<eps) { px[k++]=a; px[k++]=b; } else if(Intersect(s,e,a,b))//两直线相交 { px[k++]=intersection(s,e,a,b);//两直线交点 } } if(k==0) return 0.0; sort(px,px+k,cmp); // 排序,由于割线是直线,所以交点必定线性分布 px[k]=px[0]; sum=0; for(i=0; i<k-1; i++) { a=px[i]; b=px[i+1]; temp.x=(a.x+b.x)/2.0; temp.y=(a.y+b.y)/2.0; if(InPolygon(temp))//如果两点的中点在多边形外部,说明直线在外部 sum+=dist(a,b); } return sum;}int main(){ int q,i,j; double sum; Point s,e; //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin); while(~scanf("%d%d",&n,&q)) { if(q==0&&n==0) break; for(i=0; i<n; i++) scanf("%lf%lf",&p[i].x,&p[i].y); p[n]=p[0]; for(j=0; j<q; j++) { scanf("%lf%lf%lf%lf",&s.x,&s.y,&e.x,&e.y); sum=calculate(s,e); printf("%.3f\n",sum); } } return 0;}
- HDU1154求线段在多边形内长度
- hdu1154(点是否在多边形内部、两线段交点)
- hdu1154(求直线与多边形公共距离)
- poj 2462 / hdu 1154 Cutting a polygon 线段在多边形内长度
- 17.8.19 校内赛 解题报告【求线段交点+凸包+求多边形面积】【判定点是否在多边形内】【二分答案+半平面交】
- 判断点及线段是否在多边形内
- POJ 1410 Intersection [线段相交+点在多边形内]
- 怎么求一个点是否在一个多边形内呢?
- 求任意多边形内一点
- hdu 2823(旋转卡壳+线段相交判断+点在多边形内判断)
- POJ 1410 Intersection(判断线段交 点在多边形内)
- 判段点是否在多边形内
- 判断点在多边形内
- 点是否在多边形内
- 判断点在多边形内
- 判断点在多边形内
- 点是否在多边形内
- 点在多边形内算法
- ubantu系统更新后无法从Windows系统引导进入的解决方法
- Caught exception while loading file struts-default.xml - [unknown location]
- CreateThread 函数常见错误 cannot convert parameter 3 from 'unsigned long (void *)' to 'unsigned long...
- 银行业务调度系统
- HTML表格
- HDU1154求线段在多边形内长度
- 动态创建按钮
- 工作与生活
- 转:NTSTATUS类型返回值及含义
- linux文件权限学习
- 设置FileNet服务IP及局域网中的虚拟机
- 知足长乐
- ORA-00001: unique constraint (XINNET20100422.PK_T_THEME_ORDER) violated
- 图的邻接矩阵实现