我在 Java/Processing 中有以下代码
posX += (targetX - posX) * easing;
posY += (targetY - posY) * easing;
但我正在努力将其翻译成 Clojure,任何帮助将不胜感激!
我在 Java/Processing 中有以下代码
posX += (targetX - posX) * easing;
posY += (targetY - posY) * easing;
但我正在努力将其翻译成 Clojure,任何帮助将不胜感激!
根据您的代码片段,我猜您基本上是在使用另一组和一个缓动因子来转换一组坐标。
我将定义一个函数来以下列方式封装转换:
(defn ease-coord [factor src tgt]
(+ src (* (- tgt src) factor)))
(defn ease [factor src tgt]
(map (partial ease-coord factor) src tgt))
(ease 0.1 [1 2] [3 10])
;=> (1.2 2.8)
(ease 0.1 [1 2 3] [3 10 5])
;=> (1.2 2.8 3.2)
请注意,该ease
函数实际上适用于具有任意数量坐标的向量和列表。
如果您要对矢量数学进行大量工作,我建议您使用core.matrix 。它为所有常见的数学函数(+、-、* 等)提供向量覆盖,并允许您透明地使用表示为常规 Clojure 向量的数学向量。
下面是它的样子:
(use 'clojure.core.matrix.operators)
(defn lerp [start end factor]
(+ start (* (- end start) factor)))
(lerp [1 2] [10 10] 0.1)
=> [1.9 2.8]
如果您关心性能,您还可以使用vectorz-clj实现,它使用(x,y) 坐标core.matrix
的专用快速类型来增强。Vector2
什么是posX、posY?
它们可以是原子。
(def posX (atom 0))
(def posY (atom 0))
如果你想改变posX,你可以写一个函数
(defn update-posx
[targetX easing]
(swap!
posX
#(+ % (* (- targetX %) easing))))
更新类似于
(update-posx 20 30)
免责声明:我正在学习 clojure,这个解决方案很可能不是惯用的。
; Let *tx*, *ty* be your target coordinate
; Let sx, sy be your starting coordinate
; Let *eg* be your easing
(def ^:dynamic *eg* 0.05)
(def ^:dynamic *tx* 100)
(def ^:dynamic *ty* 100)
(defn next-position [[sx sy]] [(+ sx (* (- *tx* sx) *eg*)) (+ sy (* (- *ty* sy) *eg*))])
(defn positions [[x y]] (iterate next-position [x y]))
; To get the next position
(next-position [5 6])
; To get the next 100 positions
(take 100 (positions [5 6]))