zoukankan      html  css  js  c++  java
  • Processing 网格纹理制作(棋盘格)

    写在前面的话

    很久没有写博文了。最近在整理Processing有关文档,看到之前做的一些例子,想着分享在互联网上,当然和以前一样,目前也仅为了给初学者有个学习参考,笔者能力有限。废话不多说,干就完事了。
    来做个纹理怎么样?基本纹理很多样式,我们慢慢尝试去实现,今天搞一个网格纹理,准确的说是棋盘格,就像下图所示:

    开始

    首先写好Processing该有的样子,定义settings(),setup(),draw()等函数:

    void settings(){
       size(800,800);
    }
    void setup() {
       
    }
    
    void draw() {
       
    }
    

    这个settings()我会单独去做讲解,这里简单说一下:它是早于setup()初始化的处理函数,有点像Unity脚本系统中Start()Awake()的关系,但是逻辑层面是不一样的。很多PApplet类中的函数在这里是不能被调用的,除了size()smooth()两个函数。而且,一旦写了settings(),就必须得把上述两个函数写在settings()里头!大家以后都可以养成习惯这么去填写,因为Processing系统这么设定,有它的道理,不过如果是纯碎学习,那不码这个settings()也无妨。还有个值得说的,因为只是要做个图,其实draw()没必要写上。

    小试牛刀

    我们先试一试画一个矩形框,如下:

    noStroke();
    fill(255);
    rect(150,150,100,100);
    

    这样会在画布上出现一个白色矩形框,ok,接下来要做的是把这个事情给过程化(面向过程),写个函数封装其过程:

    void drawRect(int c, int x, int y, int w, int h) {
      noStroke();
      fill(c);
      rect(x, y, w, h);
    }
    

    drawRect()可以被传入五个参数,分别代表其颜色、坐标信息x,y、矩形长宽大小。为什么能这么去封装它,这要求思考问题本身。细细观察棋盘格的特点,黑白方块相隔,如果抽象出它的属性,那么就不难想得到有诸如上述的参数,我们把它称之为属性(当然这个说法其实是不严谨的,因为现在我们的编程思路仅仅是面向过程,在OOP面向对象中这个特点会更加明显)[哦对,有读者感兴趣的话也能找找有关函数式编程的资料,绝对会让你开拓眼界,在思考问题的方式上会有不一样的感受哦,参考https://www.zhihu.com/question/28292740?sort=created]。

    再接再厉

    有了这个函数就可以在外头传进参数来绘制想要的结果,那问题来了,如何传进去?首先是颜色,颜色好办,

    int c = color(200,20,20);  //这里可以将color类型看成是int 类型,其实在计算机里颜色这概念也就是一个数值而已
    

    这样就结束了。然后是位置,如果你之前学过或者感受过循环结构(编程是要多多感受的,你说编程有没有套路,其实很多时候是可以凭经验办事的),那么就不难想到两个for循环遍历来绘制布满整个画布的图形的例子,那在这里,同样是做这样的处理(这就是所谓的算法):

    for (int x = 0; x  < width; x += increW)
      {
        for (int y = 0; y < height; y += increH)
        {
          int c = color(255);
          drawRect(c, x, y, increW, increH);
        }
      }
    

    而对于矩形大小,我们做一假设,设想要在画布上绘制10*10个方块阵列,那么每个方块的大小,即位置偏移增量increWincreH(increment表示增量,一般我们会使用常用的英文缩写定义变量名)就可以这么计算得出:

      increW = width / WCOUNT;   //   WCOUNT、HCOUNT代表数量10、10  你可以写成 increW=width/WCOUNT;这样,没问题!
      increH = height / HCOUNT;  //   但是养成良好的编程习惯和修养,加上些空格,你自己也觉得便于阅读,还haokanmeiguan
    

    在for语句的第三个表达式中写明x自加increW,y自加increH,得到的结果便是每次传入drawRect()函数中的位置有了相应偏移,大小也有了定义,即每次位移的数值。如果你按照这一步骤敲码执行,你会得到全白的画布,为什么呢?很简单,事实上Processing已经帮你绘制了这么多方块,只是颜色统一,位置统一,完美无瑕得散步在画布上了,没有任何缝隙。而要想实现间隔黑白效果,是不是还得加上黑色方块呢。是的,就得是要绘制这样的rect:

    noStroke();
    fill(0);
    rect(150,150,100,100);
    

    但是,如何把它整合在for循环体里呢?这就又要谈到简单的算法技巧,我们可以引入一个开关变量来处理间隔绘制不同颜色的流程,对于"开关变量"这一说法,读者请参考https://blog.csdn.net/fddxsyf123/article/details/62848357这一篇之前写的。在这里你脑力应是如下的逻辑:

    if(k == 0)
    {
       fill(255);
       rect(150,150,100,100);
    }
    if(k == 1)
    {
       fill(0);
       rect(150,150,100,100);
    }
    

    结成正果

    我们进一步把它简化,看成是奇数和偶数差别,这样只要定义一个int值,每次绘画完毕,相当于状态要改变了,就得切换,这个值自加一个值或者自减就可以达成了。有机整合进循环体,可以这样表示:

    int k = 0;   // k代表状态,具体数值代表什么意思得看上下文
    int c = 0;
    for (int x = 0; x  < width; x += increW)
    {
      for (int y = 0; y < height; y += increH)
      {
        if(k % 2 == 0)  //注意这个判断条件是关键的,判断是否被2整除,如果真,则是偶数,反之奇数,这就达成了两种状态互切效果
          c = color(255);
        else 
          c = color(0);
        drawRect(c, x, y, increW, increH);
        k++;   //一个状态完毕,切换
      }
      k++;   //现在是一列一列遍历绘制,因此没换一列也得切换状态,形成棋盘网格效果
    }
    

    好了基本图形已经展现出来了~~~ 完整代码如下:

    int increW;
    int increH;
    int WCOUNT = 10;
    int HCOUNT = 10;
    
    void drawRect(int c, int x, int y, int w, int h) {
      noStroke();
      fill(c);
      rect(x, y, w, h);
    }
    
    void settings() {
      size(800, 800);
    }
    void setup() {
      increW = width/WCOUNT;
      increH = height/HCOUNT;
      int k = 0;
      int c = 0;
      for (int x = 0; x  < width; x += increW)
      {
        for (int y = 0; y < height; y += increH)
        {
          if (k % 2 == 0)
            c = color(255);
          else 
          c = color(0);
          drawRect(c, x, y, increW, increH);
          k++;
        }
        k++;
      }
    }
    
    void draw() {
    }
    

    呈现的效果

    写在最后的话

    好久没写了,是该多分享多交流,我会同步更新于CSDN上,请多多支持鼓励,有问题留言,感谢。

  • 相关阅读:
    ALinq Dynamic 使用指南——前言
    前端与后端分离的架构实例(三)
    前端与后端分离的架构实例(二)
    启动画面QSplashScreen鼠标点击的时候不退出
    Qt组件屏蔽鼠标激活
    Qt LNK2001错误
    QtDesigner中设定一个组件位于另一个组件上方
    QToolButton设置图片
    osgearth_package切片工具切局部影像或者高程tif无法生成切片问题;切完数据集无法显示问题
    Qt输入框添加搜索按钮,以及自动补全内容
  • 原文地址:https://www.cnblogs.com/sharpeye/p/13732539.html
Copyright © 2011-2022 走看看