本期的每周一库带来的是valora,是一个rust下的图形绘制库。库的介绍和主页很有意思,尤其在项目主页,其中有一节的标题是成为一个艺术家

  • valora github仓库
  • valora主页
  • valora在docs.rs页面

valora特性

  • valora包含了rng(Random Number Generator)
  • 在不改变composition scale的情况下复现任意分辨率的图形
  • 使用了type-safe color可以保证色彩的印刷一致性
  • 充分利用硬件资源
  • 充分利用Rust特性,大幅减少了调试工作量

下面我们参考valora网站上的教程来体验绘制功能

开发环境

  • Windows 10
  • cargo version: cargo 1.45.0-nightly (9fcb8c1d2 2020-05-25)
  • rustc --version: rustc 1.45.0-nightly (56daaf669 2020-06-03)

初始化新的rust工程之后使用命令安装

cargo install cargo-edit && cargo add valora

注意:由于valora的依赖项中有些包使用了测试版本,所以需要使用rustc nightly版本才能顺利安装。如果使用rustc stable版本会报错。

切换stable到nightly版本

rustup default nightly

体验valora绘制功能

接下来我们通过valora主页中Introduction部分的例子来体验绘制功能

原始代码如下:

use valora::prelude::*;
fn main() -> Result<()> {    run_fn(Options::from_args(), |_gpu, world, _rng| {        Ok(move |ctx: Context, canvas: &mut Canvas| {            canvas.set_color(LinSrgb::new(1., 1., 1.));            canvas.paint(Filled(ctx.world));
           let max_radius = world.width / 3.;            let radius = ctx.time.as_secs_f32().cos().abs() * max_radius;
           canvas.set_color(LinSrgb::new(1., 0., 0.));            canvas.paint(Filled(Ellipse::circle(world.center(), radius)));        })    })}

接下来我们通过修改原始代码中的一些参数来体验valora绘制的可玩性。

首先我们准备对例子中的背景色和圆形色彩下手。至于例子代码中相对细节的ctx_gpu等关键部分现阶段可以不用深入了解。

valora使用的色彩定义LinSrgb是均一化的rgb,通常来说rgb取值范围为0 ~ 255,均一化就是0 ~ 1。值得注意的是赋值使用了浮点数(1., 0., 0.),一般来说图形范畴内使用浮点数很普遍。

有了这些概念我们可以去找个在线color picker去选择一下我们想要的背景色和圆的颜色。

经过一番picker之后

  • 背景色选择了rgb(153, 204, 255),类似天空蓝色。
  • 圆形的颜色用个橙色类似的rgb(255, 153, 51)

那么我们把选定的色彩粘贴到代码中,同时做个均一化的除法

// color of background canvas.set_color(LinSrgb::new(153./255., 204./255., 255./255.));
// color of circle canvas.set_color(LinSrgb::new(255./255., 153./255., 51./255.));

原始代码中圆形只是在中间位置scale缩放,有点呆。

结合一点写代码的背景知识,一般来说带有绘制功能的视觉库都是用一个二维或者三位维向量来做位置参数,旋转用个3X3矩阵之类的套路。

再结合一点线性代数知识,向量外层乘以固定系数应该还是个向量。

那么我们直接把上面负责变形的代码复制粘贴到位置矩阵旁边,同时做个乘法,让圆心的x和y等尺度变化。

这样就可以实现了类似高空摄像机向下拍摄一个弹跳皮球运动的视觉误差,复制粘贴走起(主要是懒)

canvas.paint(Filled(Ellipse::circle(world.center() * ctx.time.as_secs_f32().cos().abs(), radius)));

修改之后运行一下看看效果,还凑合

mlua v0.4 发布并支持Lua 5.4 mlua v0.4 released with Lua_java

到这里基本介绍了valora库的基本用法,其实valora库的可玩性非常高,可以定义笔触,笔触轨迹,调用GPU绘制等等。

可以说Rust程序员离Artist的距离就差一个valora了。