I am building an app that allows users to select two colors and see the result of mixing them. For example, the user selects red (#ff0000) and blue (#0000ff) and the result is purple (#ff00ff).
I started trying by writing 3 methods in a UIColor extension:
hexColorconverts anIntto a colorintValuereturns the color's integer representation. i.e. the reverse ofhexColorhexDescriptionreturns the string representation of the color, such as "#ff00ff"
Here are the implementations, just in case this is needed:
public static func hexColor(hex: Int32) -> UIColor {
    return UIColor.init(red: CGFloat((hex>>16)&0xFF) / 255.0, green: CGFloat((hex>>8)&0xFF) / 255.0, blue: CGFloat(hex&0xFF) / 255.0, alpha: 1.0)
}
public func intValue() -> Int {
    var hexString = self.hexDescription()
    hexString = hexString.substringFromIndex(hexString.startIndex.successor())
    return Int(hexString, radix: 16)!
}
public func hexDescription() -> String {
    var rF: CGFloat = 0,
    gF: CGFloat = 0,
    bF: CGFloat = 0,
    aF: CGFloat = 0
    self.getRed(&rF, green: &gF, blue: &bF, alpha: &aF)
    let r = Int(rF * 255.0)
    let g = Int(gF * 255.0)
    let b = Int(bF * 255.0)
    return "#" + String(format: "%02x%02x%02x", r, g, b)
}
Then I thought about how can I actually mix the colors. My first try is to get the average of the HSV values:
public func mixWith(color: UIColor) -> UIColor {
    var myHue: CGFloat = 0
    var mySat: CGFloat = 0
    var myVal: CGFloat = 0
    var otherHue: CGFloat = 0
    var otherSat: CGFloat = 0
    var otherVal: CGFloat = 0
    self.getHue(&myHue, saturation: &mySat, brightness: &myVal, alpha: nil)
    color.getHue(&otherHue, saturation: &otherSat, brightness: &otherVal, alpha: nil)
    let averageHue = (myHue + otherHue) / 2.0
    let averageSat = (mySat + otherSat) / 2.0
    let averageVal = (myVal + otherVal) / 2.0
    return UIColor(hue: averageHue, saturation: averageSat, brightness: averageVal, alpha: 1.0)
}
But this failed. When I mix blue and yellow, I get #00ff7f but it should be white.
Then I try to get the average of the int values:
public func mixWith2(color: UIColor) -> UIColor {
    let average = (self.intValue() + color.intValue()) / 2
    return UIColor.hexColor(Int32(average))
}
But again, blue mix with yellow is not white using the above method.
At the end, I decided to use bitwise operators. I tested |, & and ^. Surprisingly, this returns white!
UIColor.hexColor(Int32(UIColor.blueColor().intValue() | 
    UIColor.yellowColor().intValue()))
and so does this:
UIColor.hexColor(Int32(UIColor.blueColor().intValue() ^ 
    UIColor.yellowColor().intValue()))
I did some other tests and this method passed all of them!
Is this a correct (gives correct result all the time) method of mixing two colors? If yes, how does it work?