互动媒体技术——编程习题集

第0章 引言

参考 0.6.2 二维噪声
迷雾森林:


loat increment = 0.01;
float zoff = 0.0;  
float zincrement = 0.02; 

void setup() {
  size(200,200);
}

void draw() {
  background(0);
  loadPixels();

  float xoff = 0.0; 

  for (int x = 0; x < width; x++) {
    xoff += increment;   
    float yoff = 0.0;  
    for (int y = 0; y < height; y++) {
      yoff += increment;
      float bright = noise(xoff,yoff,zoff)*255;
      pixels[x+y*width] = color(bright*0.5,bright,bright*0.1);
    }
  }
  updatePixels();
  zoff += zincrement; 
}

在这里插入图片描述

第一章 向量

一个简化的"飞碟",让它渐渐地驶向鼠标。(距离越近,渐进越慢)具有影子拖移效果

float x,
      x0=0.0,
      x1=0.0,
      x2=0.0,
      x3=0.0,
      x4=0.0,
      x5=0.0,
      x6=0.0,
      y,
      y0=0.0,
      y1=0.0,
      y2=0.0,
      y3=0.0,
      y4=0.0,
      y5=0.0,
      y6=0.0;
 
void positonsSet()
{
    y6=y5;
    y5=y4;
    y4=y3;
    y3=y2;
    y2=y1;
    y1=y;    
    x6=x5;
    x5=x4;
    x4=x3;
    x3=x2;
    x2=x1;
    x1=x;
}
 

float easing;
 
float diameterWidth = 32.0,
    diameterHeight = 4.0;
 
void draw_a_UFO(float x, float y, int c)
{
   fill(c);
   ellipse(x,y,diameterWidth / 2,diameterHeight * 2.5);
   ellipse(x,y,diameterWidth,diameterHeight); 
} 
 
int colorSet = 250;
int myColor;   
void colorChange()
{
    myColor -= 33;
    fill(myColor);
}
 
void setup()
{
    frameRate(10);
    size(720,404);
    smooth();
    x = 0.5 * width;
    y = 0.5 * height;
    easing = 0.2;
}
 
void draw()
{
    background(20);
    float targetX = mouseX,
          targetY = mouseY;
    x += (targetX - x) * easing;
    y += (targetY - y) * easing;
    noStroke();
    positonsSet();
    myColor = colorSet;
    draw_a_UFO(x0,y0,myColor);
    colorChange();
    draw_a_UFO(x1,y1,myColor);
    colorChange();
    draw_a_UFO(x2,y2,myColor);
    colorChange();
    draw_a_UFO(x3,y3,myColor);
    colorChange();
    draw_a_UFO(x4,y4,myColor);
    colorChange();
    draw_a_UFO(x5,y5,myColor);
    colorChange();
    draw_a_UFO(x6,y6,myColor);
    colorChange();
    println(frameCount);
}

在这里插入图片描述

第二章 力

2.7 摩檫力

摩檫力是一种耗散力.耗散力的定义是:在运动中使系统总能量减少的力.比如说,开车时,脚踩刹车板会让车通过摩檫力使轮胎减速,在这个过程中,动能被转化为热能.只要两个物体的表面相互接触,它们之间就有摩檫力.摩檫力可分为静摩檫力(物体相对表面静止不动)和动摩檫力(物体在表面上运动)


Mover[] movers = new Mover[20];

void setup() {
  size(1000,500);
  randomSeed(1);
  for(int i = 0; i < movers.length;i++) {
    movers[i] = new Mover(random(1,4),0,0); 
  }
}

void draw() {
  background(255);
  for(int i = 0; i < movers.length;i++) {
    PVector wind = new PVector(0.01,0);
    PVector gravity = new PVector(0,0.1 * movers[i].mass);
    float c = 0.05;
    float normal = 1;
    PVector friction = movers[i].velocity.get();
    friction.mult(-1);  
    friction.normalize();    
    friction.mult(c);  
    friction.mult(normal);  
    if(movers[i].location.x > width / 2) {
      movers[i].applyForce(friction);  
    }
    
    movers[i].applyForce(wind);
    movers[i].applyForce(gravity);
    movers[i].update();
    movers[i].display();
    movers[i].checkEdges();
  }
}

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);
      
      println(mag());
    }
  }
}

class Mover {
  PVector location;
  PVector velocity;
  PVector acceleration;
  float mass;
  color c;
  
  Mover(float m,float x,float y) {
    location = new PVector(x,y);
    velocity = new PVector(0,0);
    acceleration = new PVector(0,0);
    mass = m;
    c = color(random(255),random(255),random(25));
  }
  
  void applyForce(PVector force) {
    PVector newVector = force.get();
    newVector.div(mass);
    acceleration.add(newVector);
  }
  
  void update() {
    velocity.add(acceleration);
    location.add(velocity);
    acceleration.mult(0);
  }
  
  void display() {
    stroke(0);
    strokeWeight(2);
    fill(c);
    fill(random(255),random(255),random(255));
    ellipse(location.x,location.y,mass * 16,mass * 16);
  }
  
  void checkEdges() {
    if(location.x > width) {
      location.x = width;
      velocity.x *= -1;
    } else if(location.x < 0) {
      velocity.x *= -1;
      location.x = 0;
    }
    
    if(location.y > height) {
      velocity.y *= -1;
      location.y = height;
    }
  }
}

在这里插入图片描述
液滴的大小会影响其所受阻力的大小,而在不同的介质中,液滴所受到的阻力也不同,所以他的下降速度也就不同。轻的液滴重量轻,碰到液面后会反弹,重点的液滴直接落入液体中,但受到阻力大本身重力也大,故向下的力大,液体中下降快。这里设置一条空气与蜂蜜的分界线,越过分界线后,下降所受的阻力加大,速度变慢。运用到物理上浮力的公式:F浮=ρ液gV排以及阻力公式f=k*v²

Mover[] movers = new Mover[10];
 
Liquid liquid;
 
void setup() {
  size(800, 500);
  reset();
  liquid = new Liquid(0, height/2, width, height/2, 0.3);
}
 
void draw() {
  background(255);
  liquid.display();
 
  for (int i = 0; i < movers.length; i++) {

    if (liquid.contains(movers[i])) {
      PVector drag = liquid.drag(movers[i]);
      movers[i].applyForce(drag);
    }
 
    PVector gravity = new PVector(0, 0.1*movers[i].mass);
    movers[i].applyForce(gravity);
    movers[i].update();
    movers[i].display();
    movers[i].checkEdges();
  }
   
  fill(0, 120);
 
}
 
void mousePressed() {
  reset();
}
 
void reset() {
  for (int i = 0; i < movers.length; i++) {
    movers[i] = new Mover(random(0.05, 3), 30+i*60, 0);
  }
}
  
 // Liquid class
 class Liquid {
   
  // Liquid is a rectangle
  float x,y,w,h;
  // Coefficient of drag
  float c;
 
  Liquid(float x_, float y_, float w_, float h_, float c_) {
    x = x_;
    y = y_;
    w = w_;
    h = h_;
    c = c_;
  }
   
  // Is the Mover in the Liquid?
  boolean contains(Mover m) {
    PVector l = m.location;
    if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) {
      return true;
    } else {
      return false;
    }
  }
   
  // Calculate drag force
  PVector drag(Mover m) {
    // Magnitude is coefficient * speed squared
    float speed = m.velocity.mag();
    float dragMagnitude = c * speed * speed;
 
    PVector drag = m.velocity.get();
    drag.mult(-1);
     
    drag.setMag(dragMagnitude);
    return drag;
  }
   
  void display() {
    noStroke();
    fill(255,185,15);
    rect(x,y,w,h);
  }
 
}
 
class Mover {
 
  // location, velocity, and acceleration
  PVector location;
  PVector velocity;
  PVector acceleration;
   
  // Mass is tied to size
  float mass;
 
  Mover(float m, float x, float y) {
    mass = m;
    location = new PVector(x, y);
    velocity = new PVector(0, 0);
    acceleration = new PVector(0, 0);
  }
 
  // Newton's 2nd law: F = M * A
  // or A = F / M
  void applyForce(PVector force) {
    // Divide by mass
    PVector f = PVector.div(force, mass);
    // Accumulate all forces in acceleration
    acceleration.add(f);
  }
 
