【17】processing-矩阵(中文)

二维阵列

Daniel Shiffman

数组按线性顺序跟踪多个信息片段,即一维列表。然而,与某些系统(数字图像、棋盘游戏等)相关联的数据是二维的。为了使这些数据可视化,我们需要一个多维数据结构,即多维数组。二维数组实际上只不过是数组的数组(三维数组是数组的数组)。想想你的晚餐。你可以有一个你吃的东西的一维列表:

(生菜、西红柿、牛排、土豆泥、蛋糕、冰淇淋)

或者你可以有一个包含三道菜的二维列表,每道菜都包含你吃的两样东西:

(生菜、西红柿)和(牛排、土豆泥)和(蛋糕、冰淇淋)

对于数组,我们老式的一维数组如下所示:

int[] myArray = {0,1,2,3};

二维数组如下所示:

int[][] myArray = { {0,1,2,3}, {3,2,1,0}, {3,5,6,1}, {3,8,3,4} };

为了我们的目的,最好把二维数组看作一个矩阵。矩阵可以被认为是一个数字网格,排列成行和列,有点像宾果游戏板。为了说明这一点,我们可以将二维数组写出如下:

 

int[][] myArray = {  {0, 1, 2, 3},
                     {3, 2, 1, 0},
                     {3, 5, 6, 1},
                     {3, 8, 3, 4}  };

 

我们可以使用这种类型的数据结构来编码有关图像的信息。例如,以下灰度图像可以由以下数组表示:

 

 

int[][] myArray = {  {236, 189, 189,   0},
                     {236,  80, 189, 189},
                     {236,   0, 189,  80},
                     {236, 189, 189,  80}  };

 

为了遍历一维数组的每个元素,我们使用for循环,即:

 

int[] myArray = new int[10];
for (int i = 0; i < myArray.length; i++) {
  myArray[i] = 0;
}

 

对于二维数组,为了引用每个元素,必须使用两个嵌套循环。这为矩阵中的每一列和每一行提供了一个反变量。

 

int cols = 10;
int rows = 10;
int[][] myArray = new int[cols][rows];
//两个嵌套循环允许我们访问二维数组中的每个点。
//对于每一列I,访问每一行J。
for (int i = 0; i < cols; i++) {
  for (int j = 0; j < rows; j++) {
    myArray[i][j] = 0;
  }
}

 

例如,我们可以编写一个使用二维数组绘制灰度图像的程序。

 

size(200,200);
int cols = width;
int rows = height;
// 声明二维数组
int[][] myArray = new int[cols][rows];
// Initialize 2D array values
for (int i = 0; i < cols; i++) {
  for (int j = 0; j < rows; j++) {
    myArray[i][j] = int(random(255));
  }
}
//绘制点
for (int i = 0; i < cols; i++) {
  for (int j = 0; j < rows; j++) {
    stroke(myArray[i][j]);
    point(i,j);
  }
}

 

二维数组也可用于存储对象,这对于编写包含某种“网格”或“板”的草图特别方便。以下示例显示存储在二维数组中的单元格对象网格。每个单元格是一个矩形,其亮度在0-255之间以正弦函数振荡。

 

 

 

//二维对象数组
Cell[][] grid;
//网格中的列和行数
int cols = 10;
int rows = 10;
void setup() {
  size(200,200);
  grid = new Cell[cols][rows];
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      // 初始化每个对象
      grid[i][j] = new Cell(i*20,j*20,20,20,i+j);
    }
  }
}
void draw() {
  background(0);
  //计数器变量i和j也是列号和行号以及
    //用作网格中每个对象的构造函数的参数。  
  for (int i = 0; i < cols; i++) {
    for (int j = 0; j < rows; j++) {
      // 振荡并显示每个对象
      grid[i][j].oscillate();
      grid[i][j].display();
    }
  }
}
//单元格对象
class Cell {
 //单元格对象知道其在网格中的位置
    //以及变量x,y,w,h的大小
  float x,y;   // x、 y位置
  float w,h;   // 宽度和高度
  float angle; // 振荡亮度角
  // 单元构造函数
  Cell(float tempX, float tempY, float tempW, float tempH, float tempAngle) {
    x = tempX;
    y = tempY;
    w = tempW;
    h = tempH;
    angle = tempAngle;
  } 
  
  // 振荡意味着增加角度
  void oscillate() {
    angle += 0.02; 
  }
  void display() {
    stroke(255);
    // 正弦波计算颜色
    fill(127+127*sin(angle));
    rect(x,y,w,h); 
  }
}

 

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值