public class TransformUtility {
	private TransformUtility() { }

	public static Transform viewTransform(Point eye, Point look,
			Vector up) {
		Vector n = eye.subtract(look);
		Vector u = up.cross(n);
		Vector v = n.cross(u);
		Vector y = eye.subtract(Point.ORIGIN);
		n = n.normalize();
		u = u.normalize();
		v = v.normalize();
		return Transform.create(new double[] {
			u.getX(), u.getY(), u.getZ(), -y.dot(u),
			v.getX(), v.getY(), v.getZ(), -y.dot(v),
			n.getX(), n.getY(), n.getZ(), -y.dot(n),
			0, 0, 0, 1 });
	}

	public static Transform orthographicProjection(double x0, double x1,
			double y0, double y1, double N, double F) {
		return Transform.scale(2 / (x1 - x0), 2 / (y1 - y0), -2 / (F - N))
			.append(Transform.translate(-(x0 + x1) / 2, -(y0 + y1) / 2, (N + F) / 2));
	}

	public static Transform perspectiveProjection(double x0, double x1,
			double y0, double y1, double N, double F) {
		double a = -(F + N) / (F - N);
		double b = -2 * F * N / (F - N);
		return Transform.create(new double[] {
			2 * N / (x1 - x0), 0, (x1 + x0) / (x1 - x0), 0,
			0, 2 * N / (y1 - y0), (y1 + y0) / (y1 - y0), 0,
			0, 0, a, b,
			0, 0, -1, 0
		});
	}
}
