最近在做交互,以前用unity+Kinect做粒子交互发现很麻烦,现在研究开始研究Processing。
那么废话少数,接下来我们的思路是:找到深度图的中心点标记出来,将粒子系统跟随这个中心点
这串代码是入口:
import KinectPV2.*;
KinectPV2 kinect2;
float minThresh = 518;
float maxThresh = 1184;
PImage img;
int offset;
int d;
ParticleSystem ps;
void setup() {
size(512, 414, P3D);
kinect2 = new KinectPV2(this);
kinect2.enableDepthImg(true);
ps = new ParticleSystem();
img = createImage(kinect2.getDepthImage().width, kinect2.getDepthImage().height, RGB);
println(img.width, img.height);
kinect2.init();
}
void draw() {
background(255);
img.loadPixels();
//minThresh = map(mouseX,0,width,0,4500);
//maxThresh = map(mouseY,0,height,0,4500);
//println(minThresh, maxThresh);
int[] depth = kinect2.getRawDepthData();
float sumX = 0;
float sumY = 0;
float totalPixels = 0;
// image(img,0,0);
for (int x = 0; x < img.width; x++) {
for (int y = 0; y < img.height; y ++) {
offset = x + y*img.width;
d = depth[offset];
if (d> minThresh && d< maxThresh) {
img.pixels[offset] = color(255, 0, 150);
//ps.addParticle(new PVector(x, y));
//ps.run();
sumX += x;
sumY += y;
totalPixels ++;
} else {
img.pixels[offset] = color(0);
}
}
}
img.updatePixels();
image(img, 0, 0);
float avgX = sumX /totalPixels;
float avgY = sumY / totalPixels;
fill(150, 0, 255);
ellipse(avgX, avgY, 64, 64);
// 3==> the speed
for (int i = 0; i<5; i++) {
ps.addParticle(new PVector(avgX,avgY));
ps.run();
}
// ps.addParticle(mouseX,mouseY);
//ps.run();
fill(255);
textSize(32);
stroke(255);
text("offset: " + offset+ " d: " + d, 50, 50);
}
processing的粒子系统都是自己写的,不过大多数代码都是不变的。接下来是粒子类用来被继承或者扩展的
Particle类:
class Particle {
PVector location;
PVector velocity;
PVector acceleration;
float lifespan;
Particle(PVector l) {
// The acceleration
//一个向下的加速度,模拟重力
acceleration = new PVector(0, 0.01);
// circel's x and y ==> range
//返回一个任意方向,大小为的速度
velocity = new PVector(random(-1, 1), random(-2, 0));
// apawn's position
location = l.copy();
// the circle life time
lifespan = 255.0;
}
void run() {
update();
display();
}
void update() {
velocity.add(acceleration);
location.add(velocity);
lifespan-=4.0;
}
boolean isDead() {
if (lifespan <= 0) {
return true;
} else {
return false;
}
}
void display() {
// border
stroke(0, lifespan);
// border's weight
strokeWeight(1);
float r = random(0,255);
float g = random(0,255);
float b = random(0,255);
// random the circle's color
fill(r,g,b, lifespan);
// draw circle
ellipse(location.x, location.y, 3, 3);
}
}
接下来是用来管理粒子的代码
ParticleSystem管理类:
class ParticleSystem {
ArrayList<Particle> particles;
PVector origin;
ParticleSystem() {
particles = new ArrayList<Particle>();
}
void addParticle(PVector position) {
origin = position.copy();
particles.add(new Particle(origin));
}
void run() {
for (int i = particles.size()-1; i >= 0; i--) {
Particle p = particles.get(i);
p.run();
//删除生命走到尽头的粒子
if (p.isDead()) {
particles.remove(i);
}
}
}
}
效果就不说了,代码一定要分析,举一反三,才不会累!