简体   繁体   中英

How to project 3D on a 2D plane?

I created a simple Application which is meant to display, in 2D, dots which are hypothetically on a 3D plane (these points are of type Vector, written below). The class uses the XYZ Coordinates of the Camera and the XYZ Coordinates of the Vector, and uses that information to quickly translate the Vector XYZ Coordinates into XY Coordinates.

The only class needed in this question is the Vector class given below. All other classes used are omitted because they essentially fire mouse movements and redraw the frame.

--My concern is that, as the camera moves, the Vector points jump around as if the formula that I'm using is totally unreliable. Are these formulas (found under Perspective Projection) completely incorrect? The use of those formulas can be found within my set2D method. Am I doing something completely wrong, skipping steps, or perhaps have I translated the formula into code incorrectly?

Thanks!

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);
    }
}

The following line of your code does not match with the formula you are using:

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

Notice the part - ((-sinX*cosZ*eY) - (-sinX*sinZ*eX))

This should be - ((sinX*cosZ*eY) - (sinX*sinZ*eX))

Since if you take sinX and multiply it, the -ve sign stays outside. If however you multiple -sinX then the sign outside the brackets should become +ve.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM