Rotation of Point in 3D Space - algorithm

I have one problem related to rotation of point in 3D-space.
Suppose I have one point with X, Y and Z coordinates.
And now I want to rotate it, by specifying the rotation in one of these three ways:
By user-defined degree
By user-defined axis of rotation
Around (relative to) user-defined point
I found good link over here, but it doesn't address point 3. Can anyone help me solve that?

All rotations will go around the origin. So you translate to the origin, rotate, then translate back.
T = translate from global coordinates to user-coordinates
R = rotate around the origin (like in your link)
(T^-1) = translate back
point X
X_rotated = (T^-1)*R*T*X
If you have multiple points to rotate then multiply the matrices together:
A = (T^-1)*R*T
X_rotated = A*X

Related

Rotate line around center

I have to use a propriertary graphics-engine for drawing a line. I can rotate the whole drawing by its origin point (P1). What I want, is to rotate it around its center point(M). So basically that it looks like L_correct instead of L_wrong.
I think, it should be possible to correct it, by moving it from P1 to P2. But I cannot figure out what formula could be used, to determine the distance. It must probably involve the angle, width and height...
So basically my question is, if there is a function to determine x2 and y2 based on my available data?
Let's assume you have a primitive method that rotates a drawing by any given angle phi. What you want is to use that primitive to rotate a drawing D around a point M instead. Here is a sketch of how to proceed.
Translate you drawing by -M, i.e., apply the transformation T(P) = P - M to all points P in your drawing. Let T(D) be the translation of D.
Now use the primitive to rotate T(D) by the desired angle phi. Let R(T(D)) be the result.
Now translate the previous result by M and get the rotated drawing. In other words, use the transformation T'(P) = P + M.
Note that in step 1 above M is mapped to the origin 0, where the rotation primitive is known to work. After rotating in step 2, the opposite translation of step 3 puts back the drawing on its original location as this time 0 is mapped to M.

Resetting only one rotation axis

I would like to find a solution for taking a rotation represented as a matrix and then resetting one of it's components. Basically I want to be able to multiply a vector by this matrix and get a direction that is rotation around x and z axis and be constant along the y axis (up). I want to take object rotation and get the vector that represents gravity but in object local space and disregarding the yaw. So I want to reset the yaw.
I don't want to convert this to euler angles. I would prefer using a quaternion or doing some sequence of operations on the rotation matrix directly in order to avoid possible bugs with certain angles.
Ok, so I have the follwoing:
btTransform t;
mBody->getMotionState()->getWorldTransform(t);
btMatrix3x3 trans = t.getBasis().inverse();
btVector3 up = (trans * btVector3(0, 1, 0));
I realized that if I used quaternion then I got completely wrong results (why?). Now I'm getting a vector in object space that represents up vector in world space. BUT I want to rotate this vector so that it represents global up vector in object space WHEN MODEL HAS ZERO rotation around Y axis. So I have to somehow rotate this vector back. How?
You can use quaternion swing twist decomposition with passed "Y" axis. It will decompose quaternion to rotation around Y axis and rotation around axis that is perpendicular to Y.
It is described here, in my answer.
Component of a quaternion rotation around an axis

Rotate Transformation and Keep in Range

I have a transformation in Java:
AffineTransform transform = new AffineTransform();
transform.translate(x, y);
transform.rotate(Math.toRadians(rotation));
transform.translate(-x, -y);
I'm using it on four points that make up a rectangle. The transformation rotates around the origin (x, y) as expected, but I want the most left point to stay where the origin x was, and the most top point to stay where the origin y was.
Any ideas how to modify the transformation to achieve this?
I solved this by searching through all the points, finding the extreme left point, and the extreme upper point, and then offsetting all the points in the transformation by these coordinates. It's really messy though, so if anyone happens to have a better solution, I'm all ears.

How do you map a point(x,y) on a 2D image to 3D space? (illustration provided)

