欢迎光临散文网 会员登陆 & 注册

创意编程作业——互动编程习作——表现随机行为及牛顿运动学

2019-12-14 00:47 作者:山海欧内酱  | 我要投稿

继上两次创意编程作业之后,此次实验采用了有代码参考的processing,对《代码本色》之中的0-4章内容进行理解。

第0章 引言

此章主要内容为随即行为与噪声函数

习作:

本章的习作想法是用Perlin Noise去实现一些小立方体的体积随机变化


void setup(){

  size(500, 400, P3D); 

  background(100,100,100);

}

float t = 0;

float a=0;

void draw(){

  ++t;

  clear();

  for (int x = 0; x < width; x += 50){

    for (int y = 0; y < height; y += 50){

      int z=0;

        float n = noise(0.05*(x), 0.05*(y), 0.05*(z+t));

        translate(x,y,0);

       float b;

        a++;

        b=0.002*a;

        fill(b,255-b,0.5*b);

        box(n*50);

        translate(-x,-y,0);

      rotateX(PI/7);

    }

  }

}


通过随时间变化的变量t和变量 n,接收 noise()函数的值,产生随机产生的噪声值,立方体的大小通过n来表现,以下是表现效果预览:


顺带使得立方体颜色随时间会发生变化

第一章 向量

此章主要内容为processing中向量是如何表现的,以及向量之间的加减乘除等各种计算的变现方法,和向量的运动,对物理模拟有很重要的基础作用。同时也对交互有了初步的接触

习作:

关于此章节的习作,拓展自一组同时朝着鼠标加速的运动物体。小球会朝着鼠标的位置加速前进,小球移动到目的地后不会停下来。同时,可以通过交互(w,s)改变小球行动速度

if(keyPressed){

      if(key == 'w'){

        topspeed =40;

      }

      if(key == 's'){

        topspeed =0;

      }

NOC_1_11_motion101_acceleration_array.pde:


Mover[] movers = new Mover[20];


void setup() {

  size(640,360);

  for (int i = 0; i < movers.length; i++) {

    movers[i] = new Mover(); 

  }

}


void draw() {

  

  background(255);


  for (int i = 0; i < movers.length; i++) {

    movers[i].update();

    movers[i].display(); 

  }

}

Mover.pde:

class Mover {


  // The Mover tracks position, velocity, and acceleration 

  PVector position;

  PVector velocity;

  PVector acceleration;

  // The Mover's maximum speed

  float topspeed;


  Mover() {

    // Start in the center

    position = new PVector(random(width),random(height));

    velocity = new PVector(0,0);

    topspeed = 5;

  }


  void update() {

    

    // Compute a vector that points from position to mouse

    PVector mouse = new PVector(mouseX,mouseY);

    acceleration = PVector.sub(mouse,position);

    // Set magnitude of acceleration

    //acceleration.setMag(0.2);

    acceleration.normalize();

    acceleration.mult(0.2);

    // Velocity changes according to acceleration

    velocity.add(acceleration);

    // Limit the velocity by topspeed

    if(keyPressed){

      if(key == 'w'){

        topspeed =40;

      }

      if(key == 's'){

        topspeed =0;

      }

      }

    velocity.limit(topspeed);

    // position changes by velocity

    position.add(velocity);

  }

  void display() {

    stroke(0);

    strokeWeight(2);

    fill(127,200);

    ellipse(position.x,position.y,48,48);

  }

}

小球会跟随鼠标进行加速度运动,如果按下w,球体移动会更快;按下s,小球停止

the world

第二章 力

此章节主要讲述了自然界常见重要力的在processing中的表现。包括牛顿定律的体现,引力,斥力,和摩擦力,阻力,万有引力的体现和力的计算

习作:

关于此次习作,基本想法是在实现引力的同时,也会在一定程度上改变为斥力,进行观察受力小球的变化

 if (position.x > width) {

      position.x = 0;

    } else if (position.x < 0) {

      position.x = width;

    }


    if (position.y > height) {

      velocity.y *= -1;

      position.y = height;

    }

如此实现距离不同力的类型转换,在此处还可以调整力的大小

NOC_2_6_attraction.pde:

Mover m;

Mover m1;


Attractor a;


void setup() {

  size(640,360);

  for(int i=0;i<3;i++){

  m = new Mover(1,300); 

  }

  m1=new Mover(1.2,0);

  a = new Attractor();

}


void draw() {

  background(255);


  PVector force = a.attract(m);

  m.applyForce(force);

  m.update();

  m1.applyForce(force);

  m1.update();

  

  a.drag();

  a.hover(mouseX,mouseY);

 

  a.display();

  m.display();

  m1.display();

}


void mousePressed() {

  a.clicked(mouseX,mouseY); 

}

void mouseReleased() {

  a.stopDragging(); 

}


Attractor.pde:

class Attractor {

  float mass;    // Mass, tied to size

  float G;       // Gravitational Constant

  PVector position;   // position

  boolean dragging = false; // Is the object being dragged?

  boolean rollover = false; // Is the mouse over the ellipse?

  PVector dragOffset;  // holds the offset for when object is clicked on


  Attractor() {

    position = new PVector(width/2,height/2);

    mass = 20;

    G = 1;

    dragOffset = new PVector(0.0,0.0);

  }


  PVector attract(Mover m) {

    PVector force = PVector.sub(position,m.position);   

    float d = force.mag();                        

    d = constrain(d,5.0,25.0);                         

    force.normalize();                                

    float strength = (G * mass * m.mass) / (d * d);    

    if(d<10){

      strength=-strength;

    }

    force.mult(strength);     

    return force;

  }

  void display() {

    ellipseMode(CENTER);

    strokeWeight(4);

    stroke(0);

    if (dragging) fill (50);

    else if (rollover) fill(100);

    else fill(175,200);

    ellipse(position.x,position.y,mass*2,mass*2);

  }

  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 hover(int mx, int my) {

    float d = dist(mx,my,position.x,position.y);

    if (d < mass) {

      rollover = true;

    } 

    else {

      rollover = false;

    }

  }

  void stopDragging() {

    dragging = false;

  }

  void drag() {

    if (dragging) {

      position.x = mouseX + dragOffset.x;

      position.y = mouseY + dragOffset.y;

    }

  }

}

Mover.pde:

class Mover {

  PVector position;

  PVector velocity;

  PVector acceleration;

  float mass;

  Mover(float a,float b) {

    position = new PVector(b,50);

    velocity = new PVector(1,0);

    acceleration = new PVector(0,0);

    mass = a;

  }

  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,16,16);

  }

  void checkEdges() {

    if (position.x > width) {

      position.x = 0;

    } else if (position.x < 0) {

      position.x = width;

    }

    if (position.y > height) {

      velocity.y *= -1;

      position.y = height;

    }

  }

}

小球在远离鼠标操控的小球时小球呈现受到引力,而靠近时会出现斥力,具体表现更是会出现“捕获小球”的现象

其实初始设置了两个小球设置了不同规则,可惜最后发现搞错了

第三章 振荡

本章主要将讲述了由三角函数为基础的振荡运动的实现,并由此可以实现一些更加复杂的带有角度的力的计算

习作:

本章节的习作主要想实现小球能够实现对一个单摆的干涉,能够产对单摆的排斥力,对它的运动产生影响

ch3.pde:

Bob bob;

Spring spring;

float flag=0;

float one=0;

Mover mover;


void setup() {

  size(800,500);

  spring = new Spring(width/2,10,100); 

  bob = new Bob(width/2,100); 

  mover = new Mover();

}


