public Ray Transfer(Vector3d objectPos, Vector3d lensPos) { Debug.Assert(Math.Abs(lensPos.Z) < epsilon); if (!IsPointWithinLens(lensPos)) { return(null); } Vector4d transformedPos = Vector4d.Transform( (new Vector4d(objectPos) + Vector4d.UnitW), GetTransferMatrix(objectPos.Z)); if (Math.Abs(transformedPos.W) > epsilon) { Vector4d.Divide(ref transformedPos, transformedPos.W, out transformedPos); } Vector3d outputDirection = transformedPos.Xyz; if (Math.Abs(transformedPos.W) > epsilon) { outputDirection -= lensPos; } if (Math.Abs(objectPos.Z) <= FocalLength) { // the image of the incoming ray origin was in the same // half-plane as the origin itself outputDirection = -outputDirection; } return(new Ray(lensPos, outputDirection)); }