Max:提取

max15
15mAbstractions.maxpat

1. #1:开启toggle后,捕捉你的鼠标轨迹,然后在lcd上画线,这里使用了bucket物件,他总输出它收到的最后一个值,这个物件可以将你之前的鼠标位置与当前鼠标的位置连接起来。无论你何时关闭这个程序,当你下一次开启的时候,它仍会从你上一个结束点开始继续绘制。

2. 在程序的第一部分,里边有很多逻辑关系,这时我们会想到用封装来简化这个界面。同时,这组依屏幕分辨率进行鼠标控制的逻辑运算貌似在很多的地方都可以用得到,如果无需复制粘贴它便可让它为其他patch所用那就太棒了。这里便引出了提取(abstractions)的概念。一个提取就是一个保存为外部文件的subpatcher,同时可以被作为一个常规的Max物件使用。本例中的提取与这个例子位于同一文件夹下,一组提取可以在你将它们放入“patches”文件夹下的一个或多个文件夹后被创建(或者任何Max检索文件的地方)。

3. #2:绿框WTHITM(代表”Where The Heck Is The Mouse?”)就是一个典型的提取案例,双击它,则将打开这个提取,这看起来与封装很像,除了一点─这个提取无法被unlock后修改,因为它是一个独立存在的patcher文件。要查找一个提取,最简单的方式是通过File > New File Browser的搜索功能。如果你修改并保存了一个提取,则程序中所有使用到它的部分都会改变─甚至在这个patcher已经载入的情况下。

4. 用文件检查器查看WTHITM这个patch的出、入口,三点标注值得注意:Annotation(注释):在这里标记的所有文本都将在你鼠标悬停于被标记物件上方的时候显示在Clue窗口内;Hint(线索):在这里标记的所有文本都将在你鼠标悬停于被标记物件上方的时候显示在鼠标旁的气球式注释框内;Comment(评论):在这里标记的所有文本都将在你鼠标指向上级patcher的出、入口的时候显示为assistance(援助)文本。善用这些文本标记法将大大有利于今后你对它们的重复利用。

5. #3:看上去与#2很像,但在里边使用的提取叫做WTHITM_scaled,并包括了两个引数,分别为lcd物件的长度和高度。打开它,我们看到两个有趣的值,#1和#2,是的,它们分别代表WTHITM_scaled提取的两个引数。使用这些可替换值(称为 pound-sign arguments)是重复弹性使用提取的关键。如果换为更大或更小的lcd,你只需改变WTHITM_scaled提取的引数弹性变化,而无需去打开并修改它。这便是模块化封装的好处。

本例内新物件:
bucket:通过一个接一个outlet循环式传递一个数字

Max:封装

14mEncapsulation.maxpat
14mEncapsulation.maxpat

1. 运用patcher物件可以在一个patch内创建一个子patch(subpatcher),为了使我们的patch更简单易懂、易于修改,使用子patch封装可以很好的做到以上的诉求。在lock的状态下双击patcher物件可以打开封装在其中的子patch。

2. 双击绿框patcher物件,弹出它的子patch,上下两个分别为入口(inlet)和出口(outlet)物件,分别替代patcher物件的出、入口。在子patch内创建多少个入口(inlet)和出口(outlet)物件,在patcher物件上就分别对应有多少个出、入口。打开入口(inlet)和出口(outlet)物件的检查器,在comment一栏填入相应的名称或标记,将在今后编辑patcher物件的某些时候显示,以便于我们进一步的编辑。

3. 大家伙:拖动灰色框内的小球(这是一个叫做pictslider的物件)可以在底部lcd物件窗口内绘制出相应的图形。按空格键清除绘制内容(ASCII码对应为32,由key物件捕捉并由select物件(缩写为sel)触发)

4. 选中例子中“encapsulate from here —>”到“to here —>“之间的物件(共15个),然后选择Edit > Encapsulate可以将这一堆复杂的玩意全部封装到一个patcher物件内。lock状态下双击它,可以看到打开的子patch里使用了四个inlet物件和1个outlet物件,这与原始patch内这一部分的输入输出口的数量是一致的。

5. 封装能够完成两件事:i. 它允许我们在不与全部物件交互(甚至是看到)的情况下进行高层的应用,ii. 它允许我们在不改变高层程序任何东西的情况下,改变低层的逻辑。

本例内新物件:
patcher:在一个patch内创建一个子patch
inlet:从外部patch获取讯息
outlet:将讯息送至外部patch
pictslider:基于图像的滑动控制

