private static FloatRgb Mix(FloatRgb a, FloatRgb b, double weight) { var output = new FloatRgb { R = Arithmetic.Mix(a.R, b.R, weight), G = Arithmetic.Mix(a.G, b.G, weight), B = Arithmetic.Mix(a.B, b.B, weight) }; return(output); }
private static bool PixelClash(FloatRgb a, FloatRgb b, double threshold) { // Only consider pair where both are on the inside or both are on the outside var aIn = (a.R > .5f ? 1 : 0) + (a.G > .5f ? 1 : 0) + (a.B > .5f ? 1 : 0) >= 2; var bIn = (b.R > .5f ? 1 : 0) + (b.G > .5f ? 1 : 0) + (b.B > .5f ? 1 : 0) >= 2; if (aIn != bIn) { return(false); } // If the change is 0 <. 1 or 2 <. 3 channels and not 1 <. 1 or 2 <. 2, it is not a clash if (a.R > .5f && a.G > .5f && a.B > .5f || a.R < .5f && a.G < .5f && a.B < .5f || b.R > .5f && b.G > .5f && b.B > .5f || b.R < .5f && b.G < .5f && b.B < .5f) { return(false); } // Find which color is which: _a, _b = the changing channels, _c = the remaining one float aa, ab, ba, bb, ac, bc; if (a.R > .5f != b.R > .5f && a.R < .5f != b.R < .5f) { aa = a.R; ba = b.R; if (a.G > .5f != b.G > .5f && a.G < .5f != b.G < .5f) { ab = a.G; bb = b.G; ac = a.B; bc = b.B; } else if (a.B > .5f != b.B > .5f && a.B < .5f != b.B < .5f) { ab = a.B; bb = b.B; ac = a.G; bc = b.G; } else { return(false); // this should never happen } } else if (a.G > .5f != b.G > .5f && a.G < .5f != b.G < .5f && a.B > .5f != b.B > .5f && a.B < .5f != b.B < .5f) { aa = a.G; ba = b.G; ab = a.B; bb = b.B; ac = a.R; bc = b.R; } else { return(false); } // Find if the channels are in fact discontinuous return(Math.Abs(aa - ba) >= threshold && Math.Abs(ab - bb) >= threshold && Math.Abs(ac - .5f) >= Math.Abs(bc - .5f)); // Out of the pair, only flag the pixel farther from a shape edge }