偶然看到这个问题(的答案),尤其是 @七朱八白 的类编程方法,就又仔细去看了一下题目里的图。我比较认同这一效果应该是(部分)采用编程方法实现的,因为圆点有两个特征:一、它们分布在一系列间距相等的同心圆上;二、它们的大小在文字边缘有从全尺寸到消失的过渡。而这两个特征都可以相当简便地自动完成:先将一个字符图层适度虚化,然后在另一图层中的一系列同心圆上等距地绘制圆点,并使得每个圆点的半径与字符图层上该点对应坐标点下的文字透明度成正比。
由于 Photoshop 和 Illustrator 早已支持 JavaScript / Visual Basic / AppleScript 编程[1],所以我猜想这个原始图案应该是使用类似的编程方法完成的。但是我手头没有 Photoshop,所以就采用 Processing[2] 来实验这个想法。Processing 本是为视觉艺术和交互设计而开发的一门简易语言以及编程工具,后来被扩展到 Arduino 等平台,非常适合没有什么特定目的的编程初学者入门。
![]()
因为手头没有合适的粗大字体,这里采用风靡九梗的 Impact,略作虚化之后如上图。
而「在另一图层中的一系列同心圆上等距地绘制圆点,并使得每个圆点的半径与字符图层上该点对应坐标点下的文字透明度成正比」由于 Processing 没有图层的概念,被转化为「在画布上的一系列同心圆上等距地绘制圆点,并使得每个圆点的半径与此虚化图上该点对应坐标点下的 RGB 值红色分量成正比」,效果如图:
![]()
加上鼠标点击和移动部分的代码之后,更可以随意控制圆点的中心位置:
![]()
![]()
……而上述核心逻辑部分只需要以下 drawDots 函数内的十四行代码。
[code]int dotR = 15, dotSpacing = 5, circleR = 800, x, y;PGraphics pg;boolean lock = false;void drawDots(int x, int y){ int distance = dotR + dotSpacing; float scale = (float)red(pg.get(x, y)) / 255.0; ellipse(x, y, dotR * scale, dotR * scale); for(int r = 0; r |