Круг пересечения CGAL и вертикальные линии (не сегменты)

В CGAL мне нужно вычислить точные точки пересечения между набором прямых и набором окружностей. Начиная с кругов (которые могут иметь иррациональный радиус, но рациональный squared_radius), я должен вычислить вертикальную линию, проходящую через точки x_extremal_points каждого круга (не сегмента, а линии), и вычислить точку пересечения каждого круга с каждой линией.

Я использую CircularKernel и Circle_2 для кругов и Line_2 для линий. Вот пример того, как я вычисляю круги и линии и как я проверяю, пересекаются ли они.

int main()
{

    Point_2 a = Point_2(250.5, 98.5);
    Point_2 b = Point_2(156, 139);

    //Radius is half distance ab
    Circular_k::FT aRad = CGAL::squared_distance(a, b);

    Circle_2 circle_a = Circle_2(a, aRad/4);

    Circular_arc_point_2 a_left_point = CGAL::x_extremal_point(circle_a, false);
    Circular_arc_point_2 a_right_point = CGAL::x_extremal_point(circle_a, true);

    //for example use only left extremal point of circle a
    CGAL::Bbox_2 a_left_point_bb = a_left_point.bbox();

    Line_2 a_left_line = Line_2(Point_2(a_left_point_bb.xmin(), a_left_point_bb.ymin()),
                                Point_2(a_left_point_bb.xmin(), a_left_point_bb.ymax()));

    if ( do_intersect(a_left_line, circle_a) ) {
        std::cout << "intersect";
    }
    else {
        std::cout << " do not intersect ";
    }

    return 0;
}

Этот поток поднимает это исключение:

CGAL error: precondition violation!
 Expression : y != 0
 File       : c:\dev\cgal-4.7\include\cgal\gmp\gmpq_type.h
 Line       : 371
 Explanation:
 Refer to the bug-reporting instructions at http://www.cgal.org/bug_report.html

Я не могу понять, как я могу рассчитать точки пересечения. Кроме того, есть ли лучший способ для вычисления линий? Я знаю о функции x_extremal_point, но она возвращает точку Circular_arc_point, и я не могу построить вертикальную линию, проходящую через них напрямую, без использования ограничительной рамки.

2 ответа

Для эффективности вы должны взглянуть на основную проблему 1D: проецируя линии и окружность на ось X, у вас есть набор точек и набор интервалов [Xc-R, Xc+R].

Если точки L сортируются все чаще, вы можете найти левую границу интервала времени Lg(L) по дихотомии и сканировать список точек до правой границы. Это приводит к поведению O(Lg(L).C + I) (интервалы C круга), где I - число зарегистрированных пересечений.

Я предполагаю, что с помощью процесса слияния, использующего активный список, если границы интервалов также отсортированы, вы можете понизить до O(L + C + I).

Расширение до 2D элементарно.

В вашем коде вы, кажется, вычисляете пересечение окружности с вертикальной линией, проходящей через крайнюю точку окружности (я забываю ограничивающий прямоугольник). Что ж, тогда (двойное) пересечение является самой экстремальной точкой... Более глобально, вы говорите в своем тексте введения, что вы хотите вычислить точные пересечения. Тогда вам не следует использовать ограничивающие рамки, которые по определению вводят некоторую аппроксимацию.

Если я правильно понимаю ваш текст, * для проверки пересечения ваших вертикальных линий с другими окружностями вам не нужно строить линии, вам нужно только сравнить абсциссы крайних точек двух окружностей, что вы можете сделать с кольцевым ядром CGAL. * для вычисления пересечения вертикальной линии, которая имеет нерациональные коэффициенты (поскольку ее уравнение имеет вид x= +-sqrt(r)) с другим кругом, то круговое ядро ​​CGAL не даст вам предварительно приготовленное решение, Это ядро ​​поможет, но вы все равно должны вычислить несколько вещей вручную. Если вы не хотите беспокоиться, то вы также можете просто взять стандартное ядро ​​CGAL с Core::Expr в качестве базового числового типа. Он может делать что угодно, но будет медленнее.

Другие вопросы по тегам