如何找到两个矩形之间最接近的距离的两个点?

丹尼尔

我正在尝试找到一种算法,该算法将找到代表两个矩形之间最接近距离的两个点。像点CJ一样,在下面的图像中形成最小距离:

在此处输入图片说明

我试图在这里不重新发明轮子,而使用已经通过测试的升压:: boost :: geometry :: distance,但是它只会返回距离,而不会返回点。

看到

不会使事物过于通用(通过假设浮点坐标和笛卡尔坐标系),这是点到线段距离的一种实现,该距离返回投影点以及距离:

struct DistancePoint {
    double distance;
    P projected_point;
};

template <typename Strategy = bg::strategy::distance::pythagoras<> >
DistancePoint point_to_segment(P const& p, P const& p1, P const& p2) {
    P v = p2, w = p;
    bg::subtract_point(v, p1);
    bg::subtract_point(w, p1);

    auto const c1 = bg::dot_product(w, v);
    if (c1 <= 0)  return { Strategy::apply(p, p1), p1 };

    auto const c2 = bg::dot_product(v, v);
    if (c2 <= c1) return { Strategy::apply(p, p2), p2 };

    P prj = p1;
    bg::multiply_value(v, c1/c2);
    bg::add_point(prj, v);

    return { Strategy::apply(p, prj), prj };
}

现在,您可以将其与几何一起使用。我不想满足距离策略概念的所有标准,因此您不能将上述内容与boost :: geometry :: distance一起使用

但是,由于您输入的几何图形具有较低的点数,因此您可以避免使用“强行强制”(不需要库内部closest_feature选择):

R a = gen_rect(),
  b = gen_rect();

// make sure a and b don't overlap (distance > 0)
while (!bg::disjoint(a,b)) { b = gen_rect(); }

std::cout
    << wkt(a) << "\n"
    << wkt(b) << "\n"
    << bg::distance(a, b) << " apart\n";

DistancePoint nearest;
P const* which = nullptr;

for (auto& [a,b] : { std::tie(a,b), std::tie(b,a) } ) {
    auto segments = boost::make_iterator_range(bg::segments_begin(a), bg::segments_end(a));
    auto points   = boost::make_iterator_range(bg::points_begin(b), bg::points_end(b));

    for (auto&& pq : segments) {
        for (auto&& r : points) {
            auto d = point_to_segment(r, *pq.first, *pq.second);

            if (!which || d.distance < nearest.distance) {
                which = &r;
                nearest = d;
            }
        }
    }
}

std::cout << wkt(which) << " at " << nearest.distance << " from " << wkt(nearest.projected_point) << "\n";

演示

生活在Coliru

#include <boost/geometry.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/io/io.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/convex_hull.hpp>
#include <boost/geometry/algorithms/point_on_surface.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/range/adaptors.hpp>
#include <iostream>
#include <fstream>

namespace bg = boost::geometry;
namespace bgm = boost::geometry::model;
using namespace boost::adaptors;
using bg::wkt;

using P = bgm::d2::point_xy<double>;
using B = bgm::box<P>;
using S = bgm::segment<P>;
using R = bgm::polygon<P>;

R gen_rect(); // generates a random rectangle

namespace {
    struct DistancePoint {
        double distance;
        P projected_point;
    };

    // after strategy::distance::projected_point<>
    template <typename Strategy = bg::strategy::distance::pythagoras<> >
    DistancePoint point_to_segment(P const& p, P const& p1, P const& p2) {
        P v = p2, w = p;
        bg::subtract_point(v, p1);
        bg::subtract_point(w, p1);

        auto const c1 = bg::dot_product(w, v);
        if (c1 <= 0)  return { Strategy::apply(p, p1), p1 };

        auto const c2 = bg::dot_product(v, v);
        if (c2 <= c1) return { Strategy::apply(p, p2), p2 };

        P prj = p1;
        bg::multiply_value(v, c1/c2);
        bg::add_point(prj, v);

        return { Strategy::apply(p, prj), prj };
    }
}

