Toxiclibs + force physics simulation to create morphing surface??
in
Contributed Library Questions
•
2 years ago
Hi guys,
could someone give me some much needed advise/pointers on how to achieve an undulating landscape in processing. I have posted below a sketch I'm working on. Basically I want an array of attractors moving randomly top of the grid of nodes. These attractors should distort the grid by moving those nodes that are within a defined distance in the z direction (+ or -). The movement of these nodes should be fluid in their movement.
My next step will be to implement some springs between the nodes so the grid becomes more like a surface or undulating landscape....or I was thinking that i should tie the nodes to a mesh and define this as the spring to achieve this effect. Does this sound right? Any advise comments would be gratefully received!
The pic below hopefully gives an idea of the overall surface form I'm trying to achieve.
Thanks,
Farley
import processing.opengl.*;
import peasy.*;
import toxi.physics.*;
import toxi.physics.constraints.*;
import toxi.physics.behaviors.*;
import toxi.geom.*;
// VARIABLES ////////////////////////////////////////
PeasyCam myCam;
Node myNode;
Attractor myAttractor;
int numNodesX = 60;
int numNodesY = 20;
int xInc = 20;
int yInc = 20;
int envX = numNodesX * xInc;
int envY = numNodesY * yInc;
int envZ = 400;
ArrayList nodeList = new ArrayList();
Vec3D testPos;
// Declare new physics world (array)
VerletPhysics myPhysics;
// ----------------------- // GLOBAL SETUP // -----------------------
void setup() {
size(800, 800, OPENGL);
// INITIALISE ////////////////////////////////////////
myCam = new PeasyCam(this, envX*2);
myCam.lookAt(envX/2, envX/2, envX/2);
myPhysics = new VerletPhysics();
myAttractor = new Attractor();
for (int i = 0; i < numNodesX; ++i) {
for (int j = 0; j < numNodesY; ++j) {
Vec3D nodeOrigin = new Vec3D ((i+0.5) * xInc, (j+0.5) * yInc, 0);
Node tmpNode = new Node(nodeOrigin);
nodeList.add(tmpNode);
}
}
}
// ----------------------- // GLOBAL RUN // -----------------------
void draw() {
background(0);
stroke(100);
strokeWeight(0.8);
noFill();
pushMatrix();
translate(envX/2, envY/2, 0);
box(envX, envY, envZ);
popMatrix();
// RUN FUNCTIONS ////////////////////////////////////////
Vec3D v = new Vec3D(myAttractor.loc.x, myAttractor.loc.y, myAttractor.loc.z);
AttractionBehavior a = new AttractionBehavior(v, 100, 0.01);
myPhysics.addBehavior(a);
for (int i = 0; i < nodeList.size(); ++i) {
Node myNode = (Node) nodeList.get(i);
myNode.run();
}
myAttractor.run();
//drawParticles();
myPhysics.update();
}
// NAME ////////////////////////////////////////
class Node {
// DATA ////////////////////////////////////////
VerletParticle p;
// CONSTRUCTOR ////////////////////////////////////////
Node(Vec3D loc) {
p = new VerletParticle(loc);
myPhysics.addParticle(p);
}
// FUNCTIONS ////////////////////////////////////////
void run() {
display();
}
void display() {
strokeWeight(2);
stroke(0, 0, 255);
point (p.x, p.y, p.z);
}
}
// NAME ////////////////////////////////////////
class Attractor {
// DATA ////////////////////////////////////////
Vec3D loc = new Vec3D(0,0,50);
Vec3D vel = new Vec3D(1.5, 0.5, 0);
// CONSTRUCTOR ////////////////////////////////////////
Attractor() {
}
// FUNCTIONS ////////////////////////////////////////
void run() {
move();
bounce();
display();
}
void move() {
loc.addSelf(vel);
}
void bounce() {
if (loc.x > envX || loc.x < 0) {
vel.x *= -1;
}
if (loc.y > envY || loc.y < 0) {
vel.y *= -1;
}
}
void display() {
strokeWeight(2);
stroke(255, 0, 0);
point (loc.x, loc.y, loc.z);
}
}
could someone give me some much needed advise/pointers on how to achieve an undulating landscape in processing. I have posted below a sketch I'm working on. Basically I want an array of attractors moving randomly top of the grid of nodes. These attractors should distort the grid by moving those nodes that are within a defined distance in the z direction (+ or -). The movement of these nodes should be fluid in their movement.
My next step will be to implement some springs between the nodes so the grid becomes more like a surface or undulating landscape....or I was thinking that i should tie the nodes to a mesh and define this as the spring to achieve this effect. Does this sound right? Any advise comments would be gratefully received!
The pic below hopefully gives an idea of the overall surface form I'm trying to achieve.
Thanks,
Farley
import processing.opengl.*;
import peasy.*;
import toxi.physics.*;
import toxi.physics.constraints.*;
import toxi.physics.behaviors.*;
import toxi.geom.*;
// VARIABLES ////////////////////////////////////////
PeasyCam myCam;
Node myNode;
Attractor myAttractor;
int numNodesX = 60;
int numNodesY = 20;
int xInc = 20;
int yInc = 20;
int envX = numNodesX * xInc;
int envY = numNodesY * yInc;
int envZ = 400;
ArrayList nodeList = new ArrayList();
Vec3D testPos;
// Declare new physics world (array)
VerletPhysics myPhysics;
// ----------------------- // GLOBAL SETUP // -----------------------
void setup() {
size(800, 800, OPENGL);
// INITIALISE ////////////////////////////////////////
myCam = new PeasyCam(this, envX*2);
myCam.lookAt(envX/2, envX/2, envX/2);
myPhysics = new VerletPhysics();
myAttractor = new Attractor();
for (int i = 0; i < numNodesX; ++i) {
for (int j = 0; j < numNodesY; ++j) {
Vec3D nodeOrigin = new Vec3D ((i+0.5) * xInc, (j+0.5) * yInc, 0);
Node tmpNode = new Node(nodeOrigin);
nodeList.add(tmpNode);
}
}
}
// ----------------------- // GLOBAL RUN // -----------------------
void draw() {
background(0);
stroke(100);
strokeWeight(0.8);
noFill();
pushMatrix();
translate(envX/2, envY/2, 0);
box(envX, envY, envZ);
popMatrix();
// RUN FUNCTIONS ////////////////////////////////////////
Vec3D v = new Vec3D(myAttractor.loc.x, myAttractor.loc.y, myAttractor.loc.z);
AttractionBehavior a = new AttractionBehavior(v, 100, 0.01);
myPhysics.addBehavior(a);
for (int i = 0; i < nodeList.size(); ++i) {
Node myNode = (Node) nodeList.get(i);
myNode.run();
}
myAttractor.run();
//drawParticles();
myPhysics.update();
}
// NAME ////////////////////////////////////////
class Node {
// DATA ////////////////////////////////////////
VerletParticle p;
// CONSTRUCTOR ////////////////////////////////////////
Node(Vec3D loc) {
p = new VerletParticle(loc);
myPhysics.addParticle(p);
}
// FUNCTIONS ////////////////////////////////////////
void run() {
display();
}
void display() {
strokeWeight(2);
stroke(0, 0, 255);
point (p.x, p.y, p.z);
}
}
// NAME ////////////////////////////////////////
class Attractor {
// DATA ////////////////////////////////////////
Vec3D loc = new Vec3D(0,0,50);
Vec3D vel = new Vec3D(1.5, 0.5, 0);
// CONSTRUCTOR ////////////////////////////////////////
Attractor() {
}
// FUNCTIONS ////////////////////////////////////////
void run() {
move();
bounce();
display();
}
void move() {
loc.addSelf(vel);
}
void bounce() {
if (loc.x > envX || loc.x < 0) {
vel.x *= -1;
}
if (loc.y > envY || loc.y < 0) {
vel.y *= -1;
}
}
void display() {
strokeWeight(2);
stroke(255, 0, 0);
point (loc.x, loc.y, loc.z);
}
}
2