物理系统与艺术结合下的代码创作

创意编程作业

    

主题及要求

    参考《代码本色》0-4章节,针对每个章节,编写5个习作。要求每个习作至少参考2个案例且必须有一定拓展。

    

完成情况

    本次作业按照规定要求认真学习书上相关内容,并运行浏览学习了每一段给出的范例代码。每一个习作都至少参考2个案例并且结合自己的想法加以拓展。

    

具体作业

第0章-引言

    学习心得:本章主要介绍了随机行为,噪声函数。通过本章内容的学习可以发现,随机行为和噪声算法可以对图像的表现,数据的研究及可视化,对对象行为预期的控制或则测定以及对物体纹理等方面都有应用。我在学习中发现,通过随机行为绘出的图画虽然随机,但是其美感却没有丢失,甚至有一种整体的风格在。创作中,我结合噪声函数的特点,将海面各个位置浮动不定的情况进行模拟表现
在这里插入图片描述
     对于海洋海面的表现主要难处在于对其浮动情况的仿真,这一点我们可以通过噪声函数的随机特性来进行模拟。实现的主要逻辑为: 对于宽度的每一个单位都进行从上至下的绘制(一共为width),相当于两点连线,终点确定为(x,height),起始点为(x,噪声随机点y)。

      while (x < width) {
      line(x, 200 + 50 * noise(x / n, time), x, height); //海平面在y = 250 上下浮动
      x = x + 1;
      }
      time = time + 0.02; 

     为了控制海洋面波澜的幅度大小,我们设定了参数n。当n越大,则noise随机的范围越小,海洋面也就越稳定;反之,当n越小,则其随机的范围越大,海洋面就越汹涌。
     为了让用户能够参与交互,我们给与用户控制海洋面的特权!通过“↑”可以使得n减少(最小为10),使得波涛汹涌;“↓”键可以使得n增大,使得海面平静。
在这里插入图片描述

  if(keyCode == UP &n>10)
  {
    n-=10;
  }
  else if(keyCode ==DOWN)
  {
    n+=10;
  }

     

第1章-向量

    学习心得:本章主要围绕着向量,讲解了Processing中对于PVector的具体使用。通过学习可以发现,PVector作为一种数据结果其存储方式更加适合我们对物理系统的分析和编写。通过本章掌握了对于向量的基本运算以及在向量背景下的速度以及加速度概念。关于本章创作,我以“蝶灵”命名我的习作。用户可以通过鼠标来操控蝴蝶精灵们是否跟随,可以通过按键来控制蝶灵的数量,相关的数据也会在窗口中进行交互显示
在这里插入图片描述
    关于编程的实现,我们通过面对对象的思想,为蝴蝶专门设计一个类——Mover,其中有着蝴蝶必要的属性,比如:位置,运动速度(分为散开和跟随鼠标两种),加速度,最大速度。为了让蝴蝶能够听从用户的指挥,我们设置了is_broke布尔变量,当其为flase时,蝶灵们跟随用户运动:

   if(!is_broke) //此时跟随鼠标运动
   {
    // Velocity changes according to acceleration
    velocity.add(acceleration);
    // Limit the velocity by topspeed
    velocity.limit(topspeed);
    // position changes by velocity
    position.add(velocity);
   }

    上述代码实现的是计算当前情况下的新速度,限制速度的范围,计算蝶灵的移动。为了使得跟随鼠标功能的实现,还需要:

    //跟随鼠标运动的设置
    PVector mouse = new PVector(mouseX,mouseY);
    acceleration = PVector.sub(mouse,position);
    acceleration.normalize();
    acceleration.mult(0.3);

将鼠标与蝶灵当前时刻的位置的差单位化后即可得出方向,这儿再给加速度赋予一个大小即可。
    另外,对于蝴蝶飞舞和外观色彩效果的模拟,我是通过random函数,随机改变其大小和颜色来实现。
    关于交互方面,用户可以通过鼠标控制蝶灵是否跟随,通过空格键来减少蝶灵数量;通过s键来增加蝶灵的数量。
在这里插入图片描述
    

第2章-力

    学习心得:本章主要介绍了力学中的牛一牛二牛三,涉及到了流体阻力和万有引力。对我而言比较新的是流体阻力部分,其他内容在初高中都已经打了比较扎实的基础,在编程实现上也比较顺利。相比5个习作,本章的创作在视觉上可能稍有欠缺,因为我将重心放在了物理效果实现上了。本章习作我主要实现了万有引力,失重情况,流体组合和浮力的结合。因为流体阻力在案例中通过水来实现,所以我选择将其仿真性提升,将书中没有涉及的浮力一起通过编程实现。
在这里插入图片描述
    整个编程主要创建了4个文件,其中Attractor类用于实现万有引力,Liquid类用于实现流体的阻力和液体的浮力,Mover类则定义了小球的基本属性。关于万有引力和流体阻力部分书中已经给出详细的推到已经编程的解释,在这儿我就不对这部分细节进行展开。在我的习作中,用户可以控制物体是否失重,并且可以创造真实的海洋环境。
    下面对浮力部分的编程进行说明:计算物体浮力有很多种方法:
在这里插入图片描述
对于编程的实现,我通过阿基米德原理公式即可。到这儿可以看出难点在于对于V排的计算。由于我们的物体选择了球体,那么在计算上会简便许多。对于落在水中的球体的浸没部分体积的计算在数学上即称对“球缺”的计算:
在这里插入图片描述
    通过高数积分的推导我们可以得到球缺体积的计算,那么我们编程的最大难题也被解决。从编程角度来看,现在还需要考虑的是小球什么时候受到浮力。分析发现,当 |海平面的y轴坐标 - 球心y轴坐标| > R 时,小球分为还未入水或者已经完全浸没的两种情况,当 |海平面的y轴坐标 - 球心y轴坐标| <= R时,小球有被水浸没的体积,此时的 h = R - (海平面y - 小球的y)。
    分析完了以上部分,编写上就畅通无阻了,下面给出浮力部分代码:

 PVector fuli(Mover m) {
    float p = 0.1;//液体密度,默认为1
    float g = 0.1;//g = 0.1,和前面脚本统一
    float r = m.mass*8;
    float h_water = 0;
    float water_leve = 215 + 50 * noise(x / 100, time);
    if(abs(water_leve - m.position.y)<=r)//部分浸没
    {
      h_water = r - (water_leve - m.position.y);
    }
    else if(water_leve - m.position.y > r)//未浸没
    {
      h_water = 0;
    }
    else if(m.position.y - water_leve > r ) //完全浸没
    {
      h_water = 2*r;
    }
    float V_water  = 3.14 * (r - h_water/3)*h_water*h_water; //球冠体积公式
    float fuliF = p * g * V_water*0.8;
    PVector fuliForce = new PVector(0,-1);//浮力竖直朝上
    fuliForce.mult(fuliF);//确定方向以后乘以对应大小
    return fuliForce;
  }

    在具体的测试上我发现了一些不稳定因素,这可能是由于之前流体阻力部分许多简化的计算和模拟对整个系统的误差导致的,所以最后我在fuliF的值上*0.8来使得显示效果上更为接近真实状况。
    关于交互部分的设置如下:
在这里插入图片描述
    

第3章-振荡

    学习心得:本章主要介绍了三角函数,极坐标系,波以及类似的振荡运动。本章部分内容与老师最开始几周对于小球运动成像分析上比较相近。本章的习作,我主要通过结合极坐标系下的运动和xoy轴坐标系下运动的结合,绘制了一条花蛇。在功能上实现的是对于图形的绘制可进行振荡函数转为三角函数的运动轨迹切换。
在这里插入图片描述
    绘制运动轨迹的切换通过布尔变量is_circle来控制。关于振荡轨迹的绘制通过极坐标系,动态变化半径和角度来实现:

  ellipse(x+width/2, y+height/2-70, random(1,16),random(1,16)); 
  y = r * cos(theta);
  x = r * sin(theta);
  theta += 0.03;
  r += 0.15;

关于三角函数的绘制通过y = sinx,也是通过动态变化x轴坐标和半径来实现:

  ellipse(x+width/2, y+height/2-70, random(1,16),random(1,16)); 
  x = r*sin(0.1*y);
  r = r + 0.15;
  y = y + 0.2;

    细心的同学应该会发现我对x和y的坐标位置进行了交换。为了绘制一条正常坐姿的花蛇,需要将坐标系变换一下,比较简单的方式就是交换x和y的位置,使得我们的花蛇呈现的方向正确。
    当然,为了实现花蛇的外观,我将绘制椭圆的宽高进行了适当范围内的随机以达到鳞片的效果;对其颜色也进行了随机,实现花色的效果。
    交互方面,用户通过空格就可以来进行对于绘圈还是绘波的控制了。

