我一直在思考如何实现一个算法来计算多边形关于一个点的绕数。目前的实现方式如下:(注意更新代码以使其正常工作)
(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
等。 - rest函数将向量转换为列表
我可以想到一种使用for
和索引的实现方式,但我也听说最好不要使用索引。
有没有处理需要访问连续值的向量算法的惯用方法?