2011-03-28 29 views
3

要做到这一点,最好的方法是什么?这里就是我有这么远从Clojure的两个点创建线段

(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运动。

谢谢。

回答

2

我觉得这是一个非常优雅的解决方案:

(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。我认为这并不重要。

+0

就像一副手套。谢谢! – 2011-03-28 20:29:06

0

这里有一个简单的解决方案,还允许对角线:

(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的解决方案,这将返回点的懒序列,而不是一个向量:我觉得这是最有用的形式假设你以后要依次对线段上的每个点进行操作。

+0

谢谢。我更新了我的问题以获取lazy-seq而不是vector。不知道为什么我把一个载体。懒惰seq是有道理的。 – 2011-03-28 20:32:34