距离算法

两点间距离

// 两点间距离
const double Geo::distance(const double x0, const double y0, const double x1, const double y1)
{
    return std::sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1));
}

// 两点间距离
const double Geo::distance(const Point &point0, const Point &point1)
{
    return std::sqrt((point0.x - point1.x) * (point0.x - point1.x)
                        + (point0.y - point1.y) * (point0.y - point1.y));
}

点到有限长线段或无线长直线距离

点到直线距离:如果为有限长线段且垂足不在线段上,则计算点到线段端点距离。

// 点到直线距离,如果为有限长线段且垂足不在线段上,则计算点到线段端点距离
const double Geo::distance(const Point &point, const Line &line, const bool infinite)
{
    if (line.front().x == line.back().x)
    {
        if (infinite)
        {
            return std::abs(point.x - line.front().x);
        }
        else
        {
            if ((point.y >= line.front().y && point.y <= line.back().y) ||
                (point.y <= line.front().y && point.y >= line.back().y))
            {
                return std::abs(point.x - line.front().x);
            }
            else
            {
                return std::min(Geo::distance(point, line.front()), Geo::distance(point, line.back()));
            }
        }
    }
    else if (line.front().y == line.back().y)
    {
        if (infinite)
        {
            return std::abs(point.y - line.front().y);
        }
        else
        {
            if ((point.x >= line.front().x && point.x <= line.back().x) ||
                (point.x <= line.front().x && point.x >= line.back().x))
            {
                return std::abs(point.y - line.front().y);
            }
            else
            {
                return std::min(Geo::distance(point, line.front()), Geo::distance(point, line.back()));
            }
        }
    }
    
    const double a = line.back().y - line.front().y, 
                b = line.front().x - line.back().x,
                c = line.back().x * line.front().y - line.front().x * line.back().y;
    if (infinite)
    {
        return std::abs(a * point.x + b * point.y + c) / std::sqrt(a * a + b * b);
    }
    else
    {
        const double k = ((point.x - line.front().x) * (line.back().x - line.front().x) +
            (point.y - line.front().y) * (line.back().y - line.front().y)) /
            (std::pow(line.back().x - line.front().x, 2) + std::pow(line.back().y - line.front().y, 2)); 
        const double x = line.front().x + k * (line.back().x - line.front().x);

        if ((x >= line.front().x && x <= line.back().x) || (x <= line.front().x && x >= line.back().x))
        {
            return std::abs(a * point.x + b * point.y + c) / std::sqrt(a * a + b * b);
        }
        else
        {
            return std::min(Geo::distance(point, line.front()), Geo::distance(point, line.back()));
        }
    }
}

// 点到直线距离,如果为有限长线段且垂足不在线段上,则计算点到线段端点距离
const double Geo::distance(const Point &point, const Point &start, const Point &end, const bool infinite)
{
    if (start.x == end.x)
    {
        if (infinite)
        {
            return std::abs(point.x - start.x);
        }
        else
        {
            if ((point.y >= start.y && point.y <= end.y) ||
                (point.y <= start.y && point.y >= end.y))
            {
                return std::abs(point.x - start.x);
            }
            else
            {
                return std::min(Geo::distance(point, start), Geo::distance(point, end));
            }
        }
    }
    else if (start.y == end.y)
    {
        if (infinite)
        {
            return std::abs(point.y - start.y);
        }
        else
        {
            if ((point.x >= start.x && point.x <= end.x) ||
                (point.x <= start.x && point.x >= end.x))
            {
                return std::abs(point.y - start.y);
            }
            else
            {
                return std::min(Geo::distance(point, start), Geo::distance(point, end));
            }
        }
    }
    
    const double a = end.y - start.y, 
                b = start.x - end.x,
                c = end.x * start.y - start.x * end.y;
    if (infinite)
    {
        return std::abs(a * point.x + b * point.y + c) / std::sqrt(a * a + b * b);
    }
    else
    {
        const double k = ((point.x - start.x) * (end.x - start.x) +
            (point.y - start.y) * (end.y - start.y)) /
            (std::pow(end.x - start.x, 2) + std::pow(end.y - start.y, 2)); 
        const double x = start.x + k * (end.x - start.x);

        if ((x >= start.x && x <= end.x) || (x <= start.x && x >= end.x))
        {
            return std::abs(a * point.x + b * point.y + c) / std::sqrt(a * a + b * b);
        }
        else
        {
            return std::min(Geo::distance(point, start), Geo::distance(point, end));
        }
    }
}

点到多段线距离

点到多段线距离:计算点到每一段有限长线段的距离,取最近距离。

// 点到多段线距离,计算点到每一段有限长线段的距离,取最近距离
const double Geo::distance(const Point &point, const Polyline &polyline)
{
    double dis = DBL_MAX;
    for (size_t i = 1, count = polyline.size(); i < count; ++i)
    {
        dis = std::min(dis, Geo::distance(point, polyline[i - 1], polyline[i]));
    }
    return dis;
}

点到多边形距离

点到多边形距离:计算点到每一段有限长线段的距离,取最近距离。

// 点到多边形距离,计算点到每一段有限长线段的距离,取最近距离
const double Geo::distance(const Point &point, const Polygon &polygon)
{
    double dis = DBL_MAX;
    for (size_t i = 1, count = polygon.size(); i < count; ++i)
    {
        dis = std::min(dis, Geo::distance(point, polygon[i - 1], polygon[i]));
    }
    return dis;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值