public static double[] invertBilinear(Vec4 U, Vec4 X, Vec4 Y, Vec4 Z, Vec4 W) {
    Vec4 s1 = W.subtract3(X);
    Vec4 s2 = Z.subtract3(Y);
    Vec4 UminX = U.subtract3(X);
    Vec4 UminY = U.subtract3(Y);
    Vec4 normal = Z.subtract3(X).cross3(W.subtract3(Y));

    double A = s1.cross3(s2).dot3(normal);
    double B = s2.cross3(UminX).dot3(normal) - s1.cross3(UminY).dot3(normal);
    double C = UminX.cross3(UminY).dot3(normal);

    double descriminant = B * B - 4d * A * C;
    if (descriminant < 0) return null;
    descriminant = Math.sqrt(descriminant);

    double beta = B > 0 ? (-B - descriminant) / (2d * A) : 2d * C / (-B + descriminant);

    Vec4 Sbeta1 = Vec4.mix3(beta, X, W);
    Vec4 Sbeta2 = Vec4.mix3(beta, Y, Z);

    double alpha =
        U.subtract3(Sbeta1).dot3(Sbeta2.subtract3(Sbeta1)) / Sbeta2.subtract3(Sbeta1).dotSelf3();

    return new double[] {alpha, beta};
  }