Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何使用UIBezierPath创建包含数据点的曲线图?_Ios_Swift_Uikit - Fatal编程技术网

Ios 如何使用UIBezierPath创建包含数据点的曲线图?

Ios 如何使用UIBezierPath创建包含数据点的曲线图?,ios,swift,uikit,Ios,Swift,Uikit,我正在尝试使用UIBezierPath创建折线图。我的目标是给这个图表设置动画,让它看起来是“波浪形的”。但我似乎无法找到镜像数据的路径 编辑:添加数据点 let dataPoints: [Double] func wave(at elapsed: Double) -> UIBezierPath { let amplitude = CGFloat(50) - abs(fmod(CGFloat(elapsed/2), 3) - 1.5) * 100 func f(_ x:

我正在尝试使用
UIBezierPath
创建折线图。我的目标是给这个图表设置动画,让它看起来是“波浪形的”。但我似乎无法找到镜像数据的路径

编辑:添加数据点

let dataPoints: [Double]


func wave(at elapsed: Double) -> UIBezierPath {
    let amplitude = CGFloat(50) - abs(fmod(CGFloat(elapsed/2), 3) - 1.5) * 100
    func f(_ x: Int) -> CGFloat {
        return sin(((CGFloat(dataPoints[x]*100) / bounds.width) + CGFloat(elapsed/2)) * 4 * .pi) * amplitude + bounds.midY
    }
    let path = UIBezierPath()
    path.move(to: CGPoint(x: 0, y: f(0)))
    for x in 1..<dataPoints.count {
        path.addLine(to: CGPoint(x: CGFloat(x), y: f(x)))
    }
    return path
}
让数据点:[加倍]
func wave(在经过时:双)->UIBezierPath{
让振幅=CGFloat(50)-abs(fmod(CGFloat(2),3)-1.5)*100
func f(x:Int)->CGFloat{
返回sin(((CGFloat(数据点[x]*100)/bounds.width)+CGFloat(经过/2))*4*.pi)*振幅+bounds.midY
}
let path=UIBezierPath()
移动路径(到:CGPoint(x:0,y:f(0)))
对于1中的x..一些问题:

  • 您定义了
    f(:)
    ,但没有使用它,而是使用了
    dataPoints
    (我看不到您在任何地方填充)。直接使用
    f
    函数可能是最简单的方法

  • 您正在向路径添加三次Bézier曲线,但您的控制点是相同的数据点。这不会提供平滑。控制点实际上应该是
    x
    值前后的点,沿着与所讨论的曲线相切的直线(例如,沿数据点定义的直线的坡度,也称为曲线的一阶导数)

    要做到这一点并不难,但简单的解决方案是只使用
    addLine
    。如果使用足够的数据点,它看起来会很平滑

  • 当您这样做时,如果仅使用12个数据点,则不会是一条平滑的正弦曲线。相反,请使用更大的数字(120或360或其他任何数字)。对于单个正弦曲线,不要担心数据点的数量,除非您开始发现性能问题


  • 你的
    CGPoint
    值中的
    x
    值比你可能想要的小。如果你只从0开始。不清楚。你能给我们画出想要的结果吗?你只是想要一条平滑的曲线通过一些给定的点吗?看起来像是和其他点的重复。顺便说一句,尼克,我注意到你问了很多问题,但还没有回答如果有人回答一个问题,你可以考虑接受答案。参见Matt,FWW,当试图平滑随机数据点(例如对应于用户手势的点)时,那些泛型是很好的。,但在这样的情况下,用于为数据点生成的函数是已知的和固定的,采用一阶导数来查找切线将更加高效和准确。您已经添加了
    dataPoints
    变量的声明,但您尚未共享填充该数组的任何代码。而且不清楚为什么需要它,而不仅仅是使用
    f(:)
    直接保存,如下图所示。我想当您调用
    f
    时,您可以将结果保存在该数组中,但我不明白您为什么需要/想要这样做。出于某种原因,您需要保存结果吗?我刚刚在代码中添加了我预期的数据点使用情况。这些数据点填充了百分比值(0-100)我正在尝试将路径与这些值的折线图相匹配。FWIW,这对在各种设备上保持60 fps的速度没有问题,包括旧的iPhone6,即使使用未优化的调试版本。
    func wave(at elapsed: Double) -> UIBezierPath {
        let amplitude = CGFloat(50) - abs(fmod(CGFloat(elapsed/2), 3) - 1.5) * 40
        func f(_ x: Int) -> CGFloat {
            return sin(((CGFloat(x) / bounds.width) + CGFloat(elapsed/2)) * 4 * .pi) * amplitude + bounds.midY
        }
        let path = UIBezierPath()
        path.move(to: CGPoint(x: 0, y: f(0)))
        for x in 1...Int(bounds.width) {
            path.addLine(to: CGPoint(x: CGFloat(x), y: f(x)))
        }
        return path
    }