Quantcast
Channel: Library Questions - Processing 2.x and 3.x Forum
Viewing all articles
Browse latest Browse all 2896

Verlet Physics, Simulation of rigid body with complex geometry

$
0
0

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);
  }
}

Viewing all articles
Browse latest Browse all 2896

Trending Articles