A Flash Developer Resource Site

Results 1 to 1 of 1

Thread: [BETA] P5 Verlet Integration

Threaded View

  1. #1
    Professional Air Guitarist Frag's Avatar
    Join Date
    Dec 2002
    Location
    Brain, Body, Clothes, Computer Chair, Room, House, Neighborhood, City, State, Country, Continent, World, Galaxy, Universe, and on?
    Posts
    811

    [BETA] P5 Verlet Integration (Ragdoll/Vehicle physics)

    For those of you who've checked out Processing, I've converted the framework of my (much props to Metanet) VI engine into p5 to take advantage of its power. I'm still relatively new to Java so my syntax may seem a tad strange, but it works (P5 v0.91)

    Code:
    Point[] pL;
    Segment[] sL;
    Circle[] cL;
    void setup() {
      size(600, 400);
      framerate(60);
      stroke(20, 60, 40);
      ellipseMode(CENTER);
      noSmooth();
      noFill();
      pL = new Point[4];
      pL[0] = new Point(0, 0);
      pL[1] = new Point(50, 0);
      pL[2] = new Point(50, 50);
      pL[3] = new Point(0, 50);
      sL = new Segment[6];
      sL[0] = new Segment(0, 1, true);
      sL[1] = new Segment(1, 2, true);
      sL[2] = new Segment(2, 3, true);
      sL[3] = new Segment(3, 0, true);
      sL[4] = new Segment(0, 2, true);
      sL[5] = new Segment(1, 3, true);
      cL = new Circle[4];
      cL[0] = new Circle(100, 100, 50);
      cL[1] = new Circle(175, 200, 75);
      cL[2] = new Circle(275, 275, 50);
      cL[3] = new Circle(350, 350, 25);
    }
    float getDistance(int p0, int p1) {
      return sqrt(sq(pL[p0].x-pL[p1].x)+sq(pL[p0].y-pL[p1].y));
    }
    float initX = 100;
    float initY = 0;
    float drag = .9;
    float grav = 1;
    float cx, cy, cr, a, a0, a1, px, py, dx, dy, d0, d1, d;
    int p0, p1;
    void draw() {
      background(120, 140, 100);
      if (mousePressed) {
        pL[0].x += (mouseX-pL[0].x)/25;
        pL[0].y += (mouseY-pL[0].y)/25;
      }
      for (int i=0; i<pL.length; i++) {
        px = pL[i].oX;
        py = pL[i].oY;
        pL[i].oX = pL[i].x;
        pL[i].oY = pL[i].y;
        pL[i].x += drag*(pL[i].oX-px);
        pL[i].y += drag*(pL[i].oY-py)+grav;
      }
      for (int i=0; i<sL.length; i++) {
        p0 = int(sL[i].p0);
        p1 = int(sL[i].p1);
        dx = pL[p0].x-pL[p1].x;
        dy = pL[p0].y-pL[p1].y;
        d = getDistance(p0, p1);
        d0 = d1 = (d-sL[i].rL)/d;
        d0 *= 0.5;
        d1 *= 0.5;
        pL[p0].x -= dx*d0;
        pL[p0].y -= dy*d0;
        pL[p1].x += dx*d1;
        pL[p1].y += dy*d1;
      }
      for (int i=0; i<sL.length; i++) {
        if (!sL[i].collide) {
          continue;
        }
        p0 = int(sL[i].p0);
        p1 = int(sL[i].p1);
        for (int j=0; j<cL.length; j++) {
          cx = cL[j].x;
          cy = cL[j].y;
          cr = cL[j].r;
          d0 = sqrt(sq(pL[p0].x-cx)+sq(pL[p0].y-cy));
          d1 = sqrt(sq(pL[p1].x-cx)+sq(pL[p1].y-cy));
          a0 = abs(atan2(pL[p0].y-cy, pL[p0].x-cx)*180/PI-atan2(pL[p0].y-pL[p1].y, pL[p0].x-pL[p1].x)*180/PI);
          a1 = abs(atan2(pL[p1].y-cy, pL[p1].x-cx)*180/PI-atan2(pL[p1].y-pL[p0].y, pL[p1].x-pL[p0].x)*180/PI);
          a0 = a0 <= 180 ? a0 : 360-a0;
          a1 = a1 <= 180 ? a1 : 360-a1;
          if (a0>90) {
            if (d0<cr) {
              d0 = cr-d0;
              dx = pL[p0].x-cx;
              dy = pL[p0].y-cy;
              pL[p0].x += d0*(dx/cr);
              pL[p0].y += d0*(dy/cr);
            }
          } 
          else if (a1>90) {
            if (d1 < cr) {
              d1 = cr-d1;
              dx = pL[p1].x-cx;
              dy = pL[p1].y-cy;
              pL[p1].x += d1*(dx/cr);
              pL[p1].y += d1*(dy/cr);
            }
          } 
          else {
            if (d0>d1) {
              a = (45-(a1-a0))/90;
              px = pL[p1].x+(pL[p0].x-pL[p1].x)*a;
              py = pL[p1].y+(pL[p0].y-pL[p1].y)*a;
            } 
            else {
              a = (45-(a0-a1))/90;
              px = pL[p0].x+(pL[p1].x-pL[p0].x)*a;
              py = pL[p0].y+(pL[p1].y-pL[p0].y)*a;
            }
            d = sqrt(sq(px-cx)+sq(py-cy));
            if (d < cr) {
              d = cr-d;
              dx = (px-cx)/cr;
              dy = (py-cy)/cr;
              pL[p0].x += d*dx;
              pL[p0].y += d*dy;
              pL[p1].x += d*dx;
              pL[p1].y += d*dy;
            }
          }
        }
        if (pL[p0].x < 0) {
          pL[p0].x = 0;
        } 
        else if (pL[p0].x > width) {
          pL[p0].x = width;
        }
        if (pL[p0].y < 0) {
          pL[p0].y = 0;
        } 
        else if (pL[p0].y > height) {
          pL[p0].y = height;
        }
        if (pL[p1].x < 0) {
          pL[p1].x = 0;
        } 
        else if (pL[p1].x > width) {
          pL[p1].x = width;
        }
        if (pL[p1].y < 0) {
          pL[p1].y = 0;
        } 
        else if (pL[p1].y > height) {
          pL[p1].y = height;
        }
      }
      for (int i=0; i<cL.length; i++) {
        ellipse(cL[i].x, cL[i].y, cL[i].r*2, cL[i].r*2);
      }
      for (int i=0; i<sL.length; i++) {
        p0 = int(sL[i].p0);
        p1 = int(sL[i].p1);
        line(pL[p0].x, pL[p0].y, pL[p1].x, pL[p1].y);
      }
    }
    class Point {
      float x, y, oX, oY;
      Point (float Tx, float Ty) {
        x = Tx+initX;
        y = Ty+initY;
        oX = x;
        oY = y;
      }
    }
    class Segment {
      int p0, p1;
      float rL;
      boolean collide;
      Segment (int Tp0, int Tp1, boolean Tcollide) {
        p0 = int(Tp0);
        p1 = int(Tp1);
        rL = getDistance(p0, p1);
        collide = Tcollide;
      }
    }
    class Circle {
      float x, y, r;
      Circle (float Tx, float Ty, float Tr) {
        x = Tx;
        y = Ty;
        r = Tr;
      }
    }
    EDIT: As of now there is only line/circle collision (took me a few hours to figure it out ) and point/window collision. Also wanted to show off my "Modern Art" generator
    Code:
    void setup() {
      size(600, 400);
      smooth();
      background(255);
    }
    int r = 0;
    int g = 0;
    int b = 0;
    int ranC = 5;
    float ranM = 5;//random(5, 100);
    float x = 300;
    float y = 200;
    float nx, ny;
    void draw() {
      stroke(r, g, b);
      nx = x+random(-ranM, ranM);
      nx = nx<0?abs(nx):nx;
      nx = nx>width?width*2-nx:nx;
      ny = y+random(-ranM, ranM);
      ny = ny<0?abs(ny):ny;
      ny = ny>height?height*2-ny:ny;
      line(x, y, nx, ny);
      x = nx;
      y = ny;
      r += random(-ranC, ranC);
      r = r<0?255+r:r;
      r = r>255?r-255:r;
      g += random(-ranC, ranC);
      g = g<0?255+g:g;
      g = g>255?g-255:g;
      b += random(-ranC, ranC);
      b = b<0?255+b:b;
      b = b>255?b-255:b;
    }
    EDIT2: If you're confused, http://www.processing.org/
    Last edited by Frag; 07-06-2005 at 05:26 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center