简体   繁体   English

CGAL 与谓词的鲁棒距离比较

[英]CGAL robust distance comparison with predicates

I want to compare the distances between some geometrical objects in a robust way.我想以可靠的方式比较一些几何对象之间的距离。 For instance, I want to measure perpendicular distance between a point and a plane.例如,我想测量一个点和一个平面之间的垂直距离。 I want to do this measurement to many planes from the same point.我想从同一点对许多平面进行测量。 In the end, I want to pick the closest plane to my point.最后,我想选择离我的点最近的平面。

Since the double/float operations cause inexact computations, I want to do this operation by using CGAL's robustness predicates.由于 double/float 操作会导致不精确的计算,我想通过使用 CGAL 的健壮性谓词来执行此操作。 However, I do not have the theoretical background about the predicates.但是,我没有关于谓词的理论背景。 I have seen that there are concepts like "Filtered_predicate", "Exact_predicates_inexact_constructions_kernel".我看到有像“Filtered_predicate”、“Exact_predicates_inexact_constructions_kernel”这样的概念。 I do not which one to use and how to use.我不知道使用哪一个以及如何使用。 Could you help me?你可以帮帮我吗?

My guess is to define the point and planes with "Exact_predicates_inexact_constructions_kernel".我的猜测是用“Exact_predicates_inexact_constructions_kernel”定义点和平面。 And then call Exact_predicates_inexact_constructions_kernel::FT CGAL::squared_distance(plane, point) method.然后调用 Exact_predicates_inexact_constructions_kernel::FT CGAL::squared_distance(plane, point) 方法。 And then compare the FT result obtained by each plane.Is it a right approach?然后比较各个平面得到的FT结果,这样的做法对吗?

I have written the following code by using filtered_predicate.我使用 filtered_predicate 编写了以下代码。 It works for now, yet I did not try with nearly-planar planes.它现在有效,但我没有尝试使用近平面的平面。

typedef CGAL::Simple_cartesian<double>                          C;
typedef CGAL::Simple_cartesian<CGAL::Interval_nt_advanced>      FC;
typedef CGAL::Simple_cartesian<CGAL::MP_Float>                  EC;
typedef CGAL::Cartesian_converter<C, EC>                        C2E;
typedef CGAL::Cartesian_converter<C, FC>                        C2F;


template <typename K>
struct my_closest_check {
    typedef typename K::RT                      RT;
    typedef typename K::Point_3                 Point_3;
    typedef typename K::Sphere_3                Sphere_3;
    typedef typename CGAL::Uncertain<bool>      result_type;

    result_type operator()(const Sphere_3& sphere, const Point_3& point) const
    {
        return sphere.has_on_unbounded_side(point);
    }
};

typedef CGAL::Filtered_predicate<my_closest_check<EC>, my_closest_check<FC>, C2E, C2F>      FK;


int find_the_closest_plane(C::Point_3 point, vector<C::Plane_3> plane_set;) {

    int closest_plane_id = 0;
    C::Plane_3 closest_plane = plane_set[closest_plane_id];
    C::FT sq_closest_distance = CGAL::squared_distance(point, closest_plane);
    C::Sphere_3 smallest_sphere = C::Sphere_3(point, sq_closest_distance, CGAL::Orientation::COUNTERCLOCKWISE);

    for (int i = 1; i < plane_set.size(); i++) {
        C::Plane_3 current_plane = plane_set[i];
        C::Point_3 projection_point = current_plane.projection(point);
        FK is_inside;
        if (!is_inside(smallest_sphere, projection_point)) {
            closest_plane_id = i;
            closest_plane = current_plane;
            sq_closest_distance = CGAL::squared_distance(point, closest_plane);
            smallest_sphere = C::Sphere_3(point, sq_closest_distance, CGAL::Orientation::COUNTERCLOCKWISE);
        }
    }

    return closest_plane_id;
}

The only part that I am not sure is whether I should put the whole calculation inside filtered_kernel, or filtering only the in_sphere test is enough.我不确定的唯一部分是我是否应该将整个计算放在 filtered_kernel 中,或者只过滤 in_sphere 测试就足够了。 I do not need any interstep computation (like constructing the sphere exactly, finding the point-plane distance, projecting point onto plane) to be accurate, yet I want the latest output (which is the closest plane) to be exact.我不需要任何步间计算(比如精确构建球体、找到点平面距离、将点投影到平面上)是准确的,但我希望最新的 output(这是最近的平面)是准确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM