【多点构成的面积估算】凸包算法python 实现 + 经纬度坐标 python 实现

本文介绍了在用户聚类中使用凸包算法进行面积估算的场景,回顾了凸包算法的基本概念和Graham-Scan算法。通过分析和调试现有代码,发现了当点集中存在相同点时算法失效的问题,并提供了修正后的Python实现。此外,还探讨了在经纬度坐标下利用凸包算法进行面积近似计算的方法。
摘要由CSDN通过智能技术生成

做用户聚类,有一个feature涉及到面积计算,温故一下之前了解到的凸包算法的流程,实际上,这篇文章基于的原文章,达到的精度,满足我的需求。具体实现上代码参考,因为坐标系不是笛卡尔坐标系

先上笔者参考已有的实现稍作修改后作为静态工具类使用的代码

# the class that seals the algorithm that uses convex hull to calculate the points-distributed-area
from math import *


class cal_area(object):
    @staticmethod
    def deg2rad(deg):
        return deg * (pi / 180)

    @staticmethod
    def cross(A, B):
        return A[0] * B[1] - A[1] * B[0]

    @staticmethod
    def vectorMinus(a, b):
        return ((a[0] - b[0]) * 1000, (a[1] - b[1]) * 1000)

    @staticmethod
    def getLTDis(A, B):
        lon1, lat1, lon2, lat2 = map(cal_area.deg2rad, [A[0], A[1], B[0], B[1]])
        dlon = lon2 - lon1
        dlat = lat2 - lat1
        a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
        c = 2 * asin(sqrt(a))
        r = 6371.393
        # print A,B
        return c * r * 1.0  # 1000.0

    @staticmethod
    def triangleAre(A, B, C):
        x, y, z = cal_area.getLTDis(A, B), cal_area.getLTDis(B, C), cal_area.getLTDis(C, A)
        c = (x + y + z) / 2
        return sqrt((c) * (c - y) * (c - z) * (c - x))

    @staticmethod
    def grahamScanArea(data):
        data.sort(key=lambda x: (x[0], x[1]), reverse=False)
        ans = [0] * (len(data) * 2)
        m = 0
        for item in data:
            top = len(item)
            while (m > 1 and cal_area.cross(cal_area.vectorMinus(ans[m - 1], ans[m - 2]),
                                            cal_area.vectorMinus(item, ans[m - 2])) <= 0): m = m - 1
            ans[m] = item
            m = m + 1
        k = m
        flag = True
        data.reverse()
        for item in data:
            if flag:
                flag = False
                continue
            while (m > k and cal_area.cross(cal_area.vectorMinus(ans[m - 1], ans[m - 2]),
                                            cal_area.vectorMinus(item, ans[m - 2])) <= 0): m = m - 1
            ans[m] = item
            m = m + 1
        m = m - 1
        b = [ans[i] for i in range(0, m)]
        if len(b) < 3: return 0
        # if DEBU
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值