如何在MATLAB中不使用for循环调用inpolygon函数?
高效向量化解法:利用矩形网格规则性替代for循环+inpolygon
你的问题里,所有网格都是0.5×0.5的规则矩形,完全不需要用通用的inpolygon函数,更不需要逐个循环处理网格——直接通过数值范围判断就能实现向量化运算,速度会比原方法快几个数量级,尤其是大数据量场景。
核心思路
每个网格的中心是(lon_gridbox(n), lat_gridbox(n)),对应的矩形范围是:
- 经度:
lon_gridbox(n)-0.25 ≤ lon_point ≤ lon_gridbox(n)+0.25 - 纬度:
lat_gridbox(n)-0.25 ≤ lat_point ≤ lat_gridbox(n)+0.25
点在边界上的情况刚好包含在这个范围里,我们可以先判断点是否在网格内(含边界),再拆分出“内部”和“边界”的结果。
完整实现代码
% 原始输入数据 lat_points=[45.40927; 45.40961; 45.40995; 45.41029; 45.41063; 45.41097; 45.41131; 45.41165]; lon_points=[-50.00022; -50.05021; -50.10021; -50.15020; -50.20019; -50.25019; -50.30018; -50.35018]; lon_gridbox=[-84; -84;-84;-83.5;-83.5;-83.5;-83.5;-83.5;-83;-83;-83;-83;-83;-83;-82.5]; lat_gridbox=[27; 27.5;28;26.5;27;27.5;28;28.5;26.5;27;27.5;28;28.5;29;26.5]; % 1. 计算每个网格的边界 lon_min = lon_gridbox - 0.25; lon_max = lon_gridbox + 0.25; lat_min = lat_gridbox - 0.25; lat_max = lat_gridbox + 0.25; % 2. 向量化判断:每个点是否在每个网格的范围内(含边界) % MATLAB R2016b及以上可直接用广播运算符,无需bsxfun lon_in = lon_points' >= lon_min & lon_points' <= lon_max; lat_in = lat_points' >= lat_min & lat_points' <= lat_max; in_on = lon_in & lat_in; % 包含内部和边界的点 % 3. 拆分出"内部"和"边界"的结果 lon_on = (lon_points' == lon_min) | (lon_points' == lon_max); lat_on = (lat_points' == lat_min) | (lat_points' == lat_max); on_matrix = lon_on | lat_on; % 仅在边界上的点 in_matrix = in_on & ~on_matrix; % 仅在内部的点 % 4. 构造与原代码格式一致的结果矩阵 int = [lon_gridbox, lat_gridbox, in_matrix', on_matrix'];
为什么这个方法更快?
- 完全消除了for循环:MATLAB的向量化运算底层是优化过的矩阵操作,比逐个循环调用函数的效率高得多。
- 避免了通用多边形计算:
inpolygon是为任意多边形设计的,会做很多额外计算;而我们直接利用矩形的规则性,用简单的数值比较就能完成判断,开销极小。
验证结果
你可以对比原代码和这个代码的输出int矩阵,结果完全一致,但运行速度在网格数/点数很大时会有质的提升。
内容的提问来源于stack exchange,提问作者Srv
相关产品推荐
相关产品推荐

