How to rotate UIBezierPath around center of its ow

2020-03-30 04:16发布

问题:

Lets say we have a UIBezierPath... the bounds of which are perfectly square... like this:

func getExponentPath(rotate180: Bool) -> UIBezierPath {

    // establish unit of measure (grid) based on this containing view's bounds... (not to be confused with this bezierpath's bounds)

    let G = bounds.width / 5

    let exponentPath = UIBezierPath()

    let sstartPoint = CGPoint(x:(3.8)*G,y:(1.2)*G)
    exponentPath.move(to: sstartPoint)
    exponentPath.addLine(to: CGPoint(x:(5)*G,y:(1.2)*G))
    exponentPath.addLine(to: CGPoint(x:(4.4)*G,y:(0.2)*G))
    exponentPath.addLine(to: CGPoint(x:(5)*G,y:(0.2)*G))
    exponentPath.addLine(to: CGPoint(x:(5)*G,y:(0)*G))
    exponentPath.addLine(to: CGPoint(x:(3.8)*G,y:(0)*G))
    exponentPath.addLine(to: CGPoint(x:(3.8)*G,y:(0.2)*G))
    exponentPath.addLine(to: CGPoint(x:(4.4)*G,y:(0.2)*G))
    exponentPath.addLine(to: sstartPoint)

    exponentPath.close()

    // this does not work:
    // if rotate180 { exponentPath.apply(CGAffineTransform(rotationAngle: CGFloat.pi)) }

    return exponentPath

}

If rotated, this bezierpath still needs to occupy the exact same area within its containing view.

I can only presume this does not work because there's some problem with the center of rotation not being what I intend... although I get the same (wrong) result even when saying "rotate by 0."

So how can the path be rotated around it's own center point?

It seems like there should be a simple linear algebra matrix multiplication type thingy that could be applied to the set of points. =T

回答1:

I don't think you need the rotation. To draw the same shape upside down, just flip it:

        exponentPath.apply(CGAffineTransform(scaleX: 1, y: -1))
        exponentPath.apply(CGAffineTransform(translationX: 0, y: G))


回答2:

extension UIBezierPath
{
    func rotateAroundCenter(angle: CGFloat)
    {
        let center = self.bounds.getCenter()
        var transform = CGAffineTransform.identity
        transform = transform.translatedBy(x: center.x, y: center.y)
        transform = transform.rotated(by: angle)
        transform = transform.translatedBy(x: -center.x, y: -center.y)
        self.apply(transform)
    }
}


回答3:

So in case anyone else is trying to rotate a UIBezierPath on the center of it's own bounding rectangle... this is the actual working solution arrived at with help from previous answers/comments:

func getExponentPath(rotationAngle: CGFloat) -> UIBezierPath {

    // ...

    let x_translation = -( (bounds.width) - ( exponentPath.bounds.width/2) )
    let y_translation = -exponentPath.bounds.height/2

    exponentPath.apply(CGAffineTransform(translationX: x_translation, y: y_translation))
    exponentPath.apply(CGAffineTransform(rotationAngle: rotationAngle))
    exponentPath.apply(CGAffineTransform(translationX: -x_translation, y: -y_translation))

    // ...

}