Max:“影”序器

max13

1. rslider物件可以设定一个输出值的范围,如左列上例,点击并拖动鼠标可以设定这个范围,左边数字框为此范围最小值,右边的为最大值(默认值为0~127)。

2. loadbang物件可以在一个patcher载入后自动发送一个bang讯息,改变左列中例下方数字框的数字,双击loadbang物件则将发送一个bang讯息触发下边的消息框55,于是数字框内数字又将变为55。

3. umenu物件可以添加一个下拉列表,两种输出:左边的口可以输出当前选项的号数,由0开始;中间的口输出当前选项的文字。

4. #1:上部:一个loadbang物件从右至左触发两个消息框,这两个消息框为umenu物件的两个属性:prefix:在输出umenu文件名前加入路径,用于文件定位。autopopulate:将自动定位与文件夹内容联系起来,当接收到prefix的文件路径后触发。结果是:我们得到了一个在patches/media文件夹下所有文件的umenu下拉菜单。当我们选择其一的时候,三件事发生:首先,dispose消息被发送至imovie物件,清除当前载入imovie内的内容。其次,包含prefix路径的消息通过trigger物件(缩写为t)的引数symbol(缩写为s)后传入prepend物件,prepend物件在这组数据之前加上“read”后送入imovie物件。第三,trigger物件经过delay物件发送一个bang讯息,delay物件将这个讯息延迟100毫秒,这给了imovie物件读取数据的时间。过了delay的周期后,delay下边的消息框被发动,它包含了一些对于imovie物件的控制信息:length(得到影片的长度),loop 1(循环影片),以及start(开始回放)。在这样的情况下,一切都是由trigger物件中部的输出口(基于文字的)发动的。应该认识到,在这样的情况下trigger物件起着多么大的作用。

下部:imovie物件左下角文件长度信息通过size消息框进入rslider物件,并设置rslider选中整段片长(0 $1的作用)。鼠标拖动的前后位置由两个数字框表现并发送进入pack打包后进入并出发loopset消息框,它可以改变一个循环的开始、结束点,并将影片倒回loop起点($1)播放。

5. #2:screensize物件可以获得当前萤幕的分辨率,依我mbp的萤幕分辨率1440×900为例,screensize返回的数据是四个:0 0 1440 900。unpack出四个值后减1送入scale物件的最大值入口。左边mousestate获得当前鼠标坐标值,送入scale物件。scale物件将当前坐标值scale到0.~1.的范围后分别乘以240和180(设定小矩形最大值为240×180)。rect消息框可以在imovie画布上嵌入一个矩形,四个值:前两个为鼠标坐标值,后两个为矩形的宽、高。开启toggle,开始影片播放,移动鼠标看结果。

本例内新物件:
rslider:显示或改变一组数据的范围
umenu:下拉菜单,显示和发送命令
loadbang:在patcher在如后自动发送一个bang讯息
screensize:输出萤幕分辨率

Max:电影回放

max12

1. 我们可以用imovie物件在一个patcher内嵌入一段QuickTime片段。

2. 例子:imovie物件上方的几个消息框:read将读取特定的电影文件;start开始播放;stop中止播放;dispose(去除)将从imovie物件缓存中移除当前的电影,一但你dispose一个电影档,你可以用read重新载入它。点点这几个按钮试试吧。注意在你每次点击start的时候,它都是从片头开始播放。那五个竖着摆放的rate信息告诉imovie物件改变回放的速度,1.表明按正常速度正向播放,-1.表明按正常速度反向播放;0.5表明用正常速度一半的速度正向播放;0.为暂停,点击其他rate将从停止的位置继续播放。再向右的loop信息可以使电影片段持续循环回放。点击duration消息可以在imovie下方的数字框内获得当前电影片段的长度(单位为毫秒),这有利于我们创作电影配乐及了解当前所在的时间位置。

3. 要更换载入多个电影片段,一个选择是去掉read消息的引数,这样做之后,当你点击read消息框的时候,将自动弹出一个对话框供你选择你电脑系统内的任意文档。但是,向你的imovie物件添加新电影更简单的方式是使用文件浏览器。你可以通过File>New File Browser打开它。里边将装满Max认为的对你的程序创作有帮助的一切文档,包括文件名、文件类型、修改日期和自定义的标签等。点击搜索框旁边的+号,将打开精确检索框,如果某项精确检索是你常用的,你可以点击文件浏览器左下角的+图标将其保存,以供日后使用。将任何文件拖入你的patch,鼠标悬停于物件上方,能够被接收的文件将在该物件周围出现一圈蓝边。比如将一个.mov文档拖到一个imovie物件上将自动载入新的电影档。

