Рассчитать ограничивающую рамку линии толщиной - PullRequest
0 голосов
/ 06 июля 2018

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

lines with different caps

Линии обозначены 3 точками (отмечены красным), но могут иметь произвольное количество точек. Строки могут иметь разные заглавные буквы:

  1. без линейного колпачка
  2. прямоугольный колпачок (линия line_width / 2 длиннее на концах)
  3. круглые заглавные буквы (круг с радиусом line_width / 2)

Можно ли создать такую ​​линию с использованием графического фреймворка, такого как Cairo, и получить ограничивающую рамку из Cairo, или мне нужно рассчитать ее, используя тригонометрические подходы самостоятельно?

Я программирую на C.

У меня уже есть функция для вычисления ограничительной рамки многоугольника. Есть ли простой способ преобразовать эти линии в многоугольники, чтобы я мог использовать свои существующие функции?

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


Редактировать

Я нашел следующую ссылку для Каира. Кажется, поддерживаются следующие типы линий: Каирские заглавные буквы

Я хотел добавить: я никогда не использовал Каир. Я просто наткнулся на это во время моего поиска. Я начинающий с этим.

1 Ответ

0 голосов
/ 06 июля 2018

Я обнаружил Cairo Recoding Surface , который точно делает то, что мне нужно. Я рисую свои объекты на неограниченной поверхности записи и позволяю Каиру вычислить ограничивающую рамку.

Небольшой пример, который создает несколько строк и вычисляет ограничивающий прямоугольник, выглядит следующим образом:

void main(void)
{
  cairo_surface_t *rec;
  cairo_t *cr;
  double x0, y0, width, height;

  rec = cairo_recording_surface_create(CAIRO_CONTENT_COLOR_ALPHA, NULL);
  cr = cairo_create(rec);
  cairo_scale(cr, 10, 10);

  cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
  cairo_set_line_width(cr, 2);

  cairo_move_to(cr, 0, 0);
  cairo_rel_line_to(cr, 0, 20);
  cairo_rel_line_to(cr, 5, 0);
  cairo_rel_line_to(cr, 1, 1);
  cairo_stroke(cr);

  cairo_recording_surface_ink_extents(rec, &x0, &y0, &width, &height);
  printf("Size: %lf / %lf at (%lf, %lf)\n", width, height, x0, y0);
}
...