题目大意:给一个凸多边形(点不是按顺序给的),然后计算给出的线段在这个凸多边形里面的长度,如果在边界不计算。

分析:WA2..WA3...WA4..WA11...WA的无话可说,总之细节一定考虑清楚,重合的时候一定是0

代码如下:

=========================================================================================================

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std; const int MAXN = ;
const double EPS = 1e-;
const double FarX = 4e4+; int Sign(double x)
{
if(x > EPS)return ;
if(fabs(x) < EPS)return ;
return -;
}
struct point
{
double x, y;
point(double x=, double y=):x(x),y(y){}
point operator - (const point &t)const{
return point(x-t.x, y-t.y);
}
bool operator == (const point &t)const{
return Sign(x-t.x) == && Sign(y-t.y) == ;
}
double operator ^(const point &t)const{
return x*t.y - y*t.x;
}
double operator *(const point &t)const{
return x*t.x + y*t.y;
}
};
double Dist(point t1, point t2)
{
return sqrt((t1-t2)*(t1-t2));
}
struct segment
{
point S, E;
double a, b, c;///ax + by = c; segment(point S=, point E=):S(S), E(E){
a = S.y - E.y;
b = E.x - S.x;
c = E.x*S.y - S.x*E.y;
}
int Inter(const segment &tmp)const{
int t1 = Sign((S-E)^(tmp.S-E));
int t2 = Sign((S-E)^(tmp.E-E)); if(t1 == && t2 == )
return -; if(t1*t2 == -)
return ;
if(abs(t1+t2) == )///如果完全相交或者有一点相交,不考虑重合
return ;
return false;
}
point crossNode(const segment &tmp)const
{///两条线段的交点
point result;
result.x = (c*tmp.b-tmp.c*b) / (a*tmp.b-tmp.a*b);
result.y = (c*tmp.a-tmp.c*a) / (b*tmp.a-tmp.b*a); return result;
}
bool OnSeg(const point &p)
{///判断点是否在线段上
if(Sign((S-E)^(p-E)) == )
if(Sign((p.x-S.x)*(p.x-E.x)) <= )
if(Sign((p.y-S.y)*(p.y-E.y)) <= )
return true;
return false;
}
};
struct Polygon
{
int N;///有N个点
point vertex[MAXN]; int Point_In_Poly(const point &p)
{///点在多边形里面1,还是外面-1,还是边上 0
segment ray(p, point(FarX, p.y));
int cnt = ; for(int i=; i<N; i++)
{
segment L(vertex[i], vertex[i+]); if(L.OnSeg(p))
return ; if(ray.OnSeg(L.S))
{
if(L.E.y-L.S.y > EPS)
cnt ++;
}
else if(ray.OnSeg(L.E))
{
if(L.S.y-L.E.y > EPS)
cnt ++;
}
else if(L.Inter(ray)== && ray.Inter(L)==)
cnt++;
} if(cnt % )
return ;
return -;
}
double Seg_In_Poly(const segment &L1)
{///线段与多边形相交的长度,先求出线段与多边形有几个交点
point p[];
int k=; for(int i=; i<N; i++)
{
segment L2(vertex[i], vertex[i+]); if(L1.Inter(L2) == - && L2.Inter(L1) == -)
return ; if(k< && L1.Inter(L2) && L2.Inter(L1))
{
point t = L1.crossNode(L2);
if(!k || !(p[] == t) )
p[k++] = t;
}
} double len=; if(k == )
{///有两个不同的交点
len = Dist(p[], p[]);
}
else if(k == )
{///有一个交点,判断哪个端点在多边形内
if(Point_In_Poly(L1.S) == )
len = Dist(p[], L1.S);
else if(Point_In_Poly(L1.E) == )
len = Dist(p[], L1.E);
}
else if(Point_In_Poly(L1.S) == )
{///没有交点的时候,判断线段是否在多边形内
len = Dist(L1.S, L1.E);
} return len;
}
};
Polygon poly; bool cmp(point t1, point t2)
{
return Sign((t2-poly.vertex[])^(t1-poly.vertex[])) < ;
} int main()
{
int i, M, ki=; scanf("%d", &poly.N); for(i=; i<poly.N; i++)
{
scanf("%lf%lf", &poly.vertex[i].x, &poly.vertex[i].y);
if(poly.vertex[ki].y > poly.vertex[i].y ||
(poly.vertex[ki].y == poly.vertex[i].y && poly.vertex[ki].x > poly.vertex[i].x) )
ki = i;
} swap(poly.vertex[], poly.vertex[ki]);
sort(poly.vertex+, poly.vertex+poly.N, cmp);
poly.vertex[poly.N] = poly.vertex[]; scanf("%d", &M); while(M--)
{
point A, B; scanf("%lf%lf%lf%lf", &A.x, &A.y, &B.x, &B.y);
segment L(A, B);
printf("%.6f\n",poly.Seg_In_Poly(L));
} return ;
}
/**
6
1 2
2 1
2 3
3 1
3 3
4 2
200
1 1 4 10
**/

