点在多边形内外的判断有两种处理方法:射线法和转角法

一、射线法:

  • 从这一点出发,引向无穷远点的一条射线,根据交点情况确定点的位置
  • 特点:特殊情况不易处理
  1. 以要判断的点为起点,任做一条射线,计算该射线与多边形的交点的数目
  2. 若有偶数个交点,则点在多边形外;否则,点在多边形内
  3. 若与线段所在的端点处重合或相交,则要进行复杂的判断;此时可另取一条射线

二、转角法:

  • 计算多边形每条边的转角,最后相消为0,则点在多边形内部,否则点在多边形外部
  • 特点:三角形运算时间开销大
  1. 把多边形每条边的转角加起来:如果是360度,则点在多边形内;如果是0度,点在多边形外;如果是180度,则点在多边形边上;
  2. 直接求角度要用反三角函数,精度差且费时
  3. 如果是凸多边形,就用叉积

例题:POJ 1410 Intersection 判断线段交和点在矩形内

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <math.h>using namespace std;
const double eps = 1e-8;
int sgn(double x)
{if(fabs(x) < eps)return 0;if(x < 0)return -1;else return 1;
}
struct Point
{double x,y;Point(){}Point(double _x,double _y){x = _x;y = _y;}Point operator -(const Point &b)const{return Point(x - b.x,y - b.y);}//叉积double operator ^(const Point &b)const{return x*b.y - y*b.x;}//点积double operator *(const Point &b)const{return x*b.x + y*b.y;}//绕原点旋转角度B(弧度值),后x,y的变化void transXY(double B){double tx = x,ty = y;x = tx*cos(B) - ty*sin(B);y = tx*sin(B) + ty*cos(B);}
};
struct Line
{Point s,e;double k;Line(){}Line(Point _s,Point _e){s = _s;e = _e;k = atan2(e.y - s.y,e.x - s.x);}//两条直线求交点,//第一个值为0表示直线重合,为1表示平行,为2是相交//只有第一个值为2时,交点才有意义pair<int,Point> operator &(const Line &b)const{Point res = s;if(sgn((s-e)^(b.s-b.e)) == 0){if(sgn((s-b.e)^(b.s-b.e)) == 0)return make_pair(0,res);//重合else return make_pair(1,res);//平行}double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));res.x += (e.x-s.x)*t;res.y += (e.y-s.y)*t;return make_pair(2,res);}
};
//两点间距离
double dist(Point a,Point b)
{return sqrt((a-b)*(a-b));
}
//判断线段相交
bool inter(Line l1,Line l2)
{returnmax(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s)) <= 0 &&sgn((l1.s-l2.s)^(l2.e-l1.s))*sgn((l1.e-l2.s)^(l2.e-l2.s)) <= 0;
}
//判断点在线段上
bool OnSeg(Point p,Line L)
{returnsgn((L.s-p)^(L.e-p))==0&&sgn((p.x-L.s.x)*(p.x-L.e.x))<=0&&sgn((p.y-L.s.y)*(p.y-L.e.y))<=0;
}//判断点在凸多边形内,点形成一个凸包,而且按逆时针排序
//如果是顺时针,就把<0改成>0
//点的编号:0~n-1
//返回值:-1点在凸多边形外,0点在凸多边形边上,1点在凸多边形内
int inConvexPoly(Point a,Point p[],int n)
{for(int i=0;i<n;i++){if(sgn((p[i]-a)^(p[(i+1)%n]-a))<0)return -1;else if(OnSeg(a,Line(p[i],p[(i+1)%n])))return 0;}return 1;
}//判断点在任意多边形内
//射线法,poly[]的顶点数要大于等于3,点的编号:0~n-1
//返回值
//-1:点在多边形外
//0:点在多边形边界上
//1:点在多边形内
int inPoly(Point p,Point poly[],int n)
{int cnt=0;Line ray,side;ray.s=p;ray.s.y=p.y;ray.e.x=-100000000000.0;//-INF,注意取值,防止越界for(int i=0;i<n;i++){side.s=poly[i];side.e=poly[(i+1)%n];if(OnSeg(p,side))   return 0;//如果平行轴,则不考虑if(sgn(side.s.y-side.e.y)==0)continue;if(OnSeg(side.s,ray)){if(sgn(side.s.y-side.e.y)>0)cnt++;}else if(OnSeg(side.e,ray)){if(sgn(side.e.y-side.s.y)>0)cnt++;}else if(inter(ray,side))cnt++;}if(cnt%2==1)return 1;elsereturn -1;
}

