Получение модуля из 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)))

Пара проблем, с которыми вы сталкиваетесь:

  1. Вводом в sin является плавающее значение в радианах. Моя хитрость деления на 100 здесь просто гарантирует, что мы получаем хороший непрерывный вывод. Практически, если вы хотите циклически использовать каждые n пикселей, вам нужно использовать 2 PI / n для регулировки x.
  2. Округление значения даст вам очки, так как область греха от 1 до -1. Здесь я корректирую, добавляя на 100.
  3. Где вы возитесь с х, будет зависеть от точного требования. Здесь я просто упаковываю ваше значение x, беря его модуль в функции рисования.

Надеюсь это поможет.

Другие вопросы по тегам