void draw()  {

  background(255); 


  mover.update();

  mover.display();


  PVector gravity = new PVector(0,2);

  PVector hit = new PVector(one,0);

  if(mover.location.x>400){

    one=random(-10,0);   

   }

  else{

    one=random(0,10);

  }

  

  if(mover.location.y>bob.location.y){

  flag=random(-1,0);

  }

  else{

  flag=random(0,10);

  }

  bob.applyForce(hit);

  bob.applyForce(gravity);

  

  spring.connect(bob);

  

  

  spring.display(); 

  spring.displayLine(bob);

  

  bob.update();

  bob.display(); 

}


Mover.pde:

class Mover {

  PVector location;

  PVector velocity;

  PVector acceleration;

  float topspeed;

  float xoff,yoff;

  float r = 16;

  

  Mover() {

    location = new PVector(width / 2,height / 2);

    velocity = new PVector(0,0);

    topspeed = 4;

    xoff = 100;

    yoff = 10;

  }

  

  void update() {

    PVector mouse = new PVector(mouseX,mouseY);

    PVector dir = mouse.get();

    dir.sub(location);

    dir.normalize();

    dir.mult(0.5);

    acceleration = dir;

    

    velocity.add(acceleration);

    velocity.limit(topspeed);

    location.add(velocity);

  }

  

  void display() {

    

    

    stroke(0);

    strokeWeight(2);

    fill(125);

    pushMatrix();

    rectMode(CENTER);

    translate(location.x,location.y);

    arc(0,0,20+0.1*mouseX,20+0.1*mouseX,0,2*PI);

    popMatrix();

  }

}


class PVector {

  float x;

  float y;

  

  PVector(float x_,float y_) {

    x = x_;

    y = y_;

  }

  

  PVector get() {

    PVector newVector = new PVector(x,y);

    return newVector;

  }

  

  void add(PVector v) {

    x = x + v.x; 

    y = y + v.y;

  }

  

  void sub(PVector v) {

    x = x - v.x;

    y = y - v.y;

  }

  

  void mult(float n) {

    x = x * n;

    y = y * n;

  }

  

  void div(float n) {

    x = x / n;

    y = y / n;

  }

  

  float mag() {

     return sqrt(x * x + y * y); 

  }

  

  void normalize() {

    float m = mag();

    if(m != 0) {

      div(m);  

    }

  }

  

  void limit(float max) {

    if(mag() > max) {

      normalize();

      mult(max);

    }

  }

  

  float heading2D() {

    return atan2(y,x); 

  }

}


class Bob { 

  PVector location;

  PVector velocity;

  PVector acceleration;

  float mass = 24;

  

  float damping = 0.95;


  Bob(float x, float y) {

    location = new PVector(x,y);

    velocity = new PVector(0,0);

    acceleration = new PVector(0,0);

  } 


  void update() { 

    velocity.add(acceleration);

    velocity.mult(damping);

    location.add(velocity);

    acceleration.mult(0);

  }


  void applyForce(PVector force) {

    PVector f = force.get();

    f.div(mass);

    acceleration.add(f);

  }


  void display() { 

    stroke(0);

    strokeWeight(2);

    fill(175);

    ellipse(location.x,location.y,mass+mouseX*0.1 ,mass+mouseX*0.1);

  }

}


Spring.pde:

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 = b.location.get();

    force.sub(anchor);

    

    float d = force.mag();

    float stretch = (d - len);

    

    force.normalize();

    force.mult(-1 * k * stretch);

    

    b.applyForce(force);

  }

  



  void display() { 

    stroke(0);

    fill(175);

    strokeWeight(2);

    rectMode(CENTER);

    rect(anchor.x, 150, 10, 10);

  }


  void displayLine(Bob b) {

    strokeWeight(2);

    stroke(0);

    line(b.location.x, b.location.y, anchor.x, 150);

  }

}

这样,就可以实现对单摆运动的同时能够使跟随鼠标的小球对它产生斥力的效果

稍微添加了球的大小能够随鼠标位置变化的效果

第四章 粒子系统

本章节主要讲述了粒子系统的生成与实现,多态和继承的简介与实现面向对象以及力对粒子系统的影响效果实现

习作:

此章节的习作主要是实现鼠标能产生排斥力组成实现排斥力的粒子系统

