Hello there, I am trying to make a body with complex geometry move with gravity. For this I created a grid of particles that all are "attached" to each other with springs and have gravity behaviour. However the result I am getting is a very 'jumpy' geometry that is malleable and jell-like, instead of the rigid body I need. I guess the way to solve this problem is by changing the parameters of my spring (in the ComplexBody class). Any ideas about what I can do?
Here's the code:
import toxi.physics2d.*;
import toxi.physics2d.behaviors.*;
import toxi.geom.*;
VerletPhysics2D physics;
MyPolygon mypolygon;
ComplexBody complexbody;
PVector anchorPoint;
PVector massCenter;
//POLYGON
PVector[] points;
float shapeScale=2;
int gridScale=12;
int rows=25;
int cols=25;
//RECT
int w=460;
int h=90;
int xRect=0;
int yRect=0;
void setup() {
size(600, 400, P2D);
smooth();
//frameRate(30);
//VERLET PHYSICS
// Initialize the physics
physics=new VerletPhysics2D();
physics.addBehavior(new GravityBehavior(new Vec2D(0, 0.1)));
// This is the center of the world
Vec2D center = new Vec2D(width/2, height/2);
// these are the worlds dimensions (50%, a vector pointing out from the center in both directions)
Vec2D extent = new Vec2D(width/4, height/4);
// Set the world's bounding box
physics.setWorldBounds(Rect.fromCenterExtent(center, extent));
//POLYGON
anchorPoint=new PVector(width/2, height/2);
points=new PVector[8];
points[0]= new PVector(0, 0);
points[1]= new PVector(-50, 0);
points[2]= new PVector(-50, -10);
points[3]= new PVector(-75, -20);
points[4]= new PVector(-75, -40);
points[5]= new PVector(+25, -40);
points[6]= new PVector(+25, -20);
points[7]= new PVector( 0, -10);
for(PVector a: points){
a.mult(shapeScale);
a.add(anchorPoint);
}
mypolygon=new MyPolygon(points);
mypolygon.createGrid();
massCenter= mypolygon.centerOfMass();
complexbody= new ComplexBody(mypolygon.grid);
}
void draw() {
background(0);
physics.update();
mypolygon.drawGrid();
// mypolygon.drawGridTwoD();
mypolygon.drawInitialShape(50);
complexbody.display();
complexbody.createSprings();
fill(0, 100, 255);
ellipse(massCenter.x, massCenter.y, 10, 10);
}
class ComplexBody {
ArrayList<Particle> particles;
ArrayList<PVector> p;
ArrayList<VerletSpring2D> springs;
AttractionBehavior repulsion;
ComplexBody(ArrayList<PVector> p_) {
p=p_;
particles=new ArrayList<Particle>();
springs=new ArrayList<VerletSpring2D>();
for (int i=0; i<p.size(); i++) {
PVector a=p.get(i);
Particle k= new Particle(a.x, a.y);
particles.add(k);
physics.addParticle(k);
}
}
void createSprings() {
for (int i=0; i<particles.size(); i++) {
Particle s1=particles.get(i);
//stroke(255);
//strokeWeight(1);
//line(s1.x, s1.y, s1.x+10, s1.y+10);
for (int j=0; j<particles.size(); j++) {
if (j!=i) {
Particle s2=particles.get(j);
stroke(255,10);
strokeWeight(1);
line(s1.x, s1.y, s2.x, s2.y);
float r= dist(s1.x, s1.y, s2.x, s2.y);
VerletSpring2D spring=new VerletSpring2D(s1, s2, r, 1);
physics.addSpring(spring);
}
}
}
}
void display() {
for (Particle p : particles) {
p.display();
}
}
}
class MyPolygon {
float xAverage;
float yAverage;
PVector origin;
PVector location;
java.awt.Polygon p;
PVector[] pts;
ArrayList <PVector> grid;
MyPolygon(PVector[] pts_) {
pts=pts_;
grid=new ArrayList<PVector>();
p = new java.awt.Polygon();
for (PVector a : pts) {
p.addPoint(int(a.x), int(a.y));
}
}
void createGrid() {
for (int i=-rows; i<=rows; i++) {
for (int j=-cols; j<=cols; j++) {
PVector k=new PVector(anchorPoint.x+ (i*gridScale), anchorPoint.y + (j*gridScale));
if (p.contains(anchorPoint.x+ (i*gridScale), anchorPoint.y + (j*gridScale))) {
grid.add(k);
}
}
}
}
void drawGrid() {
fill(0, 0, 200, 200);
noStroke();
for (PVector v : grid) {
ellipse(v.x, v.y, 2, 2);
}
}
PVector centerOfMass() {
int xcount=0;
int ycount=0;
for (int i=0; i<grid.size(); i++) {
xcount+=grid.get(i).x;
ycount+=grid.get(i).y;
}
xAverage=xcount/grid.size();
yAverage=ycount/grid.size();
PVector r=new PVector (xAverage, yAverage);
return r;
}
void drawInitialShape(float alpha) {
fill(255, alpha);
beginShape();
for (PVector a : points) {
vertex(a.x, a.y);
}
endShape();
}
}
class Particle extends VerletParticle2D {
Particle(float x, float y) {
super(x,y);
}
void display() {
fill(255);
noStroke();
ellipse(x,y,2,2);
}
}