如何确定2D格点绘图的循环边界以覆盖指定区域
2D格点绘图的边界覆盖解决方案
原代码通过基向量坐标的最小值估算循环边界,这种方法在非正交基(比如b1=[1,1]、b2=[1,2])下会遗漏部分格点,无法覆盖整个绘图区域。要解决这个问题,我们可以通过基向量逆变换来计算准确的循环边界,确保所有落在目标区域内的格点都被遍历到,同时避免设置过大的不合理边界。
核心思路
格点的定义是p = i*b1 + j*b2(i,j为整数),反过来,对于任意点p,对应的系数可以通过基矩阵的逆变换得到:[i,j]^T = B^{-1} * p,其中B是由b1、b2作为列向量组成的矩阵。我们只需要把绘图区域的四个顶点转换到系数空间,取这些系数的极值作为循环的边界,就能覆盖所有可能生成区域内格点的i和j值。
修改后的代码实现
替换原代码中计算循环边界的部分,完整代码如下:
import numpy as np import matplotlib.pyplot as plt from typing import List, Tuple def plotLattice(ax: plt.Axes, basis_vectors: List[np.ndarray], ldown: np.ndarray, rup: np.ndarray, color: str, linewidth: float, alpha: float) -> List[np.ndarray]: """ Draws a two-dimensional lattice. Args: ax: The Matplotlib Axes instance to plot on. basis_vectors: A list of two NumPy arrays representing the basis vectors of the lattice. ldown: A NumPy array representing the lower left corner of the rectangular area to draw the lattice in. rup: A NumPy array representing the upper right corner of the rectangular area to draw the lattice in. color: A string representing the color of the lattice points and basis vectors. linewidth: A float representing the linewidth of the lattice points. alpha: A float representing the alpha value of the lattice points. Returns: A list of NumPy arrays representing the lattice points. """ # get the basis vectors b1, b2 = np.array(basis_vectors[0]), np.array(basis_vectors[1]) # list to hold the lattice points points = [] # --- 核心修改:计算准确的循环边界 --- # 构造基矩阵(列向量形式) B = np.column_stack((b1, b2)) # 计算逆矩阵 B_inv = np.linalg.inv(B) # 定义绘图区域的四个顶点 corners = np.array([ ldown, [rup[0], ldown[1]], [ldown[0], rup[1]], rup ]) # 将所有顶点转换到系数空间(i,j) coeffs = corners @ B_inv # 提取所有i和j的极值 i_vals = coeffs[:, 0] j_vals = coeffs[:, 1] # 计算循环边界:取极值的上下取整,确保覆盖所有可能的整数系数 xmin = int(np.floor(i_vals.min())) xmax = int(np.ceil(i_vals.max())) ymin = int(np.floor(j_vals.min())) ymax = int(np.ceil(j_vals.max())) # --- 边界计算结束 --- for i in range(xmin, xmax + 1): for j in range(ymin, ymax + 1): # make the linear combination p = i * b1 + j * b2 # if the point is within the plotting area, plot it and add the point to the list if ldown[0] <= p[0] <= rup[0] and ldown[1] <= p[1] <= rup[1]: ax.scatter(p[0], p[1], color=color, linewidths=linewidth, alpha=alpha) points.append(p) # plot basis vectors ax.quiver(0, 0, b1[0], b1[1], color=color, scale_units='xy', scale=1, alpha=1) ax.quiver(0, 0, b2[0], b2[1], color=color, scale_units='xy', scale=1, alpha=1) return points if __name__ == '__main__': # 测试非正交基 b1 = np.array([1, 1]) b2 = np.array([1, 2]) basis_vectors = [b1, b2] # define the plotting area ldown = np.array([-15, -15]) rup = np.array([15, 15]) fig, ax = plt.subplots() points = plotLattice(ax, basis_vectors, ldown, rup, 'blue', 3, 0.25) # resize the plotting window mngr = plt.get_current_fig_manager() mngr.resize(960, 1080) # tune axis ax.set_aspect('equal') ax.grid(True, which='both') ax.set_xlim(ldown[0], rup[0]) ax.set_ylim(ldown[1], rup[1]) # show the plot plt.show()
说明
- 这段代码通过逆变换将绘图区域的顶点映射到系数空间,确保所有能生成区域内格点的整数i、j都被包含在循环范围内,不会遗漏任何格点。
- 循环边界是基于区域顶点的系数极值计算的,不会出现过大的不合理范围,保证了代码的效率。
内容的提问来源于stack exchange,提问作者jupiter_jazz
相关产品推荐
相关产品推荐

