春水是我们使用kinect与processing结合开发的一个小项目,灵感来源于teamLab的Vortices。
在这个项目中我负责的是跟随鼠标移动而产生的粒子。
我们想要传达的是万物皆因人而具有意义。没有人时,春水只是一池春水,而当有了人的存在,春水开始变绿,开始起了波澜。当人离开,一池春水重又归于寂静。
“你未看此花时,此花与汝心同归于寂。你来看此花时,则此花颜色一时明白起来。”
概述
最初我们想要实现这样的效果,一起争论了很久应该怎么实现。
第一版的想法是每当人走过时,便会产生与人速度方向一致的粒子,而粒子与粒子之间有相互作用力,会相互影响。而规定最新生成的粒子会对已有粒子造成较大影响,因此所有的粒子都会渐渐被带着随人走动的方向运动。
于是,此时我们重点实现的是网格空间分割法。
网格空间分割法
如《代码本色》中第六章中集群中的思想,为了提高效率,我们采用了书中的网格空间分割法。
其思想是每个个体周围一定范围内的个体都会对其产生影响,传统做法是对每一个个体更新时检测每一个个体与当前个体之间的距离,当距离小于一定值时考虑其影响。但是这样带来的问题是随着个体数目的增多,复杂度会指数级增长,效率低下。
因此要采用网络空间分割法。
网络空间分割法将整个空间划分为许多固定大小的小方格,每个小方格中的物体彼此之间会产生影响,而网格与网格之间的物体则不考虑它们的相互作用。
因此要计算临近区域的个体之间的相互作用,只需要在每次更新时遍历所有物体,根据物体此时的位置将之划分到相应网格中。
void updateGrid() {
for(int i = 0; i <= yMax; i++) {
for(int j = 0; j <= xMax; j++) {
grid[i][j].clear();
forceGrid[i][j].set(0, 0);
}
}
PVector gridCount = new PVector(0, 0);
for(Particle p : particles) {
if(!p.isDead()) {
gridCount = PVector.div(p.getPos(), resolution);
grid[max(floor(gridCount.y), 0)][max(floor(gridCount.x), 0)].add(p);
}
}
}