Draw sine wave with frequency?

Deadly 提交于 2019-12-07 19:54:51

问题


I am drawing one period of a sine wave with:

let width = rect.width
let height = rect.height

let origin = CGPoint(x: width * (1 - graphWidth) / 2, y: height * 0.50)

let path = UIBezierPath()
path.move(to: origin)

for angle in stride(from: 5.0, through: 360.0, by: 5.0) {
    let x = origin.x + CGFloat(angle/360.0) * width * graphWidth
    let y = origin.y - CGFloat(sin(angle/180.0 * Double.pi)) * height * amplitude
    path.addLine(to: CGPoint(x: x, y: y))
}

Globals.sharedInstance.palleteGlowGreen.setStroke()
path.stroke()

How would I:

  1. Draw multiple periods for the same width (now its 0-360)
  2. Change number 1 (num of periods) dynamically so you see the wave squeezing.

回答1:


Just multiply the angle by periods:

@IBDesignable
class SineWaveView: UIView {

    @IBInspectable
    var graphWidth: CGFloat = 0.90  { didSet { setNeedsDisplay() } }

    @IBInspectable
    var amplitude: CGFloat = 0.20   { didSet { setNeedsDisplay() } }

    @IBInspectable
    var periods: CGFloat = 1.0      { didSet { setNeedsDisplay() } }

    override func draw(_ rect: CGRect) {
        let width = bounds.width
        let height = bounds.height

        let origin = CGPoint(x: width * (1 - graphWidth) / 2, y: height * 0.50)

        let path = UIBezierPath()
        path.move(to: origin)

        for angle in stride(from: 5.0, through: 360.0 * periods, by: 5.0) {
            let x = origin.x + angle/(360.0 * periods) * width * graphWidth
            let y = origin.y - sin(angle/180.0 * .pi) * height * amplitude
            path.addLine(to: CGPoint(x: x, y: y))
        }

        Globals.sharedInstance.palleteGlowGreen.setStroke()
        path.stroke()
    }

}

By the way, by making a change in periods call setNeedsDisplay, that means that when you update periods, the graph will be automatically redrawn.


And, rather than iterating through degrees, but then converting everything back to radians, I might just stay in radians:

override func draw(_ rect: CGRect) {
    let width = bounds.width
    let height = bounds.height

    let origin = CGPoint(x: width * (1 - graphWidth) / 2, y: height * 0.50)
    let maxAngle: CGFloat = 2 * .pi * periods
    let iterations = Int(min(1000, 100 * periods))

    let point = { (angle: CGFloat) -> CGPoint in
        let x = origin.x + angle/maxAngle * width * self.graphWidth
        let y = origin.y - sin(angle) * height * self.amplitude
        return CGPoint(x: x, y: y)
    }

    let path = UIBezierPath()
    path.move(to: point(0))

    for i in 1 ... iterations {
        path.addLine(to: point(maxAngle * CGFloat(i) / CGFloat(iterations)))
    }

    Globals.sharedInstance.palleteGlowGreen.setStroke()
    path.stroke()
}


来源:https://stackoverflow.com/questions/40411198/draw-sine-wave-with-frequency

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!