确定Swift中矩形的左上角,右上角,左下角和右下角位置(优雅的解决方案)

时间:2018-07-25 11:12:04

标签: swift

我想找到一个优雅的解决方案,以给定一个点列表来识别矩形的角(我确定将定义一个矩形)。

假设我们有以下CGPoint数组:

var points:[CGPoint] = []
points.append(CGPoint(x:1, y:0)) //TL
points.append(CGPoint(x:3, y:0)) //TR
points.append(CGPoint(x:1, y:2)) //BL
points.append(CGPoint(x:3, y:2)) //BR

要理解TopLeft拐角处在索引0处,Top Right处在索引1处等等,哪一种是一种优雅的解决方案?

我可以多次遍历该数组并使用比较来找到它……您可以考虑使用sortfilter来获得更好的解决方案吗?

编辑:请注意,点数组是无序的。我没有确切的顺序。

2 个答案:

答案 0 :(得分:2)

您可以使用map / reduce实现相对简单的语法。假设:

    var points: [CGPoint] = []
    points.append(CGPoint(x: 3, y: 6))
    points.append(CGPoint(x: 4, y: 6))
    points.append(CGPoint(x: 4, y: 2))
    points.append(CGPoint(x: 3, y: 2))

然后,您可以:

    let minX = points.map { $0.x } .reduce(points[0].x) { min($0,$1) }

此时minX =3。您也可以使用sorted(by:)

    let minX = points.sorted { $0.x < $1.x }.first!.x

两者都具有处理由点构建的任何形状的优点。 Matt还建议在数组上使用min(),如下所示:

    let minX = points.min { $0.x < $1.x }!.x

我想这很干净。

哦,还有更多的书籍……如果要在很多地方将点转换为CGRect,则可以创建一个CGRect扩展名:

extension CGRect {
    init(from points: [CGPoint]) {
        let xAxis = points.sorted { $0.x < $1.x }
        let yAxis = points.sorted { $0.y < $1.y }
        self.init(x: xAxis.first!.x, y: yAxis.first!.y, width: xAxis.last!.x - xAxis.first!.x, height: yAxis.last!.y - yAxis.first!.y)
    }
}

然后您可以将其用于:

let rect = CGRect(from: points)
// rect.minX

干杯!

答案 1 :(得分:1)

这些是Core Graphics结构,因此请Core Graphics帮助您。从任意点到任意其他点以任意顺序构造路径,并要求其边界框。现在,您有了一个CGRect,其角点就是您的点,但是现在您知道了哪个是角点,并将它们与您的角点进行匹配是微不足道的。

示例:

    var points:[CGPoint] = []
    points.append(CGPoint(x:1, y:0)) //TL
    points.append(CGPoint(x:3, y:0)) //TR
    points.append(CGPoint(x:1, y:2)) //BL
    points.append(CGPoint(x:3, y:2)) //BR

    let path = CGMutablePath()
    path.move(to: points[0])
    for ix in 1...3 {path.addLine(to: points[ix])}
    let rect = path.boundingBox 

答案是CGRect(x:1.0, y:0.0, width:2.0, height:2.0),现在您知道它的minXminYmaxXmaxY,可以轻松地将其匹配到您的原始分数

无论提供点的顺序如何,您都会得到相同的结果。