###艺工结合
##根据代码本色其中0至4章的内容来实现下图的动态图形
图形可视化中不仅仅可以可视化艺术文艺作品
同样也可以对其物理定律和数学知识实现,自然显现进行可视化
这就充分体现了艺工结合,将其枯燥的物理定律进行简单的绘制
下图为一些相关图形以及通过processing编辑的物理知识
第0章 随机数
Circle类函数:
(通过noise来替代random()的随机差异,通过规律改变圆心的坐标和半径来达到上图所示的效果)
R=map(noise(a*dr),0,1,dr-distort,dr+distort);
x=width/2+sin(a)*R;
y=height/2+cos(a)*dr;
图中所绘制的圆的中心坐标;
代码实现:
class Circle {
float x;
float y;
float R;
Circle(){
x=0;
y=0;
R=0;
}
void display(){
float max=random(PI*2);
for(float a=random(PI*2);a<max+PI/2;a+=0.01){
R=map(noise(a*dr),0,1,dr-distort,dr+distort);
x=width/2+sin(a)*R;
y=height/2+cos(a)*dr;
ellipse(x,y,1,1);
}
}
}
主函数:
Circle m;
void setup(){
size(600,600);
background(0,0,0);
frameRate(100);
m=new Circle();
}
float dr=10;
float distort=5;
void draw(){
//background(0);
fill(0, 10);
noStroke();
rect(0, 0, width, height);
fill(255, 155);//使其屏幕中的圆出现类似黑洞中间深邃的效果
noFill();
stroke(random(255),random(255),random(255));
if(dr<250){
dr+=01;
m.display();
}else{
distort+=1;
m.display();
}
if(frameCount%200==0){
background(0,0,20);
dr=10;
}
}
主要在其中学习了java全局的面向对象的类的实现
可以将其代码简洁化
其中包括了一些概率模型的实现
第1章 向量
小车模型运动描述:
小车一开始以加速度为0的匀速运动在道路上形式,同时上空掉落一物体,该物体存在重力和风力的共同作用,两个力的加速度,该模型模拟了小车在收到物体撞击时,拥有加速的的过程,即两个物体的动能何为一个物体的动能,过程中忽略热的消耗。
Mover类实现物体的相关参数和运动模型:
通过向量来描绘物体路径的位置,速度加速度,PVector为其存储了两个变量的简单数据结构,各变量运算方法类似于物理上各方向的运算方法(PVector当中的相关向量运算,常见几种如下表所示:)
add() | 向量相加 |
---|---|
sub() | 向量相减 |
mult() | 乘以标量以延伸向量 |
div() | 除以标量以缩短向量 |
mag() | 计算向量的长度 |
setMag() | 设定向量的长度 |
normalize() | 单位化向量,使其长度为1 |
limit() | 限制向量的长度 |
dist() | 计算两个向量的欧几里得距离 |
代码实现:
class Mover{
PVector location1;
PVector location2;
PVector location3;
PVector location4;
PVector velocity1;
PVector velocity2;
PVector acceleration;//rect
PVector acceleration1;
float mass;//rect
Mover(){
location1 = new PVector(30,340);//car wheel
location2 = new PVector(70,340);//car wheel
location3 = new PVector(8,300);//car//小车车体
location4 = new PVector(5,20);//rect//坠落的物体
velocity1 = new PVector(2.5,0);//velocity//匀速运时的速度
velocity2= new PVector(0,0);
acceleration = new PVector(0,0);
acceleration1 = new PVector(-4,0);
mass = 1;
}
void applyForce(PVector force) {
PVector f = PVector.div(force,mass);
acceleration.add(f);
}
void update(){
if(location1.x<300){
location1.add(velocity1);
location2.add(velocity1);
location3.add(velocity1);
}
else
{
velocity1.sub(acceleration1);
location1.add(velocity1);
location2.add(velocity1);
location3.add(velocity1);
acceleration1.mult(0);
}
velocity2.add(acceleration);
if(location4.y<270){
location4.add(velocity2);
acceleration.mult(0);
}
else
{
velocity1.sub(acceleration1);
location4.add(velocity1);
acceleration1.mult(0);
}
}
void checkEdge(){
if(location1.x>width){
location1.x=30;
location2.x=70;
location3.x=8;
}
}
void display(){
stroke(0);
fill(175);
ellipse(location1.x,location1.y,20,20);
ellipse(location2.x,location2.y,20,20);
rect(location3.x,location3.y,75,30);
rect(location4.x,location4.y,30,30);
//line(20,0,20,50);
line(0,350,800,350);
}
}
主函数类:
Mover car;
void setup()
{
size(800,400);
smooth();
car=new Mover();
}
void draw()
{
PVector wind = new PVector(0.05,0);
PVector gravity = new PVector(0,0.05);
car.applyForce(wind);//风力影响
car.applyForce(gravity); //重力影响
background(255);
car.update();
car.checkEdge();
car.display();
}
第2章 力
该模型模拟了各随机产生的小球受到引力的影响,该引力中心点位于屏幕中心,其中Mover类的构造函数中加入了用户自定义的随机位置产生圆,其中小圆的残影效果可以通过每次都重新绘制一边屏幕来实现这个效果: rect(width/2, height/2, width, height);
fill(255, 155);
引力作用情况下:
Mover类:
class Mover
{
PVector acceleration;
PVector velocity;
PVector position;
float mass;
float incr;
float angle;
Mover(PVector p)
{
position = p.get();
acceleration = new PVector();
velocity = new PVector();
mass = random(2, 2);
angle = 0;
incr = random(-0.001, 0.001);
}
void run()
{
update();
display();
}
void update()
{
velocity.add(acceleration);
velocity.limit(4);
position.add(velocity);
acceleration.mult(0);
}
void display()
{
float r = random(255);
float g = random(255);
float b = random(255);
rectMode(CENTER);
fill(r,g,b);
stroke(255);
strokeWeight(0);
angle += incr;
pushMatrix();
translate(position.x, position.y);
rotate(degrees(angle));
ellipse(0, 0, mass*25, mass*25);
popMatrix();
}
void addForce(PVector force)
{
PVector f = PVector.div(force, mass);
acceleration.add(f);
}
PVector attractTo(float x, float y)
{
PVector mousePos = new PVector(x, y);
PVector dir = PVector.sub(mousePos, position);
float dist = dir.mag();
dist = constrain(dist, 15, 25);
dir.normalize();
float f = (30*mass)/(dist*dist);
dir.mult(f);
return dir;
}
``javascript
Mover[] movers;
void setup()
{
size(600,600);
int n = 30;
movers = new Mover[n];
for (int i = 0; i < n; i++)
{
PVector p = new PVector(random(0, width), random(0, height));
movers[i] = new Mover(p);
}
}
void draw()
{
int n = 30;
//background(0);
fill(0, 10);
noStroke();
rect(width/2, height/2, width, height);
fill(255, 155);
for (int i = 0; i < n; i++)
{
movers[i].addForce(movers[i].attractTo(width/2, height/2));
movers[i].run();
}
}
第三章 振荡
通过hour()、second()、minute()等函数来获取当前的时间,并计算出每个时针分针和秒针应该转动的角度,其中时针和分针以及秒针的转动角度不同
其中在时针表的刻度盘为3到12点时,(分为上午和下午)此时30度一个小时的转动速度
(angleHour = radians(30 * (timer.currentHourFloat - 3));)
其他时刻为(angleHour = radians(30 * (timer.currentHourFloat - 1) + 300);)
根据时钟的转动规律可知
其中分针和秒针相同
并通过带有角速度的振荡来实现是正宗的摆锤,其中加速度的计算公式为:aAcceleration=(-1*gravity/r)*sin(angle);
Timer类:
//主要代码
void hourPointer(Timer timer){
pushMatrix();
translate(width/2, 200);
float angleHour = radians(270);
if ((timer.currentHourFloat >= 3 && timer.currentHourFloat <= 12) || (timer.currentHourFloat >= 15 && timer.currentHourFloat <= 24)) {
angleHour = radians(30 * (timer.currentHourFloat - 3));
} else {
angleHour = radians(30 * (timer.currentHourFloat - 1) + 300);
}
if (flag) {
rotate(angleHour);
} else {
rotate(radians(270));
}
stroke(255);
strokeWeight(7);
line(-7, 0, 45, 0);
popMatrix();
}
void minutePointer(Timer timer) {
pushMatrix();
translate(width/2, 200);
float angleMinute = radians(270);
if ((timer.currentMinuteFloat >= 0 && timer.currentMinute <= 15)) {
angleMinute = radians(270 + 6 * timer.currentMinuteFloat);
} else {
angleMinute = radians(6 * (timer.currentMinuteFloat - 15));
}
if (flag) {
rotate(angleMinute);
} else {
rotate(radians(0));
}
stroke(179, 180, 0);
strokeWeight(5);
line(-10, 0, 60, 0);
popMatrix();
}
void secondPointer(Timer timer) {
pushMatrix();
translate(width/2, 200);
float angleSecond = radians(270);
if ((timer.currentSecond >= 0 && timer.currentSecond <= 15)) {
angleSecond = radians(270 + 6 * timer.currentSecond);
} else {
angleSecond = radians(6 * (timer.currentSecond - 15));
}
if (flag) {
rotate(angleSecond);
} else {
rotate(radians(180));
}
stroke(255, 0, 0);
strokeWeight(3);
line(-15, 0, 80, 0);
stroke(255);
popMatrix();
}
}
主函数类:
Timer timer1;
Timer timer2;
Boolean flag = true;
void setup () {
size(500, 800);
timer1=new Timer();
}
void draw () {
int s = second();
int m = minute();
int y = hour();
float mf = minute() + s / 60.0;
float hf = hour() + mf / 60.0;
timer2 = new Timer(s, m, y, mf, hf);
timer2.drawClock();
timer2.hourPointer(timer2);
timer2.minutePointer(timer2);
timer2.secondPointer(timer2);
timer1.go();
}
第四章:粒子系统:
代码与上几个实验代码类似,实现了一个粒子系统,且该粒子实现了重力和摩擦力的作用,并且在碰到墙壁时,对其产生反向作用力的效果,gravity = new PVector(0, 0.01);
force = new PVector(randomGaussian(), randomGaussian());
acceleration = force.mult(mass);
为一开始小球所受到的力的作用,之后加速度受摩擦力和重力的共同作用
代码如下:
Particle类:
class Particle{
PVector velocity, location, acceleration, gravity, force;
float mass, friction;
PVector min, max;
Particle(){
min = new PVector(0, 0);
max = new PVector(width, height);
mass = 5;
friction = 0.01;
velocity = new PVector(0, 0);
location = new PVector(width/2, height/2);
gravity = new PVector(0, 0.01);
force = new PVector(randomGaussian(), randomGaussian());
acceleration = force.mult(mass);
}
void update(){
acceleration.add(gravity);
velocity.add(acceleration);
velocity.mult(1-friction);
location.add(velocity);
acceleration.set(0, 0);
}
void display(){
noStroke();
fill(255, 100);
ellipse(location.x, location.y, 5, 5);
}
void bounceWall(){
if (location.x < min.x){ location.x = min.x; velocity.x *=-1; }
if (location.x > max.x){ location.x = max.x; velocity.x *=-1; }
if (location.y < min.y){ location.y = min.y; velocity.y *=-1; }
if (location.y > max.y){ location.y = max.y; velocity.y *=-1; }
}
}
主函数类:
ArrayList particles = new ArrayList<Particle>();
int num = 100;
void setup(){
size(500, 500);
background(0);
for (int i=0; i<num; i++){
particles.add(new Particle());
}
}
void draw(){
for (int i=0; i<num; i++){
Particle p = (Particle)particles.get(i);
p.update();
p.display();
p.bounceWall();
}
fill(0, 8);
rect(0, 0, width, height);
}