【问题标题】:How to transform UIBezierPath/CGPath within a reference frame?如何在参考框架内转换 UIBezierPath/CGPath?
【发布时间】:2017-11-03 14:51:54
【问题描述】:

我需要缩放路径,但应该使用更大的、封闭的、任意矩形来执行转​​换,而不是使用路径的边界。 (即“画布”。)

我的问题是如何在不绘制画布的情况下做到这一点。

例如,在下图中:

  • 蓝色方块表示路径的原始矩形(在本例中为火箭)。

  • 紫色矩形表示“画布”或父坐标系的边界。

  • 紫色矩形仅用于定位;不被绘制。空格同样会被忽略。

  • 我需要缩放画布,并保留转换后的火箭路径(用于剪辑操作、缓存等)。即我需要在转换后丢失紫色矩形。

理想情况下,我会使用类似以下小说的内容:

var canvasPath = UIBezierPath(rect: canvasRect)
canvasPath.append(rocketPath, withName: "rocket")
canvasPath.doSomeTransformOrOther()
let transformedRocketPath = canvasPath.path(forName: "rocket")

遗憾的是,即使 UIBezierPathCGPath 像这样处理子路径,神奇的 append(:withName:) 和 path(forName:) 方法也不存在。唉!

另一种方法是临时向路径添加点,每个画布角一个。然后,变换路径。然后,使用 CGPath 的(丑陋的)apply(info:function:) 方法走路径,在没有画布点的情况下重建路径,然后绘制结果。 (是的,把伏特加递过去。)

谁能提供更理智的解决方案?感谢您的帮助我

(对于那些感兴趣的人:这与如何将不规则形状的路径居中的问题有关。紫色矩形表示最小包围圆的边界。用 MEC 的坐标系绘制火箭将使火箭看起来更直观居中,与使用 boundingBox 相比。)

更多信息:Fitting UIBezierPath/CGPath to circle

【问题讨论】:

    标签: ios core-graphics uibezierpath cgpath


    【解决方案1】:

    这是我解决问题的最后一种方法:使用将随路径缩放的“画布”矩形。然后在平移(缩放)路径时使用画布矩形。这保持了相对于画布的路径

    这样做的一个例子是从 SVG 获取路径,然后缩放,定位路径不是相对于路径的边界,而是相对于 SVG 的原生尺寸('viewbox')。这反过来又允许路径在 SVG 画布内的相对定位。

    extension UIBezierPath
    {
        func scaled(usingCanvasSize canvasSize: CGSize,
                scale: CGFloat) -> CGRect
        {
            let canvasRect = CGRect(origin: .zero, size: canvasSize)
            let canvasPath = UIBezierPath(rect: canvasRect)
    
            let scaleTransform = CGAffineTransform(scaleX: scale, y: scale)
            canvasPath.apply(scaleTransform)
            self.apply(scaleTransform)
    
            return canvas.bounds
        }
    }
    
    // Usage:
    
    let nativeSVGSize: CGSize = ...   // 'viewBox' size of SVG
    let path = UIBezierPath(...)      // From SVG, wherever.
    let scale: CGFloat = 0.5
    
    
    // Scale the path, get a "canvas" rect.
    let canvasRect = path.scaled(usingCanvasSize: nativeSVGSize,
            scale: scale)
    
    // Use the (scaled) canvas for info about the path from now on.
    
    // e.g. move the path using the center of the canvasRect.
    
    let pathCenter = canvasRect.center
    let destCenter = ... 
    let movement = CGPoint(x: destCenter.x - pathCenter.x,
            y: destCenter.y - pathCenter.y)
    
    path.apply(CGAffineTransform(translationX: movement.x,
            y: movement.y))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多