Проверка того, является ли путь простым и закрытым, с помощью cairo

Я использую cairomm вместе с gtkmm для проекта с графическим интерфейсом. Я определил абстрактный виджет GeometricShape (который наследуется от Gtk::DrawingArea) для наследования, если нужно нарисовать квадрат, круг и т. д. Этот класс определяет три области:

  1. заливка (или область тела);
  2. граница;
  3. фоновая область.

Область заливки используется для заливки фигуры определенным цветом тела. Граница (обычно черная) определяет форму, а область фона используется для заполнения оставшегося пространства (всего, кроме границы и связанной с ней области заливки) цветом. Вот пример того, как он выглядит для круга:

введите здесь описание изображения

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

Я думал о добавлении некоторой базовой логики, отличной от каира, чтобы проверить это, например, предоставив какой-то объект SimpleClosedPath для передачи в cairo (который сам проверит инвариант), но я не уверен, как это было бы возможно, поскольку Я хочу разрешить как многоугольники, так и изогнутые формы, такие как круг.

Я думал об использовании cairo для проверки, но методы проверки путей кажутся довольно ограниченными. Я чувствую, что cairo не предназначен для решения такой проблемы.

У вас есть идеи, как я могу обеспечить соблюдение этого инварианта?

На самом деле я не ищу код, а скорее идею, что-то попробовать.


person BobMorane    schedule 17.02.2018    source источник


Ответы (1)


но я не уверен, как это возможно, так как я хочу разрешить как многоугольники, так и изогнутые формы, такие как круг.

Вы знаете о cairo_copy_path_flat? Он получает сглаженную копию текущего пути, что означает, что все кривые аппроксимируются линиями.

Итак, вы каким-то образом получите контекст cairo (cairo_t в C), создадите там свою форму (с line_to, curve_to, arc и т. д.). Тогда вы вызываете не fill или stroke, а вместо этого cairo_copy_path_flat.

Результирующий путь представляет собой серию команд move_to, line_to и close_path, которые затем можно (каким-то образом...) проверить на пересечение. Проверка двух прямых линий на пересечение относительно проста, поэтому вы можете, например. просто проверьте каждую строку на пересечение с каждой другой строкой.

person Uli Schlachter    schedule 17.02.2018