Inconsistent naming of cvdMatrixes and difficult to extend

      case Cvd.Protanopia:
        colourTriplet1 = VisionDeficiency.ApplySimulationMatrix(colour, VisionDeficiency.Protanomaly);
        break;
      case Cvd.Deuteranopia:
        colourTriplet1 = VisionDeficiency.ApplySimulationMatrix(colour, VisionDeficiency.Deuteranomaly);
        break;
      case Cvd.Tritanopia:
        colourTriplet1 = VisionDeficiency.ApplySimulationMatrix(colour, VisionDeficiency.Tritanomaly);
        break;
      case Cvd.Achromatopsia:
        colourTriplet1 = new ColourTriplet(colour.RelativeLuminance, colour.RelativeLuminance, colour.RelativeLuminance);
        break;

They should be named *anpia (complete defect) instead of *anomaly (reduced)

I was going to try implement a Deutanomaly matrix but it was quite tricky as everything was internal.

I eneded up doing an extension class:

public static class UniColourExtensions
{
    public static Unicolour ApplySimulationMatrix(this Unicolour colour, object cvdMatrix)
    {
        // Get Matrix type through reflection
        var matrixAssembly = typeof(Unicolour).Assembly;
        var matrixType = matrixAssembly.GetType("Wacton.Unicolour.Matrix", true);
    
        // Convert cvdMatrix to the correct type
        var matrix = Convert.ChangeType(cvdMatrix, matrixType);
    
        // Get FromTriplet method by specifying parameter types
        var fromTripletMethod = matrixType.GetMethod("FromTriplet", 
            System.Reflection.BindingFlags.NonPublic | 
            System.Reflection.BindingFlags.Static,
            null,
            new[] { typeof(ColourTriplet) },
            null);
    
        // Get Multiply method by specifying parameter types
        var multiplyMethod = matrixType.GetMethod("Multiply",
            System.Reflection.BindingFlags.NonPublic | 
            System.Reflection.BindingFlags.Instance,
            null,
            new[] { matrixType },
            null);
        
        // Get ToTriplet method
        var toTripletMethod = matrixType.GetMethod("ToTriplet",
            System.Reflection.BindingFlags.NonPublic | 
            System.Reflection.BindingFlags.Instance);
    
        if (fromTripletMethod == null || multiplyMethod == null || toTripletMethod == null)
            throw new InvalidOperationException("Required Matrix methods not found");

        // Create Matrix from triplet using reflection
        var other = fromTripletMethod.Invoke(null, new object[] { colour.RgbLinear.Triplet });
    
        // Multiply matrices using reflection
        var result = multiplyMethod.Invoke(matrix, new[] { other });
    
        // Convert to triplet using reflection
        var colorTriplet = (ColourTriplet)toTripletMethod.Invoke(result, null);
        
        return new Unicolour(colour.Configuration, ColourSpace.RgbLinear, colorTriplet.Tuple, colour.Alpha.A);
    }
   
    public static readonly object Deuteranomaly;
    static UniColourExtensions()
    {
        var matrixType = typeof(Unicolour).Assembly
            .GetType("Wacton.Unicolour.Matrix", true);
    
        var matrixConstructor = matrixType.GetConstructor(
            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
            null,
            new[] { typeof(double[,]) },
            null);

        var data = new[,] {
            { 0.80, 0.20, 0.00 },
            { 0.258, 0.742, 0.00 },
            { 0.00, 0.142, 0.858 }
        };

        Deuteranomaly = matrixConstructor.Invoke(new object[] { data });
    }