  void update() {
     
    // Velocity changes according to acceleration
    velocity.add(acceleration);
    // Location changes by velocity
    location.add(velocity);
    // We must clear acceleration each frame
    acceleration.mult(0);
  }
   
  // Draw Mover
  void display() {
    noStroke();
    fill(0,1, 255, 30);
    ellipse(location.x, location.y, mass*16, mass*16);
  }

  void checkEdges() {
    if (location.y > height) {
      velocity.y *= -1;  // A little dampening when hitting the bottom
      location.y = height;
    }
  }
}

在这里插入图片描述
当 mouseX > pmouseX 时,即向右运动时,设定腿部相对于身体的旋转角度为PI/4
当mouseX < pmouseX 时,即向左运动时,设定腿部相对于身体的旋转角度为-PI/4
当mouseX = pmouseX 时,即不动时,设定腿部相对于身体的旋转角度为0为避免太灵敏,可以设定一个范围(如-5~5):
当mouseX - pmouseX > 5时,设定角度为PI/4
当mouseX - pmouseX < -5时,设定角度为-PI/4
当-5 <= mouseX - pmouseX <= 5时,设定角度为0
大白会随着鼠标的移动而移动,腿会随着身体而摆动。


void setup(){
  size(600,400);
}
void draw(){
  colorMode(HSB,360,100,100);
  background(0,40,100);
  float w = 120;
  float l = w/3*5;
  DaBai db = new DaBai(w,l);
  db.leftArm.a=atan2(mouseY,mouseX);
  db.rightArm.a=PI-atan2(mouseY,width-mouseX);
  if((mouseX-pmouseX)>5){
    db.leftLeg.a=PI/4;db.rightLeg.a=PI/4;
  }else if((mouseX-pmouseX)<-5){
    db.leftLeg.a=-PI/4;db.rightLeg.a=-PI/4;
  }else{
    db.leftLeg.a=0;db.rightLeg.a=0;
  }

  stroke(30,75,75);strokeWeight(2);
  line(0,0,mouseX-db.body.w-db.leftArm.l*cos(db.leftArm.a),mouseY-db.body.l/2-db.leftArm.l*sin(db.leftArm.a));
  line(width,0,mouseX+db.body.w-db.rightArm.l*cos(db.rightArm.a),mouseY-db.body.l/2-db.rightArm.l*sin(db.rightArm.a));
  
  pushMatrix();
  translate(mouseX,mouseY);
  db.display();
  popMatrix();
}

