#### Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

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

edited January 2014

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

Tagged:

• 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;

void setup() {
size(600, 600);
noFill();
p = new PVector(300, 300);
p = new PVector(500, 300);
p = new PVector(500, 400);
p = 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);

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;
}
ellipse(c.x, c.y, 10, 10);

beginShape();
for (int i = 0; i < 4; i++) vertex(p[i].x, p[i].y);
endShape(CLOSE);
}
``````
• 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 = new PVector(OFFSET, OFFSET);
p = new PVector(width - OFFSET, OFFSET);
p = new PVector(width - OFFSET, height - OFFSET);
p = new PVector(OFFSET, height - OFFSET);
}

void draw() {
background(-1);

c.set(p);
for ( int i = 0; ++i != NUM; c.add(p[i]) );
c.div(NUM);

ellipse(c.x, c.y, DIM, DIM);

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

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.

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

``````PVector[] p = new PVector;
float theta;

void setup() {
size(600, 600, P3D);
noFill();
p = new PVector(0, -100, -100);
p = new PVector(0, -100, 100);
p = new PVector(200, 100, 100);
p = 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;
}

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.

• 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

• 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();
//}
``````