开发者

How can I turn a ray-plane intersection point into barycentric coordinates?

My problem:

How can I take two 3D points and lock them to a single axis? For instance, so that both their z-axes are 0.

What I'm trying to do:

I have a set of 3D coordinates in a scene, representing a a box with a pyramid on it. I also have a camera, represented by another 3D coordinate. I subtract the camera coordinate from the scene coordinate and normalize it, returning a vector that points to the camera. I then do ray-plane intersection with a plane that is behind the camera point.

O + tD

Where O (origin) is the camera position, D is the direction from the scene point to the camera and t is time it takes for the ray to intersect the plane from the camera point.

If that doesn't make sense, here's a crude drawing:

How can I turn a ray-plane intersection point into barycentric coordinates?

I've searched far and wide, and as far as I can tell, this is called using a "pinhole camera".

The problem is not开发者_如何学Go my camera rotation, I've eliminated that. The trouble is in translating the intersection point to barycentric (uv) coordinates.

The translation on the x-axis looks like this:

uaxis.x = -a_PlaneNormal.y;
uaxis.y = a_PlaneNormal.x;
uaxis.z = a_PlaneNormal.z;

point vaxis = uaxis.CopyCrossProduct(a_PlaneNormal);

point2d.x = intersection.DotProduct(uaxis);
point2d.y = intersection.DotProduct(vaxis);

return point2d; 

While the translation on the z-axis looks like this:

uaxis.x = -a_PlaneNormal.z;
uaxis.y = a_PlaneNormal.y;
uaxis.z = a_PlaneNormal.x;

point vaxis = uaxis.CopyCrossProduct(a_PlaneNormal);

point2d.x = intersection.DotProduct(uaxis);
point2d.y = intersection.DotProduct(vaxis);

return point2d; 

My question is: how can I turn a ray plane intersection point to barycentric coordinates on both the x and the z axis?


The usual formula for points (p) on a line, starting at (p0) with vector direction (v) is:

p = p0 + t*v

The criterion for a point (p) on a plane containing (p1) and with normal (n) is:

(p - p1).n = 0

So, plug&chug:

(p0 + t*v - p1).n = (p0-p1).n + t*(v.n) = 0

   ->  t = (p1-p0).n / v.n
   ->  p = p0 + ((p1-p0).n / v.n)*v

To check:

(p - p1).n = (p0-p1).n + ((p1-p0).n / v.n)*(v.n)
                   = (p0-p1).n + (p1-p0).n
                   = 0

If you want to fix the Z coordinate at a particular value, you need to choose a normal along the Z axis (which will define a plane parallel to XY plane).

Then, you have:

n = (0,0,1)

   ->  p = p0 + ((p1.z-p0.z)/v.z) * v
   ->  x and y offsets from p0 = ((p1.z-p0.z)/v.z) * (v.x,v.y)

Finally, if you're trying to build a virtual "camera" for 3D computer graphics, the standard way to do this kind of thing is homogeneous coordinates. Ultimately, working with homogeneous coordinates is simpler (and usually faster) than the kind of ad hoc 3D vector algebra I have written above.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