Polygon rotate and move: Logic problem !

edited July 2014 in How To...

Hi,

I am trying to move a polygon and rotate at the same time. The rotation of the polygon and distance covered horizontally are related (s=r/theta). I am really exhausted. I have tried everything such as translating the poygon vetically when it rotates. I have tried calculating the vertical translation based on the rotataion of the radius about the center. But it didn't work ! b-( b-( b-(

Polygon Move

Here is the simple code. I have removed the rotation part.

void setup()
{
  size(400, 300);
}
int t=3;
void draw()
{
  background(255);
  translate(width>>1, height>>1);
  line(-width/2, 0, width/2, 0);
  if (mousePressed==true) t = (int)map(mouseX, 0, width, 3, 20);
  polygon(t, 50);
}

void polygon(int edges, int r) {
  noFill();
  beginShape();
  for (int i=0; i<edges; i++) {
    float x = r*sin(i*TWO_PI/edges);
    float y = r*cos(i*TWO_PI/edges);
    vertex(x, y);
  }
  endShape(CLOSE);
  ellipse(0, 0, 2, 2);
}

Here is my full code .... sorry for the long code.

ArrayList<PVector> poop = new ArrayList();
Morph M;
int t=5;
float dx=0.0f, ys;
void setup() {
  size(600, 300);
  M = new Morph();
  for (int i=-width/2; i<width; i+=20) {
    PVector P = new PVector(i, 0);
    poop.add(P);
  }
  y=height/2;
}
float yvel=0, y;
void draw() {
  background(-1);
  translate(width/2, height/2);
  //-------Road-------------
  stroke(0);
  noFill();
  beginShape();
  for (int m=0; m<poop.size (); m++) {
    PVector P = poop.get(m);
    vertex(P.x, P.y);
    P.x-=dx;
    if (P.x<-width/2-100) {
      poop.remove(0);
      PVector K = new PVector(width/2+100, 0);
      poop.add(K);
    }
  }
  endShape();
  //-------------------
  PVector move = poop.get(0); 
  float angle = map(M.x/M.r, 0, PI, 0, M.theta/2);
  println(angle);
  float ymove =M.r-M.r*sin(radians(angle)); 
  pushMatrix();
  println(ys);
  translate(0, -ymove);
  rotate(M.x/M.r); // theta = s/r;
  M.show(t);
  M.move(dx);
  popMatrix(); 
  //--------------------
  keyControl(); // keyControl
}
void mouseDragged() {
  t = int(constrain((map(mouseX, 0, width, 3, 100)), 3, 100));
}

class Morph {
  float x, y, r, dx, theta, rm, d;
  Morph() {
    r = 30;
    rm = 6;
    dx=0;
    d=0;
  }

  void show(int edges) {
    noStroke();
    fill(#9AFF29);
    beginShape();
    for (int i=0; i<edges; i++) {
      float xm = r*sin(i*theta);
      float ym = r*cos(i*theta);
      vertex(xm, ym);
    }
    endShape(CLOSE);
    theta = TWO_PI/edges;
    float x2 = (r-rm)*cos(theta);
    float y2 = (r-rm)*sin(theta);
    fill(0);
    ellipse(x2, y2, rm/4, rm/4);
    ellipse(0, 0, rm, rm);
  }

  void move(float dx) {
    x+=dx;
  }
}

//--------------------------
boolean left = false, right=false;
void keyPressed() {
  if (t>2) {
    if (key==CODED)
    {
      if (keyCode == LEFT) left = true;
      else if (keyCode==RIGHT) right = true;
    }
  } else {
    left = false;
    right = false;
  }
}

void keyReleased() {
  left = false;
  right = false;
}

//-------keyControl---------
void keyControl() {
  if (left) dx-=0.1f;
  else if (right)dx+=0.1f;
  else {
    if (dx>0) {
      dx-=0.1f;
      if (dx<0)dx=0;
    } else if (dx<0) {
      dx+=0.1f;
      if (dx>0)dx=0;
    }
  }
  if (dx>15)dx=15.0f; // set max speed +x dir
  if (dx<-15)dx=-15.0f; // set max speed -x dir
  //println(dx + " " + t);
}

Answers

  • Answer ✓

    If you want to keep the polygon in contact with the road then don't rotate about the centre 360 degrees.

    Instead rotate 360/nbrSides degrees about the point in contact with the ground, when the polygon has 2 points in contact with the ground shift the rotation point to the new point in contact i.e. left or right depending on which direction you are traveling.

  • Answer ✓

    Depending on what you need this for, you might consider using a physics engine. If you're just moving around a few shapes then that's probably overkill, but if you have a bunch of arbitrary polygons that you want to behave realistically, there are libraries that handle that for you: https://github.com/shiffman/Box2D-for-Processing

