春水是我们使用kinect与processing结合开发的一个小项目,灵感来源于teamLab的Vortices。
在这个项目中我负责的是跟随鼠标移动而产生的粒子。
我们想要传达的是万物皆因人而具有意义。没有人时,春水只是一池春水,而当有了人的存在,春水开始变绿,开始起了波澜。当人离开,一池春水重又归于寂静。
“你未看此花时,此花与汝心同归于寂。你来看此花时,则此花颜色一时明白起来。”
概述
这个粒子系统中的粒子有较长的生命周期,前期跟随鼠标移动,后期受到科里奥利力作用,根据当时的受力情况如洋流一样做旋涡状的圆周运动,同时受到周围粒子的作用力。
前置内容–鼠标轨迹记录
想要实现一个跟随鼠标移动的效果。实际上,之前在《远山》中也实现过跟随鼠标泛起的涟漪,但是那时比较简单,只需要记录最近五次的鼠标位置,每隔几帧更新,重新绘制涟漪,使之扩大并且透明度增高就可以实现。
而在本项目中,由于粒子生命周期较长,而且会随机生成在鼠标轨迹的任意位置,所以原来的简单方法不太适用了。
想着可以使用一个队列,先进先出,实现起来还是非常简单的,但后来发现processing里似乎没有封装Java的队列,ArrayList是少数可用的容器之一,所以就只能手写了两个简单的鼠标轨迹的类来记录鼠标移动的轨迹,实现这个功能。
Mouse类
主要功能是对每个记录的鼠标位置负责。
记录当前鼠标位置,并有80的生命周期,当生命周期结束,就不再记录此位置信息。
class Mouse {
public PVector pos;
public int lifespan;
Mouse(PVector mousePos) {
pos = mousePos;
lifespan = 80;
}
boolean isDead() {
if(lifespan-- <= 0) {
return true;
}
else
return false;
}
public PVector getPos() {
return pos.copy();
}
public int getLifespan() {
return lifespan;
}
MouseTrack类
主要功能为维护鼠标轨迹的ArrayList。
每隔固定帧数添加新的鼠标位置到ArrayList,同时检查list中已有的鼠标位置,生命周期是否结束,若结束则将之从ArrayList中移除。
注意点是每次更新鼠标位置时需要进行检测:
鼠标位置是否在屏幕中:
if(pos.x > 0 && pos.y > 0 && pos.x < width && pos.y < height)
鼠标位置变化的距离:
由于使用Kinect检测人的左右手位置,但人持续站在范围内,但手没有移动时,由于Kinect的精度问题,仍然会有小幅度的位置变化数据,因此当变化的距离小于一定值时,将之视为没有移动,即不记录当前鼠标位置。
if(PVector.sub(pos, prevPos).mag() > 15) {
add(pos);
}
prevPos = pos;
class MouseTrack {
public ArrayList<Mouse> list;
public boolean isRemoved = false;
PVector prevPos = new PVector(0, 0);
int stayCount = 0;
MouseTrack() {
list = new ArrayList<Mouse>();
}
void add(PVector pos) {
if(pos.x > 0 && pos.y > 0 && pos.x < width && pos.y < height) {
Mouse m = new Mouse(pos);
list.add(m);
}
}
void update(PVector pos) {
if(PVector.sub(pos, prevPos).mag() > 15) {
add(pos);
}
prevPos = pos