4. #1:metro建立了一个基于mousestate物件的测试,mousestate的第二输出口(鼠标水平坐标)被使用,它的值被scale物件scale到-2.~2.的范围内(如果你显示器分辨率水平大于1024,则这个值可以设的更大),scale后的值经过rate消息框发送命令实时控制影片播放速率。

5. #2:这次采集的是鼠标纵坐标,并用它来改变影片回放的点,要实现这个功能,你首先需要得到影片的长度(点击duration获得)。为了完全控制影片的位置,最好将影片速率事先设到0。

6. #3:四个.mov文件首先通过read进入imovie的输入口,接下来,key物件监测我们的键盘输入;a、s、d、f四个键(ASCII码 97, 115, 100, 和 102)经select物件到达switch命令(一个start命令紧随其后,以让视频重新开始)。一切就绪后,你将可以通过键盘上的a、s、d、f四个键实时快速切换这四个视频文件,由于它们已经事先经由read读入imovie物件的缓存,所以在切换时只会有非常小的延迟(个人感觉基本可以忽略不及,但没试过大的文件)。

Max:程序绘制

max11

1. 左上角的例子:counter物件可以生成一组循环的值。依次点击第一个按钮可以依次生成一组0-9的循环值。counter第三个输入口为“赋值于下一次点击”,比如物件改变第一排第一个数字框的数字为5,可以在下一次点击的时候直接跳到5,而无论之前的数字是几,点击蓝色背景的按钮(发送bang信息)则可以将下一次点击的值恢复到零。counter物件最后一个输入口可以实时设定最大值。

2. counter的多引数应用:1个引数:设定最大值;2个引数:设定最小值和最大值;三个引数:设定方向(direction)、最小和最大值。

3. scale物件:将一组输入值的范围(引数前两位)映射到一组输出值范围(引数后两位)内。左列二例:输入值0-100并映射到输出值-1.0~1.0上,即:如输入值为0,则输出值为-1.0;输入值为100,输出值为1.0;输入值为50,输出值为0.0。如果输入值超越输入值范围,输出值也会按计算的增量相应增加。因此,输入150输出则为2.0,输入-100输出则为-3.0。这个物件的引数是用于决定转换的数学表达式。

4. 左列三例:点击第一个消息框,最下边的数字框将在1000毫秒(1毫秒=1/1000秒)内由0增加到目标值(100)。点击第二个消息框,起始值将在5000毫秒(5秒)后回到0。点击第三个消息框,数字将在2.5秒后由20上升到50。

5. 大家伙:

#1:使用了4个不同的counter物件,一个用于设定位置和大小,另外三个改变颜色。需要了解最左边的那个counter是最重要的,它从0数到767,共给我们768步。x/y轴的值则由%(一个数字除以另一个数字,整除后输出剩余的值,例如22%10=2)和/(一个数字除以另一个数字,输出结果)物件计算,将我们的lcd物件打碎为24×24的格子。注意看counter的两个输出,它们均生成了一组0-23的循环,%跑得快,/依metro的速率改变。这个值乘以10(获得左上角的像素位置)后加10(获得右下角的像素值)。这为我们的程序建立了一个可用来作画的以圆形填充的lcd方格界面。另外三个counter物件在三个不同的数值范围内循环,使我们得到了一个不断变色的调色板。第一个引数2强制counter从小值增加到最大值之后再减小到最小值,如此反复。这是在绘制时颜色缓慢改变的原因。这个引数(direction)的使用:0=增加,1=减小,2=增加后减小,如此反复。

#2:运用scale物件绘制基于正弦波计算的形状。counter’物件产生从0到最大值(由metro物件右侧的两个数字框内数字决定)的输出。它被scale物件界定于0.0~6.283185(2×π)之间,而后发送进入一个sin物件,计算出输入值的正弦值,产生一个在-1.0~1.0范围内变动的正弦波。这个值被送入另一个scale物件,映射进入一个整数范围0~319(lcd物件的大小范围)之内,这用于产生x轴的值。它隔壁与它同样的那堆方块儿用于产生y轴的值。这些数字随后被插入一组数列(list)(使用pack物件,使用prepend物件lineto它们)后被传送到lcd内。

