Существует много информации о 2D системе частиц и ее взаимодействии с мышью, но я не смог найти надежных инструкций для 3D.
На самом деле, есть две проблемы.Первый - перенести положение экрана мыши (x, y) в мировые координаты (x, y, z)
, а второй - написать еще одну функцию repel3D с обновлением X, Y, Z, используя двауглы фи и тета.Эти углы могут быть рассчитаны с помощью функции PeasyCam.getRotations ().
В принципе, мне нужно подобное поведение в 3D.
https://youtu.be/vIxX23ozQ7c
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(); } }
}