2011-07-06 73 views
5

我有一個存儲爲向量矢量的x,y點列表,我想找出邊界。獲取x,y點列表的邊界

例如,給定這樣的:

[[0 0] [20 30] [-50 -70] [200 300]] 

其結果將是:

{:x -50, :y -70, :x2 200, :y2 300} 

這裏是我到目前爲止所。它給出了期望的結果,但似乎冗長而且對我來說不是很合適。

(defn get-stroke-bounds [vector-of-points] 
    (reduce (fn [m [x y]] 
     {:x (min (:x m Integer/MAX_VALUE) x) 
     :y (min (:y m Integer/MAX_VALUE) y) 
     :x2 (max (:x2 m Integer/MIN_VALUE) x) 
     :y2 (max (:y2 m Integer/MIN_VALUE) y)}) 
     {} 
     (vector-of-points))) 

有關如何改進它的任何想法?謝謝!

回答

3

如果我已經在使用向量輸入點,我想要返回值是在相同的格式。考慮到這一點,我認爲這是一個很好的習慣解決方案:

(defn bounds 
    [points] 
    (let [xs (sort (map first points)) 
     ys (sort (map second points))] 
    (list [(first xs) (first ys)] 
      [(last xs) (last ys)]))) 
+0

將'first'和'second'映射到列表中以獲得可排序的內容!當然!謝謝! – jhickner

4

您的解決方案已經相當不錯了!這是相當習慣的,並且在算法上最優的點數(也就是比排序的方法更好)的點數也是O(n)。

但在這裏做,你可能會感興趣的另一種方式....創建,主要是因爲我的高階函數:-)

(defn get-stroke-bounds [stroke] 
    (zipmap 
     [:x :y :x2 :y2] 
     (map 
     (fn [[getter reducer]] 
      (reduce 
      reducer 
      (map getter stroke))) 
     [ 
      [first min] 
      [second min] 
      [first max] 
      [second max]]))) 
+0

絕對有趣!花了我一段時間來了解它的工作原理。很酷! – jhickner

1

我不認爲你的解決方案的忠實粉絲不是clojure-ey。但是如果你喜歡較少的代碼,你可以嘗試一個有序集合。

(let [v [[0 0] [20 30] [-50 -70] [200 300]] 
     v-sorted (apply sorted-set v)] 
    [(first v-sorted) (last v-sorted)]) 

更新:對不起,上面的代碼是不正確的。對單獨排序的x和y進行排序以找到不是最大或最小點的邊界是必要的。約翰的solution更好,除非套是首選。