  • @Quark Thank you :) I have thought about that but the only problem I found that it would not look like that it is rotating. The rotation would not look like animated instead it would look like mechanical.

    @KevinWorkman Thank you :) Actually I am trying to move this on a 2D terrain and I dont want to use any library. I thought this issue I would deal later but I am also facing problem moving on a terrain. I was trying to move a ciricle on randomly generated 2D terrain but it is not happening.

    Something like this but it not working well

    ArrayList<PVector> poop  = new ArrayList();
    void setup() {
      size(400, 300);
      for (int i=0; i<width; i+=20) {
        PVector P = new PVector(i, noise(i)*100);
        poop.add(P);
      }
    }
    void draw() {
      background(-1);
      translate(0, height/2);
      beginShape();
      for (int i=0; i<poop.size (); i++) {
        PVector P = poop.get(i);
        vertex(P.x, P.y);
        if (P.x<0) {
          poop.remove(0);
          PVector Pnew = new PVector(width, noise(random(40))*30);
          poop.add(Pnew);
        }
        P.x--;
      }
      endShape();
    
      ellipse(width/2, poop.get(poop.size()/2).y-20, 40, 40);
    }
    
  • Answer ✓

    Quark's idea can still be made to look animated, just don't give it a constant rotation.

    Every time the point of rotation changes make the rotation start fast and then slow down as it reaches the halfway point. After it passes the halfway point make it speed up again to give the illusion of gravity

  • Answer ✓

    I am trying to move this on a 2D terrain and I dont want to use any library. I thought this issue I would deal later but I am also facing problem moving on a terrain. I was trying to move a ciricle on randomly generated 2D terrain but it is not happening.

    Why don't you want to use any libraries? This sounds like a perfect place to use a physics library.

  • Answer ✓

    Are you trying to move a circle or a polygon?

    Is the 2D terrain a straight line or rough line or something else?

    Your first post indicated a polygon on a smooth serface but now you appear to have moved to a circle on a rough surface. Please state the problem more clearly.

  • edited July 2014 Answer ✓

    the problem you originally posted can be solved with sin/cos and a bit of time (which i happened to have)

    i tried to leave most your code intact and only added some calculations to figure out the correct rotation alpha and y offset dY for a specified x position xBar.

    // hansi raber/ asdfg.me / 2014 for forum.processing.org
    // released as WTFPL
    // please keep credits
    
    int N=3; // num edges
    int R = 50; // radius of surrounding circle
    
    void setup()
    {
      size(400, 300);
    }
    
    void draw()
    {
      background(255);
      stroke( 0 ); 
      float y = height - 30; 
      line(0, y, width, y);
      translate(width/2, y);
      if (mousePressed==true) N = (int)map(mouseX, 0, width, 3, 20);
    
      float innerAngle = PI-TWO_PI/N; 
      float deltaX = 2*R*cos(innerAngle/2); 
      float xBar = mouseX-width/2; 
      float xTilde = deltaX*floor(xBar/deltaX+0.5);
      float D = xBar - xTilde;
      float alpha = acos( D/R );   
      float dY = sqrt( R*R - D*D );   
      text( floor(xBar/deltaX+0.5) + "/" + xTilde + "/" + D + "/" + alpha, 10, 10 ); 
      noStroke(); 
      fill( 255, 0, 0 ); 
      ellipse( xTilde, 0, 5, 5 ); 
      fill( 0, 255, 0 ); 
      ellipse( xBar, 0, 5, 5 ); 
    
      stroke( 0 ); 
      pushMatrix(); 
      translate( xTilde+D, -dY ); 
      rotate( PI/2-alpha );  
      polygon(N, R);
      popMatrix(); 
    
    }
    
    void polygon(int edges, int r) {
      noFill();
      beginShape();
      for (int i=0; i<edges; i++) {
        float x = r*sin(i*TWO_PI/edges);
        float y = r*cos(i*TWO_PI/edges);
        vertex(x, y);
      }
      endShape(CLOSE);
      ellipse(0, 0, 2, 2);
    }
    

    here's a sketch "explaining" the variable names: polyrot

    ps. the walking stick (setting N = 2) is great fun!

  • Answer ✓

    pps. try it out for yourself here http://superduper.org/processing/polywalk/

  • edited August 2014

    @kritzikratzi Thanks you so much man .... I'll take it from here :) :)

    @Qurak... I am really sorry for not begin clear :( :( I was trying to start with something simple

    1. I was trying to move a polygon on a straight line then I would make it move on a 2D terrain.
    2. For testing I was trying to move a circle on a 2D terrain then I though I woud replace it with a polygon.

    but none of them working :( sadly :(

    @kevinWorkMan I always try to avoid libraries because of their plasticity. I want to create my own custom classes and function using my custom algorithms. I work hard on algorithm part as you see I am really poor in that. :( :( I belive that "more I code , more I learn" but thank for helping me out

  • I belive that "more I code , more I learn"

    Absolutely true :)

    Fluency with language syntax is a secondary skill compared with the ability to create algorithms to solve problems like this. So go for it :)>-

  • I always try to avoid libraries because of their plasticity. I want to create my own custom classes and function using my custom algorithms.

    Fair enough. But there is something to be said for not reinventing the wheel every time you have to drive to the supermarket, as well.

Sign In or Register to comment.