Получение модуля из seq->stream
Код ниже рисует мне синусоидальную волну по всему экрану и за его пределами. Тем не менее, я хочу, чтобы х никогда не превышал (ширина). В этот момент окно должно быть очищено, и волна должна быть нарисована снова, начиная с 0. Я пытался
(set-state! :x (mod (seq->stream x) (width)))
но это не сработало. Я проверил несколько примеров, попробовал код, который использовал проверку (> x (width))
, попытался поместить логику в функцию рисования, но они тоже не работают.
Я хотел бы нарисовать непрерывный сигнал (например, электрокардиограмму) на ограниченном дисплее. Буду признателен за любую помощь.
(ns soso.core
(:require [quil.core :refer :all]
[quil.helpers.seqs :refer [seq->stream range-incl]]))
(defn setup []
(smooth)
(frame-rate 100)
(background 255)
(let [x (range-incl)]
(set-state! :x (seq->stream x))))
(defn draw []
(stroke 0)
(stroke-weight 2)
(let [x ((state :x))
y (round (* 100 (abs (sin x))))]
(ellipse x y 4 4)))
редактировать
Когда я попытался вставить логику в функцию рисования, я написал (set-state! :x 0)
в функции настройки и поместите следующий код в функцию рисования:
(let [x (if (> ((state :x)) 10)
0
(inc ((state :x))))])
Но это не сработало и не выдало никакой ошибки ни в один из буферов nrepl. Чтобы увидеть, что случилось, я попробовал этот код в пользовательском репле:
(let [x 0]
(take 20
(if (> x 10)
0
(inc x))))
Даже если бы я попробовал этот код, обернув оператор if внутри (into '())
код жаловался: "IllegalArgumentException Не знаю, как создать ISeq из: java.lang.Long clojure.lang.RT.seqFrom". То же самое с:
(loop [x 0]
(if (> x 10)
0
(recur (inc x))))
Что не так с этим утверждением if? Api clojure говорит, что если тестирует условие теста, а затем оценивает и дает то или иное, соответственно, ответвления. Если он дает, он должен выплевывать это целое число, которое, в свою очередь, добавляется в список, который, в свою очередь, должен быть перечислен функцией take, я думаю.
1 ответ
Нечто подобное, похоже, дает тот эффект, который вы ищете.
(defn draw []
(stroke 0)
(stroke-weight 2)
(let [x ((state :x))
y (+ 100 (* 100 (sin (/ x 100))))]
(ellipse (mod x (width)) y 4 4)))
Пара проблем, с которыми вы сталкиваетесь:
- Вводом в sin является плавающее значение в радианах. Моя хитрость деления на 100 здесь просто гарантирует, что мы получаем хороший непрерывный вывод. Практически, если вы хотите циклически использовать каждые n пикселей, вам нужно использовать 2 PI / n для регулировки x.
- Округление значения даст вам очки, так как область греха от 1 до -1. Здесь я корректирую, добавляя на 100.
- Где вы возитесь с х, будет зависеть от точного требования. Здесь я просто упаковываю ваше значение x, беря его модуль в функции рисования.
Надеюсь это поможет.