Page 9 of 10
Re: формат векторной графики
Posted: Thu Jan 20, 2011 11:02 pm
by SoUrcerer
Что-то я не догоняю, может мне подскажет кто?
Вот я делаю
Путь 1: M 0,0 Q 10,10 20,20
и Путь 2: M 0,0 q 10,10 20,20
В первом координаты абсолютные, и такую кривую Безье я легко строю.
Во втором координаты относительные, но относительно чего они относительные, я понять не могу. Какие во втором случае будут координаты, если их переводить к виду первых?
Re: формат векторной графики
Posted: Fri Jan 21, 2011 12:16 am
by SoUrcerer
Разобрался сам.
Может быть, кому-нибудь поможет:
Команда M 1,1 переводит перо в точку 1,1
Команда q 10,10 20,20 построит кривую Безье (в данном случае линию) по опорным точкам (1,1) (10+1,10+1) (20+1,20+1)
Если за ней последует q 30,30 20,20, то опорные точки будут такими: (20+1, 20+1) (30+20+1, 30+20+1) (20+20+1, 20+20+1)
Если бы подумал головой, то понял, что так и должно было быть. Но на сложных примерах понять это было непросто.
Re: формат векторной графики
Posted: Fri Jan 21, 2011 12:41 am
by SoUrcerer
Прошу прощения за столько сообщений подряд.
Набросал простую программку для отрисовки SVG paths (пока еще слишком сырая для работы), правда, еще не придумал, как удобно это дело масштабировать и заливать.
Но если отрендерить path для буквы n из Arial, потом залить в графическом редакторе черным и с бикубическим сглаживанием уменьшить, получится вот так:

