【创意编程作业】《代码本色》第3章——振荡

Part1 实现效果以及扩展

在这里插入图片描述
研究不同质量物体(按照sin函数分布),在弹簧系统下的运动规律:整体呈现sin曲线。
同时单个小球颜色变换,在整体画面呈现sin曲线运动。
操作说明:
1、点击鼠标重置;
2、键盘上/下键进行帧率的增/减。

Part2 振荡

sin()函数的结果是一条介于-1到1的平滑曲线。这条曲线符合振荡的效果, 振荡是两点之间的周期性运动。
简谐运动即是物体按照正弦曲线周期性振荡。
振幅:离开运动中心的最大距离。
周期:完成一次往复运动所花费的时间。
在Processing中振荡的周期应当用帧数表示,需要通过frameRate获取当前帧率、通过frameCount获取当前帧数。
如果有需要的话,可以使用map函数将三角函数的结果映射到指定范围。
在这里插入图片描述

《代码本色》参考实例
1、简谐运动
在这里插入图片描述
2、弹簧
在弹簧模型中,物体悬挂在弹簧上进行上下摆动的简谐运动。弹簧的弹力可以通过胡克定律计算得到:在这里插入图片描述
k为常量,影响弹力大小。
x代表弹簧形变程度。
在这里插入图片描述在这里插入图片描述
模拟物体运动必要的几个变量:位置、速度、加速度。
在弹簧模型中,钟摆受力有重力和弹力。根据上一章的关于力的知识,可知由已知力可以改变物体的加速度、速度、位置。所以首先需要计算出距离,再由胡克定律计算出弹力,最后通过弹力改变上述三个变量值。
在这里插入图片描述

Part3 设计思路

通过上述的知识点和两个案例,我想运用(Processing模拟的)弹力系统,研究不同重力物体的运动情况,其重力分布是按照sin函数进行分配,其整体运动状态也应该呈现sin曲线模式。因为其所受弹力与形变长度有关,形变长度又与重力相关,重力又影响了位置。于是设计了本实验。
同时,摆钟小球的颜色根据逐一变化,与整体运动结合,形成了视觉上的运动体验,也间接地绘制出了sin曲线。
此外设计了键盘上下键来调节帧率,以方便用户观察其中规律。鼠标点击进行复原。

Part4 代码实现

①主函数

Bob[] bob=new Bob[30];
Spring[] spring=new Spring[30];
boolean isColor;
float nowFrameRate;
void setup(){
  frameRate(20);
  size(900,300);
  isColor=false;
  for(int i=0;i<bob.length;i++)
  {
    spring[i] = new Spring(15+30*i,10,100); 
    bob[i] = new Bob(15+30*i,100,10+2*sin(i));  
  } 
}

void draw()  {
  background(250); 
  
  for(int i=0;i<bob.length;i++)
  {
     if(frameCount%30==i)
        isColor=true;
     else
        isColor=false;
     bob[i].setColor(isColor);
     PVector gravity = new PVector(0,9.8);
     bob[i].applyForce(gravity);
  
     spring[i].connect(bob[i]);
     spring[i].constrainLength(bob[i],30,200);
  
     bob[i].update();
     bob[i].drag(mouseX,mouseY);
  
     spring[i].displayLine(bob[i]);
     bob[i].display(); 
     spring[i].display(); 
  }
  fill(0);
  text("frameRate:",10,height-20);
  text(int(frameRate),70,height-20);
  text("1.Click to reset.    2.Press UP/DOWN to add/sub frameRate.  ",10,height-5);
  
}

void keyReleased(){
  if(keyCode==UP)
  {
    frameRate(frameRate++);
  }
  if(keyCode==DOWN)
  {
    if(frameRate>=2)
      frameRate(frameRate--);
  }
}
void mousePressed()  {
   reset();
}

void reset() {
  for (int i = 0; i < bob.length; i++) {
    spring[i] = new Spring(15+30*i,10,100); 
    bob[i] = new Bob(15+30*i,100,10+2*sin(i)); 
  }
}

②Mover类

class Bob { 
  PVector position;
  PVector velocity;
  PVector acceleration;
  float mass;
  

  float damping = 0.98;


  PVector dragOffset;
  boolean dragging = false;
  boolean isColor=false;

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

  void update() { 
    velocity.add(acceleration);
    velocity.mult(damping);
    position.add(velocity);
    acceleration.mult(0);
  }

  void applyForce(PVector force) {
    PVector f = force.get();
    f.div(mass);
    acceleration.add(f);
  }
  
  void setColor(boolean c){
    isColor=c;
  }

  void display() { 
    stroke(0);
    strokeWeight(2);
    if(position.y>=158&&position.y<=162)
      fill(240);
   else 
   {
      if(isColor)
      fill(115,214,97);
    else
      fill(240);
     }
    //fill(position.y/200*255,position.y/200*200,position.y/200*255);
    if (dragging) {
      fill(50);
    }
    ellipse(position.x,position.y,25,25);
  } 

  void clicked(int mx, int my) {
    float d = dist(mx,my,position.x,position.y);
    if (d < mass) {
      dragging = true;
      dragOffset.x = position.x-mx;
      dragOffset.y = position.y-my;
    }
  }

  void stopDragging() {
    dragging = false;
  }

  void drag(int mx, int my) {
    if (dragging) {
      position.x = mx + dragOffset.x;
      position.y = my + dragOffset.y;
    }
  }
}

③Spring类

class Spring { 
  PVector anchor;
  float len;
  float k = 0.2;

  Spring(float x, float y, int l) {
    anchor = new PVector(x, y);
    len = l;
  } 

  void connect(Bob b) {
    PVector force = PVector.sub(b.position, anchor);
    float d = force.mag();
    float stretch = d - len;

    force.normalize();
    force.mult(-1 * k * stretch);
    b.applyForce(force);
  }

  void constrainLength(Bob b, float minlen, float maxlen) {
    PVector dir = PVector.sub(b.position, anchor);
    float d = dir.mag();
    if (d < minlen) {
      dir.normalize();
      dir.mult(minlen);
      b.position = PVector.add(anchor, dir);
      b.velocity.mult(0);
    } 
    else if (d > maxlen) {
      dir.normalize();
      dir.mult(maxlen);
      b.position = PVector.add(anchor, dir);
      b.velocity.mult(0);
    }
  }

  void display() { 
    stroke(0);
    fill(175);
    strokeWeight(2);
    rectMode(CENTER);
    rect(anchor.x, anchor.y, 2, 2);
  }

  void displayLine(Bob b) {
    strokeWeight(2);
    stroke(0);
    line(b.position.x, b.position.y, anchor.x, anchor.y);
  }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值