mirror of
https://github.com/dyne/FreeJ.git
synced 2026-02-11 15:20:48 +01:00
processing-js 0.4 has been merged in some relevant parts basic and topic scripts added for test color handling fixed, more scripts show up now
317 lines
6.5 KiB
Plaintext
317 lines
6.5 KiB
Plaintext
ParticleSystem ps;
|
|
Random generator;
|
|
|
|
void setup() {
|
|
size(200, 200);
|
|
frameRate(30);
|
|
colorMode(RGB, 255, 255, 255, 100);
|
|
generator = new Random();
|
|
|
|
// Create an alpha masked image to be applied as the particle's texture
|
|
PImage msk = loadImage("texture.gif");
|
|
PImage img = createImage(msk.width,msk.height);
|
|
for (int i = 0; i < img.pixels.length; i++) img.pixels[i] = color(255);
|
|
img.mask(msk);
|
|
|
|
ps = new ParticleSystem(0,new Vector3D(width/2,height-20),img);
|
|
smooth();
|
|
}
|
|
|
|
void draw() {
|
|
background(0);
|
|
|
|
// Calculate a "wind" force based on mouse horizontal position
|
|
float dx = (mouseX - width/2) / 1000.0;
|
|
Vector3D wind = new Vector3D(dx,0,0);
|
|
ps.add_force(wind);
|
|
ps.run();
|
|
for (int i = 0; i < 2; i++) {
|
|
ps.addParticle();
|
|
}
|
|
|
|
// Draw an arrow representing the wind force
|
|
drawVector(wind, new Vector3D(width/2,50,0),500);
|
|
|
|
}
|
|
|
|
// Renders a vector object 'v' as an arrow and a location 'loc'
|
|
void drawVector(Vector3D v, Vector3D loc, float scayl) {
|
|
pushMatrix();
|
|
float arrowsize = 4;
|
|
// Translate to location to render vector
|
|
translate(loc.x,loc.y);
|
|
stroke(255);
|
|
// Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate
|
|
rotate(v.heading2D());
|
|
// Calculate length of vector & scale it to be bigger or smaller if necessary
|
|
float len = v.magnitude()*scayl;
|
|
// Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction)
|
|
line(0,0,len,0);
|
|
line(len,0,len-arrowsize,+arrowsize/2);
|
|
line(len,0,len-arrowsize,-arrowsize/2);
|
|
popMatrix();
|
|
}
|
|
|
|
|
|
|
|
// A simple Particle class, renders the particle as an image
|
|
|
|
class Particle {
|
|
Vector3D loc;
|
|
Vector3D vel;
|
|
Vector3D acc;
|
|
float timer;
|
|
PImage img;
|
|
|
|
// One constructor
|
|
Particle(Vector3D a, Vector3D v, Vector3D l, PImage img_) {
|
|
acc = a.copy();
|
|
vel = v.copy();
|
|
loc = l.copy();
|
|
timer = 100.0;
|
|
img = img_;
|
|
}
|
|
|
|
// Another constructor (the one we are using here)
|
|
Particle(Vector3D l,PImage img_) {
|
|
acc = new Vector3D(0.0,0.0,0.0);
|
|
float x = (float) generator.nextGaussian()*0.3f;
|
|
float y = (float) generator.nextGaussian()*0.3f - 1.0f;
|
|
vel = new Vector3D(x,y,0);
|
|
loc = l.copy();
|
|
timer = 100.0;
|
|
img = img_;
|
|
}
|
|
|
|
void run() {
|
|
update();
|
|
render();
|
|
}
|
|
|
|
// Method to apply a force vector to the Particle object
|
|
// Note we are ignoring "mass" here
|
|
void add_force(Vector3D f) {
|
|
acc.add(f);
|
|
}
|
|
|
|
// Method to update location
|
|
void update() {
|
|
vel.add(acc);
|
|
loc.add(vel);
|
|
timer -= 2.5;
|
|
acc.setXY(0,0);
|
|
}
|
|
|
|
// Method to display
|
|
void render() {
|
|
imageMode(CORNER);
|
|
tint(255,timer);
|
|
image(img,loc.x-img.width/2,loc.y-img.height/2);
|
|
}
|
|
|
|
// Is the particle still useful?
|
|
boolean dead() {
|
|
if (timer <= 0.0) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// A class to describe a group of Particles
|
|
// An ArrayList is used to manage the list of Particles
|
|
|
|
class ParticleSystem {
|
|
|
|
ArrayList particles; // An arraylist for all the particles
|
|
Vector3D origin; // An origin point for where particles are birthed
|
|
PImage img;
|
|
|
|
ParticleSystem(int num, Vector3D v, PImage img_) {
|
|
particles = new ArrayList(); // Initialize the arraylist
|
|
origin = v.copy(); // Store the origin point
|
|
img = img_;
|
|
for (int i = 0; i < num; i++) {
|
|
particles.add(new Particle(origin, img)); // Add "num" amount of particles to the arraylist
|
|
}
|
|
}
|
|
|
|
void run() {
|
|
// Cycle through the ArrayList backwards b/c we are deleting
|
|
for (int i = particles.size()-1; i >= 0; i--) {
|
|
Particle p = (Particle) particles.get(i);
|
|
p.run();
|
|
if (p.dead()) {
|
|
particles.remove(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Method to add a force vector to all particles currently in the system
|
|
void add_force(Vector3D dir) {
|
|
for (int i = particles.size()-1; i >= 0; i--) {
|
|
Particle p = (Particle) particles.get(i);
|
|
p.add_force(dir);
|
|
}
|
|
|
|
}
|
|
|
|
void addParticle() {
|
|
particles.add(new Particle(origin,img));
|
|
}
|
|
|
|
void addParticle(Particle p) {
|
|
particles.add(p);
|
|
}
|
|
|
|
// A method to test if the particle system still has particles
|
|
boolean dead() {
|
|
if (particles.isEmpty()) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
public class Vector3D {
|
|
public float x;
|
|
public float y;
|
|
public float z;
|
|
|
|
Vector3D(float x_, float y_, float z_) {
|
|
x = x_; y = y_; z = z_;
|
|
}
|
|
|
|
Vector3D(float x_, float y_) {
|
|
x = x_; y = y_; z = 0f;
|
|
}
|
|
|
|
Vector3D() {
|
|
x = 0f; y = 0f; z = 0f;
|
|
}
|
|
|
|
void setX(float x_) {
|
|
x = x_;
|
|
}
|
|
|
|
void setY(float y_) {
|
|
y = y_;
|
|
}
|
|
|
|
void setZ(float z_) {
|
|
z = z_;
|
|
}
|
|
|
|
void setXY(float x_, float y_) {
|
|
x = x_;
|
|
y = y_;
|
|
}
|
|
|
|
void setXYZ(float x_, float y_, float z_) {
|
|
x = x_;
|
|
y = y_;
|
|
z = z_;
|
|
}
|
|
|
|
void setXYZ(Vector3D v) {
|
|
x = v.x;
|
|
y = v.y;
|
|
z = v.z;
|
|
}
|
|
public float magnitude() {
|
|
return (float) Math.sqrt(x*x + y*y + z*z);
|
|
}
|
|
|
|
public Vector3D copy() {
|
|
return new Vector3D(x,y,z);
|
|
}
|
|
|
|
public Vector3D copy(Vector3D v) {
|
|
return new Vector3D(v.x, v.y,v.z);
|
|
}
|
|
|
|
public void add(Vector3D v) {
|
|
x += v.x;
|
|
y += v.y;
|
|
z += v.z;
|
|
}
|
|
|
|
public void sub(Vector3D v) {
|
|
x -= v.x;
|
|
y -= v.y;
|
|
z -= v.z;
|
|
}
|
|
|
|
public void mult(float n) {
|
|
x *= n;
|
|
y *= n;
|
|
z *= n;
|
|
}
|
|
|
|
public void div(float n) {
|
|
x /= n;
|
|
y /= n;
|
|
z /= n;
|
|
}
|
|
|
|
/*public float dot(Vector3D v) {
|
|
//implement DOT product
|
|
}*/
|
|
|
|
/*public Vector3D cross(Vector3D v) {
|
|
//implement CROSS product
|
|
}*/
|
|
|
|
public void normalize() {
|
|
float m = magnitude();
|
|
if (m > 0) {
|
|
div(m);
|
|
}
|
|
}
|
|
|
|
public void limit(float max) {
|
|
if (magnitude() > max) {
|
|
normalize();
|
|
mult(max);
|
|
}
|
|
}
|
|
|
|
public float heading2D() {
|
|
float angle = (float) Math.atan2(-y, x);
|
|
return -1*angle;
|
|
}
|
|
|
|
public Vector3D add(Vector3D v1, Vector3D v2) {
|
|
Vector3D v = new Vector3D(v1.x + v2.x,v1.y + v2.y, v1.z + v2.z);
|
|
return v;
|
|
}
|
|
|
|
public Vector3D sub(Vector3D v1, Vector3D v2) {
|
|
Vector3D v = new Vector3D(v1.x - v2.x,v1.y - v2.y,v1.z - v2.z);
|
|
return v;
|
|
}
|
|
|
|
public Vector3D div(Vector3D v1, float n) {
|
|
Vector3D v = new Vector3D(v1.x/n,v1.y/n,v1.z/n);
|
|
return v;
|
|
}
|
|
|
|
public Vector3D mult(Vector3D v1, float n) {
|
|
Vector3D v = new Vector3D(v1.x*n,v1.y*n,v1.z*n);
|
|
return v;
|
|
}
|
|
|
|
public float distance (Vector3D v1, Vector3D v2) {
|
|
float dx = v1.x - v2.x;
|
|
float dy = v1.y - v2.y;
|
|
float dz = v1.z - v2.z;
|
|
return (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
|
|
}
|
|
|
|
}
|