private void calculateXiEta(Point p) {
		// solves:
		//		a1 * xi * eta + a2 * xi + a3 * eta + a4 = 0
		//		b1 * xi * eta + b2 * xi + b3 * eta + b4 = 0

		double a1 = ( + x[0].x() - x[1].x() + x[2].x() - x[3].x() ) / 4;
		double a2 = ( - x[0].x() + x[1].x() + x[2].x() - x[3].x() ) / 4;
		double a3 = ( - x[0].x() - x[1].x() + x[2].x() + x[3].x() ) / 4;
		double a4 = ( + x[0].x() + x[1].x() + x[2].x() + x[3].x() ) / 4 - p.x();
		double b1 = ( + x[0].y() - x[1].y() + x[2].y() - x[3].y() ) / 4;
		double b2 = ( - x[0].y() + x[1].y() + x[2].y() - x[3].y() ) / 4;
		double b3 = ( - x[0].y() - x[1].y() + x[2].y() + x[3].y() ) / 4;
		double b4 = ( + x[0].y() + x[1].y() + x[2].y() + x[3].y() ) / 4 - p.y();

		// solve:
		//		sa * xi^2 + sb * xi + sc = 0
		if (a1 != 0) {
			double sa = a1 * b2 - a2 * b1;
			double sb = a1 * b4 - a4 * b1 + a3 * b2 - a2 * b3;
			double sc = a3 * b4 - a4 * b3;

			xi  = solveQuadraticFormula(sa, sb, sc);
		}

		// solve:
		//		sa * eta^2 + sb * eta + sc = 0
		if (b1 != 0) {
			double sa = a1 * b3 - a3 * b1;
			double sb = a1 * b4 - a4 * b1 + a2 * b3 - a3 * b2;
			double sc = a2 * b4 - a4 * b2;

			eta = solveQuadraticFormula(sa, sb, sc);
		}

		if (!Double.isNaN(xi) && Double.isNaN(eta))
			eta = - (a2 * xi + a4) / (a1 * xi + a3);

		if (Double.isNaN(xi) && !Double.isNaN(eta))
			xi = - (b3 * eta + b4) / (b1 * eta + b2);

		if (!Double.isNaN(xi) && !Double.isNaN(eta))
			return;

		// a1 and b1 are zero.
		// now solves:
		//		a2 * xi + a3 * eta + a4 = 0
		//		b2 * xi + b3 * eta + b4 = 0
		double determinant = a2 * b3 - a3 * b2;
		if (determinant != 0) {
			xi  = a3 * b4 - a4 * b3 / determinant;
			eta = a4 * b2 - a2 * b4 / determinant;
		}
	}