2010-12-27 3 views
8

Краткое описание: Я работаю над веб-приложением рисования и вам нужно нарисовать сплошные сплайны толщиной 1px, которые проходят через их контрольные точки.Рисование сглаженных, пиксельных совершенных 1px сплайнов (особенно Catmull-Rom)

Проблема, с которой я борюсь, заключается в том, что мне нужно нарисовать каждый пиксель между p1 и p2, как если бы я использовал инструмент карандаша 1px. Таким образом, без сглаживания и по одному пикселю за раз. Это нужно сделать вручную без использования какого-либо кода библиотеки строк/кривых, поскольку моя кисть зависит от наличия координаты пикселя для применения кончика кисти к холсту.

По существу, мне нужно объединить один пиксель, шаг из чего-то вроде алгоритма Брешенема с координатами, возвращаемыми уравнением Катмулла-Рома. У меня проблемы, потому что точки Catmull-Rom распределены неравномерно (поэтому я не могу просто сказать, что должно быть 100 пикселей на кривой и запустить уравнение 100 раз). Я попытался использовать оценочное начальное значение максимума дельта X и Y и заполнить пробелы с помощью Bresenham, но из-за округления я все еще получаю некоторые «грязные» разделы (т. Е. Линия явно движется вверх и но я все еще получаю два пикселя с одним и тем же компонентом Y, в результате чего получается «жирный» участок линии).

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

EDIT: Вот пример кривой, что я, возможно, придется сделать:

alt text

Какие могут иметь ожидаемый результат, глядя, как это (обратите внимание, что это оценка):

alt text

Используя уравнение сплайна Catmull-Rom, нам нужно четыре точки для создания сегмента. P0 и P3 используются как касательные для входящего и исходящего направления из сегмента P1-> P2. С сплаймом Catmull-Rom синяя секция - это все, что получает интерполяцию, когда t перемещается от 0 до 1. P0 и P3 можно дублировать, чтобы гарантировать, что зеленая часть будет отображаться, так что это не проблема для меня.

Для простоты мне нужно отображать пиксели на кривой между P1 и P2, учитывая, что у меня есть касательные в форме P0 и P3. Мне не обязательно использовать сплайны Catmull-Rom, но они кажутся правильными инструментами для этой работы, поскольку контрольные точки должны проходить через. Неравномерное распределение точек интерполяции - это то, что бросает меня за цикл.

EDIT2: Вот пример того, что я имею в виду, когда я говорю, моя Результирующая кривая загрязнен:

alt text

Красные стрелки указывают несколько мест, где не должно быть пиксель. Это происходит потому, что компоненты X и Y вычисляемой координаты не изменяются с той же скоростью. Таким образом, когда каждый из компонентов округляется (так что у меня точное местоположение пикселя), может случиться так, что либо X, либо Y не наткнутся, потому что рассчитанная координата, скажем, (42.4999, 50.98). Обмен раундом для пола или потолка не решает проблему, так как он просто меняется там, где это происходит.

+0

Было бы здорово, если бы вы могли добавить еще один рисунок, показывающий ожидаемый результат от P1 до P2. –

+0

@belisarius Я не разработал математику, для которой пиксели будут заполнены на основе уравнения Катмулла-Рома, но второе изображение должно дать вам представление о том, чего я пытаюсь достичь. – Xenethyl

+0

Я попросил его из-за вашего комментария: _but, я все еще получаю два пикселя с тем же Y-компонентом_ –

ответ

2

Здесь у вас есть a paper describing method for the re-parametrization of splines, чтобы получить равноотстоящие точки вдоль длины кривой.Я думаю, что это может решить вашу проблему, если вы можете приспособить ее к кривым Катмулла-Рома (не должно быть слишком сложно, я думаю)

+0

Спасибо за ссылку на бумагу. Я не включил «длину дуги» в свой Google. Я просто немного поработал и получил гораздо лучшие результаты (см. Http://www.actionscript.org/forums/showthread.php3?t=213252). Кажется, что принятое решение этого шага совсем немного зависит от аппроксимации и предварительного расчета. Это может создать проблему производительности для меня, поскольку это выполняется в JavaScript. Я мог бы повторно опубликовать свою проблему по-другому, после того как я обдумаю это, но пока что спасибо за помощь. Вы, конечно, указали мне в правильном направлении. – Xenethyl

+0

@ Xenethyl Рад помочь! Надеюсь, вы сможете оптимизировать его для своего сценария. –