如何从cgpoints数组中获取中心点?

迅捷京东

我有一个CGPoints数组:

let points = [(1234.0, 1053.0), (1241.0, 1111.0), (1152.0, 1043.0)]

我想做的就是找到CGPoints的中心。因此,我可以将一个对象放置在所有点的中心。如果这是一个可以说整数的数组,则可以这样减少数组:

points.reduce(0, +)

然后除以总数组数即可得出平均值。但是由于它的CGPoints,这是行不通的。关于如何实现这一目标的任何想法?

Farhad回答了有关如何平均所有这些数据点的问题。(+1)

但这真的是您想要的吗?考虑:

这个图片

This convex shape is defined by the blue points, but the mean of all of those points is the red point. But that’s not really in the center of the shape. It is skewed up because there are five data points near the top, and only two down below. This convex shape illustrates the problem well, but it doesn’t need to be convex to manifest this issue. Any situation where the data points are not relatively evenly distributed can manifest this behavior.

The green point is the centroid of the polygon. You can see that it falls below the center of the bounding box (the crosshairs in the above image), like you’d expect. For simple shapes, that might be a better place to place your label. That can be calculated as follows:

extension Array where Element == CGPoint {
    /// Calculate signed area.
    ///
    /// See https://en.wikipedia.org/wiki/Centroid#Of_a_polygon
    ///
    /// - Returns: The signed area

    func signedArea() -> CGFloat {
        if isEmpty { return .zero }

        var sum: CGFloat = 0
        for (index, point) in enumerated() {
            let nextPoint: CGPoint
            if index < count-1 {
                nextPoint = self[index+1]
            } else {
                nextPoint = self[0]
            }

            sum += point.x * nextPoint.y - nextPoint.x * point.y
        }

        return sum / 2
    }

    /// Calculate centroid
    ///
    /// See https://en.wikipedia.org/wiki/Centroid#Of_a_polygon
    ///
    /// - Note: If the area of the polygon is zero (e.g. the points are collinear), this returns `nil`.
    ///
    /// - Parameter points: Unclosed points of polygon.
    /// - Returns: Centroid point.

    func centroid() -> CGPoint? {
        if isEmpty { return nil }

        let area = signedArea()
        if area == 0 { return nil }

        var sumPoint: CGPoint = .zero

        for (index, point) in enumerated() {
            let nextPoint: CGPoint
            if index < count-1 {
                nextPoint = self[index+1]
            } else {
                nextPoint = self[0]
            }

            let factor = point.x * nextPoint.y - nextPoint.x * point.y
            sumPoint.x += (point.x + nextPoint.x) * factor
            sumPoint.y += (point.y + nextPoint.y) * factor
        }

        return sumPoint / 6 / area
    }

    func mean() -> CGPoint? {
        if isEmpty { return nil }

        return reduce(.zero, +) / CGFloat(count)
    }
}

extension CGPoint {
    static func + (lhs: CGPoint, rhs: CGPoint) -> CGPoint {
        CGPoint(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
    }

    static func - (lhs: CGPoint, rhs: CGPoint) -> CGPoint {
        CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y)
    }

    static func / (lhs: CGPoint, rhs: CGFloat) -> CGPoint {
        CGPoint(x: lhs.x / rhs, y: lhs.y / rhs)
    }

    static func * (lhs: CGPoint, rhs: CGFloat) -> CGPoint {
        CGPoint(x: lhs.x * rhs, y: lhs.y * rhs)
    }
}

And you’d calculate the centroid like so:

let points = [(1234.0, 1053.0), (1241.0, 1111.0), (1152.0, 1043.0)]
    .map(CGPoint.init)

guard let point = points.centroid() else { return }

FWIW具有复杂的凹形形状,即使质心也不是最佳的。请参见找到不规则形状的多边形的“可视”中心的最快方法是什么?

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在 WebGL Globe 中获取屏幕中心点的经纬度值?

来自分类Dev

如何使用Google Maps API获取KML的中心点

来自分类Dev

如何在python中围绕中心点旋转图形

来自分类Dev

如何获得中心点的角度?

来自分类Dev

如何找到图像的中心点?

来自分类Dev

如何获得gridView单元的中心点?

来自分类Dev

如何获得细胞中心点

来自分类Dev

如何从图像的中心点放大图像?

来自分类Dev

在中心点附近

来自分类Dev

在Python中获取经度和纬度群集的中心点

来自分类Dev

如何计算4点的加权中心点?

来自分类Dev

尝试绘制点云,在opengl中仅在中心点

来自分类Dev

在滚动Google地图时获取地图中心点

来自分类Dev

如何从可可中的中心点顺时针方向旋转 NSButton?

来自分类Dev

iOS:如何围绕中心点旋转UIImageView?

来自分类Dev

如何找到以分水岭分割的区域的中心点?

来自分类Dev

如何描述从中心点径向向外移动的线?

来自分类Dev

如何从几何Arcgis Android查找中心点?

来自分类Dev

如何从中心点为svg线设置动画?

来自分类Dev

如何找到以分水岭分割的区域的中心点?

来自分类Dev

如何描述从中心点径向向外移动的线?

来自分类Dev

如何围绕环中的中心点绘制圆形按钮?

来自分类Dev

在Unity C#中绕中心点旋转

来自分类Dev

在CSS中更改径向渐变的中心点

来自分类Dev

OpenCV质量中心点

来自分类Dev

使用svg.js和svg-pan-zoom如何获取当前的“视口”中心点?

来自分类Dev

我需要从线段中绘制一个三角形-如何找到中心点?

来自分类Dev

将一个int数组复制到一个更大的int数组中,该int数组表示给定中心点处的图像

来自分类Dev

计算数据框中多个经纬度长点的中心点

Related 相关文章

热门标签

归档