2011-03-28 58 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