2016-05-05 15 views
0

Ich habe schnelle Funktionen erstellt, wo ich Farbwert senden und Triadic und Tetraden Werte zurückgeben möchten. Es funktioniert irgendwie, aber ich bin nicht glücklich über die Farbergebnisse. Kann mir bitte jemand helfen, die Formel zu verfeinern?Computing komplementäre, triadic, tetradic und analagous Farben

Ich habe einige Quellen verfolgt, aber die zurückgegebenen Farben waren zu hell oder gesättigt im Vergleich zu mehreren Online-Web-basierten Farbschemata. Ich weiß, dass es auch eine Frage der Vorliebe ist und ich mag die Ergebnisse des unten stehenden Codes, aber in einigen Fällen von Farben ist das Ergebnis einer Farbe viel zu nah an der ursprünglichen Farbe, so dass es kaum sichtbar ist. Sie gilt nur für ein paar Farben ...

I wurde mit der Formel von hier:

enter image description here

meinen Code:

func getTriadColor(color: UIColor) -> (UIColor, UIColor){ 

    var hue : CGFloat = 0 
    var saturation : CGFloat = 0 
    var brightness : CGFloat = 0 
    var alpha : CGFloat = 0 

    let triadHue = CGFloat(color.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)) 

    let triadColor1 = UIColor(hue: (triadHue + 0.33) - 1.0, saturation: saturation, brightness: brightness, alpha: alpha) 
    let triadColor2 = UIColor(hue: (triadHue + 0.66) - 1.0, saturation: saturation, brightness: brightness, alpha: alpha) 


    return (triadColor1, triadColor2) 

} 

func getTetradColor(color: UIColor) -> (UIColor, UIColor, UIColor){ 

    var hue : CGFloat = 0 
    var saturation : CGFloat = 0 
    var brightness : CGFloat = 0 
    var alpha : CGFloat = 0 

    let tetradHue = CGFloat(color.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)) 

    let tetradColor1 = UIColor(hue: (tetradHue + 0.25) - 1.0, saturation: saturation, brightness: brightness, alpha: alpha) 
    let tetradColor2 = UIColor(hue: (tetradHue + 0.5) - 1.0, saturation: saturation, brightness: brightness, alpha: alpha) 
    let tetradColor3 = UIColor(hue: (tetradHue + 0.75) - 1.0, saturation: saturation, brightness: brightness, alpha: alpha) 



    return (tetradColor1, tetradColor2, tetradColor3) 
} 

Und ich schönen sauberen Code fand auch für die Suche nach Komplementärfarbe, über die ich mich sehr freue

func getComplementColor(color: UIColor) -> UIColor{ 

    let ciColor = CIColor(color: color) 

    let compRed: CGFloat = 1.0 - ciColor.red 
    let compGreen: CGFloat = 1.0 - ciColor.green 
    let compBlue: CGFloat = 1.0 - ciColor.blue 

    return UIColor(red: compRed, green: compGreen, blue: compBlue, alpha: 1.0) 
} 
+0

Sie haben bessere Ergebnisse dieses Posting zu http://codereview.stackexchange.com – rmaddy

Antwort

2

Die Formeln in Ihrem Screenshot sind falsch, weil sie die Verwendung der Absolutwertfunktion anstelle der Modulofunktion angeben. Das heißt, zum Beispiel des Bildschirm Schuss definiert

H = | (H 0 + 180 °) - 360 ° |

aber überlegen, was das gibt für den Eingang H = 90 °:

H = | (90 ° + 180 °) - 360 ° | = | 270 ° - 360 ° | = | -90 ° | = 90 °

Glauben Sie, dass die komplementäre Farbton von H = 90 ° H = 90 °, die gleiche Farbton ist?

Die richtige Formel

H = (H + 180 °) mod 360 °

wobei „mod“ für „Modulo“ kurz ist, und bedeutet „ der Rest nach dem Teilen durch ". Mit anderen Worten, wenn die Antwort über 360 ° liegen würde, subtrahiere 360 ​​°. Für H = 90 ° ergibt dies die korrekte Antwort von H = 270 °.

Aber Sie haben dieses Problem nicht einmal in Ihrem Code, weil Sie die Absolutwertfunktion (oder die Modulo-Funktion) in Ihrem Code nicht verwendet haben. Da Sie nichts tun, um Ihre Farbtonwerte im Bereich 0 ... 1 zu belassen, werden Ihre Farbtonwerte, die kleiner als Null sind, auf Null abgeschnitten, und Ihre Farbtonwerte über einem werden auf einen ausgeschnitten (und beide Null und Eins bedeuten Rot).

Ihre getComplementColor ist auch nicht die Standarddefinition der "Komplementärfarbe".

Hier sind die richtigen Definitionen:

extension UIColor { 

    var complement: UIColor { 
     return self.withHueOffset(0.5) 
    } 