I have a stack of images (about 180 of them) and there are 2 stars (just basic annotations) on every single image. Hence, the position (x,y) of the two stars are provided initially. The dimensions of all these images are fixed and constant.
The 'distance' between the image is about 1o with the origin to be the center (width/2, height/2) of every single 2D image. Note that, if this is plotted out and interpolated nicely, the stars would actually form a ring of an irregular shape.
The dotted red circle and dotted purple circle are there to give a stronger scent of a 3D space and the arrangement of the 2D images (like a fan). It also indicates that each slice is about 1o apart.
With the provided (x,y) that appeared in the 2D image, how do you get the corresponding (x,y,z) in the 3d space knowing that each image is about 1o apart?
I know that MATLAB had 3D plotting capabilities, how should I go about implementing the solution to the above scenario? (Unfortunately, I have very little experience plotting 3D with MATLAB)
SOLUTION
Based on the accepted answer, I looked up a bit further: spherical coordinate system. Based on the computation of phi, rho and theta, I could reconstruct the ring without problems. Hopefully this helps anyone with similar problems.
I have also documented the solution here. I hope it helps someone out there, too:
http://gray-suit.blogspot.com/2011/07/spherical-coordinate-system.html
I believe the y coordinate stays as is for 3D, so we can treat this as converting 2D x and image angle to an x and z when viewed top down.
The 2D x coordinate is the distance from the origin in 3D space (viewed top down). The image angle is the angle the point makes with respect to the x axis in 3D space (viewed top down). So the x coordinate (distance from orign) and the image angle (angle viewed top down) makes up the x and z coordinates in 3D space (or x and y if viewed top down).
That is a polar coordinate.
Read how to convert from polar to cartesian coordinates to get your 3D x and z coordinates.
I'm not great at maths either, here's my go:
3D coords = (2Dx * cos(imageangle), 2Dy, 2Dx * sin(imageangle))
Given the 2D coordinates (x,y) just add the angle A as a third coordinate: (x,y,A). Then you have 3D.
If you want to have the Anotations move on a circle of radius r in 3D you can just calculate:
you can use (r*cos(phi),r*sin(phi),0) which draws a circle in the XY-plane and rotate it with a 3x3 rotation matrix into the orientation you need.
It is not clear from you question around which axis your rotation is taking place. However, my answer holds for a general rotation axis.
First, put your points in a 3D space, lying on the X-Y plane. This means the points have a 0 z-coordinate. Then, apply a 3D rotation of the desired angle around the desired axis - in your example, it is a one degree rotation. You could calculate the transformation matrix yourself (should not be too hard, google "3D rotation matrix" or similar keywords). However, MATLAB makes it easier, using the viewmtx function, which gives you a 4x4 rotational matrix. The extra (fourth) dimension is dependent on the projection you specify (it acts like a scaling coefficient), but in order to make things simple, I will let MATLAB use its default projection - you can read about it in MATLAB documentation.
So, to make the plot clearer, I assume four points which are the vertices of a square lying on the x-y plane (A(1,1), B(1,-1), C(-1,-1), D(1,-1)).
az = 0; % Angle (degrees) of rotation around the z axis, measured from -y axis.
el = 90; % Angle (degrees) of rotation around the y' axis (the ' indicates axes after the first rotation).
x = [1,-1, -1, 1,1]; y = [1, 1, -1, -1,1]; z = [0,0, 0, 0,0]; % A square lying on the X-Y plane.
[m,n] = size(x);
x4d = [x(:),y(:),z(:),ones(m*n,1)]'; % The 4D version of the points.
figure
for el = 90 : -1 :0 % Start from 90 for viewing directly above the X-Y plane.
T = viewmtx(az, el);
x2d = T * x4d; % Rotated version of points.
plot3 (x2d(1,:), x2d(2,:),x2d(3,:),'-*'); % Plot the rotated points in 3D space.
grid
xlim ([-2,2]);
ylim ([-2,2]);
zlim([-2,2]);
pause(0.1)
end
If you can describe your observation of a real physical system (like a binary star system) with a model, you can use particle filters.
Those filters were developed to locate a ship on the sea, when only one observation direction was available. One tracks the ship and estimates where it is and how fast it moves, the longer one follows, the better the estimates become.

Determine transformation matrix

As a followup to my previous question about determining camera parameters I have formulated a new problem.
I have two pictures of the same rectangle:
The first is an image without any transformations and shows the rectangle as it is.
The second image shows the rectangle after some 3d transformation (XYZ-rotation, scaling, XY-translation) is applied. This has caused the rectangle to look a trapezoid.
I hope the following picture describes my problem:
alt text http://wilco.menge.nl/application.data/cms/upload/transformation%20matrix.png
How do determine what transformations (more specifically: what transformation matrix) have caused this tranformation?
I know the pixel locations of the corners in both images, hence i also know the distances between the corners.
I'm confused. Is this a 2d or a 3d problem?
The way I understand it, you have a flat rectangle embedded in 3d space, and you're looking at two 2d "pictures" of it - one of the original version and one based on the transformed version. Is this correct?
If this is correct, then there is not enough information to solve the problem. For example, suppose the two pictures look exactly the same. This could be because the translation is the identity, or it could be because the translation moves the rectangle twice as far away from the camera and doubles its size (thus making it look exactly the same).
This is a math problem, not programming ..
you need to define a set of equations (your transformation matrix, my guess is 3 equations) and then solve it for the 4 transformations of the corner-points.
I've only ever described this using German words ... so the above will sound strange ..
Based on the information you have, this is not that easy. I will give you some ideas to play with, however. If you had the 3D coordinates of the corners, you'd have an easier time. Here's the basic idea.
Move a corner to the origin. Thereafter, rotations will take place about the origin.
Determine vectors of the axes. Do this by subtracting the adjacent corners from the origin point. These will be a local x and y axis for your world.
Determine angles using the vectors. You can use the dot and cross products to determine the angle between the local x axis and the global x axis (1, 0, 0).
Rotate by the angle in step 3. This will give you a new x axis which should match the global x axis and a new local y axis. You can then determine another rotation about the x axis which will bring the y axis into alignment with the global y axis.
Without the z coordinates, you can see that this will be difficult, but this is the general process. I hope this helps.
The solution will not be unique, as Alex319 points out.
If the second image is really a trapezoid as you say, then this won't be too hard. It is a trapezoid (not a parallelogram) because of perspective, so it must be an isosceles trapezoid.
Draw the two diagonals. They intersect at the center of the rectangle, so that takes care of the translation.
Rotate the trapezoid until its parallel sides are parallel to two sides of the original rectangle. (Which two? It doesn't matter.)
Draw a third parallel through the center. Scale this to the sides of the rectangle you chose.
Now for the rotation out of the plane. Measure the distance from the center to one of the parallel sides and use the law of sines.
If it's not a trapezoid, just a quadralateral, then it'll be harder, you'll have to use the angles between the diagonals to find the axis of rotation.

Resources