数学:如何将3D世界转换为2D屏幕坐标

时间:2011-02-17 03:22:57

标签: c# math coordinate-systems

我正在寻找一种将3D xyz坐标转换为2D xy(像素)坐标的方法。我得到了一个坐标列表,我需要在2d平面上绘制。

平面将始终为自上而下的视图宽度,以下尺寸宽度:800像素,高度400像素

3D世界坐标可以包含从-4000到4000的负值。我在维基百科和几个SO线程上阅读了一些转换文章,但它们要么不符合我的需要,要么它们太复杂了我的有限的数学知识。

我希望有人可以帮助我。 谢谢你的时间。

此致 标记

4 个答案:

答案 0 :(得分:1)

你可以使用类似[(x / z),(y / z)]的东西来投射3d到2d - 我相信这是一个相当粗略的方法,我认为3d到2d谷歌搜索会返回一些相当标准的算法

答案 1 :(得分:1)

Rob或多或少是正确的,只是通常需要使用缩放因子(即[k *(x / z),k *(y / z)])。如果你永远不改变自己的观点或方向,那么你需要完全理解其工作原理的所有数学都是截距定理。

我认为它的标准实现使用所谓的同质坐标,这有点复杂。但是对于快速而肮脏的实现,只需使用“普通”3D坐标就可以了。

在处理观点背后的坐标时,您还需要小心。事实上,这就是我发现(基于多边形的)3D图形中最丑陋的部分。

答案 2 :(得分:0)

你可能会觉得这很有趣:A 3D Plotting Library in C#

答案 3 :(得分:0)

可能有所帮助的东西:我正在研究的一些代码...

// Location in 3D space (x,y,z), w = 1 used for affine matrix transformations...
public class Location3d : Vertex4d
{
    // Default constructor
    public Location3d()
    {
        this.x = 0;
        this.y = 0;
        this.z = 0;
        this.w = 1; // w = 1 used for affine matrix transformations...
    }
    // Initiated constructor(dx,dy,dz)
    public Location3d(double dx, double dy, double dz)
    {
        this.x = dx;
        this.y = dy;
        this.z = dz;
        this.w = 1;     // w = 1 used for affine matrix transformations...
    }
}

// Point in 2d space(x,y) , screen coordinate system?
public class Point2d
{
    public int x { get; set; }              // 2D space x,y
    public int y { get; set; }

    // Default constructor
    public point2d()
    {
        this.x = 0;
        this.y = 0;
    }
}

// Check if a normal  vertex4d of a plane is pointing away?
// z = looking toward the screen +1 to -1   
public bool Checkvisible(Vertex4d v)
{
    if(v.z <= 0)
    {
        return false;       // pointing away, thus invisible
    }
    else
    {
        return true;
    }
}

// Check if a vertex4d is behind you, out of view(behinde de camera?)
// z = looking toward the screen +1 to -1
public bool CheckIsInFront(Vertex4d v)
{
    if(v.z < 0)
    {
        return false;       // some distans from the camera
    }
    else
    {
        return true;
    }
}

如果椎体位于屏幕区域之外,需要进行一些修剪!!!