You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确定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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 13:17:57