点在多边形内外的判断【计算几何】相关推荐

  1. 判断点在多边形内外的简单算法

    发信人: RovingCloud (寻找当年的OI感觉), 信区: ACMICPC 标  题: [原创]惊喜发现判断点在多边形内外的超简单算法 发信站: 逸仙时空 Yat-sen Channel (W ...

  2. opencv 判断点在多边形内外

    基于Python 和 OpenCV 画出多边形,以及判断某个点是不是在多边形内. 1.cv2.pointPolygonTest() 函数 函数定义:cv2.pointPolygonTest(conto ...

  3. 给定一个多边形的点集——判断所给点集的方向为顺时针方向还是逆时针方向【java实现+原理讲解】

    问题   给定一个点集,按照索引从小到大的顺序遍历将点集的点相连接可以形成一个多边形.如何判断所给点集的方向是顺时针方向还是逆时针方向呢?   如下图的左图,随着索引的增加,取出来的点绕顺时针排布,类 ...

  4. 七巧板复原算法——计算机图形学基本算法之一, 点在多边形内部的判断

    注:此时我已经完成了一个演示版本,但是为了文章的渐进性,我将把开发过程一步步的写出来,用来记录. 本实验代码用到的图形学关系和算法列举如下: 基本计算机图形学关系和算法 1.点在多边形内部的 点在多边 ...

  5. 微信地图多边形算法及判断点位是否在多边形中

    最新一个小项目,需要用到地图定义自由区域,并判断选点是否落在此区域内,思路是通过map的polygons中的points来定义多边形边界,通过polygons的fillColor . strokeCo ...

  6. php 判断点在多边形内,PHP判断点是否在多边形区域内外

    PHP判断点是否在多边形区域内外: 根据数学知识的射线法,射线与几何多边形相交的点的个数为奇数则是在几何内部: 偶数在外部:/** * Created by PhpStorm. * function: ...

  7. HDU1756(判断点在多边形内外)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1756 bool IsOnline(Point p,Segment s) /** 判断点p是否在线段s上 * ...

  8. 几何基础之点在多边形内的判断

    1.判断点在三角形的内外 即可判定点P在内. 三角形面积计算公式:. 2.判断点在多边形的内外 方法一:扫描法 以p点做一条射线,让其与多边形一个顶点相交,再判断是否与多边形上点共线当然这个点不可能是 ...

  9. 多边形碰撞检测(判断点在多边形内)

    点与规则的矩形或者等边.等腰三角形等的碰撞检测很简单,本文主要是介绍"点与多边不规则图形的碰撞检测". 如图,这个多边形已经相当复杂,包含凸和凹,该如何解决呢? 结论:使用交点数判 ...

最新文章

  1. linux中文乱码的解决
  2. python模拟鼠标点击和键盘输入的操作_Python模拟鼠标点击及键盘输入(PyUserInput)...
  3. bootstrap grid php,bootstrap grid用法
  4. 使用JMeter对异步HTTP / REST服务进行压力/负载测试
  5. Eclipse安装TestNG插件
  6. Java 中的5个代码性能提升技巧,最高提升近10倍
  7. python装饰器系列(五)
  8. 唐山师范学院计算机宿舍,唐山师范学院宿舍条件怎么样宿舍图片内景
  9. 数据结构笔记(四)-- 静态链表实现
  10. linux生成ssl证书给haproxy,如何为多个SSL证书配置HAProxy
  11. MFC 时间记时器, string 转化为CString
  12. 你真的懂Linux吗?Linux运维从业方向与前景
  13. 已知任意三点坐标求圆心
  14. Perforce携手龙智成功举办2021年度中国用户大会助力中国企业“加速开发”
  15. python压缩HTML文件,python压缩javascript文件代码
  16. CAD制图软件中如何设置CAD打印样式表(CTB)?
  17. 学习笔记:弱监督学习-valse青年会议
  18. echart柱状图堆列实现百分比显示
  19. 高小英和张东健1998年合作出演过爱情片《恋风恋歌
  20. How to reassign lifecycle in Windchill

热门文章

  1. 构成子网与构成超网的分析
  2. LibreOJ 数列分块入门
  3. C/C++ 代码转换规范化的脚本
  4. 作品第四课----agruments应用一求出函数参数的总合
  5. 当电桥为恒流源时惠斯通电桥电压的计算方法
  6. 易语言服务器不在一个网段,设置二级路由器保持局域网在同一个网段
  7. 中餐菜单分类名称创意_外卖运营小知识:优化外卖菜单,挽回店铺亏损
  8. mysql2008r1_mysql8 参考手册-分区修剪
  9. aes子密钥生成c语言_HBase配置AES加密
  10. Linux上装vscode需要认证,linux系统安装vscode方法 ubuntu等系统上部署VisualStudioCode