Rotating plane such that it has a certain normal vector - c++

I've got the following problem:
In 3D there's a vector from fixed the center of a plane to the origin. This plane has arbitrary coordinates around this center thus its normal vector is not necessarily the mentioned vector. Therefore I have to rotate the plane around this fixed center such that the mentioned vector is the plane's normal vector.
My first idea was to compute the angle between the vector and the normal vector, but the problem then is how to rotate the plane.
Any ideas?

A plane is a mathematical entity which satisfies the following equation:
Where n is the normal, and a is any point on the plane (in this case the center point as above). It makes no sense to "rotate" this equation - if you want the plane to face a certain direction, just make the normal equal to that direction (i.e. the "mentioned" vector).
You later mentioned in the comments that the "plane" is an OpenGL quad, in which case you can use Quaternions to compute the rotation.
This Stackoverflow post tells you how to compute the rotation quaternion from your current normal vector to the "mentioned" vector. This site tells you how to convert a quaternion into a rotation matrix (whose dimensions are 3x3).
Let's suppose the center point is called q, and that the rotation matrix you obtain has the following form:
This can only rotate geometry about the origin. A rotation about a general point requires a 4x4 matrix (what OpenGL uses), which can be constructed as follows:

Related

Intersection of a ray with a segment in 3d

Ray and segment of polygon lie in the same plane. The normal vector of this plane is known. I need to know if a ray intersects this segment
Choose the largest component of plane normal and make projection onto corresponding plane OXY, OXZ or OYZ (in general we can use any non-zero component)
Say Z-component is the largest, so make projection onto OXY plane. This projection is very simple - just use X and Y components. You have rather simple 2d problem now. (Example for line segments intersection).

Rounding a 3D point relative to a plane

I have a Plane class that holds n for normal and q for a point on the plane. I also have another point p that also lies on that plane. How do I go about rounding p to the nearest unit on that plane. Like snapping a cursor to a 3D grid but the grid can be rotating plane.
Image to explain:
Red is the current point. Green is the rounded point that I'm trying to get.
Probably the easiest way to achieve this is by taking the plane to define a rotated and shifted coordinate system. This allows you to construct the matrices for transforming a point in global coordinates into plane coordinates and back. Once you have this, you can simply transform the point into plane coordinates, perform the rounding/projection in a trivial manner, and convert back to world coordinates.
Of course, the problem is underspecified the way you pose the question: the transformation you need has six degrees of freedom, your plane equation only yields three constraints. So you need to add some more information: the location of the origin within the plane, and the rotation of your grid around the plane normal.
Personally, I would start by deriving a plane description in parametric form:
xVec = alpha*direction1 + beta*direction2 + x0
Of course, such a description contains nine variables (three vectors), but you can normalize the two direction vectors, and you can constrain the two direction vectors to be orthogonal, which reduces the amount of freedoms back to six.
The two normalized direction vectors, together with the normalized normal, are the base vectors of the rotated coordinate system, so you can simply construct the rotation matrix by putting these three vectors together. To get the inverse rotation, simply transpose the resulting matrix. Add the translation / inverse translation on the appropriate side of the rotation, and you are done.

Computer Vision: labelling camera pose

I am trying to create a dataset of images of objects at different poses, where each image is annotated with camera pose (or object pose).
If, for example, I have a world coordinate system and I place the object of interest at the origin and place the camera at a known position (x,y,z) and make it face the origin. Given this information, how can I calculate the pose (rotation matrix) for the camera or for the object.
I had one idea, which was to have a reference coordinate i.e. (0,0,z') where I can define the rotation of the object. i.e. its tilt, pitch and yaw. Then I can calculate the rotation from (0,0,z') and (x,y,z) to give me a rotation matrix. The problem is, how to now combine the two rotation matrices?
BTW, I know the world position of the camera as I am rendering these with OpenGL from a CAD model as opposed to physically moving a camera around.
The homography matrix maps between homogeneous screen coordinates (i,j) to homogeneous world coordinates (x,y,z).
homogeneous coordinates are normal coordinates with a 1 appended. So (3,4) in screen coordinates is (3,4,1) as homogeneous screen coordinates.
If you have a set of homogeneous screen coordinates, S and their associated homogeneous world locations, W. The 4x4 homography matrix satisfies
S * H = transpose(W)
So it boils down to finding several features in world coordinates you can also identify the i,j position in screen coordinates, then doing a "best fit" homography matrix (openCV has a function findHomography)
Whilst knowing the camera's xyz provides helpful info, its not enough to fully constrain the equation and you will have to generate more screen-world pairs anyway. Thus I don't think its worth your time integrating the cameras position into the mix.
I have done a similar experiment here: http://edinburghhacklab.com/2012/05/optical-localization-to-0-1mm-no-problemo/

