Allow a slider to set the colorRotation in radians

This commit is contained in:
Eryn Wells 2018-10-09 16:51:35 -07:00
parent e2886f9aad
commit 1b8fc1feb7
5 changed files with 74 additions and 6 deletions

View file

@ -43,13 +43,21 @@ extension Float4 {
} }
} }
extension Matrix2x2 { extension Matrix3x3 {
static func rotation(theta: Float) -> Matrix2x2 { static func rotation(angle theta: Float) -> Matrix3x3 {
return self.init(rows: [ return self.init(rows: [
Float2(cos(theta), -sin(theta)), Float3(cos(theta), -sin(theta), 0.0),
Float2(sin(theta), cos(theta)), Float3(sin(theta), cos(theta), 0.0),
Float3(0, 0, 1),
]) ])
} }
static func translation(dx: Float, dy: Float) -> Matrix3x3 {
var mat = self.init(1.0)
mat.columns.2.x = dx
mat.columns.2.y = dy
return mat
}
} }
extension Matrix4x4 { extension Matrix4x4 {

View file

@ -49,7 +49,7 @@ public struct Parameters {
public var color2 = Float4() public var color2 = Float4()
public var color3 = Float4() public var color3 = Float4()
public var colorRotation = Matrix2x2(1.0) public var colorTransform = Matrix3x3(1.0)
public var colorStyle: ColorStyle { public var colorStyle: ColorStyle {
get { get {
@ -303,6 +303,19 @@ public class Field {
didChange = true didChange = true
} }
if let rotation = userInfo["colorRotation"] as? Float {
// Create a transform matrix to handle it
let dx = Float(size.x) / 2.0
let dy = Float(size.y) / 2.0
let translate = Matrix3x3.translation(dx: dx, dy: dy)
let rotate = Matrix3x3.rotation(angle: rotation)
let invTranslate = Matrix3x3.translation(dx: -dx, dy: -dy)
parameters.colorTransform = invTranslate * rotate * translate
// Save the value to defaults
defaults.colorRotation = rotation
didChange = true
}
if didChange { if didChange {
populateParametersBuffer() populateParametersBuffer()
} }

View file

@ -92,6 +92,21 @@ extension UserDefaults {
} }
} }
public var colorRotation: Float {
get {
if let obj = object(forKey: "colorRotation") as? NSNumber {
return obj.floatValue
} else {
let defaultValue: Float = 0.0
set(defaultValue, forKey: "colorRotation")
return defaultValue
}
}
set {
set(newValue, forKey: "colorRotation")
}
}
func float4(forKey key: String) -> Float4? { func float4(forKey key: String) -> Float4? {
guard let values = array(forKey: key) as? [Float], values.count >= 4 else { guard let values = array(forKey: key) as? [Float], values.count >= 4 else {
return nil return nil

View file

@ -14,6 +14,10 @@ private struct StyleItem {
let name: String let name: String
let tag: Int let tag: Int
let colorNames: [String] let colorNames: [String]
var allowsRotation: Bool {
return colorNames.count > 1
}
} }
public class PreferencesViewController: NSViewController { public class PreferencesViewController: NSViewController {
@ -43,6 +47,14 @@ public class PreferencesViewController: NSViewController {
private var colorStackView = NSStackView() private var colorStackView = NSStackView()
private var colorViews = [ColorView]() private var colorViews = [ColorView]()
private lazy var colorRotationSlider: RotationSliderView = {
let rotationSlider = RotationSliderView(label: NSLocalizedString("Color θ", comment: "name of color rotation slider"))
rotationSlider.slider.target = self
rotationSlider.slider.action = #selector(PreferencesViewController.sliderDidUpdate(sender:))
rotationSlider.slider.floatValue = self.defaults.colorRotation
return rotationSlider
}()
private lazy var targetSlider: SliderView = { private lazy var targetSlider: SliderView = {
let targetSlider = SliderView(label: NSLocalizedString("Target", comment: "name of the target slider")) let targetSlider = SliderView(label: NSLocalizedString("Target", comment: "name of the target slider"))
if #available(OSX 10.12.2, *) { if #available(OSX 10.12.2, *) {
@ -135,6 +147,7 @@ public class PreferencesViewController: NSViewController {
colorStackView.addArrangedSubview(colorView) colorStackView.addArrangedSubview(colorView)
colorViews.append(colorView) colorViews.append(colorView)
} }
colorStackView.addArrangedSubview(colorRotationSlider)
colorStackView.addArrangedSubview(targetSlider) colorStackView.addArrangedSubview(targetSlider)
colorStackView.addArrangedSubview(featherSlider) colorStackView.addArrangedSubview(featherSlider)
@ -217,6 +230,9 @@ public class PreferencesViewController: NSViewController {
colorView.isHidden = true colorView.isHidden = true
} }
} }
// Hide the color rotation slider if there's only one color
colorRotationSlider.isHidden = styleItem.colorNames.count == 1
} }
func postColorNotification() { func postColorNotification() {
@ -229,6 +245,7 @@ public class PreferencesViewController: NSViewController {
} }
info["target"] = targetSlider.slider.floatValue info["target"] = targetSlider.slider.floatValue
info["feather"] = featherSlider.slider.floatValue info["feather"] = featherSlider.slider.floatValue
info["colorRotation"] = colorRotationSlider.slider.floatValue
NotificationCenter.default.post(name: PreferencesDidChange_Color, object: nil, userInfo: info) NotificationCenter.default.post(name: PreferencesDidChange_Color, object: nil, userInfo: info)
} }
} }
@ -304,3 +321,18 @@ class SliderView: ParameterView {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
} }
class RotationSliderView: SliderView {
override init(label: String) {
super.init(label: label)
let slider = control as! NSSlider
slider.minValue = -Double.pi
slider.maxValue = Double.pi
slider.numberOfTickMarks = 5
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View file

@ -44,7 +44,7 @@ typedef struct {
float target; float target;
float feather; float feather;
float4 colors[4]; float4 colors[4];
float2x2 colorRotation; float3x3 colorTransform;
} Parameters; } Parameters;
typedef float3 Ball; typedef float3 Ball;