Clojure图像合成的DSL

6

我正在尝试用Clojure创建一个小型图像合成库/DSL。基本上,想法是允许库的用户组合一些数学函数来程序化地创建有趣的图像。

这些函数需要在双精度值上操作,并采用将位置向量转换为颜色值的形式,例如 (x,y,z) -> (r,g,b,a)

然而,我面临着一些有趣的设计决策:

  • 输入可能具有1、2、3或甚至4个维度(x、y、z加上时间)
  • 最好提供向量数学运算(点积、加法、乘法等)
  • 组合函数与旋转、缩放等操作非常有价值
  • 出于性能原因,始终使用原始双精度数学很重要(即避免特别创建装箱双精度)。因此,需要返回红色、绿色和蓝色分量的函数可能需要变成三个分别返回原始红色、绿色和蓝色值的函数。

您对如何在 Clojure(1.4 beta)中合理实现这种 DSL 有什么想法吗?


你在 Github 上有这个项目的早期草稿吗? - rplevy
https://github.com/mikera/clisk - mikera
你是否知道Pan(以及我的Pancito,它是一个纯Haskell的副本)?那是一个基于Haskell的库,可以实现这个功能。你可以在谷歌上搜索一些信息,这可能会给你一些想法。如果你希望生成美丽的东西,请不要灰心 - 我仍然很惊讶Conal如何从这样一个强大的库中生成如此丑陋的图像。另外还有Pancito:http://www.acooke.org/pancito-code/。 - andrew cooke
2个回答

1
看一下 ImageMagick 工具 http://www.imagemagick.org,你就能了解到这个库需要进行哪些操作。
也许你会发现,如果复制默认的 IM 工具集,就不需要降到矢量数学层面。

0

好的,我最终想出了一个不错的方法来做这件事。

诀窍在于将函数表示为代码向量(在“代码即数据”的意义上,例如

[(Math/sin (* 10 x)) 
 (Math/cos (* 12 y)) 
 (Math/cos (+ (* 5 x) (* 8 y)))]

然后可以将其“编译”以创建3个对象,这些对象实现了一个具有以下方法的Java接口:

public double calc(double x, double y, double z, double t) {
    .....
}

这些函数对象可以使用原始值调用,以获取每个像素的红色、绿色和蓝色颜色值。结果类似于:

enter image description here

最后,现在可以使用简单的DSL来组合函数,例如,要放大纹理,可以这样做:

(vscale 10 some-function-vector)

我已经将所有代码发布在GitHub上,供有兴趣的人使用:

https://github.com/mikera/clisk


1
你可以让它生成Piet的“源”代码,并将其用作生成交叉编译器 ;) - Dave Newton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接