How to check if a point is inside a quad in perspective projection?

I want to test if any given point in the world is on a quad/plane? The quad/plane can be translated/rotated/scaled by any values but it still should be able to detect if the given point is on it. I also need to get the location where the point should have been, if the quad was not applied any rotation/scale/translation.
For example, consider a quad at 0, 0, 0 with size 100x100, rotated at an angle of 45 degrees along z axis. If my mouse location in the world is at ( x, y, 0, ), I need to know if that point falls on that quad in its current transformation? If yes, then I need to know if no transformations were applied to the quad, where that point would have been on it? Any code sample would be of great help
A ray-casting approach is probably simplest:
Use gluUnProject() to get the world-space direction of the ray to cast into the scene. The ray's origin is the camera position.
Put this ray into object space by transforming it by the inverse of your rectangle's transform. Note that you need to transform both the ray's origin point and direction vector.
Compute the intersection point between this ray and the XY plane with a standard ray-plane intersection test.
Check that the intersection point's x and y values are within your rectangle's bounds, if they are then that's your desired result.
A math library such as GLM will be very helpful if you aren't confident about some of the math involved here, it has corresponding functions such as glm::unProject() as well as functions to invert matrices and do all the other transformations you'd need.

Orientation of figures in space

I have a sphere in my program and I intend to draw some rectangles over at a distance x from the centre of this sphere. The figure looks something below:
The rectangles are drawn at (x,y,z) points that I have already have in a vector of 3d points.
Let's say the distance x from centre is 10. Notice the orientation of these rectangles and these are tangential to an imaginary sphere of radius 10 (perpendicular to an imaginary line from the centre of sphere to the centre of rectangle)
Currently, I do something like the following:
For n points vector<vec3f> pointsInSpace where the rectnagles have to be plotted
for(int i=0;i<pointsInSpace.size();++i){
//draw rectnagle at (x,y,z)
}
which does not have this kind of tangential orientation that I am looking for.
It looked to me of applying roll,pitch,yaw rotations for each of these rectangles and using quaternions somehow to make them tangential as to what I am looking for.
However, it looked a bit complex to me and I wanted to ask about some better method to do this.
Also, the rectangle in future might change to some other shape, so a kind of generic solution would be appreciated.
I think you essentially want the same transformation as would be accomplished with a LookAt() function (you want the rectangle to 'look at' the sphere, along a vector from the rectangle's center, to the sphere's origin).
If your rectangle is formed of the points:
(-1, -1, 0)
(-1, 1, 0)
( 1, -1, 0)
( 1, 1, 0)
Then the rectangle's normal will be pointing along Z. This axis needs to be oriented towards the sphere.
So the normalised vector from your point to the center of the sphere is the Z-axis.
Then you need to define a distinct 'up' vector - (0,1,0) is typical, but you will need to choose a different one in cases where the Z-axis is pointing in the same direction.
The cross of the 'up' and 'z' axes gives the x axis, and then the cross of the 'x' and 'z' axes gives the 'y' axis.
These three axes (x,y,z) directly form a rotation matrix.
This resulting transformation matrix will orient the rectangle appropriately. Either use GL's fixed function pipeline (yuk), in which case you can just use gluLookAt(), or build and use the matrix above in whatever fashion is appropriate in your own code.
Personally I think the answer of JasonD is enough. But here is some info of the calculation involved.
Mathematically speaking this is a rather simple problem, What you have is a 2 known vectors. You know the position vector and the spheres normal vector. Since the square can be rotated arbitrarily along around the vector from center of your sphere you need to define one more vector, the up vector. Without defining up vector it becomes a impossible solution.
Once you define a up vector vector, the problem becomes simple. Assuming your square is on the XY-plane as JasonD suggest above. Then your matrix becomes:
up_dot_n_dot_n.X up_dot_n_dot_n.Y up_dot_n_dot_n.Z 0
n.X n.y n.z 0
up_dot_n.x up_dot_n.x up_dot_n.z 0
p.x p.y p.z 1
Where n is the normal unit vector of p - center of sphere (which is trivial if sphere is in the center of the coordinate system), up is a arbitrary unit vector vector. The p follows form definition and is the position.
The solution has a bit of a singularity at the up direction of the sphere. An alternate solution is to rotate first 360 around up, the 180 around rotated axis dot up. Produces same thing different approach no singularity problem.