How do I draw a cosine or sine curve in Swift?

﹥>﹥吖頭↗ 提交于 2019-12-30 12:59:36

问题


I've been trying to figure out how to use UIBezierPath for this project, but I don't know how to implement this kind of drawing. I can draw a circle and arcs and straight lines, but I am feeling pretty lost on this one. Appreciate the help


回答1:


To draw a sine wave on a UIBezierPath called path, draw a number of line segments using path.addLine(to:). The trick is to convert the angle (0 to 360) to the x coordinate of a point, and sin(x) to the y coordinate of a point.

Here is an example:

class SineView: UIView{
    let graphWidth: CGFloat = 0.8  // Graph is 80% of the width of the view
    let amplitude: CGFloat = 0.3   // Amplitude of sine wave is 30% of view height

    override func draw(_ rect: CGRect) {
        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))
        }

        UIColor.black.setStroke()
        path.stroke()
    }
}

let sineView = SineView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
sineView.backgroundColor = .white

Here it is running in a Playground:


@Rob updated this code making it @IBDesignable with @IBInspectable properties in addition to adding a periods property. Check out his answer here.




回答2:


This allows you to place a sine wave inside a rect:

    func generateWave(cycles: Int, inRect: CGRect, startAngleInDegrees: CGFloat = 0) -> UIBezierPath {
        let dx = inRect.size.width
        let amplitude = inRect.size.height
        let scaleXToDegrees = 1 / (inRect.size.width / 360.0 / CGFloat(cycles))
        let path = UIBezierPath()
        for x in stride(from: 0, to: dx + 5, by: 5) {
            let y = sin(D2R(startAngleInDegrees + x * scaleXToDegrees)) * amplitude / 2
            let p = CGPoint(x: x + inRect.origin.x, y: y + inRect.origin.y)
            if x == 0 {
                path.move(to: p)
            } else {
                path.addLine(to: p)
            }
        }
        return path
    }

To animate:

    override func update(_ currentTime: TimeInterval) {
        shape?.removeFromParent()

        let path = generateWave(cycles: 7, inRect: targetRect, startAngleInDegrees: currentStartAngle)
        shape = SKShapeNode(path: path.cgPath)
        shape!.strokeColor = .red
        shape!.lineWidth = 1
        self.addChild(shape!)
        currentStartAngle += 5
    }


来源:https://stackoverflow.com/questions/40230312/how-do-i-draw-a-cosine-or-sine-curve-in-swift

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