gpt4 book ai didi

c# - 将 3D 点投影到 2D 屏幕坐标

转载 作者:太空狗 更新时间:2023-10-29 20:15:35 29 4
gpt4 key购买 nike

基于 3D Programming For Windows (Charles Petzold) 第 7 章中的信息,我尝试编写辅助函数,将 Point3D 投影到包含相应屏幕坐标 (x,y) 的标准 2D 点:

public Point Point3DToScreen2D(Point3D point3D,Viewport3D viewPort )
{
double screenX = 0d, screenY = 0d;

// Camera is defined in XAML as:
// <Viewport3D.Camera>
// <PerspectiveCamera Position="0,0,800" LookDirection="0,0,-1" />
// </Viewport3D.Camera>

PerspectiveCamera cam = viewPort.Camera as PerspectiveCamera;

// Translate input point using camera position
double inputX = point3D.X - cam.Position.X;
double inputY = point3D.Y - cam.Position.Y;
double inputZ = point3D.Z - cam.Position.Z;

double aspectRatio = viewPort.ActualWidth / viewPort.ActualHeight;

// Apply projection to X and Y
screenX = inputX / (-inputZ * Math.Tan(cam.FieldOfView / 2));

screenY = (inputY * aspectRatio) / (-inputZ * Math.Tan(cam.FieldOfView / 2));

// Convert to screen coordinates
screenX = screenX * viewPort.ActualWidth;

screenY = screenY * viewPort.ActualHeight;


// Additional, currently unused, projection scaling factors
/*
double xScale = 1 / Math.Tan(Math.PI * cam.FieldOfView / 360);
double yScale = aspectRatio * xScale;

double zFar = cam.FarPlaneDistance;
double zNear = cam.NearPlaneDistance;

double zScale = zFar == Double.PositiveInfinity ? -1 : zFar / (zNear - zFar);
double zOffset = zNear * zScale;

*/

return new Point(screenX, screenY);
}

然而,在测试中,此函数返回不正确的屏幕坐标(通过将 2D 鼠标坐标与简单的 3D 形状进行比较来检查)。由于我缺乏 3D 编程经验,我对原因感到困惑。

block 注释部分包含可能必不可少的缩放计算,但我不确定如何进行,并且本书继续介绍了使用 XAML 的 MatrixCamera。最初,我只想进行基本计算,而不管它与矩阵相比效率有多么低。

任何人都可以建议需要添加或更改的内容吗?

最佳答案

我已经使用 3DUtils 创建并成功测试了一种工作方法Codeplex 源库。

真正的工作是在 3DUtils 的 TryWorldToViewportTransform() 方法中执行的。没有它,此方法将无法工作(请参阅上面的链接)。

在 Eric Sink 的文章中也找到了非常有用的信息:Auto-Zoom .

注意。可能有更可靠/有效的方法,如果有,请将它们添加为答案。与此同时,这足以满足我的需求。

    /// <summary>
/// Takes a 3D point and returns the corresponding 2D point (X,Y) within the viewport.
/// Requires the 3DUtils project available at http://www.codeplex.com/Wiki/View.aspx?ProjectName=3DTools
/// </summary>
/// <param name="point3D">A point in 3D space</param>
/// <param name="viewPort">An instance of Viewport3D</param>
/// <returns>The corresponding 2D point or null if it could not be calculated</returns>
public Point? Point3DToScreen2D(Point3D point3D, Viewport3D viewPort)
{
bool bOK = false;

// We need a Viewport3DVisual but we only have a Viewport3D.
Viewport3DVisual vpv =VisualTreeHelper.GetParent(viewPort.Children[0]) as Viewport3DVisual;

// Get the world to viewport transform matrix
Matrix3D m = MathUtils.TryWorldToViewportTransform(vpv, out bOK);

if (bOK)
{
// Transform the 3D point to 2D
Point3D transformedPoint = m.Transform(point3D);

Point screen2DPoint = new Point(transformedPoint.X, transformedPoint.Y);

return new Nullable<Point>(screen2DPoint);
}
else
{
return null;
}
}

关于c# - 将 3D 点投影到 2D 屏幕坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/519106/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com