How to rotate many 3D planes around their center along the Y axis

edited January 2014 in How To...

Hi, I want to rotate many 3D planes around their center along the Y axis. My idea is to translate each plane into the center of the screen, rotate them along Y axis and then translate them to their right place. But after the rotation all the axes are rotated and I cannot figure how to translate the planes correctly. Any idea? Is it possible to remove perspective?

Thanks, paolofuse

Answers

  • edited January 2014

    You didn't mention it, but I'm going to assume that the planes all have their normal pointing along the y-axis. If they don't then after you translate them to the origin you would have to first rotate them to align that way. Edit: In other words I am assuming that the planes exist on the xz-plane. If they don't they will still spin on the y-axis which will make them look "tilted" while spinning

    Assuming that their normals point along the y-axis:
    - Take each of the 4 corner points, use them to find the plane's center (the average of the 4 point's positions), and translate all 4 to the origin using the plane's center. None of the points will actually be at the origin, the center of the plane will be there
    - Rotate all 4 points along the y-axis
    - Translate all 4 points back using the plane's center position - Repeat these steps for the other planes

  • Here is an example in 2D, you could think of it as looking down on the planes from above to relate it to yours:

    PVector[] p = new PVector[4];
    
    void setup() {
      size(600, 600);
      noFill();
      p[0] = new PVector(300, 300);
      p[1] = new PVector(500, 300);
      p[2] = new PVector(500, 400);
      p[3] = new PVector(300, 400);
    }
    
    void draw() {
      background(-1);
    
      PVector c = new PVector(0, 0);
      for (int i = 0; i < 4; i++) c.add(p[i]);
      c.div(4.0);
    
      float theta = radians(frameCount*0.1);
      for (int i = 0; i < 4; i++) {
        p[i].sub(c);
        float pX = p[i].x*cos(theta)-p[i].y*sin(theta);
        float pY = p[i].x*sin(theta)+p[i].y*cos(theta);
        p[i].x = pX;
        p[i].y = pY;
        p[i].add(c);
      }
      ellipse(c.x, c.y, 10, 10);
    
      beginShape();
      for (int i = 0; i < 4; i++) vertex(p[i].x, p[i].y);
      endShape(CLOSE);
    }
    
  • edited January 2014

    Tweaked the answer a little in order to understand how it works. But it's beyond me! :(
    Anyways, gonna post my exercise anyways as an alternative: ;;)

    /** 
     * Rotate Around (v2.1)
     * by  Asimes (2014/Jan)
     * mod GoToLoop
     *
     * forum.processing.org/two/discussion/2619/
     * how-to-rotate-many-3d-planes-around-their-center-along-the-y-axis
     */
    
    static final float SPD = .1;
    static final int NUM = 4, DIM = 20, OFFSET = 150;
    
    final PVector[] p = new PVector[NUM];
    final PVector c = new PVector();
    
    void setup() {
      size(600, 400);
      frameRate(60);
      smooth(4);
    
      noFill();
      stroke(0);
      strokeWeight(1.5);
    
      p[0] = new PVector(OFFSET, OFFSET);
      p[1] = new PVector(width - OFFSET, OFFSET);
      p[2] = new PVector(width - OFFSET, height - OFFSET);
      p[3] = new PVector(OFFSET, height - OFFSET);
    }
    
    void draw() {
      background(-1);
    
      c.set(p[0]);
      for ( int i = 0; ++i != NUM; c.add(p[i]) );
      c.div(NUM);
    
      ellipse(c.x, c.y, DIM, DIM);
    
      final float theta = radians(frameCount*SPD);
      final float sine = sin(theta), csin = cos(theta);
      int i = -1;
    
      beginShape();
    
      while (++i != NUM) {
        p[i].sub(c);
    
        final float px = p[i].x*csin - p[i].y*sine;
        final float py = p[i].x*sine + p[i].y*csin;
    
        p[i].set(px, py);
        p[i].add(c);
    
        vertex(p[i].x, p[i].y);
      }
    
      endShape(CLOSE);
    }
    
  • Hi asimes, what you told in your first pot is correct. I need to rotate along Y axis, so what I need is to TILT my planes. It's easy to do if I translate a plane into the center, but I need to rotate each plane around its Y axis. Thanks.

  • edited January 2014

    The same code will produce that effect, I just pointed out that it would happen because I was not sure if it was desirable. Edit: Normally an additional rotation step is necessary to avoid this effect

    The example I posted is in 2D and performs a rotation around the z-axis because we are looking at x and y in 2D. If you were to replace all of the code that affects y with z then it would cause a rotation around the y-axis.

  • Answer ✓

    Here, I thought I'd make a 3D version incase my explanation was not clear enough:

    PVector[] p = new PVector[4];
    float theta;
    
    void setup() {
      size(600, 600, P3D);
      noFill();
      p[0] = new PVector(0, -100, -100);
      p[1] = new PVector(0, -100, 100);
      p[2] = new PVector(200, 100, 100);
      p[3] = new PVector(200, 100, -100);
      theta = TWO_PI/360.0;
    }
    
    void draw() {
      background(-1);
      translate(width/2, height/2);
    
      // The box is at the origin, shown for reference
      box(10);
    
      PVector c = new PVector(0.0, 0.0, 0.0);
      for (int i = 0; i < 4; i++) c.add(p[i]);
      c.div(4.0);
    
      for (int i = 0; i < 4; i++) {
        p[i].sub(c);
        float pX = p[i].x*cos(theta)-p[i].z*sin(theta);
        float pZ = p[i].x*sin(theta)+p[i].z*cos(theta);
        p[i].x = pX;
        p[i].z = pZ;
        p[i].add(c);
      }
    
      beginShape();
      for (int i = 0; i < 4; i++) vertex(p[i].x, p[i].y);
      endShape(CLOSE);
    }
    
  • @GoToLoop, When a rotation is performed it rotates an object around the origin. If the plane was not translated so that its center was at the origin then it would fly around all over the place.

    The first step of the for loop moves the plane so that its center is at the origin (p[i].sub(c)). Then the math for a rotation about the desired axis (the z-axis in the 2D sketch and the y-axis in the 3D sketch). Finally the plane is translated back to where it should be after being rotated (p[i].add(c)).

    The problem with doing this using Processing's translate() / rotate() functions is that the coordinate system has changed and so translating the plane back where it belongs after the rotation is not very straightforward.

  • seasea
    edited January 2014

    I have sаme trouble.

    Is it possible to remove perspective?

    I think you have to use beginCamera() and endCamera() function, but I'm not sure... http://www.processing.org/reference/beginCamera_.html

  • seasea
    edited February 2014

    Hi. My friend help me. this is virtual screens

    PGraphics screen1, screen2;
    
    void setup() {
      size(700, 700, P3D);
    
      screen1 = createGraphics(200, 200, P3D);
      screen2 = createGraphics(200, 200, P3D);
    }
    
    void draw() { 
      drawInsideScreen1();
      drawInsideScreen2();
      drawScreens();
    }
    
    void drawInsideScreen1() {
      screen1.beginDraw();
      screen1.background(255,0,0);
      screen1.translate(screen1.width/2, screen1.height/2);  
      screen1.box(50);
      screen1.endDraw();
    }
    
    void drawInsideScreen2() {
      screen2.beginDraw();
      screen2.background(0,255,0);
      screen2.translate(screen2.width/2, screen2.height/2);
      screen2.box(50);
      screen2.endDraw();
    }
    
    void drawScreens() {
      image(screen1, 100 - screen1.width/2, 100 - screen1.height/2);
      image(screen2, 500 - screen2.width/2, 500 - screen2.height/2);
    }
    
    //void drawCenteredBox(PVector position, PVector size) {
    //  camera(position.x, position.y, (height/2.0) / tan(PI*30.0 / 180.0), position.x, position.y, 0, 0, 1, 0);
    //  pushMatrix();
    //  translate(position.x, position.y);
    //  //rotateY(PI/4);
    //  box(100);
    //  popMatrix();
    //}
    
Sign In or Register to comment.