void keyPressed() {
  switch(key) {
  case ' '://s Key
    if(is_circle)
    {
      is_circle = false;
    }
    else {
      is_circle = true;
    }
  }
}

    

第4章-粒子系统

    学习心得:本章主要的内容比较考察对JAVA语言的应用,在编程上需要考虑的细节也比较多。对于比较好效果的实现还需要综合考察设计理念和编程能力,总体而言是难度比较大但是创造力无穷极具魅力的一章。其主要从单个粒子的分析到粒子类的构建到通过JAVA面向对象语言的继承和多态的特性来实现粒子系统,通过本章节的学习也充分感受到了粒子系统的魅力和可创性本章的习作,我主要通过对粒子构建上的改造,增加了更多的变换效果,并且将变量之间相互关联起来综合实现了以 “飞鸟世界“ 为名的粒子系统世界。
在这里插入图片描述
     先从设计理念上来解释我的作品:我的主要构思是展现生物从细胞演化到飞鸟的过程。用户可以通过按键来决定细胞在什么时候进行演化,甚至可以实现演化的倒退,让飞鸟重新变成细胞。在构图设计上,以暖色调为主,将细胞演化的颜色与细胞的寿命联系到一起,将世界的颜色(即背景图片的颜色)与细胞的数量联系到一起,让整个画面呈动态变化的展现。
    本习作的编程基于对案例全黑小球的改编,并且借鉴了一位博主《冰与火世界的构建》作品。代码逻辑构建上分为5个文件,其中Cell为细胞部分,Triangle是跟随的小三角形亮光,他们都是Particle的子类,继承了Particle的位置,速度,加速度,原始位置,角度,生命周期等属性和相关函数。Cell和Triangle分别对Particle父类的函数进行重写。所有的对象都需要加入ParticleSystem类下的Plist列表。在颜色模型的使用上选择了HSB,关于背景的颜色将其与粒子的个数进行关联:

  //根据粒子的数量来确定背景颜色的饱和度
  background(300, ps.getSize(), 366);

    关于细胞的绘制是通过Point()画点来实现,通过改变两个点的颜色属性,将其与当前生命剩余进行关联,并且让较大的 Point的透明度的值较低,就可以完成对细胞的构建:

      stroke(hue + lifespan * 1.5+random(100), 360, 360, 30);
      strokeWeight(100);
      point(p.x, p.y);

      stroke(hue + lifespan * 1.5, 360, 360, 180);
      strokeWeight(30);
      point(p.x, p.y);

    关于飞鸟的绘制,则是将点取代为三角形,为了实现仿真的特性,让三角形进行不停的旋转,所以可以在父类中定义相关的旋转属性:

triangle(p.x, p.y,p.x+random(-2,2), p.y+random(-2,2),p.x+random(-3,3), p.y+random(-5,5));
    //转动
    aVelocity += aAcceleration;
    angle += aVelocity;

    所有粒子都具有生命周期,需要通过相关的进行衰减的设置:

    //.....
    lifespan = maxLifespan = 250;
    //用于控制生命流逝的快慢
    lifeRate = random(0.35, 1);
    //.....
        //生命流逝
    lifespan -= lifeRate;

    关于较小的跟随特效三角形的绘制,只需要在Triangle类中绘制相应的旋转小三角即可,这个步骤和对Cell的构造比较类似,不再详述。

    为了实现从细胞到飞鸟的效果,我们还需要几个布偶变量来控制绘画的内容:

 boolean is_OpenIntroduce = true;
void keyPressed() {
  switch(key) {
  case ' '://s Key,让细胞孵化为飞鸟
    if(is_cell)
     {is_cell = false;break;}
    else
     {is_cell = true;break;}
   //..........
  }
}

    通过Space空格键就可以来控制对飞鸟世界的交互了:
在这里插入图片描述

总结

    以上便是对本次《代码本色》的学习和习作创作的具体内容。通过本次的学习也发现到了只要创造力无限,就可以通过编程的方式来创造一个魅力的世界;同样,编程的世界也同样可以赋予我们意想不到的惊喜,让我们更好地拥有创造力。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值