Inheritance - SGU 129(线段与多边形相交的长度)的更多相关文章

  1. dtIntersectSegmentPoly2D 2D上的线段与多边形相交计算 产生结果:是否相交,线段跨越的开始和结束百分比,相交的边

    dtIntersectSegmentPoly2D(startPos, endPos, verts, nv, tmin, tmax, segMin, segMax): http://geomalgori ...

  2. Snake - SGU 128(构造多边形)

    题目大意:有N个点,如果可以使用这N个点连接,连接的时候任意两条边要成直角,任意边都要平行于x轴或者y轴,并且不能出现跨立相交,最终组成一个闭合的多边形,求出来这个多边形的最小长度. 分析:容易证明这 ...

  3. HDU 1558 Segment set (并查集+线段非规范相交)

    题目链接 题意 : 如果两个线段相交就属于同一集合,查询某条线段所属集合有多少线段,输出. 思路 : 先判断与其他线段是否相交,然后合并. #include <cstdio> #inclu ...

  4. 线段和矩形相交 POJ 1410

    // 线段和矩形相交 POJ 1410 // #include <bits/stdc++.h> #include <iostream> #include <cstdio& ...

  5. 判断线段和直线相交 POJ 3304

    // 判断线段和直线相交 POJ 3304 // 思路: // 如果存在一条直线和所有线段相交,那么平移该直线一定可以经过线段上任意两个点,并且和所有线段相交. #include <cstdio ...

  6. Geometric Shapes (poj3449多边形相交)

    题意:给你一些多边形的点,判断每个多边形和那些多边形相交,编号按照字典序输出 思路:枚举每个多边形的每条边看是否相交,这里的相交是包括端点的,关键是给你正方形不相邻两个点求另外两个点怎么求,长方形给你 ...

  7. hdu 5130(2014广州 圆与多边形相交模板)

    题意:一个很多个点p构成的多边形,pb <= pa * k时p所占区域与多边形相交面积 设p(x,y),       (x - xb)^2+(y - yb)^2 / (x - xa)^2+(y ...

  8. hdu3340 线段树+多边形

    Rain in ACStar Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  9. POJ_3304_Segments_线段判断是否相交

    POJ_3304_Segments_线段判断是否相交 Description Given n segments in the two dimensional space, write a progra ...

随机推荐

  1. CI 笔记,使用 json的参考文档(废弃)

    Json的处理转换, Json转换步骤, a)         先设置json为空字符串, b)         While循环,遍历, While(!!$row = mysql_fetch_arra ...

  2. ios 设置label的高度随着内容的变化而变化

    好吧 步骤1:创建label _GeRenJianJie = [[UILabel alloc]init]; 步骤2:设置label _GeRenJianJie.textColor = RGBAColo ...

  3. 在ASP.NET 中调用RSACryptoServiceProvider失败,提示未找到文件

    在本地开发环境调试下,调试这个RSA加密是没问题的,但是部署到IIS就会报错. 原来是,在本地vs调试与IIS上运行是存在权限差异的.本地调试权限最大,IIS 次之. 所以在我们声明CspParame ...

  4. pc110301QWERTYU

    水题一道,SOLVED只是次数的问题.map一下,就是很easy啦. #include<iostream> #include<cstdio> #include<cstri ...

  5. html5 拖拽的简要介绍

    1,首先,你要告诉计算机那个元素可以拖动,或者是一张图,或者是一个盒子,在标签里面加上 draggable="true"  2,然后,监听该元素被拖动的函数 ondragstart ...

  6. 笔记一:Python的PyDev插件在eclipse上面安装(新的插件地址 location)

    注:部分内容参考网上的,若有侵权,请作者联系我,马上进行删改 安装PyDev: 首先需要去Eclipse官网下载:http://www.eclipse.org/,Eclipse需要JDK支持,如果Ec ...

  7. 使用 fn 标签 解决字数过多时用省略号代替 .............................

    list列表单条记录某字段大于10就后面添加省略号(如:内容只是显示开始的10个字,后面的用省略号代替) 在list列表中单条记录某字段大于10就后面添加省略号, 首先引入 jstl标签: <% ...

  8. 安装指南【win10下安装fedora】

    系统安装 安装准备 系统:fedora .Win 10 硬件:U盘一枚.PC一台 软件:UltraISO 安装步骤 使用UltraISO将镜像写入U盘 window10使用磁盘管理,空出一个未分配的区 ...

  9. jquery技巧(持续更新。。)

    (1)集合处理功能         //为索引为0,1,2的元素分别设置不同的字体颜色         $('p').each(function(i){               this.styl ...

  10. Python 手册——调用解释器

    通常Python的解释器被安装在目标机器的 /usr/local/bin/python 目录下:把 /usr/local/bin 目录放进你的UNIX Shell 的搜索路径里,确保它可以通过输入py ...