互动媒体技术——《代码本色》习作一

概述

1.要求介绍
2.案例参考
3.作品拓展
一、要求介绍

针对《代码本色》第0章编写1个习作,需有不少于2个案例参考,且必须有一定的拓展。报告:写一篇文章,发表为博文/推文等形式,描述运用的规律,若用到了数学/物理/化学等学科中的知识,要用平实易懂的语言介绍原理,尝试运用凝练的数学语言表达(公式、方程、推导等),特别要描述出这些原理如何在作品中呈现的。

二、案例参考
1.案例参考一:均匀分布

(1)随机数的分布:均匀分布
了解Processing的随机数生成器产生的随机数。random()函数中取得的随机数并不是真正随机的,因此它们称为“伪随机数”。它们是由模拟随机的数学函数生成的。随着时间推移,这个函数将呈现出固定的模式,但那段时间很长,所以对我们来说,它的随机性已经足够了。
(2)相关代码:使用柱状图测试均匀分布

//随机数的分布
int [] randomCount;
void setup() {
  size(640, 240);
  randomCount=new int[20];
}
void draw() {
  background(255);
  int index=int(random(randomCount.length));//选择一个随机数,增加计数
  randomCount[index]++;
  stroke(0);
  fill(127);
  int w=width/randomCount.length;
  
  for (int x=0; x<randomCount.length;x++) {
    fill(random(125,255),random(0,255),random(125,255));
    rect(x*w, height-randomCount[x]*5,w-1,randomCount[x]*5);
  }
}

(3)效果展示
在这里插入图片描述

2.案例参考二:Perlin噪声

(1)Perlin噪声介绍:
由Ken Perlin发明的自然噪声生成算法 ,一个噪声函数基本上是一个种子随机发生器。它需要一个整数作为参数,然后根据这个参数返回一个随机数。如果你两次都传同一个参数进来,它就会产生两次相同的数。这条规律非常重要,否则柏林函数只是生成一堆垃圾。
在这里插入图片描述
(2)processing中关于Perlin噪声的使用
在Processing中使用noise()函数生成Perlin噪声,其中有一、二、三个参数可选,分别代表一维、二维、三维的噪声。
在这里插入图片描述
(2)相关代码:利用perlin噪声生成云彩