class DaBai{
  float w,l;
  Head head;
  Body body;
  Arm leftArm;
  Arm rightArm;
  Leg leftLeg;
  Leg rightLeg;
  DaBai(float w,float l){
    this.w=w;this.l=l;
    head = new Head(w/3.5);
    body = new Body(l/3);
    leftArm = new Arm(l/5,0);
    rightArm = new Arm(l/5,0);
    leftLeg = new Leg(l/6,0);
    rightLeg = new Leg(l/6,0);
  }
  void display(){
    ellipseMode(RADIUS);
    // left arm
    pushMatrix();
    translate(-body.w,-body.l/2);
    rotate(leftArm.a);
    leftArm.display();
    popMatrix();
    // right arm
    pushMatrix();
    translate(body.w,-body.l/2);
    rotate(rightArm.a);
    rightArm.display();
    popMatrix();
    // left leg
    pushMatrix();
    translate(-body.w/3,body.l/1.25);
    rotate(leftLeg.a);
    leftLeg.display();
    popMatrix();
    // right leg
    pushMatrix();
    translate(body.w/3,body.l/1.25);
    rotate(rightLeg.a);
    rightLeg.display();
    popMatrix();
    // body
    body.display();
    // head
    pushMatrix();
    translate(0,-body.l);
    head.display();
    popMatrix();
  } 
}
class Head{
  float w,l;
  Head(float w){
    this.w=w;l=w*2/3;
  }
  void display(){
    ellipseMode(RADIUS);
    fill(0,0,100);stroke(0,0,0);strokeWeight(2);
    ellipse(0,0,w,l);
    fill(0,0,0);stroke(0,0,0);
    ellipse(-w/5*2,-l/10,l/10,l/10);
    ellipse(w/5*2,-l/10,l/10,l/10);
    noFill();stroke(0,0,0);strokeWeight(2);
    bezier(-w/5*2,-l/10,0,l/20,0,l/20,w/5*2,-l/10);
    fill(20,80,80);stroke(20,80,80);strokeWeight(2);
    ellipse(-w/5*3,l/5,l/10,l/15);
    ellipse(w/5*3,l/5,l/10,l/15);
  } 
}
class Body{
  float w,l;
  Body(float l){
    this.l=l;w=l*1/1.2;
  }
  void display(){
    ellipseMode(RADIUS);
    fill(0,0,100);stroke(0,0,0);strokeWeight(2);
    ellipse(0,0,w,l);
    fill(30,10,100);stroke(0,10,60);strokeWeight(1);

    ellipse(w/5*2,-l/5*2,w/8,w/8);
    beginShape();
    vertex(w/5*2-w/8,-l/5*2);
    vertex(w/5*2-w/16,-l/5*2);
    vertex(w/5*2-w/16,-l/5*2-w/16);
    vertex(w/5*2+w/16,-l/5*2-w/16);
    vertex(w/5*2+w/16,-l/5*2);
    vertex(w/5*2+w/8,-l/5*2);
    endShape();
  }
}
class Arm{
  float w,l;
  float a;
  Arm(float w,float a){
    this.w=w;l=w*1/3;this.a=a;
  }
  void display(){
    ellipseMode(RADIUS);
    fill(0,0,100);stroke(0,0,0);strokeWeight(2);
    ellipse(0,0,w,l);
  } 
}
class Leg{
  float w,l;
  float a;
  Leg(float l,float a){
    this.l=l;w=l*1/2;this.a=a;
  }
  void display(){
    ellipseMode(RADIUS);
    fill(0,0,100);stroke(0,0,0);strokeWeight(2);
    ellipse(0,0,w,l);
  } 
}

在这里插入图片描述

第三章 震荡

带有角速度的振荡

一个以弧度为单位的圆(一个圆周为2π,即:360度=2π),在单位时间内所走的弧度即为角速度.公式为:ω=Ч/t(Ч为所走过弧度,t为时间)ω的单位为:弧度每秒

Oscillator[] oscillators = new Oscillator[200];

void setup() {
  size(800,500);
  background(255);
  for(int i = 0; i < oscillators.length; i++) {
    oscillators[i] = new Oscillator(); 
  }  
}

void draw() {
  background(255);
  for(int i = 0; i < oscillators.length; i++) {
    oscillators[i].oscillate();
    oscillators[i].display();
  }
}

class Oscillator {
  PVector angle;
  PVector velocity;
  PVector amplitude;
  color c;
  Oscillator() {
    angle = new PVector();
    velocity = new PVector(random(-0.05,0.05),random(-0.05,0.05));
    amplitude = new PVector(random(width / 2),random(height / 2));
    
    c = color(random(55),random(255),random(255));
  }
  
  void oscillate() {
    angle.add(velocity); 
  }
  
  void display() {
    float x = sin(angle.x) * amplitude.x;
    float y = sin(angle.y) * amplitude.y;
    
    pushMatrix();
    translate(width / 2,height / 2);
    stroke(0);
    fill(c);
    line(0,0,x,y);
    ellipse(x,y,16,16);
    popMatrix();
  }
}

class PVector {
  float x;
  float y;
  
  PVector() {
    x = 0;
    y = 0;
  }
  
  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); 
  }
}

在这里插入图片描述

第四章 粒子系统

ParticleSystem ps;
PShape s;
float angle=0;
float aVelocity=0;
float aAcceleration=0.001;

void setup() {
  size(300, 800);
  ps = new ParticleSystem(new PVector(width/2, height-50));
}

void draw() {
  background(255);
  ps.addParticle();
  ps.run();
}

void mousePressed(){
  ps=(new ParticleSystem(new PVector(mouseX,mouseY)));
}

class Particle {
  PVector location;
  PVector velocity;
  PVector acceleration;
  float lifespan;
  Particle(PVector l) {
    acceleration = new PVector(0, 0.05);
    velocity = new PVector(random(-1, 1), random(-14, -1));
    location = l.copy();
    lifespan = 255.0;
  }

