# How do I get from orthographic to perspective?

I programmed a cube in java and calculated the x y and z position for it's rotation on the x,y and z axis but I'm finding it hard to display the z axis i've been trying to change the distance of the vectors with higher z values to be closer to the middle of the Screen or the (0,0) point but am finding this rather hard any tips? Thank you.

here's the code:

public class vert {
//screen position
int x;
int y;
int z;
//real rot position
int xr;
int yr;
int zr;

public void rotate(int xpos,int ypos,int zpos,int rotx,int roty,int rotz) {

//x,y
//calculate the new rotation
double rx1 = Math.toDegrees(Math.atan2(ypos,xpos)) + rotx;
//calculate the hypotenuse
double hypx1 = Math.sqrt(xpos * xpos + ypos * ypos);
//calculate x1
double posx1 = Math.cos(Math.toRadians(rx1)) * hypx1;
int tointx1 = (int) Math.round(posx1);
int x1 = tointx1;
//calculate y1
double posy1 = Math.sin(Math.toRadians(rx1)) * hypx1;
int tointy1 = (int) Math.rint(posy1);
int y1 = tointy1;

//x,z
//calculate the new rotation
double ry2 = Math.toDegrees(Math.atan2(zpos,x1)) + roty;
//calculate the hypotenuse
double hypy2 = Math.sqrt(x1 * x1 + zpos * zpos);
//calculate x final
double posx2 = Math.cos(Math.toRadians(ry2)) * hypy2;
int tointx2 = (int) Math.round(posx2);
int x2 = tointx2;
//calculate z1
double posz2 = Math.sin(Math.toRadians(ry2)) * hypy2;
int tointz2 = (int) Math.rint(posz2);
int z1 = tointz2;

//y,z
//calculate the new rotation
double rz3 = Math.toDegrees(Math.atan2(z1,y1)) + rotz;
//calculate the hypotenuse
double hypz3 = Math.sqrt(y1 * y1 + z1 * z1);
//calculate y final
double posy3 = Math.cos(Math.toRadians(rz3)) * hypz3;
int tointy3 = (int) Math.round(posy3);
int y2 = tointy3;
//calculate z final
double posz3 = Math.sin(Math.toRadians(rz3)) * hypz3;
int tointz3 = (int) Math.rint(posz3);
int z2 = tointz3;

xr = x2;
yr = y2;
zr = z2 + 128;
}

public void perspective() {

double pers = Screen.camfocallenght / zr;
x = (int) Math.rint(xr * pers) + Screen.x;
y = (int) Math.rint(yr * pers) + Screen.y;
}
}


And here's the code that draws the cube onto screen:

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

import javax.swing.JComponent;
import javax.swing.JFrame;

public class Screen extends JComponent{

private static final long serialVersionUID = 1L;

static int height = 400;
static int width = 600;

static double camfocallenght = 100;

static int y = height / 2;
static int x = width / 2;

int movex = 0;
int movey = 0;
int movez = -100;

int a = 0;
int b = 0;
int c = 0;

vert[] v = new vert[12];

public void paint(Graphics g) {

v[0] = new vert();
v[0].rotate(movex + 45,movey + -45,movez + 45, a, b, c);
v[1] = new vert();
v[1].rotate(movex + 45,movey + 45,movez + 45, a, b, c);
v[2] = new vert();
v[2].rotate(movex + -45,movey + 45,movez + 45, a, b, c);
v[3] = new vert();
v[3].rotate(movex + -45,movey + -45,movez + 45, a, b, c);

v[4] = new vert();
v[4].rotate(movex + 45,movey + -45,movez + -45, a, b, c);
v[5] = new vert();
v[5].rotate(movex + 45,movey + 45,movez + -45, a, b, c);
v[6] = new vert();
v[6].rotate(movex + -45,movey + 45,movez + -45, a, b, c);
v[7] = new vert();
v[7].rotate(movex + -45,movey + -45,movez + -45, a, b, c);

v[0].perspective();
v[1].perspective();
v[2].perspective();
v[3].perspective();
v[4].perspective();
v[5].perspective();
v[6].perspective();
v[7].perspective();

g.setColor(Color.green);

g.drawLine( v[4].x, v[4].y, v[5].x, v[5].y);
g.drawLine( v[6].x, v[6].y, v[7].x, v[7].y);
g.drawLine( v[5].x, v[5].y, v[6].x, v[6].y);
g.drawLine( v[7].x, v[7].y, v[4].x, v[4].y);

g.setColor(Color.RED);

g.drawLine(v[0].x, v[0].y, v[4].x, v[4].y);
g.drawLine(v[1].x, v[1].y, v[5].x, v[5].y);
g.drawLine(v[2].x, v[2].y, v[6].x, v[6].y);
g.drawLine(v[3].x, v[3].y, v[7].x, v[7].y);

g.setColor(Color.CYAN);

g.drawLine( v[0].x, v[0].y, v[1].x, v[1].y);
g.drawLine( v[2].x, v[2].y, v[3].x, v[3].y);
g.drawLine( v[1].x, v[1].y, v[2].x, v[2].y);
g.drawLine( v[3].x, v[3].y, v[0].x, v[0].y);

String ShowZ = Integer.toString(v[1].xr);
String Show4 = Integer.toString(v[4].x);
String Showb = Integer.toString(b);

g.drawString("x rotation:", 0, 10);
g.drawString(Showb, 0, 22);
g.drawString("z pos of vert 1:", 0, 30);
g.drawString(ShowZ, 0, 42);
g.drawString("x pos of vert 1 with perspective:", 0, 50);
g.drawString(Show4, 0, 62);

//a++;
b++;
//c++;

try {
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
JFrame frame = new JFrame("Draw Line");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setSize(width, height);
frame.setVisible(true);
while (true) {
frame.getContentPane().repaint();
}
}
}

• Ok,here's the graphics – ENR813 Feb 12 '18 at 17:49
• I Guess no help in sight :( – ENR813 Feb 13 '18 at 9:08
• I recommend starting here: en.wikipedia.org/wiki/3D_projection – CobaltHex Feb 13 '18 at 9:09
• (And using matricies - It will make your math a lot cleaner) – CobaltHex Feb 13 '18 at 9:18
• so I've been playing around with this but still couldn't get it to work any suggestions? – ENR813 Mar 27 '18 at 10:52

You just need to divide the x and y components by z. If you want to put the vanishing point "farther", then make the z component smaller (e.g. divide it by a constant). If you want to make the fov larger, then increase it by a constant.

• Thanks tried that but got this as result: Exception in thread "AWT-EventQueue-0" java.lang.ArithmeticException – ENR813 Feb 13 '18 at 9:23
• @ENR813 That clearly states what the problem is. Make sure you don't divide by zero – Bálint Feb 13 '18 at 9:25
• the Cube collapsed into a plane with an x dont know why – ENR813 Feb 13 '18 at 10:16
• @ENR how large can the z componebt be? – Bálint Feb 13 '18 at 10:17
• I don't seem to be calculating the z component incorrectly – ENR813 Feb 13 '18 at 15:58

You will get a lot more of readability if you use matrices for this, then to find the new position of the vector, you just multiply the vector by the matrix.

This question is a bit old, but if you meant how to find the on-screen position based on the world position, then you need to multiply the world position by the perspective matrix:

mat4 perspective = mat4_perspective_fov(fov, width, height, near, far);
onscreen_pos = vec4_multiply_mat4(world_pos, perspective);


If you meant how to make a transition from orthographic to perspective (and vice-versa), you can linear interpolate two projection matrices:

mat4 perspective = mat4_perspective_fov(fov, width, height, near, far);
mat4 orthographic = mat4_ortho(left, right, bottom, top, near, far);
mat4 interpolated = mat4_lerp(perspective, ortho, 0.5);
onscreen_pos = vec4_multiply_mat4(world_pos, interpolated);


Then you will have a middle ground (0.5) between an orthographic and perspective projection.