关于2D粒子系统及其与鼠标的相互作用的信息很多,但是我找不到3D的可靠说明。
实际上,有两个问题。第一个是将鼠标屏幕(x,y)的位置转移到世界坐标(x,y,z)
,第二个是使用两个角度phi和theta编写另一个具有X,Y,Z更新的repel3D函数。这些角度可以通过PeasyCam.getRotations()函数来计算。
基本上,我在3D中需要类似的行为。
import peasy.*;
PeasyCam cam;
static int N = 2048;
static float RADIUS = 128.0;
int offset = 64;
float threshold = 64.0;
ParticleSystem ps = new ParticleSystem();
void setup(){
size(512, 512, P3D);
cam = new PeasyCam(this, RADIUS * 2);
cam.setMinimumDistance(32);
cam.setMaximumDistance(999);
for (int i = 0; i < N; i++) {
float n = 1E4;
float rho = sqrt(random(n)) * 1.0;
float theta = random(0, TWO_PI);
float phi = 2.0 * asin(sqrt(random(1.0)));
float x = rho * sin(phi) * cos(theta);
float y = rho * sin(phi) * sin(theta);
float z = rho * cos(phi);
ps.add(new Particle(x, y, z));
}
}
void draw(){
background(220);
strokeWeight(4);
ps.update();
ps.draw();
}
float angleTo(PVector a_, PVector b_){ return atan2(b_.y - a_.y, b_.x - a_.x); }
class Particle extends PVector{
PVector origin;
float repulsion = 0.2;
Particle(float x_, float y_, float z_){
x = x_;
y = y_;
z = z_;
origin = new PVector(x_, y_, z_);
}
void repel2D(PVector start_, PVector from_, float base_, float ex_){
x += ((cos(angleTo(from_, this)) * (pow(base_, ex_) / PVector.dist(from_, this))) + (start_.x - x)) * repulsion;
y += ((sin(angleTo(from_, this)) * (pow(base_, ex_) / PVector.dist(from_, this))) + (start_.y - y)) * repulsion;
}
void draw(){
stroke(0);
strokeWeight(4);
point(x, y, z);
}
}
class ParticleSystem extends ArrayList<Particle>{
void update(){
PVector mouse = new PVector(-width/2 + mouseX, -height/2 + mouseY);
PVector center = new PVector(width/2, height/2);
for(Particle p : this) { p.repel2D(p.origin, mouse, threshold, 2.0); }}
void draw(){ for(Particle p : this) { p.draw(); } }
}