heres the rest of the code (i.e. the 2 classes)......I was playing around with creating voids within a 3D grid using repellers and nodes. The lines dont really mean anything other than to visualise the grid/deformed grid. My eventual aim is to implement some physics so the nodes spread apart and react to each other (maybe using springs) which will hopefully give me some sort of surface that I can export into a 3D modeller.
Every line is duplicated when i export the pdf unfortunately.
(press the 's' key to stop the repellers moving and repell nodes)
(press the 'p' key to export frame as pdf)
thanks (ps sorry if its a bit of a mess)!!
// NAME /////////////////////////////
class Node {
// DATA /////////////////////////////
Vec3D nodeLoc = new Vec3D (0,0,0);
Vec3D speed = new Vec3D (0,0,0);
Vec3D accel = new Vec3D (0,0,0);
boolean sep;
float sepForce = 40;
float slowForce = 5;
// CONSTRUCTOR /////////////////////////////
Node(Vec3D nodeLoc_) {
nodeLoc = nodeLoc_;
}
// FUNCTIONS /////////////////////////////
void run() {
move();
display();
bounce();
activateRep();
drawLine();
}
void move() {
// Store acceleration in the function
speed.addSelf(accel);
// 2 = maximum velocity. It is good to instigate a threshold
speed.limit(2);
// Adding Vec3D speed (x = 1) to Vec3D loc
nodeLoc.addSelf(speed);
// Reset acceleration to 0
accel.clear();
}
void display() {
stroke(255,0,0);
strokeWeight(2);
point(nodeLoc.x,nodeLoc.y,nodeLoc.z);
}
void bounce() {
if(nodeLoc.x > boundingBox) {
speed.x *= -1;
}
if(nodeLoc.x < 0) {
speed.x *= -1;
}
if(nodeLoc.y > boundingBox) {
speed.y *= -1;
}
if(nodeLoc.y < 0) {
speed.y *= -1;
}
if(nodeLoc.z > boundingBox) {
speed.z *= -1;
}
if(nodeLoc.z < 0) {
speed.z *= -1;
}
}
void activateRep() {
if (keyPressed) {
if (key == 's' || key == 'S') {
sep = true;
}
}
if (sep) {
separation(sepForce);
slow(slowForce);
}
}
//------------------------------------------------------------
void separation(float separation) {
Vec3D steer = new Vec3D();
int count = 0;
for(int i = 0; i < repellerArray.size(); i++) {
// Repeller other is an instance of the class Repeller
Repeller other = (Repeller) repellerArray.get(i);
// distanceTo is a function from Toxiclibs library
float distance = nodeLoc.distanceTo(other.repellerLoc);
if (distance > 0 && distance < other.voidSize) {
Vec3D diff = nodeLoc.sub(other.repellerLoc);
// Makes movement of the agents less mechanical and smoother
diff.normalizeTo(1.0/distance);
steer.addSelf(diff);
count++;
}
}
if(count > 0) {
steer.scaleSelf(1.0/count);
}
// Allows us to implement a scale factor as separation() needs to be tuned
steer.scaleSelf(separation);
accel.addSelf(steer);
}
void slow (float slowForce) {
Vec3D steer = new Vec3D();
int count = 0;
for(int i = 0; i < repellerArray.size(); i++) {
// Repeller other is an instance of the class Repeller
Repeller other = (Repeller) repellerArray.get(i);
// distanceTo is a function from Toxiclibs library
float distance = nodeLoc.distanceTo(other.repellerLoc);
if (distance <= other.voidSize*2) {
Vec3D diff = nodeLoc.sub(other.repellerLoc);
// Makes movement of the agents less mechanical and smoother
diff.normalizeTo(1.0/distance);
steer.subSelf(diff);
count++;
}
}
if(count > 0) {
steer.scaleSelf(1.0/count);
}
// Allows us to implement a scale factor as separation() needs to be tuned
steer.scaleSelf(slowForce);
accel.addSelf(steer);
}
void drawLine() {
for(int i = 0; i < nodeArray.size(); i++) {
//for(int j = 0; j < numGroundX-1; j++) {
// Ball other is an instance of the class Ball
Node other = (Node) nodeArray.get(i);
// distanceTo is a function from Toxiclibs library
float distance = nodeLoc.distanceTo(other.nodeLoc);
if (distance > 0 && distance <= 150) {
strokeWeight(0.2);
stroke(0,0,255);
line(nodeLoc.x,nodeLoc.y,nodeLoc.z,other.nodeLoc.x,other.nodeLoc.y,other.nodeLoc.z);
}
}
}
}
// NAME /////////////////////////////
class Repeller {
// DATA /////////////////////////////
Vec3D repellerLoc = new Vec3D (0,0,0);
Vec3D speed = new Vec3D (random(-2,2),random(-2,2),random(-2,2));
Vec3D accel = new Vec3D (0,0,0);
float voidSpacing = 300;
float voidSize;
boolean stop;
// CONSTRUCTOR /////////////////////////////
Repeller(Vec3D repellerLoc_) {
repellerLoc = repellerLoc_;
voidSize = random(50,250);
}
// FUNCTIONS /////////////////////////////
void run() {
display();
move();
bounce();
avoidance(20);
drawBox();
}
void display() {
stroke(0,0,255,125);
strokeWeight(4);
point(repellerLoc.x,repellerLoc.y,repellerLoc.z);
}
void drawBox() {
for(int i = 0; i < repellerArray.size(); i++) {
if (keyPressed) {
if (key == 'b' || key == 'B') {
strokeWeight(0.5);
stroke(100);
noFill();
pushMatrix();
translate(repellerLoc.x,repellerLoc.y,repellerLoc.z);
box(voidSize);
popMatrix();
}
}
}
}
void move() {
speed.addSelf(accel);
speed.limit(2);
repellerLoc.addSelf(speed);
accel.clear();
if (keyPressed) {
if (key == 's' || key == 'S') {
stop = true;
}
}
if (stop) {
speed = new Vec3D(0,0,0);
}
}
void bounce() {
if(repellerLoc.x > boundingBox) {
speed.x *= -1;
}
if(repellerLoc.x < 0) {
speed.x *= -1;
}
if(repellerLoc.y > boundingBox) {
speed.y *= -1;
}
if(repellerLoc.y < 0) {
speed.y *= -1;
}
if(repellerLoc.z > boundingBox) {
speed.z *= -1;
}
if(repellerLoc.z < 0) {
speed.z *= -1;
}
}
void avoidance(float avoidance) {
Vec3D steer = new Vec3D();
int count = 0;
for(int i = 0; i < repellerArray.size(); i++) {
// Ball other is an instance of the class Ball
Repeller other = (Repeller) repellerArray.get(i);
// distanceTo is a function from Toxiclibs library
float distance = repellerLoc.distanceTo(other.repellerLoc);
if (distance > 0 && distance < voidSpacing) {
Vec3D diff = repellerLoc.sub(other.repellerLoc);
// Makes movement of the agents less mechanical and smoother
diff.normalizeTo(1.0/distance);
steer.addSelf(diff);
count++;
}
}
if(count > 0) {
steer.scaleSelf(1.0/count);
}
// Allows us to implement a scale factor as separate(), cohesion() and align() need to be tuned
steer.scaleSelf(avoidance);
accel.addSelf(steer);
}
}