绘制Siri的WaveForm效果

时间:2017-02-16 19:18:37

标签: ios swift graphics core spectrum

我一直在努力了解如何在iOS中绘制Siri的波形效果,并且遇到了this伟大的存储库。 最终结果如下:

enter image description here

但是我很难理解生成波形的代码发生了什么。我可以生成一个静态正弦波,但是,我似乎并不理解。

特别是当我们计算y的值时,为什么它必须是:

let y = scaling * maxAmplitude * normedAmplitude * sin(CGFloat(2 * M_PI) * self.frequency * (x / self.bounds.width) + self.phase) + self.bounds.height/2.0

源代码:

 //MARK : Properties 


let density : CGFloat =        1
let frequency : CGFloat =      1.5
var phase :CGFloat =           0
var phaseShift:CGFloat =      -0.15
var numberOfWaves:Int =        6
var primaryLineWidth:CGFloat = 1.5
var idleAmplitude:CGFloat =    0.01
var waveColor:UIColor =        UIColor.white
var amplitude:CGFloat =        1.0 {
    didSet {
        amplitude = max(amplitude, self.idleAmplitude)
        self.setNeedsDisplay()
    }
}

方法

  override open func draw(_ rect: CGRect) {
    // Convenience function to draw the wave
    func drawWave(_ index:Int, maxAmplitude:CGFloat, normedAmplitude:CGFloat) {
        let path = UIBezierPath()
        let mid = self.bounds.width/2.0

        path.lineWidth = index == 0 ? self.primaryLineWidth : self.secondaryLineWidth

        for x in Swift.stride(from:0, to:self.bounds.width + self.density, by:self.density) {
            // Parabolic scaling
            let scaling = -pow(1 / mid * (x - mid), 2) + 1

  // The confusing part /////////////////////////////////////////
            let y = scaling * maxAmplitude * normedAmplitude *
     sin(CGFloat(2 * M_PI) * self.frequency * (x / self.bounds.width) + self.phase)  
+ self.bounds.height/2.0

  //////////////////////////////////////////////////////////////////
            if x == 0 {
                path.move(to: CGPoint(x:x, y:y))
            } else {
                path.addLine(to: CGPoint(x:x, y:y))
            }
        }

        path.stroke()
    }

    let context = UIGraphicsGetCurrentContext()
    context?.setAllowsAntialiasing(true)

    self.backgroundColor?.set()
    context?.fill(rect)

    let halfHeight = self.bounds.height / 2.0
    let maxAmplitude = halfHeight - self.primaryLineWidth

    for i in 0 ..< self.numberOfWaves {
        let progress = 1.0 - CGFloat(i) / CGFloat(self.numberOfWaves)
        let normedAmplitude = (1.5 * progress - 0.8) * self.amplitude
        let multiplier = min(1.0, (progress/3.0*2.0) + (1.0/3.0))
        self.waveColor.withAlphaComponent(multiplier * self.waveColor.cgColor.alpha).set()
        drawWave(i, maxAmplitude: maxAmplitude, normedAmplitude: normedAmplitude)
    }
    self.phase += self.phaseShift
}

两个for循环看起来都很数学,我不知道那里发生了什么。 提前谢谢。

0 个答案:

没有答案