python - 如何找到线与网格的交点?

标签 python algorithm numpy grid intersection

我有轨迹数据,其中每个轨迹都由一系列坐标(x、y 点)组成,并且每个轨迹都由唯一的 ID 标识。

这些轨迹在 x - y 平面内,我想将整个平面分成大小相等的网格(正方形网格)。该网格显然是不可见的,但用于将轨迹划分为子段。每当轨迹与网格线相交时,它就会在那里被分割,并成为一个具有new_id的新子轨迹。

我附上了一个简单的手工图表来阐明我的期望。

enter image description here

可以看出轨迹是如何在网格线的交点处被划分的,并且这些线段中的每一个都有新的唯一id。

我正在研究 Python,并寻求一些 Python 实现链接、建议、算法,甚至是相同的伪代码。

如果有什么不清楚的地方请告诉我。

更新

为了将平面划分为网格,单元索引如下:

#finding cell id for each coordinate
#cellid = (coord / cellSize).astype(int)
cellid = (coord / 0.5).astype(int)
cellid
Out[] : array([[1, 1],
              [3, 1],
              [4, 2],
              [4, 4],
              [5, 5],
              [6, 5]])
#Getting x-cell id and y-cell id separately 
x_cellid = cellid[:,0]
y_cellid = cellid[:,1]

#finding total number of cells
xmax = df.xcoord.max()
xmin = df.xcoord.min()
ymax = df.ycoord.max()
ymin = df.ycoord.min()
no_of_xcells = math.floor((xmax-xmin)/ 0.5)
no_of_ycells = math.floor((ymax-ymin)/ 0.5)
total_cells = no_of_xcells * no_of_ycells
total_cells
Out[] : 25 

由于平面现在被分成 25 个单元格,每个单元格都有一个 cellid。为了找到交叉点,也许我可以检查轨迹中的下一个坐标,如果 cellid 保持不变,那么轨迹的那段在同一个单元格中并且与网格没有交叉点。比如说,如果 x_cellid[2] 大于 x_cellid[0],则线段与垂直网格线相交。虽然,我仍然不确定如何找到与网格线的交叉点并在交叉点上分割轨迹,为它们提供新的 id。

最佳答案

这可以通过 shapely 解决:

%matplotlib inline
import pylab as pl
from shapely.geometry import MultiLineString, LineString
import numpy as np
from matplotlib.collections import LineCollection

x0, y0, x1, y1 = -10, -10, 10, 10
n = 11

lines = []
for x in np.linspace(x0, x1, n):
    lines.append(((x, y0), (x, y1)))

for y in np.linspace(y0, y1, n):
    lines.append(((x0, y), (x1, y)))

grid = MultiLineString(lines)

x = np.linspace(-9, 9, 200)
y = np.sin(x)*x
line = LineString(np.c_[x, y])

fig, ax = pl.subplots()
for i, segment in enumerate(line.difference(grid)):
    x, y = segment.xy
    pl.plot(x, y)
    pl.text(np.mean(x), np.mean(y), str(i))

lc = LineCollection(lines, color="gray", lw=1, alpha=0.5)
ax.add_collection(lc);

结果:

enter image description here

不要使用 shapely,自己动手:

import pylab as pl
import numpy as np
from matplotlib.collections import LineCollection

x0, y0, x1, y1 = -10, -10, 10, 10
n = 11
xgrid = np.linspace(x0, x1, n)
ygrid = np.linspace(y0, y1, n)
x = np.linspace(-9, 9, 200)
y = np.sin(x)*x
t = np.arange(len(x))

idx_grid, idx_t = np.where((xgrid[:, None] - x[None, :-1]) * (xgrid[:, None] - x[None, 1:]) <= 0)
tx = idx_t + (xgrid[idx_grid] - x[idx_t]) / (x[idx_t+1] - x[idx_t])

idx_grid, idx_t = np.where((ygrid[:, None] - y[None, :-1]) * (ygrid[:, None] - y[None, 1:]) <= 0)
ty = idx_t + (ygrid[idx_grid] - y[idx_t]) / (y[idx_t+1] - y[idx_t])

t2 = np.sort(np.r_[t, tx, tx, ty, ty])

x2 = np.interp(t2, t, x)
y2 = np.interp(t2, t, y)

loc = np.where(np.diff(t2) == 0)[0] + 1

xlist = np.split(x2, loc)
ylist = np.split(y2, loc)


fig, ax = pl.subplots()
for i, (xp, yp) in enumerate(zip(xlist, ylist)):
    pl.plot(xp, yp)
    pl.text(np.mean(xp), np.mean(yp), str(i))


lines = []
for x in np.linspace(x0, x1, n):
    lines.append(((x, y0), (x, y1)))

for y in np.linspace(y0, y1, n):
    lines.append(((x0, y), (x1, y)))

lc = LineCollection(lines, color="gray", lw=1, alpha=0.5)
ax.add_collection(lc);

关于python - 如何找到线与网格的交点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45200428/

相关文章:

python - Pandas dataframe.loc 方法太慢

python - matplotlib 中从点到轴的虚线

python - 生成集合中字符串及其子字符串的所有组合——python

python - 是否可以通过导入向 python3 添加语句?或者我是否必须修改c文件并重新编译

python - 在 cython 中迭代数组,列表是否比 np.array 更快?

python - numpy ValueError 形状未对齐

c - 汉诺塔迭代 n > 3 钉

algorithm - 关于 Smith-Waterman 算法的问题

algorithm - 具有给定起点和终点城市的不归路旅行商

python - numpy:使用运算符 - 数组包含 None