ポイントに対するポリゴンの巻き数を計算するアルゴリズムを実装する方法を考えようとしています。現在の実装は次のとおりです: (コードが機能するように更新されていることに注意してください)
(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
インデックスを使わないほうがいいとも聞きます。
各反復で連続する値にアクセスする必要があるベクトル アルゴリズムを処理する慣用的な方法はありますか?