Как определить Каир рисунок с шириной линии даже? - PullRequest
0 голосов
/ 19 октября 2019

Я использую cr (из события отрисовки виджета Gtk) и хочу создать прямоугольник (или линию), используя четное количество пикселей (2,4,6 и т. Д.) Без каких-либо «преобразований контекста». Согласно эта строка будет " вокруг пути ". И согласно это" диаметр круглого пера ".

Но в прямоугольнике он будет меньше снаружи и больше внутри или наоборот? И в строке будет вверх, вниз, влево или вправо?

Я понимаю, что при нечетной ширине линии " вокруг пути " означает 1 в центре, а остальные равныоколо. Но при четной ширине линии, например, когда ширина линии равна 2, будет 1 пиксель внутри пути или снаружи?

Существует ли стабильный способ определения затронутых пикселей или он случайный?

Обход создания двух раз за каждый штрих, сначала с шириной линии 1, а затем с использованием оставшегося (нечетного) числа, убивает боль и отнимает много времени.

1 Ответ

1 голос
/ 23 октября 2019

Но в прямоугольнике будет меньше снаружи и больше внутри или наоборот? И в линии будет вверх, вниз, влево или вправо?

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

Я понимаю, что при нечетной ширине линии «вокруг пути» означает 1 в центре, а остальныеодинаково вокруг. Но при четной ширине линии, например, когда ширина линии равна 2, будет 1 пиксель внутри пути или снаружи?

При ширине линии 3 1,5 пикселя будут нарисованы по обе стороны отпуть.

При ширине линии 4 по обе стороны пути рисуется 2 пикселя.

Возможно, следующий пример проясняет ситуацию. Это написано на Lua и использует LGI в качестве привязки cairo для Lua, но это напрямую связано с C API:

local cairo = require("lgi").cairo
s = cairo.ImageSurface(cairo.Format.RGB24, 100, 30)
cr = cairo.Context(s)

cr:set_source_rgb(1, 1, 1)
cr:paint()

cr:set_source_rgb(0, 0, 0)

cr:set_line_width(2)
cr:rectangle(5, 10, 5, 5)
cr:stroke()

cr:set_line_width(6)
cr:rectangle(15, 10, 14, 14)
cr:stroke()

cr:set_line_width(7)
cr:rectangle(40.5, 10.5, 14, 14)
cr:stroke()

cr:set_line_width(7)
cr:rectangle(70, 10, 14, 14)
cr:stroke()

s:write_to_png("out.png")

Полученное изображение: Output of example program

Первый прямоугольник имеет ширину линии 2. Он рисуется с целочисленными координатами, так что есть, например, линия от (5, 10) до (10, 10) (верхняя линия). Половина ширины линии рисуется по обе стороны от линии, поэтому эта линия соответствует «заполненному прямоугольнику» от (4, 9) до (6, 11).

Последний прямоугольник имеет ширину линии7 и также рисуется с целочисленными координатами. Его верхняя линия идет от (70, 10) до (70, 24). Поскольку половина ширины линии находится по обе стороны от линии, «заполненный прямоугольник» переходит от (66,5, 6,5) к (73,5, 27,5). Эти числа не являются целыми числами, и в результате вы можете увидеть, что было применено некоторое сглаживание.

В отличие от этого, у прямоугольника второго до последнего его положение сдвинуто на 0,5. Это приводит к тому, что «заполненный прямоугольник» для его «верхней линии» снова попадает в пиксельную сетку.

См. Также этот раздел часто задаваемых вопросов: https://www.cairographics.org/FAQ/#sharp_lines

...