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

Haskell实现:基于两点获取所有(Int, Int)型直线点的函数

生成两点间直线上的所有整数点的Haskell函数

嘿,我明白你被这个问题困扰很久了,咱们来一步步解决它。要获取两个(Int, Int)点连线上的所有整数坐标点,核心思路是利用**最大公约数(gcd)**来确定最小步长,这样就能遍历所有不遗漏的整数点。

实现代码

linePoints :: (Int, Int) -> (Int, Int) -> [(Int, Int)]
linePoints p1@(x1, y1) p2@(x2, y2)
  | p1 == p2  = [p1]  -- 两点相同的特殊情况
  | otherwise = take (g + 1) $ iterate step p1
  where
    dx = x2 - x1       -- x方向总位移
    dy = y2 - y1       -- y方向总位移
    g = gcd (abs dx) (abs dy)  -- 位移的最大公约数
    step (x, y) = (x + dx `div` g, y + dy `div` g)  -- 每一步的移动量

代码解释

  1. 特殊情况处理:如果传入的两个点完全相同,直接返回只包含该点的列表,避免无效计算。
  2. 计算位移与步长:
    • dx和dy分别是两点在x、y方向的总距离,正负号代表移动方向。
    • g是dx和dy绝对值的最大公约数,它决定了直线上整数点的总数(g + 1个,包含起点和终点)。
    • step函数定义了每次移动的最小单位:把总位移除以g,保证每一步移动后都落在整数坐标上,且不会跳过任何直线上的整数点。
  3. 生成点序列:用iterate生成从起点开始的无限点序列,再用take (g + 1)截取到终点为止的所有点,刚好覆盖整条直线上的所有整数点。

示例用法

-- 斜线方向的直线点
linePoints (0,0) (3,6)  -- 输出: [(0,0),(1,2),(2,4),(3,6)]

-- 垂直直线的情况
linePoints (5,5) (5,10) -- 输出: [(5,5),(5,6),(5,7),(5,8),(5,9),(5,10)]

-- 反向输入两点的情况
linePoints (2,3) (0,0)  -- 输出: [(2,3),(0,0)]

这个函数能完美覆盖所有整数点的情况,不管是水平、垂直还是任意斜线方向的直线都适用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:01:39