Clojure Quil:画线时嵌套循环
Clojure Quil: nested loops while drawing lines
我在计算 Clojure Quil 库中的算法时遇到了严重的问题。我一直在尝试使用功能中间件模式制作一些 networks/flocking 模式的图表,例如 this 。我的问题是如何在 Quild 中创建嵌套的 "for loop" 以便用一条线将任何给定点连接到任何其他点?区别在于一组点连接 1->2 3->4...等和一组连接 1->2 1->3 1->4 2->3 2->4...等等
我的程序看起来像这样,尽管为了这个问题,我试图将它编辑为通用的。
(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)
我希望这不是完全不透明。
您的代码有两个问题:
首先是您在 when
语句中检查 (rest coll)
而不是 (rest x)
,从而导致无限循环。
第二个是 map
return 是一个惰性序列,这意味着对 connections
的调用没有发生。这可以通过使用 doall
包装对 map
的调用来解决,但是由于您对副作用感兴趣,而不是 return 值,因此您应该改用 doseq
。
这个版本的函数(其中多余的 loop
也被删除)应该可以工作:
(defn make-conts [coll]
(when (not (empty? (rest coll)))
(doseq [endpoint (rest coll)]
(connections (first coll) endpoint))
(recur (rest coll))))
您可以使用 clojure.math.combinatorics
:
中的 combinations
而不是自己编写代码来生成组合
(require '[clojure.math.combinatorics :as combi])
(defn make-conts [coll]
(doseq [[p1 p2] (combi/combinations coll 2)]
(connections p1 p2)))
我在计算 Clojure Quil 库中的算法时遇到了严重的问题。我一直在尝试使用功能中间件模式制作一些 networks/flocking 模式的图表,例如 this 。我的问题是如何在 Quild 中创建嵌套的 "for loop" 以便用一条线将任何给定点连接到任何其他点?区别在于一组点连接 1->2 3->4...等和一组连接 1->2 1->3 1->4 2->3 2->4...等等
我的程序看起来像这样,尽管为了这个问题,我试图将它编辑为通用的。
(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)
我希望这不是完全不透明。
您的代码有两个问题:
首先是您在 when
语句中检查 (rest coll)
而不是 (rest x)
,从而导致无限循环。
第二个是 map
return 是一个惰性序列,这意味着对 connections
的调用没有发生。这可以通过使用 doall
包装对 map
的调用来解决,但是由于您对副作用感兴趣,而不是 return 值,因此您应该改用 doseq
。
这个版本的函数(其中多余的 loop
也被删除)应该可以工作:
(defn make-conts [coll]
(when (not (empty? (rest coll)))
(doseq [endpoint (rest coll)]
(connections (first coll) endpoint))
(recur (rest coll))))
您可以使用 clojure.math.combinatorics
:
combinations
而不是自己编写代码来生成组合
(require '[clojure.math.combinatorics :as combi])
(defn make-conts [coll]
(doseq [[p1 p2] (combi/combinations coll 2)]
(connections p1 p2)))