-
canvas.png (499 Bytes)
Viewed 5978 times
По-моему, очень неплохо.
Буду думать, как аккуратно заливать контуры и адекватно масштабировать символы. Буду рад подсказкам.
UPD:ан нет, упустил в спецификации T. The control point is assumed to be the reflection of the control point on the previous command relative to the current point - это как?
Re: формат векторной графики
Posted: Fri Jan 21, 2011 1:10 am
by IgorA
Sorcerer wrote:Набросал простую программку для отрисовки SVG paths (пока еще слишком сырая для работы), правда, еще не придумал, как удобно это дело масштабировать и заливать.
Если эта программа на asm-е, то думаю из нее можно перенести функции рисующие SVG paths в какую-либо графическую библиотеку. Многим подобные функции окажутся полезными. Рекурсивный алгоритм заливки требует много места в стеке, так что насчет заливки ничего толкового сказать не могу.
Re: формат векторной графики
Posted: Fri Jan 21, 2011 1:12 am
by SoUrcerer
Пока что не на асме... Но с планами перевестись на асм. Ничего сверхестественного в коде нет.
Re: формат векторной графики
Posted: Fri Jan 21, 2011 1:27 am
by SoUrcerer
Интересный алгоритм заливки, может быть, даже будет работать быстро. Только не представляю, как его доделать для случаев, когда внутри закрашиваемой области есть "дыры", которые закрашивать не нужно.
http://expace.narod.ru/imageprocessing/algoritm.html
Re: формат векторной графики
Posted: Fri Jan 21, 2011 11:26 am
by SoUrcerer
Добил реализацию путей (пока что на javascript, но код действительно простейший). Сейчас буду думать над заливкой. Что касается масштабирования, мне нравится качество работы плагина scaling из zsea.
Чтобы полноценно выводить символы с помощью SVG paths, достаточно реализации следующих функций:
(prevx, prevy - переменные для хранения предыдущего положения пера, contx, conty - переменные для хранения предыдущей контрольной точки)
M (x, y) - перенести перо в точку (x,y). prevx=x; prevy=y; contx =0; conty = 0
L (x,y) - построить линию из (prevx,prevy) в (x,y). prevx=x; prevy=y; contx =0; conty = 0
H (x) - построить линию из (prevx,prevy) в (x,prevy). prevx=x; prevy=prevy; contx =0; conty = 0
h (x) - построить линию из (prevx,prevy) в (x+prevx,prevy). prevx=x+prevx; prevy=prevy; contx =0; conty = 0
V (y) - построить линию из (prevx,prevy) в (prevx,y). prevx=prevx; prevy=y; contx =0; conty = 0
v (y) - построить линию из (prevx,prevy) в (prevx,y+prevy). prevx=prevx; prevy=y+prevy; contx =0; conty = 0
Q (x,y) (x1, y1) - построить квадратичную кривую Безье из начальной точки (prevx,prevy) в конечную точку (x1,y1) при контрольной точке (x,y). prevx=x1; prevy=y1; contx=x; conty=y
q (x,y) (x1, y1) - построить квадратичную кривую Безье из начальной точки (prevx,prevy) в конечную точку (x1+prevx,y1+prevy) при контрольной точке (x+prevx,y+prevy). prevx=x1+prevx; prevy=y1+prevy; contx=x+prevx; conty=y+prevy
T (x,y) - построить квадратичную кривую Безье из начальной точки (prevx,prevy) в конечную точку (x,y) при контрольной точке, равной (2*prevx-contx,2*prevy-conty), если contx и conty не равны 0, иначе contx=x; conty=y
z - залить контур
Большая часть из этих функций уже есть (или легко может быть добавлена) в библиотеке vectors (нужно лишь научиться ее готовить - это я про себя).
Остается:
1. Написать парсер выражений,
2. Придумать, как заливать и масштабировать такую графику.
[offtop]Надеюсь, что смогу сделать всё это, и что не загорами тот день, когда в системе наконец появятся современные векторные масштабируемые шрифты. (По поводу их размера можно не переживать - Droid Sans занимает около 15 килобайт) [/offtop]
Re: формат векторной графики
Posted: Tue Jan 25, 2011 1:11 am
by Gluk
Sorcerer, круто, нет слов
в свою очередь хотел дописать в спецификацию:
неграфические функции:
1) объявить шрифт. параметры - метка (внутр. имя - номер) шрифта, формат шрифта (число), сам текст определения шрифта в этом формате, строка параметров для этого шрифта (кегль и т.д, могут отличаться от формата к формату, поэтому не стандартизуем). Есть изначально один предопределенный шрифт, это системный. Шрифт можно этой же функцией копировать-изменить, задав в строке-параметрах новые параметры, но не задавая описание формата (на него сперва нужно переключиться, т.к. такое работает для текущего шрифта), и присвоить новой метке, автоматического переключения не происходит.
2) переключиться на другой шрифт. параметры - метка шрифта.
Re: формат векторной графики
Posted: Tue Jan 25, 2011 1:17 am
by Gluk
причем форматом шрифта может быть... опять таки BFG(VS) =)
С неграфической функцией "начать определение буквы". Но т.к. это не для общего формата, то функция в нулевую уходит (контекстно-зависимый набор функций, в данном случае контекст - рисование шрифта). То есть подмножество формата. Туда же можно сколько угодно функций, нужных только для шрифтов занести (хотя я вот так сходу не могу таких придумать больше)
Re: формат векторной графики
Posted: Tue Jan 25, 2011 1:23 am
by Gluk
Так, пока не забыл.. была мысль использовать для координат только целые значения. Хотя почему была, она есть и будет есть) добавить возможность объявлять несколько координатных сеток разного масштаба - и можно рисовать звездные небеса. При автоматической конвертации создавать самую мелкую необходимую сетку - числа потратят столько же, сколько в формате-источнике (если это не SVG, где числа текстом пишутся), а при создании новых произведений (или полуручной конвертации) подбирать необходимую точность. В ручную, конечно, это никто не будет делать, да и это забота не художника, а сохранялки в формат)
Re: формат векторной графики
Posted: Tue Jan 25, 2011 1:47 am
by SoUrcerer
Разве из целочисленных координат не следует невозможность нормального масштабирования в будущем? Допустим, у нас есть квадрат (0,0)-(13,13). Как его уменьшить в 14 раз?
Re: формат векторной графики
Posted: Tue Jan 25, 2011 1:49 am
by SoUrcerer
И "самая мелкая сетка" - это какая? Даже сетки в 1x1 пиксел может не хватить, если мы хотим изображение 800x600 впихнуть в thumbnail "по-быстрому".
Re: формат векторной графики
Posted: Tue Jan 25, 2011 2:14 am
by SoUrcerer
Gluk wrote:причем форматом шрифта может быть... опять таки BFG(VS) =)
С неграфической функцией "начать определение буквы". Но т.к. это не для общего формата, то функция в нулевую уходит (контекстно-зависимый набор функций, в данном случае контекст - рисование шрифта). То есть подмножество формата. Туда же можно сколько угодно функций, нужных только для шрифтов занести (хотя я вот так сходу не могу таких придумать больше)
Примерно как SVG - шрифты... Там все это задается тегами font и glyph
Re: формат векторной графики
Posted: Tue Jan 25, 2011 12:43 pm
by Gluk
"Примерно как SVG - шрифты... Там все это задается тегами font и glyph" - ну и хорошо, проще будет конвертация =)
"И "самая мелкая сетка" - это какая? Даже сетки в 1x1 пиксел может не хватить, если мы хотим изображение 800x600 впихнуть в thumbnail "по-быстрому"." - вопрос закономерен, я его ожидал) если в рисунке - источнике в координатах самая точная из них равна 5.75379, то сетки 1000000*1000000 хватит за глаза. А если, каким-то чудом все остальные координаты кратны первой, то можно сетку y*x (где x,y кратны этому числу, и одна клеточка имеет размеры, равные этому числу) делать, этого будет достаточно для точного расположения всех объектов.
"Разве из целочисленных координат не следует невозможность нормального масштабирования в будущем? Допустим, у нас есть квадрат (0,0)-(13,13). Как его уменьшить в 14 раз?" - неа, не следует. В примере выше показано как можно заменить вещественную координату целочисленной, не потеряв в точности.
Вот как масштабировать квадрат с вещественными координатами (0.0,0.0)-(1.3*1.3)? Правильно, разделить его координаты на 14. получится квадрат (0.0,0.0)-(0.9285314...*0.9285314...).
В целочисленных координатах, квадрат останется (0,0)-(13,13), но вот если раньше одна клетка сетки была равна 7 пикселов, то теперь она равна 0.5 пиксела. Как раз эти коэффициенты остаются вещественными)
Re: формат векторной графики
Posted: Tue Jan 25, 2011 1:09 pm
by Gluk
еще 1 графический объект...
#) Вычитание. Параметры: метка (вычитание считается графическим объектом, и как к таковому, к нему можно обращаться по метке для копирования и т.д.), сколько объектов вычитать (по умолчанию - 1), из скольки объектов вычитать (по умолчанию - 1), затем, после команды, идут по очереди объекты, которые вычитают, и, сразу следом, из которых вычитают. Такой порядок позволяет строить первые в буферной области, а вторые рисовать, просто учитывая ее (не ставя пиксел) при рисовании второго. Ну можно так и не делать, но в любом случае такой порядок мешать не будет)