hdu 1154& Poj2462 Cutting a Polygon 计算几何模板集合

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1154

用到了直线与线段的关系,直线与线段的交点,点是否在多边形内部,点是否在线段上等的模板

Cutting a Polygon

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 878   Accepted: 256

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 1e-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 to 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

Source

Waterloo local 2005.06.11

 

 题目大意:

给你一个由n个点构成的多边行,然后一条直线穿过这个多边行,问直线与多边形相交的相邻的点构成线段在多边行内部的长度,即:有多长的线段在多变形内部。

思路,寻找直线与多边形的所有交点,然后判断交点的中点是否在多边形内部,累计求和,

//注意:G++输出要用%0.3f

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define PI acos(-1.0)
#define EXP exp(1)
#define pppp cout<='0'&&ch<='9')
        ret = ch - '0';
    while((ch=getchar())>='0'&&ch<='9')
        ret=ret*10+(ch-'0');
    return flag ? -ret : ret;
}
const int maxn=1550;
struct Point
{
    double x;
    double y;

    Point() {}
    Point(double x,double y):x(x),y(y) {}

    Point operator + (const Point &rh) const
    {
        return Point(x+rh.x, y+rh.y);
    }
    Point operator - (const Point &rh)const
    {
        return Point(x-rh.x, y-rh.y);
    }
    bool operator == (const Point &rh)const
    {
        if(x==rh.x && y==rh.y)
            return true;
        return false;
    }
} p[maxn],rec[maxn];
struct Line
{
    Point a;
    Point b;
    Line() {}
    Line(Point a,Point b):a(a),b(b) {}
}line;
int n,m;
double Cross(Point a, Point b)//叉积
{
    return  a.x*b.y-b.x*a.y;
//    double t=a.x*b.y-b.x*a.y;
//    if(t>0)
//        return 1;//锐角
//    else if(t<0)
//        return -1;//钝角
//    else
//        return 0;//平行
}
int CheckLineIntersection(Line L1, Line L2)//判断直线的关系,并返回什么关系
{
    // -1表示直线重合
    // 0表示都平行于y轴,没有交点
    // 1表示L1平行于y轴
    // 2表示L2平行于y轴
    // 3表示不平行于y轴且两条直线也不平行或重合
    // 4表示不平行于y轴但两条直线平行
    int state=0;
    double KL1,KL2;
    if( fabs(L1.a.x-L1.b.x)>EPS )//直线L1不平行于y轴没有斜率
    {
        KL1=(L1.b.y-L1.a.y)/(L1.b.x-L1.a.x);//斜率L1
        state+=1;
    }
    if( fabs(L2.a.x-L2.b.x)>EPS )//直线L1不平行于y轴没有斜率
    {
        KL2=(L2.b.y-L2.a.y)/(L2.b.x-L2.a.x);//斜率L2
        state+=2;
    }
    if(state==0)
    {
        if( fabs(L1.a.x-L2.a.x)=min(a.x,b.x) && c.x<=max(a.x,b.x) && c.y>=min(a.y, b.y) && c.y<=max(a.y,b.y))//去掉在线段上的麻烦
    {
        return (abs((c.x-a.x)*(b.y-a.y)-(b.x-a.x)*(c.y-a.y)) <= EPS);
    }
    return false;
}
bool on_flat(Point a)//点是否在多边形内部
{
    int cnt=0;
    Point p1=p[0];
    Point p2;
    for(int i=1; i<=n; ++i)
    {
        p2=p[i];
        if(on_line(p1,p2,a))//表示点在线段上,根据不同要求
        {
            cnt=1;
            break;
        }
        if(a.y>min(p1.y,p2.y))//如果射线交于边的下端点,不算相交,所以是>
        {
            if(a.y<=max(p1.y,p2.y))
            {
                if(a.x<=max(p1.x,p2.x))
                {
                    if(p1.y!=p2.y)//如果射线和边重合,不算
                    {
                        //判断是否满足在这个边的左边,其中(p1.x - p2.x) / (p1.y - p2.y)为tan
                        double tem=(a.y-p2.y)*(p1.x-p2.x)/(p1.y-p2.y)+p2.x;
                        if( p1.x==p2.x || a.x<=tem)
                            cnt++;
                    }
                }
            }
        }
        p1=p2;
    }
    if(cnt&1)
        return true;
    else
        return false;
}
double Dis(Line L)//线段的长度
{
    return sqrt( (L.a.x-L.b.x)*(L.a.x-L.b.x) + (L.a.y-L.b.y)*(L.a.y-L.b.y));
}
double Get_Slove()
{
    int pos=0;
    for(int i=0; i

 

 

 

 

 

 

你可能感兴趣的:(计算几何,模板)