SVG картинки высокой точности

Когда мне понадобилось опубликовать научную статью в интернете, передо мной встала достаточно серьезная проблема — как рисовать иллюстрации и графики. Сомнений не было в том, что это должна быть векторная графика. Кроме того, графический движок должен обеспечивать не только рисование всевозможных графических примитивов, но и интерполяцию сплайнами для отрисовки графиков функций по заданным точкам.

Естественным выбором любого математика является язык PostScript, однако не все Hosting провайдеры разрешают C CGI скрипты, которые необходимы для отрисовки математических формул, например посредством такого инструмента, как MathTeX. Но это другая история.

Мой выбор пал на Scalable Vector Graphics, которая поддерживается большинством современных браузеров и, что не менее важно, поддерживает практически все графические примитивы и даже интерполяцию сплайнами. SVG картинка представляет собой текст языке XML. SVG стандарт хорошо документирован и не представляет большой cложности даже для начинающих web-дизайнеров.

Немного побродив по просторам интернета, я нашел приличный редактор Inkscape, который поддерживает SVG стандарт и принялся за дело.
Потратив пару часов пытаясь нарисовать картинку распределения сил действующих на физический маятник я понял, что рисовать подобное мышкой, высчитывая синусы и косинусы и с трудом попадая в нужные точки на экране — работа не благодарная. Вы можете сами оценить труд затраченный, например, на следующую картинку в редакторе Inkscape.

image

Поскольку, для меня, всегда проще написать программу на языке C, нежели рисовать мышкой на экране, я решил написать библиотеку функций для отрисовки SVG картинок.

Принцип весьма прост. Инициализируем необходимые стркутуры.


#include ‹stdlib.h›
#include ‹stdio.h›

#include ‹svgc.h›

struct __svg_sheet   *sheet;
struct __svg_line    *line;
struct __svg_rect    *rect;
struct __svg_circle  *circle;

struct __svg_scene *scene;

int main( void )
{

   sheet = (struct __svg_sheet *)__svg_new_sheet( 200, 200, 10, 10, 10, 10 );
   if( !sheet )
   {
      printf( "Unable to create sheet\n" );
   }
   (void)__svg_set_stroke_width( (struct __svg_node *)sheet, 1.0 );

   scene = __svg_new_scene( sheet );
   if( !scene )
   {
      printf( "Unable to create scene\n" );
   }


Организуем список графических примитивов.


   /* Set current values for newest objects: */
   __svg_set_scene_stroke( "black" );
   __svg_set_scene_stroke_width( 1.0 );
   __svg_set_scene_stroke_linecap( LINECAP_SQUARE );
   __svg_set_scene_fill( "none" );

   rect = (struct __svg_rect *)__svg_new_rect( 50.0, 50.0, 50.0, 50.0, 0, 0 );
   (void)__svg_set_fill_rgb( (struct __svg_node *)rect, 255, 0, 0 );
   (void)__svg_scene_add_node( scene, (struct __svg_node *)rect );

   /* Set current values for newest objects: */
   __svg_set_scene_stroke_width( 2.0 );
   __svg_set_scene_stroke_rgb( 0, 138, 147 );
   __svg_set_scene_stroke_dasharray( "15,7,3,7" );

   line = (struct __svg_line *)__svg_new_line( 50.0, 150.0, 150.0, 50.0 );
   (void)__svg_scene_add_node( scene, (struct __svg_node *)line );

   /* Set current values for newest objects: */
   __svg_set_scene_stroke( "black" );
   __svg_set_scene_stroke_width( 1.0 );
   __svg_set_scene_stroke_dasharray( "none" );
   __svg_set_scene_fill_rgb( 0, 0, 255 );

   circle = (struct __svg_circle *)__svg_new_circle( 125.0, 125.0, 35.0 );
   (void)__svg_scene_add_node( scene, (struct __svg_node *)circle );


И сохраняем полученное изображение в файл.

   __svg_paint_scene( scene, 0, "M.svg" );

   __svg_free_scene( scene );

   return( 0 );
}



Вот результат.

image

Download

Исходные тексты SVG C Library можно загрузить в виде архива svgc-1.0.4.tar.gz.

Git репозиторий доступен по адресу http://git.kxlab.com. Вы можете снять вашу локальную копию используя следующую команду


$ git clone <a href="http://git.kxlab.com/pub/scm/git/svgc.git">git.kxlab.com/pub/scm/git/svgc.git</a>


Более подробно, читайте на странице SVG C Library.

Удачи в публикации научных статей в интернете.


0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.