python射线法判断一个点在图形区域内外


Posted in Python onJune 28, 2019

用python 实现的代码:判断一个点在图形区域内外,供大家参考,具体内容如下

# -*-encoding:utf-8 -*-
# file:class.py
#
 
"""
信息楼
0 123.425658,41.774177
1 123.425843,41.774166
2 123.425847,41.774119
3 123.42693,41.774062
4 123.426943,41.774099
5 123.427118,41.774089
6 123.427066,41.773548
7 123.426896,41.773544
8 123.426916,41.773920
9 123.425838,41.773965
10 123.425804,41.773585
11 123.425611,41.773595
图书馆
0 123.425649,41.77303
1 123.426656,41.772993
2 123.426611,41.772398
3 123.425605,41.772445
"""
 
 
class Point:
 lat = ''
 lng = ''
 
 def __init__(self,lat,lng):
 self.lat = lat #纬度
 self.lng = lng #经度
 
 def show(self):
 print self.lat," ",self.lng
 
 
#将信息楼的边界点实例化并存储到points1里
point0 = Point(123.425658,41.774177)
point1 = Point(123.425843,41.774166)
point2 = Point(123.425847,41.774119)
point3 = Point(123.42693,41.774062)
point4 = Point(123.426943,41.774099)
point5 = Point(123.427118,41.774089)
point6 = Point(123.427066,41.773548)
point7 = Point(123.426896,41.773544)
point8 = Point(123.426916,41.773920)
point9 = Point(123.425838,41.773961)
point10 = Point(123.425804,41.773585)
point11 = Point(123.425611,41.773595)
 
points1 = [point0,point1,point2,point3,
   point4,point5,point6,point7,
   point8,point9,point10,point11,
  ]
 
 
#将图书馆的边界点实例化并存储到points2里
point0 = Point(123.425649,41.77303)
point1 = Point(123.426656,41.772993)
point2 = Point(123.426611,41.772398)
point3 = Point(123.425605,41.772445)
 
points2 = [point0,point1,point2,point3]
 
 
'''
将points1和points2存储到points里,
points可以作为参数传入
'''
points = [points1,points2]
 
 
'''
输入一个测试点,这个点通过GPS产生
建议输入三个点测试
在信息学馆内的点:123.4263790000,41.7740520000 123.42699,41.773592 
在图书馆内的点: 123.4261550000,41.7726740000 123.42571,41.772499 123.425984,41.772919 
不在二者内的点: 123.4246270000,41.7738130000
在信息学馆外包矩形内,但不在信息学馆中的点:123.4264060000,41.7737860000
'''
#lat = raw_input(please input lat)
#lng = raw_input(please input lng)
lat = 123.42699
lng = 41.773592
point = Point(lat,lng)
 
debug = raw_input("请输入debug")
if debug == '1':
 debug = True
else:
 debug = False
 
#求外包矩形
def getPolygonBounds(points):
 length = len(points)
 #top down left right 都是point类型
 top = down = left = right = points[0]
 for i in range(1,length):
 if points[i].lng > top.lng:
  top = points[i]
 elif points[i].lng < down.lng:
  down = points[i]
 else:
  pass
 if points[i].lat > right.lat:
  right = points[i]
 elif points[i].lat < left.lat:
  left = points[i]
   else:
   pass
 
 point0 = Point(left.lat,top.lng)
 point1 = Point(right.lat,top.lng)
 point2 = Point(right.lat,down.lng)
 point3 = Point(left.lat,down.lng)
 polygonBounds = [point0,point1,point2,point3]
 return polygonBounds
 
#测试求外包矩形的一段函数
if debug:
 poly1 = getPolygonBounds(points[0])
 print "第一个建筑的外包是:"
 for i in range(0,len(poly1)):
 poly1[i].show() 
 poly2 = getPolygonBounds(points[1])
 print "第二个建筑的外包是:"
 for i in range(0,len(poly2)):
 poly2[i].show() 
 
 
