You need to enable JavaScript to run this app. 如何在数组中选取两个非对齐坐标之间的像素点
优惠活动
大模型
产品
解决方案
定价
更多

如何在数组中选取两个非对齐坐标之间的像素点

非共行/共列点连线的像素选取实现

选取两个非共行、非共列坐标之间的离散像素点,本质是低分辨率整数数组上的直线光栅化问题,不需要复杂的几何推导,有成熟的工程化实现方案可以直接落地,结合你提到的40x40数组、取[10,10]到[17,32]连线像素的场景,具体操作逻辑如下:

核心参数计算

首先把两个端点的坐标固定下来,计算基础差值与步进方向,避免取点偏离直线走向:

  • 记两个端点为(x0, y0)和(x1, y1),对应你举例的参数就是x0=10、y0=10,x1=17、y1=32
  • 计算两个方向的坐标增量绝对值:dx = abs(x1 - x0),dy = abs(y1 - y0),本例中dx=7,dy=22
  • 计算两个方向的步进方向:sx = 1 if x1 > x0 else -1,sy = 1 if y1 > y0 else -1,本例中两个方向的步进值都为1,因为终点坐标大于起点坐标

取点逻辑适配

因为两个方向的增量不一致,需要选择增量更大的方向作为主遍历方向,避免取点出现断层:

  • 若dy > dx(如本例dy=22远大于dx=7),固定沿着y方向逐点遍历,总遍历次数等于dy+1,每移动一个y步,通过累计偏移量计算对应的x坐标,累计值取整后即为当前位置的像素坐标
  • 若dx > dy,反过来沿着x方向逐点遍历,每步通过累计偏移量计算对应的y坐标
  • 若dx = dy,即为45度斜线,每步x、y各步进1即可,不存在累计误差

可直接复用的成熟实现

上述累计取整的逻辑其实就是经典的Bresenham直线算法,完全用整数运算实现,没有浮点计算开销,非常适配数组像素操作的场景,简化后的通用实现如下:

def get_line_pixels(x0, y0, x1, y1):
    dx = abs(x1 - x0)
    dy = abs(y1 - y0)
    sx = 1 if x1 > x0 else -1
    sy = 1 if y1 > y0 else -1
    # 初始化误差变量
    err = dx - dy
    points = []
    while True:
        points.append((x0, y0))
        # 碰到终点就停止
        if x0 == x1 and y0 == y1:
            break
        e2 = 2 * err
        if e2 > -dy:
            err -= dy
            x0 += sx
        if e2 < dx:
            err += dx
            y0 += sy
    return points

针对你举的例子,直接调用get_line_pixels(10, 10, 17, 32),返回的元组列表就是两点连线上的所有有效像素坐标,可以直接用来索引数组取值。

特殊场景调整

  • 如果要取从起点出发的半直线(沿直线方向延伸到数组边界),只需要把循环的停止条件从“碰到终点就停”改成“坐标超出40x40数组的边界就停”即可
  • 不建议直接用斜率计算加四舍五入的方式取点,这种纯浮点取整的方案很容易在长斜线上出现像素错位,Bresenham的误差累积逻辑就是专门为了消除这个问题设计的,取点连续性远好于直接取整的方案

内容的提问来源于stack exchange,提问作者Coolcrab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.07 05:45:07