1
$\begingroup$

I have coordinates for 4 vertices/points that define a plane and the normal/perpendicular. The plane has an arbitrary rotation applied to it.

How can I 'un-rotate'/translate the points so that the plane has rotation 0 on x,y,z ?

I've tried to get the plane rotation from the plane's normal:

rotationX = atan2(normal.z,normal.y); rotationY = atan2(normal.z,normal.x); rotationZ = atan2(normal.y,normal.x); 

Is this correct ?

How do I apply the inverse rotation to the position vectors ?

I've tried to create a matrix with those rotations and multiply it with the vertices, but it doesn't look right.

At the moment, I've wrote a simple test using Processing and can be seen here:

float s = 50.0f;//scale/unit PVector[] face = {new PVector(1.08335042,0.351914703846,0.839020013809), new PVector(-0.886264681816,0.69921118021,0.839020371437), new PVector(-1.05991327763,-0.285596489906,-0.893030643463), new PVector(0.909702301025,-0.63289296627,-0.893030762672)}; PVector n = new PVector(0.150384, -0.500000, 0.852869); PVector[] clone;  void setup(){   size(400,400,P3D);   smooth();   clone = unRotate(face,n,true); }  void draw(){   background(255);   translate(width*.5,height*.5);   if(mousePressed){     rotateX(map(mouseY,0,height,0,TWO_PI));     rotateY(map(mouseX,0,width,0,TWO_PI));   }   stroke(128,0,0);   beginShape(QUADS);     for(int i = 0 ; i < 4; i++) vertex(face[i].x*s,face[i].y*s,face[i].z*s);   endShape();   stroke(0,128,0);   beginShape(QUADS);     for(int i = 0 ; i < 4; i++) vertex(clone[i].x*s,clone[i].y*s,clone[i].z*s);   endShape();  } //get rotation from normal PVector getRot(PVector loc,Boolean asRadians){   loc.normalize();   float rz = asRadians ? atan2(loc.y,loc.x) : degrees(atan2(loc.y,loc.x));   float ry = asRadians ? atan2(loc.z,loc.x) : degrees(atan2(loc.z,loc.x));   float rx = asRadians ? atan2(loc.z,loc.y) : degrees(atan2(loc.z,loc.y));   return new PVector(rx,ry,rz); } //translate vertices PVector[] unRotate(PVector[] verts,PVector no,Boolean doClone){   int vl = verts.length;   PVector[] clone;   if(doClone) {     clone = new PVector[vl];     for(int i = 0; i

Any syntax/pseudo code or explanation is useful.

What trying to achieve is this: If I have a rotated plane: rotated plane

How can move the vertices to have something that would have no rotation: plane with no rotations

Thanks!

UPDATE:

@muad

I'm not sure I understand. I thought I was using matrices for rotations. PMatrix3D's rotateX,rotateY,rotateZ calls should done the rotations for me. Doing it manually would be declaring 3d matrices and multiplying them. Here's a little snippet to illustrate this:

 PMatrix3D rx = new PMatrix3D(1,          0,          0,  0,                                0, cos(rot.x),-sin(rot.x),  0,                                0, sin(rot.x),cos(rot.x) ,  0,                                0,          0,          0,  1);   PMatrix3D ry = new PMatrix3D(cos(rot.y), 0,sin(rot.y),  0,                                         0, 1,0         ,  0,                               -sin(rot.y), 0,cos(rot.y),  0,                                         0, 0,0         ,  1);   PMatrix3D rz = new PMatrix3D(cos(rot.z),-sin(rot.z), 0, 0,                                sin(rot.z), cos(rot.z), 0, 0,                                0         ,          0, 1, 0,                                0         ,          0, 0, 1);   PMatrix3D r = new PMatrix3D();   r.apply(rx);r.apply(ry);r.apply(rz);    //test   PMatrix rmat = new PMatrix3D();rmat.rotateX(rot.x);rmat.rotateY(rot.y);rmat.rotateZ(rot.z);   float[] frmat = new float[16];rmat.get(frmat);   float[] fr    = new float[16];r.get(fr);   println(frmat);println(fr);  /* Outputs: [0] 0.059300933 [1] 0.09312407 [2] -0.99388695 [3] 0.0 [4] 0.90466285 [5] 0.41586864 [6] 0.09294289 [7] 0.0 [8] 0.42198166 [9] -0.9046442 [10] -0.059584484 [11] 0.0 [12] 0.0 [13] 0.0 [14] 0.0 [15] 1.0 [0] 0.059300933 [1] 0.09312407 [2] -0.99388695 [3] 0.0 [4] 0.90466285 [5] 0.41586864 [6] 0.09294289 [7] 0.0 [8] 0.42198166 [9] -0.9046442 [10] -0.059584484 [11] 0.0 [12] 0.0 [13] 0.0 [14] 0.0 [15] 1.0  */ 
  • 0
    @Rahul Thank you for the explanation. The axis-aligned green quadrilateral is what I want.2010-09-23

3 Answers 3

2

From your comments, what I understand of your problem is that you have the coordinates of an arbitrarily oriented rectangle centred on the origin, and you want to find the rotation that will bring it to an axis-aligned rectangle on the $xy$ plane.

Let $u$ and $v$ be the unit vectors that should be mapped to the axis-oriented unit vectors $e_x$ and $e_y$ respectively. You can get these by subtracting adjacent points of the rectangle and normalizing. Then you want a rotation $R$ which satisfies $Ru = e_x$, $Rv = e_y$, and $Rn = e_z$.

You can express this as $R[u\;v\;n] = [e_x\;e_y\;e_z] = I$. Then $R$ equals $[u\;v\;n]^{-1}$, which is simply $[u\;v\;n]^T$ since $u$, $v$, and $n$ are an orthonormal set. To be more explicit, the rotation matrix you want is: $R = \begin{bmatrix}u_x & u_y & u_z \\ v_x & v_y & v_z \\ n_x & n_y & n_z\end{bmatrix}.$ If you really like Euler angles (rotateX, rotateY, rotateZ), there are ways to convert a rotation matrix like above to Euler angles, but they're ugly. You're best off using the rotation matrix explicitly.

By the way, if your rectangle is not centred on the origin, and you want to perform the rotation keeping its centre (say $c$) fixed, you'll have to get the rotated coordinates of a point $p$ not simply as $Rp$ but as $R(p-c) + c$.

  • 0
    @Rahul Thank you, I understand the difference between "plane" and "quadrilateral". I don't want to to rotate a paralellogram and turn it into a rectangle - I want to rotate a quadrilateral that has an arbitrary rotation on x,y,z so it's in the xy plane(and could be drawn in 2d). Imagine a piece of paper(rectangular, arbitrary clipping) that is rotated in 3d space. I want to rotate it so it's aligned to the xy plane(could be xz,yz, as long as it sits flat in one 'orthonormal' plane). It is an abritrary quadrilateral :(2010-10-06
1

Try to represent rotations using matrices instead of angles - then finding the inverse is easy.

  • 1
    No I am not suggesting to use Euler angles.2010-10-03
0

At the moment, I went with a somewhat simple solution that allows me to draw a plane/face with 4 vertices with arbitrary rotations, in 2D:

Here's how it works:

PVector[] unRotateVerts(PVector[] verts,PVector n){   //get the angle between the face4 normal and Y   angle = PVector.angleBetween(n,y);//acos(n.dot(y));   //get the axis of rotation, by getting the perpendicular   axis = n.cross(y);   axis.normalize();   //clone vertices   int vl = verts.length;   PVector[] clone = new PVector[vl];   for(int i = 0; i

This works perfectly for aligning with XZ, but rotations on the Z axis are still there. Any hints on how to remove that would be handy.