2

我已经搜索过,但我就是想不通。其他问题没有帮助,或者我不明白。

问题是,我在 3D 图像中有一堆点。这些点用于一个矩形,由于透视,从 3D 相机的角度来看,它看起来不像一个矩形。任务是将矩形中的点映射到屏幕上。我见过一些被称为“四边形到四边形的转换”的方法,但其中大多数是用于将二维四边形映射到另一个四边形。但是我已经得到了现实世界中矩形的 X、Y和 Z坐标,所以我正在寻找一些更简单的方法。有谁知道这样做的任何实用算法或方法?

如果有帮助,我的 3d 相机实际上是一个带有 OpenNI 和 NITE 中间件的 Kinect 设备,我正在使用 WPF。

提前致谢。

编辑: 我还在维基百科上找到了使用角度和余弦的 3d 投影页面,但这似乎是一种困难的方法(在 3d 图像中查找角度),我不确定它是否是真正的解决方案。

4

5 回答 5

2

您可能想查看投影矩阵

这就是任何 3D 光栅化器在 2D 屏幕上“展平” 3D 体积的方式。

于 2011-04-22T17:33:37.397 回答
2

请参阅此代码以获取给定 WPF 相机的投影矩阵:

private static Matrix3D GetProjectionMatrix(OrthographicCamera camera, double aspectRatio)
{ 
    // This math is identical to what you find documented for
    // D3DXMatrixOrthoRH with the exception that in WPF only
    // the camera's width is specified.  Height is calculated
    // from width and the aspect ratio.
    double w = camera.Width;
    double h = w / aspectRatio;
    double zn = camera.NearPlaneDistance;
    double zf = camera.FarPlaneDistance;
    double m33 = 1 / (zn - zf);
    double m43 = zn * m33;
    return new Matrix3D(
        2 / w, 0, 0, 0,
        0, 2 / h, 0, 0,
        0, 0, m33, 0,
        0, 0, m43, 1);
}

private static Matrix3D GetProjectionMatrix(PerspectiveCamera camera, double aspectRatio)
{ 
    // This math is identical to what you find documented for
    // D3DXMatrixPerspectiveFovRH with the exception that in
    // WPF the camera's horizontal rather the vertical
    // field-of-view is specified.
    double hFoV = MathUtils.DegreesToRadians(camera.FieldOfView);
    double zn = camera.NearPlaneDistance;
    double zf = camera.FarPlaneDistance;
    double xScale = 1 / Math.Tan(hFoV / 2);
    double yScale = aspectRatio * xScale;
    double m33 = (zf == double.PositiveInfinity) ? -1 : (zf / (zn - zf));
    double m43 = zn * m33;
    return new Matrix3D(
        xScale, 0, 0, 0,
        0, yScale, 0, 0,
        0, 0, m33, -1,
        0, 0, m43, 0);
}

/// <summary>
///     Computes the effective projection matrix for the given
///     camera.
/// </summary>
public static Matrix3D GetProjectionMatrix(Camera camera, double aspectRatio)
{
    if (camera == null)
    {
        throw new ArgumentNullException("camera");
    }
    PerspectiveCamera perspectiveCamera = camera as PerspectiveCamera;
    if (perspectiveCamera != null)
    {
        return GetProjectionMatrix(perspectiveCamera, aspectRatio);
    }
    OrthographicCamera orthographicCamera = camera as OrthographicCamera;
    if (orthographicCamera != null)
    {
        return GetProjectionMatrix(orthographicCamera, aspectRatio);
    }
    MatrixCamera matrixCamera = camera as MatrixCamera;
    if (matrixCamera != null)
    {
        return matrixCamera.ProjectionMatrix;
    }
    throw new ArgumentException(String.Format("Unsupported camera type '{0}'.", camera.GetType().FullName), "camera");
}
于 2011-04-22T17:46:35.357 回答
1

我找到了这个。使用直截了当的数学而不是矩阵。

这称为透视投影,可将 3D 顶点转换为 2D 屏幕顶点。我用它来帮助我完成我制作的 3D 程序。

HorizontalFactor = ScreenWidth / Tan(PI / 4)
VerticalFactor = ScreenHeight / Tan(PI / 4)

ScreenX = ((X * HorizontalFactor) / Y) + HalfWidth
ScreenY = ((Z * VerticalFactor) / Y) + HalfHeight

希望这会有所帮助。我认为它是你在哪里寻找的。对不起格式(这里是新的)

于 2011-08-29T21:55:35.477 回答
1

你可以做一个基本的正交投影(我在考虑光线追踪,所以这可能不适用于你正在做的事情):

在此处输入图像描述

代码非常直观:

for y in image.height:
  for x in image.width:
    ray = new Ray(x, 0, z, Vector(0, 1, 0)) # Pointing forward
    intersection = prism.intersection(ray) # Since you aren't shading, you can check only for intersections.

    image.setPixel(x, y, intersection) # Returns black and white image of prism mapped to plane

您只需将方向(0, 1, 0)直接射入太空的矢量并记录击中的矢量。

于 2011-04-22T17:44:02.840 回答
0

将 3d 世界中的点映射到 2d 屏幕是 OpenGL 和 Direct3d 等框架工作的一部分。就像 Heandel 所说的那样,它被称为光栅化。也许您可以使用 Direct3d?

于 2011-04-22T17:37:49.560 回答