int main() {
    std::cout << std::setprecision(2);

    for (auto i = 0; i<10; ++i) {
        R a = gen_rect(),
          b = gen_rect();

        // make sure a and b don't overlap (distance > 0)
        while (!bg::disjoint(a,b)) { b = gen_rect(); }

        std::cout
            << wkt(a) << "\n"
            << wkt(b) << "\n"
            << bg::distance(a, b) << " apart\n";

        DistancePoint nearest;
        P const* which = nullptr;

        for (auto& [a,b] : { std::tie(a,b), std::tie(b,a) } ) {
            auto segments = boost::make_iterator_range(bg::segments_begin(a), bg::segments_end(a));
            auto points   = boost::make_iterator_range(bg::points_begin(b), bg::points_end(b));

            for (auto&& pq : segments) {
                for (auto&& r : points) {
                    auto d = point_to_segment(r, *pq.first, *pq.second);

                    if (!which || d.distance < nearest.distance) {
                        which = &r;
                        nearest = d;
                    }
                }
            }
        }

        std::cout << wkt(which) << " at " << nearest.distance << " from " << wkt(nearest.projected_point) << "\n";

        {
            std::ofstream svg("output" + std::to_string(i) + ".svg");
            boost::geometry::svg_mapper<P> mapper(svg, 400, 400, "style='fill-opacity:1;fill:rgb(255,255,255)'");
            mapper.add(a);
            mapper.add(b);
            S dline {*which, nearest.projected_point};
            mapper.add(dline);

            mapper.map(a, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");
            mapper.map(b, "fill-opacity:0.5;fill:rgb(204,153,0);stroke:rgb(202,153,0);stroke-width:2");
            mapper.map(dline, "stroke-dasharray:1,1;stroke:rgb(255,0,0);stroke-width:1");
        }
    }
}

// details for generating the rectangles
#include <boost/geometry/strategies/transform/matrix_transformers.hpp>
#include <random>
std::mt19937 prng { std::random_device{}() };

static auto rand(double b, double e) { 
    return std::uniform_real_distribution<double>(b, e)(prng);
}

R gen_rect() {
    B initial {{0, 0}, { rand(0.1, 1), rand(0.1, 1) } };
    R raw, rect; // todo rotate and stuff
    bg::assign(raw, initial);

    using namespace bg::strategy::transform;
    auto rot   = rand(-M_PI, +M_PI);
    auto scale = rand(1, 3);
    auto x     = rand(-5, 5),
         y     = rand(-5, 5);

    matrix_transformer<double, 2, 2> xfrm(
         scale* cos(rot), scale*sin(rot), x,
         scale*-sin(rot), scale*cos(rot), y,
                       0,              0, 1);

    bg::transform(raw, rect, xfrm);
    bg::correct(rect);
    return rect;
}

这将生成一些随机场景,例如:

在此处输入图片说明

在此处输入图片说明

在此处输入图片说明

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

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

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

我如何找到两个点/像素之间的距离?

来自分类Dev

我如何找到两个点/像素之间的距离?

来自分类Dev

Python:如何在两个单独的数组之间找到两个相等/最接近的值?

来自分类Dev

如何在数组中找到与整数和数字之间的两个最接近的差

来自分类Dev

找到最接近另一个的两个点

来自分类Dev

如何添加两个点之间的距离(SRID = 32636)?

来自分类Dev

Shapely中两个几何的最接近点的坐标

来自分类Dev

如何找到React Native的两个元素之间的距离?

来自分类Dev

如何找到两个经度位置之间的距离?

来自分类Dev

如何找到 GPS 轨迹数据集中两个相邻点之间的距离(以英尺为单位)?

来自分类Dev

两个表之间最接近点的唯一分配

来自分类Dev

Python:最接近的两个目标

来自分类Dev

如何找到两个对象之间等距的点?

来自分类Dev

如何找到两个线段之间的点的特定比例?

来自分类Dev

如何找到两个矩阵之间最近的两个点?

来自分类Dev

如何找到两个矩阵之间最近的两个点?

来自分类Dev

如何找到两个非接口类的最接近的公共超类

来自分类Dev

如何从谁的值最接近零的列表中找到两个索引

来自分类Dev

两个表之间的文本字段最接近的匹配:如何改善plpgsql函数

来自分类Dev

计算两个经纬度点之间的距离?

来自分类Dev

找到两个顶点子集之间的最小距离

来自分类Dev

快速找到两个MLMultiArrays之间的距离

来自分类Dev

找到两个顶点子集之间的最小距离

来自分类Dev

如何计算距离的两个点之间,对很多随之而来的点,蟒蛇组内

来自分类Dev

如何沿着两个向量找到距离等于X的点

来自分类Dev

如何沿着两个向量找到距离等于X的点

来自分类Dev

填充两个矩形之间的空间

来自分类Dev

填充两个矩形之间的空间

来自分类Dev

如何计算数据框中两个连续点之间的距离和角度?

Related 相关文章

  1. 1

    我如何找到两个点/像素之间的距离?

  2. 2

    我如何找到两个点/像素之间的距离?

  3. 3

    Python:如何在两个单独的数组之间找到两个相等/最接近的值?

  4. 4

    如何在数组中找到与整数和数字之间的两个最接近的差

  5. 5

    找到最接近另一个的两个点

  6. 6

    如何添加两个点之间的距离(SRID = 32636)?

  7. 7

    Shapely中两个几何的最接近点的坐标

  8. 8

    如何找到React Native的两个元素之间的距离?

  9. 9

    如何找到两个经度位置之间的距离?

  10. 10

    如何找到 GPS 轨迹数据集中两个相邻点之间的距离(以英尺为单位)?

  11. 11

    两个表之间最接近点的唯一分配

  12. 12

    Python:最接近的两个目标

  13. 13

    如何找到两个对象之间等距的点?

  14. 14

    如何找到两个线段之间的点的特定比例?

  15. 15

    如何找到两个矩阵之间最近的两个点?

  16. 16

    如何找到两个矩阵之间最近的两个点?

  17. 17

    如何找到两个非接口类的最接近的公共超类

  18. 18

    如何从谁的值最接近零的列表中找到两个索引

  19. 19

    两个表之间的文本字段最接近的匹配:如何改善plpgsql函数

  20. 20

    计算两个经纬度点之间的距离?

  21. 21

    找到两个顶点子集之间的最小距离

  22. 22

    快速找到两个MLMultiArrays之间的距离

  23. 23

    找到两个顶点子集之间的最小距离

  24. 24

    如何计算距离的两个点之间,对很多随之而来的点,蟒蛇组内

  25. 25

    如何沿着两个向量找到距离等于X的点

  26. 26

    如何沿着两个向量找到距离等于X的点

  27. 27

    填充两个矩形之间的空间

  28. 28

    填充两个矩形之间的空间

  29. 29

    如何计算数据框中两个连续点之间的距离和角度?

热门标签

归档