Processing绘制随风飘扬的名画

Processing绘制随风飘扬的名画

目录:

  • 最终效果
  • 参考示例
  • 绘制原理
  • 绘制过程
  • 总结与体会

最终效果

在这里插入图片描述

参考示例

两个参考示例来自《代码本色》一书,另一个参考示例来自网站https://www.openprocessing.org,这个示例给出了关于风的参数。
示例一 2-1:

// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com

Mover m;

void setup() {
  size(640,360);
  m = new Mover(); 
}

void draw() {
  background(255);
  PVector wind = new PVector(0.01,0);
  PVector gravity = new PVector(0,0.1);
  m.applyForce(wind);//添加风力
  m.applyForce(gravity);//添加重力
  m.update();
  m.display();
  m.checkEdges();

}
// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com

class Mover {

  PVector position;
  PVector velocity;
  PVector acceleration;
  float mass;

  Mover() {
    position = new PVector(30,30);
    velocity = new PVector(0,0);
    acceleration = new PVector(0,0);
    mass = 1;
  }
  void applyForce(PVector force) {
    PVector f = PVector.div(force,mass);
    acceleration.add(f);
  }
  void update() {
    velocity.add(acceleration);
    position.add(velocity);
    acceleration.mult(0);
  }
  void display() {
    stroke(0);
    strokeWeight(2);
    fill(127);
    ellipse(position.x,position.y,48,48);
  }
  void checkEdges() {

    if (position.x > width) {
      position.x = width;
      velocity.x *= -1;
    } else if (position.x < 0) {
      velocity.x *= -1;
      position.x = 0;
    }
    if (position.y > height) {
      velocity.y *= -1;
      position.y = height;
    }
  }
}

示例运行效果:
在这里插入图片描述
本示例绘制了一个被风吹动的小球,同时小球还受到重力的作用下降,当小球撞到了画布边缘时做出判断,模拟出了弹力。
这提供给我一个想法:“风”,大自然的风可不是这么规律,自然界的风往往方向变化多端,要是风的吹向时刻在变化,那么,小球也就不是如此规律地左右循环了。为此,我修改了代码,让风的方向不变,但是大小随机变化得到下面的放飞的小球:
在这里插入图片描述

示例二 2-8:

// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com

Mover[] movers = new Mover[20];

float g = 0.4;

void setup() {
  size(640,360);
  for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover(random(0.1,2),random(width),random(height)); 
  }
}

void draw() {
  background(255);


  for (int i = 0; i < movers.length; i++) {
    for (int j = 0; j < movers.length; j++) {
      if (i != j) {
        PVector force = movers[j].attract(movers[i]);
        movers[i].applyForce(force);
      }
    }

    movers[i].update();
    movers[i].display();
  }

}
// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com

class Mover {

  PVector position;
  PVector velocity;
  PVector acceleration;
  float mass;

  Mover(float m, float x, float y) {
    mass = m;
    position = new PVector(x, y);
    velocity = new PVector(0, 0);
    acceleration = new PVector(0, 0);
  }

  void applyForce(PVector force) {
    PVector f = PVector.div(force, mass);
    acceleration.add(f);
  }

  void update() {
    velocity.add(acceleration);
    position.add(velocity);
    acceleration.mult(0);
  }
  void display() {
    stroke(0);
    strokeWeight(2);
    fill(0, 100);
    ellipse(position.x, position.y, mass*24, mass*24);
  }
  PVector attract(Mover m) {
    PVector force = PVector.sub(position, m.position);             // Calculate direction of force
    float distance = force.mag();                                 // Distance between objects
    distance = constrain(distance, 5.0, 25.0);                             // Limiting the distance to eliminate "extreme" results for very close or very far objects
    force.normalize();                                            // Normalize vector (distance doesn't matter here, we just want this vector for direction

    float strength = (g * mass * m.mass) / (distance * distance); // Calculate gravitional force magnitude
    force.mult(strength);                                         // Get force vector --> magnitude * direction
    return force;
  }


}

运行效果:
在这里插入图片描述
参考这个示例并不是说用到了这个示例的技术,而是因为这个示例中“多个小球”汇聚在一起又离开,从而想到如果这个小球有特定的图像,赋予不同的贴图图片,比如贴上的是不同的人脸,那么这个示例就可以表现一些人员流动和人格魅力的吸引力。总之“吸引力”为这个群组里面的联系。

通过上面两个示例,拓展的目标定在了有运动联系的群组图元,并且受到不同风速的影响,由于一些原因,《代码本色》本章的拓展已经完成过一个,是关于粒子的运动,后来做到第四章的拓展时,发现已经做好的和第四章的示例太相似。不过本文的拓展灵感也因第四章的拓展而得到闪现:模拟图元构成的画被风吹动的效果。

绘制原理

主要思想:
1、读入目标绘画作品
2、规定固定的图元数量
3、使得每一个图元受力运动

这里模拟自然界风吹的时候用到了柏林噪声,用这个方法产生的力来模拟自然界的风力会非常的自然。这一点《代码本色》一书的第0章就提到过。柏林噪声能生成符合自然序列(“光滑”)的伪随机数。

processing里面的noise函数可以产生柏林噪声,可接收x,y,z三个坐标分量作为输入,并返回0.0~1.0的double值作为输出。由于输出归一化,程序中需要将数值扩大相应的倍数,而且为了使方向有正有负,最后还需要减去一个设定值。

模拟绘画作品时,为了使得绘制高效,避免出现非常卡顿的现象,不能一个像素一个像素地获取颜色,而是取一个像素点的颜色,绘制5像素或者更大像素的图元。

在用柏林噪声的时候遇到了参数盲目调节的问题,后来幸运地在https://www.openprocessing.org找到一篇用柏林噪声来模拟风的示例,使用到了示例中的参数,而后自行进行略为调整。得到以下绘制过程

绘制过程

读入jpg图片,获取作品的高度

 img = loadImage("5.jpg");
 imgX=img.width;
 imgY=img.height;
 

绘制图元

  for(int j=50;j<imgY;j+=4)
   {
     for(int i=20;i<imgX;i++) 
     {

          float step = sin(a)*(sin((imgY-i)*PI/imgY));
          float swing = j+step*(180.0*noise(a+i/300.0, a+j/300.0,a/10.0)-90);//计算风力
          float dx = randomC()/2;
          float dy = randomC()/2;
          float x = i;
          float y = swing+dy;//更新物体的坐标
        strokeWeight(3);
          stroke(255);
          stroke(img.get(i,j));
          point(x,y);//图元为点,这里也可以图元为矩形rect,效果有些不同
  }

总结与体会

“用代码来画使得画动起来的画”十分好玩,也许真的有一天做出了各种各样变换的方式来使得“名画”动起来,我的电脑就是一个小型的数字名画展览器^ ^,毕竟到目前为止,我已经有两个关于如何使“名画”动起来的想法实现了。

  • 10
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 57
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 57
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值