public void drawCloud() {
    for (int x=0; x<width; x++) {
      for (int y=0; y<height; y++) {
        float n=noise(0.02*x, 0.02*y, 0.02*t)*255;
        set(x, y, color(n));
      }
    }

(3)效果展示
在这里插入图片描述

三、作品拓展

(1)作品一:利用随机数生成树枝

  • 效果展示
    在这里插入图片描述
  • 介绍
    总体介绍:该作品由自定义的概率生成每一个树枝,树枝的生成利用了递归,之前尝试过每一个树枝给它定义过三个枝丫,但是那样子由于层级太多,导致生成的枝丫全堆积在了一起。于是设置了自定的概率,通过概率控制枝丫的个数,比如分支为一的概率为0.5,同时分支为一时,枝丫是向左分支还是向右分支的概率相等。分支为二的概率为0.3.分支为3的概率为0.2.这样子就可以将树枝的枝丫分割开来,能够实现比较好的效果。
    在这里插入图片描述
  • 代码展示
ArrayList<Twig> twig = new ArrayList<Twig>();//存放所有的树枝
int maxHight =10;//树的最大层级
void setup() {
  size(600,600);
  float rootLength = random(80.0, 150.0);
  twig.add(new Twig(width/2, height, width/2, height-rootLength, 0));
  ///递归生成整个树
  recursion(twig.get(0));
}
void draw() {
  background(0);
  for (int i = 0; i < twig.size(); i++) {
    Twig branch = twig.get(i);
    branch.drawTwig();
    if(!branch.judgeLevel()){    
      ellipse(branch.end.x,branch.end.y,random(0,10),random(0,10));
    }
  }
}
int red=0;
void mouseClicked()
{
  twig.clear();
  float rootLength = random(80.0, 150.0);
  twig.add(new Twig(width/2, height, width/2, height-rootLength, 0));
  red=int(random(0,255));
  recursion(twig.get(0));
}
////****************递归生成树枝******************
void recursion(Twig twigFather) {
  ArrayList<Twig> sonTwig = new ArrayList<Twig>();//存放新生成的子树枝
  PVector beginSon=twigFather.end;//子树枝的开始点
  float probel=random(0,1);
  if(probel<0.25){
    sonTwig.add(new Twig(beginSon.x, beginSon.y, beginSon.x+random(20, 50), beginSon.y-random(10, 50), twigFather.level+1));
  }else if (probel<0.5){
    sonTwig.add(new Twig(beginSon.x, beginSon.y, beginSon.x-random(20, 50), beginSon.y-random(10, 50), twigFather.level+1));
  }else if(probel<0.8){
    sonTwig.add(new Twig(beginSon.x, beginSon.y, beginSon.x-random(20, 50), beginSon.y-random(10, 50), twigFather.level+1));
    sonTwig.add(new Twig(beginSon.x, beginSon.y, beginSon.x+random(20, 20), beginSon.y-random(10, 50), twigFather.level+1));    
  }else{
     sonTwig.add(new Twig(beginSon.x, beginSon.y, beginSon.x+random(20, 50), beginSon.y-random(10, 50), twigFather.level+1));
    sonTwig.add(new Twig(beginSon.x, beginSon.y, beginSon.x-random(20, 50), beginSon.y-random(10, 50), twigFather.level+1));
  }
  // 将新生成的树枝加入总的树枝
  for (Twig sonTwigone : sonTwig) {
    twig.add(sonTwigone);  
    if (sonTwigone.level < maxHight) {
      // 如果不是最大的深度,那么就继续生成树枝
      recursion(sonTwigone);
    }
  }
}
//******************树枝类**********************
class Twig {
  private PVector start;//树枝绘制的起点
  private PVector end;//树枝绘制的终点
  private int level;//树枝的层级
  //**********构造函数***********
  public Twig(float x1, float y1, float x2, float y2, int level) {
    this.start=new PVector(x1, y1);
    this.end=new PVector(x2, y2);
    this.level=level;//树的层级
    
  }
  //**********绘制树枝***********
  public void drawTwig() {  
    strokeWeight(10-level);
    stroke(red,100,this.level*20);
    line(start.x, start.y, end.x, end.y);
  }
  //**********判断层级是否小于最大层数***********
  public boolean judgeLevel(){
    if(this.level<maxHight)return true;
    else return false;
  }
}

(2)作品二:伪随机数之均匀分布实现油漆飞溅效果

  • 流程展示
    在这里插入图片描述
    1.map:实现颜色的映射

  • 代码展示

void setup() {
  size(800, 500);
  background(255);
}

void draw() {
}

//鼠标按下执行的操作
void mousePressed() {
  drawManyCircle();
}
void drawManyCircle() {
  pushMatrix();
  translate(mouseX, mouseY);
  fill(random(125, 255), random(255), random(255));
  noStroke();
  int circleNum = int(map(random(1), 0, 1, 400, 500));
  //print(map(random(1), 0, 1, 700, 1000));
  //循环生成很多大小不同的圆形
  for (int i = 0; i < circleNum; i++) {
    float diameter = random(1);
    float dis = pow(random(1), 4);
    //圆的半径控制在1—15大小范围内
    //各个圆之间的距离控制在0—150的范围内
    float circleDiameter = map(diameter, 0, 1.5, 1, 15);
    float circleDistance = map(dis, 0, 1, 0, 150);
    float radians = random(TWO_PI);
    ellipse(circleDistance * sin(radians), circleDistance * cos(radians), circleDiameter, circleDiameter);
  }
  popMatrix();
}

  • 效果展示
    在这里插入图片描述

(3)作品三:使用Perlin噪声生成流动的冰淇淋

  • 相关实现介绍:
  1. noiseDetail():noiseDetail以指定细节程度
  2. noiseSeed():指定噪声种子,同样的种子每次产生相同的噪声
  3. 使用一维Perlin噪声,使用两个参数的输入,一个输入与x有关,另一个输入与y有关。
  • 代码展示
Perlin perlin1=new Perlin();
int t=0;
void setup()
{
  size(350, 800, P3D);
  noiseSeed(4);
  noiseDetail(3);
}
void draw() {
  ++t;
  perlin1.drawMoutain();
  strokeWeight(4);
  perlin1.drawLine();
}
class Perlin {
  public Perlin() {
    super();
  }
  public void drawMoutain() {
    if (frameCount%20==0)stroke(random(125, 255), random(0, 255), random(125, 255));
    for (float x=0; x<width; x++) {
      float n=noise(0.015*x, 0.01*t)*(height/2);
      line(x, 0, x, height/2-n);
    }
  }
   public void drawLine(){
    line(0,height/2,width/2,height);
    line(width,height/2,width/2,height);    
  }
  
  • 效果展示

在这里插入图片描述

发布了28 篇原创文章 · 获赞 4 · 访问量 5397

猜你喜欢

转载自blog.csdn.net/Program_dancing/article/details/103131648
今日推荐