Max/MSP/Jitter 官方教程翻译05 - 矩阵的数学运算

00 翻译自 Cycling74 的 Max/MSP/Jitter 官方文档:Tutorial 3: Math Operations on a Matrix

本教程介绍如何对存储在 Jitter 矩阵中的数据做简单的数学运算,使用 jit.op 对象来缩放矩阵单元格或单个平面。

教程分为三个​​简单的例子,你可以使用 jit.op 对象执行这些操作。jit.op 对矩阵的所有对象而不是单个数字执行数学运算。


向矩阵中的所有单元格添加常量

第一个示例显示了连接到 jit.opjit.matrix 对象,其输出可由 jit.pwindow 查看。每次改变连接到 jit.op 右输入口的数字框,都会从 jit.matrix 输出一个新的矩阵。从参数中可以看出,jit.matrix 生成一个 4x3 的单平面 char(0-255) 矩阵。jit.pwindow 把这个矩阵可视化为一个灰度图像。拖动数字框将改变显示的灰度级别(黑色 0 ~ 白色 255)。

请注意,jit.matrix 输出了一个所有单元格都为 0 的矩阵。如果将 jit.matrixjit.pwindow 对象绕过 jit.op 连接在一起,无论向 jit.matrix 发送多少次 bang 消息,都只能看到黑色图像。jit.opjit.matrixjit.op 之间的矩阵的所有单元都加上了一个值(由数字框给定)。

@ 操作符

jit.op 根据参数指定的运算(用 @op 表示)向矩阵加了一个值(不是乘或除)。@op 之后的参数是一个符号(或符号列表),它定义了 jit.op 在输入矩阵上执行的数学运算。

在这个例子中,op 属性设置为 + ,它对从左入口输入的任何矩阵都执行加法操作。右侧入口中的整数值会加到矩阵中的所有单元格。这个值被称为标量(scalar),因为它向整个矩阵添加了相同的值(在教程 11 中我们会展示 jit.op 如何使用两个矩阵进行数学运算)。

要点:更改 jit.op 右侧入口中的标量值不会输出新矩阵。如果断开数字框和按钮之间的接线,jit.pwindow 将停止显示任何新内容。原因在于,大多数 Jitter 对象与大多数 Max 对象一样,仅在数据进入其最左侧入口时才会输出数据。

在上面的例子中,每次更改数字框时 jit.op 都会存储新的标量值。此时按钮发送一个 bang 给 jit.matrix,让它将新的矩阵(所有值设置为 0)发送到 jit.op 的左入口,触发输出矩阵。

如果在按钮上方的接线上放置一个断点,然后 shift-cmd-T 逐步执行消息,就能看到它是如何运作的。(有关如何使用断点功能跟踪 Max 消息,请参阅教程:消息顺序和调试)

使用 jit.op 的 val 属性,标量值也可以作为常量。例如,如果想要为矩阵的所有单元格添加 134,可以使用 val 属性并省去数字框:

类似地,如果想要更改由任何给定的 jit.op 对象执行的数学运算,可以用消息 op 后跟数学符号,发送到对象的左入口。

多平面数据的数学运算

第二个示例显示了使用 jit.op 将值传入矩阵的更复杂的例子。


为矩阵的每个平面使用单独的标量

这个 patch 跟第一个类似,区别在于现在使用的是 4 平面矩阵。这由 jit.matrix 的第一个参数给出。jit.pwindow 现在有颜色了,它正在解析矩阵 α/红/绿/蓝 4 个单独存储颜色通道的平面。这个例子中的 jit.op 包含 op 属性的四个符号的列表:每个符号设置输入矩阵的一个平面的数学运算。在这个 patch 中,保留第一个(alpha)平面不做改动,而为其他 3 个平面做加法运算。

pak 对象向 jit.op 右输入口传送四个打包的整数。pakpack 的唯一区别是,当更改任何数字时,pak 都会输出一个新列表(pack 需要一个新数字或左侧入口的一个 bang 来触发输出新列表)。由 pak 生成的四个数字决定了传入 jit.op 矩阵的每个平面的标量值。

在上面的示例中,平面 0 没有添加任何内容(op 属性的第一个参数是 pass)。平面 1,2 和 3 将分别添加 161,26 和 254。jit.pwindow 将输出矩阵的单元格解析为洋红色(即使只看到一种颜色,矩阵中实际上有 12 个单元格,都设置为相同的值)。

要点:如果jit.op 对象的 op 属性只有一个值(只使用一个数字作为标量),jit.op 将在输入矩阵的所有平面都使用该运算符号和标量值。

修改图像中的颜色

第三个例子说明如何在矩阵中使用 jit.op,这个矩阵已经存储了相关数据:


将单个平面与标量相乘

单击消息框 importmovie colorbars.pngjit.matriximportmovie 消息将图像或 QuickTime 视频文件中的单帧图像加载到对象存储的矩阵中。它会将原图像缩放到矩阵的尺寸(320 x 240)。

