Hi
How could I compute transformation matrix around arbitrary axis for a point cloud? There is many useful resources like below but I could not realize them. "(1) Translate space so that the rotation axis passes through the origin. (2) Rotate space about the z axis so that the rotation axis lies in the xz plane. (3) Rotate space about the y axis so that the rotation axis lies along the z axis. (4) Perform the desired rotation by θ about the z axis. (5) Apply the inverse of step (3). (6) Apply the inverse of step (2). (7) Apply the inverse of step (1)." I have point cloud generated by a custom made scanner. I am rotating the object around 2 axis (ZX) but of course rotation axises are not aligned to center of the sensor. I could not apply steps 2 and 3. Lets say sensor coords are (xs, ys, zs) = [0 ,0, 0} I have point coordinates (xi, yi, zi) and the rotation axis center (xr, yr, zr). After translate point coordinates to (xr,yr,zr) how will I apply rotation around (zr)? Is there any module or Eigen method? -- Mehmet Akif Ceylan
05375918497 _______________________________________________ [hidden email] / http://pointclouds.org http://pointclouds.org/mailman/listinfo/pcl-users |
given point P_i
Rotation center C Rotation Axis A and angle theta The algorithm for getting the rotated point P_j is P_j = Rotate(P_i-C,A,theta)+C Where Rotate(X,A,theta) can be steps 2,3,4,3^-1,2^-1 but can instead be a quaternion rotation. The resource you linked uses matrices, which depending on who you ask can give you very different results as people don't seem to agree in what order rotations get applied, as well as suffer from gimbal lock. A quaternion is better because it was literally made for your problem, the quaternion 'q' in your case would be q=(A.x*sin(theta),A.y*sin(theta),A.z*sin(theta),cos(theta)) assuming you are using quaternions with the cos(rotationRadians) in the W component of a 4D vector. You can google 'quaternion 3d point rotation formula' for how to rotate a point by a quaternion. NOTE: with a quaternion the rotation still takes place around the origin! On 02/05/18 22:51, Mehmet Akif Ceylan wrote: > Hi > > How could I compute transformation matrix around arbitrary axis for a > point cloud? > There is many useful resources like below but I could not realize them. > https://sites.google.com/site/glennmurray/Home/rotation-matrices-and-formulas/rotation-about-an-arbitrary-axis-in-3-dimensions > > "(1) Translate space so that the rotation axis passes through the origin. > (2) Rotate space about the z axis so that the rotation axis lies in the > xz plane. > (3) Rotate space about the y axis so that the rotation axis lies along > the z axis. > (4) Perform the desired rotation by θ about the z axis. > (5) Apply the inverse of step (3). > (6) Apply the inverse of step (2). > (7) Apply the inverse of step (1)." > > I have point cloud generated by a custom made scanner. I am rotating the > object around 2 axis (ZX) but of course rotation axises are not aligned > to center of the sensor. > I could not apply steps 2 and 3. > > Lets say sensor coords are (xs, ys, zs) = [0 ,0, 0} > I have point coordinates (xi, yi, zi) and the rotation axis center (xr, > yr, zr). > After translate point coordinates to (xr,yr,zr) how will I apply > rotation around (zr)? > > Is there any module or Eigen method? > > > -- > Mehmet Akif Ceylan > 05375918497 > > > _______________________________________________ > [hidden email] / http://pointclouds.org > http://pointclouds.org/mailman/listinfo/pcl-users > [hidden email] / http://pointclouds.org http://pointclouds.org/mailman/listinfo/pcl-users |
Thank you very much DevSH
I will work on quaternions. For Euler solution... I should calculate a vector from every point to rotation center and compute a new transformation matrix or at least rotation matrix according to given solution I think, right? Or finding a centroid for the cloud and calculating one transformation matrix to apply all the points in it will work? -- Sent from: http://www.pcl-users.org/ _______________________________________________ [hidden email] / http://pointclouds.org http://pointclouds.org/mailman/listinfo/pcl-users |
Essentially all rotation is mathematically defined to take place around
the origin (0,0,0) So you need to shift all the points by the difference between the center of rotation and the origin. Then perform the rotation, and shift back by the same amount. On 03/05/18 00:28, meakcey wrote: > Thank you very much DevSH > > I will work on quaternions. > > For Euler solution... > I should calculate a vector from every point to rotation center and compute > a new transformation matrix or at least rotation matrix according to given > solution I think, right? > Or finding a centroid for the cloud and calculating one transformation > matrix to apply all the points in it will work? > > > > -- > Sent from: http://www.pcl-users.org/ > _______________________________________________ > [hidden email] / http://pointclouds.org > http://pointclouds.org/mailman/listinfo/pcl-users > [hidden email] / http://pointclouds.org http://pointclouds.org/mailman/listinfo/pcl-users |
In reply to this post by meakcey
I was attempting to do the same thing earlier this week. Essentially what you
need to do is get the transformation matrix that transforms the vector onto the z-axis. Then you rotate about the z-axis by the amount that you want. Finally you undo all of the transformations to get the vector back into its original plane (this 'undoing' is done by multiplying by the inverse matrix of the original transform). Here is a snippet of code that has this rotation about an arbitrary vector working. Eigen::Matrix4f transformationMatrix(double theta, Eigen::Vector3f rotVector, pcl::PointXYZ rotVectOrigin){ Eigen::Matrix4f step1 = Eigen::Matrix4f::Identity(); Eigen::Matrix4f step2 = Eigen::Matrix4f::Identity(); Eigen::Matrix4f step3 = Eigen::Matrix4f::Identity(); Eigen::Matrix4f step4 = Eigen::Matrix4f::Identity(); //Step1: transform the origin point so that it sits at the world frame origin Eigen::Matrix4f transformation = Eigen::Matrix4f::Identity(); step1(0, 3) = -rotVectOrigin.x; step1(1, 3) = -rotVectOrigin.y; step1(2, 3) = -rotVectOrigin.z; //Step2: rotate space about the x axis so that the rotation axis lies in the xz plane rotVector.normalize(); double length = std::sqrt(pow(rotVector[1], 2) + pow(rotVector[2], 2)); //gets the length of the projection of the unit vector onto the yz plane step2(1, 1) = rotVector[2] / length; step2(1, 2) = -rotVector[1] / length; step2(2, 1) = rotVector[1] / length; step2(2, 2) = rotVector[2] / length; //Step3: rotate space about the y axis so that the rotation axis lies along the z axis step3(0, 0) = length; step3(0, 2) = -rotVector[0]; step3(2, 0) = rotVector[0]; step3(2, 2) = length; //Step4: perform desired rotation about the z axis step4(0, 0) = cos(theta); step4(0, 1) = -sin(theta); step4(1, 0) = sin(theta); step4(1, 1) = cos(theta); //final step multiplies all of these transformations and then inverts them to get it back into the same plane return (step1.inverse()*step2.inverse()*step3.inverse()*step4*step3*step2*step1); } -- Sent from: http://www.pcl-users.org/ _______________________________________________ [hidden email] / http://pointclouds.org http://pointclouds.org/mailman/listinfo/pcl-users |
Eigen has quaternion rotation routines, I strongly advise to use them.
Such a formulation mathematically and logically clearer. On 07/05/18 22:02, cjlark wrote: > I was attempting to do the same thing earlier this week. Essentially what you > need to do is get the transformation matrix that transforms the vector onto > the z-axis. Then you rotate about the z-axis by the amount that you want. > Finally you undo all of the transformations to get the vector back into its > original plane (this 'undoing' is done by multiplying by the inverse matrix > of the original transform). > > Here is a snippet of code that has this rotation about an arbitrary vector > working. > > Eigen::Matrix4f transformationMatrix(double theta, Eigen::Vector3f > rotVector, pcl::PointXYZ rotVectOrigin){ > > Eigen::Matrix4f step1 = Eigen::Matrix4f::Identity(); > Eigen::Matrix4f step2 = Eigen::Matrix4f::Identity(); > Eigen::Matrix4f step3 = Eigen::Matrix4f::Identity(); > Eigen::Matrix4f step4 = Eigen::Matrix4f::Identity(); > > //Step1: transform the origin point so that it sits at the world frame > origin > Eigen::Matrix4f transformation = Eigen::Matrix4f::Identity(); > step1(0, 3) = -rotVectOrigin.x; > step1(1, 3) = -rotVectOrigin.y; > step1(2, 3) = -rotVectOrigin.z; > > //Step2: rotate space about the x axis so that the rotation axis lies in > the xz plane > rotVector.normalize(); > double length = std::sqrt(pow(rotVector[1], 2) + pow(rotVector[2], 2)); > //gets the length of the projection of the unit vector onto the yz plane > step2(1, 1) = rotVector[2] / length; > step2(1, 2) = -rotVector[1] / length; > step2(2, 1) = rotVector[1] / length; > step2(2, 2) = rotVector[2] / length; > > //Step3: rotate space about the y axis so that the rotation axis lies along > the z axis > step3(0, 0) = length; > step3(0, 2) = -rotVector[0]; > step3(2, 0) = rotVector[0]; > step3(2, 2) = length; > > //Step4: perform desired rotation about the z axis > step4(0, 0) = cos(theta); > step4(0, 1) = -sin(theta); > step4(1, 0) = sin(theta); > step4(1, 1) = cos(theta); > > //final step multiplies all of these transformations and then inverts them > to get it back into the same plane > return > (step1.inverse()*step2.inverse()*step3.inverse()*step4*step3*step2*step1); > > } > > > > -- > Sent from: http://www.pcl-users.org/ > _______________________________________________ > [hidden email] / http://pointclouds.org > http://pointclouds.org/mailman/listinfo/pcl-users > [hidden email] / http://pointclouds.org http://pointclouds.org/mailman/listinfo/pcl-users |
Free forum by Nabble | Edit this page |