python解决直线过网格问题_numpy_matplotlib
python解决直线过网格问题_numpy_matplotlib
文章目录
- python解决直线过网格问题_numpy_matplotlib
- 1. 问题引子
- 2. 改良和更新
- 3. 验证与实例
1. 问题引子
这个问题是来源于小白五年前写的一篇博客,当时是小白还在逛matlab论坛的时候发现被反复提问的一个问题。
在一个10*10的网格里,判断一条线段经过的网格位置(判断序号)。并计算经过的每个网格内线段的长度。
当时是用matlab写了一段粗劣的程序,并发表在本人的博客上:Matlab研究小问题:如何计算一条线段所经过的网格区域和各区域内的长度
令人没有想到的是,这篇博客的热度一直不减,几乎每年的四五月份就会受到大量的关注、收藏和提问。
小白估计这是某专业某门课程里的编程作业。
小白想起当年在学校里,折腾Matlab的那些日子,不免也心有感伤。青葱岁月一去不复返了。
这里也想对还在用Matlab的同学们提个醒:Matlab上手容易,配置简单,作为算法学习的初步工具尚可,但其一,它是商业软件,其二,目前就业市场上的岗位,绝少是以Matlab编程为要求的。(这也都是小白当年吃过的亏)
所以小白近几年也几乎不再去写matlab相关的博文了。
因为完全可以用python来做科学计算的替代。(至少小白够用了,至于Matlab的那些高阶功能,一般也用不上)
2. 改良和更新
在以下实现的python版本中,使用了numpy和matplotlib库来作为计算和绘图的辅助。
对于五年前的那个问题,以下版本
- 添加了网格横纵数的自由设置,不再只能是10*10;
- 将斜截式方程改良为两点式方程;
- 可以计算直线段垂直或平行于网格的情况。
Talk is cheap, show me the code.
二话不说,直接上干货:
# -*- coding:utf-8 -*-
import numpy as np
import matplotlib.pyplot as pltdef calLineCrossPt(pt11, pt12, pt21, pt22):[x1, y1] = pt11[x2, y2] = pt12[x3, y3] = pt21[x4, y4] = pt22x0 = -10y0 = -10if abs((x3-x4)*(y1-y2)-(x1-x2)*(y3-y4)) > np.spacing(20):x0 = ((x3-x4)*(x2*y1-x1*y2)-(x1-x2)*(x4*y3-x3*y4))/ \((x3-x4)*(y1-y2)-(x1-x2)*(y3-y4))y0 = ((y3-y4)*(y2*x1-y1*x2)-(y1-y2)*(y4*x3-y3*x4))/ \((y3-y4)*(x1-x2)-(y1-y2)*(x3-x4))elif abs(y1-y2)<np.spacing(20):x0 = x1y0 = y1elif abs(x1-x2)<np.spacing(20):x0 = x1y0 = y1pt0 = [x0, y0]return pt0def calDistance2pts(pt1, pt2):return np.sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)def calTwoPointDist(pt1, pt2, x_grid_num, y_grid_num):[x1, y1] = pt1[x2, y2] = pt2xmin = min(x1, x2)xmax = max(x1, x2)ymin = min(y1, y2)ymax = max(y1, y2)xcal = range(int(np.ceil(xmin)), int(np.floor(xmax)) + 1)ycal = range(int(np.ceil(ymin)), int(np.floor(ymax)) + 1)pt0 = [[x1, y1], [x2, y2]]for xi in xcal:pt00 = calLineCrossPt(pt1, pt2, [xi, ymin], [xi, ymax])pt0.append([xi, pt00[1]])for yi in ycal:pt01 = calLineCrossPt(pt1, pt2, [xmin, yi], [xmax, yi])pt0.append([pt01[0], yi])pt0 = np.unique(pt0, axis=0)print('=======================')print('直线与格网的交点(包含直线首尾端点)')print(pt0)ptInd = []gridInd = []dist = []pos = np.array(range(1, x_grid_num * y_grid_num + 1))pos = pos.reshape((y_grid_num, x_grid_num))for i in range(0, len(pt0)-1):tmpDist = np.sqrt((pt0[i][0] - pt0[i + 1][0]) ** 2 + (pt0[i][1] - pt0[i + 1][1]) ** 2)if tmpDist < np.spacing(20):continuedist.append(tmpDist)xind = np.max([int(np.ceil(pt0[i][0])), int(np.ceil(pt0[i + 1][0]))]) - 1yind = np.max([int(np.ceil(pt0[i][1])), int(np.ceil(pt0[i + 1][1]))]) - 1ptInd.append([xind, yind])gridInd.append(pos[yind][xind])return [gridInd, dist]if __name__ == '__main__':point1 = [3.2, 2]point2 = [7.5, 8.2]x_grid_num = 8y_grid_num = 12[gridInd, gridDist] = calTwoPointDist(point1, point2, x_grid_num, y_grid_num)print('======================')print('直线穿过以下编号的格子:')print(gridInd)print('直线在格子中的分段距离为:')print(gridDist)x = np.linspace(0, x_grid_num, x_grid_num + 1)y = np.linspace(0, y_grid_num, y_grid_num + 1)[grid_x, grid_y] = np.meshgrid(x, y)fig = plt.figure()ax = plt.axes()for xi in x:lx = plt.axvline(xi)plt.setp(lx, color='b', linewidth=1.0, alpha=1)for yi in y:ly = plt.axhline(yi)plt.setp(ly, color='b', linewidth=1.0, alpha=1)ax.set_xlim([0, x_grid_num])ax.set_ylim([0, y_grid_num])ax.set_aspect(1)plt.xticks(range(0,x_grid_num + 1))plt.yticks(range(0,y_grid_num + 1))pos = np.array(range(1, x_grid_num * y_grid_num + 1))pos = pos.reshape((y_grid_num, x_grid_num))for yi in range(0, y_grid_num):for xi in range(0, x_grid_num):plt.text(xi+0.3-(len(str(pos[yi][xi]))-2)*0.1, yi+0.3, pos[yi][xi])plt.plot([point1[0], point2[0]], [point1[1], point2[1]], linewidth =1, color='r')plt.show()
3. 验证与实例
Example1: 当网格为12*10,设置直线段两个点为[3.2, 2] [7.5, 8.2]时
=======================
直线与格网的交点(包含直线首尾端点)
[[3.2 2. ][3.2 2. ][3.89354839 3. ][4. 3.15348837][4.58709677 4. ][5. 4.59534884][5.28064516 5. ][5.97419355 6. ][6. 6.0372093 ][6.66774194 7. ][7. 7.47906977][7.36129032 8. ][7.5 8.2 ]]
======================
直线穿过以下编号的格子:
[28, 40, 41, 53, 54, 66, 78, 79, 91, 92, 104]
直线在格子中的分段距离为:
[1.216967281912105, 0.18679032699116002, 1.030176954920945, 0.7245200562081378, 0.49244722570396715, 1.2169672819121056, 0.045282503513008256, 1.1716847783990967, 0.5830122327299841, 0.6339550491821208, 0.2433934563824204]
Example2: 当网格为11*10,设置直线段两个点为[2.3, 8.2] [8.2, 2]时
=======================
直线与格网的交点(包含直线首尾端点)
[[2.3 8.2 ][2.49032258 8. ][3. 7.46440678][3.44193548 7. ][4. 6.41355932][4.39354839 6. ][5. 5.36271186][5.34516129 5. ][6. 4.31186441][6.29677419 4. ][7. 3.26101695][7.2483871 3. ][8. 2.21016949][8.2 2. ]]
======================
直线穿过以下编号的格子:
[91, 80, 81, 70, 71, 60, 61, 50, 51, 40, 41, 30, 31]
直线在格子中的分段距离为:
[0.276084560784252, 0.7393450949815596, 0.641077708939706, 0.8095360850114535, 0.5708867189098116, 0.8797270750413492, 0.5006957288799165, 0.9499180650712435, 0.4305047388500215, 1.0201090551011383, 0.3603137488201268, 1.0903000451310336, 0.290122758790232]
Example3: 当网格为11*10,设置直线段两个点为[2.3, 2] [8.2, 2]时
=======================
直线与格网的交点(包含直线首尾端点)
[[2.3 2. ][3. 2. ][4. 2. ][5. 2. ][6. 2. ][7. 2. ][8. 2. ][8.2 2. ]]
======================
直线穿过以下编号的格子:
[14, 15, 16, 17, 18, 19, 20]
直线在格子中的分段距离为:
[0.7000000000000002, 1.0, 1.0, 1.0, 1.0, 1.0, 0.1999999999999993]
这个例子中我们发现,如果是刚好在网格分界线上,这个程序给出的网格是更靠下及更靠左的那个格子位置。
Example4: 当网格为11*10,设置直线段两个点为[2.3, 2.1] [8.2, 2.1]时
=======================
直线与格网的交点(包含直线首尾端点)
[[2.3 2.1][3. 2.1][4. 2.1][5. 2.1][6. 2.1][7. 2.1][8. 2.1][8.2 2.1]]
======================
直线穿过以下编号的格子:
[25, 26, 27, 28, 29, 30, 31]
直线在格子中的分段距离为:
[0.7000000000000002, 1.0, 1.0, 1.0, 1.0, 1.0, 0.1999999999999993]
Example5: 当网格为11*10,设置直线段两个点为[8.2, 2.5] [8.2, 8.5]时
=======================
直线与格网的交点(包含直线首尾端点)
[[8.2 2.5][8.2 3. ][8.2 4. ][8.2 5. ][8.2 6. ][8.2 7. ][8.2 8. ][8.2 8.5]]
======================
直线穿过以下编号的格子:
[31, 42, 53, 64, 75, 86, 97]
直线在格子中的分段距离为:
[0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5]
【水平所限,难免出错,如有错漏,轻喷勿骂】
python解决直线过网格问题_numpy_matplotlib相关推荐
- python直线拟合_RANSAC算法详解(附Python拟合直线模型代码)
之前只是简单了解RANSAC模型,知道它是干什么的.然后今天有个课程设计的报告,上去讲了一下RANSAC,感觉这个东西也没那么复杂,所以今天就总结一些RASAC并用Python实现一下直线拟合. RA ...
- 高德API+Python解决租房问题
项目简介:编写Python脚本爬取某租房网站的房源信息,利用高德的 js API 在地图上标出房源地点,划出距离工作地点1小时内可到达的范围,附上公交路径规划功能查看不同路径的用时. 本教程由ekCi ...
- Python版本的数据结构书_《用Python解决数据结构与算法问题》
源于经典 数据结构作为计算机从业人员的必备基础,Java, c 之类的语言有很多这方面的书籍,Python 相对较少, 其中比较著名的一本 problem-solving-with-algorithm ...
- Python解决The truth value of a Series is ambiguous.md
Python解决The truth value of a Series is ambiguous.md import pandas as pd data = pd.read_csv('x.csv') ...
- python计算学生平均年龄_CodeSalt | Python解决按学生年龄排序的实际问题
Python解决按学生年龄排序的实际问题 问题:定义一个Class:包含姓名name.性别gender.年龄age,需要按年龄给学生排序. 输入:包含学生对象的List. 输出:按照年龄age进行排序 ...
- 用 python 解决汉诺塔问题并附带演示过程
用 python 解决汉诺塔问题并附带演示过程 参考文章: (1)用 python 解决汉诺塔问题并附带演示过程 (2)https://www.cnblogs.com/shinawear/p/1061 ...
- python解决组合问题
python解决组合问题 参考文章: (1)python解决组合问题 (2)https://www.cnblogs.com/vipchenwei/p/7147488.html (3)https://w ...
- python解决鸡兔同笼问题
python解决鸡兔同笼问题 参考文章: (1)python解决鸡兔同笼问题 (2)https://www.cnblogs.com/xiaolu915/p/10587499.html 备忘一下.
- Python解决八皇后问题
Python解决八皇后问题 参考文章: (1)Python解决八皇后问题 (2)https://www.cnblogs.com/littleseven/p/5362791.html 备忘一下.
最新文章
- DevDays2012 开发者日中文版资料下载
- 生产环境提升rman备份速度----启动块跟踪
- 分布式系统中的进程标识
- java外卖系统源码_JAVAWEB校园订餐系统项目源码 一个外卖点餐系统 - 下载 - 搜珍网...
- printf的缓存问题
- pandas 字符串切片后保存_我擦~字符串转字节切片后,切片的容量竟然千奇百怪...
- python---subplot函数
- 李宏毅机器学习--课后作业HW_1
- 基于 OpenFlow 的 SDN 技术 (论文笔记)
- VS 0x80041FEB
- 代码的坏味道之十七 :Inappropriate Intimacy(狎昵关系)
- ArcGIS 裁剪地图显示范围
- 推送原理解析 极光推送使用详解
- ps命令 查看系统进程信息
- 个人收款码跟聚合码的区别
- 移动硬盘在计算机中不显示数据能恢复,移动硬盘在电脑上不显示怎么办?分享常用电脑知识...
- 数据库系统工程师备考心得——30天一次拿下
- 【抽象代数】第一章 代数系统《抽象代数极简教程》/ By 禅与计算机程序设计艺术ChatGPT
- 服务器获取真实客户端 IP
- Lotus Notes 邮件归档设置