  void run() {
    update();
    display();
  }

  void update() {
    velocity.add(acceleration);
    location.add(velocity);
  }

  boolean isDead() {

    if (lifespan <= 0) {
      return true;
    } else {
      return false;
    }
  }

  void display() {

    stroke(0, lifespan);
    strokeWeight(1);
    float r = random(0,255);
    float g = random(0,255);
    float b = random(0,255);
    fill(r,g,b, lifespan);
    rectMode(CENTER);
    pushMatrix();
    rotate(angle);
    float k=random(1,10);
    
    line(location.x-k,location.y,location.x+k,location.y);
    ellipse(location.x+k,location.y,8,8);
    ellipse(location.x-k,location.y,8,8);   
    line(location.x,location.y-k,location.x,location.y+k);
    ellipse(location.x,location.y+k,8,8);
    ellipse(location.x,location.y-k,8,8);
    s=createShape();
  s.beginShape();
  s.vertex(location.x+50/2,location.y+18/2);
  s.vertex(location.x+61/2,location.y+37/2);
  s.vertex(location.x+83/2,location.y+43/2);
  s.vertex(location.x+69/2,location.y+60/2);
  s.vertex(location.x+71/2,location.y+82/2);
  s.vertex(location.x+50/2,location.y+73/2);
  s.vertex(location.x+29/2,location.y+82/2);
  s.vertex(location.x+31/2,location.y+60/2);
  s.vertex(location.x+17/2,location.y+43/2);
  s.vertex(location.x+39/2,location.y+37/2);
  s.endShape();
    shape(s);
    popMatrix();

  }
}
class ParticleSystem {

  ArrayList<Particle> particles;
  PVector origin;

  ParticleSystem(PVector position) {
    origin = position.copy();
    particles = new ArrayList<Particle>();
  }

  void addParticle() {
    particles.add(new Particle(origin));
  }

  void run() {
    for (int i = particles.size()-1; i >= 0; i--) {
      Particle p = particles.get(i);
      p.run();
      if (p.isDead()) {
        particles.remove(i);
      }
    }
  }
}

在这里插入图片描述
参考到一个知乎博主的代码
利用公式:
x = r * sin(a) * cos(b)
y = r * cos(a) * cos(b)
z = r * sin(b)
设置粒子数:100
设置粒子的大小:8
背景使用P3D,使得可以旋转

int num = 100; 
ArrayList<Particle> particles;
PVector Rotate;
Particle tempP;
void setup(){
  size(1080,680,P3D); 
  colorMode(HSB);
  Rotate = new PVector();
  particles = new ArrayList<Particle>();
  for(int i = 0; i < num; i++){
    particles.add( new Particle() );
  }
  background(255);
}

void draw(){

  noStroke();
  fill(255, 18);
  rect(0,0,width,height);  
  

  Rotate = new PVector(frameCount*0.003, frameCount*0.04, frameCount*0.03);
  pushMatrix();
  translate(width/2, height/2);
  rotateX(Rotate.x);
  rotateY(Rotate.y);
  rotateZ(Rotate.z);

  for(int i = particles.size()-1; i >= 0; i--){
    tempP = particles.get(i);
    tempP.move();
  }
  popMatrix();
}




class Particle{
  PVector pos,radian;
  float dis,h,s,b;
  float _weight = 8;
  Particle(){
    radian = new PVector(random(TWO_PI), random(TWO_PI));  
    pos = new PVector();
    dis = 160;
  }
  
  void move(){
    update();
    display();
  }
  
  void update(){
    pos.x = dis*sin(radian.x)*cos(radian.y);
    pos.y = dis*cos(radian.x)*cos(radian.y);
    pos.z = dis*sin(radian.y);
  }
  
  void display(){
    h = noise(radian.x*0.3, frameCount*0.012)*95 + 130 + map(mouseX, 0 ,width, -20, 20);
    noStroke();
    fill(h,85,55);
    translate(pos.x,pos.y,pos.z);
    sphere(_weight);
    translate(-pos.x,-pos.y,-pos.z);
  }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值