在 Clojure 中从两点创建线段

发布于 2024-10-26 13:48:07 字数 436 浏览 1 评论 0原文

执行此操作的最佳方法是什么?这是我到目前为止所得到的

(defn line-segment [start end]
  (let [x-direction (abs (- (first end) (first start)))
        y-direction (abs (- (last end) (last start)))]
    (cond
      (= 0 x-direction) (something ...)
      (= 0 y-direction) (something ...))))

这是我的最终目标

user=> (line-segment [5 6] [5 8])
([5 6] [5 7] [5 8])

是的,没有对角线,只有 x 或 y 运动。

谢谢。

What's the best way to go about doing this? Here's what I've got so far

(defn line-segment [start end]
  (let [x-direction (abs (- (first end) (first start)))
        y-direction (abs (- (last end) (last start)))]
    (cond
      (= 0 x-direction) (something ...)
      (= 0 y-direction) (something ...))))

Here's my end goal

user=> (line-segment [5 6] [5 8])
([5 6] [5 7] [5 8])

And yes, there are no diagonals, only x or y movement.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

相思碎 2024-11-02 13:48:07

我认为这是一个非常优雅的解决方案:

(defn line-segment [start end]
  (let [x1 (first start) x2 (first end)
        y1 (last start)  y2 (last end)
        dx (if (> x1 x2) -1 1)
        dy (if (> y1 y2) -1 1)]
    (for [x (range x1 (+ dx x2) dx)
          y (range y1 (+ dy y2) dy)]
      [x y])))

REPL 会话:

user> (line-segment [5 6] [5 8])
([5 6] [5 7] [5 8])
user> (line-segment [5 8] [5 6])
([5 8] [5 7] [5 6])
user> (line-segment [-2 7] [1 7])
([-2 7] [-1 7] [0 7] [1 7])
user> (line-segment [1 7] [-2 7])
([1 7] [0 7] [-1 7] [-2 7])

即使您的示例输出被格式化为向量,该函数也会返回一个 LazySeq。我以为这并不重要。

I think this is a pretty elegant solution:

(defn line-segment [start end]
  (let [x1 (first start) x2 (first end)
        y1 (last start)  y2 (last end)
        dx (if (> x1 x2) -1 1)
        dy (if (> y1 y2) -1 1)]
    (for [x (range x1 (+ dx x2) dx)
          y (range y1 (+ dy y2) dy)]
      [x y])))

REPL session:

user> (line-segment [5 6] [5 8])
([5 6] [5 7] [5 8])
user> (line-segment [5 8] [5 6])
([5 8] [5 7] [5 6])
user> (line-segment [-2 7] [1 7])
([-2 7] [-1 7] [0 7] [1 7])
user> (line-segment [1 7] [-2 7])
([1 7] [0 7] [-1 7] [-2 7])

This function returns a LazySeq even though your sample output was formatted as a vector. I figured this wasn't important.

深居我梦 2024-11-02 13:48:07

这是一个简单的解决方案,也允许对角线:

(use 'clojure.contrib.math)

(defn line-segment [start end]
  (let [x1 (first start) x2 (first end)
        y1 (last start)  y2 (last end)
        xdiff (- x2 x1)
        ydiff (- y2 y1)
        maxdiff (max (abs xdiff) (abs ydiff))
        dx (/ xdiff maxdiff)
        dy (/ ydiff maxdiff)]
    (for [i (range (inc maxdiff))]
      [(round (+ x1 (* i dx))) (round (+ y1 (* i dy)))])))

与 dbryne 的解决方案一样,这返回点的惰性序列而不是向量:我认为这是最有用的形式,假设您随后想要对线上的每个点执行某些操作依次分段。

Here's a simple solution that also allows diagonals:

(use 'clojure.contrib.math)

(defn line-segment [start end]
  (let [x1 (first start) x2 (first end)
        y1 (last start)  y2 (last end)
        xdiff (- x2 x1)
        ydiff (- y2 y1)
        maxdiff (max (abs xdiff) (abs ydiff))
        dx (/ xdiff maxdiff)
        dy (/ ydiff maxdiff)]
    (for [i (range (inc maxdiff))]
      [(round (+ x1 (* i dx))) (round (+ y1 (* i dy)))])))

As with dbryne's solution, this returns a lazy sequence of points rather than a vector: I think this is the most useful form assuming that you subsequently want to do something with each of the points on the line segment in turn.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文