基于p5实现的“运动”效果
1、引力 attractive force
参考了《代码本色》第二章力的内容,对实验A3实现的大五人格中的神经质性线条进行了引力的拓展。在体现神经质性的线条设计中,主要是通过鼠标移动的速度控制线条的属性,鼠标移动的速度越快,即表示一个人的感情越敏感,情绪越消极,精神更衰弱。如果鼠标移动的速度保持很慢,就说明一个人情绪非常稳定,平衡消极情绪的能力很强。
如何用力的相关内容对其进行拓展呢?
其实也借鉴了我所设计的外倾性线条的特点:通过点与点之间的距离来判断点的“人际互动”密度。初高中我们就学过万有引力的相关知识,两个点也可以看作是两个行星,彼此间的引力对其个体的运动都有影响。
设计Ball的属性如下,包括定义点之间的引力计算:
function Ball(x, y, mass, id)
{
this.x = x;
this.y = y;
this.xVel = 0;
this.yVel = 0;
this.mass = mass;
this.id = id;
this.c=color(random(360),random(100),random(100));
this.attract = function(object)
{
if(this.x < object.x)
{
this.xVel+=G*this.mass*object.mass/pow(dist(this.x,this.y,object.x,object.y),1);
}
else
{
this.xVel-=G*this.mass*object.mass/pow(dist(this.x,this.y,object.x,object.y),1);
}
if(this.y < object.y)
{
this.yVel+=G*this.mass*object.mass/pow(dist(this.x,this.y,object.x,object.y),1);
}
else
{
this.yVel-=G*this.mass*object.mass/pow(dist(this.x,this.y,object.x,object.y),1);
}
this.x += this.xVel;//t=1
this.y += this.yVel;
}
this.draw=function()
{
fill(this.c);
circle(this.x, this.y, this.mass);
}
}
首先设定引力常量g为0.001,数值g的设置对点的运动速度有很大的影响。
随机生成两个“行星”,显示他们的轨迹如下:
由于受到另一个点的引力作用,两个点的运动就变得有意思了。
让我们设置更多的“行星”,对他们的轨迹记录方式进行改变,并修改引力常量g,实现更多的效果如下:
2、钟摆运动 pendulum
参考了《代码本色》钟摆运动的内容,首先实现了最基础的单个时钟的钟摆运动:
Pendulum类设计如下
class Pendulum {
constructor(m, a, id)
{
this.i = id;
this.r1 = s / 4;
this.m1 = m;
this.a1 = PI / 2;
this.a_v = 0;
this.a1_a = 0;
this.x1 = 0;
this.y1 = 0;
}
update() {
this.a1_a = (-g * (2 * this.m1 + this.m2) * sin(this.a1) - this.m2 * g * sin(this.a1 - 2 * this.a2) - 2 * sin(this.a1 - this.a2) * this.m2 * (this.a2_v * this.a2_v * this.r2 + this.a1_v * this.a1_v * this.r1 * cos(this.a1 - this.a2))) / (this.r1 * (2 * this.m1 + this.m2 - this.m2 * cos(2 * this.a1 - 2 * this.a2)));
this.a1_v += this.a1_a;
this.a1 += this.a1_v;
this.x1 = this.r1 * sin(this.a1);
this.y1 = this.r1 * cos(this.a1);
stroke(0);
strokeWeight(1.5);
line(0, 0, this.x1, this.y1);
colorMode(HSB, n);
strokeWeight(1);
fill(this.i, n / 2, n);
circle(this.x1, this.y1, this.m1);
colorMode(RGB);
}
}
双钟摆就是在原钟摆上再挂一个钟摆,两个钟摆受到彼此的影响而摆动。
效果如下,其中大钟摆的质量是小钟摆的两倍:
Pendulum类代码如下:
class Pendulum {
constructor(m, a, i,isSingle)
{
this.i = i;
this.r1 = s / 4;
this.m1 = m;
this.a1 = PI / 2;
this.a1_v = 0;
this.a2_v = 0;
this.a1_a = 0;
this.a2_a = 0;
this.x1 = 0;
this.y1 = 0;
this.x2 = 0;
this.y2 = 0;
if(isSingle==1)
{
this.r2 = this.r1;
this.m2 = 0;
this.a2 = PI / 2 ;
}
else if(isSingle==2)
{
this.r2 = s / 5;
this.m2 =this.m1/2;
this.a2 = PI / 2 * a;
}
}
update() {
this.a1_a = (-g * (2 * this.m1 + this.m2) * sin(this.a1) - this.m2 * g * sin(this.a1 - 2 * this.a2) - 2 * sin(this.a1 - this.a2) * this.m2 * (this.a2_v * this.a2_v * this.r2 + this.a1_v * this.a1_v * this.r1 * cos(this.a1 - this.a2))) / (this.r1 * (2 * this.m1 + this.m2 - this.m2 * cos(2 * this.a1 - 2 * this.a2)));
this.a2_a = (2 * sin(this.a1 - this.a2) * (this.a1_v * this.a1_v * this.r1 * (this.m1 + this.m2) + g * (this.m1 + this.m2) * cos(this.a1) + this.a2_v * this.a2_v * this.r2 * this.m2 * cos(this.a1 - this.a2))) / (this.r2 * (2 * this.m1 + this.m2 - this.m2 * cos(2 * this.a1 - 2 * this.a2)));
this.a1_v += this.a1_a;
this.a2_v += this.a2_a;
this.a1 += this.a1_v;
this.a2 += this.a2_v;
this.x1 = this.r1 * sin(this.a1);
this.y1 = this.r1 * cos(this.a1);
this.x2 = this.x1 + this.r2 * sin(this.a2);
this.y2 = this.y1 + this.r2 * cos(this.a2);
stroke(0);
strokeWeight(1.5);
line(0, 0, this.x1, this.y1);
line(this.x1, this.y1, this.x2, this.y2);
colorMode(HSB,n);
strokeWeight(1);
fill(this.i, n / 2, n);
circle(this.x1, this.y1, this.m1);
circle(this.x2, this.y2, this.m2);
colorMode(RGB);
}
}
结合之前拓展的库中的功能,实现了以下的效果:
小结
《代码本色》中的教程和例子都是用processing写的,关于p5的例子网上能找到的也很有限,想找个语法参考都不容易,实现的时候最大的困难竟然是p5语法…让人头秃。
虽然但是,gif动图只能放5MB以内大小的也是把我难到了,随便一录都是10MB以上。