如何在2D平面上投影3D?

时间:2015-06-02 16:06:38

标签: java 3d projection

我创建了一个简单的应用程序,用于在2D中显示假想在3D平面上的点(这些点的类型为Vector,如下所示)。该类使用摄像机的XYZ坐标和矢量的XYZ坐标,并使用该信息将矢量XYZ坐标快速转换为XY坐标。

此问题中唯一需要的类是下面给出的Vector类。使用的所有其他类都被省略,因为它们实际上会激活鼠标移动并重绘帧。

- 我担心的是,当相机移动时,矢量点会跳跃,好像我使用的公式完全不可靠。 these公式(在透视投影下找到)是否完全不正确?可以在我的set2D方法中找到这些公式的使用。我做错了什么,跳过了步骤,或者我是否错误地将公式翻译成了代码?

谢谢!

import java.awt.Color;
import java.awt.Graphics;


public class Vector 
{
    private int cX, cY, cZ; //Camera Coordinates
    private int aX, aY, aZ; //Object Coordinates

    private double bX, bY; //3D to 2D Plane Coordinates

    public Vector(int aX, int aY, int aZ, int cX, int cY, int cZ)
    {
        this.aX = aX;
        this.aY = aY;
        this.aZ = aZ;

        this.cX = cX;
        this.cY = cY;
        this.cY = cZ;

        set2D();
    }

    //SETS
    public void setCameraX(int cX)
    {
        this.cX = cX;
        set2D();
    }

    public void setCameraY(int cY)
    {
        this.cY = cY;
        set2D();
    }

    public void setCameraZ(int cZ)
    {
        this.cZ = cZ;
        set2D();
    }

    public void setCameraXYZ(int cX, int cY, int cZ)
    {
        setCameraX(cX);
        setCameraY(cY);
        setCameraZ(cZ);
    }

    public void setObjX(int x)
    {
        this.aX = x;
    }

    public void setObjY(int y)
    {
        this.aY = y;
    }

    public void setObjZ(int z)
    {
        this.aZ = z;
    }

    public void setObjXYZ(int x, int y, int z)
    {
        this.aX = x;
        this.aY = y;
        this.aZ = z;
    }

    public void set2D()
    {
        //---
        //the viewer's position relative to the display surface which goes through point C representing the camera.
        double eX = aX - cX;
        double eY = aY - cY;
        double eZ = aZ - cZ;
        //----

        double cosX = Math.cos(eX);
        double cosY = Math.cos(eY);
        double cosZ = Math.cos(eZ);

        double sinX = Math.sin(eX);
        double sinY = Math.sin(eY);
        double sinZ = Math.sin(eZ);

        //---
        //The position of point A with respect to a coordinate system defined by the camera, with origin in C and rotated by Theta with respect to the initial coordinate system.
        double dX = ((cosY*sinZ*eY) + (cosY*cosZ*eX)) - (sinY * eZ);
    double dY = ((sinX*cosY*eZ) + (sinX*sinY*sinZ*eY) + (sinX*sinY*cosZ*eX)) + ((cosX*cosZ*eY) - (cosX*sinZ*eX));
    double dZ = ((cosX*cosY*eZ) + (cosX*sinY*sinZ*eY) + (cosX*sinY*cosZ*eX)) - ((-sinX*cosZ*eY) - (-sinX*sinZ*eX));
        //---           

        //---
        //The 2D projection coordinates of the 3D object
        bX = (int)(((eZ / dZ) * dX) - eX);
        bY = (int)(((eZ / dZ) * dY) - eY); 
        //---

        System.out.println(bX + " " + bY);
    }

    //GETS
    public int getCameraX()
    {
        return cX;
    }

    public int getCameraY()
    {
        return cY;
    }

    public int getCameraZ()
    {
        return cZ;
    }

    public int getObjX()
    {
        return aX;
    }

    public int getObjY()
    {
        return aY;
    }

    public int getObjZ()
    {
        return aY;
    }

    public int get2DX()
    {
        return (int)bX;
    }

    public int get2DY()
    {
        return (int)bY;
    }

    //DRAW
    public void draw(Graphics g)
    {
        g.setColor(Color.red);
        g.fillOval((int)bX, (int)bY, 3, 3);
    }

    //TO STRING
    public String toString()
    {
        return (aX + " " + aY + " " + aZ);
    }
}

1 个答案:

答案 0 :(得分:1)

您的代码的以下行与您使用的公式不匹配:

double dZ = ((cosX*cosY*eZ) + (cosX*sinY*sinZ*eY) + (cosX*sinY*cosZ*eX)) - ((-sinX*cosZ*eY) - (-sinX*sinZ*eX));

注意部分- ((-sinX*cosZ*eY) - (-sinX*sinZ*eX))

这应该是- ((sinX*cosZ*eY) - (sinX*sinZ*eX))

因为如果您使用sinX并将其相乘,则-ve标志会保持在外面。但是,如果您有多个-sinX,则括号外的符号应为+ ve。

相关问题