public static Double3x3 Inverse(Double3x3 m) { double det = m.m00 * (m.m11 * m.m22 - m.m21 * m.m12) - m.m01 * (m.m10 * m.m22 - m.m12 * m.m20) + m.m02 * (m.m10 * m.m21 - m.m11 * m.m20); if (det == 0) return m; double invdet = 1 / det; Double3x3 minv; minv.m00 = (m.m11 * m.m22 - m.m21 * m.m12) * invdet; minv.m01 = (m.m02 * m.m21 - m.m01 * m.m22) * invdet; minv.m02 = (m.m01 * m.m12 - m.m02 * m.m11) * invdet; minv.m10 = (m.m12 * m.m20 - m.m10 * m.m22) * invdet; minv.m11 = (m.m00 * m.m22 - m.m02 * m.m20) * invdet; minv.m12 = (m.m10 * m.m02 - m.m00 * m.m12) * invdet; minv.m20 = (m.m10 * m.m21 - m.m20 * m.m11) * invdet; minv.m21 = (m.m20 * m.m01 - m.m00 * m.m21) * invdet; minv.m22 = (m.m00 * m.m11 - m.m10 * m.m01) * invdet; return minv; }
private static void BuildConversionMatrices(RGBDefinition definition) { RGBDefinition d = definition; Double3 R = new Double3(d.r.x / d.r.y, 1.0, (1.0 - d.r.x - d.r.y) / d.r.y); Double3 G = new Double3(d.g.x / d.g.y, 1.0, (1.0 - d.g.x - d.g.y) / d.g.y); Double3 B = new Double3(d.b.x / d.b.y, 1.0, (1.0 - d.b.x - d.b.y) / d.b.y); Double3 W = new Double3(d.w.x / d.w.y, 1.0, (1.0 - d.w.x - d.w.y) / d.w.y); Double3x3 altMat = new Double3x3(R.x, G.x, B.x, R.y, G.y, B.y, R.z, G.z, B.z); Double3 s = Double3x3.Inverse(altMat) * W; d.toXYZ = new Double3x3(s.x * R.x, s.y * G.x, s.z * B.x, s.x * R.y, s.y * G.y, s.z * B.y, s.x * R.z, s.y * G.z, s.z * B.z); d.fromXYZ = Double3x3.Inverse(d.toXYZ); }