Noob3D

I am having some problems with this code for displaying a rotating 3d pyramid, when i try to implement persperctive it doesnt look quite right. Can u help(im sure u can!), please

//
Cell3D.java
/
/

import java.awt.;
import java.applet.
;

public class Cell3D extends Applet{
Image offscrimg;
Graphics offscrgfx;
Triangle[] tris;
double xrot, yrot, zrot;
double zoom = 2;

public void init() {
	Point3D a, b, c, d, e;
	a = new Point3D(0, -20, 0);
	b = new Point3D(-20, 20, -20);
	c = new Point3D(20, 20, -20);
	d = new Point3D(20, 20, 20);
	e = new Point3D(-20, 20, 20);
	//
	tris = new Triangle[4];
	tris[0] = new Triangle();
	tris[0].pts[0] = a;
	tris[0].pts[1] = b;
	tris[0].pts[2] = c;	
	
	tris[1] = new Triangle();
	tris[1].pts[0] = a;
	tris[1].pts[1] = c;
	tris[1].pts[2] = d;	
	
	tris[2] = new Triangle();
	tris[2].pts[0] = a;
	tris[2].pts[1] = d;
	tris[2].pts[2] = e;	
	
	tris[3] = new Triangle();
	tris[3].pts[0] = a;
	tris[3].pts[1] = e;
	tris[3].pts[2] = b;	
}


public void update(Graphics g){
	if(offscrimg == null){
		offscrimg = createImage(getSize().width, getSize().height);
		offscrgfx = offscrimg.getGraphics();
	}
	offscrgfx.clearRect(0, 0, getSize().width, getSize().height);
	paint(offscrgfx);
	g.drawImage(offscrimg, 0, 0, null);
}
	

public void paint(Graphics g1) {
	Graphics2D g = (Graphics2D) g1;

	int scx = getSize().width/2;
	int scy = getSize().height/2;
	//
	for(int i=0; i<tris.length; i++){
		int[] dx = new int[3];
		int[] dy = new int[3];
		//
		for(int j=0; j<3; j++){
			double x = tris[i].pts[j].x;
			double y = tris[i].pts[j].y;
			double z = tris[i].pts[j].z;
			double newx, newy, newz;
			//xrot
			newx = x;
			newy = y * Math.cos(xrot) - z * Math.sin(xrot);
			newz = y * Math.sin(xrot) + z * Math.cos(xrot);
			x = newx;
			y = newy;
			z = newz;
			//yrot
			newx = x * Math.cos(yrot) - z * Math.sin(yrot);
			newy = y;
			newz = -x * Math.sin(yrot) + z * Math.cos(yrot);
			x = newx;
			y = newy;
			z = newz;
			//zrot
			newx = x * Math.cos( zrot ) - y * Math.sin( zrot );
			newy = x * Math.sin( zrot ) + y * Math.cos( zrot );
			newz = z;
			x = newx;
			y = newy;
			z = newz;	
					
		
			//no perspective
			int drawx = scx + (int)( zoom * x);
			int drawy = scy + (int)( zoom * y);
					
			//with perspective		
		//	int drawx = scx + (int)( zoom * (x/(Math.abs(z))));
		//	int drawy = scy + (int)( zoom * (y/(Math.abs(z))));
			
			dx[j] = drawx;
			dy[j] = drawy;
			//
		}
		
		g.setStroke(new BasicStroke(1.0f));
		g.drawPolygon(dx, dy, dx.length);
		
		//origin
		g.setStroke(new BasicStroke(3.0f));
		g.drawLine(scx, scy, scx, scy);
		//end rendering code
	}
	
	
	xrot += 0.008;
	yrot += 0.008;
	zrot += 0.008;
	try{ Thread.sleep(16); }catch(Exception e){}
	repaint();
}

}

//
Point3D.java
/
/
public class Point3D{
public float x, y, z;
public Point3D(float x, float y, float z){
this.x = x;
this.y = y;
this.z = z;
}
}

//
Triangle.java
/
/
public class Triangle{
public Point3D[] pts;
public Triangle(){
pts = new Point3D[3];
}
}

Why do you write your renderer yourself?
There are lots of renderers (Java3D, Xith3D, JMe, lwjgl, jogl) out there, that do exactly this job.

I think you have to move the pyramid away or you’ll rotate it around the camera. Try:


int cameraz = 50;
int drawx = scx + (int)( zoom * (x/(z+cameraz))));
int drawy = scy + (int)( zoom * (y/(z+cameraz))));

Mess around with cameraz and zoom until it looks ok.

None of wich work in a applet.

Besides, writing your own renderer is fun and can teach you the basics of 3d graphics.

thanx, but is this the best way to implement perspective, it seems very flawed no im thinking about it, i have read of a way using projections, is this better .

I don’t know what you mean by “using projections”. The best way would be to use matrices, but it is alot more complicated.

Tiem to put on the old fogey hat…

In The Bad Old Days™ before we had GPUs or even fast CPUs (ie circa 386 - 496) we played a lot of tricks for erpformance.

Trick 1: Dont do translation through a matrix. Just store discrete x,y,z delta values
Trick 2: Dont do perspective through the matrix. Instead just scale Z and Y by Z (x = x/z, y y=y/z);

This allows the most inportant trick…
Trick 3: use 3x3 matrices and use them just for rotation