我一直在想如何實現一個algorithm來計算相對於一個點的多邊形的圈數。目前實現如下:(注意更新,以便代碼工作)第i個和第i + 1個元素循環的習慣clojure
(defn winding-num
"Return winding number of polygon
see Alciatore "
[poly point]
; translate poly such that point is at origin
(let [translated-poly (map #(vec-f - % point) poly)]
; w is wind-num
(loop [vertices translated-poly w 0]
(cond
(= (count vertices) 1)
w
:else
(let [x1 (first (first vertices))
x2 (first (second vertices))
y1 (second (first vertices))
y2 (second (second vertices))]
(cond
(and (< (* y1 y2) 0)
(> (+ x1 (/ (* y1 (- x2 x1))
(- y1 y2)))
0))
(if (< y1 0)
(recur (rest vertices) (inc w))
(recur (rest vertices) (dec w)))
(and (zero? y1)
(> x1 0))
(if (> y2 0)
(recur (rest vertices) (+ w 0.5))
(recur (rest vertices) (- w 0.5)))
(and (zero? y2)
(> x2 0))
(if (< y1 0)
(recur (rest vertices) (+ w 0.5))
(recur (rest vertices) (- w 0.5)))
:else
(recur (rest vertices) w)))))))
我的問題,這是
- 人們說這是最好的時候可能使用比明確的較高水平運行的循環結構遞歸;例如
map
,for
,reduce
等 - 其餘的功能載體轉換成列表
我能想到用for
和指標實現的,但我也聽到它最好不使用索引。
是否有一種處理矢量算法的慣用方式,在每次迭代中需要訪問連續值?
什麼是'vec-f'? – 2013-04-30 03:17:20
vec-f只是我寫的一個函數,用於使矢量操作更加方便,在這種情況下,它會減少另一個矢量 – zenna 2013-04-30 04:08:17
正如Rob在下面所說的,您可能正在尋找分區。如果你追求速度,那麼使用loop/recur應該是最快的。您可能還想考慮在let中使用解構來刪除像這樣的一些重複: (let [[x1 y1] [x2 y2]] verticies coll(rest vertices)] ... – bmaddy 2013-04-30 15:43:01