单击按钮,jit.pwindow 中显示图像校准颜色条。这时 jit.op 的算术运算符设置为:alpha 平面不做修改(pass), 其他平面设置为 *(乘)。这个矩阵有 4 个平面,因此使用 4 个浮点数列表设置每个标量。平面 1~3 中的值都是 1.,结果是显示原始的图像:


所有标量均为 1

如果将标量设置为 1.0,0 和 0.,会看到以下图像:

包含颜色条的矩阵的所有平面(平面 1 除外)都乘以 0。这将消除矩阵的α,绿色和蓝色平面,仅留下红色(平面 1)。

将中间值(例如 0.,0.,1. 和 0.5)设置为 jit.op 的标量,会得到颜色栏看起来不同的图像:

在这种情况下,忽略 alpha 通道并将红色通道归零。蓝色平面的值是它们的一半。绿色通道(平面 2)保持不变。

要点: jit.op 中的一些数学标量使用浮点数,有些则使用整数。这取决于相关运算符(由 op 属性定义)以及输入矩阵的类型。本教程所有示例都使用了 char 矩阵,因此在添加时可以使用整数(任何浮点数都将被截断,因为矩阵数据保留 0-255 范围内的整数)。

如果使用 float32 矩阵作为输入,就需要添加浮点数。同样,用 char 乘以浮点标量的矩阵也可以(240 * 0.5 = 120,整数)。但是,由于 jit.op 输出的矩阵仍然是 char 矩阵(参见下面的注释),因此仍然只能获得 0-255 范围内的值。

如果你尝试使用标量值,容易看到某些颜色条消失或与相邻条形图合并。这是因为颜色条都设置为范围相似的标准颜色值。如果一次只显示一个通道(设置一个平面为 1,其余为 0),顶部七个条形中的四个将显示颜色。

本教程中只演示了 + 和 * 运算符,实际上 jit.op 对象可以执行许多其他的数学运算。运算符的完整列表请查看参考文档,或双击 jit.op 帮助文件中的 p op_list 子 patch。

调整大小

创建 jit.pwindow 对象时,它默认显示为 80 像素宽,60 像素高。它可以像 Max 中的许多 UI 对象一样改变大小。如果要精确地指定大小,可以使用 inspector 或向其发送尺寸消息,后跟宽度和高度(以像素为单位):


更改 jit.pwindow 的大小

如果给某个固定尺寸(像素)的 jit.pwindow 发送不同的尺寸的矩阵,jit.pwindow 会按自身的大小来缩放传入的矩阵。如果将非常小的矩阵发送到非常大的 jit.pwindow ,会做像素化处理(图像中颜色完全相同的矩形区域)。如果发送大矩阵到一个小的 jit.pwindow,可能会丢失不同程度的细节。

要点:在上面的示例中,含有颜色块的 jit.matrix 的大小(由其维度决定)为 320 x 240 个单元格,planecount 为 4,类型是 char。jit.op 对象(以及大多数 Jitter 对象)识别出信息并自动适配计算、输出相同规格的矩阵。

如果要更改 jit.matrix 的大小, jit.op 将立即识别变化并重新适应。jit.pwindow 也适配传入的矩阵,但方式略有不同。如果输入矩阵小于其自身的尺寸,则使用重复数据填充所有像素。(这会产生前一段中描述的像素化效果)如果输入矩阵大于其自身的维度,则必须忽略某些数据,只显示它可以显示的内容。因此,即使教程 patch 中的 jit.pwindow跟输入矩阵的大小不同,它们也会尽可能适配 jit.op 矩阵。

最后一个例子中的 jit.pwindow 尽可能显示了 jit.op 输出的整个矩阵,但它必须忽略所有其他行和列,以使其接收的 320x240 矩阵适合自己的 160x120 显示区域。

小结

jit.op 对矩阵上的所有数据进行数学运算。可以分别对矩阵单元格中的整体或每个平面执行计算。jit.op 的 op 属性决定要执行什么数学运算,可以输入 @op [operator] 属性参数,或者由左入口中的 op [operator] 消息提供。

对于多平面矩阵(例如彩色图片和视频),可以给出运算符列表(例如,op pass *)来指定每个平面的操作,并且可以为每个平面提供不同的标量值。在教程 11 中我们会看到如何使用矩阵来代替简单的标量。

你可以使用 size [width] [height] 消息设置 jit.pwindow 的大小。jit.pwindow 将尽可能适应接收到的矩阵的大小。如果输入矩阵小于其维度,它将复制数据;如果输入矩阵大于其自身维度,它将忽略某些数据。大多数 Jitter 对象都尽量适应它们接收的矩阵的维度、类型和平面数量。对 jit.op 而言,它没有自己的维度,所以它自动适配传入的矩阵大小。


友情提示:独自折腾 Max 易患上癔症……不妨入群互助

👇👇👇

kidult00 wechat
扫码关注 00 的公众号
如果文章帮您节省时间或者解答疑问,不妨打个赏 :)