#3:目前为止我们见过的最复杂的程序。它依靠lcd物件的空闲(idle)机制做一些程序绘制。当idle消息开启(通过idle 1消息)。lcd物件会输出你鼠标当前相对于lcd物件画布的位置。x/y坐标由lcd物件的第二个输出口输出为一组list。淡蓝色连接线将当前鼠标坐标送入unpack物件,这些值被送入我们的绘画代码,创造出一组值,绘制出两个能够跟随鼠标反应的圆形,并且能够对鼠标与它们的不同距离产生不同反应。开启最顶端的toggle盒子,然后用鼠标在lcd上转转,看看那俩球是如何反应的。

在这个程序内有非常重要的两步:第一,用line物件使得输出值的时间周期为1秒(1000毫秒),这使得产生的结果在不断插入的过程中有一种更有机的感觉。第二,我们运用cartopol(cartesian to polar) 物件使得鼠标的x/y轴(“Cartesian”)笛卡尔坐标值转化为一对基于距离/角(“Polar”)的极坐标值,这对在圆形范围内绘制内容很有帮助。一旦polar坐标被计算出来,它们将被限制符合于圆形绘制范围的大小,然后被用于一个复杂、多消息消息框的一部分,结果就是你看到的那两个球体。

程序底部的消息框发送4个有序的绘制命令到lcd物件。前两个用paintoval命令绘制固定位置(100 100 140 140 和 180 100 220 240)的两个背景圆形,后三个数字0 0 0设定它们的颜色为黑色。后两个用pack物件得到的值绘制出两个绿色(0 255 0)的“追随者”,四个值提供了“追随者”开始和结束的角度并由paintarc命令绘制出来。

6. 结论:运用一组输入值,然后依据你的需要scale它们,这是很多Max程序至关重要的步骤。用counter物件创造循环,用scale物件将输入值scale到输出值,并用line物件在不同的时间内插入数字。有时,我们也会运到一些基于三角学计算的物件。

本例内新物件:

count:计算收到的bang讯息,输出它。

scale:将一组输入值范围映射到一组输出值范围。

line:在一定时间内平滑输出一个值到另一个值。

sin:正弦功能。

cartopol:笛卡尔(Cartesian)坐标到极(Polar)坐标的转换。

相关知识:

1. 正弦:正弦是三角函数的一种。它的定义域是整个实数集,值域是[-1,1]。它是周期函数,其最小正周期为2π。在自变量为(4n+1)π/2〔n为整数〕时,该函数有极大值1;在自变量为(4n+3)π/2时,该函数有极小值-1。正弦函数是奇函数,其图像关于原点对称。

2. 笛卡尔坐标系:在數學裏,笛卡兒坐標系,也稱直角坐標系,是一種正交坐標系。二維的直角坐標系是由兩條相互垂直、0 點重合的數軸構成的。在平面內,任何一點的坐標 是根據數軸上 對應的點的坐標設定的。在平面內,任何一點與坐標的對應關係,類似於數軸上點與坐標的對應關係。

採用直角坐標,幾何形狀可以用代數公式明確的表達出來。幾何形狀的每一個點的直角坐標必須遵守這代數公式。例如,一個圓圈,半徑是 2 ,圓心位於直角坐標系的原點。圓圈可以用公式表達為

3. 极坐标系:在数学中,极坐标系是一个二维坐标系统。该坐标系统中的点由一个夹和一段相对中心——极点(相当于我们较为熟知的直角坐标系中的原点)的距离来表示。极坐标系的应用领域十分广泛,包括数学物理工程航海以及机器人领域。在两点间的关系用夹角和距离很容易表示时,极坐标系便显得尤为有用;而在平面直角坐标系中,这样的关系就只能使用三角函数来表示。对于很多类型的曲线,极坐标方程是最简单的表达形式,甚至对于某些曲线来说,只有极坐标方程能够表示。

Max:随机绘制

max10

1. 那个大家伙:
#1:pack物件的七个值分别为:形状左、右、上、下的位置,以及RGB颜色的三个值(0-255间)。一切随机的值均由random物件生成。
#2:与上同理,区别是由于drunk物件的限制作用,所以方块位置及颜色的变化都非常缓慢。
#3:framepoly由于绘制多边形,每一对x/y值代表一个顶点。pack物件内8个值正好给予4对顶点,随机颜色由prepend frpg(foreground RGB)单独生成(在旁边)

2. drunk物件:第一个引数设定随机值的范围,第二个引数设定随机增减数目的范围。

本例内新物件:
random:生成一个随机数字
drunk:在一定变化范围内生成随机数字(Output random numbers in a moving range)