从混乱到艺术:WEIRD生成艺术系统的核心技术与实战指南

从混乱到艺术:WEIRD生成艺术系统的核心技术与实战指南

【免费下载链接】weird Generative art in Common Lisp 【免费下载链接】weird 项目地址: https://gitcode.com/gh_mirrors/we/weird

你是否曾因传统绘图工具的局限而无法实现脑海中的复杂图案?是否在寻找一种能够通过代码精确控制视觉元素的创作方式?WEIRD(Generative Art in Common Lisp)作为一款强大的生成艺术框架,将彻底改变你的创作流程。本文将带你深入探索这个由Common Lisp构建的艺术生成系统,掌握从基础图形绘制到复杂算法艺术的完整实现路径。

读完本文后,你将能够:

  • 搭建WEIRD开发环境并运行第一个生成艺术程序
  • 理解并运用Weir图结构创建动态网络图形
  • 掌握随机数生成与SVG渲染的核心技术
  • 实现从简单几何形状到复杂分形图案的创作
  • 运用高级特性如Alterations系统构建动态艺术作品

项目概述:WEIRD生成艺术系统

WEIRD是一个基于Common Lisp的生成艺术框架,是snek→weir→weird迭代发展的第三代作品。该系统专为算法艺术创作设计,提供了从向量运算到SVG渲染的完整工具链。项目主要作者在过去几年创作的几乎所有生成艺术作品都基于该系统的不同版本。

核心组件架构

WEIRD系统由多个紧密协作的核心组件构成,形成了完整的生成艺术工作流:

mermaid

  • Weir图结构:核心数据结构,用于管理顶点、边和多边形,支持复杂的拓扑关系操作
  • Rnd随机数生成:提供多种概率分布的随机数生成器,是生成艺术的"创意引擎"
  • Wsvg渲染系统:将数学图形转换为SVG格式,支持路径、形状和颜色控制
  • Veq向量运算:提供高效的2D/3D向量数学支持,是所有几何计算的基础

安装与环境配置

WEIRD系统依赖于Common Lisp环境和Quicklisp包管理器。以下是在Ubuntu系统上的完整安装步骤:

# 安装SBCL和Quicklisp
sudo apt-get update && sudo apt-get install -y sbcl git
mkdir -p ~/quicklisp && cd ~/quicklisp
curl -O https://beta.quicklisp.org/quicklisp.lisp
sbcl --load quicklisp.lisp --eval "(quicklisp-quickstart:install)" --eval "(ql:add-to-init-file)" --quit

# 获取WEIRD源码和依赖
mkdir -p ~/projects && cd ~/projects
git clone https://gitcode.com/gh_mirrors/we/weird.git
git clone https://gitcode.com/gh_mirrors/inconvergent/cl-veq.git
cd cl-veq && git checkout v4.1.0-beta && cd ..

# 配置Quicklisp本地项目
echo "(push \"~/projects/\" ql:*local-project-directories*)" >> ~/.sbclrc

安装完成后,通过以下Lisp代码验证环境:

(ql:quickload :weird)
(weir:make) ; 应返回类似<@weir: WEIR123 (dim: 2, verts: 0, max: 10000)>的对象

核心技术解析:从基础到高级

Weir图结构:生成艺术的骨架

Weir图结构是WEIRD系统的核心,它不仅是一种数据结构,更是一种创作范式。与传统绘图API不同,Weir允许艺术家以数学方式定义和操作图形元素之间的关系。

基础图操作

创建Weir实例并添加基本图形元素:

;; 创建一个新的Weir实例
(defparameter *wer* (weir:make :max-verts 1000 :name :artwork))