设置好力 v=new PVector(mouseX,mouseY);

ch4.pde:

ParticleSystem ps;

Repeller repeller;


void setup() {

  size(640,360);

  ps = new ParticleSystem(new PVector(width/2,50));

  repeller = new Repeller(width/2-20,height/2);

}


void draw() {

  background(255);

  ps.addParticle();

  

  // Apply gravity force to all Particles

  PVector gravity = new PVector(0,0.1);

  ps.applyForce(gravity);

  

  ps.applyRepeller(repeller);

  

  repeller.display();

  ps.run();

}


Particle.pde:

class Particle {

  PVector position;

  PVector velocity;

  PVector acceleration;

  float lifespan;

  

  float mass = 1; // Let's do something better here!


  Particle(PVector l) {

    acceleration = new PVector(0,0);

    velocity = new PVector(random(-1,1),random(-2,0));

    position = l.get();

    lifespan = 255.0;

  }


  void run() {

    update();

    display();

  }


  void applyForce(PVector force) {

    PVector f = force.get();

    f.div(mass);   

    acceleration.add(f);

  }


  // Method to update position

  void update() {

    velocity.add(acceleration);

    position.add(velocity);

    acceleration.mult(0);

    lifespan -= 1.0;

  }


  // Method to display

  void display() {

    stroke(0,lifespan);

    strokeWeight(2);

    fill(127,lifespan);

    ellipse(position.x-5+random(0,5),position.y-5+random(0,5),20,20);

  }


  // Is the particle still useful?

  boolean isDead() {

    if (lifespan < 0.0) {

      return true;

    } else {

      return false;

    }

  }

}


ParticleSystem.pde:

class ParticleSystem {

  ArrayList<Particle> particles;

  PVector origin;


  ParticleSystem(PVector position) {

    origin = position.get();

    particles = new ArrayList<Particle>();

  }


  void addParticle() {

    particles.add(new Particle(origin));

  }


  // A function to apply a force to all Particles

  void applyForce(PVector f) {

    for (Particle p: particles) {

      p.applyForce(f);

    }

  }


  void applyRepeller(Repeller r) {

    for (Particle p: particles) {

      PVector force = r.repel(p);        

      p.applyForce(force);

    }

  }



  void run() {

    for (int i = particles.size()-1; i >= 0; i--) {

      Particle p = particles.get(i);

      p.run();

      if (p.isDead()) {

        particles.remove(i);

      }

    }

  }

}


Repeller.pde:

class Repeller {

  

  // Gravitational Constant

  float G = 100;

  // position

  PVector position;

  float r = 10;


  Repeller(float x, float y)  {

    position = new PVector(x,y);

  }


  void display() {

    stroke(0);

    strokeWeight(2);

    fill(175);

    ellipse(mouseX,mouseY,48,48);

  }

  PVector repel(Particle p) {

    PVector v;

      v=new PVector(mouseX,mouseY);

    PVector dir = PVector.sub(v,p.position);     

    float d = dir.mag();            

    dir.normalize();                    

    d = constrain(d,5,100);                

    float force = -1 * G / (d * d);    

    dir.mult(force);                    

    return dir;

  }  

}

如此,就实现了鼠标处的小球对粒子系统的排斥效果。可以实现例子生成点的位置变化从而让小球来接也很容易实现

同时添加了生成点的随机抖动,很有精污的感觉

结语:

这几章节《代码本色》的阅读学习,我切身感受到了图像编程的神奇,但由自身编程水平所限,很多想法在经历很多次尝试后也没有完美实现,只能挑选出了简单的程序实现,借助同学的启发。但在习作过程中,自身对代码的理解也有了进步,很多想法也能够实现,也对之前的部分有了更为深入的体会。

虽然只是实现了很简单的随机与物理效果,但长足的积累肯定能够组合出复杂的效果。


创意编程作业——互动编程习作——表现随机行为及牛顿运动学的评论 (共 条)

分享到微博请遵守国家法律