互动媒体技术课程作业3 《代码本色》编程练习
互动媒体技术课程作业3 《代码本色》编程练习
(processing语言)
1.Ch_0 _RandomWalk
实现米老鼠图形随机平滑移动,位置坐标用map函数生成
代码如下
class Walker { PVector position; PVector noff; Walker() { position = new PVector(width/2,height/2); noff = new PVector(random(1000),random(1000)); } void display() { strokeWeight(0); //face fill(0); stroke(0); ellipse(position.x, position.y, 90, 90); ellipse(position.x-40,position.y-40,60,60); ellipse(position.x+40,position.y-40,60,60); fill(255); stroke(255); ellipse(position.x-10,position.y+7,40,55); ellipse(position.x+10,position.y+7,40,55); ellipse(position.x,position.y+18,60,50); fill(0); stroke(0); ellipse(position.x-17,position.y+5,12,25); ellipse(position.x+17,position.y+5,12,25); ellipse(position.x,position.y+25,20,12); fill(226, 54, 39); stroke(226, 54, 39); ellipse(position.x-20,position.y+25,12,10); ellipse(position.x+20,position.y+25,12,10); //word hi fill(0); strokeWeight(10); stroke(0); line(position.x+100,position.y-100,position.x+100,position.y-60); line(position.x+130,position.y-100,position.x+130,position.y-60); line(position.x+100,position.y-80,position.x+130,position.y-80); line(position.x+160,position.y-75,position.x+160,position.y-60); fill(226, 54, 39); stroke(226, 54, 39); ellipse(position.x+160,position.y-100,10,8); } // Randomly move up, down, left, right, or stay in one place void walk() { position.x =map(noise(noff.x),0,1,0,width); //map() position.y =map(noise(noff.y),0,1,0,height); noff.add(0.01,0.01,0); } } Walker w; void setup() { size(800, 800); frameRate(60); // Create a walker object w = new Walker(); } void draw() { background(255); // Run the walker object w.walk(); w.display(); }
2.Ch_01 _Vectors
模拟自然生态系统中鱼群觅食场景,鼠标所在位置代表食物,圆圈代表鱼。
原例子中鼠标若一直不动,圆将越来越集中,15个圆趋于同一个;改进部分为将加速度乘以的常数变为用Perlin噪声生成的随机数,使结果更加分散,更加模拟自然。
实现模拟“觅食”现象的关键在于
1.计算由物体指向目标位置(鼠标)的向量;
2.单位化该向量(将向量的大小缩短为1);
3.改变以上单位向量的长度(乘以某个合适的值);
4.将步骤3中得到的向量赋给加速度。
在Update()中实现
代码如下
Mover[] movers = new Mover[15]; float t=0; void setup() { size(640,640); 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(); } t++; } 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(n); acceleration.normalize(); float n =noise(t)/10; acceleration.mult(n); //acceleration.mult(0.2); // Velocity changes according to acceleration velocity.add(acceleration); // Limit the velocity by topspeed 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); } }
3.Ch_02 _Forces
模拟了一个原子内部引力系统,场景为一个可以随机移动的原子核和其周围的电子。
所有电子(Mover对象)都被原子核(Attract对象)吸引,绕其周围运动,但相互之间有排斥作用
1.调整原例中的力的作用效果,使模拟更真实
2.原子核的随机移动
模拟关键:斥力和引力的生成(由物理公式转化为代码)
斥力引力 同属 万有引力
引力示例(斥力只需改变方向,向量乘-1)
PVector attract(Mover m) { // 现在,Mover对象知道如何吸引其他Mover对象 PVector force = PVector.sub(location,m.location); float distance = force.mag(); distance = constrain(distance,5.0,25.0); force.normalize(); float strength = (G mass m.mass) / (distance * distance); force.mult(strength); return force; }
完整代码如下
Mover[] movers = new Mover[100]; Attractor a; float g = 1; void setup() { size(640,640); a =new Attractor(); for(int i = 0; i < movers.length; i++) { movers[i] = new Mover(random(4,12),random(width),random(height)); } } void draw() { background(255); a.display(); for(int i = 0; i < movers.length; i++) { for (int j = 0; j < movers.length; j++) { if (i != j) { PVector force = movers[j].repel(movers[i]); movers[i].applyForce(force); } } PVector force = a.attract(movers[i]); movers[i].applyForce(force); movers[i].update() movers[i].display(); } } class Attractor { float mass; // Mass, tied to size float radius; // Radius of the attractor PVector position; // position PVector noff; Attractor() { position = new PVector(width/2,height/2); noff = new PVector(random(width),random(height)); mass = 10; radius = mass * 3; drag = new PVector(0.0,0.0); } PVector attract(Mover m) PVector force = PVector.sub(position,m.position); // Calculate direction of force float d = force.mag(); // Distance between objects d= constrain(d,1.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) / (d * d); // Calculate gravitional force magnitude force.mult(5*strength); // Get force vector --> magnitude * direction return force; } //Method to display void display() { ellipseMode(CENTER); stroke(0); fill(0); //map() position.x =map(noise(noff.x),0,1,0,width); position.y =map(noise(noff.y),0,1,0,height); noff.add(0.001,0.001,0); ellipse(position.x,position.y,radius*2,radius*2); } } 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); fill(175,200); ellipse(position.x,position.y,mass*2,mass*2); } PVector repel(Mover m) { PVector force = PVector.sub(position,m.position); // Calculate direction of force float distance = force.mag(); // Distance between objects distance = constrain(distance,1.0,100000.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(-0.001*strength); // Get force vector --> magnitude * direction return force; } void checkEdges() { if (position.x > width) { position.x = width; velocity.x *= -1; } else if (position.x < 0) { position.x = 0; velocity.x *= -1; } if (position.y > height) { position.y = height; velocity.y *= -1; } else if (position.y < 0) { position.y = 0; velocity.y *= -1; } } }
4.Ch_03 _Oscillation
模拟可微小形变的鱼(有弹性)寻找食物进阶版
1.优化了一条鱼的弹性,使用三个小球加弹簧的系统,模拟具有弹性的身体和鱼的外形
2.鱼食可以鼠标拖动
关键技术:
1.弹簧的弹力实现,三个小球互相作用(Bob类,Spring类)
2.给其中一个小球(作为鱼头)增加向鱼食运动的引力(Bob类中的 applyForce(PVector force) )
3.实现鼠标拖动鱼食(mousePressed() mouseReleased())
胡克定律
class Spring { ..... .... void update() { // Vector pointing from anchor to bob position PVector force = PVector.sub(a.position, b.position); // What is distance float d = force.mag(); // Stretch is difference between current distance and rest length float stretch = d - len; // Calculate force according to Hooke's Law // F = k * stretch force.normalize(); force.mult(-1 * k * stretch); a.applyForce(force); force.mult(-1); b.applyForce(force); }
完整代码如下
Attractor a; Bob b1; Bob b2; Bob b3; Spring s1;Spring s2; Spring s3; void setup() { size(640, 640); a= new Attractor(new PVector(width/2,height/2),20,0.4); //Create objects at starting position //Note third argument in Spring constructor is "rest length" b1= new Bob(width/2, 100); b2= new Bob(width/2-100, 200); b3= new Bob(width/2+100, 300); s1= new Spring(b1,b2,100); s2= new Spring(b2,b3,80); s3= new Spring(b1,b3,100); } void draw() { background(255); a.rollover(mouseX,mouseY); a.go(); s1.update(); s2.update(); s3.update(); s1.display(); s2.display(); s3.display(); PVector f = a.attract(b1); // Apply that force to the Crawle b1.applyForce(f); b1.update(); b1.display1(); b2.update(); b2.display0(); b3.update(); b3.display0(); } void mousePressed() { a.clicked(mouseX,mouseY); } void mouseReleased() a.stopDragging(); } class Bob { PVector position; PVector velocity; PVector acceleration; float mass = 12; //Arbitrary damping to simulate friction / drag float damping = 0.95; //Constructor Bob(float x, float y) { position = new PVector(x,y); velocity = newPVector(); acceleration =new PVector(); mass = 12; } //Standard Euler integration void update() { velocity.add(acceleration); velocity.mult(damping); position.add(velocity); acceleration.mult(0); } //Newton's law: F = M * A void applyForce(PVector force) { PVector f = force.get(); f.div(mass); acceleration.add(f); } //Draw the bob void display0() { stroke(0); strokeWeight(2); fill(175); if (dragging) { fill(50); } ellipse(position.x,position.y,mass*2,mass*2); } void display1() { stroke(0); strokeWeight(2); fill(0); if (dragging) { fill(50); } ellipse(position.x,position.y,mass*2,mass*2); } } class Spring { //position PVector anchor; //Rest length and spring constant float len; float k = 0.2; Bob a; Bob b; //Constructor Spring(Bob a_, Bob b_, int l) ; a= a_; b= b_; len = l; } //Calculate spring force void update() { // Vector pointing from anchor to bob position PVector force = PVector.sub(a.position, b.position); // What is distance float d = force.mag(); // Stretch is difference between current distance and rest length float stretch = d - len; // Calculate force according to Hooke's Law // F = k * stretch force.normalize(); force.mult(-1 * k * stretch); a.applyForce(force); force.mult(-1); b.applyForce(force); } void display() { strokeWeight(2); stroke(0); line(a.position.x, a.position.y, b.position.x, b.position.y); } } class Attractor { float mass; // Mass, tied to size float G; // Gravitational Constant PVector pos; // position boolean dragging = false; // Is the object being dragged? boolean rollover = false; // Is the mouse over the ellipse? PVector drag; // holds the offset for when object is clicked on Attractor(PVector l_,float m_, float g_) { pos = l_.get(); mass = m_; G= g_; drag = new PVector(0.0,0.0); } void go() { render(); drag(); } PVector attract(Bob c) { PVector dir = PVector.sub(pos,c.position); // Calculate direction of force float d = dir.mag(); // Distance between objects d= constrain(d,5.0,25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects dir.normalize(); // Normalizevector (distance doesn't matter here, we just want this vector for direction) float force = (G * mass * c.mass) / (d * d); // Calculate gravitional force magnitude dir.mult(5*force); // Get forcevector --> magnitude * direction return dir; } //Method to display void render() { ellipseMode(CENTER); stroke(0,100); if (dragging) fill (50); else if (rollover) fill(100); else fill(175,50); ellipse(pos.x,pos.y,mass*3,mass*2); } //The methods below are for mouse interaction void clicked(int mx, int my) { float d = dist(mx,my,pos.x,pos.y); if (d < mass) { dragging = true; drag.x = pos.x-mx; drag.y = pos.y-my; } } void rollover(int mx, int my) { float d = dist(mx,my,pos.x,pos.y); if (d < mass) { rollover = true; } else { rollover = false; } } void stopDragging() { dragging = false; } void drag() { if (dragging) { pos.x = mouseX + drag.x; pos.y = mouseY + drag.y; } } }
5.Ch_04 _System
模拟烟火特效
模拟关键
1.粒子束生成 (多个Repeller(使用ArrayList))。
2.每个粒子之间的斥力(类似第二章)
3.粒子的消亡周期(模拟烟火短暂,且会变色的特性)
完整代码如下
ParticleSystem ps; void setup() { size(640,640); ps= new ParticleSystem(new PVector(width/2,50)); } void draw() { background(255); ps.addParticle(mouseX,mouseY); ps.update(); ps.intersection(); ps.display(); } class Particle { PVector position; PVector velocity; PVector acceleration; float lifespan; float r = 6 ; boolean highlight; Particle(float x, float y) { acceleration = new PVector(0, 0.05); velocity = new PVector(random(-1, 1), random(-2, 0)); position = new PVector(x, y); lifespan = 255.0; } void run() { update(); display(); } void intersects(ArrayList<Particle> particles) { highlight = false; for (Particle other : particles) { if (other != this) { float d = PVector.dist(other.position, position); if (d < r + other.r) highlight = true; } } } } void applyForce(PVector f) { acceleration.add(f); } //Method to update position void update() { velocity.add(acceleration) position.add(velocity) acceleration.mult(0); lifespan -= 1.5; } //Method to display void display() { stroke(0, lifespan) strokeWeight(2); fill(127, lifespan); if (highlight) { fill(163,18,205); } ellipse(position.x, position.y, r*2, r*2); } // Is the particle still useful? boolean isDead() { if (lifespan < 0.0) return true; } else { return false; } } } class ParticleSystem { ArrayList<Particle> particles; ParticleSystem(PVector position) { particles = new ArrayList<Particle>(); } void addParticle(float x, float y) { particles.add(new Particle(x, y)); } void display() { for (Particle p : particles) { p.display(); } } void intersection() { for (Particle p : particles) p.intersects(particles); } } void update() { for (int i = particles.size()-1; i >= 0; i--) { Particle p = particles.get(i); p.update(); if (p.isDead()) { particles.remove(i); } } } }
- 点赞
- 收藏
- 分享
- 文章举报
- 【互动媒体技术】艺工交叉 作业1 实验数据分析 数据分析
- 【互动媒体技术】艺工交叉作业1 实验数据分析 文献综述
- 互动媒体技术作业——十二个“一”扩展版
- 【互动媒体技术】互动编程习作1——表现随机行为及牛顿运动学
- 互动媒体技术作业——十二个"一"
- 互动媒体技术作业
- 十二个“一”与耍猴(互动媒体技术作业)
- 流动墨迹速度感知实验(互动媒体技术作业)
- 多视角交叉认知(互动媒体技术作业)
- 互动媒体技术作业——processing码绘
- 十二个“一”,十二台手机(互动媒体技术作业)
- 【互动媒体习作】创意编程作业——导航
- Coursera-吴恩达-机器学习-(编程练习4)Neural Networks Learning(对应第5周课程)
- linux运维实战练习-2015年9月13日-9月15日课程作业(练习)安排
- 斯坦福大学开放课程——编程方法 作业1-1
- 武汉大学“多核架构及编程技术”精品课程理论教学
- 斯坦福大学开放课程——编程方法 作业6
- linux运维实战练习-2015年9月13日-9月15日课程作业(练习)安排
- 第七周判断与循环编程练习/课堂作业 多项式加法+鞍点《程序设计入门——C语言》第七期 浙江大学 翁恺
- 【互动媒体】结课作业第二部分:数据分析、可视化以及几个额外问题