Как мне заполнить форму, состоящую из кривых Безье и прямых линий?

8

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

я

a

Зеленые линии - это пути Безье, а белая часть - это то, что визуализируется.

Код, который я использую для Безье, здесь . Один для строк здесь . Для тех, кто не знает, что это Луа.

Путь рендеринга (строк): 32 - 39 Алгоритм выглядит следующим образом:

  1. Итерация от 0 до 1 через определенные интервалы
  2. вычисление х и у по этой формуле: (1-index)^2*x1+2*(1-index)*index*x2+index^2*x3

До этого момента все работало нормально. Зеленые линии создаются методом пути.

Белая часть отображается совершенно иначе:

  1. Я получаю координаты x Безье и линии в определенном Y, помещаю их в таблицу.
  2. Я перебираю таблицу и каждый раз, когда сталкиваюсь с точкой, я меняю значение состояния. В том же цикле for также проверяется, включено ли состояние. Если это так, я рисую пиксель на экране.

Чтобы найти значения x для y, я использую метод getX (строка 46 в Безье и строка 31 в строке).

Вот код, который я использую для самого чертежа:

local xBuffer = {}
local state = false

for i=0,500 do
    for k,v in pairs(beziers) do
        a,b = v.getX(i)
        if a then
            xBuffer[round(a)] = 1
            if b then
                xBuffer[round(a)] = 1
            end
        end
    end
    for k,v in pairs(lines) do
        a = v.getX(i)
        if a then
            xBuffer[round(a)] = 1
        end
    end
    state = false
    for x=0,600 do
        if xBuffer[x] then
            state = not state
        end
        if state then
            love.graphics.points(x,i)
        end
    end
end

Краткое объяснение: для i, v в парах перебирает таблицу, заданную в качестве аргумента для пар. love.graphics.points (x, y) устанавливает точку в x, y.

Заранее спасибо.

творец
источник
Есть ли причина, по которой никто не отвечает? Должен ли я переформулировать вопрос?
Создатель
1
Его первые дни есть так много людей, у которых есть время, чтобы ответить, и вы только до сих пор достигли 5 просмотров. Этот обмен стеками еще младенец, и у него не так много пользователей.
joojaa
ХОРОШО. Спасибо. Я не понимал, что здесь так мало людей.
Создатель

Ответы:

6

Если вы спешите заставить работать ваш рендерер, и у вас уже есть правильно заполненная многоугольная подпрограмма , могу ли я предложить альтернативный, возможно, более простой подход? Хотя я не знаком с Lua, кажется, вы решаете для точного пересечения линии сканирования с квадратичным Безье, который, хотя и замечательный, возможно, излишним.

Вместо этого сделайте тесселяцию Безье на отрезки, а затем добавьте их в конвертер полигонального сканирования. Я предлагаю просто использовать (рекурсивное) двоичное подразделение: то есть квадратичный Безье с контрольными точками можно разбить на два Безье, и где (что также хорошо, если у вас есть только математика с фиксированной точкой).(A¯,B¯,C¯)(A¯,D¯,E¯)(E¯,F¯,C¯)

D¯=A¯+B¯2E¯=A¯+2B¯+C¯4F¯=B¯+C¯2

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

Саймон Ф
источник
1
Спасибо! A, B, C векторы правильные? Кроме того, я использую метод scanline, потому что он позволяет мне получить точное количество очков, которое мне нужно. Не могли бы вы взглянуть на код и догадаться, почему он не работает? Просто формулы. Также я бы одобрил ответ, но у меня нет 15 репутации.
Создатель
Да, AB & C являются векторами; 2D в вашем случае, но это в равной степени относится и к N размерам. Что касается прохождения кода ... как я уже сказал, я не знаю Lua, и даже получить правильный правильный рендерер отсканированной полигональной линии может быть сложно - например, вы должны быть очень осторожны при подсчете пересечений, которые лежат точно на позициях вершин. Когда вы распространяете это на непосредственную работу с Безье (что я делал более 20 лет назад), это еще сложнее. Извините, у меня нет времени.
Симон Ф
1
Спасибо за помощь. Просто нашел проблему. A и c в квадратном уравнении были инвертированы.
Создатель