// Compute viewing matrix that maps a
// screen coordinate to a ray direction
Vector3D look = new Vector3D(lookat.x-eye.x, lookat.y-eye.y, lookat.z-eye.z);
Du = Vector3D.normalize(look.cross(up));
Dv = Vector3D.normalize(look.cross(Du));
float fl = (float)(width / (2*Math.tan((0.5*fov)*Math.PI/180)));
Vp = Vector3D.normalize(look);
Vp.x = Vp.x*fl - 0.5f*(width*Du.x + height*Dv.x);
Vp.y = Vp.y*fl - 0.5f*(width*Du.y + height*Dv.y);
Vp.z = Vp.z*fl - 0.5f*(width*Du.z + height*Dv.z);
Example use:
Vector3D dir = new Vector3D(i*Du.x + j*Dv.x + Vp.x,
i*Du.y + j*Dv.y + Vp.y,
i*Du.z + j*Dv.z + Vp.z);
Ray ray = new Ray(eye, dir);