#判断点是否在外包矩形外
def isPointInRect(point,polygonBounds):
 if point.lng >= polygonBounds[3].lng and \
  point.lng <= polygonBounds[0].lng and \
  point.lat >= polygonBounds[3].lat and \
  point.lat <= polygonBounds[2].lat:\
  return True
 else:
 return False
 
#测试是否在外包矩形外的代码
if debug:
 if(isPointInRect(point,poly1)):
 print "在信息外包矩形内"
 else:
 print "在信息外包矩形外"
 
 if(isPointInRect(point,poly2)):
 print "在图书馆外包矩形内"
 else:
 print "在图书馆外包矩形外"
 
 
 
#采用射线法,计算测试点是否任意一个建筑内
def isPointInPolygon(point,points):
 #定义在边界上或者在顶点都建筑内
 Bound = Vertex = True
 count = 0
 precision = 2e-10
 
 #首先求外包矩形
 polygonBounds = getPolygonBounds(points)
 
 #然后判断是否在外包矩形内,如果不在,直接返回false
 if not isPointInRect(point, polygonBounds):
 if debug:
  print "在外包矩形外"
 return False
 else:
 if debug:
  print "在外包矩形内"
 
 length = len(points)
 p = point
 p1 = points[0]
 for i in range(1,length):
 if p.lng == p1.lng and p.lat == p1.lat:
  if debug:
  print "Vertex1"
  return Vertex
 
 p2 = points[i % length]
 if p.lng == p2.lng and p.lat == p2.lat:
  if dubug:
  print "Vertex2"
  return Vertex
 
 if debug: 
  print i-1,i
  print "p:"
  p.show()
  print "p1:"
  p1.show()
  print "p2:"
  p2.show()
 
 if p.lng < min(p1.lng,p2.lng) or \
  p.lng > max(p1.lng,p2.lng) or \
  p.lat > max(p1.lat,p2.lat): 
  p1 = p2
  if debug:
  print "Outside"
  continue
 
 elif p.lng > min(p1.lng,p2.lng) and \
  p.lng < max(p1.lng,p2.lng):
  if p1.lat == p2.lat:
  if p.lat == p1.lat and \
   p.lng > min(p1.lng,p2.lng) and \
   p.lng < max(p1.lng,p2.lng):
   return Bound
  else:
   count = count + 1
   if debug:
   print "count1:",count
   continue
  if debug:
  print "into left or right"   
 
  a = p2.lng - p1.lng
  b = p1.lat - p2.lat
  c = p2.lat * p1.lng - p1.lat * p2.lng
  d = a * p.lat + b * p.lng + c
  if p1.lng < p2.lng and p1.lat > p2.lat or \
   p1.lng < p2.lng and p1.lat < p2.lat: 
  if d < 0:
   count = count + 1
   if debug:
   print "count2:",count
  elif d > 0:
   p1 = p2
   continue
  elif abs(p.lng-d) < precision :
   return Bound
  else :    
  if d < 0:
   p1 = p2
   continue
  elif d > 0:
   count = count + 1
   if debug:
   print "count3:",count
  elif abs(p.lng-d) < precision :
   return Bound
 else:
  if p1.lng == p2.lng:
  if p.lng == p1.lng and \
   p.lat > min(p1.lat,p2.lat) and \
   p.lat < max(p1.lat,p2.lat):
    return Bound
  else:
  p3 = points[(i+1) % length]
  if p.lng < min(p1.lng,p3.lng) or \
   p.lng > max(p1.lng,p3.lng):
   count = count + 2
   if debug:
   print "count4:",count
  else:
   count = count + 1
   if debug:
   print "count5:",count 
 p1 = p2
 if count % 2 == 0 :
 return False
 else :
 return True
 
 
 
length = len(points)
flag = 0
for i in range(length):
 if isPointInPolygon(point,points[i]):
 print "你刚才输入的点在第 %d 个建筑里" % (i+1)
 print "然后根据i值,可以读出建筑名,或者修改传入的points参数"
 break
 else:
 flag = flag + 1
 
if flag == length:
 print "在头 %d 建筑外" % (i+1)

 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python 文件读写操作实例详解
