3.6 FAQ

График не рисуется?!

Проверьте, что точки графика находятся внутри ограничивающего параллелепипеда, при необходимости увеличьте его с помощью функции Axis(). Проверьте, что размерность массива правильная для выбранного типа графика. Убедитесь, что функция Finish() была вызвана после построения графика (или график был сохранен в файл). Иногда отражение света от плоских поверхностей (типа, Dens()) может выглядеть как отсутствие графика.

Не нашел нужного графика?!

Многие “новые” графики можно строить, используя уже существующие функции. Например, поверхность вращения кривой относительно оси можно построить, используя специальную функцию Torus(), а можно построить как параметрически заданную поверхность Surf(). См. также Hints и Примеры MathGL MathGL. Если же нужного типа графика все равно нет, то пишите мне и в следующей версии этот график появится.

Требуется ли знание сторонних библиотек (например, OpenGL) для использования библиотеки MathGL?

Нет. Библиотека MathGL самодостаточна и не требует знания сторонних библиотек.

На каком языке написана библиотека? Для каких языков у нее есть интерфейсы?

Ядро библиотеки написано на С++. Кроме него, есть интерфейсы для чистого С, фортрана, паскаля, форта и собственный командный язык MGL. Также есть поддержка большого числа интерпретируемых языков (Python, Java, ALLEGROCL, CHICKEN, Lisp, CFFI, C#, Guile, Lua, Modula 3, Mzscheme, Ocaml, Octave, Perl, PHP, Pike, R, Ruby, Tcl). Эти интерфейсы написаны с помощью SWIG (и функции чистого С и классы). Однако на данный момент только интерфейсы для Python и Octave включены в скрипты сборки. Причина в том, что я не знаю других языков, чтобы проверить качество интерфейса :(. Замечу, что большинство прочих языков могут использовать С функции напрямую.

Как мне использовать MathGL с Фортраном?

Библиотеку MathGL можно использовать как есть с компилятором gfortran поскольку он использует по умолчанию AT&T нотацию для внешних функций. Для других компиляторов (например, Visual Fortran) необходимо включить использование AT&T нотации вручную. AT&T нотация требует, чтобы имя функции завершалось символом ‘_’, аргументы функции передавались по указателю и длины строк передавались в конце списка аргументов. Например:

C функцияvoid mgl_fplot(HMGL graph, const char *fy, const char *stl, int n);

AT&T функцияvoid mgl_fplot_(uintptr_t *graph, const char *fy, const char *stl, int *n, int ly, int ls);

При использовании фортрана необходимо также включить библиотеку -lstdc++. Кроме того, если библиотека была собрана с опцией enable-double=ON (по умолчанию в версии 2.1 и более поздних), то все вещественные числа должны быть типа real*8. Это можно включить по умолчанию опцией -fdefault-real-8.

У меня есть класс Foo и в нем метод рисования Foo::draw(mglGraph *gr). Как мне нарисовать что-то в окне FLTK, GLUT или Qt?

Функции-члены класса в С++ имеют “скрытый” параметр – указатель на экземпляр класса и их прямое использование невозможно. Решением будет определение интерфейсной функции:

int foo_draw(mglGraph *gr, void *par)
{   ((Foo *)foo)->draw(gr);    }

и подстановка именно ее в вызов функции Window():

gr->Window(argc,argv,foo_draw,"Title",this);

Можно также наследовать Ваш класс от класса mglDraw и использовать функцию типа gr->Window(argc, argv, foo, "Title");.

Как мне вывести текст на русском/испанском/арабском/японском и т.д.?

Стандартный путь состоит в использовании кодировки UTF-8 для вывода текста. Кроме того, все функции вывода текста имеют интерфейс для 8-битных (char *) строк. Однако в последнем случае Вам может потребоваться установить используемую в исходном тексте локаль. Например, для русского языка в кодировке CP1251 можно использовать setlocale(LC_CTYPE, "ru_RU.cp1251"); (под MS Windows имена локали другие – setlocale(LC_CTYPE, "russian_russia.1251")). Настоятельно не рекомендую использовать константу LC_ALL, поскольку при этом меняется и формат чисел (в частности, десятичная точка), что может, например, вызвать сложности (неудобство) при написании формул и чтении текстовых файлов. Например, программа ожидает ‘,’ в качестве разделителя целой и дробной части, а пользователь вводит ‘.’.

Как мне вырезать (исключить из рисования) точку или область на графике?

Есть три основных способа. Во-первых, можно вырезать точку, задав одну из ее координат равной NAN. Во-вторых, можно воспользоваться функцией SetCutBox() или CutOff() для удаления точек из некоторой области (see Обрезание). Наконец, можно сделать эти точки прозрачными (невидимыми) с помощью функций SurfA(), Surf3A() (see Парные графики). В последнем случае обеспечивается еще и плавность включения прозрачности.

Я использую VisualStudio, CBuilder или другой компилятор (не MinGW/gcc). Как мне подключить библиотеку MathGL?

Начиная с версии 2.0, рекомендуемый к использованию класс mglGraph (заголовочный файл #include <mgl2/mgl.h>) содержbn только с inline функции и может использоваться с любым компилятором без перекомпиляции бинарной версии библиотеки. Однако, если Вы планируете использовать низкоуровневые возможности (т.е. классы mglBase, mglCanvas и т.д.), то Вам следует перекомпилировать библиотеку MathGL с использованием Вашего компилятора.

Отмечу, что использование предоставляемых динамических библиотек *.dll требует создания библиотек импорта (import library *.lib). Эта процедура зависит от используемого компилятора – обратитесь к документации по Вашему компилятору. Например для VisualStudio это можно сделать командой lib.exe /DEF:libmgl.def /OUT:libmgl.lib.

Как мне собрать MathGL под Windows?

Простейший путь – использование комбинации CMake и MinGW. Также Вам может потребоваться дополнительные библиотеки, такие как GSL, PNG, JPEG и пр. Все они могут быть найдены на http://gnuwin32.sourceforge.net/packages.html. После установки всех компонент, просто запустите конфигуратор CMake и соберите MathGL командой make.

Как создать окно FLTK/GLUT/Qt с текущими результатами параллельно с выполнением основных вычислений?

Следует создать отдельный поток для обработки сообщений в окно. Обновление данных в окне можно выполнить вызовом функции Update(). Подробнее см. Animation.

Сколько человек участвовало в создании библиотеки?

Большую часть библиотеки написал один человек. Это результат примерно года работы на написание ядра библиотеки и базовых функций (в основном вечерами и по выходным). Процесс усовершенствования продолжается и теперь :). Скрипты сборки в основном написаны Д.Кулагиным, а экспорт в PRC/PDF написан М.Видассовым.

Как мне показать растровую картинку на рисунке?

Можно импортировать ее в экземпляр mglData и построить с помощью функции Dens(). Например, для черно-белого рисунка можно использовать код: mglData bmp; bmp.Import("fname.png","wk"); gr->Dens(bmp,"wk");.

Как использовать MathGL в Qt, FLTK, wxWidgets ...?

Есть специальные классы (виджеты) для этих библиотек: QMathGL для Qt, Fl_MathGL для FLTK и т.д. Если Вы не нашли подходящий класс, то можете создать свой собственный виджет, рисующий растровое изображение из mglCanvas::GetBits().

Как мне создать 3D в PDF?

Используйте функцию WritePRC(), которая создаст PDF файл если MathGL был собран с enable-pdf=ON.

Как мне создать TeX рисунок?

Используйте функцию WriteTEX(), которая создаст LaTeX файлы с собственно рисунком ‘fname.tex’, с цветами MathGL ‘mglcolors.tex’ и основной файл ‘mglmain.tex’, который может использоваться для просмотра изображения и/или генерации PDF с помощью команды типа pdflatex mglmain.tex.

Можно ли использовать MathGL в JavaScript?

Да, пример JavaScript файла находится в папке texinfo/ исходных текстов. Для его работы необходимо предоставить JSON данные с 3d изображением (можно создать с помощью WriteJSON() функции). Скрипт позволяет выполнять базовые операции: приближение/удаление, вращение и сдвиг. Примеры использования JavaScript можно найти в http://mathgl.sf.net/json.html.

Как сменить шрифт (семейство шрифтов)?

Во-первых, надо загрузить файлы отсюда или отсюда. Далее, в экземпляре mglGraph загружаем шрифты: gr->LoadFont(fontname,path);. Здесь fontname – базовое имя шрифта, например ‘STIX2’, и path – путь к папке с файлами шрифтов. Вызовите gr->RestoreFont(); для использования шрифта по умолчанию.

Как нарисовать метки оси снаружи от графика?

Просто используйте отрицательные значения длины меток, например gr->SetTickLen(-0.1);.

Как нарисовать одинаковые оси координат для прямоугольного (не квадратного) рисунка?

Просто используйте Aspect(NAN,NAN) для каждого подграфика, или в начале рисования.

Как задать полупрозрачный фон?

Просто используйте код типа Clf("r{A5}"); или подготовьте PNG файл и задайте его в качестве фона рисунка LoadBackground("fname.png");.

Как уменьшить поля вокруг графика?

Простейший путь состоит в использовании стилей subplot. Однако, вы должны быть осторожны в изменении стиля subplot если вы планируете добавлять colorbar или вращать график – часть графика может стать невидимой.

Can I combine bitmap and vector output in EPS?

Yes. Sometimes you may have huge surface and a small set of curves and/or text on the plot. You can use function rasterize just after making surface plot. This will put all plot to bitmap background. At this later plotting will be in vector format. For example, you can do something like following:

gr->Surf(x, y, z);
gr->Rasterize(); // make surface as bitmap
gr->Axis();
gr->WriteFrame("fname.eps");
Почему у меня не получается использовать имя ‘I’ для переменной?

MathGL поддерживает стандарт C99, в котором имя ‘I’ зарезервированно для мнимой единицы. Если Вам все таки нужно это имя для переменной, то поместите

#undef I

сразу после включения заголовочных файлов MathGL.

Как мне создать MPEG видео по графикам?

Вам следует сохранить каждый кадр в файл JPEG с именем типа ‘frame0001.jpg’, ‘frame0002.jpg’, ... Далее используйте ImageMagic для конвертации этих файлов в видео формата MPEG с помощью команды convert frame*.jpg movie.mpg. См. также MPEG.