ZOJ1081

给一个点和一个多边形 判断点在多边形内(边上)还是在多边形外

在多边形外的点引一条射线必然穿过多边形的两条边

而在多边形内的点则不一定。

当然凹多边形有特殊情况 但是总能找到对应位置关系的边来抵消

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std; const double eps=1e-9; int cmp(double x)
{
if(fabs(x)<eps)return 0;
if(x>0)return 1;
else return -1;
} const double pi=acos(-1.0); inline double sqr(double x)
{
return x*x;
} 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)==0&&cmp(a.y-b.y)==0;
}
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(sqr(x)+sqr(y));
}
}; struct line
{
point a,b;
line(){};
line(point x,point y):a(x),b(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 A)
{
double tx=p.x,ty=p.y;
return point(tx*cos(A)-ty*sin(A),tx*sin(A)+ty*cos(A));
} bool parallel(line a,line b)
{
return !cmp(det(a.a-a.b,b.a-b.b));
} bool line_joined(line a,line b,point &res)
{
if(parallel(a,b))return false;
double s1=det(a.a-b.a,b.b-b.a);
double s2=det(a.b-b.a,b.b-b.a);
res=(s1*a.b-s2*a.a)/(s1-s2);
return true;
} bool pointonSegment(point p,point s,point t)
{
return cmp(det(p-s,t-s))==0&&cmp(dot(p-s,p-t))<=0;
} void PointProjLine(const point p,const point s,const point t,point &cp)
{
double r=dot((t-s),(p-s))/dot(t-s,t-s);
cp=s+r*(t-s);
} struct polygon_convex
{
vector<point>P;
polygon_convex(int Size=0)
{
P.resize(Size);
}
}; bool comp_less(const point &a,const point &b)
{
return cmp(a.x-b.x)<0||cmp(a.x-b.x)==0&&cmp(a.y-b.y)<0; } polygon_convex convex_hull(vector<point> a)
{
polygon_convex res(2*a.size()+5);
sort(a.begin(),a.end(),comp_less);
a.erase(unique(a.begin(),a.end()),a.end());//删去重复点
int m=0;
for(int i=0;i<a.size();i++)
{
while(m>1&&cmp(det(res.P[m-1]-res.P[m-2],a[i]-res.P[m-2]))<=0)--m;
res.P[m++]=a[i];
}
int k=m;
for(int i=int(a.size())-2;i>=0;--i)
{
while(m>k&&cmp(det(res.P[m-1]-res.P[m-2],a[i]-res.P[m-2]))<=0)--m;
res.P[m++]=a[i];
}
res.P.resize(m);
if(a.size()>1)res.P.resize(m-1);
return res;
} bool is_convex(vector<point> &a)
{
for(int i=0;i<a.size();i++)
{
int i1=(i+1)%int(a.size());
int i2=(i+2)%int(a.size());
int i3=(i+3)%int(a.size());
if((cmp(det(a[i1]-a[i],a[i2]-a[i1]))*cmp(det(a[i2]-a[i1],a[i3]-a[i2])))<0)
return false;
}
return true;
}
int containO(const polygon_convex &a,const point &b)
{
int n=a.P.size();
point g=(a.P[0]+a.P[n/3]+a.P[2*n/3])/3.0;
int l=0,r=n;
while(l+1<r)
{
int mid=(l+r)/2;
if(cmp(det(a.P[l]-g,a.P[mid]-g))>0)
{
if(cmp(det(a.P[l]-g,b-g))>=0&&cmp(det(a.P[mid]-g,b-g))<0)r=mid;
else l=mid;
}else
{
if(cmp(det(a.P[l]-g,b-g))<0&&cmp(det(a.P[mid]-g,b-g))>=0)l=mid;
else r=mid;
}
}
r%=n;
int z=cmp(det(a.P[r]-b,a.P[l]-b))-1;
if(z==-2)return 1;
return z;
} bool circle_in_polygon(point cp,double r,polygon_convex &pol)
{ polygon_convex pp=convex_hull(pol.P);
if(containO(pp,cp)!=1)return false;
for(int i=0;i<pol.P.size();i++)
{
int j;
if(i<pol.P.size()-1)j=i+1;
else j=0;
point prol;
PointProjLine(cp,pol.P[i],pol.P[j],prol);
double dis;
if(pointonSegment(prol,pol.P[i],pol.P[j]))dis=dist(prol,cp);
else dis=min(dist(cp,pol.P[i]),dist(pol.P[j],cp));
if(cmp(dis-r)==-1)return false;
}
return true;
} const int maxn=1e+6; point po[maxn+10]; double area(point a[],int n)
{
double sum=0;
a[n]=a[0];
for(int i=0;i<n;i++)
sum+=det(a[i+1],a[i]);
return sum/2.;
} int Point_in(point a[],int n,point t)
{
int num=0,i,d1,d2,k;
a[n]=a[0];
for(int i=0;i<n;i++)
{
if(pointonSegment(t,a[i],a[i+1]))return 2;
k=cmp(det(a[i+1]-a[i],t-a[i]));
d1=cmp(a[i].y-t.y);
d2=cmp(a[i+1].y-t.y);
if(k>0&&d1<=0&&d2>0)num++;
if(k<0&&d2<=0&&d1>0)num--;
}
return num!=0;
} point pp[100];
int main()
{freopen("t.txt","r",stdin);
int n,m;
int tot=1;
while(scanf("%d",&n)&&n>0)
{
if(tot>1)printf("\n");
printf("Problem %d:\n",tot++);
scanf("%d",&m);
for(int i=0;i<n;i++)
pp[i].input();
point t;
for(int i=0;i<m;i++)
{
t.input();
int ans=Point_in(pp,n,t);
if(ans>0)printf("Within\n");
else printf("Outside\n");
}
}
return 0;
}

  

ZOJ1081 Points Within 点和多边形的位置关系的更多相关文章

  1. Cupid's Arrow---hdu1756(判断点与多边形的位置关系 模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1756 题意:中文题,套模板即可: /* 射线法:判断一个点是在多边形内部,边上还是在外部,时间复杂度为 ...

  2. LightOj1190 - Sleepwalking(判断点与多边形的位置关系--射线法模板)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1190 题意:给你一个多边形含有n个点:然后又m个查询,每次判断点(x, y)是否在多边 ...

  3. UVA 10256 The Great Divide (凸包,多边形的位置关系)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34148 [思路] 凸包 求出红蓝点的凸包,剩下的问题就是判断两个凸 ...

  4. Intersecting Lines (计算几何基础+判断两直线的位置关系)

    题目链接:http://poj.org/problem?id=1269 题面: Description We all know that a pair of distinct points on a ...

  5. POJ 1269 Intersecting Lines (判断直线位置关系)

    题目链接:POJ 1269 Problem Description We all know that a pair of distinct points on a plane defines a li ...

  6. POJ 1269 Intersecting Lines(判断两直线位置关系)

    题目传送门:POJ 1269 Intersecting Lines Description We all know that a pair of distinct points on a plane ...

  7. 平面内,线与线 两条线找交点 两条线段的位置关系(相交)判定与交点求解 C#

    个人亲自编写.测试,可以正常使用   道理看原文,这里不多说   网上找到的几篇基本都不能用的   C#代码 bool Equal(float f1, float f2) { return (Math ...

  8. JS魔法堂:判断节点位置关系

    一.前言 在polyfill querySelectorAll 和写弹出窗时都需要判断两个节点间的位置关系,通过jQuery我们可以轻松搞定,但原生JS呢?下面我将整理各种判断方法,以供日后查阅. 二 ...

  9. POJ 2398 - Toy Storage 点与直线位置关系

    Toy Storage Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5439   Accepted: 3234 Descr ...

随机推荐

  1. c++基础_字符串对比

    #include <iostream> #include <string.h> #include <algorithm> using namespace std; ...

  2. c++基础_杨辉三角形

    #include <iostream> using namespace std; int main(){ int n; cin>>n; ][]; ;i<n;i++){ a ...

  3. Redis Hashes 巧用sort排序

    假设我们有如下的数据结构: 我们想按download排序,并且返回hash中的其他field,需要怎么处理呢? 我们首先会想到sort命令.对,就是这个sort. 我们先看一下sort的语法: 可以看 ...

  4. LINUX:Contos7.0 / 7.2 LAMP+R 下载安装Redis篇

    文章来源:http://www.cnblogs.com/hello-tl/p/7569108.html 更新时间:2017-09-21 16:09 简介 LAMP+R指Linux+Apache+Mys ...

  5. Python接口测试中通过登录接口获取实时token

    1.封装login_token 2.headers:对应登录请求头部信息 3.request_param:登录的参数数据 4.json.dumps:将一个Python数据结构转换为JSON 5.dic ...

  6. YOLOv3配置(win10+opencv3.40+cuda9.1+cudnn7.1+vs2015)

    最近心血来潮想学一下YOLOv3,于是就去网上看了YOLOv3在win10下的配置教程.在配置过程中塌坑无数,花了很多时间和精力,所以我想就此写一篇博客来介绍在在win10+vs2015的环境下如何配 ...

  7. (转载)C++ string中find() ,rfind() 等函数 用法总结及示例

    string中 find()的应用  (rfind() 类似,只是从反向查找) 原型如下: (1)size_t find (const string& str, size_t pos = 0) ...

  8. Springboot和SpringMVC区别

    Springboot和SpringMVC区别----http://www.cnblogs.com/xdyixia/p/9279644.html

  9. LA3263 一笔画

    题目大意:依次给定多个点(要求第一个点和最后一个点重叠),把前后两个点相连求最后得到的图形的面的个数 根据欧拉定理: 设平面图的顶点数为V,边数为E,面数为F,则V+F-E = 2 这里的E是指如果一 ...

  10. hdu - 1113 Word Amalgamation (stl)

    http://acm.hdu.edu.cn/showproblem.php?pid=1113 给定一个字典,然后每次输入一个字符串问字典中是否有单词与给定的字符串的所有字母一样(顺序可以打乱),按字典 ...