Retrieve 2D co-ordinate from a 3D point on a 3D pl

2019-05-27 03:11发布

问题:

I have a point a point (x, y, z) that is on a plane defined by ax+by+cz+d=0. I'm trying to figure out what the (x', y') relative to the plane, where it has a starting point of (x0, y0, z0) and the x'-axis is defined by (1,0) and the y'-axis is defined by (0,1).

My major goal is to have the mouse click on a surface, and know the 2D co-ordinates on a particular surface. I've managed to intersect the ray onto a plane quite trivially.

As a side-note, I'm using DirectX 9 - my familiarity with matrix/vector math is limited by the APIs provided to me through the D3DX libraries.

One thought I had was to use the angle of between one of the axis vectors and find the distance from origin, and figure out the x/y using simple trig. But I'm not sure if that's really an ideal solution or not - or if it can actually solve the issue at hand.

回答1:

Since you have a 2D image on that plane, you apparently want to match its coordinate system. To do so, determine the unit vectors of the picture. That is, take the 3d coordinates B for the picture position (x,0) for any x>0, and subtract from that the 3d coordinates A for the origin (0,0) of the picture. The resulting vector B − A will describe the positive x direction of your image. Do the same for the y direction. Then normalize both these vectors. This means dividing them by their length, sqrt(x²+y²+z²), but D3Dx has a function D3DXVec3Normalize for this. Let's call the resulting 3d vectors X and Y. To compute the x and y coordinate of any 3D point p, simply subtract the origin A from p, i.e. compute the vector p − A. Then compute the dot product between the result and the unit vectors X and Y. This will give you two numbers: the desired coordinates. This is because the dot product can be used to compute an orthogonal projection.

Translating this into D3Dx, it should look somewhat like the following. As I have never used it, this might have mistakes.

D3DXVECTOR3 *p;                  // input point
D3DXVECTOR3 a, b, c, ab, ac, ap; // helper vectors
FLOAT x, y;                      // output coordinates
imagePosTo3D(&a, 0, 0);          // a = origin of image
imagePosTo3D(&b, 1, 0);          // b = anywhere on positive x axis, perhaps a corner
imagePosTo3D(&c, 0, 1);          // c = anywhere on positive y axis, perhaps a corner
D3DXVec3Subtract(&ab, &b, &a);   // ab = b - a
D3DXVec3Subtract(&ac, &c, &a);   // ac = c - a
D3DXVec3Normalize(&ab, &ab);     // ab = ab / |ab|
D3DXVec3Normalize(&ac, &ac);     // ac = ac / |ac|
// the above has to be done once for the image, the code below for every p
D3DXVec3Subtract(&ap, p, &a);    // ap = p - a
x = D3DXVec3Dot(&ab, &ap);       // x = ab∙ap
y = D3DXVec3Dot(&ac, &ap);       // y = ac∙ap