Mar 12 Python
对Python3中的print函数以及与python2的对比分析
May 02 Python
Python 实现「食行生鲜」签到领积分功能
Sep 26 Python
在PyCharm下使用 ipython 交互式编程的方法
Jan 17 Python
Python类的继承、多态及获取对象信息操作详解
Feb 28 Python
python3 自动识别usb连接状态,即对usb重连的判断方法
Jul 03 Python
Python TCPServer 多线程多客户端通信的实现
Dec 31 Python
Python-opencv实现红绿两色识别操作
Jun 04 Python
Python3内置函数chr和ord实现进制转换
Jun 05 Python
解决导入django_filters不成功问题No module named 'django_filter'
Jul 15 Python
Python 用户输入和while循环的操作
May 23 Python
利用Python第三方库实现预测NBA比赛结果
Jun 21 Python
Python OpenCV之图片缩放的实现(cv2.resize)
Jun 28 #Python
如何使用Python 打印各种三角形
Jun 28 #Python
python射线法判断检测点是否位于区域外接矩形内
Jun 28 #Python
python 列表转为字典的两个小方法(小结)
Jun 28 #Python
numpy和pandas中数组的合并、拉直和重塑实例
Jun 28 #Python
使用Python画股票的K线图的方法步骤
Jun 28 #Python
连接pandas以及数组转pandas的方法
Jun 28 #Python
You might like
php实现的遍历文件夹下所有文件,编辑删除
2010/01/05 PHP
php生成随机密码的三种方法小结
2010/09/04 PHP
PHP类的反射用法实例
2014/11/03 PHP
PHP基于面向对象封装的分页类示例
2019/03/15 PHP
php实现快速对二维数组某一列进行组装的方法小结
2019/12/04 PHP
json 定义
2008/06/10 Javascript
JSON 学习之JSON in JavaScript详细使用说明
2010/02/23 Javascript
Jquery异步提交表单代码分享
2015/03/26 Javascript
Javascript中replace()小结
2015/09/30 Javascript
浅谈javascript中replace()方法
2015/11/10 Javascript
javascript图片延迟加载实现方法及思路
2015/12/31 Javascript
jQuery实现的左右移动焦点图效果
2016/01/14 Javascript
JS 设置Cookie 有效期 检测cookie
2017/06/15 Javascript
详解如何提高 webpack 构建 Vue 项目的速度
2017/07/03 Javascript
JS中的两种数据类型及实现引用类型的深拷贝的方法
2018/08/12 Javascript
Vue组件系列开发之模态框
2019/04/18 Javascript
利用Angular7开发一个Radio组件的全过程
2019/07/11 Javascript
el-table表头根据内容自适应完美解决表头错位和固定列错位
2021/01/07 Javascript
[01:27:43]VGJ.S vs TNC Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
[04:03][TI9趣味短片] 小鸽子茶话会
2019/08/20 DOTA
Python实现文件按照日期命名的方法
2015/07/09 Python
Python爬虫模拟登录带验证码网站
2016/01/22 Python
Python编程pygal绘图实例之XY线
2017/12/09 Python
Python语言实现百度语音识别API的使用实例
2017/12/13 Python
Python绘制七段数码管实例代码
2017/12/20 Python
canvas烟花特效锦集
2018/01/17 HTML / CSS
SIXPAD智能健身仪英国官网:革命性的训练装备品牌
2018/09/27 全球购物
英国电视和家用电器购物网站:rlrdistribution.co.uk
2018/11/20 全球购物
Unix控制后台进程都有哪些进程
2016/09/22 面试题
会议开场欢迎词
2014/01/15 职场文书
年级组长自我鉴定
2014/02/22 职场文书
党员承诺践诺书
2014/05/20 职场文书
2014年乡镇卫生院工作总结
2014/11/24 职场文书
检讨书范文
2019/04/16 职场文书
Javascript 解构赋值详情
2021/11/17 Javascript
HTML5页面打开微信小程序功能实现
2022/09/23 HTML / CSS