我搜索过但我无法弄清楚这一点。其他问题没有帮助,或者我不理解。
问题是,我在3D图像中有一堆点。这些点是一个矩形,由于透视,它看起来不像3D相机视图中的矩形。任务是将该矩形的点映射到屏幕。我已经看到了一些有些人称之为“四到四变换”的方法,但大多数都用于将二维四边形映射到另一个四边形。但是我在现实世界中得到了矩形的X,Y 和Z 坐标,所以我正在寻找一些更简单的方法。有谁知道这样做的任何实用算法或方法?
如果有帮助,我的3D相机实际上是一个带有OpenNI和NITE中间件的Kinect设备,我正在使用WPF。
提前致谢。
修改 我还发现维基百科上的3D投影页面使用了角度和余弦,但这似乎是一种困难的方式(在3d图像中找到角度),我不确定它是否是真正的解决方案。
答案 0 :(得分:2)
您可能需要查看projection matrices
这就是任何3D光栅化器在2D屏幕上“展平”3D体积的方式。
答案 1 :(得分:2)
See this code获取给定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");
}
答案 2 :(得分: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)
的向量直接射入太空并记录哪些被击中。
答案 3 :(得分:1)
我找到了this。使用直接的数学而不是matricies。
这称为透视投影,用于从3D顶点转换为2D屏幕顶点。我用它来帮助我完成我的3D程序。
HorizontalFactor = ScreenWidth / Tan(PI / 4)
VerticalFactor = ScreenHeight / Tan(PI / 4)
ScreenX = ((X * HorizontalFactor) / Y) + HalfWidth
ScreenY = ((Z * VerticalFactor) / Y) + HalfHeight
希望这可以提供帮助。我认为你在哪里寻找。抱歉格式化(此处新增)
答案 4 :(得分:0)
将3D世界中的点映射到2D屏幕是OpenGL和Direct3d等框架工作的一部分。它像希恩德尔所说的那样被称为光栅化。也许你可以使用Direct3d?