2016-09-18 99 views
0

我在Clojure Quil庫中計算算法時遇到了嚴重問題。我一直在嘗試使用功能性中間件模式製作一些網絡/植絨模式圖,如this。我的問題是如何在Quild中創建一個嵌套的「for循環」,以便將任何給定的點連接到任何其他點上?區別在於連接1→2→3→4 ......等的一組點和連接1-> 2 1-> 3 1-> 4 2-> 3 2-> 4的一組點等等Clojure Quil:繪製線條時嵌套循環

我的程序看起來像這樣,雖然我試圖編輯它爲這個問題的通用。

(ns stack-question.core 
    (:require [quil.core :as q] 
      [quil.middleware :as m])) 

;how to draw the point 
(defn draw-points [point] 
    (q/point (:x point) (:y point))) 

;the main data structure 
(defn make-point [num] 
    {:name num 
    :x (rand 500.0) 
    :y (rand 500.0)})  

;draws connections between two objects 
(defn connections [p1 p2] 
     (q/stroke 200 200 100 150) 
     (q/line (:x p1) (:y p1) (:x p2) (:y p2))))) 

(defn setup [] 
    (q/frame-rate 30) 
    {:points (map make-points (take 1000 (range)))}) 

;this function isn't important to the question 
;but let's just say that the points move position each frame 
(defn update-state [state] 
    (update state :points move-group)) 

;this is the problem function here. 
;I'm trying to map over the collection, but with a fixed head 
;and do so for each element in the collection 
(defn make-conts [coll] 
    (loop [x coll] 
    (when (not (empty? (rest coll))) 
     (map (partial connections (first x)) (rest x)) 
     (recur (rest x))))) 


(defn draw-state [state] 
    (do 
    ;(q/frame-rate 1) 
    (q/background 0) 
    (doseq [x (map draw-point (:points state))] x) 
    (doseq [x (make-conts (:points state))] x))) 

(q/defsketch stack-question 
    :title "GL" 
    :size [500 500] 
    :setup setup 
    :update update-state 
    :draw draw-state 
    :middleware [m/fun-mode] 
    :renderer :opengl) 

我希望這不是完全不透明的。

回答

0

有兩個問題與您的代碼:

第一個是你在when語句中檢查(rest coll)代替(rest x),導致一個無限循環。

第二個是map返回一個惰性序列,這意味着connections的調用沒有發生。這可以通過將電話打到mapdoall來解決,但由於您對副作用感興趣,而不是返回值,因此應該使用doseq來代替。

這個版本的功能(其中多餘loop也被移除)的應工作:

(defn make-conts [coll] 
    (when (not (empty? (rest coll))) 
     (doseq [endpoint (rest coll)] 
     (connections (first coll) endpoint)) 
     (recur (rest coll)))) 

不需要編寫代碼來自己生成的組合,您可以使用combinationsclojure.math.combinatorics

(require '[clojure.math.combinatorics :as combi]) 

(defn make-conts [coll] 
    (doseq [[p1 p2] (combi/combinations coll 2)] 
    (connections p1 p2)))