    var splitComplement0: UIColor { 
     return self.withHueOffset(150/360) 
    } 

    var splitComplement1: UIColor { 
     return self.withHueOffset(210/360) 
    } 

    var triadic0: UIColor { 
     return self.withHueOffset(120/360) 
    } 

    var triadic1: UIColor { 
     return self.withHueOffset(240/360) 
    } 

    var tetradic0: UIColor { 
     return self.withHueOffset(0.25) 
    } 

    var tetradic1: UIColor { 
     return self.complement 
    } 

    var tetradic2: UIColor { 
     return self.withHueOffset(0.75) 
    } 

    var analagous0: UIColor { 
     return self.withHueOffset(-1/12) 
    } 

    var analagous1: UIColor { 
     return self.withHueOffset(1/12) 
    } 

    func withHueOffset(offset: CGFloat) -> UIColor { 
     var h: CGFloat = 0 
     var s: CGFloat = 0 
     var b: CGFloat = 0 
     var a: CGFloat = 0 
     self.getHue(&h, saturation: &s, brightness: &b, alpha: &a) 
     return UIColor(hue: fmod(h + offset, 1), saturation: s, brightness: b, alpha: a) 
    } 
} 

Hier sind einige Beispiele von Komplementärfarben (original oben, komplementär unten):

complementary

Hier sind geteilt Komplementärfarben (Original auf oben):

split complementary

Hier sind Triade Farben (original oben):

triadic

Hier tetradic Farben (original oben) sind:

tetradic

Hier sind analoge Farben (original in der Mitte):

analagous

Hier

ist der Spielplatz ich verwendet, um diese Bilder zu erzeugen:

import XCPlayground 
import UIKit 

let view = UIView(frame: CGRectMake(0, 0, 320, 480)) 
view.backgroundColor = [#Color(colorLiteralRed: 0.9607843137254902, green: 0.9607843137254902, blue: 0.9607843137254902, alpha: 1)#] 

let vStack = UIStackView(frame: view.bounds) 
vStack.autoresizingMask = [ .FlexibleWidth, .FlexibleHeight ] 
view.addSubview(vStack) 
vStack.axis = .Vertical 
vStack.distribution = .FillEqually 
vStack.alignment = .Fill 
vStack.spacing = 10 

typealias ColorTransform = (UIColor) -> UIColor 

func tile(color color: UIColor) -> UIView { 
    let view = UIView() 
    view.translatesAutoresizingMaskIntoConstraints = false 
    view.backgroundColor = color 
    return view 
} 

func strip(transforms: [ColorTransform]) -> UIStackView { 
    let strip = UIStackView() 
    strip.translatesAutoresizingMaskIntoConstraints = false 
    strip.axis = .Vertical 
    strip.distribution = .FillEqually 
    strip.alignment = .Fill 
    strip.spacing = 0 

    let hStacks = (0 ..< transforms.count).map { (i: Int) -> UIStackView in 
     let stack = UIStackView() 
     stack.translatesAutoresizingMaskIntoConstraints = false 
     stack.axis = .Horizontal 
     stack.distribution = .FillEqually 
     stack.alignment = .Fill 
     stack.spacing = 4 
     strip.addArrangedSubview(stack) 
     return stack 
    } 

    for h in 0 ..< 10 { 
     let hue = CGFloat(h)/10 
     let color = UIColor(hue: hue, saturation: 1, brightness: 1, alpha: 1) 
     for (i, transform) in transforms.enumerate() { 
      hStacks[i].addArrangedSubview(tile(color: transform(color))) 
     } 
    } 

    return strip 
} 

vStack.addArrangedSubview(strip([ 
    { $0 }, 
    { $0.complement }])) 

vStack.addArrangedSubview(strip([ 
    { $0 }, 
    { $0.splitComplement0 }, 
    { $0.splitComplement1 }])) 

vStack.addArrangedSubview(strip([ 
    { $0 }, 
    { $0.triadic0 }, 
    { $0.triadic1 }])) 

vStack.addArrangedSubview(strip([ 
    { $0 }, 
    { $0.tetradic0 }, 
    { $0.tetradic1 }, 
    { $0.tetradic2 }])) 

vStack.addArrangedSubview(strip([ 
    { $0.analagous0 }, 
    { $0 }, 
    { $0.analagous1 }])) 

XCPlaygroundPage.currentPage.liveView = view 
+0

Vielen Dank! Das hat den Trick gemacht und ich habe mehr über die Farben gelernt. Sehr elegante Lösung, viel sauberer. In Bezug auf meinen Code, ich dachte, um zu erstellen, wenn Anweisung für das Subtrahieren von 1 aus dem Float wenn größer als 1 wie andere Verweis, die ich gefunden habe, aber Ihre Lösung ist mehr als großartig! – Alessign