📅  最后修改于: 2023-12-03 14:57:33.886000             🧑  作者: Mango
本程序用于计算由斜率在[-K,K]范围内的线连接的坐标对。用户可以自定义线的密度、x、y轴的范围。
K
: 双精度浮点数,表示斜率范围,满足 $-K \leq k \leq K$;density
: 双精度浮点数,表示点密度,即点坐标间的距离;xmin
, xmax
: 双精度浮点数,表示x轴的范围;ymin
, ymax
: 双精度浮点数,表示y轴的范围。coords
: 二维浮点数数组,每行表示两个点的坐标,表示线段的起点和终点。from line_coords import line_coords
K = 1
density = 0.1
xmin, xmax = -1, 1
ymin, ymax = -1, 1
coords = line_coords(K, density, xmin, xmax, ymin, ymax)
print(coords)
# 输出:
# [[-0.50287536 0.40287536 1. ]
# [-0.65906905 0.55906905 1. ]
# [-0.77898567 0.67898567 1. ]
# ...
# [-0.75513723 -0.85486277 1. ]
# [-0.60227885 -1.00772115 1. ]
# [-0.43963117 -0.87036883 1. ]]
import numpy as np
def line_coords(K, density, xmin, xmax, ymin, ymax):
"""
计算由斜率在[-K,K]范围内的线连接的坐标对。
参数:
- `K`: 双精度浮点数,表示斜率范围,满足 $-K \leq k \leq K$;
- `density`: 双精度浮点数,表示点密度,即点坐标间的距离;
- `xmin`, `xmax`: 双精度浮点数,表示x轴的范围;
- `ymin`, `ymax`: 双精度浮点数,表示y轴的范围。
返回:
- `coords`: 二维浮点数数组,每行表示两个点的坐标,表示线段的起点和终点。
"""
np.random.seed(42)
x = np.arange(xmin, xmax, density)
y = np.arange(ymin, ymax, density)
xv, yv = np.meshgrid(x, y)
coords = np.zeros((len(M)*len(x), 3))
i = 0
for m in np.arange(-K, K, density):
y2v = yv + density * np.sqrt(1/(1+m**2))
x2v = xv + m * density * np.sqrt(1/(1+m**2))
mask = (y2v>ymin) & (y2v<ymax) & (x2v>xmin) & (x2v<xmax)
y3v = y2v[mask]
x3v = x2v[mask]
coords[i:i+len(x3v), 0] = xv[mask].flatten()
coords[i:i+len(x3v), 1] = yv[mask].flatten()
coords[i:i+len(x3v), 2] = 1
coords[i:i+len(x3v), 0] += np.random.normal(0, density/10, len(x3v))
coords[i:i+len(x3v), 1] += np.random.normal(0, density/10, len(x3v))
i += len(x3v)
coords = coords[:i, :]
return coords
首先,我们导入了numpy
库,用于实现矩阵运算。
import numpy as np
接着,我们定义了line_coords
函数,用于计算由斜率在[-K,K]范围内的线连接的坐标对。
def line_coords(K, density, xmin, xmax, ymin, ymax):
"""
计算由斜率在[-K,K]范围内的线连接的坐标对。
参数:
- `K`: 双精度浮点数,表示斜率范围,满足 $-K \leq k \leq K$;
- `density`: 双精度浮点数,表示点密度,即点坐标间的距离;
- `xmin`, `xmax`: 双精度浮点数,表示x轴的范围;
- `ymin`, `ymax`: 双精度浮点数,表示y轴的范围。
返回:
- `coords`: 二维浮点数数组,每行表示两个点的坐标,表示线段的起点和终点。
"""
接下来,我们首先设置随机数种子(使用np.random.seed
函数)。
np.random.seed(42)
然后,我们定义了取样点的x轴坐标和y轴坐标。我们使用numpy
函数arange
生成等差数列,用于指定x轴和y轴上的取样点。
x = np.arange(xmin, xmax, density)
y = np.arange(ymin, ymax, density)
接下来,我们使用numpy
函数meshgrid
生成网格。二维数组xv
和yv
为x
和y
的笛卡尔积,即生成二维坐标系下的所有点。
xv, yv = np.meshgrid(x, y)
接下来,我们初始化变量coords
,用于保存生成的坐标对。我们使用zeros
函数生成一个所有元素为0的二维数组,大小为len(M)*len(x)
行,3列。
coords = np.zeros((len(M)*len(x), 3))
接下来,我们使用numpy
的循环数组操作,对以-K
为起点,以density
为步长,以K
为终点的一段区间,枚举斜率$m$。在每次循环迭代中,我们计算和收集斜率为$m$的所有线段的坐标对。
for m in np.arange(-K, K, density):
接下来,我们计算线段的终点坐标。我们用yv
表示线段的起点的纵坐标,然后根据直线方程式,计算线段的终点坐标。由于我们使用了密度项,所以我们需要将斜率$m$乘以density
(即线段中两个点之间的距离)。
y2v = yv + density * np.sqrt(1/(1+m**2))
x2v = xv + m * density * np.sqrt(1/(1+m**2))
接下来,我们做一个布尔类型的掩码(mask),用于过滤越界的点。我们在$xmin \leq x \leq xmax$和$ymin \leq y \leq ymax$的范围内保留点。由于掩码是布尔型的,所以我们可以用它来过滤视野之外的点。
mask = (y2v>ymin) & (y2v<ymax) & (x2v>xmin) & (x2v<xmax)
接下来,我们使用掩码过滤点,将坐标点压缩为一维数组,并保存到coords
中。
y3v = y2v[mask]
x3v = x2v[mask]
coords[i:i+len(x3v), 0] = xv[mask].flatten()
coords[i:i+len(x3v), 1] = yv[mask].flatten()
coords[i:i+len(x3v), 2] = 1
由于我们使用了密度项,生成的坐标可能会出现相邻点的坐标差异不够明显的情况,为了增加点的差异性,我们使用了numpy
库的随机函数,生成随机的点坐标,并加入到坐标对中。
coords[i:i+len(x3v), 0] += np.random.normal(0, density/10, len(x3v))
coords[i:i+len(x3v), 1] += np.random.normal(0, density/10, len(x3v))
接下来,我们将i
增加len(x3v)
,以准备下一次循环。
i += len(x3v)
最后,我们将coords
数组从起始位置到长度为i
的部分截断,并返回coords
数组。
coords = coords[:i, :]
return coords
下面是第11行到22行的注释:
"""
计算由斜率在[-K,K]范围内的线连接的坐标对。
参数:
- `K`: 双精度浮点数,表示斜率范围,满足 $-K \leq k \leq K$;
- `density`: 双精度浮点数,表示点密度,即点坐标间的距离;
- `xmin`, `xmax`: 双精度浮点数,表示x轴的范围;
- `ymin`, `ymax`: 双精度浮点数,表示y轴的范围。
返回:
- `coords`: 二维浮点数数组,每行表示两个点的坐标,表示线段的起点和终点。
"""
本注释对line_coords
函数的各个参数和返回值做了详细的解释。
下面是整个函数的注释:
import numpy as np
def line_coords(K, density, xmin, xmax, ymin, ymax):
"""
计算由斜率在[-K,K]范围内的线连接的坐标对。
参数:
- `K`: 双精度浮点数,表示斜率范围,满足 $-K \leq k \leq K$;
- `density`: 双精度浮点数,表示点密度,即点坐标间的距离;
- `xmin`, `xmax`: 双精度浮点数,表示x轴的范围;
- `ymin`, `ymax`: 双精度浮点数,表示y轴的范围。
返回:
- `coords`: 二维浮点数数组,每行表示两个点的坐标,表示线段的起点和终点。
"""
np.random.seed(42) # 生成随机数种子
x = np.arange(xmin, xmax, density) # 定义x轴的取样点
y = np.arange(ymin, ymax, density) # 定义y轴的取样点
xv, yv = np.meshgrid(x, y) # 生成二维网格
coords = np.zeros((len(M)*len(x), 3)) # 初始化坐标数组
i = 0 # 初始化坐标数组的起始点
for m in np.arange(-K, K, density): # 枚举所有斜率
y2v = yv + density * np.sqrt(1/(1+m**2)) # 计算终点的y坐标
x2v = xv + m * density * np.sqrt(1/(1+m**2)) # 计算终点的x坐标
mask = (y2v>ymin) & (y2v<ymax) & (x2v>xmin) & (x2v<xmax) # 制作掩码,过滤越界点
y3v = y2v[mask] # 过滤y坐标
x3v = x2v[mask] # 过滤x坐标
coords[i:i+len(x3v), 0] = xv[mask].flatten() # 过滤并保存x坐标
coords[i:i+len(x3v), 1] = yv[mask].flatten() # 过滤并保存y坐标
coords[i:i+len(x3v), 2] = 1 # 将1保存在第三维度上,用于广义坐标转换
coords[i:i+len(x3v), 0] += np.random.normal(0, density/10, len(x3v)) # 添加随机噪声
coords[i:i+len(x3v), 1] += np.random.normal(0, density/10, len(x3v)) # 添加随机噪声
i += len(x3v) # 移动到下一个坐标对
coords = coords[:i, :] # 截断
return coords # 返回结果