How to project a 3D point on to a canvas

Hi everyone, the current task I’ve set myself is to take an array of 4 three-dimensional points and project them on to a two-dimensional canvas. I’m having a bit of trouble understanding what I’ve read and tried to put into practice and was wondering whether anyone could tell me where I’ve gone wrong.
Say for example I have these 4 three-dimensional points representing the corners of a quadrilateral, with two points at Z coordinate 20 and the other two at Z coordinate 40, making up a square with its faces facing down the X axis. If I then translate this set of points 100 points down the negative X axis, I should now be able to see the back two points, which should also be rendered with perspective projection, meaning that the two furthest points appear closer together. This is the perspective projection I’ve used: http://msdn.microsoft.com/en-us/library/bb205351(v=vs.85).aspx
In the “Remarks” section.

Now my understanding breaks down when I come to transform the points to their perspective view. From what I’ve gathered, the point, which can be represented with a 3-dimensional vector is multiplied by the view matrix, which I’ve initially set to the identity matrix. From here presumably you’re meant to have a transformed point (3-dimensional vector), which you then have to multiply by the projection matrix, which in my case is in a perspective view.

From that I now have a new transformed 3-dimensional vector that I can simply render to the screen as I would normal screen pixels. So in a nutshell:

TransformedPoint = Point x ViewMatrix x ProjectionMatrix

Is this right? This appears to just produce the same point as the original. I know I’ll have to post some code up here, but could you tell if this logically isn’t very sound anyway?
Also, I’m rendering all this into an AWT Canvas.

Thanks in advance for any help!

Paul

Yes, that should work.

Or just use gluProject.

Hey, thanks for the reply! I’ve almost got what I need now, but there’s a glitch that I don’t really understand the reason of. I’ve taken the 3D point and multiplied if by the view matrix, which I’ve just set as the identity. I’ve then multiplied this transformed point by the projection matrix shown above to get the clip space coordinates, which I then multiply by the viewport half width/height to transform it to screen coordinates and then divide both the X and Y components by the Z component for the foreshortening. The problem I’ve found is that when I move the point forward, it moves into the scene as you’d expect, but when I move it backwards to the point where it’s behind the camera and not visible in the scene, it reappears in opposite corner.
So for example, a point that’s in the bottom right hand corner, moves out of the window by the bottom right corner as its Z component deceases, but the point then reappears from the top left hand corner and moves towards the centre.
Has anyone ever heard of anything similar to this?

Hi,

That’s how gluProject works as well, there you can grab the 3rd parameter returned to see whether the point is in front ( >1 ) or behind the canvas plane ( <1 ). Maybe you have something similar and otherwise you can just check if the point is behind the canvas plane.

Mike

Thanks for the reply. :slight_smile: Here’s the code I have for rendering the points:


for(int i = 0; i < vertices.length; i++) {
	Point4f transPos = Point4f.multiply(Point4f.multiply(vertices[i], viewMat), projMat);
	if(transPos.getX() < -1 || transPos.getX() > 1 || transPos.getY() < -1 || transPos.getY() > 1) continue;
	int x = (int) (Main.WIDTH * 0.5 + transPos.getX() * Main.WIDTH * 0.5 / transPos.getZ());
	int y = (int) (Main.HEIGHT * 0.5 + transPos.getY() * Main.HEIGHT * 0.5 / transPos.getZ());
	screen.drawPoint(x, y, 0xffffffff);
}

(btw Main.WIDTH and Main.HEIGHT are the viewport width and height).

I thought that the if statement on the 3rd line checks whether the point is outside of the clip space, which would have eliminated points behind the camera. Could this be because the X and Y components are divided by the Z component after that check? Or is normal to just put in another check to determine whether the Z component of the point is less than the Z component of the camera?

Hi all again :slight_smile: I’ve still got this problem. I’ve attempted to change a few things, although they didn’t really help. The problem remains that when the point moves behind the viewport, it reappears in the opposite corner and moves towards the point to infinity. I tried adding the Z component to this statement:


if(transPos.getX() < -1 || transPos.getX() > 1 || transPos.getY() < -1 || transPos.getY() > 1) continue;

Although it didn’t seem to solve my problem, however it did clip points further out in the scene. Does anyone know of any source code where something similar has been achieved and is working (perspective projection of a 3D point on a 2D canvas)?
If anyone could post a source I’d really appreciate it. I’m reading from a few different sources, although from what I’m gathering from them all collectively doesn’t mention a glitch of this nature.