使用UIBezierPath绘制极坐标函数

时间:2015-03-23 18:23:08

标签: ios objective-c core-graphics uibezierpath polar-coordinates

是否可以使用UIBezierPath绘制极坐标函数?不仅仅是圈子,我还谈论心形,limacons,lemniscates等。基本上我有一个UIView,并且想在视图中绘制形状。

2 个答案:

答案 0 :(得分:3)

对于这样的形状没有内置方法,但是你总是可以通过一系列非常短的直线来近似它们。我有理由以这种方式近似一个圆,一个约有100条直线的圆看起来与用ovalInRect绘制的圆相同。这样做最容易,首先在极坐标中创建点,然后在将点数组传递给我将线添加到贝塞尔曲线路径的方法之前将它们转换为直角坐标。

答案 1 :(得分:2)

这是我的快速帮助函数(已完全注释),该函数根据极坐标函数在给定的CGRect中生成(x,y)坐标。

func cartesianCoordsForPolarFunc(frame: CGRect, thetaCoefficient:Double, thetaCoefficientDenominator:Double, cosScalar:Double, iPrecision:Double) -> Array<CGPoint> {

    // Frame: The frame in which to fit this curve.
    // thetaCoefficient: The number to scale theta by in the cos.
    // thetaCoefficientDenominator: The denominator of the thetaCoefficient
    // cosScalar: The number to multiply the cos by.
    // iPrecision: The step for continuity. 0 < iPrecision <= 2.pi. Defaults to 0.1

    // Clean inputs
    var precision:Double = 0.1 // Default precision
    if iPrecision != 0 {// Can't be 0.
        precision = iPrecision
    }

    // This is ther polar function
    // var theta: Double = 0 //  0 <= theta <= 2pi
    // let r = cosScalar * cos(thetaCoefficient * theta)

    var points:Array<CGPoint> = [] // We store the points here
    for theta in stride(from: 0, to: 2*Double.pi * thetaCoefficientDenominator, by: precision) { // Try to recreate continuity
        let x = cosScalar * cos(thetaCoefficient * theta) * cos(theta) // Convert to cartesian
        let y = cosScalar * cos(thetaCoefficient * theta) * sin(theta) // Convert to cartesian

        let scaled_x = (Double(frame.width) - 0)/(cosScalar*2)*(x-cosScalar)+Double(frame.width) // Scale to the frame
        let scaled_y = (Double(frame.height) - 0)/(cosScalar*2)*(y-cosScalar)+Double(frame.height) // Scale to the frame

        points.append(CGPoint(x: scaled_x, y:scaled_y)) // Add the result
    }

    return points
}

鉴于上述几点,这是一个如何绘制UIBezierPath的示例。在我的示例中,这是在自定义UIView函数中,我将其称为UIPolarCurveView。

let flowerPath = UIBezierPath() // Declare my path

// Custom Polar scalars
let k: Double = 9/4
let length = 50

// Draw path
let points = cartesianCoordsForPolarFunc(frame: frame, thetaCoefficient: k, thetaCoefficientDenominator:4 cosScalar: length, iPrecision: 0.01)      flowerPath.move(to: points[0])
for i in 2...points.count {         
       flowerPath.addLine(to: points[i-1])
}

flowerPath.close()

结果如下: Graph of the polar curve given in the example PS:如果计划在同一帧中包含多个图形,请确保通过将第二个cosScalar设为所使用的cosScalars中的最大for x, y in L来修改比例缩放。示例中的功能。