8084| 0
|
[入门教程] 写给设计师的编程趣味指南-(2)创造第一个PROCESSING程序 |
本帖最后由 kaka 于 2017-8-18 08:22 编辑 这一节,我们就来玩转 processing。 其他编程语言的经典入门大多从输出 “HelloWorld” 开始讲起。 但属于设计师的 “HelloWorld”,不应该是字符。咱们从画图开始! 画布与函数在开始前,首先聊聊 Processing 中的画布—— Sketch 。Sketch 的字面含义就是素描,草图。程序设计者把工程文件的名字起得太优雅了,就是想告诉我们,这就是给设计师玩的Sketch! 打开Processing,它会自动新建一个叫名叫 sketch_xxxx 的文件。我们可以直接开始写代码。完成后点 File-save 就可以保存自己的作品。 第一步,我们先写下这行命令: size(500,500);接着点击左上方的三角按钮运行程序。它会弹出一个灰色的窗口,这就是运行后的样子。 聪明的读者是不是已经能猜到这段代码的含义呢? 没错。size()就是用来设置画布大小的函数。以后如果看到这样的格式:一串英文字符,后面再跟一对括号,那在程序中就被称为函数。 格式: 函数名()与数学函数的定义不一样。程序中的函数,其实是一些代码块的封装。我们可以无需搞清函数内部的构造和原理,只需要知道它究竟能做什么。正如要开汽车不需要懂引擎的运作原理。 现在再回到size函数。它后面的括号里还有两个参数,中间用逗号作了区分。前一个代表窗口的宽度,后一个代表窗口的高度,完整的调用形式如下。 size(x,y) // x设置运行窗口宽度,y设置高度表达式写完后,请千万要记得在指令后面加一个;号,代表结束。这是初学者最容易踩的坑,请记得保持这个习惯,否则程序会出BUG(错误)。 这样具有历史意义的第一行代码就被我们敲出来了。后面介绍的绘图函数也会同样简单。函数相当神奇,使用它可以大大提高效率,它生来就是为懒人服务的。只要懂得正确地组装,就能写出功能丰富的程序。 坐标系统[size=1.4em]在使用绘图函数之前,需要了解 Procssing 的坐标系统。这与我们中学阶段接触到的笛卡尔坐标系很不一样,它的 Y 轴方向是反的。假如我们定义了一个 150 X 100 的画布,那左上角的第一个像素坐标就为(0,0),右下角的最后一个像素坐标则为(149,99)。 觉得难记可以这么去理解,坐标数其实代表了偏移量。起始坐标点序号为 0,与它相邻的坐标就距离初始坐标一个单位,因此序号为 1 。第 150 个坐标距离与第 1 个坐标相比,偏移了 149 个单位,所以序号就为 149。 但为什么要从0计算到149而不是从1计算到150呢?看上去多麻烦。这是程序中约定俗成的,很多概念都是从0开始计数。 我尝试从另一个设计角度去解释,以理解它的一些优点。假如我们要在画布中确立一个中心点。 如果是从 0 开始计数,要寻找中心像素就会很方便。只需将屏幕的宽高各自除以 2 (除了像素点为偶数的情况不存在绝对的中心)。而如果从 1 开始计数,除以 2 之后横纵坐标还要再加 1,才能得到准确的中心位置。(程序中两数相除,不会进行四舍五入,会直接舍去小数点后的数字) 现在应该对这种计数方式印象更深了吧,其实如果你是ps老手,就会发现在ps的信息面板上早就是按这样的方式来标记图片像素的位置。 改变坐标系这个坐标系可不是一成不变的,有一个函数 translate 可以改变它。 调用形式: [size=1.4em]translate(x,y);它可以将整个坐标系进行平移,xy 可以取正数或者负数,数值的正负决定移动的方向,数值的大小决定移动距离。以 x 值为例,如果取正数,则会朝 x 轴的正方向平移 x 个单位。负数则往负方向平移 x 个单位。 例如: translate(50, 50) 绘图函数坐标系统就像地图一样。通过它,所有绘制的图形都有了立足之地。下面开始介绍各种绘图函数。 画点在 size 后面写下这段代码。 [size=1.4em]point(250,250);点三角符号运行。 嗯?什么也没看到?再凑近看看。你会发现中央出现了一个小黑点。 这就是用于画点的函数。在 processing 里,这个点刚好就是一个像素的大小。第一个参数代表横坐标,第二个参数代表纵坐标。由于屏幕宽高都为 500,所以这个点刚好处于中间的位置。 但若想在画布中心画点,可以用这种便捷的方式去表示。 [size=1.4em]point(width/2, height/2);其中 width 会获取屏幕的宽,height 会获取屏幕的高,“/”在程序中代表除号。这样写程序可以自动计算结果,而无需给出具体的坐标。 你甚至可以在里面写一个超复杂的表达式进去 [size=1.4em]point(1 + 2 + 3 + 4 + 5, 100 - 50 - 20 - 10)当然,没事可不要这么去写,除非是想研究什么古怪的数列规律~~ 画圆接着来看画圆函数,ellipse。 调用形式: [size=1.4em]ellipse(x, y, a, b)括号中的前两个参数与point函数类似,后两个参数分别代表圆的宽和高。如果宽高值不一样,就能画出椭圆。 可以加在原代码后面的效果: 整体代码: size(500, 500); point(250, 250); ellipse(250, 250, 20, 20); 终于出现了一个大大的圆点。但有没有发现,之前绘制的点消失不见了! 其实,它只是被ellipse绘制的圆形覆盖了。在程序中,代码是由上到下,逐行执行的。先执行的先绘制,后执行的会覆盖前面的。有没有觉得和ps的图层很像? 画线,画三角,画方形这几个函数的用法也很简单。 画线: [size=1.4em]line(x1, y1, x2, y2) x1, y1代表线条的一个端点坐标,x2,y2则代表另一个。函数会将两个坐标连起来。 画三角: [size=1.4em]triangle(x1, y1, x2, y2, x3, y3)这里会用到三对坐标参数,分别代表3个顶点坐标。 画方形: [size=1.4em]rect(x,y,a,b)前两个参数代表方形左上方的顶点坐标,a,b 分别代表方形的长和宽。 你可以单独地去试验这些函数,熟悉它们的用法。之后可以复制下面的代码: size(500, 500); ellipse(175, 220, 183, 183); ellipse(width-175, 220, 183, 183); rect(100, 100, 300, 300); line(150, 160, 220, 240); line(width-150, 160, width-220, 240); ellipse(175, 220, 60, 60); ellipse(width-175, 220, 60, 60); point(width/2, height/2); triangle(170, 300, width-170, 300, 250, 350); 这个例子将前面介绍的函数都一并用上了,还画了一个表情图形(姑且算吧),你也可以尝试自己画一些稍微复杂的图案。同时琢磨两个问题。 [size=1.4em]
上色 只有形状,不免无趣。我们还要学会上色。和我们预想的上色方式不一样,不是每个形状都会有一个对应的色彩属性,来让你去定义它的颜色。比如ellipse(200,200,20,20,?)后面再加一个参数之类的。 程序中上色要使用 fill 函数,这是一种通用的上色方法,并且要写在绘图函数前面, fill 的输入参数很特别,允许几种输入方式。 可以这样 fill(x) x代表灰度值,最小为0(代表黑色),最大为255(代表白色) 可以这样 fill(x,a) x代表灰度值,a代表透明度(最小值0,最大值255) 也可以这样 fill(r,g,b) r代表red(红),g代表green(绿),b代表blue(蓝)。设计师对RGB应该是相当熟悉了,代表的就是三原色。 还能这样 fill(r,g,b,a) rgb就代表三原色,a代表alpha(透明度) 实例效果: size(500, 500); fill(125); ellipse(100, 250, 100, 100); fill(125, 100); ellipse(200, 250, 100, 100); fill(255, 0, 0); ellipse(300, 250, 100, 100); fill(255, 0, 0, 50); ellipse(400, 250, 100, 100); 但如果前面只写一个fill呢? size(500, 500); fill(125); ellipse(100, 250, 100, 100); ellipse(200, 250, 100, 100); ellipse(300, 250, 100, 100); ellipse(400, 250, 100, 100); 那之后绘制的图像,都会填充同一个颜色。如果将 fill 放在中间,前面的依然会是默认的白色,只有后面的代码会产生影响。(代码由上至下执行的) size(500,500); ellipse(100, 250, 100, 100); fill(125); ellipse(200, 250, 100, 100); ellipse(300, 250, 100, 100); ellipse(400, 250, 100, 100); 如果希望绘制的每个形状都是不同的颜色,就得在每个绘图函数的前面加上fill。 与fill相关的还有noFill函数。 noFill()它不需要输入任何参数,写在绘图函数前面,之后绘制的图形都不会填充颜色,而只显示边线。 size(500,500); noFill(); ellipse(100,250,100,100); ellipse(200,250,100,100); ellipse(300,250,100,100); ellipse(400,250,100,100); 除非你后面又写上fill(),那才会开启填充功能。 边线除了能处理形状的填充色,还可以单独对边线的颜色和宽度进行处理。 边线颜色stroke(x) stroke 函数可以改变边线的颜色。括号内参数与 fill 函数的用法完全一样。代表边线的颜色。可以选择四种不同的参数输入方法。 stroke(x)x代表灰度值,最小为0(代表黑色),最大为255(代表白色) stroke(x,a)x代表灰度值,a代表透明度alpha stroke(r,g,b)rgb代表三原色RGB stroke(r,g,b,a)rgb代表三原色RGB,a代表透明度alpha 边线宽度strokeWeight(x)控制边线的粗细(还可以控制点的大小) noStroke() 除非你后面又写上fill(),那才会开启填充功能。 边线除了能处理形状的填充色,还可以单独对边线的颜色和宽度进行处理。 边线颜色stroke(x) stroke 函数可以改变边线的颜色。括号内参数与 fill 函数的用法完全一样。代表边线的颜色。可以选择四种不同的参数输入方法。 stroke(x)x代表灰度值,最小为0(代表黑色),最大为255(代表白色) stroke(x,a)x代表灰度值,a代表透明度alpha stroke(r,g,b)rgb代表三原色RGB stroke(r,g,b,a)rgb代表三原色RGB,a代表透明度alpha 边线宽度strokeWeight(x)控制边线的粗细(还可以控制点的大小) noStroke() 无需输入参数,代表不显示边线 stroke的用法就留待大家去探索了。如果把下面这行代码写在之前表情图案的前面,就会出现这个效果。 strokeWeight(8);所有的边线都被加粗了。 最后还有一个与上色相关的background函数,它可以用来填充背景,相当于油漆桶。括号中填的也是色彩参数,和前面的完全一致,有四种不同的参数输入方式。如果把background(200,0,0)写在前面可以得到。 size(500, 500); strokeWeight(8); background(200, 0, 0); ellipse(175, 220, 183, 183); ellipse(width-175, 220, 183, 183); rect(100, 100, 300, 300); line(150, 160, 220, 240); line(width-150, 160, width-220, 240); ellipse(175, 220, 60, 60); ellipse(width-175, 220, 60, 60); point(width/2, height/2); triangle(170, 300, width-170, 300, 250, 350); 是不是开始像个“作品”了:) End学程序不要单纯去背知识点,而是要将它们灵活运用起来。除了一些特别常用的函数要记住以外,其余的在用的时候再去查也是没有问题的。 在 Processing 官网中可以查到各种函数的用法。(https://processing.org/reference/)
通过这节的介绍。是不是觉得代码没有以前那么神秘了? 在程序中画图,远没有用画笔或者ps工具那么形象和自由。里面的任何一个图形,都需要用数据来描述它的位置,大小或角度。而对于复杂的图形,是很难纯靠想象,直接写出代码的。一般是先绘制好草图,再用ps的信息面板查看关键点的坐标,最后选择合适的函数去表现。
看到这里,有怀疑精神的设计师估计会跳出来。我在PS里面随便拉几下就能画出来的图形,为什么非要在用程序里画,过程还这么麻烦?这完全体现不出程序的优势呀? 说得很有道理,请保持好质疑的心态,答案在下节揭晓。之后还会聊聊两个“大头”函数,setup函数和draw函数。只要灵活运用它们,就可以让图片“动”起来。而我们在学校里曾经学习的那些有关数学函数的知识,也开始有了用武之地,过往那些看似枯燥的数学公式,将会成为我们控制图形的利器。 转自www.inslab.cn |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed