【问题标题】:Find points between the curve which is draw by given points找到由给定点绘制的曲线之间的点
【发布时间】:2019-02-03 21:41:54
【问题描述】:

我的任务是通过给定点绘制曲线路径。我通过使用 CGMutablepath 来完成这项工作。但是有时我需要根据给出“x”点来找到“y”点来显示价值。我附上了下面的示例图片。

我用黑点表示的点。如果我给出路径中某处的“x”,我需要找到一个“y”点。如果有人知道解决方案,请帮助我。

【问题讨论】:

  • 如何描述生成的CGMutablepath?也许您对每个路径部分都有公式/表达式/方程式。
  • 这是什么曲线?

标签: ios math graph charts


【解决方案1】:

你很可能有一个分段参数插值,即形式

x(t) = Pi(t),
y(t) = Qi(t)

其中PiQi 是已知系数的多项式。

如果指定x,则必须求解it 的方程x = Pi(t)。要找到i,您需要知道Pi 的范围(对于多项式来说不太难)。然后当你有i 时,你必须求解一个多项式方程。这对于三次曲线很好,但对于更高的度数有问题。

根据数据,it 可能有几种解决方案。

那么当你知道t,计算y(t)

【讨论】:

    【解决方案2】:

    我通过使用三次函数解决了这个问题。我提到了这个video

    //
    //  CubicFunction.swift
    //
    //  Created by Karthik Venkatesh on 30/08/18.
    //  Copyright © 2018 karthik. All rights reserved.
    //
    
    import Foundation
    import Accelerate
    
    extension Array {
        func chunked(into size: Int) -> [[Element]] {
            return stride(from: 0, to: count, by: size).map {
                Array(self[$0 ..< Swift.min($0 + size, count)])
            }
        }
    }
    
    class CubicFunction {
    
        var matrix_a = [[CGFloat]]()
        var matrix_b = [CGFloat]()
    
        var coefficients = [CGFloat]()
    
        init(withPoints points: [CGPoint]) {
            self.constructMatrixA(forXValues: points.map{ $0.x })
            let matrixAItemsPerRow = matrix_a.first?.count ?? 0
            self.constructMatrixB(forXValues: points.map{ $0.y })
            var matrix_a_1d = [CGFloat]()
            for row in matrix_a { matrix_a_1d.append(contentsOf: row) }
            let inversed = self.invert(matrix: matrix_a_1d.map{ Double($0) }).map{ CGFloat($0) }
            let inversed_matrix = inversed.chunked(into: matrixAItemsPerRow)
            self.coefficients.append(contentsOf: self.multiply(matrixA: inversed_matrix, matrixB: matrix_b))
       }
    
       private func constructMatrixA(forXValues values: [CGFloat]) {
            for value in values {
                var row = [CGFloat]()
                for i in stride(from: values.count - 1, to: 0, by: -1) {
                    row.append(pow(value,CGFloat(i)))
                }
                row.append(1)
                matrix_a.append(row)
            }
        }
    
        private func constructMatrixB(forXValues values: [CGFloat]) {
            self.matrix_b.append(contentsOf: values)
        }
    
        private func invert(matrix : [Double]) -> [Double] {
            var inMatrix = matrix
            var N = __CLPK_integer(sqrt(Double(matrix.count)))
            var pivots = [__CLPK_integer](repeating: 0, count: Int(N))
            var workspace = [Double](repeating: 0.0, count: Int(N))
            var error : __CLPK_integer = 0
    
            withUnsafeMutablePointer(to: &N) {
                dgetrf_($0, $0, &inMatrix, $0, &pivots, &error)
                dgetri_($0, &inMatrix, $0, &pivots, &workspace, $0, &error)
            }
            return inMatrix
        }
    
        private func multiply(matrixA: [[CGFloat]], matrixB: [CGFloat]) -> [CGFloat] {
            if matrixA[0].count != matrixB.count { return [] }
            var result: [CGFloat] = [CGFloat]()
            for i in 0..<matrixA.count {
                let row = matrixA[i]
                var value: CGFloat = 0
                for j in 0..<row.count {
                    value = value + (row[j] * matrixB[j])
                }
                result.append(value)
            }
            return result
        }
    
        func y(forX x: CGFloat) -> CGFloat? {
            var y: CGFloat? = nil
            for index in 0..<self.coefficients.count {
                y = (y ?? 0) + (self.coefficients[index] * pow(x, CGFloat(self.coefficients.count - 1 - index)))
            }
            return y
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-29
      • 1970-01-01
      • 1970-01-01
      • 2020-03-25
      • 2019-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多