主题
创作一组编程习作,体现随机行为及牛顿运动学
要求
- 编程语言与工具:编程工具不限;
- 作品:参考《代码本色》的第0~4章内容及其实例程序(自行在processing内下载),针对这5章分别编写1个习作(一共5个),每个习作都有不少于2个案例参考,且必须有一定的拓展;
- 报告:写一篇文章(也可以多篇文章,但最好有一个总的导航文章),发表为博文/推文等形式,描述运用的规律,若用到了数学/物理/化学等学科中的知识,要用平实易懂的语言介绍原理,尝试运用凝练的数学语言表达(公式、方程、推导等),特别要描述出这些原理如何在作品中呈现的。
评价
- 技术性:技术难度
- 综合性:通过编程融汇其他学科知识、方法
- 拓展性:对原作的变化与组合
- 表现性:艺术表现水平
- 展示质量:报告+视频+演示程序的直观呈现水平
代码本色
随机游走
float time = 0;
void setup() {
size(400, 400);
}
void draw() {
background(0);
float x = 0;
fill(255);
ellipse(random(width),random(height),1,1);
while (x < width) {
stroke(135,206,250);
line(x, 200 + 50 * noise(x / 100, time), x, height);
x = x + 1;
}
time = time + 0.02;
}
用随机函数random()模拟了夜空中星星闪烁
用柏林噪声函数noise()模拟了海面波浪起伏的效果
向量
主程序
Mover[] movers = new Mover[20];
void setup(){
size(600,600);
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].checkEdges();
movers[i].display();
}
}
Mover 类
class Mover{
PVector location;
PVector velocity;
PVector acceleration;
float topspeed;
Mover(){
location = new PVector(random(width), 0);
velocity = new PVector(1,1);
acceleration = new PVector(-0.001,0.001);
topspeed = 5;
}
void update(){
PVector mouse = new PVector(mouseX, mouseY);
PVector dir = PVector.sub(mouse, location);
dir.normalize();
dir.mult(1);
acceleration = dir;
velocity.add(acceleration);
velocity.limit(topspeed);
location.add(velocity);
if(keyPressed)
{
if(key=='w')
{
acceleration = new PVector(0,-0.001);
acceleration.normalize();
acceleration.mult(0.4);
velocity.add(acceleration);
location.add(velocity);
}
velocity.limit(topspeed);
}
}
void display(){
stroke(0);
noFill();
float w=5;
stroke(135,206,250);
strokeWeight(w);
ellipse(location.x,location.y,32,32);
stroke(255);
strokeWeight(1);
ellipse(location.x,location.y,32-w,32-w);
ellipse(location.x,location.y,32+w,32+w);
}
void checkEdges(){
if (location.x > width) {
location.x = 0;
}
else if (location.x < 0) {
location.x = width;
}
if (location.y > height) {
location.y = 0;
}
else if (location.y < 0) {
location.y = height;
}
}
}
会跟随鼠标位置进行移动,按W键,会给予圆环一个向上的加速度
力
主程序
Mover[] movers = new Mover[20];
Attractor a;
float g = 1;
Liquid liquid;
void setup() {
size(640,360);
a = new Attractor();
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover(random(4,12),random(width),random(height));
}
liquid = new Liquid(0, height/2, width, height/2, 1);
}
void draw() {
background(255);
liquid.display();
a.display();
a.drag();
a.rollover(mouseX, mouseY);
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();
}
for (int i = 0; i < movers.length; i++) {
if (liquid.contains(movers[i])) {
PVector dragForce = liquid.drag(movers[i]);
movers[i].applyForce(dragForce);
}
}
}
void mousePressed() {
a.clicked(mouseX, mouseY);
}
void mouseReleased() {
a.stopDragging();
}
Accractor类
class Attractor {
float mass;
float radius;
PVector position;
boolean dragging = false;
boolean rollover = false;
PVector drag;
Attractor() {
position = new PVector(width/2,height/2);
mass = 10;
radius = mass * 3;
drag = 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);
force.mult(strength);
return force;
}
void display() {
ellipseMode(CENTER);
stroke(0);
if (dragging) fill (50);
else if (rollover) fill(100);
else fill(0);
ellipse(position.x,position.y,radius*2,radius*2);
}
void clicked(int mx, int my) {
float d = dist(mx,my,position.x,position.y);
if (d < radius) {
dragging = true;
drag.x = position.x-mx;
drag.y = position.y-my;
}
}
void rollover(int mx, int my) {
float d = dist(mx,my,position.x,position.y);
if (d < radius) {
rollover = true;
}
else {
rollover = false;
}
}
void stopDragging() {
dragging = false;
}
void drag() {
if (dragging) {
position.x = mouseX + drag.x;
position.y = mouseY + drag.y;
}
}
}
Mover类
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);
float distance = force.mag();
distance = constrain(distance,1.0,10000.0);
force.normalize();
float strength = (g * mass * m.mass) / (distance * distance);
force.mult(-1*strength);
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;
}
}
}
liquad类
class Liquid {
float x,y,w,h;
float c;
Liquid(float x_, float y_, float w_, float h_, float c_) {
x = x_;
y = y_;
w = w_;
h = h_;
c = c_;
}
boolean contains(Mover m) {
PVector l = m.position;
if (l.x > x && l.x < x + w && l.y > y && l.y < y + h) {
return true;
}
else {
return false;
}
}
PVector drag(Mover m) {
float speed = m.velocity.mag();
float dragMagnitude = c * speed * speed;
PVector dragForce = m.velocity.get();
dragForce.mult(-1);
dragForce.normalize();
dragForce.mult(dragMagnitude);
return dragForce;
}
void display() {
noStroke();
fill(0, 69, 107);
rect(x,y,w,h);
}
}
实现了小球受到黑球的引力以及下半部分水的流体阻力
震荡
int _frameRate = 60;
int sampling = 100;
float amplitude = 100;
float cycle = 1;
float wavelength = 200;
float offset_time;
float offset_time_velocity = TWO_PI/_frameRate/cycle;
float offset_time_eachPoint;
float point_position_y;
ArrayList<Wave> waves;
Point tempP;
Wave tempW;
void setup() {
size(400,400);
frameRate(_frameRate);
offset_time_eachPoint = TWO_PI / (wavelength/width * sampling);
waves = new ArrayList<Wave>();
for (int i = 0; i < 3; i ++) {
Wave w = new Wave(i);
waves.add(w);
}
}
void draw() {
background(51);
offset_time += offset_time_velocity;
stroke(255);
for (int i = waves.size() - 1; i >= 0; i --) {
tempW = waves.get(i);
tempW.change();
}
}
class Wave{
int index_wave;
ArrayList<Point> points;
Wave(int _i){
index_wave = _i;
points = new ArrayList<Point>();
for (int i = 0; i < sampling; i ++) {
Point p = new Point(i, index_wave);
points.add(p);
}
}
void change() {
for (int i = points.size() - 1; i >= 0; i--) {
tempP = points.get(i);
tempP.move();
tempP.display();
}
}
}
class Point{
PVector pos;
int index_point;
int index_wave;
float offset_time_currentPoint;
float shrink;
float offset_eachWave = PI;
Point(int _i, int _i_w) {
index_point = _i;
index_wave = _i_w;
pos = new PVector();
offset_time_currentPoint = index_point * offset_time_eachPoint + index_wave*offset_eachWave;
pos.x = (index_point+0.5)/sampling*width;
shrink = pow( sin(pos.x/width * PI), 2);
}
void move() {
pos.y = shrink * amplitude * sin(offset_time + offset_time_currentPoint) + height/2;
}
void display() {
point(pos.x, pos.y);
}
}
粒子系统
主程序
ParticleSystem ps;
void setup() {
size(600, 400);
ps = new ParticleSystem(new PVector(width/2, 50));
}
void draw() {
background(255);
ps.addParticle();
ps.run();
}
Particle类
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(-2, 0));
location = l.copy();
lifespan = 255.0;
}
void run() {
update();
display();
}
void update() {
velocity.add(acceleration);
location.add(velocity);
lifespan-=1.0;
}
boolean isDead() {
if (lifespan <= 0) {
return true;
} else {
return false;
}
}
void display() {
// border
stroke(0, lifespan);
strokeWeight(1);
fill(random(0,255), random(0,255), random(0,255), lifespan);
ellipse(location.x, location.y, 3, 3);
}
}
ParticleSystem类
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() {![在这里插入图片描述](https://img-blog.csdnimg.cn/20200105113233746.gif)
for (int i = particles.size()-1; i >= 0; i--) {
Particle p = particles.get(i);
p.run();
if (p.isDead()) {
particles.remove(i);
}
}
}
}
实现了一个烟花效果,随时间慢慢消失