;; 添加路径(一系列连接的线段)
(weir:2add-path! *wer* 
  (veq:f$_ '((-100.0 -200.0) (400.0 300.0) (800.0 100.0))) 
  :closed t) ; :closed t表示闭合路径

;; 添加独立顶点和边
(weir:2add-vert! *wer* 100.0 200.0) ; 添加顶点,返回顶点索引0
(weir:2add-vert! *wer* 300.0 400.0) ; 添加顶点,返回顶点索引1
(weir:add-edge! *wer* 0 1) ; 在顶点0和1之间添加边

;; 批量添加边
(weir:add-edges! *wer* '((2 3) (4 5) (6 7)))
高级特性:Alterations系统

Alterations系统是WEIR最具创新性的功能之一,它允许延迟应用图修改操作,确保所有修改基于初始状态计算,避免实时修改带来的计算偏差。

;; 使用Alterations系统的基本示例
(weir:with (*wer* % :db t) ; :db t可查看Alteration展开过程
  ;; 添加两个顶点并命名结果
  (% (weir:2add-vert? (veq:f2 100.0 200.0)) :res :a?) ; 顶点结果命名为:a?
  (% (weir:2add-vert? (veq:f2 300.0 400.0)) :res :b?) ; 顶点结果命名为:b?
  
  ;; 添加一条依赖于前两个顶点的边
  (% (weir:add-edge? :a? :b?))) ; 依赖:a?和:b?的结果

;; 获取所有Alteration结果
(weir:get-alteration-result-map *wer*) ; 返回包含所有命名结果的哈希表

Alterations系统采用"未来"(Future)模式,允许创建依赖于其他修改结果的操作。当一个Alteration依赖的"未来"操作失败时,该Alteration会被自动跳过,确保系统稳定性。

图遍历与修改

WEIR提供了强大的图遍历和修改工具,支持从简单迭代到复杂拓扑变换的各种操作:

;; 遍历所有边并应用力模拟
(veq:vdef* apply-forces (wer &key (stp 0.1))
  (weir:with (wer %) ; 使用Alteration上下文
    (weir:itr-edges (wer e) ; 遍历所有边
      (veq:f2let ((v0 (weir:2gv wer (first e))) ; 获取第一个顶点坐标
                  (v1 (weir:2gv wer (second e))) ; 获取第二个顶点坐标
                  (force (veq:f2- v1 v0))) ; 计算从v0到v1的向量作为力
        ;; 对两个顶点应用相反方向的力
        (% (weir:2move-vert? (first e) (veq:f2scale force stp)))
        (% (weir:2move-vert? (second e) (veq:f2scale force (- stp))))))))

随机数生成:创作的不确定性引擎

随机性是生成艺术的灵魂。WEIR的Rnd模块提供了丰富的随机数生成函数,支持从简单均匀分布到复杂概率模型的各种需求。

基础随机函数
;; 基本随机数生成
(rnd:rnd) ; [0.0, 1.0)范围内的随机浮点数
(rnd:rnd 100.0) ; [0.0, 100.0)范围内的随机浮点数
(rnd:rnd* 50.0) ; [-50.0, 50.0)范围内的随机浮点数
(rnd:rndi 10) ; [0, 10)范围内的随机整数

;; 二维空间随机点
(rnd:2in-circ 100.0) ; 半径100的圆内随机点
(rnd:2in-rect 200.0 300.0) ; 200x300矩形内随机点
(rnd:2on-line (veq:f2 0.0 0.0) (veq:f2 100.0 100.0)) ; 两点间线段上随机点
概率分布与高级采样
;; 正态分布采样
(multiple-value-bind (n1 n2) (rnd:norm :mu 0.0 :sigma 1.0)
  (print (list n1 n2))) ; 生成两个符合正态分布的随机数

;; 伯努利分布
(rnd:bernoulli 10 0.3) ; 10个伯努利试验,成功概率0.3

;; 最大距离采样(Mitchell's Best Candidate算法)
(defparameter *points* 
  (rnd:max-distance-sample 50 
    (lambda (n) (rnd:nin-circ n 400.0)))) ; 在圆内生成50个均匀分布的点
随机决策与流程控制
;; 概率性执行代码
(rnd:prob 0.3 ; 30%概率执行第一个表达式
  (print "执行此代码的概率为30%")
  (print "70%概率执行此代码")) ; 可选的第二个表达式

;; 随机选择
(rnd:either ; 等概率选择执行一个表达式
  (print "选择第一个选项")
  (print "选择第二个选项")
  (print "选择第三个选项")) ; 可接受任意数量的选项

;; 加权随机选择
(rnd:weighted ; 带权重的选择
  '((0.1 "罕见事件") ; 10%概率
    (0.3 "常见事件")  ; 30%概率
    (0.6 "大概率事件"))) ; 60%概率

SVG渲染:将数学转化为视觉

Wsvg模块负责将Weir图结构和其他几何元素渲染为SVG格式,支持从简单形状到复杂路径的各种视觉元素。

基础图形绘制
;; 创建SVG画布并绘制基本形状
(defparameter *wsvg* (wsvg:make* :width 1000 :height 1000)) ; 创建1000x1000的SVG画布

;; 绘制路径
(wsvg:path *wsvg* 
  (veq:f$_ '((100.0 200.0) (300.0 400.0) (500.0 300.0))) 
  :sw 2.0 :stroke "black" :closed t) ; sw指定线宽

;; 绘制矩形
(wsvg:rect *wsvg* 100.0 150.0 :xy '(200 300) 
  :fill "red" :stroke "black" :sw 1.5 :fo 0.5) ; fo指定填充透明度

;; 绘制圆形
(wsvg:circ *wsvg* 50.0 :xy '(500 500) 
  :fill "blue" :stroke "white" :sw 2.0)

;; 保存SVG文件
(wsvg:save *wsvg* "basic-shapes.svg")
高级SVG特性
;; 贝塞尔曲线
(wsvg:bzspl *wsvg* 
  (veq:f$_ '((100.0 500.0) (300.0 100.0) (500.0 900.0) (700.0 300.0))) 
  :sw 3.0 :stroke "purple")

;; 宽线模拟(JPath)
(wsvg:jpath *wsvg* 
  (veq:f$_ '((100.0 100.0) (300.0 300.0) (500.0 200.0) (700.0 400.0))) 
  :width 20.0 :rs 0.5 :sw 1.0) ; width指定线宽,rs控制填充密度

;; 同心圆
(wsvg:wcirc *wsvg* 100.0 :xy '(500 500) 
  :outer-rad 200.0 :rs 0.1 :sw 0.5 :stroke "gray") ; 从100到200半径的同心圆

实战案例:从代码到艺术作品

案例一:随机网络图形

以下示例创建一个动态网络图形,模拟粒子间的随机连接和力作用:

(defun create-random-network ()
  (let* ((wer (weir:make :max-verts 1000))
         (wsvg (wsvg:make* :width 1000 :height 1000)))
    
    ;; 添加随机顶点
    (loop repeat 50 do
      (weir:2add-vert! wer 
        (rnd:rnd* 450.0)  ; x坐标在[-450, 450)范围
        (rnd:rnd* 450.0))) ; y坐标在[-450, 450)范围
    
    ;; 创建随机连接
    (loop for i from 0 below 49 do
      (loop repeat (rnd:rndi 5) do ; 每个顶点随机连接1-5个其他顶点
        (let ((j (rnd:rndi 50)))
          (when (/= i j)
            (weir:add-edge! wer i j)))))
    
    ;; 应用力模拟
    (loop repeat 10 do ; 迭代10次力模拟
      (apply-forces wer :stp 0.01))
    
    ;; 渲染结果
    (weir:itr-edges (wer e) ; 遍历所有边并绘制
      (wsvg:path wsvg (weir:2gvs wer e) 
        :sw (rnd:rndrng 0.5 2.0) ; 随机线宽
        :stroke (format nil "hsl(~a, 70%, 50%)" (rnd:rndrng 0 360)))) ; 随机色相
    
    (weir:itr-verts (wer v) ; 遍历所有顶点并绘制
      (wsvg:circ wsvg (+ 2 (rnd:rnd 5)) 
        :xy (veq:lst (weir:2gv wer v)) 
        :fill "white" :stroke "black" :sw 0.5))
    
    (wsvg:save wsvg "random-network.svg")))

这段代码创建了一个包含50个随机分布顶点的网络,每个顶点随机连接到其他1-5个顶点。通过10次力模拟迭代,网络会呈现出类似物理系统的自然平衡状态。最终渲染时,每条边使用随机线宽和色相,每个顶点绘制为大小随机的白色圆点。

案例二:分形树生成

利用递归和随机数生成,可以创建类似自然树木的分形结构:

(defun branch (wer start end depth &key g)
  (when (<= depth 0) (return-from branch))
  
  ;; 添加当前分支
  (let ((a (weir:2add-vert! wer (veq:f2-x start) (veq:f2-y start)))
        (b (weir:2add-vert! wer (veq:f2-x end) (veq:f2-y end))))
    (weir:add-edge! wer a b :g g)
    
    ;; 计算分支方向
    (let* ((dir (veq:f2- end start))
           (len (veq:f2len dir))
           (angle (veq:f2angle dir))
           (sub-len (* len (rnd:rndrng 0.6 0.8)))) ; 子分支长度为当前分支的60-80%
    
      ;; 创建两个子分支
      (loop for angle-offset in (list (rnd:rndrng -0.4 -0.1) 
                                      (rnd:rndrng 0.1 0.4)) do
        (let* ((new-angle (+ angle angle-offset))
               (new-dir (veq:f2from (veq:f2 0 0) new-angle sub-len))
               (new-end (veq:f2+ end new-dir)))
          (branch wer end new-end (1- depth) :g g))))))

(defun create-fractal-tree ()
  (let* ((wer (weir:make :max-verts 10000))
         (wsvg (wsvg:make* :width 1000 :height 800))
         (g (weir:add-grp! wer :name :tree)))
    
    ;; 创建树干
    (branch wer (veq:f2 500 800) (veq:f2 500 600) 8 :g g)
    
    ;; 渲染结果
    (loop for path in (weir:2walk-graph wer :g g)
          do (wsvg:jpath wsvg (weir:2gvs wer path) 
               :width (* 5 (rnd:rndrng 0.5 1.5)) 
               :stroke "saddlebrown" :sw 0.5))
    
    (wsvg:save wsvg "fractal-tree.svg")))

这个分形树生成函数使用递归方式创建树枝:从树干开始,每个树枝末端随机生成两个新的分支,新分支长度为当前分支的60-80%,角度有微小随机偏移。通过8次递归迭代,生成具有自然形态的树状结构。使用JPath功能渲染宽线条,模拟真实树木的枝干效果。

案例三:动态艺术作品

结合Alterations系统和随机数生成,可以创建随时间变化的动态艺术作品:

(defun dynamic-artwork ()
  (let* ((frames 30) ; 生成30帧动画
         (wer (weir:make :max-verts 1000)))
    
    ;; 初始化100个随机顶点
    (loop repeat 100 do
      (weir:2add-vert! wer (rnd:rnd* 450) (rnd:rnd* 450)))
    
    ;; 为每一帧生成变化
    (loop for i from 0 below frames do
      (let ((wsvg (wsvg:make* :width 1000 :height 1000)))
        
        ;; 使用Alterations系统更新顶点位置
        (weir:with (wer %)
          (weir:itr-verts (wer v)
            (% (weir:2move-vert? v 
                 (veq:f2 (rnd:rnd* 5) (rnd:rnd* 5)))))) ; 小幅度随机移动
        
        ;; 创建voronoi图
        (create-voronoi wer wsvg)
        
        ;; 保存当前帧
        (wsvg:save wsvg (format nil "dynamic-art-~2,'0d.svg" i))))))

这个动态艺术作品生成30帧SVG动画,每帧中100个随机分布的顶点会小幅度随机移动,然后基于这些顶点生成Voronoi图。通过连续播放这些SVG文件,可以创建一个不断演变的分形图案动画。

高级技术与性能优化

图结构性能优化

对于包含数千个顶点和边的复杂图形,性能优化至关重要:

;; 使用KD树加速空间查询
(weir:build-kdtree! wer) ; 为Weir实例构建KD树

;; 只查询附近顶点,避免全量遍历
(defun nearby-verts (wer v radius)
  (weir:query-kdtree wer (weir:2gv wer v) radius))

;; 使用分组减少操作范围
(defun process-group-only (wer g)
  (weir:with-grp (wer g* g) ; 只在指定分组内操作
    (weir:itr-edges (wer e :g g*) ; 明确指定分组
      ;; 处理边...
      )))

复杂图案生成技术

结合多种技术可以创建更复杂的图案:

;; 混合Weir图和随机算法创建纹理
(defun create-texture ()
  (let* ((wer (weir:make :max-verts 1000))
         (wsvg (wsvg:make* :width 1000 :height 1000))
         (g (weir:add-grp! wer :name :texture)))
    
    ;; 创建网格
    (loop for x from -400 to 400 by 50 do
      (loop for y from -400 to 400 by 50 do
        (weir:2add-vert! wer x y :g g)))
    
    ;; 添加随机扰动
    (weir:with (wer %)
      (weir:itr-verts (wer v :g g)
        (% (weir:2move-vert? v 
             (veq:f2 (rnd:rnd* 20) (rnd:rnd* 20))))))
    
    ;; 应用Delaunay三角剖分
    (weir:delaunay! wer :g g)
    
    ;; 渲染带随机颜色的三角形
    (loop for poly in (weir:get-polys wer :g g)
          do (wsvg:path wsvg (weir:2gvs wer poly) 
               :fill (format nil "rgba(~a, ~a, ~a, 0.3)" 
                       (rnd:rnd 256) (rnd:rnd 256) (rnd:rnd 256))
               :stroke "black" :sw 0.5))
    
    (wsvg:save wsvg "random-texture.svg")))

项目扩展与社区资源

自定义Alterations

WEIRD允许定义自定义的Alteration操作,扩展系统功能:

;; 定义一个创建带随机扰动边的自定义Alteration
(weir:defalt random-edge? (wer p1 p2 &key (variance 10.0))
  (let ((v1 (weir:2add-vert! wer (veq:f2-x p1) (veq:f2-y p1)))
        (v2 (weir:2add-vert! wer 
              (+ (veq:f2-x p2) (rnd:rnd* variance))
              (+ (veq:f2-y p2) (rnd:rnd* variance)))))
    (weir:add-edge! wer v1 v2)))

;; 使用自定义Alteration
(weir:with (wer %)
  (% (random-edge? (veq:f2 0 0) (veq:f2 100 100) :variance 15.0)))

与其他Common Lisp库集成

WEIRD可以与其他Common Lisp库无缝集成,扩展功能:

;; 与cl-cairo2集成生成PNG图像
(defun weir-to-png (wer filename &key (width 1000) (height 1000))
  (cairo:with-png-file (filename width height)
    (cairo:set-source-rgb 1 1 1) ; 白色背景
    (cairo:paint)
    
    (cairo:set-source-rgb 0 0 0) ; 黑色线条
    (weir:itr-edges (wer e)
      (let ((pts (weir:2gvs wer e)))
        (when (>= (length pts) 2)
          (cairo:move-to (first (first pts)) (second (first pts)))
          (loop for (x y) in (cdr pts) do
            (cairo:line-to x y))
          (cairo:stroke))))))

总结与未来展望

WEIRD生成艺术系统为算法艺术创作提供了强大而灵活的工具集。通过本文介绍的核心技术和实战案例,你已经掌握了从简单图形到复杂算法艺术的完整创作流程。

核心知识点回顾

  • Weir图结构:管理顶点、边和多边形的核心数据结构,支持复杂拓扑操作
  • Alterations系统:延迟修改机制,确保所有操作基于初始状态计算
  • 随机数生成:从简单分布到复杂采样的完整随机数工具链
  • SVG渲染:支持路径、形状、颜色和高级效果的渲染系统

进阶学习路径

  1. 数学基础:深入学习向量运算、图论和分形几何
  2. Common Lisp高级特性:掌握宏编程和元编程,扩展WEIRD功能
  3. 物理模拟:实现更复杂的物理引擎,创建动态艺术作品
  4. 机器学习集成:探索AI辅助生成艺术的可能性

WEIRD作为一个活跃发展的开源项目,未来可能会加入更多高级特性,如3D渲染支持、GPU加速计算和交互式创作工具。无论你是艺术家、程序员还是创意爱好者,WEIRD都为你提供了一个将代码转化为艺术的强大平台。

现在,是时候启动你的Common Lisp环境,开始用代码创作属于你的生成艺术作品了!

【免费下载链接】weird Generative art in Common Lisp 【免费下载链接】weird 项目地址: https://gitcode.com/gh_mirrors/we/weird

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值