--- /dev/null
--- /dev/null
++cmake_minimum_required(VERSION 2.8.12)
++if(POLICY CMP0043)
++ cmake_policy(SET CMP0043 OLD)
++endif()
++
++project( MathGL2 )
++
++set(mgl_clean_files )
++set(MGL_DEP_LIBS)
++add_definitions(-DMGL_SRC)
++
++set(MGL_DEP_LIBS)
++
++if(NOT CMAKE_BUILD_TYPE)
++ set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are:
++ None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE)
++endif(NOT CMAKE_BUILD_TYPE)
++
++set(CMAKE_VERBOSE_MAKEFILE ON)
++set(MathGL_VERSION_MAJOR 2)
++<<<<<<< HEAD
++set(MathGL_VERSION_MINOR 3.5)
++set(MathGL_SOVERSION 7.4.3)
++=======
++set(MathGL_VERSION_MINOR 4)
++set(MathGL_PATCH_VERSION 1)
++set(MathGL_VERSION ${MathGL_VERSION_MAJOR}.${MathGL_VERSION_MINOR}.${MathGL_PATCH_VERSION})
++set(MathGL_SOVERSION 7.5.0)
++
++set(MathGL_INSTALL_LIB_DIR "lib" CACHE PATH "Installation directory for libraries")
++set(MathGL_INSTALL_BIN_DIR "bin" CACHE PATH "Installation directory for executables")
++set(MathGL_INSTALL_INCLUDE_DIR "include" CACHE PATH "Installation directory for headers")
++if(WIN32 AND NOT CYGWIN)
++ set(DEF_INSTALL_CMAKE_DIR cmake)
++else()
++ set(DEF_INSTALL_CMAKE_DIR lib/cmake/mathgl)
++endif()
++set(MathGL_INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files")
++# Make relative paths absolute (needed later on)
++foreach(p LIB BIN INCLUDE CMAKE)
++ set(var MathGL_INSTALL_${p}_DIR)
++ if(NOT IS_ABSOLUTE "${${var}}")
++ set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
++ endif()
++endforeach()
++
++macro(mgl_po_src)
++ set(l_files )
++ foreach(src_file ${ARGN})
++ get_filename_component(fp ${src_file} ABSOLUTE)
++ file(RELATIVE_PATH rel ${CMAKE_SOURCE_DIR} ${fp})
++ list(APPEND l_files "${rel}")
++ endforeach(src_file ${ARGN})
++ set(po_files ${po_files} ${l_files} PARENT_SCOPE)
++endmacro(mgl_po_src)
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++function(mgl_add_lib mgl_tmp_lib)
++ if(${mgl_tmp_lib} MATCHES mgl)
++ set(mgllib mgl)
++ set(mgllib2 mgl2)
++ else(${mgl_tmp_lib} MATCHES mgl)
++ set(mgllib mgl-${mgl_tmp_lib})
++ set(mgllib2 mgl2-${mgl_tmp_lib})
++ endif(${mgl_tmp_lib} MATCHES mgl)
++ set(mgl_src_lst ${ARGV})
++ list(REMOVE_AT mgl_src_lst 0)
++ add_library(${mgllib} SHARED ${mgl_src_lst})
++ add_library(${mgllib}-static STATIC ${mgl_src_lst})
++ set_target_properties(${mgllib} PROPERTIES SOVERSION ${MathGL_SOVERSION})
++ set_target_properties(${mgllib} PROPERTIES DEFINE_SYMBOL "mgl_EXPORTS")
++ set_target_properties(${mgllib} PROPERTIES C_VISIBILITY_PRESET hidden)
++ set_target_properties(${mgllib} PROPERTIES CXX_VISIBILITY_PRESET hidden)
++ set_target_properties(${mgllib} PROPERTIES VISIBILITY_INLINES_HIDDEN 1)
++ target_compile_definitions(${mgllib}-static PUBLIC MGL_STATIC_DEFINE)
++ if(MSVC)
++ set(mgl_lib_static "-static")
++ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
++ set(mgl_lib_end "d")
++ else(CMAKE_BUILD_TYPE STREQUAL "Debug")
++ set(mgl_lib_end)
++ endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
++ elseif(MSVC)
++ set(mgl_lib_static)
++ set_target_properties(${mgllib} PROPERTIES CLEAN_DIRECT_OUTPUT 1)
++ set_target_properties(${mgllib}-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
++ endif(MSVC)
++ if(enable-mgl2)
++ set_target_properties(${mgllib} PROPERTIES OUTPUT_NAME "${mgllib2}${mgl_lib_end}")
++ set_target_properties(${mgllib}-static PROPERTIES OUTPUT_NAME "${mgllib2}${mgl_lib_static}${mgl_lib_end}")
++ else(enable-mgl2)
++ set_target_properties(${mgllib} PROPERTIES OUTPUT_NAME "${mgllib}${mgl_lib_end}")
++ set_target_properties(${mgllib}-static PROPERTIES OUTPUT_NAME "${mgllib}${mgl_lib_static}${mgl_lib_end}")
++ endif(enable-mgl2)
++
++ install(
++ TARGETS ${mgllib} ${mgllib}-static
++ EXPORT MathGLTargets
++ RUNTIME DESTINATION ${MathGL_INSTALL_BIN_DIR}
++ ARCHIVE DESTINATION ${MathGL_INSTALL_LIB_DIR}
++ LIBRARY DESTINATION ${MathGL_INSTALL_LIB_DIR}
++ )
++endfunction(mgl_add_lib mgl_tmp_lib)
++
++MACRO(MGL_DEPENDENT_OPTION option doc default depends1 force1 depends2 force2)
++ IF(${option}_ISSET MATCHES "^${option}_ISSET$")
++ SET(${option}_AVAILABLE 1)
++ IF(${force1})
++ FOREACH(d ${depends1})
++ STRING(REGEX REPLACE " +" ";" CMAKE_DEPENDENT_OPTION_DEP "${d}")
++ IF(${CMAKE_DEPENDENT_OPTION_DEP})
++ ELSE(${CMAKE_DEPENDENT_OPTION_DEP})
++ SET(${option}_AVAILABLE 0)
++ SET(depends1_AVAILABLE 1)
++ ENDIF(${CMAKE_DEPENDENT_OPTION_DEP})
++ ENDFOREACH(d)
++ ENDIF(${force1})
++ IF(${force2})
++ FOREACH(d ${depends2})
++ STRING(REGEX REPLACE " +" ";" CMAKE_DEPENDENT_OPTION_DEP "${d}")
++ IF(${CMAKE_DEPENDENT_OPTION_DEP})
++ ELSE(${CMAKE_DEPENDENT_OPTION_DEP})
++ SET(${option}_AVAILABLE 0)
++ SET(depends2_AVAILABLE 1)
++ ENDIF(${CMAKE_DEPENDENT_OPTION_DEP})
++ ENDFOREACH(d)
++ ENDIF(${force2})
++ IF(${option}_AVAILABLE)
++ OPTION(${option} "${doc}" "${default}")
++ SET(${option} "${${option}}" CACHE BOOL "${doc}" FORCE)
++ ELSE(${option}_AVAILABLE)
++ IF(${option} MATCHES "^${option}$")
++ ELSE(${option} MATCHES "^${option}$")
++ SET(${option} "${${option}}" CACHE INTERNAL "${doc}")
++ ENDIF(${option} MATCHES "^${option}$")
++ IF(depends1_AVAILABLE)
++ SET(${option} OFF)
++ ELSEIF(depends2_AVAILABLE)
++ SET(${option} ON)
++ ENDIF(depends1_AVAILABLE)
++ ENDIF(${option}_AVAILABLE)
++ ELSE(${option}_ISSET MATCHES "^${option}_ISSET$")
++ SET(${option} "${${option}_ISSET}")
++ ENDIF(${option}_ISSET MATCHES "^${option}_ISSET$")
++ENDMACRO(MGL_DEPENDENT_OPTION)
++include(CMakeDependentOption)
++
++string(TIMESTAMP MGL_NIGHT "%d.%m.%y")
++
++if(WIN32)
++ option(enable-dep-dll "Enable copying off all dependent dll libraries to the install directory" OFF)
++endif(WIN32)
++
++option(enable-double "Enable double precision in MathGL library" ON)
++option(enable-mpi "Enable mpi")
++option(enable-opengl "Enable OpenGL support" ON)
++option(enable-all-docs "Enable all documentation building")
++#option(enable-doc "Enable documentation building")
++option(enable-all "Enable all core features")
++option(enable-all-widgets "Enable all Widgets")
++option(enable-all-swig "Enable all SWIG based interfaces")
++option(enable-rvalue "Enable move constructor support (need C++11)" OFF)
++option(enable-pthread "Enable POSIX threads support" ON)
++option(enable-pthr-widget "Enable POSIX threads for widgets" ON)
++option(enable-openmp "Enable OpenMP support" OFF)
++
++if(enable-pthread AND enable-openmp)
++ message(SEND_ERROR "You can't enable POSIX threads and OpenMP at the same time!")
++endif(enable-pthread AND enable-openmp)
++
++option(enable-lgpl "Enable only LGPL part of MathGL")
++option(enable-mgl2 "Use names 'libmgl2-*' instead of 'libmgl-*'")
++option(enable-ltdl "Enable loading modules support")
++CMAKE_DEPENDENT_OPTION(enable-doc-site "Enable HTML documentation for website" OFF "NOT enable-all-docs" ON)
++CMAKE_DEPENDENT_OPTION(enable-doc-html "Enable HTML documentation" OFF "NOT enable-all-docs" ON)
++CMAKE_DEPENDENT_OPTION(enable-doc-info "Enable INFO documentation" OFF "NOT enable-all-docs" ON)
++CMAKE_DEPENDENT_OPTION(enable-doc-pdf-ru "Enable Russian PDF documentation" OFF "NOT enable-all-docs" ON)
++CMAKE_DEPENDENT_OPTION(enable-doc-pdf-en "Enable English PDF documentation" OFF "NOT enable-all-docs" ON)
++#CMAKE_DEPENDENT_OPTION(enable-doc-prc "Enable PDF samples for HTML docs" OFF "NOT enable-all-docs" ON)
++#CMAKE_DEPENDENT_OPTION(enable-doc-json "Enable JSON samples for HTML docs" OFF "NOT enable-all-docs" ON)
++option(enable-texi2html "Use texi2html (obsolete package) instead of texi2any" OFF)
++CMAKE_DEPENDENT_OPTION(enable-mgltex "Enable installation of mgltex package (MGL scripts in LATEX document)" OFF "NOT enable-lgpl" OFF)
++
++CMAKE_DEPENDENT_OPTION(enable-zlib "Enable zlib support" ON "NOT enable-all" ON)
++CMAKE_DEPENDENT_OPTION(enable-png "Enable png support" ON "NOT enable-all" ON)
++CMAKE_DEPENDENT_OPTION(enable-jpeg "Enable jpeg support" ON "NOT enable-all" ON)
++MGL_DEPENDENT_OPTION(enable-gsl "Enable gsl support" ON "NOT enable-lgpl" ON "NOT enable-all" ON)
++MGL_DEPENDENT_OPTION(enable-hdf4 "Enable hdf4 support" ON "NOT enable-lgpl" ON "NOT enable-all" ON)
++MGL_DEPENDENT_OPTION(enable-hdf5 "Enable hdf5 support" ON "NOT enable-lgpl" ON "NOT enable-all" ON)
++CMAKE_DEPENDENT_OPTION(enable-pdf "Enable pdf support" ON "NOT enable-all" ON)
++CMAKE_DEPENDENT_OPTION(enable-gif "Enable gif support" ON "NOT enable-all" ON)
++CMAKE_DEPENDENT_OPTION(enable-glut "Enable glut support" ON "NOT enable-all-widgets" ON)
++CMAKE_DEPENDENT_OPTION(enable-fltk "Enable fltk widget" ON "NOT enable-all-widgets" ON)
++CMAKE_DEPENDENT_OPTION(enable-wx "Enable wxWidget widget" ON "NOT enable-all-widgets" ON)
++CMAKE_DEPENDENT_OPTION(enable-qt4 "Enable Qt4 widget" OFF "NOT enable-all-widgets" ON)
++CMAKE_DEPENDENT_OPTION(enable-qt4asqt "Set Qt4 as default libmgl-qt" OFF "enable-qt4" OFF)
++CMAKE_DEPENDENT_OPTION(enable-qt5 "Enable Qt5 widget" ON "NOT enable-all-widgets" ON)
++CMAKE_DEPENDENT_OPTION(enable-qt5asqt "Set Qt5 as default libmgl-qt" ON "enable-qt5" OFF)
++
++<<<<<<< HEAD
++# msvc fwprintf print char* for the specifier of "%s" format
++if(MSVC AND MSVC_VERSION GREATER 1899)
++ SET(CMAKE_CXX_FLAGS "/EHsc -D_CRT_STDIO_ISO_WIDE_SPECIFIERS ${CMAKE_CXX_FLAGS}")
++ SET(CMAKE_C_FLAGS "-D_CRT_STDIO_ISO_WIDE_SPECIFIERS ${CMAKE_C_FLAGS}")
++endif(MSVC AND MSVC_VERSION GREATER 1899)
++=======
++include(CheckCXXSourceCompiles)
++
++if(${CMAKE_SIZEOF_VOID_P} EQUAL 4)
++ set(CMAKE_REQUIRED_FLAGS -msse2 -mfpmath=sse)
++ CHECK_CXX_SOURCE_COMPILES("
++ int main(void){}" mgl_sse)
++ if(mgl_sse)
++ SET(CMAKE_CXX_FLAGS "-msse2 -mfpmath=sse ${CMAKE_CXX_FLAGS}")
++ SET(CMAKE_C_FLAGS "-msse2 -mfpmath=sse ${CMAKE_C_FLAGS}")
++ endif(mgl_sse)
++ unset(CMAKE_REQUIRED_FLAGS)
++endif(${CMAKE_SIZEOF_VOID_P} EQUAL 4)
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++if(enable-qt4 OR enable-qt5)
++ set(QT_ENABLED ON)
++ if(enable-qt4asqt AND enable-qt5asqt)
++ message(SEND_ERROR "You cannot make Qt4 and Qt5 as qt at the same time.")
++ endif(enable-qt4asqt AND enable-qt5asqt)
++ if(enable-qt4 AND NOT enable-qt5)
++ set(enable-qt4asqt TRUE)
++ endif(enable-qt4 AND NOT enable-qt5)
++ if(enable-qt5 AND NOT enable-qt4)
++ set(enable-qt5asqt TRUE)
++ endif(enable-qt5 AND NOT enable-qt4)
++# if(NOT enable-opengl)
++# message(SEND_ERROR "You cannot build MathGL with Qt4 or Qt5 without OpenGL enabled.")
++# endif(NOT enable-opengl)
++endif(enable-qt4 OR enable-qt5)
++
++CMAKE_DEPENDENT_OPTION(enable-json-sample "Enable JSON sample" ON "QT_ENABLED" OFF)
++MGL_DEPENDENT_OPTION(enable-python "Enable python interface" ON "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
++MGL_DEPENDENT_OPTION(enable-lua "Enable Lua (v.5.1) interface" OFF "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
++MGL_DEPENDENT_OPTION(enable-octave "Enable octave interface" ON "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
++MGL_DEPENDENT_OPTION(enable-octave-install "Octave interface will install for all users" ON "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
++
++include_directories( ${MathGL2_SOURCE_DIR}/include ${MathGL2_BINARY_DIR}/include)
++set(MGL_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/include/mgl2")
++set(MGL_CGI_PATH "${CMAKE_INSTALL_PREFIX}/share/mathgl" CACHE STRING "Set CGI install directory")
++set(MGL_DEF_FONT "STIX" CACHE STRING "Set default font name")
++
++if(NOT WIN32)
++# set(MGL_CGI_PATH "${CMAKE_INSTALL_PREFIX}/share/mathgl")
++ set(MGL_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/mathgl")
++ set(MGL_DOC_PATH "${CMAKE_INSTALL_PREFIX}/share/doc/mathgl")
++ set(MGL_MAN_PATH "${CMAKE_INSTALL_PREFIX}/share/man")
++ set(MGL_INFO_PATH "${CMAKE_INSTALL_PREFIX}/share/info")
++ set(MGL_FONT_PATH "${MGL_DATA_PATH}/fonts")
++else(NOT WIN32)
++ set(MGL_FONT_PATH "${CMAKE_INSTALL_PREFIX}/fonts")
++endif(NOT WIN32)
++
++include(CheckFunctionExists)
++include(CMakePushCheckState)
++include(TestBigEndian)
++
++TEST_BIG_ENDIAN(WORDS_BIGENDIAN)
++if(WORDS_BIGENDIAN)
++ ADD_DEFINITIONS(-DWORDS_BIGENDIAN)
++endif(WORDS_BIGENDIAN)
++
++CHECK_FUNCTION_EXISTS(sin MGL_SIN)
++CHECK_FUNCTION_EXISTS(memrchr HAVE_MEMRCHR)
++if(NOT MGL_SIN)
++ cmake_push_check_state()
++ set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} m)
++ CHECK_FUNCTION_EXISTS(sin MGL_SIN_M)
++ cmake_pop_check_state()
++ if(MGL_SIN_M)
++ set(M_LIB m)
++ elseif(MGL_SIN_M)
++ message(SEND_ERROR "Math library not found")
++ endif(MGL_SIN_M)
++endif(NOT MGL_SIN)
++set(MGL_DEP_LIBS ${M_LIB} ${MGL_DEP_LIBS})
++
++if(HAVE_MEMRCHR)
++ ADD_DEFINITIONS(-DHAVE_MEMRCHR)
++endif(HAVE_MEMRCHR)
++
++include(CheckTypeSize)
++check_type_size("long" SIZEOF_LONG)
++
++<<<<<<< HEAD
++include(CheckCXXSourceCompiles)
++=======
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++#unset(MGL_HAVE_C99_COMPLEX)
++CHECK_CXX_SOURCE_COMPILES(
++"#include <complex>
++#include <complex.h>
++int main(int argc, char *args[])
++{std::complex<double> c(2.0, 1.0);
++double _Complex i=1.0i;
++double _Complex *a = reinterpret_cast<double _Complex *>(&c);
++std::complex<double> b(*a);return 0;}" MGL_HAVE_C99_COMPLEX)
++if(NOT MGL_HAVE_C99_COMPLEX)
++ set(MGL_HAVE_C99_COMPLEX 0)
++endif(NOT MGL_HAVE_C99_COMPLEX)
++
++#unset(MGL_HAVE_NAN_INF)
++CHECK_CXX_SOURCE_COMPILES(
++"#include <math.h>
++int main(){double a=NAN, b=INFINITY;return 0;}" MGL_HAVE_NAN_INF)
++if(NOT MGL_HAVE_NAN_INF)
++ set(MGL_HAVE_NAN_INF 0)
++endif(NOT MGL_HAVE_NAN_INF)
++
++#unset(MGL_HAVE_ATTRIBUTE)
++CHECK_CXX_SOURCE_COMPILES(
++"int __attribute__((pure)) test1() {return 0;}
++int __attribute__((const)) test2(int x) {return x*x;}
++int main(int argc, char* argv[]) {return 0;}" MGL_HAVE_ATTRIBUTE)
++if(NOT MGL_HAVE_ATTRIBUTE)
++ set(MGL_HAVE_ATTRIBUTE 0)
++endif(NOT MGL_HAVE_ATTRIBUTE)
++
++<<<<<<< HEAD
++unset(MGL_HAVE_TYPEOF CACHE)
++CHECK_CXX_SOURCE_COMPILES(
++"#define mgl_isnum(a) ({typeof (a) _a = (a); _a==_a;})
++int main(){bool a=mgl_isnum(1);return 0;}" MGL_HAVE_TYPEOF)
++if(NOT MGL_HAVE_TYPEOF)
++ set(MGL_HAVE_TYPEOF 0)
++endif(NOT MGL_HAVE_TYPEOF)
++
++if(NOT MSVC AND enable-rvalue)
++ SET(CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}")
++ unset(MGL_HAVE_RVAL CACHE)
++ CHECK_CXX_SOURCE_COMPILES(
++ "struct test { test() {} test(test&& a){} };
++ int main() { test t; return 0; }" MGL_HAVE_RVAL)
++ if(NOT MGL_HAVE_RVAL)
++ message(SEND_ERROR "Couldn't enable rvalue.")
++# set(MGL_HAVE_RVAL 0)
++ endif(NOT MGL_HAVE_RVAL)
++else(NOT MSVC AND enable-rvalue)
++ set(MGL_HAVE_RVAL 0)
++endif(NOT MSVC AND enable-rvalue)
++
++
++
++=======
++if(NOT MSVC AND enable-rvalue)
++ SET(CMAKE_CXX_FLAGS "-std=gnu++11 ${CMAKE_CXX_FLAGS}")
++ unset(MGL_HAVE_RVAL CACHE)
++ CHECK_CXX_SOURCE_COMPILES(
++ "struct test { test() {} test(test&& a){} };
++ int main() { test t; return 0; }" MGL_HAVE_RVAL)
++ if(NOT MGL_HAVE_RVAL)
++ message(SEND_ERROR "Couldn't enable rvalue.")
++# set(MGL_HAVE_RVAL 0)
++ endif(NOT MGL_HAVE_RVAL)
++else(NOT MSVC AND enable-rvalue)
++ set(MGL_HAVE_RVAL 0)
++endif(NOT MSVC AND enable-rvalue)
++
++
++
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++CHECK_CXX_SOURCE_COMPILES(
++"#include <getopt.h>
++int main(int argc, char *args[]) {
++int ch = getopt(argc, args, \"1:2:3:4:5:6:7:8:9:hno:L:C:A:s:S:q:\"); return 0; }" MGL_HAVE_GETOPT)
++if(NOT MGL_HAVE_GETOPT)
++<<<<<<< HEAD
++ include_directories(${MathGL_SOURCE_DIR}/addons/getopt)
++=======
++ include_directories(${MathGL2_SOURCE_DIR}/addons/getopt)
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ set(getopt_lib-static getopt-static)
++endif(NOT MGL_HAVE_GETOPT)
++
++if(enable-double)
++ set(MGL_USE_DOUBLE 1)
++else(enable-double)
++ set(MGL_USE_DOUBLE 0)
++endif(enable-double)
++
++if(enable-qt4 OR enable-qt5)
++ set(MGL_HAVE_QT 1)
++endif(enable-qt4 OR enable-qt5)
++
++if(enable-openmp)
++ find_package(OpenMP)
++ if(OPENMP_FOUND)
++ set(MGL_HAVE_OMP 1)
++ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
++ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
++ else(OPENMP_FOUND)
++ message(SEND_ERROR "Couldn't find OpenMP. You can enable POSIX threads instead.")
++ set(MGL_HAVE_OMP 0)
++ endif(OPENMP_FOUND)
++else(enable-openmp)
++ set(MGL_HAVE_OMP 0)
++endif(enable-openmp)
++
++if(enable-mpi)
++ set(MGL_HAVE_MPI 1)
++ find_package(MPI REQUIRED)
++ set(CMAKE_CXX_COMPILE_FLAGS ${CMAKE_CXX_COMPILE_FLAGS} ${MPI_COMPILE_FLAGS})
++ set(CMAKE_CXX_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS} ${MPI_LINK_FLAGS})
++ include_directories(${MPI_INCLUDE_PATH})
++else(enable-mpi)
++ set(MGL_HAVE_MPI 0)
++endif(enable-mpi)
++
++
++if(enable-pthr-widget OR enable-pthread)
++ if(enable-pthread)
++ set(MGL_HAVE_PTHREAD 1)
++ else(enable-pthread)
++ set(MGL_HAVE_PTHREAD 0)
++ endif(enable-pthread)
++ set(MGL_HAVE_PTHR_WIDGET 1)
++ include(FindThreads)
++ if(NOT CMAKE_USE_PTHREADS_INIT)
++ message(SEND_ERROR "Couldn't find POSIX threads library.")
++ endif(NOT CMAKE_USE_PTHREADS_INIT)
++ set(MGL_DEP_LIBS ${CMAKE_THREAD_LIBS_INIT} ${MGL_DEP_LIBS})
++else(enable-pthr-widget OR enable-pthread)
++ set(MGL_HAVE_PTHR_WIDGET 0)
++ set(MGL_HAVE_PTHREAD 0)
++endif(enable-pthr-widget OR enable-pthread)
++
++if(enable-gsl)
++ set(MGL_HAVE_GSL 1)
++ find_library(GSL_LIB gsl)
++ find_library(GSL_CBLAS_LIB gslcblas)
++ find_path(GSL_INCLUDE_DIR gsl/gsl_fft_complex.h)
++ if(NOT GSL_LIB OR NOT GSL_CBLAS_LIB OR NOT GSL_INCLUDE_DIR)
++ message(SEND_ERROR "${GSL_LIB}")
++ message(SEND_ERROR "${GSL_CBLAS_LIB}")
++ message(SEND_ERROR "${GSL_INCLUDE_DIR}")
++ message(SEND_ERROR "Couldn't find GSL libraries.")
++ else(NOT GSL_LIB OR NOT GSL_CBLAS_LIB OR NOT GSL_INCLUDE_DIR)
++ set(CMAKE_REQUIRED_INCLUDES ${GSL_INCLUDE_DIR})
++ set(CMAKE_REQUIRED_LIBRARIES ${GSL_LIB} ${GSL_CBLAS_LIB})
++ CHECK_CXX_SOURCE_COMPILES("#include <gsl/gsl_multifit_nlin.h>
++ int main(){gsl_multifit_fdfsolver *s=0;gsl_matrix *J = 0;
++ gsl_multifit_fdfsolver_jac(s, J);}" MGL_HAVE_GSL2)
++ endif(NOT GSL_LIB OR NOT GSL_CBLAS_LIB OR NOT GSL_INCLUDE_DIR)
++ set(MGL_DEP_LIBS ${GSL_LIB} ${GSL_CBLAS_LIB} ${MGL_DEP_LIBS})
++ include_directories(${GSL_INCLUDE_DIR})
++else(enable-gsl)
++ set(MGL_HAVE_GSL 0)
++endif(enable-gsl)
++
++if(enable-all OR enable-ltdl)
++ set(MGL_HAVE_LTDL 1)
++ find_library(LTDL_LIB ltdl)
++ find_path(LTDL_INCLUDE_DIR ltdl.h)
++ if(NOT LTDL_LIB OR NOT LTDL_INCLUDE_DIR)
++ message(SEND_ERROR "${LTDL_LIB}")
++ message(SEND_ERROR "${LTDL_INCLUDE_DIR}")
++ message(SEND_ERROR "Couldn't find LTDL library.")
++ endif(NOT LTDL_LIB OR NOT LTDL_INCLUDE_DIR)
++ set(MGL_DEP_LIBS ${LTDL_LIB} ${MGL_DEP_LIBS})
++ include_directories(${LTDL_INCLUDE_DIR})
++else(enable-all OR enable-ltdl)
++ set(MGL_HAVE_LTDL 0)
++endif(enable-all OR enable-ltdl)
++
++if(enable-hdf4)
++ set(MGL_HAVE_HDF4 1)
++ find_library(HDF4_LIB df)
++ find_library(HDF4MF_LIB mfhdf)
++ find_path(HDF4_INCLUDE_DIR hdf/mfhdf.h)
++ if(NOT HDF4_LIB OR NOT HDF4MF_LIB OR NOT HDF4_INCLUDE_DIR)
++ message(SEND_ERROR "${HDF4_LIB}")
++ message(SEND_ERROR "${HDF4MF_LIB}")
++ message(SEND_ERROR "${HDF4_INCLUDE_DIR}")
++ message(SEND_ERROR "Couldn't find HDF4 libraries.")
++ endif(NOT HDF4_LIB OR NOT HDF4MF_LIB OR NOT HDF4_INCLUDE_DIR)
++ set(MGL_DEP_LIBS ${HDF4MF_LIB} ${HDF4_LIB} ${MGL_DEP_LIBS})
++ include_directories(${HDF4_INCLUDE_DIR})
++else(enable-hdf4)
++ set(MGL_HAVE_HDF4 0)
++endif(enable-hdf4)
++
++if(enable-hdf5)
++ set(MGL_HAVE_HDF5 1)
++ find_package(HDF5)
++ if(NOT HDF5_FOUND)
++ find_package(HDF5 NAMES hdf5 COMPONENTS C shared static)
++ if(NOT HDF5_FOUND)
++ message(SEND_ERROR "Couldn't find HDF5 library.")
++ endif(NOT HDF5_FOUND)
++ endif(NOT HDF5_FOUND)
++ set(MGL_DEP_LIBS ${HDF5_LIBRARIES} ${HDF5_C_SHARED_LIBRARY} ${MGL_DEP_LIBS})
++ include_directories(${HDF5_INCLUDE_DIRS})
++else(enable-hdf5)
++ set(MGL_HAVE_HDF5 0)
++endif(enable-hdf5)
++
++if(enable-jpeg)
++ set(MGL_HAVE_JPEG 1)
++ include(FindJPEG)
++ if(NOT JPEG_FOUND)
++ message(SEND_ERROR "Couldn't find JPEG library.")
++ endif(NOT JPEG_FOUND)
++ set(MGL_DEP_LIBS ${JPEG_LIBRARIES} ${MGL_DEP_LIBS})
++ include_directories(${JPEG_INCLUDE_DIR})
++else(enable-jpeg)
++ set(MGL_HAVE_JPEG 0)
++endif(enable-jpeg)
++
++
++if(enable-zlib)
++ set(MGL_HAVE_ZLIB 1)
++ include(FindZLIB)
++ if(NOT ZLIB_FOUND)
++ message(SEND_ERROR "Couldn't find ZLib library.")
++ endif(NOT ZLIB_FOUND)
++ set(MGL_DEP_LIBS ${ZLIB_LIBRARIES} ${MGL_DEP_LIBS})
++ include_directories(${ZLIB_INCLUDE_DIR})
++else(enable-zlib)
++ set(MGL_HAVE_ZLIB 0)
++endif(enable-zlib)
++
++if(enable-png)
++ set(MGL_HAVE_PNG 1)
++ if(NOT MGL_HAVE_ZLIB)
++ message(SEND_ERROR "You have to enable ZLib if you plan to use PNG export.")
++ endif(NOT MGL_HAVE_ZLIB)
++ include(FindPNG)
++ if(NOT PNG_FOUND)
++ message(SEND_ERROR "Couldn't find PNG library.")
++ endif(NOT PNG_FOUND)
++ set(MGL_DEP_LIBS ${PNG_LIBRARIES} ${MGL_DEP_LIBS})
++ include_directories(${PNG_INCLUDE_DIR})
++else(enable-png)
++ set(MGL_HAVE_PNG 0)
++endif(enable-png)
++
++
++if(enable-pdf)
++ set(MGL_HAVE_PDF 1)
++ if(NOT MGL_HAVE_PNG)
++ message(SEND_ERROR "You have to enable PNG if you plan to use PDF export.")
++ endif(NOT MGL_HAVE_PNG)
++ find_library(HPDF_LIB hpdf)
++ if(NOT HPDF_LIB)
++ message(SEND_ERROR "Couldn't find libHaru or libhpdf.")
++ endif(NOT HPDF_LIB)
++ find_path(HPDF_INCLUDE_DIR hpdf_u3d.h)
++ if(NOT HPDF_INCLUDE_DIR)
++ message(SEND_ERROR "Couldn't find headers of 3d-enabled version of libhpdf.")
++ endif(NOT HPDF_INCLUDE_DIR)
++ include_directories(${HPDF_INCLUDE_DIR})
++ set(MGL_DEP_LIBS ${HPDF_LIB} ${MGL_DEP_LIBS})
++else(enable-pdf)
++ set(MGL_HAVE_PDF 0)
++endif(enable-pdf)
++
++if(enable-gif)
++ set(MGL_HAVE_GIF 1)
++ include(FindGIF)
++ if(NOT GIF_FOUND)
++ message(SEND_ERROR "Couldn't find GIF library.")
++ endif(NOT GIF_FOUND)
++ set(MGL_DEP_LIBS ${GIF_LIBRARIES} ${MGL_DEP_LIBS})
++ include_directories(${GIF_INCLUDE_DIR})
++else(enable-gif)
++ set(MGL_HAVE_GIF 0)
++endif(enable-gif)
++
++if(enable-opengl)
++ set(MGL_HAVE_OPENGL 1)
++ include(FindOpenGL)
++ if(NOT OPENGL_FOUND)
++ message(SEND_ERROR "Couldn't find OpenGL libraries.")
++ endif(NOT OPENGL_FOUND)
++ set(MGL_DEP_LIBS ${OPENGL_LIBRARIES} ${MGL_DEP_LIBS})
++ include_directories(${OPENGL_INCLUDE_DIR} )
++else(enable-opengl)
++ set(MGL_HAVE_OPENGL 0)
++endif(enable-opengl)
++
++if(enable-glut)
++ set(MGL_HAVE_GLUT 1)
++ if(NOT MGL_HAVE_OPENGL)
++ message(SEND_ERROR "You have to enable OpenGL if you plan to use GLUT.")
++ endif(NOT MGL_HAVE_OPENGL)
++ include(FindGLUT)
++ if(NOT GLUT_FOUND)
++ message(SEND_ERROR "Couldn't find GLUT library.")
++ endif(NOT GLUT_FOUND)
++else(enable-glut)
++ set(MGL_HAVE_GLUT 0)
++endif(enable-glut)
++
++if(enable-fltk)
++ set(MGL_HAVE_FLTK 1)
++ FIND_PACKAGE(FLTK)
++ if(NOT FLTK_FOUND)
++ message(SEND_ERROR "Couldn't find FLTK library.")
++ else(NOT FLTK_FOUND)
++ include_directories(${FLTK_INCLUDE_DIR})
++ CHECK_CXX_SOURCE_COMPILES(
++ "#include <FL/Fl_Copy_Surface.H>
++ int main(){return 0;}" MGL_HAVE_FL_COPY)
++ endif(NOT FLTK_FOUND)
++ if(NOT MGL_HAVE_FL_COPY)
++ set(MGL_HAVE_FL_COPY 0)
++ endif(NOT MGL_HAVE_FL_COPY)
++else(enable-fltk)
++ set(MGL_HAVE_FLTK 0)
++endif(enable-fltk)
++
++if(enable-wx)
++ set(MGL_HAVE_WX 1)
++ FIND_PACKAGE(wxWidgets COMPONENTS base core gl)
++ if(NOT wxWidgets_FOUND)
++ message(SEND_ERROR "Couldn't find wxWidgets library.")
++ endif(NOT wxWidgets_FOUND)
++else(enable-wx)
++ set(MGL_HAVE_WX 0)
++endif(enable-wx)
++
++
++find_program(findxgettext xgettext)
++find_program(findmsgmerge msgmerge)
++find_program(findmsgfmt msgfmt)
++find_program(findmsgcat msgcat)
++if(NOT findmsgfmt OR NOT findxgettext OR NOT findmsgmerge OR NOT findmsgcat )
++ message("Building of translation files was disabled, because xgettext, msgmerge, msgcat or msgfmt was not found. Current translations will be just coped.")
++ set(USE_GETTEXT 0)
++else(NOT findmsgfmt OR NOT findxgettext OR NOT findmsgmerge OR NOT findmsgcat )
++ set(USE_GETTEXT 1)
++endif(NOT findmsgfmt OR NOT findxgettext OR NOT findmsgmerge OR NOT findmsgcat )
++find_package(Intl)
++if(NOT Intl_FOUND)
++ set(MGL_USE_LIBINTL 0)
++ message("Gettext and translations was fully disabled, because libintl was not found.")
++else(NOT Intl_FOUND)
++ set(MGL_USE_LIBINTL 1)
++ set(MGL_DEP_LIBS ${Intl_LIBRARIES} ${MGL_DEP_LIBS})
++ include_directories(${Intl_INCLUDE_DIRS})
++endif(NOT Intl_FOUND)
++set(po_files )
++if(WIN32)
++ set(USE_GETTEXT 0)
++ set(MGL_USE_LIBINTL 0)
++endif(WIN32)
++
++if(enable-doc-info)
++ set(MGL_HAVE_DOC_INFO 1)
++ find_program(findmi makeinfo)
++ if(NOT findmi)
++ message(SEND_ERROR "Couldn't find makeinfo needed for documentation building.")
++ endif(NOT findmi)
++else(enable-doc-info)
++ set(MGL_HAVE_DOC_INFO 0)
++endif(enable-doc-info)
++
++if(enable-doc-html OR enable-doc-site)
++ if(enable-texi2html)
++ find_program(findth texi2html)
++ if(NOT findth)
++ message(SEND_ERROR "Couldn't find texi2html needed for documentation building.")
++ endif(NOT findth)
++ else(enable-texi2html)
++ find_program(findth texi2any)
++ if(NOT findth)
++ message(SEND_ERROR "Couldn't find texi2any needed for documentation building.")
++ endif(NOT findth)
++ endif(enable-texi2html)
++endif(enable-doc-html OR enable-doc-site)
++
++if(enable-texi2html)
++ set(site_en ${CMAKE_BINARY_DIR}/texinfo/doc_en/doc_en.html)
++ set(site_ru ${CMAKE_BINARY_DIR}/texinfo/doc_ru/doc_ru.html)
++ set(th_opt )
++else(enable-texi2html)
++ set(th_opt --html)
++ set(site_en ${CMAKE_BINARY_DIR}/texinfo/doc_en/index.html)
++ set(site_ru ${CMAKE_BINARY_DIR}/texinfo/doc_ru/index.html)
++endif(enable-texi2html)
++
++if(enable-doc-html)
++ set(MGL_HAVE_DOC_HTML 1)
++else(enable-doc-html)
++ set(MGL_HAVE_DOC_HTML 0)
++endif(enable-doc-html)
++
++if(enable-doc-site)
++ set(MGL_HAVE_DOC_SITE 1)
++else(enable-doc-site)
++ set(MGL_HAVE_DOC_SITE 0)
++endif(enable-doc-site)
++
++if(enable-doc-pdf-ru)
++ set(MGL_HAVE_DOC_PDF_RU 1)
++ find_program(findtp texi2pdf)
++ if(NOT findtp)
++ message(SEND_ERROR "Couldn't find texi2pdf needed for documentation building.")
++ endif(NOT findtp)
++else(enable-doc-pdf-ru)
++ set(MGL_HAVE_DOC_PDF_RU 0)
++endif(enable-doc-pdf-ru)
++
++if(enable-doc-pdf-en)
++ set(MGL_HAVE_DOC_PDF_EN 1)
++ find_program(findtp texi2pdf)
++ if(NOT findtp)
++ message(SEND_ERROR "Couldn't find texi2pdf needed for documentation building.")
++ endif(NOT findtp)
++else(enable-doc-pdf-en)
++ set(MGL_HAVE_DOC_PDF_EN 0)
++endif(enable-doc-pdf-en)
++
++if(enable-doc-site)
++ set(MGL_HAVE_DOC_JSON 1)
++else(enable-doc-site)
++ set(MGL_HAVE_DOC_JSON 0)
++endif(enable-doc-site)
++
++if(enable-doc-site)
++ set(MGL_HAVE_DOC_PRC 1)
++ if(NOT enable-pdf)
++ message(SEND_ERROR "You need to enable pdf support for MathGL.")
++ endif(NOT enable-pdf)
++else(enable-doc-site)
++ set(MGL_HAVE_DOC_PRC 0)
++endif(enable-doc-site)
++
++if(UNIX)
++ add_definitions(-DNO_COLOR_ARRAY)
++endif(UNIX)
++
++if(WIN32)
++ add_definitions(-DWIN32)
++endif(WIN32)
++
++if(NOT MGL_HAVE_GETOPT)
++ add_subdirectory( addons/getopt )
++endif(NOT MGL_HAVE_GETOPT)
++
++add_subdirectory( src )
++add_subdirectory( widgets )
++add_subdirectory( include )
++if(NOT enable-lgpl)
++ if(MGL_HAVE_QT)
++ add_subdirectory( udav )
++ if(enable-json-sample)
++ add_subdirectory( json )
++ endif(enable-json-sample)
++ endif(MGL_HAVE_QT)
++ if(enable-python OR enable-lua OR enable-octave)
++ add_subdirectory( lang )
++ endif(enable-python OR enable-lua OR enable-octave)
++add_subdirectory( utils )
++add_subdirectory( examples )
++<<<<<<< HEAD
++ if(NOT WIN32)
++ add_subdirectory( fonts )
++ endif(NOT WIN32)
++# add_subdirectory( mgllab )
++=======
++if(NOT WIN32)
++ add_subdirectory( fonts )
++endif(NOT WIN32)
++add_subdirectory( mgllab )
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++endif(NOT enable-lgpl)
++
++if(NOT MSVC AND NOT BORLAND)
++
++ if(MGL_HAVE_DOC_HTML OR MGL_HAVE_DOC_SITE OR MGL_HAVE_DOC_INFO OR MGL_HAVE_DOC_PDF_RU OR MGL_HAVE_DOC_PDF_EN )
++ add_subdirectory( texinfo )
++ endif(MGL_HAVE_DOC_HTML OR MGL_HAVE_DOC_SITE OR MGL_HAVE_DOC_INFO OR MGL_HAVE_DOC_PDF_RU OR MGL_HAVE_DOC_PDF_EN )
++
++endif(NOT MSVC AND NOT BORLAND)
++
++if(enable-mgltex)
++ add_subdirectory( mgltex )
++endif(enable-mgltex)
++
++if(MGL_USE_LIBINTL)
++ if(USE_GETTEXT)
++ set(mgl_tl_list )
++ add_custom_command(OUTPUT mathgl.pot
++ COMMAND ${findxgettext} -s --keyword=_ -C -c --package-name=MathGL2 --package-version=${MathGL_VERSION} -o ${MathGL2_BINARY_DIR}/mathgl.pot ${po_files}
++ WORKING_DIRECTORY ${MathGL2_SOURCE_DIR}/
++ DEPENDS ${po_files} )
++ set(mgl_clean_files mathgl.pot ${mgl_clean_files})
++ foreach(tl ru es) # en)
++ add_custom_command(OUTPUT mathgl_${tl}.po.done
++ COMMAND ${findmsgmerge} -U mathgl_${tl}.po ${MathGL2_BINARY_DIR}/mathgl.pot
++ COMMAND ${CMAKE_COMMAND} -E touch ${MathGL2_BINARY_DIR}/mathgl_${tl}.po.done
++ WORKING_DIRECTORY ${MathGL2_SOURCE_DIR}/
++ DEPENDS mathgl.pot mathgl_${tl}.po)
++ add_custom_command(OUTPUT mathgl_${tl}.mo
++ COMMAND ${findmsgfmt} -o mathgl_${tl}.mo ${MathGL2_SOURCE_DIR}/mathgl_${tl}.po
++ DEPENDS mathgl_${tl}.po.done)
++ install( FILES ${MathGL2_BINARY_DIR}/mathgl_${tl}.mo DESTINATION "${CMAKE_INSTALL_PREFIX}/share/locale/${tl}/LC_MESSAGES/" RENAME mathgl.mo )
++ set(mgl_tl_list mathgl_${tl}.mo ${mgl_tl_list})
++ set(mgl_clean_files mathgl_${tl}.mo mathgl_${tl}.po.done ${mgl_clean_files})
++ endforeach(tl)
++ add_custom_target(mgl_translations ALL DEPENDS ${mgl_tl_list})
++ else(USE_GETTEXT)
++ foreach(tl ru es) # en)
++ install( FILES ${MathGL2_SOURCE_DIR}/translations/mathgl_${tl}.mo DESTINATION "${CMAKE_INSTALL_PREFIX}/share/locale/${tl}/LC_MESSAGES/" RENAME mathgl.mo )
++ endforeach(tl)
++ endif(USE_GETTEXT)
++endif(MGL_USE_LIBINTL)
++
++set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${mgl_clean_files}")
++
++# WARNING!!! DO NOT ADD ANYTHING AFTER THIS LINE!
++add_subdirectory ( scripts )
--- /dev/null
--- /dev/null
++<<<<<<< HEAD
++2.3.5.1 Released 2 June 2016
++=======
++2.4.1 Released 20 July 2017
++
++* Add 'beltc' plot, which is 'belt' with manual coloring.
++* Add style '~' for 'plot' and 'tens' to omit some points at output.
++* Add style ':' for 'axis' to draw lines through point (0,0,0).
++* Bugfixes
++
++2.4 Released 17 May 2017
++
++* Add mgllab executable, which is FLTK based version of UDAV. Most things mgllab do faster.
++* Add string manipulation in MGL language:
++ o 'str'[n] -- get string of only n-th symbol;
++ o 'str'+v -- add value v to the last character of the string;
++ o 'str',val || 'str',!val -- append numeric value to the string (as before).
++* Add time value to MGL language in format: "hh-mm-ss_DD.MM.YYYY" or "hh-mm-ss" or "DD.MM.YYYY".
++* Add 'iris' plot to show cross-dependencies of several data arrays.
++* Add 'flame2d' to draw flame fractals.
++* Add 'bbox' to set bounding box for 2D output.
++* Add 'section' to get part of data between specified values.
++* Add 'detect' to found curves along data maximums.
++* Add 'dilate' to extend the region of 1-th value.
++* Add 'erode' to narrow the region of 1-th value.
++* Add 'apde' to solve PDE equation in inhomogeneous nonlinear media with spatial dispersion.
++* Add 'symbol' to draw the glyphs defined by 'addsymbol'.
++* Add 'addsymbol' to declare user-defined symbol (or glyph), which can be used as markers for plot (with style '&') or drawn itself by 'symbol' command.
++* Add 'openhdf' to open all data arrays from HDF file.
++* Extend 'crop' to cut to optimal size for FFT (i.e. to closest of 2^n*3^m*5^l).
++* Add function mgl_data_max_first() and data suffixes .m[xyz][fl] to find first/last maximum along direction.
++* Add function mgl_datac_diff_par() to parametric derivative of complex data.
++* Add style 'F' for 'bars' and 'barh' to set fixed bar widths.
++* Add style 'a' for 'plot', 'tens', 'area' and 'region' to accurate drawing of data, which partially lie out of axis range.
++* Add style '#' for 'region' to draw wired plot.
++* Add possibility of manual shift in 'multiplot'.
++* Add parsing arguments of options for MGL commands.
++* MGL command 'correl' now can perform 2d and 3d correlations.
++* Option 'meshnum' now change the number of drawn markers for 'plot', 'tens', 'step, 'mark' and 'textmark'.
++* Function 'step' handle data with x.nx>y.nx similarly to 'bars'.
++* Extend 'tile' and 'tiles' by adding manual coloring and face orientation.
++* Add variant of MGL command 'copy' to copy data with "incorrect" names.
++* Improve tick labels drawing.
++* Improve time-ticks (add weeks) and add subticks to its.
++* Improve 'fplot' to handle several singularities.
++* Add LaTeX command \dfrac{}{}. This is full-sized version of \frac{}{}. Unfortunately, there is no support of nesting (i.e. \dfrac{\dfrac{}{}}{} not working). Contrary, \frac{}{} allow nesting.
++* Add mglODEc() -- ODE solver for complex variables.
++* Add cmplx(a,b)=a+i*b to the list of known functions in formula parsing
++* Update CMake find_package to find MathGL.
++* Increase line width for wired text.
++* Update documentation: add description of new commands, add hint @ref{Mixing bitmap and vector output}.
++* Add translation to Russian for most of labels and messages.
++* Name 'all' are reserved in MGL scripts now as synonym of -1.
++
++* INCOMPATIBLE: Replace libmgl-qt by libmgl-qt4 and libmgl-qt5 for resolving conflicts of simultaneously installed both Qt4 and Qt5.
++* Minor bugfixes.
++
++
++2.3.5.1 Released 20 June 2016
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++* INCOMPATIBLE: library libmgl-qt is removed. You need to use libmgl-qt4 or libmgl-qt5 explicitly now.
++* Compatibility changes for latest MS VisualStudio.
++* Bugfixes.
++
++2.3.5 Released 16 May 2016
++
++* Greatly update mgltex (by Diego Sejas Viscarra)
++ o \MGL@codes: Bugfix: category code for tabulators is changed too
++ o \MGL@quality: 9 is accepted as quality value now
++ o \MGL@scale: Now accepts any positive value
++ o \MGL@test@switch: New command to verify and validate switching arguments
++ o \mglTeX: Add a small negative space in the logo, between the "mgl" and "TEX"
++ o \mglTeX: Declared now as robust command
++ o \mglcomments: Now accepts arguments 0 (equivalent to off) and 1 (equivalent to on), besides the usual off and on
++ o \mglgraphics: New command options: gray, mglscale, quality, variant
++ o \mglname: Now writes the MGL code line setsize 600 400 to the main script
++ o \mglplot: Added \bgroup and \egroup in order to keep changes private
++ o New command options: gray, mglscale, quality, variant
++ o \mglsettings: Added options gray and variant
++ o Now calls the \mglswitch and \mglcomments commands for the switch and comments options, respectively
++ o \mglswitch: Now accepts arguments 0 (equivalent to off) and 1 (equivalent to on), besides the usual off and on
++ o mglTeX now depends on the ifpdf package
++ o Change definition of \mglcommentname from MGL comment to mglTEX comment
++ o Introduce the concept of global, local and private settings in the documentation
++ o New commands: \mglgray (to activate/deactivate) gray-scale mode locally, and \mglvariant (to set variant of arguments in MGL scripts locally)
++ o New package option 9q for setting quality to 9 (for testing purposes of the author)
++ o New package options 0v, 1v, 2v to select variant of arguments in MGL scripts
++ o New package options gray, color to activate/deactivate gray-scale mode for graphics
++ o Remove the \MGL@setkeys command, since it isn’t needed as first thought
++ o Rename \MGL@document@scripts to \MGL@doc@scripts
++ o Rename \MGL@script@name to \MGL@script
++ o Rename command \MGL@graph@ext to \MGL@imgext
++ o Rename command \mglcommonscriptname to mglsetupscriptname
++ o Rename environment mglcommon to mglsetupscript (mglcommon is still available, but deprecated)
++ o Rename family MGL@keys as MGL@gr@keys for consistency
++ o Reorganize and update documentation
++ o Some minor bugfixes
++ o The MGL code line "setsize 600 400" is now automatically written to the main script in order for the scaling options and commands to work
++ o mgl: New environment options: gray, mglscale, quality, variant
++ o mglcode: New environment options: gray, mglscale, quality, variant
++* Add MGL command 'variant' to select proper variant of arguments (like "var1?var2?var3?...") in MGL commands.
++* Remove limitation of maximal number (was 1000) of arguments for MGL commands. This is actual for 'list' command.
++* Add mglWnd::Widget() for accessing widget which is used for drawing.
++* Add Gray() for producing gray-scaled image.
++* Add MGL command 'setsizescl' for scaling all further 'setsize'.
++* Add Shear() for shearing plot.
++* Add ShearPlot() for placing plots side-by-side with some shearing.
++* Add mglData::Limit() for limit maximal absolute value of data.
++* Add mglTridMat() for tridiagonal matrix algorithm.
++* Add MGL command 'diffract' for single step diffraction calculation.
++* Add 'ifsfile' for reading IFS fractal parameters from *.ifs file.
++* Add style '*' for 2d versions of Pipe() and Flow() to draw threads from points inside axis range.
++* Add "norm()" to the list of known functions
++* Compatibility changes for MS VisualStudio, MacOS, Win64.
++* Bugfix for legend export into EPS and SVG.
++* Bugfix for importing data from std::vector.
++* Improve Surf3*() drawing.
++* Force NAN if divided by 0 in formulas.
++* Option "-S" of mglconv now perform scaling in any cases
++
++
++2.3.4 Released 13 February 2016
++
++* Add mglData::Pulse() for determining pulse parameters.
++* Add mglData::ScanFile() for getting formated data from textual file.
++* Add mglData::SetList() for setting data from variable argument list of double values.
++* Add mglIFS2d() and mglIFS3d() for fractal generation using iterated function system (thanks to Diego Sejas Viscarra).
++* Add option to SetSize() for scaling only primitives but don't erase it.
++* Add Pmap() plot for Poincare map.
++* Add Lamerey() plot for Lamerey diagram.
++* Add Bifurcation() plot for Bifurcation diagram.
++* Add mglGraph::SetPenDelta() for changing size of semi-transparent area around lines, marks, glyphs, ...
++
++* Add MGL command 'echo' for printing the content of data.
++* Add MGL command 'print' -- like 'info' but print immediately in stdout.
++* Allow MGL command 'save' append textual strings to a file.
++* Add option to rewrite file in 'savehdf'.
++
++* Add callback functions to mglQt, mglFLTK, and extend mglDraw class for simpler drawing in parallel with calculation (see @ref{Draw and calculate}).
++
++* Force set focus for editor in UDAV.
++* Add line numbers to UDAV editor. Cyan number denote current line, red numbers denote lines with errors.
++* Disable mouse wheel for zooming in UDAV by default.
++
++* Update mgltex (thanks to Diego Sejas Viscarra).
++
++* INCOMPATIBLE: Scale internally d1,d2 arguments in Curve() to be exactly the same as Bezier curve (P0=p1, P1=d1+p1, P2=p2-d2, P3=p2).
++
++* Minor bugfixes and improvements.
++
++2.3.3 Released 01 June 2015
++
++* Add SurfCA() and Surf3CA() plots.
++* Add wavelet transforms.
++* Add AttachLight() for attaching light settings to inplots.
++* Add manual rotation angle for axis ticks (by "value" option).
++* Add mglDataS class which is similar to std::vector<double> one.
++* Add missing mglDataC functions.
++
++* Add style '%' for color scheme along 2 coordinates (as in Map()).
++* If tick template start with '&' then long integer is passed instead of double.
++* Add style 'V' for drawing text centered vertically.
++* Add style "dN" in Smooth() for averaging over (2*N+1)-th points.
++* Add TeX symbols "\quote", "--" and Cyrillic ones.
++
++* Add complex numbers in MGL -- any expression started with '!' will have complex value(s).
++* Add 'rkstep' command for Runge-Kutta step in MGL script.
++* Add functions 'min()', 'max()' to MGL parser and formula evaluation.
++* MGL command 'join' now can join arbitrary number of data arrays.
++* Command 'stop' is not required to be placed before 'func'.
++* Add warning about writing to temporary arrays in MGL scripts.
++* Names 'rnd','nan','inf' are reserved in MGL scripts now.
++
++* Add annotation for plot styles and options into header files.
++* Greatly improve the speed of formula parsing for MGL scripts
++* Update JS interface
++* Add binary font files for speeding up initialization and font loading
++* Exclude "pure" attribute for function due to compatibility reasons
++* Add mgl_set_size_scl() for additional scaling width and height of the image
++* Add options -S, -q for mglconv
++* Rearrange toolbuttons in UDAV.
++* Bugfix for Flow() and Pipe() functions
++* Other minor improvements, bugfixes and compatibility changes
++
++2.3.2 Released 2 February 2015
++
++* Update mgltex (thanks to Diego Sejas Viscarra)
++* Add reading files with complex numbers by 'read' command.
++* Parallelize reading textual data files.
++* Add 'i','j','k' variables for data filling.
++* Add 2-color style for candle and ohlc plot.
++* Add saving images in QMathGL even if corresponding format support is disabled.
++* Add cmake option MGL_DEF_FONT to change default font name or use built-in one (if MGL_DEF_FONT is empty).
++* Compatibility changes and bugfixes.
++
++2.3.1 Released 21 October 2014
++
++* Add MGL command 'load' for loading MGL commands from external DLL (or .so) module.
++* Add Logo() function to draw bitmap (logo), which is stretched along whole axis range
++* Add MGL command 'reset' which restore default settings and clear image (i.e. call DefaultPlotParam()).
++* Change y coordinate at x-z projection.
++* Improve projection of 'unrotatable' objects (like legend, title, ...).
++* Add projection (Ternary&8) which is the same as usual (Ternary&4) but don't print text on projections
++* Improve orientation of axis ticks and labels.
++* Add mglWnd::SetDrawFunc().
++* Add mgl_set_global_warn() and mgl_get_global_warn() for set/get messages of global scope.
++* Make copying private of mglGraph and derived.
++* Add virtual destructors.
++* Add some static functions for mglGraph.
++* Add option "-n" to mglconv to disable automatic saving of the image.
++* Add option "-s" to mglview and mglconv to run setup script before the main one.
++* Become compatible with giflib 5.1.
++* Add light scaling at MGLD import.
++* Add scaling of frames at Adjust().
++* Possible bugfix for 32bit gcc.
++* Update docs.
++
++
++2.3 Released 7 August 2014
++
++* Add background image, which allow in particular semi-transparent background color. Correspondingly add function Rasterize() for saving current image as background, and function LoadBackground() for loading background image from PNG or JPEG file.
++* Add primitives to draw polygon and angle arc.
++* Allow arbitrary factor for axis ticks (like, gr->SetTicks('x',M_PI,0,NAN,"\\pi");).
++* Add function AddTick() for adding manual tick to existed ones.
++* Add new styles and symbols:
++ - arrow style 'X';
++ - color gradient (color scheme) of glyphs in text;
++ - manual dash style, like "{df090}";
++ - manual mask style, like "{s00ff00182424f800}";
++ - Add styles 'fFE0123456789+-' for printing numbers in functions Axis(), Colorbar(), Table() and Label();
++ - style '!' to disable ticks tuning in Axis() and Colorbar();
++ - special symbol '\b' which will be ignored at printing;
++ - calligraphic TeX symbols, like \calB, \calE, \calF, \calH, \calI, \calL, \calM, \calR, \ell, \scrg, \scro.
++
++* Add ODE solving functions for textual formulas
++* Add function for global cubic spline interpolation, and function to refill using global spline.
++* Add functions "random(dat)" and "gamma_inc(a,x)" to the list of known functions for formula parsing
++* Add 'inf' variable to the MGL and formula parsing
++* Allow reading JPEG files for mglData::Import().
++* Function mgl_data_subdata_ext() handle NULL argument(s). Add variants of SubData() with 1 and 2 arguments.
++* Warning messages and information are printed to stderr until call of mgl_suppress_warn(true) will disable it.
++* Add function mgl_check_version() and MGL command 'version' to check if MathGL version is valid.
++* Add move constructor(s) if compiler support C++11 rvalues.
++
++* Changes in algorithms:
++ - Greatly increase speed of formula parsing (i.e. of functions mglData::Modify(), mglData::Fill() and similar), and speeding up many other places;
++ - Improve algorithm for contours drawing and filling, taking special attention to quasi-random data.
++ - Spline() now use 5-th order polynomials to keep continuity of 2nd derivative too.
++ - Add function attributes 'pure' or 'const', which potentially can speed up drawing.
++ - Use spline instead of linear interpolation in functions Flow() and Pipe().
++ - Adjust columnplot and gridplot positions for non-zero distance between the inplots.
++ - Improve colorbar labels drawing at SetRotatedText(false)
++ - Choose new scales for perspective.
++ - Allow 'negative' angles for text rotation
++ - Use new s-hull version for triangulation.
++* Make function mgl_get_curvs() to be exported. This function is used internally to connect line segments to a set of curves (in particular, for contour lines).
++* Add ViewAsRotate() function which handle arguments of View() by the same way as Rotate() function, i.e View(tetx,tetz,tety) <=> ViewAsRotate(-tetz,-tetx,-tety)
++* Function mglWindow::Adjust() for Quality&4==0 now show image in widgets even if draw function is absent (i.e. =NULL).
++
++* improvements in UDAV:
++ - Rearrange tool buttons;
++ - Add features for manual dashing and manual mask in Style dialog;
++ - Add dialog for new dialog for new inplots (including subplot, multiplot, columnplot, stickplot, gridplot);
++ - Add option to use dots plot at image refreshing (for faster rotation etc);
++ - Add new primitives (arc,polygon,rotated text) as mouse handled ones;
++ - Add close button to data tabs;
++ - Add button to stop script drawing and stop() slot for QMathGL;
++ - Allow to delete/hide/unhide selected plot;
++ - Allow to move selected plot between inplots;
++ - Improve NewCommand dialog -- now it replace the script command if user change arguments only;
++ - MGL commands 'perspective' and 'fog' now work correctly in UDAV;
++ - Update UDAV icons to use Oxygen ones.
++
++2.2.2.1 Released 19 March 2014
++
++* Compatibility changes for MS VisualStudio 2010 and early.
++* Function SetRange(v1,v2) ignore NAN values now.
++* Add enable-json-sample for building json-samples on demand only.
++* Update docs.
++
++
++2.2.2 Released 10 March 2014
++
++* Add mgl_region_3d() to draw region (or ribbon) between 2 curves. Correspondingly extend mglGraph::Region() function and MGL command 'region'.
++* Allow LGPL for MathGL widgets.
++* Improve export to TeX.
++* Add missing functions to Fortran interface.
++* Bugfix for legend with enabled lighting.
++* Minor bugfixes and memory leaks.
++
++
++2.2.1 Released 22 January 2014
++
++* Add Qt5 support.
++* Add Pascal interface.
++* Improve JavaScript interface.
++* Add function AddRange(char dir, mreal v1, mreal v2) and extend corresponding MGL commands '[xyzc]range'.
++* Add 'hypot' function for known functions in formula parsing.
++* Add style '~' to disable colorbar or axis labels. NOTE, axis style '_' is obsolete and should be replaced by '~'.
++* Change Aspect() if Ax=NAN. Now, Ay and Az set the ratio to optimal aspect (not exact value as previously).
++* Disable changes by View(),Zoom(),Perspective() for position of Title(), Legend(), Colorbar().
++* Partial support of perspective in CalcXYZ().
++* Speed up PDE solving.
++* Add complex versions of PDE, QO2d, QO3d.
++* Correct filled background for Box() in curved coordinates.
++* Allow nx=1 for Stem and Error.
++* Bugfix for drawing single axis.
++* Bugfix for missing options parsing for some of MGL commands.
++* Bugfix for .pmin suffix in MGL. Add mglData::MaximalNeg() and mglData::MinimalPos() functions. Add .nmin and .nmax suffixes.
++* Bugfix for colorbar labels.
++* Force using python 2.7 by default due to bug in Ubuntu. Debian sid works well with python 3.* too.
++* Minor bugfixes and memory leaks.
++
++
++2.2 Released 11 November 2013
++
++* Add OpenMP calls mostly everywhere (can work as replacement of pthreads - a bit faster since more loops is parallelized).
++* Greatly speed up consequent FFT and Hankel transforms. Add mgl_clear_fft() function for manual clearing of saved FFT/Hankel data.
++* Add OHLC() plot for drawing Open-High-Low-Close diagram
++* Add wxMathGL widget.
++* Add interface for Lua v.5.1.
++* Add mask for face drawing if one of symbols "-+=;oOsS~<>jdD*^" is specified in color scheme. This work only for export in bitmap images.
++* Add Quality=8 for dots drawing (extremely fast).
++* Add styles '4','6','8' for Cone() and Cones() to produce square, hex-, octo-prism.
++* Add style 't' for Cones() to produce tubes (cylinders).
++* Add style '^' for Legend() to left/right align legend if its coordinates are right/left from the center
++* Add style '<', '^', '>' for aligning/centering boxes in Bars(), Barh(), BoxPlot(), Cones(). Also this plots become centered by default if nx sizes are the same for all data.
++* Add Dots() function which set independently both color and alpha of dots
++* Improve automatic axis position. Add style '^' for inverse automatic axis position.
++* Improve tick labeling. Add style TuneTicks&4 for zero filling of tick labels.
++* Add mglData::Refill() for filling by interpolation of parametrically dependent data
++* Add transparency for Area() and Region() plots.
++* Add mgl_clf_chr() function and extend 'clf' command.
++* Fourier now perform true inverse Fourier transform (instead of backward one).
++* Improve/change lighting from local sources. Add SetDiffuse() function.
++* C functions now return NULL if HMDT data cannot be created for given input argument(s).
++* Enable line width for Mesh() and Fall() plots.
++* Replace +INF and -INF by NAN in textual formula output.
++* Add manual compression of JSON.
++* Define WORDS_BIGENDIAN and HAVE_MEMRCHR (thanks to Dinar Valeev).
++* Bugfix for cleaning unused points.
++* Fix 'setsize' command at UDAV starting.
++* Rewrite MGL parsing by using std::wstring for avoiding possible bugs of wcs*() functions.
++* Minor bugfixes.
++* Update docs.
++
++2.1.3.1 Released 8 May 2013
++
++* Compatibility changes for MS VS.
++* Bugfixes for cmake options enable-double=OFF, enable-zlib=OFF.
++* Enable mouse actions for Firefox in JS sample.
++
++2.1.3 Released 2 May 2013
++
++* Functions SinFFT, CosFFT, Hankel and so on, become multi-threaded
++* Use DFT instead of FFT if GSL support is disabled (much slow!).
++* Add Join() function for joining mglData arrays
++* Add Roots() function for root finding of nonlinear equation using provided guess(es)
++* Add mglExprC for parsing formula with complex numbers
++* Correctly read #QNAN values in data files
++* Speed up Dots() drawing
++* Add flag to disable tick labels at axis origin (see SetOriginTick())
++* Add MGL commands 'origintick', 'tickshift'
++* WriteJSON now use zlib if filename end at 'z' (like "test.jsonz")
++* Make separate libmgl-mpi
++* Add SetAutoRanges() function (duplicate corresponding options)
++* Add JSON sample usage via QtWebKit (thanks to DATADVANCE)
++* Bugfixes and memory leaks
++
++2.1.2 Released 28 January 2013
++
++* Exclude "local" functions from resulting library.
++* String in MGL script now can be concatenated with another string or data/numbers (like 'max(u)=',u.max,' a.u.').
++* Bugfix for colors in 3D PDF.
++* Bugfix for drawing in MPI mode.
++* If Aspect() function have NAN argument(s) then it try to select optimal aspect ratio.
++* Option 'size' in Legend() now change only text size (not mark size).
++* Option 'meshnum' now influence on Boxs() and Belt() functions
++* Adjust marks drawing (line width and dots).
++* Minor improvements and bugfixes.
++
++2.1.1 Released 24 December 2012
++
++* Bugfix for SetRange(val,val) function
++* Exclude export MGL to CPP
++* MGL parsing now produce errors for any wrong list of arguments
++* Add help message to mgl.cgi
++* Improve text rotation at View()
++* Make compatible with GIF library v.5.0.
++* Bugfix for making MPI interface.
++* Bugfix for running in Win32 mode.
++* Update docs and MGL samples
++
++2.1 Released 13 December 2012
++
++* Add class mglDataC for complex data arrays.
++* Add mglData::Solve() for finding x-value where dat(x)=val.
++* Add mglData::Clean() for removing rows with duplicate values for given column.
++* Add Vect3() plot for drawing vectors on slice of 3d vector field.
++* Add Table() function for drawing table with data values.
++* Add ZoomAxis() for zooming/shifting axis range as whole.
++* Add WriteJSON() function for exporting in JSON format suitable for later drawing by JavaScript
++* Add JavaScript code for visualizing JSON data.
++* Add mgl.cgi tool which return PNG image for CGI request in form of MGL script.
++* Add MGL commands 'errbox', 'face'
++
++* Color can be specified as its RGB[A] values, i.e. like "{xFFFFFF}" or "{xFFFFFFFF}".
++* Color in color scheme may have position in range [0,1]. Format is {CN,pos} or {xFFFFFF,pos}.
++* Now pen width for marks is proportional to pen width of line multiplied by size of marks.
++* Now you can use different font-faces in the plot simultaneously.
++* Now Legend() automatically use several columns if it contain too many legend entries.
++* Add style '-' for legend for drawing them horizontally.
++* Vectors is drawn now even if only starting or ending points are placed in bounding box.
++* Strongly rewrite the algorithm of vector field plotting.
++
++* Grid lines for NAN origin values are always located at far-away edges.
++* Try correctly place axis and tick labels even for axis with inverse range (i.e. for v2<v1).
++ Note, it work well for 2D axis. One should use Aspect() with negative values to do it correctly in general case.
++* Axis style 'XYZ' draw corresponding axis with ticks labels from other side of axis. This also influence on followng Label() calls.
++* Text is drawn for initially invisible axis (like z-axis) too.
++
++* Add functions GetFrame(), AddFrame() for replacing or adding data from given frame. Work if MGL_VECT_FRAME is set on (by default is on).
++* Frames now save 3D information if MGL_VECT_FRAME is set (by default).
++* CalcXYZ() function now use data from z-buffer for better determining {x,y,z} coordinates.
++
++* Add dialog for data arguments in "New command" dialog of UDAV.
++* Value of arguments are saved while the kind of command is changed in "New command" dialog of UDAV.
++* Extend classification of commands in "New command" dialog of UDAV and make it automatic.
++* Mouse position at an object click now is displayed on the image itself.
++* Add zoom in/out by mouse wheel.
++* Add zoom in/out of axis range by mouse wheel, and shift of axis range by middle button.
++* Text editor in UDAV now highlight current line.
++* Completer can be switched off correctly now.
++* Multi-line strings (i.e. separated by "\" symbol) are highlighted correctly now.
++* Add option to enable/disable selected plot in UDAV.
++* Rearrange hot-keys in UDAV and in QMathGL.
++
++* Make code compilable by Borland compiler too.
++* Improve output in OpenGL mode.
++* Add fog at export in EPS/SVG formats.
++* Add mglParse::AllowFileIO() for enable/disable I/O commands in MGL scripts.
++
++* Export functions now can write in stdout if file name is "-".
++* Picture drawing now use multi-threading for each stage.
++
++* Functions mglData::Spline*, mglData::Linear* now can return gradient at the point.
++* mglFourier now make true inverse transform
++
++* Add annotation for all pure C functions.
++* Update list of built-in glyphs
++* Update samples
++* Update documentation
++* Different bugfixes
++
++* INCOMPATIBLE CHANGES in the arguments of functions: mgl_axis, mgl_axis_grid, mgl_label, mgl_labelw, mgl_legend_pos, mgl_legend; and in functions for MGL parsing.
++* MINOR INCOMPATIBLE: plotting functions now use double argument always.
++
++2.0.3 Released 27 July 2012
++
++* Make code compilable by compilers GNU/MinGW GCC, Clang, MS VisualStudio
++* Add mglTriangulation() using s_hull_pro algorithm
++* Add mglData::Grid() and mglGraph::DataGrid() for filling regular data by values of triangulated surface
++* Add cmake options 'enable-png' and 'enable-zlib'
++* Add SetTimeUTC() for using UTC time instead of local one
++* Add SetTickShift() for additional shift of tick labels
++* Add mglGraph::MPI_Send() and mglGraph::MPI_Recv()
++* Vector plots now draw vector at edges, which are directed out of bounding box
++* Add gap between 1d plots for avoiding possible undetermined overlapping.
++* Add parallel build for documentation
++* Bugfixes for memory leaks and uninitialized variables
++* Bugfix for setting text size
++* Bugfix for handling NAN color value
++* Bugfix for missing lines in export to EPS/SVG
++
++2.0.2 Released 24 May 2012
++
++* Add 'U' style for Axis() which disable ticks rotation.
++* Bugfix for enable-opengl option.
++* Bugfix for lighting.
++
++2.0.1 Released 23 May 2012
++
++* Improve speed of drawing
++* Add reading 3d data files using mglData::ReadMat()
++* Exclude unnecessary dependencies/inclusions
++* Improve build system
++ - Add multithreading
++ - Add install for Octave
++ - Separate enable-doc option from enable-all
++* Minor bugfixes
++
++2.0 Released 12 April 2012
--- /dev/null
--- /dev/null
++<<<<<<< HEAD
++mathgl (2.3.5.1-1) UNRELEASED; urgency=medium
++
++ * New upstream version 2.3.5.1
++
++ -- Dimitrios Eftaxiopoulos <eftaxiop@filippos.ntua.gr> Tue, 24 Jan 2017 18:39:45 +0200
++=======
++mathgl (2.4.1-2) unstable; urgency=medium
++
++ * Push to unstable. Closes: #868622
++
++ -- Alastair McKinstry <mckinstry@debian.org> Wed, 02 Aug 2017 10:43:55 +0100
++
++mathgl (2.4.1-1) experimental; urgency=medium
++
++ * New upstream release
++ * Remove spurious build-dependency on libtwebkit-dev. Closes: #867297
++
++ -- Alastair McKinstry <mckinstry@debian.org> Tue, 01 Aug 2017 08:52:55 +0100
++
++mathgl (2.4-1) unstable; urgency=medium
++
++ * New upstream release
++ * Library version numbers updated to soname 7.4.1->7.5.0
++ * Standards-Version: 4.0.0
++ * Set libmgl-data as M-A: foreign
++ * Added myself as uploader
++
++ -- Alastair McKinstry <mckinstry@debian.org> Wed, 28 Jun 2017 09:27:37 +0100
++
++mathgl (2.3.4-1.1) unstable; urgency=medium
++
++ * Non-maintainer upload.
++ * Fix from Bas Couwenberg for HDF5 build issue. Closes: #835680
++
++ -- Alastair McKinstry <mckinstry@debian.org> Mon, 12 Sep 2016 10:41:06 +0100
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++mathgl (2.3.4-1) unstable; urgency=medium
++
++ * Imported Upstream version 2.3.4
++ * Disable C++11 features
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sat, 20 Feb 2016 13:34:52 +0200
++
++mathgl (2.3.3+svn1216-1) unstable; urgency=medium
++
++ * Imported Upstream version 2.3.3+svn1216 (Closes: #800460)
++ * Fix GSL-2 use bug - thanks to Bas Couwenberg (Closes: #805801)
++ * Fix Qt related bug -thanks to Peter Green (Closes: #803312)
++ * Enable Octave interface (Closes: #741156)
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sat, 05 Dec 2015 16:20:20 +0200
++
++mathgl (2.3.3-3) unstable; urgency=medium
++
++ * Disable need for C++11 support (Closes: #800460)
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Mon, 05 Oct 2015 21:53:19 +0300
++
++mathgl (2.3.3-2) unstable; urgency=medium
++
++ * Fix FTBFS on several arches (patched by E. G. Evans) (#Closes: 797610)
++ * Set enable-qt ON in json sample enable line
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sat, 05 Sep 2015 22:51:26 +0300
++
++mathgl (2.3.3-1) unstable; urgency=medium
++
++ * Imported Upstream version 2.3.3 (Closes: #788776)
++ * Transition from Qt4 to Qt5 (Closes: #784495)
++ * Add libqt5opengl5-dev, libxcursor-dev and fluid to Build-Depends
++ * Set compat=9
++ * Fix several dep5 related issues in d/copyright
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sat, 29 Aug 2015 03:52:28 +0300
++
++mathgl (2.3.2-1) experimental; urgency=medium
++
++ * Imported Upstream version 2.3.2
++ * Fix d/copyright format as prompted by lintian warning
++ * Add file argument to udav exec in udav/udav.desktop
++ * Fix d/copyright as prompted by lintian info
++ * Replace swig3.0 build dep by swig
++ * Update Conflicts/Replaces entries in d/control
++ * Set versioned build dependency for libssl1.0.0 to avert FTBFS
++ * Update copyright holder names in d/copyright
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Thu, 12 Feb 2015 11:26:30 +0200
++
++mathgl (2.2.2.1-3) unstable; urgency=medium
++
++ * Re-enable Architecture=any on all arch dependent binaries
++ * Edit several Conflicts and Replaces lines in d/control
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sun, 20 Apr 2014 09:53:11 +0300
++
++mathgl (2.2.2.1-2) unstable; urgency=medium
++
++ * Exclude kfreebsd-i386 from build arch due to FTBFS
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Mon, 24 Mar 2014 12:20:56 +0200
++
++mathgl (2.2.2.1-1) unstable; urgency=medium
++
++ * Imported Upstream version 2.2.2.1
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Mon, 24 Mar 2014 01:00:27 +0200
++
++mathgl (2.2.2+svn930-2) unstable; urgency=medium
++
++ * Build against newer libwxgtk3.0 (Closes: #741710)
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sun, 16 Mar 2014 09:02:42 +0200
++
++mathgl (2.2.2+svn930-1) unstable; urgency=medium
++
++ * Imported Upstream version 2.2.2+svn930 (Closes: #741131)
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sat, 15 Mar 2014 12:08:13 +0200
++
++mathgl (2.2.1+svn921-1) unstable; urgency=low
++
++ * Imported Upstream version 2.2.1+svn921 (Closes: #737110, #737437)
++ * Fix DEP5 lintian error in d/copyright
++ * Disable openmpi support and keep pthread support (Closes: #738540)
++ * Disable octave interface due to FTBFS
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sun, 23 Feb 2014 19:16:25 +0200
++
++mathgl (2.2-1) unstable; urgency=low
++
++ * Imported Upstream version 2.2
++ * Disable documentation building in order to avoid FTBFS on some arches
++ * Disable Lua interface
++ * Drop symbols files (Closes: #701320, #701651)
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Fri, 10 Jan 2014 12:29:27 +0200
++
++mathgl (2.1.3.1-4) unstable; urgency=low
++
++ * More symbols changes for build on ia64
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sun, 18 Aug 2013 11:32:38 +0300
++
++mathgl (2.1.3.1-3) unstable; urgency=low
++
++ * Further symbols tweaking for build on ia64
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sun, 18 Aug 2013 08:48:20 +0300
++
++mathgl (2.1.3.1-2) unstable; urgency=low
++
++ * Amend symbols files to enable build on ia64
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sat, 17 Aug 2013 21:00:08 +0300
++
++mathgl (2.1.3.1-1) unstable; urgency=low
++
++ * Imported Upstream version 2.1.3.1 (Closes: #708969)
++ * Add mpi-default-dev to build dependencies.
++ * Add patch for lang/setup.py.in to enable python to read directory tree
++ written in utf-8 (not ascii) encoding.
++ * Add UDAV.desktop and udav.png to the files to be installed within the
++ package udav.
++ * Add Replaces and Conflicts with mathgl-1* packages in the debian/control
++ file.
++ * Add udav manpage.
++ * Replace octave3.2-headers with liboctave-dev in build deps.
++ * Fix library package names to reflect soname.
++ * Rename mathgl-doc binary to mathgl-doc-en.
++ * Fix installation directory in doc-base file mathgl-doc-en.
++ * Fix installation directory of python module and files.
++ * Add udav binary package.
++ * Make build dependency on libhdf5-dev only.
++ * Add c++ compilation include path for pyconfig.h
++ * Fix typo in libmgl-glut6.0.0 package (by D. Haley) (Closes: #698570)
++ * Change soname in libraries from 6 to 7
++ * Add libmgl-qt7.0.0 library package creation
++ * Add libmgl-fltk7.0.0 and libmgl-wx7.0.0 packages
++ * Remove DM-Upload-Allow field from debian/control
++ * Remove D. Haley from uploaders after his request
++ * Update Standards-Version to 3.9.4
++ * Add title for CMakeLists-txt.patch
++ * Remove encoding specification line from udav.desktop
++ * Shorten debian/rules file by using dh $@ and overrides
++ * Remove .pyc file from python-mathgl package
++ * Remove old udav manpage file
++ * Modify vcs field
++ * Associate udav.1 manpage to package udav
++ * Built with g++-4.7 on both unstable and experimental
++ * Add version on libfltk1.3-dev build dependency
++ * Remove (optional) tags from symbols
++ * Built with gcc-4.8 on amd64
++ * Add Conflicts/Replaces options in debian/control
++ * Remove multiarch related commands from debian/rules
++ * Add libqtwebkit-dev to build deps in debian/control
++ * Amend libmgl7.0.0 related symbols for amd64
++ * Install executable mgl.cgi in /usr/bin
++ * Amend overlooked debian/copyright
++ * Add libmgl-mpi binary package
++ * Add header to the CMakeLists-txt.patch
++ * Correct short package description lines (Closes: #703834)
++ * Minor symbols tuning
++ * Remove version from libfltk1.3-dev build dependency
++ * Fix most, missing compilation and linker flag, lintian warnings
++ * Update header of CMakeLists-txt.patch
++ * Add --parallel option to dh $@ in debian/rules
++ * Include missing files and licenses in debian/copyright
++ * Fix build failure due to gsl 1.15 --> 1.16 upgrade
++ * Add full text of BSD license in debian/copyright
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sun, 11 Aug 2013 22:24:05 +0300
++
++mathgl (2~rc1-3) experimental; urgency=low
++
++ * Fix symbols FTBFS, related to libmgl-wnd6, on several arches.
++ * Make libmgl-dev dependent on libmgl-wnd6.
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Wed, 4 Jan 2012 20:16:00 +0200
++
++mathgl (2~rc1-2) experimental; urgency=low
++
++ * Correct typo in mathgl description in debian/control (Closes: #644863).
++ * Try to fix symbols FTBFS on several arches.
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Wed, 4 Jan 2012 15:30:00 +0200
++
++mathgl (2~rc1-1) experimental; urgency=low
++
++ * New experimental upstream release (Closes: #632468).
++ * No documentation debian packages provided.
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Wed, 28 Sep 2011 11:30:00 +0300
++
++mathgl (1.11.2-6) unstable; urgency=low
++
++ * Fix FTBFS for sparc (Closes: #642654).
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Mon, 26 Sep 2011 16:23:12 +0300
++
++mathgl (1.11.2-5) unstable; urgency=low
++
++ * Resolve differences for all non-optional symbols, in symbols files for ia64,
++ sparc and sh4 architectures (Closes: #642654).
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Mon, 26 Sep 2011 10:25:00 +0300
++
++mathgl (1.11.2-4) unstable; urgency=low
++
++ * Add python-numpy to Depnds of python-mathgl in debian/control and add
++ dh_numpy in binary-arch in debian/rules (Closes: #641793).
++ * Ammend symbols files for ia64, sparc and sh4 architectures (Closes: #642654).
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sat, 24 Sep 2011 23:16:00 +0300
++
++mathgl (1.11.2-3) unstable; urgency=low
++
++ * Replace libfltk-dev with libfltk1.3-dev | libfltk-dev in debian/control
++ Build-Depends (Closes: #638834).
++ * Ammend symbols files for s390x architecture (Closes: #639492).
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Wed, 7 Sep 2011 06:04:00 +0300
++
++mathgl (1.11.2-2) unstable; urgency=low
++
++ * Add debian/source/options file in order to avoid the generation of unneeded debian-
++ changes patch, due to the creation of extra file config.log during build.
++ * Ammend symbols files.
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Thu, 18 Aug 2011 20:48:00 +0300
++
++mathgl (1.11.2-1) unstable; urgency=low
++
++ * Incorporate changes due to the last two NMU's.
++ * New upstream version.
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Tue, 28 Jun 2011 17:01:00 +0200
++
++mathgl (1.11.1.1-2.2) unstable; urgency=low
++
++ * Non-maintainer upload (closes: #610777).
++ * debian/libmgl-qt5.symbols: _ZN10QByteArrayD1Ev is needed on sparc and
++ ia64, so add it as optional.
++ * debian/libmgl-wx5.symbols: three destructors known to be undefined on
++ armel/armhf are also not defined on ia64 or sparc, so mark these as
++ optional also. Destructors of foreign classes are not part of the
++ library ABI, so it's fine to ignore these.
++
++ -- Steve Langasek <vorlon@debian.org> Sun, 19 Jun 2011 07:57:43 +0000
++
++mathgl (1.11.1.1-2.1) unstable; urgency=low
++
++ * Non-maintainer upload.
++ * Fix library symbols files (closes: #610777):
++ - debian/libmgl-qt5.symbols: drop _ZN10QByteArrayD2Ev, which is not
++ present on *any* architecture anymore.
++ - debian/libmgl-fltk5.symbols: _ZN9Fl_PixmapC2EPKPKc is not present on
++ ia64 or sparc and never has been.
++ - debian/libmgl5.symbols:
++ + _ZN7mglFuncD1Ev is present on all architectures, drop the
++ architecture list (fixing the 'kfeebsd' typo that caused a build
++ failure on kfreebsd-amd64).
++ + _ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED2Ev,
++ _ZN8u3dLightD2Ev: symbols not seen on *any* archs, drop.
++ + Drop 18 symbols whose exclusion list included all 15 architectures
++ that have been tested.
++ + Other symbols that are template instantiations are now marked as
++ optional symbols instead of tagged with an arch list, since they are
++ not part of the ABI and will come and go based on the compiler
++ version used, *not* just on the architecture.
++ + If there are 8 or more architectures in the arch qualifier, invert
++ it. In some cases this reveals that certain symbols are actually
++ 64-bit specific - so infer that not-yet-tested 32-bit archs follow
++ the pattern.
++ - debian/*.symbols: any symbols marked for armel should also be marked
++ for armhf.
++ * debian/rules: clean the dependency_libs out of .la files at build
++ time, per Policy 10.2. Closes: #620629.
++
++ -- Steve Langasek <vorlon@debian.org> Sat, 18 Jun 2011 07:33:55 +0000
++
++mathgl (1.11.1.1-3) unreleased; urgency=low
++
++ * Further attempt to fix symbol breakages
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sun, 29 May 2011 19:41:00 +0200
++
++mathgl (1.11.1.1-2) unstable; urgency=low
++
++ * Try to fix libmgl5 related symbols breakage on all arches
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sun, 22 May 2011 20:50:00 +0200
++
++mathgl (1.11.1.1-1) unstable; urgency=low
++
++ * New upstream version
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Tue, 26 Apr 2011 01:15:00 +0200
++
++mathgl (1.11.0.1-9) unreleased; urgency=low
++
++ * Again try to fix build failure due to broken symbols for several architectures
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sat, 2 Apr 2011 02:05:00 +0200
++
++mathgl (1.11.0.1-8) unstable; urgency=low
++
++ * Try to fix build failure due to broken symbols for several architectures
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Thu, 24 Mar 2011 23:56:00 +0200
++
++mathgl (1.11.0.1-7) unstable; urgency=low
++
++ * Create patch for the removal of the texinfo/mgl_ru.info-* files
++ * Update symbols files (Closes: #618235)
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Mon, 14 Mar 2011 00:10:00 +0200
++
++mathgl (1.11.0.1-6) unstable; urgency=low
++
++ * Try to fix build failure due to broken symbols for sparc64
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sat, 5 Mar 2011 21:27:00 +0200
++
++mathgl (1.11.0.1-5) unstable; urgency=low
++
++ * Try to fix build failure due to broken symbols for armel and s390
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Fri, 25 Feb 2011 21:30:00 +0200
++
++mathgl (1.11.0.1-4) unstable; urgency=low
++
++ * Create mixed symbols files for amd64 and i386 with tagged symbols
++ (Closes: #610777)
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sat, 19 Feb 2011 23:10:00 +0200
++
++mathgl (1.11.0.1-3) unstable; urgency=low
++
++ * Upload in unstable
++ * Change symbols files for pbuilder --distribution unstable (Closes: #610777)
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sat, 12 Feb 2011 22:14:00 +0200
++
++mathgl (1.11.0.1-2) experimental; urgency=low
++
++ * Update symbols files for pbuilder --distribution experimental.
++ * Remove createpngdirectory.patch from series.
++ * Apply patch for FTBFS on i386 (Closes: #607539).
++ * Add Replaces tags for old mathgl-doc package in debian/control.
++ * Various improvements in the debian/rules file.
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Mon, 17 Jan 2011 21:43:00 +0200
++
++mathgl (1.11.0.1-1) experimental; urgency=low
++
++ * Correct debian/copyright file.
++ * Create proper patches for the changes in the source tree.
++ * Add new package for Russian documentation.
++ * New upstream release (Closes: #603004).
++ * Correct several spelling mistakes in manpages and in lang/numpy.i
++ * Create symbols files for libraries.
++ * Register documentation to doc-base.
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sun, 12 Dec 2010 19:13:00 +0200
++
++mathgl (1.10.2.1-2) unstable; urgency=low
++
++ * Make .png pictures visible from the html documentation.
++ * Add python support (Closes: #541481).
++
++ -- Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr> Sun, 11 Sep 2010 12:37:00 +0200
++
++mathgl (1.10.2.1-1) unstable; urgency=low
++
++ [ D Eftaxiopoulos ]
++ * Update to Debian Policy 3.9.1
++ * Put myself and D. Haley to the maintainers list.
++ * Comment out parallel-build-png.patch in the debian/patches/series file
++ since it seems to apply to a texinfo/Makefile.am file that is not
++ included in the source tree.
++ * Append package quilt to the build-depends list for the source in the
++ debian/control file, in order to fix a lintian error.
++ * Reinstate debian/source/format file with content '3.0 (quilt)'.
++ * Fix Lintian warnings related to manpages.
++
++ [ D Haley ]
++ * New upstream release 1.10.2.1 (Closes: #562743).
++
++ [ Salvatore Bonaccorso ]
++ * New Maintainer (Closes: #564422). Set Maintainer to Debian Science
++ Maintainers <debian-science-maintainers@lists.alioth.debian.org>.
++ * Convert to '3.0 (quilt)' package source format. Drop quilt framework for
++ packaging.
++ * debian/control:
++ - Change Vcs-Browser and Vcs-Git to the debian-science git repository.
++ - Change Section for source package to 'science' as per debian-science
++ group policy.
++ - Set DM-Upload-Allowed field to yes.
++ * Add myself to Uploaders.
++
++ [ Sylvestre Ledru ]
++ * Missing dependency against automake added.
++
++ -- Sylvestre Ledru <sylvestre@debian.org> Sun, 15 Aug 2010 21:45:47 +0200
++
++mathgl (1.9-3) unstable; urgency=low
++
++ * QA upload.
++ * Properly orphan the package (see #564422), set maintainer to QA.
++ * Bump Standards-Version to 3.8.4, no changes needed.
++ * Add debian/README.source, pointing to quilt doc.
++ * Bump build-deps on octave from 3.0 to 3.2 (Closes: #574025).
++
++ -- Stefano Zacchiroli <zack@debian.org> Fri, 26 Mar 2010 14:06:08 +0100
++
++mathgl (1.9-2) unstable; urgency=low
++
++ * Fix FTBFS. Closes: #545882.
++ * Update Standards-Version to 3.8.3.
++
++ -- Bradley Smith <bradsmith@debian.org> Wed, 09 Sep 2009 22:44:44 +0100
++
++mathgl (1.9-1) unstable; urgency=low
++
++ * New upstream release. Closes: #535503.
++ * QT -> qt in package descriptions. Closes: #534425.
++
++ -- Bradley Smith <bradsmith@debian.org> Sun, 19 Jul 2009 16:41:41 +0100
++
++mathgl (1.8.1-6) unstable; urgency=low
++
++ * Redo descriptions.
++
++ -- Bradley Smith <bradsmith@debian.org> Tue, 09 Jun 2009 20:26:42 +0100
++
++mathgl (1.8.1-5) unstable; urgency=low
++
++ * Correct info-dir-section in texinfo/mathgl.texi. Closes: #528893.
++
++ -- Bradley Smith <bradsmith@debian.org> Wed, 27 May 2009 17:52:50 +0100
++
++mathgl (1.8.1-4) unstable; urgency=low
++
++ * Correct libltdl-dev Build-Depend. Closes: #526426.
++ * Further improve descriptions.
++
++ -- Bradley Smith <bradsmith@debian.org> Fri, 01 May 2009 12:59:05 +0100
++
++mathgl (1.8.1-3) unstable; urgency=low
++
++ * Tidy up descriptions. Closes: #521830, #521917.
++ * Update Standards-Version to 3.8.1. (No changes).
++ * Fix watch file.
++
++ -- Bradley Smith <bradsmith@debian.org> Sat, 18 Apr 2009 17:42:59 +0100
++
++mathgl (1.8.1-2) unstable; urgency=low
++
++ * Fix parallel builds. Closes: #519738.
++
++ -- Bradley Smith <bradsmith@debian.org> Thu, 19 Mar 2009 19:08:37 +0000
++
++mathgl (1.8.1-1) unstable; urgency=low
++
++ * New upstream release. Closes: #518769.
++
++ -- Bradley Smith <bradsmith@debian.org> Sun, 08 Mar 2009 13:29:33 +0000
++
++mathgl (1.8-1) unstable; urgency=low
++
++ * Initial release. Closes: #510378.
++
++ -- Bradley Smith <bradsmith@debian.org> Thu, 01 Jan 2009 11:27:32 +0000
--- /dev/null
--- /dev/null
++Source: mathgl
++Section: science
++Priority: optional
++Maintainer: Debian Science Maintainers <debian-science-maintainers@lists.alioth.debian.org>
++Uploaders: Dimitrios Eftaxiopoulos <eftaxi12@otenet.gr>,
++ Alastair McKinstry <mckinstry@debian.org>
++Build-Depends: debhelper (>= 9), libltdl-dev, libgsl-dev, freeglut3-dev,
++ libgl1-mesa-dev | libgl-dev, libpng-dev, libhdf5-dev, libqt5opengl5-dev,
++ libjpeg-dev, libtiff-dev, libfltk1.3-dev, libqt5webkit5-dev, libwxgtk3.0-dev,
++ texinfo, texlive, texlive-generic-recommended, liblua5.1-dev, libxcursor-dev,
++ libgif-dev, python-dev, python-numpy, libfontconfig1-dev,
++ libhdf4-dev, chrpath, libxinerama-dev, libxmu-dev, libxi-dev, libhpdf-dev,
++ mpi-default-dev, swig3.0, cmake, libxft-dev, liboctave-dev, fluid
++Standards-Version: 4.0.0
++Homepage: http://mathgl.sourceforge.net/doc_en/Main.html
++Vcs-Git: https://anonscm.debian.org/debian-science/packages/mathgl.git
++Vcs-Browser: https://anonscm.debian.org/gitweb/?p=debian-science/packages/mathgl.git
++
++Package: mathgl
++Architecture: any
++Section: libs
++Depends: ${shlibs:Depends}, ${misc:Depends}, libmgl7.5.0 (= ${binary:Version})
++Description: library for scientific graphs (utilities and examples)
++ A free cross-platform library of fast C++ routines for plotting data in up
++ to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++ files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++ MathGL can also be used in the console. There are interfaces to a set of
++ languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++ .
++ This package contains MathGL utilities and examples.
++
++Package: udav
++Architecture: any
++Section: libs
++Depends: ${shlibs:Depends}, ${misc:Depends}, libmgl7.5.0 (= ${binary:Version})
++Description: library for scientific graphs (window interface)
++ A free cross-platform library of fast C++ routines for plotting data in up
++ to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++ files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++ MathGL can also be used in the console. There are interfaces to a set of
++ languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++ .
++ This package contains the udav window environment based on mathgl.
++
++# Package: mathgl-doc-en
++# Architecture: all
++# Section: doc
++# Depends: dpkg (>= 1.15.4) | install-info, ${misc:Depends}
++# Replaces: mathgl-doc, mathgl-doc-ru
++# Conflicts: mathgl-doc, mathgl-doc-ru
++# Description: library for scientific graphs (English documentation)
++# A free cross-platform library of fast C++ routines for plotting data in up
++# to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++# files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++# MathGL can also be used in the console. There are interfaces to a set of
++# languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++# .
++# This package contains the MathGL documentation in English.
++
++Package: libmgl7.5.0
++Architecture: any
++Multi-Arch: foreign
++Section: libs
++Depends: ${shlibs:Depends}, ${misc:Depends}, libmgl-data
++Replaces: libmgl5, libmgl6, libmgl6.0.0, libmgl7.1.0, libmgl7.2.0,
++ libmgl7.4.0
++Conflicts: libmgl5, libmgl6, libmgl6.0.0, libmgl7.1.0, libmgl7.2.0,
++ libmgl7.4.0
++Description: library for scientific graphs (main runtime library)
++ A free cross-platform library of fast C++ routines for plotting data in up
++ to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++ files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++ MathGL can also be used in the console. There are interfaces to a set of
++ languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++ .
++ This package contains the shared object files.
++
++<<<<<<< HEAD
++# Package: libmgl-mpi7.4.1
++# Architecture: any
++# Section: libs
++# Depends: ${shlibs:Depends}, ${misc:Depends}, libmgl-data
++# Replaces: libmgl-mpi7.0.0, libmgl-mpi7.1.0, libmgl-mpi7.2.0, libmgl-mpi7.4.0
++# Conflicts: libmgl-mpi7.0.0, libmgl-mpi7.1.0, libmgl-mpi7.2.0, libmgl-mpi7.4.0
++# Description: library for scientific graphs (mpi enhanced runtime library)
++# A free cross-platform library of fast C++ routines for plotting data in up
++# to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++# files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++# MathGL can also be used in the console. There are interfaces to a set of
++# languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++# .
++# This package contains the, parallel interface enhanced, shared object
++# files.
++=======
++Package: libmgl-mpi7.5.0
++Architecture: any
++Section: libs
++Depends: ${shlibs:Depends}, ${misc:Depends}, libmgl-data
++Replaces: libmgl-mpi7.0.0, libmgl-mpi7.1.0, libmgl-mpi7.2.0, libmgl-mpi7.4.0
++Conflicts: libmgl-mpi7.0.0, libmgl-mpi7.1.0, libmgl-mpi7.2.0, libmgl-mpi7.4.0
++Description: library for scientific graphs (mpi enhanced runtime library)
++ A free cross-platform library of fast C++ routines for plotting data in up
++ to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++ files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++ MathGL can also be used in the console. There are interfaces to a set of
++ languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++ .
++ This package contains the, parallel interface enhanced, shared object
++ files.
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++Package: libmgl-wnd7.5.0
++Architecture: any
++Section: libs
++Depends: ${shlibs:Depends}, ${misc:Depends}, libmgl-data
++Replaces: libmgl-fltk5, libmgl-wnd6, libmgl-qt5, libmgl-wx5, libmgl-wnd6.0.0,
++ libmgl-wnd7.1.0, libmgl-wnd7.2.0, libmgl-wnd7.4.0
++Conflicts: libmgl-fltk5, libmgl-wnd6, libmgl-qt5, libmgl-wx5, libmgl-wnd6.0.0,
++ libmgl-wnd7.1.0, libmgl-wnd7.2.0, libmgl-wnd7.4.0
++Description: library for scientific graphs (windows runtime library)
++ A free cross-platform library of fast C++ routines for plotting data in up
++ to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++ files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++ MathGL can also be used in the console. There are interfaces to a set of
++ languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++ .
++ This package contains the window opening related shared object files based
++ on Fltk, Qt and Wx.
++
++Package: libmgl-glut7.5.0
++Architecture: any
++Section: libs
++Depends: ${shlibs:Depends}, ${misc:Depends}, libmgl-data
++Replaces: libmgl-glut5, libmgl-glut6.0.0, libmgl-glut7.1.0, libmgl-glut7.2.0,
++ libmgl-glut7.4.0
++Conflicts: libmgl-glut5, libmgl-glut6.0.0, libmgl-glut7.1.0, libmgl-glut7.2.0,
++ libmgl-glut7.4.0
++Description: library for scientific graphs (glut interface for windows)
++ A free cross-platform library of fast C++ routines for plotting data in up
++ to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++ files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++ MathGL can also be used in the console. There are interfaces to a set of
++ languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++ .
++ This package contains the glut interface shared object files for window
++ opening.
++
++Package: libmgl-qt5-7.5.0
++Architecture: any
++Section: libs
++Depends: ${shlibs:Depends}, ${misc:Depends}, libmgl-data
++Replaces: libmgl-qt5, libmgl-qt7.1.0, libmgl-qt7.2.0, libmgl-qt7.4.0
++Conflicts: libmgl-qt5, libmgl-qt7.1.0, libmgl-qt7.2.0, libmgl-qt7.4.0
++Description: library for scientific graphs (Qt interface for windows)
++ A free cross-platform library of fast C++ routines for plotting data in up
++ to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++ files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++ MathGL can also be used in the console. There are interfaces to a set of
++ languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++ .
++ This package contains the Qt interface shared object files for window
++ opening.
++
++Package: libmgl-fltk7.5.0
++Architecture: any
++Section: libs
++Depends: ${shlibs:Depends}, ${misc:Depends}, libmgl-data
++Replaces: libmgl-fltk5, libmgl-fltk7.1.0, libmgl-fltk7.2.0, libmgl-fltk7.4.0
++Conflicts: libmgl-fltk5, libmgl-fltk7.1.0, libmgl-fltk7.2.0, libmgl-fltk7.4.0
++Description: library for scientific graphs (fltk interface for windows)
++ A free cross-platform library of fast C++ routines for plotting data in up
++ to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++ files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++ MathGL can also be used in the console. There are interfaces to a set of
++ languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++ .
++ This package contains the fltk interface shared object files for window
++ opening.
++
++Package: libmgl-wx7.5.0
++Architecture: any
++Section: libs
++Depends: ${shlibs:Depends}, ${misc:Depends}, libmgl-data
++Replaces: libmgl-wx5, libmgl-wx7.1.0, libmgl-wx7.2.0, libmgl-wx7.4.0
++Conflicts: libmgl-wx5, libmgl-wx7.1.0, libmgl-wx7.2.0, libmgl-wx7.4.0
++Description: library for scientific graphs (wx interface for windows)
++ A free cross-platform library of fast C++ routines for plotting data in up
++ to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++ files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++ MathGL can also be used in the console. There are interfaces to a set of
++ languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++ .
++ This package contains the wx interface shared object files for window
++ opening.
++
++# Package: mgl-lua
++# Architecture: any
++# Section: libs
++# Depends: ${shlibs:Depends}, ${misc:Depends}, libmgl-data
++# Description: library for scientific graphs (Lua interface)
++# A free cross-platform library of fast C++ routines for plotting data in up
++# to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++# files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++# MathGL can also be used in the console. There are interfaces to a set of
++# languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++# .
++# This package contains the Lua interface shared object files.
++
++Package: libmgl-data
++Architecture: all
++Section: misc
++Depends: ${misc:Depends}
++Description: library for scientific graphs (data files)
++ A free cross-platform library of fast C++ routines for plotting data in up
++ to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++ files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++ MathGL can also be used in the console. There are interfaces to a set of
++ languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++ .
++ This package contains the MathGL data files.
++
++Package: libmgl-dev
++Architecture: any
++Section: libdevel
++Depends: libmgl7.5.0 (= ${binary:Version}), libmgl-wnd7.5.0 (= ${binary:Version}),
++ libmgl-wx7.5.0 (= ${binary:Version}), libmgl-fltk7.5.0 (= ${binary:Version}),
++ libmgl-qt5-7.5.0 (= ${binary:Version}), libmgl-glut7.5.0 (= ${binary:Version}),
++ libmgl-mpi7.5.0 (= ${binary:Version}), ${misc:Depends}, libgsl-dev,
++ libgl1-mesa-dev | libgl-dev, libpng-dev
++Description: library for scientific graphs (development files)
++ A free cross-platform library of fast C++ routines for plotting data in up
++ to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++ files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++ MathGL can also be used in the console. There are interfaces to a set of
++ languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++ .
++ This package contains the development files.
++
++Package: python-mathgl
++Architecture: any
++Section: python
++Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, python-numpy
++Description: library for scientific graphs (Python module)
++ A free cross-platform library of fast C++ routines for plotting data in up
++ to 3 dimensions. It can export plots to bitmaps and vector EPS, SVG, IDTF
++ files. There are simple window interfaces based on GLUT, FLTK and/or Qt.
++ MathGL can also be used in the console. There are interfaces to a set of
++ languages, such as, C, Fortran, Pascal, Forth, Python, Octave.
++ .
++ This package provides the Python module for mathgl.
--- /dev/null
--- /dev/null
++<<<<<<< HEAD
++--- a/CMakeLists.txt
+++++ b/CMakeLists.txt
++@@ -118,9 +118,9 @@
++=======
++Index: mathgl-2.4/CMakeLists.txt
++===================================================================
++--- mathgl-2.4.orig/CMakeLists.txt
+++++ mathgl-2.4/CMakeLists.txt
++@@ -145,7 +145,7 @@ if(WIN32)
++ endif(WIN32)
++
++ option(enable-double "Enable double precision in MathGL library" ON)
++-option(enable-mpi "Enable mpi")
+++option(enable-mpi "Enable mpi" ON)
++ option(enable-opengl "Enable OpenGL support" ON)
++ option(enable-all-docs "Enable all documentation building")
++ #option(enable-doc "Enable documentation building")
++@@ -153,9 +153,9 @@ option(enable-all "Enable all core featu
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ option(enable-all-widgets "Enable all Widgets")
++ option(enable-all-swig "Enable all SWIG based interfaces")
++ option(enable-rvalue "Enable move constructor support (need C++11)" OFF)
++-option(enable-pthread "Enable POSIX threads support" OFF)
+++option(enable-pthread "Enable POSIX threads support" ON)
++ option(enable-pthr-widget "Enable POSIX threads for widgets" ON)
++-option(enable-openmp "Enable OpenMP support" ON)
+++option(enable-openmp "Enable OpenMP support" OFF)
++
++ if(enable-pthread AND enable-openmp)
++ message(SEND_ERROR "You can't enable POSIX threads and OpenMP at the same time!")
++<<<<<<< HEAD
++@@ -141,19 +141,19 @@
++=======
++@@ -163,7 +163,7 @@ endif(enable-pthread AND enable-openmp)
++
++ option(enable-lgpl "Enable only LGPL part of MathGL")
++ option(enable-mgl2 "Use names 'libmgl2-*' instead of 'libmgl-*'")
++-option(enable-ltdl "Enable loading modules support")
+++option(enable-ltdl "Enable loading modules support" ON)
++ option(enable-doc-site "Enable HTML documentation for website")
++ #CMAKE_DEPENDENT_OPTION(enable-doc-site "Enable HTML documentation for website" OFF "NOT enable-all-docs" ON)
++ CMAKE_DEPENDENT_OPTION(enable-doc-html "Enable HTML documentation" OFF "NOT enable-all-docs" ON)
++@@ -177,19 +177,19 @@ CMAKE_DEPENDENT_OPTION(enable-mgltex "En
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++ CMAKE_DEPENDENT_OPTION(enable-zlib "Enable zlib support" ON "NOT enable-all" ON)
++ CMAKE_DEPENDENT_OPTION(enable-png "Enable png support" ON "NOT enable-all" ON)
++-CMAKE_DEPENDENT_OPTION(enable-jpeg "Enable jpeg support" OFF "NOT enable-all" ON)
++-MGL_DEPENDENT_OPTION(enable-gsl "Enable gsl support" OFF "NOT enable-lgpl" ON "NOT enable-all" ON)
++-MGL_DEPENDENT_OPTION(enable-hdf4 "Enable hdf4 support" OFF "NOT enable-lgpl" ON "NOT enable-all" ON)
++-MGL_DEPENDENT_OPTION(enable-hdf5 "Enable hdf5 support" OFF "NOT enable-lgpl" ON "NOT enable-all" ON)
++-CMAKE_DEPENDENT_OPTION(enable-pdf "Enable pdf support" OFF "NOT enable-all" ON)
++-CMAKE_DEPENDENT_OPTION(enable-gif "Enable gif support" OFF "NOT enable-all" ON)
++-CMAKE_DEPENDENT_OPTION(enable-glut "Enable glut support" OFF "NOT enable-all-widgets" ON)
++-CMAKE_DEPENDENT_OPTION(enable-fltk "Enable fltk widget" OFF "NOT enable-all-widgets" ON)
++-CMAKE_DEPENDENT_OPTION(enable-wx "Enable wxWidget widget" OFF "NOT enable-all-widgets" ON)
+++CMAKE_DEPENDENT_OPTION(enable-jpeg "Enable jpeg support" ON "NOT enable-all" ON)
+++MGL_DEPENDENT_OPTION(enable-gsl "Enable gsl support" ON "NOT enable-lgpl" ON "NOT enable-all" ON)
+++MGL_DEPENDENT_OPTION(enable-hdf4 "Enable hdf4 support" ON "NOT enable-lgpl" ON "NOT enable-all" ON)
+++MGL_DEPENDENT_OPTION(enable-hdf5 "Enable hdf5 support" ON "NOT enable-lgpl" ON "NOT enable-all" ON)
+++CMAKE_DEPENDENT_OPTION(enable-pdf "Enable pdf support" ON "NOT enable-all" ON)
+++CMAKE_DEPENDENT_OPTION(enable-gif "Enable gif support" ON "NOT enable-all" ON)
+++CMAKE_DEPENDENT_OPTION(enable-glut "Enable glut support" ON "NOT enable-all-widgets" ON)
+++CMAKE_DEPENDENT_OPTION(enable-fltk "Enable fltk widget" ON "NOT enable-all-widgets" ON)
+++CMAKE_DEPENDENT_OPTION(enable-wx "Enable wxWidget widget" ON "NOT enable-all-widgets" ON)
++ CMAKE_DEPENDENT_OPTION(enable-qt4 "Enable Qt4 widget" OFF "NOT enable-all-widgets" ON)
++ CMAKE_DEPENDENT_OPTION(enable-qt4asqt "Set Qt4 as default libmgl-qt" OFF "enable-qt4" OFF)
++-CMAKE_DEPENDENT_OPTION(enable-qt5 "Enable Qt5 widget" OFF "NOT enable-all-widgets" ON)
++-CMAKE_DEPENDENT_OPTION(enable-qt5asqt "Set Qt5 as default libmgl-qt" OFF "enable-qt5" OFF)
+++CMAKE_DEPENDENT_OPTION(enable-qt5 "Enable Qt5 widget" ON "NOT enable-all-widgets" ON)
+++CMAKE_DEPENDENT_OPTION(enable-qt5asqt "Set Qt5 as default libmgl-qt" ON "enable-qt5" OFF)
++
++ # msvc fwprintf print char* for the specifier of "%s" format
++ if(MSVC AND MSVC_VERSION GREATER 1899)
++<<<<<<< HEAD
++@@ -178,9 +178,9 @@
++ endif(enable-qt4 OR enable-qt5)
++
++ CMAKE_DEPENDENT_OPTION(enable-json-sample "Enable JSON sample" ON "QT_ENABLED" OFF)
++-MGL_DEPENDENT_OPTION(enable-python "Enable python interface" OFF "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
++=======
++@@ -226,11 +226,11 @@ if(enable-qt4 OR enable-qt5)
++ # endif(NOT enable-opengl)
++ endif(enable-qt4 OR enable-qt5)
++
++-CMAKE_DEPENDENT_OPTION(enable-json-sample "Enable JSON sample (WebKit variant is the default)." ON "QT_ENABLED" OFF)
++-CMAKE_DEPENDENT_OPTION(enable-json-sample-we "Enable JSON sample (WebEngine variant)." OFF "enable-json-sample" OFF)
++-MGL_DEPENDENT_OPTION(enable-python "Enable python interface" OFF "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
+++CMAKE_DEPENDENT_OPTION(enable-json-sample "Enable JSON sample (WebKit variant is the default)." ON "QT_ENABLED" ON)
+++CMAKE_DEPENDENT_OPTION(enable-json-sample-we "Enable JSON sample (WebEngine variant)." ON "enable-json-sample" ON)
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
+++MGL_DEPENDENT_OPTION(enable-python "Enable python interface" ON "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
++ MGL_DEPENDENT_OPTION(enable-lua "Enable Lua (v.5.1) interface" OFF "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
++-MGL_DEPENDENT_OPTION(enable-octave "Enable octave interface" OFF "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
+++MGL_DEPENDENT_OPTION(enable-octave "Enable octave interface" ON "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
++ MGL_DEPENDENT_OPTION(enable-octave-install "Octave interface will install for all users" ON "NOT enable-lgpl" ON "NOT enable-all-swig" ON)
++
++<<<<<<< HEAD
++ include_directories( ${MathGL_SOURCE_DIR}/include ${MathGL_BINARY_DIR}/include)
++@@ -411,7 +411,7 @@
++ endif(NOT HDF5_FOUND)
++ endif(NOT HDF5_FOUND)
++ set(MGL_DEP_LIBS ${HDF5_LIBRARIES} ${HDF5_C_SHARED_LIBRARY} ${MGL_DEP_LIBS})
++- include_directories(${HDF5_INCLUDE_DIR})
+++ include_directories(${HDF5_INCLUDE_DIRS})
++ else(enable-hdf5)
++ set(MGL_HAVE_HDF5 0)
++ endif(enable-hdf5)
++=======
++ include_directories( ${MathGL2_SOURCE_DIR}/include ${MathGL2_BINARY_DIR}/include)
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
--- /dev/null
--- /dev/null
++<<<<<<< HEAD
++=======
++file(COPY ${CMAKE_SOURCE_DIR}/examples/iris.dat DESTINATION ${CMAKE_BINARY_DIR}/examples)
++file(COPY ${CMAKE_SOURCE_DIR}/examples/Equirectangular-projection.jpg DESTINATION ${CMAKE_BINARY_DIR}/examples)
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++add_executable(mgl_example wnd_samples.cpp full_test.cpp samples.cpp)
++target_link_libraries(mgl_example mgl-static ${getopt_lib-static})
++
++if(MGL_HAVE_FLTK)
++ include_directories(${FLTK_INCLUDE_DIR})
++ add_executable(mgl_fltk_example wnd_samples.cpp fltk_example.cpp)
++ target_link_libraries(mgl_fltk_example mgl-fltk)
++endif(MGL_HAVE_FLTK)
++
++if(MGL_HAVE_GLUT)
++ add_executable(mgl_glut_example wnd_samples.cpp glut_example.cpp)
++ target_link_libraries(mgl_glut_example mgl-glut)
++endif(MGL_HAVE_GLUT)
++
++if(MGL_HAVE_WX)
++ include(${wxWidgets_USE_FILE})
++ add_executable(mgl_wx_example wnd_samples.cpp wx_example.cpp)
++ target_link_libraries(mgl_wx_example mgl-wx)
++endif(MGL_HAVE_WX)
++
++if(QT_ENABLED)
++ add_executable(mgl_qt_example wnd_samples.cpp qt_example.cpp)
++ if(enable-qt5)
++ include(../scripts/qt5.cmake)
++ target_link_libraries(mgl_qt_example mgl-qt5)
++ else(enable-qt5)
++ include(../scripts/qt4.cmake)
++ target_link_libraries(mgl_qt_example mgl-qt4)
++ endif(enable-qt5)
++
++ if(MGL_HAVE_OPENGL)
++ add_executable(mgl_qgl_example wnd_samples.cpp qgl_example.cpp)
++ if(enable-qt5)
++ target_link_libraries(mgl_qgl_example mgl ${MGL_QT5_LIBS})
++ else(enable-qt5)
++ target_link_libraries(mgl_qgl_example mgl ${MGL_QT4_LIBS})
++ endif(enable-qt5)
++ endif(MGL_HAVE_OPENGL)
++endif(QT_ENABLED)
++
++if(MGL_HAVE_LTDL)
++ add_library(mgl_module MODULE mgl_module.cpp)
++ target_link_libraries(mgl_module mgl) # for compatibility with win32
++endif(MGL_HAVE_LTDL)
++
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * full_test.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU General Public License as published by *\r
++ * the Free Software Foundation; either version 2 of the License, or *\r
++ * (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU General Public License *\r
++ * along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include <time.h>\r
++#include <locale.h>\r
++#include <time.h>\r
++#include <getopt.h>\r
++<<<<<<< HEAD\r
++=======\r
++#include <unistd.h>\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++\r
++#include "mgl2/mgl.h"\r
++#include "mgl2/font.h"\r
++#include "mgl2/eval.h"\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_create_cpp_font(HMGL gr, const wchar_t *how);\r
++long MGL_EXPORT mgl_check_tex_table();\r
++//-----------------------------------------------------------------------------\r
++struct mglSample /// Structure for list of samples\r
++{\r
++ const char *name;\r
++ void (*func)(mglGraph*);\r
++ const char *mgl;\r
++};\r
++extern mglSample samp[];\r
++extern const char *mmgl_dat_prepare;\r
++//-----------------------------------------------------------------------------\r
++int MGL_LOCAL_PURE mgl_cmd_smp(const void *a, const void *b)\r
++{\r
++ const mglSample *aa = (const mglSample *)a;\r
++ const mglSample *bb = (const mglSample *)b;\r
++ return strcmp(aa->name, bb->name);\r
++}\r
++//-----------------------------------------------------------------------------\r
++int type = 0;\r
++int dotest = 0;\r
++int width = 800;\r
++int height = 600;\r
++int big = 0;\r
++int srnd = 0;\r
++int use_mgl = 0;\r
++int verbose = 0;\r
++int quality = MGL_DRAW_NORM;\r
++//-----------------------------------------------------------------------------\r
++void mgls_prepare1d(mglData *y, mglData *y1=0, mglData *y2=0, mglData *x1=0, mglData *x2=0);\r
++void mgls_prepare2d(mglData *a, mglData *b=0, mglData *v=0);\r
++void mgls_prepare3d(mglData *a, mglData *b=0);\r
++void mgls_prepare2v(mglData *a, mglData *b);\r
++void mgls_prepare3v(mglData *ex, mglData *ey, mglData *ez);\r
++//-----------------------------------------------------------------------------\r
++void save(mglGraph *gr,const char *name,const char *suf);\r
++void test(mglGraph *gr)\r
++{\r
++ mglParse par;\r
++ par.Execute(gr,"text 0 -0.2 'abcde'\ntext 0 0 'abcde'[2]\n"\r
++ "text 0 0.2 'abcde'+2\ntext 0 0.4 'abcde',2\ntext 0 0.6 'abcde',2,'k'"\r
++ "text 0 0.8 'abcde',2,'k'+1\ntext 0 1 'abcde',2,'k'[5]\ntext 0 1 'abcde''k'[5]");\r
++ return;\r
++\r
++ gr->SubPlot(2,2,0); gr->Axis();\r
++ gr->SubPlot(2,2,1); gr->Rotate(40,60); gr->Axis();\r
++ gr->SetRotatedText(false); gr->SubPlot(2,2,2); gr->Axis();\r
++ gr->SubPlot(2,2,3); gr->Rotate(40,60); gr->Axis(); return;\r
++ mglData a; a.SetList(5,0.,1.,0.,1.,-1.,2.);\r
++ gr->Plot(a);\r
++ return;\r
++ par.Execute(gr,"call 'test' -1\n func 'test' 1\nline $1 0 1 1 'b'\nreturn\n");\r
++// par.Execute(gr,"load '/home/balakin/mathgl-code/mathgl-2x/build/examples/libmgl_module.so':baxis\n");\r
++// par.Execute(gr,"subplot 1 1 0:#rotate 40 60\nperspective 1.22:box:axis\n");\r
++ return;\r
++}\r
++//-----------------------------------------------------------------------------\r
++static struct option longopts[] =\r
++{\r
++ { "big", no_argument, &big, 1 },\r
++ { "web", no_argument, &big, 2 },\r
++ { "mini", no_argument, &big, 3 },\r
++ { "help", no_argument, NULL, '?' },\r
++ { "height", required_argument, NULL, 'h' },\r
++ { "kind", required_argument, NULL, 'k' },\r
++ { "list", no_argument, NULL, 'l' },\r
++ { "mgl", no_argument, &use_mgl, 1 },\r
++ { "srnd", no_argument, &srnd, 1 },\r
++\r
++ { "png", no_argument, &type, 0 },\r
++ { "eps", no_argument, &type, 1 },\r
++ { "svg", no_argument, &type, 2 },\r
++ { "solid", no_argument, &type, 3 },\r
++ { "jpeg", no_argument, &type, 4 },\r
++ { "prc", no_argument, &type, 5 },\r
++ { "gif", no_argument, &type, 6 },\r
++ { "none", no_argument, &type, 7 },\r
++ { "bps", no_argument, &type, 8 },\r
++ { "pdf", no_argument, &type, 9 },\r
++ { "obj_old",no_argument, &type, 10 },\r
++ { "obj", no_argument, &type, 11 },\r
++ { "off", no_argument, &type, 12 },\r
++ { "stl", no_argument, &type, 13 },\r
++ { "tex", no_argument, &type, 14 },\r
++ { "json", no_argument, &type, 15 },\r
++ { "jsonz", no_argument, &type, 16 },\r
++ { "docs", no_argument, &type, 17 },\r
++\r
++ { "test", no_argument, &dotest, 1 },\r
++ { "font", no_argument, &dotest, 2 },\r
++ { "time", no_argument, &dotest, 3 },\r
++ { "fexport",no_argument, &dotest, 4 },\r
++ { "textbl", no_argument, &dotest, 5 },\r
++\r
++ { "thread", required_argument, NULL, 't' },\r
++ { "verbose",no_argument, &verbose, 1 },\r
++ { "width", required_argument, NULL, 'w' },\r
++ { "quality",required_argument, NULL, 'q' },\r
++ { NULL, 0, NULL, 0 }\r
++};\r
++//-----------------------------------------------------------------------------\r
++void usage()\r
++{\r
++ puts (\r
++// "--png - output png\n"\r
++ "--width=num - png picture width\n"\r
++ "--height=num - png picture height\n"\r
++ "--mini - png picture is 200x150\n"\r
++ "--big - png picture is 1920x1440\n"\r
++ "--web - png picture is 640x480\n"\r
++ "--prc - output prc\n"\r
++ "--pdf - output pdf\n"\r
++ "--eps - output EPS\n"\r
++ "--tex - output LaTeX\n"\r
++ "--jpeg - output JPEG\n"\r
++ "--json - output JSON\n"\r
++ "--jsonz - output JSONz\n"\r
++ "--solid - output solid PNG\n"\r
++ "--svg - output SVG\n"\r
++ "--obj - output obj/mtl\n"\r
++ "--obj_old - output obj/mtl in old way\n"\r
++ "--off - output off\n"\r
++ "--stl - output stl\n"\r
++ "--docs - output in png, prc/pdf and json\n"\r
++ "--none - none output\n"\r
++ "--srnd - use the same random numbers in any run\n"\r
++ "--list - print list of sample names\n"\r
++ "--kind=name - produce only this sample\n"\r
++ "--thread=num - number of threads used\n"\r
++ "--mgl - use MGL scripts for samples\n"\r
++ "--test - run in test mode\n"\r
++ "--time - measure execution time for all samples\n"\r
++ "--font - write current font as C++ file\n"\r
++ "--quality=val - use specified quality for plot(s)\n"\r
++ "--fexport - test most of output formats\n"\r
++ );\r
++}\r
++//-----------------------------------------------------------------------------\r
++void save(mglGraph *gr,const char *name,const char *suf="")\r
++{\r
++ // return;\r
++ char buf[128];\r
++ switch(type)\r
++ {\r
++ case 1: // EPS\r
++ snprintf(buf,128,"%s%s.eps",name,suf);\r
++ gr->WriteEPS(buf);\r
++ break;\r
++ case 2: // SVG\r
++ snprintf(buf,128,"%s%s.svg",name,suf);\r
++ gr->WriteSVG(buf); break;\r
++ case 3: // PNG\r
++ snprintf(buf,128,"%s%s.png",name,suf);\r
++ gr->WritePNG(buf,0,true); break;\r
++ case 4: // JPEG\r
++ snprintf(buf,128,"%s%s.jpg",name,suf);\r
++ gr->WriteJPEG(buf); break;\r
++ case 5: // PRC\r
++ snprintf(buf,128,"%s%s.prc",name,suf);\r
++ gr->WritePRC(buf,"",false); break;\r
++ case 6: // GIF\r
++ snprintf(buf,128,"%s%s.gif",name,suf);\r
++ gr->WriteGIF(buf); break;\r
++ case 7: gr->Finish(); // none\r
++ break;\r
++ case 8: // EPS to PNG\r
++ snprintf(buf,128,"%s%s.png",name,suf);\r
++ gr->WritePNG(buf,0,false);\r
++ break;\r
++ case 9: // PDF\r
++ snprintf(buf,128,"%s%s.prc",name,suf);\r
++ gr->WritePRC(buf); remove(buf); break;\r
++ case 10: // old OBJ\r
++ snprintf(buf,128,"%s%s.obj",name,suf);\r
++ gr->WriteOBJold(buf); break;\r
++ case 11: // OBJ\r
++ snprintf(buf,128,"%s%s.obj",name,suf);\r
++ gr->WriteOBJ(buf); break;\r
++ case 12: // OFF\r
++ snprintf(buf,128,"%s%s.off",name,suf);\r
++ gr->WriteOFF(buf); break;\r
++ case 13: // STL\r
++ snprintf(buf,128,"%s%s.stl",name,suf);\r
++ gr->WriteSTL(buf); break;\r
++ case 14: // TeX\r
++ snprintf(buf,128,"%s%s.tex",name,suf);\r
++ gr->WriteTEX(buf); break;\r
++ case 15: // JSON\r
++ snprintf(buf,128,"%s%s.json",name,suf);\r
++ gr->WriteJSON(buf); break;\r
++ case 16: // JSON\r
++ snprintf(buf,128,"%s%s.jsonz",name,suf);\r
++ gr->WriteJSON(buf,"",true); break;\r
++ case 17: // PNG + JSON + PDF\r
++ snprintf(buf,128,"%s%s.png",name,suf);\r
++ gr->WritePNG(buf,0,true);\r
++ snprintf(buf,128,"%s%s.json",name,suf);\r
++ gr->WriteJSON(buf);\r
++ gr->SetSize(height,height,false);\r
++ snprintf(buf,128,"%s%s.prc",name,suf);\r
++ gr->WritePRC(buf); remove(buf); break;\r
++ default:// PNG (no alpha)\r
++#if MGL_HAVE_PNG\r
++ snprintf(buf,128,"%s%s.png",name,suf);\r
++ gr->WritePNG(buf,0,false); break;\r
++#else\r
++ snprintf(buf,128,"%s%s.bmp",name,suf);\r
++ gr->WriteBMP(buf); break;\r
++#endif\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void smgl_fexport(mglGraph *gr) // test file export\r
++{\r
++ gr->SubPlot(3,2,0);\r
++ double d,x1,x2,x0,y=0.95;\r
++ d=0.3, x0=0.2, x1=0.5, x2=0.6;\r
++ gr->Line(mglPoint(x0,1-0*d),mglPoint(x1,1-0*d),"k-"); gr->Puts(mglPoint(x2,y-0*d),"Solid '-'",":rL");\r
++ gr->Line(mglPoint(x0,1-1*d),mglPoint(x1,1-1*d),"k|"); gr->Puts(mglPoint(x2,y-1*d),"Long Dash '|'",":rL");\r
++ gr->Line(mglPoint(x0,1-2*d),mglPoint(x1,1-2*d),"k;"); gr->Puts(mglPoint(x2,y-2*d),"Dash ';'",":rL");\r
++ gr->Line(mglPoint(x0,1-3*d),mglPoint(x1,1-3*d),"k="); gr->Puts(mglPoint(x2,y-3*d),"Small dash '='",":rL");\r
++ gr->Line(mglPoint(x0,1-4*d),mglPoint(x1,1-4*d),"kj"); gr->Puts(mglPoint(x2,y-4*d),"Dash-dot 'j'",":rL");\r
++ gr->Line(mglPoint(x0,1-5*d),mglPoint(x1,1-5*d),"ki"); gr->Puts(mglPoint(x2,y-5*d),"Small dash-dot 'i'",":rL");\r
++ gr->Line(mglPoint(x0,1-6*d),mglPoint(x1,1-6*d),"k:"); gr->Puts(mglPoint(x2,y-6*d),"Dots ':'",":rL");\r
++ gr->Line(mglPoint(x0,1-7*d),mglPoint(x1,1-7*d),"k "); gr->Puts(mglPoint(x2,y-7*d),"None ' '",":rL");\r
++\r
++ d=0.25; x1=-1; x0=-0.8; y = -0.05;\r
++ gr->Mark(mglPoint(x1,5*d),"k."); gr->Puts(mglPoint(x0,y+5*d),"'.'",":rL");\r
++ gr->Mark(mglPoint(x1,4*d),"k+"); gr->Puts(mglPoint(x0,y+4*d),"'+'",":rL");\r
++ gr->Mark(mglPoint(x1,3*d),"kx"); gr->Puts(mglPoint(x0,y+3*d),"'x'",":rL");\r
++ gr->Mark(mglPoint(x1,2*d),"k*"); gr->Puts(mglPoint(x0,y+2*d),"'*'",":rL");\r
++ gr->Mark(mglPoint(x1,d),"ks"); gr->Puts(mglPoint(x0,y+d),"'s'",":rL");\r
++ gr->Mark(mglPoint(x1,0),"kd"); gr->Puts(mglPoint(x0,y),"'d'",":rL");\r
++ gr->Mark(mglPoint(x1,-d,0),"ko"); gr->Puts(mglPoint(x0,y-d),"'o'",":rL");\r
++ gr->Mark(mglPoint(x1,-2*d,0),"k^"); gr->Puts(mglPoint(x0,y-2*d),"'\\^'",":rL");\r
++ gr->Mark(mglPoint(x1,-3*d,0),"kv"); gr->Puts(mglPoint(x0,y-3*d),"'v'",":rL");\r
++ gr->Mark(mglPoint(x1,-4*d,0),"k<"); gr->Puts(mglPoint(x0,y-4*d),"'<'",":rL");\r
++ gr->Mark(mglPoint(x1,-5*d,0),"k>"); gr->Puts(mglPoint(x0,y-5*d),"'>'",":rL");\r
++\r
++ d=0.25; x1=-0.5; x0=-0.3; y = -0.05;\r
++ gr->Mark(mglPoint(x1,5*d),"k#."); gr->Puts(mglPoint(x0,y+5*d),"'\\#.'",":rL");\r
++ gr->Mark(mglPoint(x1,4*d),"k#+"); gr->Puts(mglPoint(x0,y+4*d),"'\\#+'",":rL");\r
++ gr->Mark(mglPoint(x1,3*d),"k#x"); gr->Puts(mglPoint(x0,y+3*d),"'\\#x'",":rL");\r
++ gr->Mark(mglPoint(x1,2*d),"k#*"); gr->Puts(mglPoint(x0,y+2*d),"'\\#*'",":rL");\r
++ gr->Mark(mglPoint(x1,d),"k#s"); gr->Puts(mglPoint(x0,y+d),"'\\#s'",":rL");\r
++ gr->Mark(mglPoint(x1,0),"k#d"); gr->Puts(mglPoint(x0,y),"'\\#d'",":rL");\r
++ gr->Mark(mglPoint(x1,-d,0),"k#o"); gr->Puts(mglPoint(x0,y-d),"'\\#o'",":rL");\r
++ gr->Mark(mglPoint(x1,-2*d,0),"k#^"); gr->Puts(mglPoint(x0,y-2*d),"'\\#\\^'",":rL");\r
++ gr->Mark(mglPoint(x1,-3*d,0),"k#v"); gr->Puts(mglPoint(x0,y-3*d),"'\\#v'",":rL");\r
++ gr->Mark(mglPoint(x1,-4*d,0),"k#<"); gr->Puts(mglPoint(x0,y-4*d),"'\\#<'",":rL");\r
++ gr->Mark(mglPoint(x1,-5*d,0),"k#>"); gr->Puts(mglPoint(x0,y-5*d),"'\\#>'",":rL");\r
++\r
++ gr->SubPlot(3,2,1);\r
++ double a=0.1,b=0.4,c=0.5;\r
++ gr->Line(mglPoint(a,1),mglPoint(b,1),"k-A"); gr->Puts(mglPoint(c,1),"Style 'A' or 'A\\_'",":rL");\r
++ gr->Line(mglPoint(a,0.8),mglPoint(b,0.8),"k-V"); gr->Puts(mglPoint(c,0.8),"Style 'V' or 'V\\_'",":rL");\r
++ gr->Line(mglPoint(a,0.6),mglPoint(b,0.6),"k-K"); gr->Puts(mglPoint(c,0.6),"Style 'K' or 'K\\_'",":rL");\r
++ gr->Line(mglPoint(a,0.4),mglPoint(b,0.4),"k-I"); gr->Puts(mglPoint(c,0.4),"Style 'I' or 'I\\_'",":rL");\r
++ gr->Line(mglPoint(a,0.2),mglPoint(b,0.2),"k-D"); gr->Puts(mglPoint(c,0.2),"Style 'D' or 'D\\_'",":rL");\r
++ gr->Line(mglPoint(a,0),mglPoint(b,0),"k-S"); gr->Puts(mglPoint(c,0),"Style 'S' or 'S\\_'",":rL");\r
++ gr->Line(mglPoint(a,-0.2),mglPoint(b,-0.2),"k-O"); gr->Puts(mglPoint(c,-0.2),"Style 'O' or 'O\\_'",":rL");\r
++ gr->Line(mglPoint(a,-0.4),mglPoint(b,-0.4),"k-T"); gr->Puts(mglPoint(c,-0.4),"Style 'T' or 'T\\_'",":rL");\r
++ gr->Line(mglPoint(a,-0.6),mglPoint(b,-0.6),"k-_"); gr->Puts(mglPoint(c,-0.6),"Style '\\_' or none",":rL");\r
++ gr->Line(mglPoint(a,-0.8),mglPoint(b,-0.8),"k-AS"); gr->Puts(mglPoint(c,-0.8),"Style 'AS'",":rL");\r
++ gr->Line(mglPoint(a,-1),mglPoint(b,-1),"k-_A"); gr->Puts(mglPoint(c,-1),"Style '\\_A'",":rL");\r
++\r
++ a=-1; b=-0.7; c=-0.6;\r
++ gr->Line(mglPoint(a,1),mglPoint(b,1),"kAA"); gr->Puts(mglPoint(c,1),"Style 'AA'",":rL");\r
++ gr->Line(mglPoint(a,0.8),mglPoint(b,0.8),"kVV"); gr->Puts(mglPoint(c,0.8),"Style 'VV'",":rL");\r
++ gr->Line(mglPoint(a,0.6),mglPoint(b,0.6),"kKK"); gr->Puts(mglPoint(c,0.6),"Style 'KK'",":rL");\r
++ gr->Line(mglPoint(a,0.4),mglPoint(b,0.4),"kII"); gr->Puts(mglPoint(c,0.4),"Style 'II'",":rL");\r
++ gr->Line(mglPoint(a,0.2),mglPoint(b,0.2),"kDD"); gr->Puts(mglPoint(c,0.2),"Style 'DD'",":rL");\r
++ gr->Line(mglPoint(a,0),mglPoint(b,0),"kSS"); gr->Puts(mglPoint(c,0),"Style 'SS'",":rL");\r
++ gr->Line(mglPoint(a,-0.2),mglPoint(b,-0.2),"kOO"); gr->Puts(mglPoint(c,-0.2),"Style 'OO'",":rL");\r
++ gr->Line(mglPoint(a,-0.4),mglPoint(b,-0.4),"kTT"); gr->Puts(mglPoint(c,-0.4),"Style 'TT'",":rL");\r
++ gr->Line(mglPoint(a,-0.6),mglPoint(b,-0.6),"k-__"); gr->Puts(mglPoint(c,-0.6),"Style '\\_\\_'",":rL");\r
++ gr->Line(mglPoint(a,-0.8),mglPoint(b,-0.8),"k-VA"); gr->Puts(mglPoint(c,-0.8),"Style 'VA'",":rL");\r
++ gr->Line(mglPoint(a,-1),mglPoint(b,-1),"k-AV"); gr->Puts(mglPoint(c,-1),"Style 'AV'",":rL");\r
++\r
++ gr->SubPlot(3,2,2);\r
++ //#LENUQ\r
++ gr->FaceZ(mglPoint(-1, -1), 0.4, 0.3, "L#"); gr->Puts(mglPoint(-0.8,-0.9), "L", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.6,-1), 0.4, 0.3, "E#"); gr->Puts(mglPoint(-0.4,-0.9), "E", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.2,-1), 0.4, 0.3, "N#"); gr->Puts(mglPoint(0, -0.9), "N", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.2, -1), 0.4, 0.3, "U#"); gr->Puts(mglPoint(0.4,-0.9), "U", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.6, -1), 0.4, 0.3, "Q#"); gr->Puts(mglPoint(0.8,-0.9), "Q", "w:C", -1.4);\r
++ //#lenuq\r
++ gr->FaceZ(mglPoint(-1, -0.7), 0.4, 0.3, "l#"); gr->Puts(mglPoint(-0.8,-0.6), "l", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.6,-0.7), 0.4, 0.3, "e#"); gr->Puts(mglPoint(-0.4,-0.6), "e", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.2,-0.7), 0.4, 0.3, "n#"); gr->Puts(mglPoint(0, -0.6), "n", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.2, -0.7), 0.4, 0.3, "u#"); gr->Puts(mglPoint(0.4,-0.6), "u", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.6, -0.7), 0.4, 0.3, "q#"); gr->Puts(mglPoint(0.8,-0.6), "q", "k:C", -1.4);\r
++ //#CMYkP\r
++ gr->FaceZ(mglPoint(-1, -0.4), 0.4, 0.3, "C#"); gr->Puts(mglPoint(-0.8,-0.3), "C", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.6,-0.4), 0.4, 0.3, "M#"); gr->Puts(mglPoint(-0.4,-0.3), "M", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.2,-0.4), 0.4, 0.3, "Y#"); gr->Puts(mglPoint(0, -0.3), "Y", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.2, -0.4), 0.4, 0.3, "k#"); gr->Puts(mglPoint(0.4,-0.3), "k", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.6, -0.4), 0.4, 0.3, "P#"); gr->Puts(mglPoint(0.8,-0.3), "P", "w:C", -1.4);\r
++ //#cmywp\r
++ gr->FaceZ(mglPoint(-1, -0.1), 0.4, 0.3, "c#"); gr->Puts(mglPoint(-0.8, 0), "c", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.6,-0.1), 0.4, 0.3, "m#"); gr->Puts(mglPoint(-0.4, 0), "m", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.2,-0.1), 0.4, 0.3, "y#"); gr->Puts(mglPoint(0, 0), "y", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.2, -0.1), 0.4, 0.3, "w#"); gr->Puts(mglPoint(0.4, 0), "w", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.6, -0.1), 0.4, 0.3, "p#"); gr->Puts(mglPoint(0.8, 0), "p", "k:C", -1.4);\r
++ //#BGRHW\r
++ gr->FaceZ(mglPoint(-1, 0.2), 0.4, 0.3, "B#"); gr->Puts(mglPoint(-0.8, 0.3), "B", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.6,0.2), 0.4, 0.3, "G#"); gr->Puts(mglPoint(-0.4, 0.3), "G", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.2,0.2), 0.4, 0.3, "R#"); gr->Puts(mglPoint(0, 0.3), "R", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.2, 0.2), 0.4, 0.3, "H#"); gr->Puts(mglPoint(0.4, 0.3), "H", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.6, 0.2), 0.4, 0.3, "W#"); gr->Puts(mglPoint(0.8, 0.3), "W", "w:C", -1.4);\r
++ //#bgrhw\r
++ gr->FaceZ(mglPoint(-1, 0.5), 0.4, 0.3, "b#"); gr->Puts(mglPoint(-0.8, 0.6), "b", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.6,0.5), 0.4, 0.3, "g#"); gr->Puts(mglPoint(-0.4, 0.6), "g", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.2,0.5), 0.4, 0.3, "r#"); gr->Puts(mglPoint(0, 0.6), "r", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.2, 0.5), 0.4, 0.3, "h#"); gr->Puts(mglPoint(0.4, 0.6), "h", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.6, 0.5), 0.4, 0.3, "w#"); gr->Puts(mglPoint(0.8, 0.6), "w", "k:C", -1.4);\r
++ //#brighted\r
++ gr->FaceZ(mglPoint(-1, 0.8), 0.4, 0.3, "{r1}#"); gr->Puts(mglPoint(-0.8, 0.9), "\\{r1\\}", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.6,0.8), 0.4, 0.3, "{r3}#"); gr->Puts(mglPoint(-0.4, 0.9), "\\{r3\\}", "w:C", -1.4);\r
++ gr->FaceZ(mglPoint(-0.2,0.8), 0.4, 0.3, "{r5}#"); gr->Puts(mglPoint(0, 0.9), "\\{r5\\}", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.2, 0.8), 0.4, 0.3, "{r7}#"); gr->Puts(mglPoint(0.4, 0.9), "\\{r7\\}", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(0.6, 0.8), 0.4, 0.3, "{r9}#"); gr->Puts(mglPoint(0.8, 0.9), "\\{r9\\}", "k:C", -1.4);\r
++ // HEX\r
++ gr->FaceZ(mglPoint(-1, -1.3), 1, 0.3, "{xff9966}#"); gr->Puts(mglPoint(-0.5,-1.2), "\\{xff9966\\}", "k:C", -1.4);\r
++ gr->FaceZ(mglPoint(0, -1.3), 1, 0.3, "{x83CAFF}#"); gr->Puts(mglPoint( 0.5,-1.2), "\\{x83CAFF\\}", "k:C", -1.4);\r
++\r
++ gr->SubPlot(3,2,3);\r
++ char stl[3]="r1", txt[4]="'1'";\r
++ for(int i=0;i<10;i++)\r
++ {\r
++ txt[1]=stl[1]='0'+i;\r
++ gr->Line(mglPoint(-1,0.2*i-1),mglPoint(1,0.2*i-1),stl);\r
++ gr->Puts(mglPoint(1.05,0.2*i-1),txt,":L");\r
++ }\r
++\r
++ gr->SubPlot(3,2,4); gr->Title("TriPlot sample"); gr->Rotate(50,60);\r
++ double t[] = {0,1,2, 0,1,3, 0,2,3, 1,2,3};\r
++ double xt[] = {-1,1,0,0}, yt[] = {-1,-1,1,0}, zt[] = {-1,-1,-1,1};\r
++ mglData tt(4,3,t), uu(4,xt), vv(4,yt), ww(4,zt);\r
++ gr->TriPlot(tt,uu,vv,ww,"b");\r
++ gr->TriPlot(tt,uu,vv,ww,"k#");\r
++\r
++ gr->SubPlot(3,2,5);\r
++ mglData r(4); r.Fill(1,4);\r
++ gr->SetRanges(1,4,1,4); gr->Axis();\r
++ gr->Mark(r,r,"s");\r
++ gr->Plot(r,"b");\r
++\r
++ gr->WriteJPEG("fexport.jpg");\r
++// gr->WritePNG("fexport.png");\r
++ gr->WriteBMP("fexport.bmp");\r
++ gr->WriteTGA("fexport.tga");\r
++ gr->WriteEPS("fexport.eps");\r
++ gr->WriteSVG("fexport.svg");\r
++ gr->WriteGIF("fexport.gif");\r
++\r
++ gr->WriteXYZ("fexport.xyz");\r
++ gr->WriteSTL("fexport.stl");\r
++ gr->WriteOFF("fexport.off");\r
++ gr->WriteTEX("fexport.tex");\r
++ gr->WriteOBJ("fexport.obj");\r
++ gr->WritePRC("fexport.prc");\r
++ gr->WriteJSON("fexport.json");\r
++\r
++ gr->ExportMGLD("fexport.mgld");\r
++ gr->Clf();\r
++ gr->ImportMGLD("fexport.mgld");\r
++}\r
++//-----------------------------------------------------------------------------\r
++int main(int argc,char **argv)\r
++{\r
++// const char *f = strrchr(argv[0],'/');\r
++// std::string p(argv[0],f-argv[0]);\r
++// printf("getcwd = '%s', argv = '%s', path = '%s', inst = '%s'\n", getcwd(NULL,0), argv[0], p.c_str(), MGL_INSTALL_DIR);\r
++// fflush(stdout);\r
++\r
++ mgl_textdomain(argv?argv[0]:NULL,"");\r
++ mgl_suppress_warn(true);\r
++ const char *suf = "";\r
++ char name[256]="", *tmp;\r
++ int ch;\r
++ time_t st,en; time(&st);\r
++ mglGraph *gr = NULL;\r
++ mglSample *s=samp;\r
++ while(( ch = getopt_long_only(argc, argv, "", longopts, NULL)) != -1)\r
++ switch(ch)\r
++ {\r
++ case 0: break;\r
++ case 'w': width =atoi(optarg); break;\r
++ case 'h': height=atoi(optarg); break;\r
++ case 'q': quality =atoi(optarg); break;\r
++ case 'k': mgl_strncpy(name, optarg,256);\r
++ tmp=strchr(name,'.'); if(tmp) *tmp=0;\r
++ tmp=strchr(name,'-'); if(tmp) *tmp=0;\r
++ break;\r
++ case 't': mgl_set_num_thr(atoi(optarg)); break;\r
++ case 'l':\r
++ while(s->name[0]) { printf("%s ",s->name); s++; }\r
++ printf("\n"); return 0;\r
++ case '?':\r
++ default: usage(); return 0;\r
++ }\r
++\r
++ if(dotest==1) printf("Global (before):%s\n",mglGlobalMess.c_str());\r
++ gr = new mglGraph;\r
++ if( type==11|| type==12|| type==5 || type==9) width=height;\r
++ switch(big)\r
++ {\r
++ case 1: gr->SetSize(1920,1440); suf = "-lg"; break;\r
++ case 2: gr->SetSize(640,480); break;\r
++ case 3: gr->SetSize(192,144); suf = "-sm"; break;\r
++ default: gr->SetSize(width,height);\r
++ }\r
++ gr->SetQuality(quality);\r
++\r
++ if(dotest==1)\r
++ {\r
++ mgl_set_test_mode(true); test(gr);\r
++ time(&en); printf("time is %g sec\n",difftime(en,st));\r
++#if MGL_HAVE_PNG\r
++ gr->WritePNG("test.png","",false);\r
++#else\r
++ gr->WriteBMP("test.bmp");\r
++#endif\r
++ gr->WriteSVG("test.svg");\r
++ gr->WriteEPS("test.eps");\r
++ printf("Messages:%s\n",gr->Message());\r
++ printf("Global:%s\n",mglGlobalMess.c_str());\r
++ delete gr; return 0;\r
++ }\r
++ else if(dotest==2) // NOTE mgl_gen_fnt[###][6] have to be updated if new glyphs will be added to built-in font\r
++ { mgl_create_cpp_font(gr->Self(), L"!-~,¡-ÿ,̀-̏,Α-ω,ϑ,ϕ,ϖ,ϰ,ϱ,ϵ,А-я,ℏ,ℑ,ℓ,ℜ,←-↙,∀-∯,≠-≯,⟂");\r
++ delete gr; return 0; }\r
++ else if(dotest==3)\r
++ {\r
++ int qual[7]={0,1,2,4,5,6,8};\r
++ size_t ll=strlen(mmgl_dat_prepare)+1;\r
++ mglParse par;\r
++ par.AllowSetSize(true);\r
++ FILE *fp = fopen(big?"time_big.texi":"time.texi","w");\r
++ fprintf(fp,"@multitable @columnfractions .16 .12 .12 .12 .12 .12 .12 .12\n");\r
++ fprintf(fp,"@headitem Name");\r
++ for(int i=0;i<7;i++) fprintf(fp," @tab q=%d",qual[i]);\r
++ clock_t beg,end;\r
++ while(s->name[0]) // all samples\r
++ {\r
++ char *buf = new char[strlen(s->mgl)+ll];\r
++ strcpy(buf,s->mgl); strcat(buf,mmgl_dat_prepare);\r
++ fprintf(fp,"\n@item %s",s->name);\r
++\r
++ printf("%s",s->name);\r
++ for(int i=0;i<7;i++)\r
++ {\r
++ gr->DefaultPlotParam();\r
++ gr->SetQuality(qual[i]); gr->Clf();\r
++ beg = clock();\r
++ if(!use_mgl) s->func(gr);\r
++ else par.Execute(gr,buf);\r
++ gr->Finish();\r
++ end = clock();\r
++ fprintf(fp," @tab %.3g",double(end-beg)/CLOCKS_PER_SEC);\r
++ printf("\t%d->%g",qual[i],double(end-beg)/CLOCKS_PER_SEC);\r
++ fflush(fp); fflush(stdout);\r
++ }\r
++ printf("\n"); delete []buf; s++;\r
++ }\r
++ fprintf(fp,"\n@end multitable\n"); fclose(fp);\r
++ }\r
++ else if(dotest==4)\r
++ { smgl_fexport(gr); delete gr; return 0; }\r
++ else if(dotest==5)\r
++ {\r
++ mgl_check_tex_table();\r
++ delete gr; return 0;\r
++ }\r
++\r
++ if(type==15 || type==16) big=3; // save mini version for json\r
++\r
++ if(srnd) mgl_srnd(1);\r
++ gr->VertexColor(false); gr->Compression(false);\r
++ if(name[0]==0)\r
++ {\r
++ while(s->name[0]) // all samples\r
++ {\r
++ gr->DefaultPlotParam(); gr->Clf();\r
++ if(use_mgl)\r
++ {\r
++ mglParse par;\r
++ par.AllowSetSize(true);\r
++ char *buf = new char[strlen(s->mgl)+strlen(mmgl_dat_prepare)+1];\r
++ strcpy(buf,s->mgl); strcat(buf,mmgl_dat_prepare);\r
++ if(type!=7) printf("\n-------\n%s\n-------\n",verbose?buf:s->mgl);\r
++ par.Execute(gr,buf); delete []buf;\r
++ const char *mess = gr->Message();\r
++ if(*mess) printf("Warnings: %s\n-------\n",mess);\r
++ }\r
++ else s->func(gr);\r
++ save(gr, s->name, suf);\r
++ printf("%s ",s->name); fflush(stdout); s++;\r
++ gr->SetQuality(quality);\r
++ }\r
++ printf("\n");\r
++ }\r
++ else // manual sample\r
++ {\r
++ mglSample tst; tst.name=name;\r
++ int i=0;\r
++ for(i=0;samp[i].name[0];i++); // determine the number of samples\r
++ s = (mglSample *) bsearch(&tst, samp, i, sizeof(mglSample), mgl_cmd_smp);\r
++ if(s)\r
++ {\r
++ gr->DefaultPlotParam(); gr->Clf();\r
++ if(use_mgl)\r
++ {\r
++ mglParse par;\r
++ par.AllowSetSize(true);\r
++ char *buf = new char[strlen(s->mgl)+strlen(mmgl_dat_prepare)+1];\r
++ strcpy(buf,s->mgl); strcat(buf,mmgl_dat_prepare);\r
++ if(type!=7) printf("\n-------\n%s\n-------\n",verbose?buf:s->mgl);\r
++ par.Execute(gr,buf); delete []buf;\r
++ const char *mess = gr->Message();\r
++ if(*mess) printf("Warnings: %s\n-------\n",mess);\r
++ }\r
++ else s->func(gr);\r
++ save(gr, s->name, suf);\r
++ }\r
++ else printf("no sample %s\n",name);\r
++ }\r
++ delete gr; return 0;\r
++}\r
++//-----------------------------------------------------------------------------\r
--- /dev/null
--- /dev/null
++<<<<<<< HEAD
++add_executable(make_bin make_bin.cpp)
++target_link_libraries(make_bin mgl-static ${getopt_lib-static})
++=======
++include_directories( ${MathGL2_SOURCE_DIR}/include ${MathGL2_BINARY_DIR}/include)
++set(hdrF ../include/mgl2/font.h ../include/mgl2/define.h ${MathGL2_BINARY_DIR}/include/mgl2/config.h)
++add_executable(make_bin make_bin.cpp ../src/font.cpp ${hdrF})
++#target_link_libraries(make_bin mgl-static ${getopt_lib-static})
++target_link_libraries(make_bin ${MGL_DEP_LIBS})
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++set(MGL_FONTS STIX adventor bonum cursor heroscn heros pagella schola termes)
++set(MGL_FONTS_BIN )
++set(MGL_FONTS_SRC )
++
++foreach(SAMPLE ${MGL_FONTS})
++ set(MGL_FONTS_BIN ${MGL_FONTS_BIN} ${MathGL2_BINARY_DIR}/fonts/${SAMPLE}.vfmb)
++ add_custom_command(OUTPUT ${MathGL2_BINARY_DIR}/fonts/${SAMPLE}.vfmb
++ COMMAND make_bin -p ${MathGL2_SOURCE_DIR}/fonts/ -o ${MathGL2_BINARY_DIR}/fonts/${SAMPLE}.vfmb ${SAMPLE}
++ DEPENDS ${SAMPLE}.vfm make_bin )
++endforeach(SAMPLE)
++
++add_custom_target(fonts ALL DEPENDS ${MGL_FONTS_BIN})
++
++install(DIRECTORY ${MathGL2_BINARY_DIR}/fonts/ DESTINATION ${MGL_FONT_PATH}
++ PATTERN "*[mM]ake*" EXCLUDE
++ PATTERN ".svn" EXCLUDE
++ PATTERN "*.vfmb")
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * canvas_cf.h is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#ifndef MGL_CANVAS_CF_H\r
++#define MGL_CANVAS_CF_H\r
++#include "mgl2/abstract.h"\r
++//-----------------------------------------------------------------------------\r
++#ifdef __cplusplus\r
++extern "C" {\r
++#endif\r
++\r
++/// Create HMGL object with specified sizes\r
++HMGL MGL_EXPORT mgl_create_graph(int width, int height);\r
++uintptr_t MGL_EXPORT mgl_create_graph_(int *width, int *height);\r
++/// Delete HMGL object\r
++void MGL_EXPORT mgl_delete_graph(HMGL gr);\r
++void MGL_EXPORT mgl_delete_graph_(uintptr_t *gr);\r
++/// Set size of frame in pixels. Normally this function is called internally.\r
++void MGL_EXPORT mgl_set_size(HMGL gr, int width, int height);\r
++void MGL_EXPORT mgl_set_size_(uintptr_t *gr, int *width, int *height);\r
++/// Set size of frame in pixels, but don't erase primitives\r
++void MGL_EXPORT mgl_scale_size(HMGL gr, int width, int height);\r
++void MGL_EXPORT mgl_scale_size_(uintptr_t *gr, int *width, int *height);\r
++/// Scaling for all further set size calls.\r
++void MGL_EXPORT mgl_set_size_scl(double scl);\r
++void MGL_EXPORT mgl_set_size_scl_(double *scl);\r
++/// Set default parameters for plotting\r
++void MGL_EXPORT mgl_set_def_param(HMGL gr);\r
++void MGL_EXPORT mgl_set_def_param_(uintptr_t *gr);\r
++/// Combine plots from 2 canvases. Result will be saved into gr\r
++void MGL_EXPORT mgl_combine_gr(HMGL gr, HMGL gr2);\r
++void MGL_EXPORT mgl_combine_gr_(uintptr_t *gr, uintptr_t *gr2);\r
++/// Force preparing the image. It can be useful for OpenGL mode mostly.\r
++void MGL_EXPORT mgl_finish(HMGL gr);\r
++void MGL_EXPORT mgl_finish_(uintptr_t *gr);\r
++/// Force preparing the image and save result into background one.\r
++void MGL_EXPORT mgl_rasterize(HMGL gr);\r
++void MGL_EXPORT mgl_rasterize_(uintptr_t *gr);\r
++/// Set boundary box for export graphics into 2D file formats.\r
++/** If x2<0 (y2<0) then full width (height) will be used.\r
++ * If x1<0 or y1<0 or x1>=x2|Width or y1>=y2|Height then cropping will be disabled. */\r
++void MGL_EXPORT mgl_set_bbox(HMGL gr, int x1, int y1, int x2, int y2);\r
++void MGL_EXPORT mgl_set_bbox_(uintptr_t *gr, int *x1, int *y1, int *x2, int *y2);\r
++\r
++/// Set the size of semi-transparent area around lines, marks, glyphs, ... Default is 1.\r
++void MGL_EXPORT mgl_pen_delta(HMGL gr, double d);\r
++void MGL_EXPORT mgl_pen_delta_(uintptr_t *gr, double *d);\r
++\r
++/// Set tick length\r
++void MGL_EXPORT mgl_set_tick_len(HMGL gr, double len, double stt);\r
++void MGL_EXPORT mgl_set_tick_len_(uintptr_t *gr, mreal *len, mreal *stt);\r
++/// Set axis and ticks style\r
++void MGL_EXPORT mgl_set_axis_stl(HMGL gr, const char *stl, const char *tck, const char *sub);\r
++void MGL_EXPORT mgl_set_axis_stl_(uintptr_t *gr, const char *stl, const char *tck, const char *sub, int,int,int);\r
++\r
++/// Auto adjust ticks\r
++void MGL_EXPORT mgl_adjust_ticks(HMGL gr, const char *dir);\r
++void MGL_EXPORT mgl_adjust_ticks_(uintptr_t *gr, const char *dir, int);\r
++/// Auto adjust ticks and set ticks format ("+E0123456789-fF")\r
++void MGL_EXPORT mgl_adjust_ticks_ext(HMGL gr, const char *dir, const char *stl);\r
++void MGL_EXPORT mgl_adjust_ticks_ext_(uintptr_t *gr, const char *dir, const char *stl, int, int);\r
++/// Set the ticks parameters\r
++void MGL_EXPORT mgl_set_ticks(HMGL gr, char dir, double d, int ns, double org);\r
++void MGL_EXPORT mgl_set_ticks_(uintptr_t *gr, char *dir, mreal *d, int *ns, mreal *org, int);\r
++/// Set the ticks parameters and specify ticks factor string\r
++void MGL_EXPORT mgl_set_ticks_fact(HMGL gr, char dir, double d, int ns, double org, const char *fact);\r
++void MGL_EXPORT mgl_set_ticks_factw(HMGL gr, char dir, double d, int ns, double org, const wchar_t *fact);\r
++void MGL_EXPORT mgl_set_ticks_fact_(uintptr_t *gr, char *dir, double *d, int *ns, double *org, const char *fact,int,int);\r
++\r
++/// Set manual ticks text (\n separated). Use "" to disable this feature.\r
++void MGL_EXPORT mgl_set_ticks_str(HMGL gr, char dir, const char *lbl, int add);\r
++void MGL_EXPORT mgl_set_ticks_str_(uintptr_t *gr, const char *dir, const char *lbl, int *add,int,int);\r
++void MGL_EXPORT mgl_set_ticks_wcs(HMGL gr, char dir, const wchar_t *lbl, int add);\r
++/// Set manual ticks position and text (\n separated). Use "" to disable this feature.\r
++void MGL_EXPORT mgl_set_ticks_val(HMGL gr, char dir, HCDT val, const char *lbl, int add);\r
++void MGL_EXPORT mgl_set_ticks_val_(uintptr_t *gr, const char *dir, uintptr_t *val, const char *lbl, int *add,int,int);\r
++void MGL_EXPORT mgl_set_ticks_valw(HMGL gr, char dir, HCDT val, const wchar_t *lbl, int add);\r
++/// Add manual tick at given position. Use "" to disable this feature.\r
++void MGL_EXPORT mgl_add_tick(HMGL gr, char dir, double val, const char *lbl);\r
++void MGL_EXPORT mgl_add_tick_(uintptr_t *gr, const char *dir, mreal *val, const char *lbl,int,int);\r
++void MGL_EXPORT mgl_add_tickw(HMGL gr, char dir, double val, const wchar_t *lbl);\r
++/// Tune ticks (tune|1 for common multiplier, tune|2 for common component)\r
++void MGL_EXPORT mgl_tune_ticks(HMGL gr, int tune, double fact_pos);\r
++void MGL_EXPORT mgl_tune_ticks_(uintptr_t *gr, int *tune, mreal *fact_pos);\r
++/// Set templates for ticks\r
++void MGL_EXPORT mgl_set_tick_templ(HMGL gr, char dir, const char *templ);\r
++void MGL_EXPORT mgl_set_tick_templ_(uintptr_t *gr, const char *dir, const char *templ,int,int);\r
++void MGL_EXPORT mgl_set_tick_templw(HMGL gr, char dir, const wchar_t *templ);\r
++/// Set time templates for ticks\r
++void MGL_EXPORT mgl_set_ticks_time(HMGL gr, char dir, double d, const char *t);\r
++void MGL_EXPORT mgl_set_ticks_time_(uintptr_t *gr, const char *dir, mreal *d, const char *t,int,int);\r
++/// Set additional shift of tick labels\r
++void MGL_EXPORT mgl_set_tick_shift(HMGL gr, double sx, double sy, double sz, double sc);\r
++void MGL_EXPORT mgl_set_tick_shift_(uintptr_t *gr, mreal *sx, mreal *sy, mreal *sz, mreal *sc);\r
++\r
++/// Draws bounding box outside the plotting volume\r
++void MGL_EXPORT mgl_box(HMGL gr);\r
++void MGL_EXPORT mgl_box_(uintptr_t *gr);\r
++/// Draws bounding box outside the plotting volume with color c\r
++/** Style ‘@’ produce filled back faces. */\r
++void MGL_EXPORT mgl_box_str(HMGL gr, const char *col, int ticks);\r
++void MGL_EXPORT mgl_box_str_(uintptr_t *gr, const char *col, int *ticks, int);\r
++/// Draw axises with ticks in direction(s) dir.\r
++/** Parameter \a dir may contain:\r
++ * ‘xyzt’for drawing axis in corresponding direction;\r
++ * ‘XYZT’ for drawing axis in corresponding direction but with inverted positions of labels;\r
++ * ‘~’, ‘_’ for disabling tick labels;\r
++ * ‘U’ for disabling rotation of tick labels;\r
++ * ‘^’ for inverting default axis origin;\r
++ * ‘!’ for disabling ticks tuning;\r
++ * ‘AKDTVISO’ for drawing arrow at the end of axis;\r
++ * ‘a’ for forced adjusting of axis ticks;\r
++ * ‘f’ for printing ticks labels in fixed format;\r
++ * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;\r
++ * ‘F’ for printing ticks labels in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive ticks;\r
++ * ‘-’ for printing usual ‘-’ in ticks labels;\r
++ * ‘0123456789’ for precision at printing ticks labels.\r
++ * Option "value" set the manual rotation angle for the ticks.*/\r
++void MGL_EXPORT mgl_axis(HMGL gr, const char *dir, const char *stl, const char *opt);\r
++void MGL_EXPORT mgl_axis_(uintptr_t *gr, const char *dir, const char *stl, const char *opt,int,int,int);\r
++/// Draw grid lines perpendicular to direction(s) dir.\r
++void MGL_EXPORT mgl_axis_grid(HMGL gr, const char *dir,const char *pen, const char *opt);\r
++void MGL_EXPORT mgl_axis_grid_(uintptr_t *gr, const char *dir,const char *pen, const char *opt,int,int,int);\r
++/// Print the label text for axis dir.\r
++/** Option "value" set additional shifting of the label. */\r
++void MGL_EXPORT mgl_label(HMGL gr, char dir, const char *text, double pos, const char *opt);\r
++void MGL_EXPORT mgl_label_(uintptr_t *gr, const char *dir, const char *text, mreal *pos, const char *opt,int,int,int);\r
++/// Print the label text for axis dir.\r
++/** Option "value" set additional shifting of the label. */\r
++void MGL_EXPORT mgl_labelw(HMGL gr, char dir, const wchar_t *text, double pos, const char *opt);\r
++\r
++/// Draw colorbar at edge of axis\r
++/** Parameter \a sch may contain:\r
++ * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly;\r
++ * ‘I’ for positioning near bounding (by default, at edges of subplot);\r
++ * ‘A’ for using absolute coordinates;\r
++ * ‘~’ for disabling tick labels.\r
++ * ‘!’ for disabling ticks tuning;\r
++ * ‘f’ for printing ticks labels in fixed format;\r
++ * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;\r
++ * ‘F’ for printing ticks labels in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive ticks;\r
++ * ‘-’ for printing usual ‘-’ in ticks labels;\r
++ * ‘0123456789’ for precision at printing ticks labels.*/\r
++void MGL_EXPORT mgl_colorbar(HMGL gr, const char *sch);\r
++void MGL_EXPORT mgl_colorbar_(uintptr_t *gr, const char *sch,int);\r
++/// Draw colorbar at manual position\r
++/** Parameter \a sch may contain:\r
++ * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly;\r
++ * ‘I’ for positioning near bounding (by default, at edges of subplot);\r
++ * ‘A’ for using absolute coordinates;\r
++ * ‘~’ for disabling tick labels.\r
++ * ‘!’ for disabling ticks tuning;\r
++ * ‘f’ for printing ticks labels in fixed format;\r
++ * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;\r
++ * ‘F’ for printing ticks labels in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive ticks;\r
++ * ‘-’ for printing usual ‘-’ in ticks labels;\r
++ * ‘0123456789’ for precision at printing ticks labels.*/\r
++void MGL_EXPORT mgl_colorbar_ext(HMGL gr, const char *sch, double x, double y, double w, double h);\r
++void MGL_EXPORT mgl_colorbar_ext_(uintptr_t *gr, const char *sch, mreal *x, mreal *y, mreal *w, mreal *h, int);\r
++/// Draw colorbar with manual colors at edge of axis\r
++/** Parameter \a sch may contain:\r
++ * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly;\r
++ * ‘I’ for positioning near bounding (by default, at edges of subplot);\r
++ * ‘A’ for using absolute coordinates;\r
++ * ‘~’ for disabling tick labels.\r
++ * ‘!’ for disabling ticks tuning;\r
++ * ‘f’ for printing ticks labels in fixed format;\r
++ * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;\r
++ * ‘F’ for printing ticks labels in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive ticks;\r
++ * ‘-’ for printing usual ‘-’ in ticks labels;\r
++ * ‘0123456789’ for precision at printing ticks labels.*/\r
++void MGL_EXPORT mgl_colorbar_val(HMGL gr, HCDT dat, const char *sch);\r
++void MGL_EXPORT mgl_colorbar_val_(uintptr_t *gr, uintptr_t *dat, const char *sch,int);\r
++/// Draw colorbar with manual colors at manual position\r
++/** Parameter \a sch may contain:\r
++ * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly;\r
++ * ‘I’ for positioning near bounding (by default, at edges of subplot);\r
++ * ‘A’ for using absolute coordinates;\r
++ * ‘~’ for disabling tick labels.\r
++ * ‘!’ for disabling ticks tuning;\r
++ * ‘f’ for printing ticks labels in fixed format;\r
++ * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;\r
++ * ‘F’ for printing ticks labels in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive ticks;\r
++ * ‘-’ for printing usual ‘-’ in ticks labels;\r
++ * ‘0123456789’ for precision at printing ticks labels.*/\r
++void MGL_EXPORT mgl_colorbar_val_ext(HMGL gr, HCDT dat, const char *sch,double x, double y, double w, double h);\r
++void MGL_EXPORT mgl_colorbar_val_ext_(uintptr_t *gr, uintptr_t *dat, const char *sch, mreal *x, mreal *y, mreal *w, mreal *h, int);\r
++\r
++/// Add string to legend\r
++void MGL_EXPORT mgl_add_legend(HMGL gr, const char *text,const char *style);\r
++void MGL_EXPORT mgl_add_legend_(uintptr_t *gr, const char *text,const char *style,int,int);\r
++void MGL_EXPORT mgl_add_legendw(HMGL gr, const wchar_t *text,const char *style);\r
++/// Clear saved legend string\r
++void MGL_EXPORT mgl_clear_legend(HMGL gr);\r
++void MGL_EXPORT mgl_clear_legend_(uintptr_t *gr);\r
++/// Draw legend of accumulated strings at position {x,y}\r
++/** Parameter fnt may contain:\r
++ * font style for legend text;\r
++ * colors for background (first one), border (second one) and text (last one);\r
++ * ‘A’ for positioning in absolute coordinates;\r
++ * ‘^’ for positioning outside of specified point;\r
++ * ‘-’ for arranging entries horizontally;\r
++ * ‘#’ for drawing box around legend.\r
++ * Option value set the space between line samples and text (default is 0.1).*/\r
++void MGL_EXPORT mgl_legend_pos(HMGL gr, double x, double y, const char *font, const char *opt);\r
++void MGL_EXPORT mgl_legend_pos_(uintptr_t *gr, mreal *x, mreal *y, const char *font, const char *opt,int,int);\r
++/// Draw legend of accumulated strings\r
++/** Parameter fnt may contain:\r
++ * font style for legend text;\r
++ * colors for background (first one), border (second one) and text (last one);\r
++ * ‘A’ for positioning in absolute coordinates;\r
++ * ‘^’ for positioning outside of specified point;\r
++ * ‘-’ for arranging entries horizontally;\r
++ * ‘#’ for drawing box around legend.\r
++ * Option value set the space between line samples and text (default is 0.1).\r
++ * Parameter \a where sets position: 0 at bottom-left, 1 at bottom-right, 2 at top-left, 3 at top-right (default).*/\r
++void MGL_EXPORT mgl_legend(HMGL gr, int where, const char *font, const char *opt);\r
++void MGL_EXPORT mgl_legend_(uintptr_t *gr, int *where, const char *font, const char *opt,int,int);\r
++/// Set number of marks in legend sample\r
++void MGL_EXPORT mgl_set_legend_marks(HMGL gr, int num);\r
++void MGL_EXPORT mgl_set_legend_marks_(uintptr_t *gr, int *num);\r
++\r
++/// Show current image\r
++void MGL_EXPORT mgl_show_image(HMGL gr, const char *viewer, int keep);\r
++void MGL_EXPORT mgl_show_image_(uintptr_t *gr, const char *viewer, int *keep, int);\r
++/// Write the frame in file (depending extension, write current frame if fname is empty)\r
++void MGL_EXPORT mgl_write_frame(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_frame_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++/// Write the frame in file using BMP format\r
++void MGL_EXPORT mgl_write_tga(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_tga_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++/// Write the frame in file using BMP format\r
++void MGL_EXPORT mgl_write_bmp(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_bmp_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++/// Write the frame in file using JPEG format\r
++void MGL_EXPORT mgl_write_jpg(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_jpg_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++/// Write the frame in file using PNG format with transparency\r
++void MGL_EXPORT mgl_write_png(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_png_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++/// Write the frame in file using PNG format without transparency\r
++void MGL_EXPORT mgl_write_png_solid(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_png_solid_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++/// Write the frame in file using PostScript format as bitmap\r
++void MGL_EXPORT mgl_write_bps(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_bps_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++/// Write the frame in file using PostScript format\r
++void MGL_EXPORT mgl_write_eps(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_eps_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++/// Write the frame in file using SVG format\r
++void MGL_EXPORT mgl_write_svg(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_svg_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++/// Write the frame in file using LaTeX format\r
++void MGL_EXPORT mgl_write_tex(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_tex_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++/// Write the frame in file using OBJ format\r
++void MGL_EXPORT mgl_write_obj(HMGL gr, const char *fname,const char *descr, int use_png);\r
++void MGL_EXPORT mgl_write_obj_(uintptr_t *gr, const char *fname,const char *descr, int *use_png,int,int);\r
++/// Write the frame in file using OBJ format (old version)\r
++void MGL_EXPORT mgl_write_obj_old(HMGL gr, const char *fname,const char *descr, int use_png);\r
++void MGL_EXPORT mgl_write_obj_old_(uintptr_t *gr, const char *fname,const char *descr, int *use_png,int,int);\r
++/// Write the frame in file using STL format (faces only)\r
++void MGL_EXPORT mgl_write_stl(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_stl_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++/// Write the frame in file using OFF format\r
++void MGL_EXPORT mgl_write_off(HMGL gr, const char *fname,const char *descr, int colored);\r
++void MGL_EXPORT mgl_write_off_(uintptr_t *gr, const char *fname,const char *descr,int *colored,int,int);\r
++/// Write the frame in file using XYZ format\r
++void MGL_EXPORT mgl_write_xyz(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_xyz_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++\r
++/*void MGL_EXPORT mgl_write_x3d(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_x3d_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++void MGL_EXPORT mgl_write_wgl(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_wgl_(uintptr_t *gr, const char *fname,const char *descr,int,int);*/\r
++\r
++/// Write the frame in file using PRC format\r
++void MGL_EXPORT mgl_write_prc(HMGL gr, const char *fname,const char *descr, int make_pdf);\r
++void MGL_EXPORT mgl_write_prc_(uintptr_t *gr, const char *fname,const char *descr, int *make_pdf,int,int);\r
++/// Write the frame in file using GIF format (only for current frame!)\r
++void MGL_EXPORT mgl_write_gif(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_gif_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++\r
++/// Start write frames to cinema using GIF format\r
++void MGL_EXPORT mgl_start_gif(HMGL gr, const char *fname,int ms);\r
++void MGL_EXPORT mgl_start_gif_(uintptr_t *gr, const char *fname,int *ms,int);\r
++/// Stop writing cinema using GIF format\r
++void MGL_EXPORT mgl_close_gif(HMGL gr);\r
++void MGL_EXPORT mgl_close_gif_(uintptr_t *gr);\r
++\r
++/// Export points and primitives in file using MGLD format\r
++void MGL_EXPORT mgl_export_mgld(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_export_mgld_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++/// Import points and primitives from file using MGLD format\r
++void MGL_EXPORT mgl_import_mgld(HMGL gr, const char *fname, int add);\r
++void MGL_EXPORT mgl_import_mgld_(uintptr_t *gr, const char *fname, int *add, int);\r
++/// Export in JSON format suitable for later drawing by JavaScript\r
++void MGL_EXPORT mgl_write_json(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_json_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++void MGL_EXPORT mgl_write_json_z(HMGL gr, const char *fname,const char *descr);\r
++void MGL_EXPORT mgl_write_json_z_(uintptr_t *gr, const char *fname,const char *descr,int,int);\r
++MGL_EXPORT const char *mgl_get_json(HMGL gr);\r
++\r
++/// Get RGB values of current bitmap\r
++/** Position of element {i,j} is [3*i + 3*Width*j]. */\r
++MGL_EXPORT const unsigned char *mgl_get_rgb(HMGL gr);\r
++MGL_EXPORT const unsigned char *mgl_get_rgb_(uintptr_t *gr);\r
++/// Get RGBA values of current bitmap\r
++/** Position of element {i,j} is [4*i + 4*Width*j]. */\r
++MGL_EXPORT const unsigned char *mgl_get_rgba(HMGL gr);\r
++MGL_EXPORT const unsigned char *mgl_get_rgba_(uintptr_t *gr);\r
++/// Get RGBA values of background image\r
++/** Position of element {i,j} is [4*i + 4*Width*j]. */\r
++MGL_EXPORT const unsigned char *mgl_get_background(HMGL gr);\r
++MGL_EXPORT const unsigned char *mgl_get_background_(uintptr_t *gr);\r
++/// Set object/subplot id\r
++void MGL_EXPORT mgl_set_obj_id(HMGL gr, int id);\r
++void MGL_EXPORT mgl_set_obj_id_(uintptr_t *gr, int *id);\r
++/// Get object id\r
++int MGL_EXPORT mgl_get_obj_id(HMGL gr, int x, int y);\r
++int MGL_EXPORT mgl_get_obj_id_(uintptr_t *gr, int *x, int *y);\r
++/// Get subplot id\r
++int MGL_EXPORT mgl_get_spl_id(HMGL gr, int x, int y);\r
++int MGL_EXPORT mgl_get_spl_id_(uintptr_t *gr, int *x, int *y);\r
++/// Get width of the image\r
++int MGL_EXPORT mgl_get_width(HMGL gr);\r
++int MGL_EXPORT mgl_get_width_(uintptr_t *gr);\r
++/// Get height of the image\r
++int MGL_EXPORT mgl_get_height(HMGL gr);\r
++int MGL_EXPORT mgl_get_height_(uintptr_t *gr);\r
++/// Calculate 3D coordinate {x,y,z} for screen point {xs,ys}\r
++void MGL_EXPORT mgl_calc_xyz(HMGL gr, int xs, int ys, mreal *x, mreal *y, mreal *z);\r
++void MGL_EXPORT mgl_calc_xyz_(uintptr_t *gr, int *xs, int *ys, mreal *x, mreal *y, mreal *z);\r
++/// Calculate screen point {xs,ys} for 3D coordinate {x,y,z}\r
++void MGL_EXPORT mgl_calc_scr(HMGL gr, double x, double y, double z, int *xs, int *ys);\r
++void MGL_EXPORT mgl_calc_scr_(uintptr_t *gr, mreal *x, mreal *y, mreal *z, int *xs, int *ys);\r
++/// Check if {xs,ys} is close to active point with accuracy d, and return its position or -1\r
++long MGL_EXPORT mgl_is_active(HMGL gr, int xs, int ys, int d);\r
++long MGL_EXPORT mgl_is_active_(uintptr_t *gr, int *xs, int *ys, int *d);\r
++\r
++/// Create new frame.\r
++int MGL_EXPORT mgl_new_frame(HMGL gr);\r
++int MGL_EXPORT mgl_new_frame_(uintptr_t *gr);\r
++/// Finish frame drawing\r
++void MGL_EXPORT mgl_end_frame(HMGL gr);\r
++void MGL_EXPORT mgl_end_frame_(uintptr_t *gr);\r
++/// Get the number of created frames\r
++int MGL_EXPORT mgl_get_num_frame(HMGL gr);\r
++int MGL_EXPORT mgl_get_num_frame_(uintptr_t *gr);\r
++/// Reset frames counter (start it from zero)\r
++void MGL_EXPORT mgl_reset_frames(HMGL gr);\r
++void MGL_EXPORT mgl_reset_frames_(uintptr_t *gr);\r
++/// Get drawing data for i-th frame (work if MGL_VECT_FRAME is set on)\r
++void MGL_EXPORT mgl_get_frame(HMGL gr, int i);\r
++void MGL_EXPORT mgl_get_frame_(uintptr_t *gr, int *i);\r
++/// Set drawing data for i-th frame (work if MGL_VECT_FRAME is set on)\r
++void MGL_EXPORT mgl_set_frame(HMGL gr, int i);\r
++void MGL_EXPORT mgl_set_frame_(uintptr_t *gr, int *i);\r
++/// Append drawing data from i-th frame (work if MGL_VECT_FRAME is set on)\r
++void MGL_EXPORT mgl_show_frame(HMGL gr, int i);\r
++void MGL_EXPORT mgl_show_frame_(uintptr_t *gr, int *i);\r
++/// Delete primitives for i-th frame (work if MGL_VECT_FRAME is set on)\r
++void MGL_EXPORT mgl_del_frame(HMGL gr, int i);\r
++void MGL_EXPORT mgl_del_frame_(uintptr_t *gr, int *i);\r
++/// Clear list of primitives for current drawing\r
++void MGL_EXPORT mgl_clear_frame(HMGL gr);\r
++void MGL_EXPORT mgl_clear_frame_(uintptr_t *gr);\r
++\r
++/// Set the transparency type (0 - usual, 1 - glass, 2 - lamp)\r
++void MGL_EXPORT mgl_set_transp_type(HMGL gr, int kind);\r
++void MGL_EXPORT mgl_set_transp_type_(uintptr_t *gr, int *kind);\r
++/// Set the transparency on/off.\r
++void MGL_EXPORT mgl_set_alpha(HMGL gr, int enable);\r
++void MGL_EXPORT mgl_set_alpha_(uintptr_t *gr, int *enable);\r
++/// Set the gray-scale mode on/off.\r
++void MGL_EXPORT mgl_set_gray(HMGL gr, int enable);\r
++void MGL_EXPORT mgl_set_gray_(uintptr_t *gr, int *enable);\r
++/// Set the fog distance or switch it off (if d=0).\r
++void MGL_EXPORT mgl_set_fog(HMGL gr, double d, double dz);\r
++void MGL_EXPORT mgl_set_fog_(uintptr_t *gr, mreal *dist, mreal *dz);\r
++/// Set the using of light on/off.\r
++void MGL_EXPORT mgl_set_light(HMGL gr, int enable);\r
++void MGL_EXPORT mgl_set_light_(uintptr_t *gr, int *enable);\r
++/// Switch on/off the specified light source.\r
++void MGL_EXPORT mgl_set_light_n(HMGL gr, int n, int enable);\r
++void MGL_EXPORT mgl_set_light_n_(uintptr_t *gr, int *n, int *enable);\r
++/// Set to attach light settings to inplot.\r
++void MGL_EXPORT mgl_set_attach_light(HMGL gr, int enable);\r
++void MGL_EXPORT mgl_set_attach_light_(uintptr_t *gr, int *enable);\r
++\r
++/// Add white light source at infinity.\r
++void MGL_EXPORT mgl_add_light(HMGL gr, int n, double x, double y, double z);\r
++void MGL_EXPORT mgl_add_light_(uintptr_t *gr, int *n, mreal *x, mreal *y, mreal *z);\r
++/// Add light source at infinity (more settings).\r
++void MGL_EXPORT mgl_add_light_ext(HMGL gr, int n, double x, double y, double z, char c, double br, double ap);\r
++void MGL_EXPORT mgl_add_light_ext_(uintptr_t *gr, int *n, mreal *x, mreal *y, mreal *z, char *c, mreal *br, mreal *ap, int);\r
++/// Add local light source.\r
++void MGL_EXPORT mgl_add_light_loc(HMGL gr, int n, double x, double y, double z, double dx, double dy, double dz, char c, double br, double ap);\r
++void MGL_EXPORT mgl_add_light_loc_(uintptr_t *gr, int *n, mreal *x, mreal *y, mreal *z, mreal *dx, mreal *dy, mreal *dz, char *c, mreal *br, mreal *ap, int);\r
++\r
++/// Pop transformation matrix from stack\r
++void MGL_EXPORT mgl_mat_pop(HMGL gr);\r
++void MGL_EXPORT mgl_mat_pop_(uintptr_t *gr);\r
++/// Push transformation matrix into stack\r
++void MGL_EXPORT mgl_mat_push(HMGL gr);\r
++void MGL_EXPORT mgl_mat_push_(uintptr_t *gr);\r
++\r
++/// Clear up the frame\r
++void MGL_EXPORT mgl_clf(HMGL gr);\r
++void MGL_EXPORT mgl_clf_(uintptr_t *gr);\r
++/// Clear up the frame but keep fog settings\r
++void MGL_EXPORT mgl_clf_nfog(HMGL gr);\r
++void MGL_EXPORT mgl_clf_nfog_(uintptr_t *gr);\r
++/// Clear up the frame and fill background by specified color\r
++void MGL_EXPORT mgl_clf_rgb(HMGL gr, double r, double g, double b);\r
++void MGL_EXPORT mgl_clf_rgb_(uintptr_t *gr, mreal *r, mreal *g, mreal *b);\r
++/// Clear up the frame and fill background by specified color\r
++void MGL_EXPORT mgl_clf_chr(HMGL gr, char col);\r
++void MGL_EXPORT mgl_clf_chr_(uintptr_t *gr, const char *col, int);\r
++/// Clear up the frame and fill background by specified color with manual transparency\r
++void MGL_EXPORT mgl_clf_str(HMGL gr, const char *col);\r
++void MGL_EXPORT mgl_clf_str_(uintptr_t *gr, const char *col, int);\r
++/// Load background image\r
++void MGL_EXPORT mgl_load_background(HMGL gr, const char *fname, double alpha);\r
++void MGL_EXPORT mgl_load_background_(uintptr_t *gr, const char *fname, mreal *alpha, int);\r
++\r
++/// Put further plotting in m-th cell of nx*ny grid of the image.\r
++/** String \a style may contain:\r
++ * '<' for reserving space at left\r
++ * '>' for reserving space at right\r
++ * '^' for reserving space at top\r
++ * '_' for reserving space at bottom\r
++ * '#' for using whole region. */\r
++void MGL_EXPORT mgl_subplot(HMGL gr, int nx,int ny,int m,const char *style);\r
++void MGL_EXPORT mgl_subplot_(uintptr_t *gr, int *nx,int *ny,int *m, const char *s,int);\r
++/// Put further plotting in m-th cell of nx*ny grid of the image and shift it by distance {dx,dy}.\r
++/** String \a style may contain:\r
++ * '<' for reserving space at left\r
++ * '>' for reserving space at right\r
++ * '^' for reserving space at top\r
++ * '_' for reserving space at bottom\r
++ * '#' for using whole region. */\r
++void MGL_EXPORT mgl_subplot_d(HMGL gr, int nx,int ny,int m,const char *style, double dx, double dy);\r
++void MGL_EXPORT mgl_subplot_d_(uintptr_t *gr, int *nx,int *ny,int *m, mreal *dx, mreal *dy);\r
++/// Put further plotting in rectangle of dx*dy cells starting from m-th cell of nx*ny grid of the image.\r
++/** String \a style may contain:\r
++ * '<' for reserving space at left\r
++ * '>' for reserving space at right\r
++ * '^' for reserving space at top\r
++ * '_' for reserving space at bottom\r
++ * '#' for using whole region. */\r
++void MGL_EXPORT mgl_multiplot(HMGL gr, int nx,int ny,int m,int dx,int dy,const char *style);\r
++void MGL_EXPORT mgl_multiplot_(uintptr_t *gr, int *nx,int *ny,int *m,int *dx,int *dy, const char *s,int);\r
++/// Put further plotting in rectangle of dx*dy cells starting from m-th cell of nx*ny grid of the image and shift it by distance {sx,sy}..\r
++/** String \a style may contain:\r
++ * '<' for reserving space at left\r
++ * '>' for reserving space at right\r
++ * '^' for reserving space at top\r
++ * '_' for reserving space at bottom\r
++ * '#' for using whole region. */\r
++void MGL_EXPORT mgl_multiplot_d(HMGL gr, int nx,int ny,int m,int dx,int dy,const char *style,double sx,double sy);\r
++void MGL_EXPORT mgl_multiplot_d_(uintptr_t *gr, int *nx,int *ny,int *m,int *dx,int *dy, const char *s, mreal *sx, mreal *sy,int);\r
++/// Put further plotting in a region [x1,x2]*[y1,y2] of the image (x1,x2,y1,y2 in range [0, 1]).\r
++void MGL_EXPORT mgl_inplot(HMGL gr, double x1,double x2,double y1,double y2);\r
++void MGL_EXPORT mgl_inplot_(uintptr_t *gr, mreal *x1, mreal *x2, mreal *y1, mreal *y2);\r
++/// Put further plotting in a region [x1,x2]*[y1,y2] of the subplot (x1,x2,y1,y2 in range [0, 1]).\r
++void MGL_EXPORT mgl_relplot(HMGL gr, double x1,double x2,double y1,double y2);\r
++void MGL_EXPORT mgl_relplot_(uintptr_t *gr, mreal *x1, mreal *x2, mreal *y1, mreal *y2);\r
++/// Put further plotting in column cell of previous subplot/inplot.\r
++void MGL_EXPORT mgl_columnplot(HMGL gr, int num, int ind, double d);\r
++void MGL_EXPORT mgl_columnplot_(uintptr_t *gr, int *num, int *i, mreal *d);\r
++/// Put further plotting in matrix cell of previous subplot/inplot.\r
++void MGL_EXPORT mgl_gridplot(HMGL gr, int nx, int ny, int m, double d);\r
++void MGL_EXPORT mgl_gridplot_(uintptr_t *gr, int *nx, int *ny, int *m, mreal *d);\r
++/// Put further plotting in cell of stick rotated on angles tet, phi.\r
++void MGL_EXPORT mgl_stickplot(HMGL gr, int num, int ind, double tet, double phi);\r
++void MGL_EXPORT mgl_stickplot_(uintptr_t *gr, int *num, int *i, mreal *tet, mreal *phi);\r
++/// Put further plotting in cell of stick sheared on sx, sy.\r
++void MGL_EXPORT mgl_shearplot(HMGL gr, int num, int ind, double sx, double sy, double xd, double yd);\r
++void MGL_EXPORT mgl_shearplot_(uintptr_t *gr, int *num, int *i, mreal *sy, mreal *sx, mreal *xd, mreal *yd);\r
++/// Add title for current subplot/inplot.\r
++/** Style '#' draw box around the title. */\r
++void MGL_EXPORT mgl_title(HMGL gr, const char *title, const char *stl, double size);\r
++void MGL_EXPORT mgl_title_(uintptr_t *gr, const char *title, const char *stl, mreal *size, int,int);\r
++void MGL_EXPORT mgl_titlew(HMGL gr, const wchar_t *title, const char *stl, double size);\r
++/// Set factor of plot size\r
++void MGL_EXPORT mgl_set_plotfactor(HMGL gr, double val);\r
++void MGL_EXPORT mgl_set_plotfactor_(uintptr_t *gr, mreal *val);\r
++\r
++/// Set aspect ratio for further plotting.\r
++void MGL_EXPORT mgl_aspect(HMGL gr, double Ax,double Ay,double Az);\r
++void MGL_EXPORT mgl_aspect_(uintptr_t *gr, mreal *Ax, mreal *Ay, mreal *Az);\r
++/// Set aspect ratio for further plotting.\r
++void MGL_EXPORT mgl_shear(HMGL gr, double Sx,double Sz);\r
++void MGL_EXPORT mgl_shear_(uintptr_t *gr, mreal *Sx, mreal *Sy);\r
++/// Rotate a further plotting.\r
++void MGL_EXPORT mgl_rotate(HMGL gr, double TetX,double TetZ,double TetY);\r
++void MGL_EXPORT mgl_rotate_(uintptr_t *gr, mreal *TetX, mreal *TetZ, mreal *TetY);\r
++/// Rotate a further plotting around vector {x,y,z}.\r
++void MGL_EXPORT mgl_rotate_vector(HMGL gr, double Tet,double x,double y,double z);\r
++void MGL_EXPORT mgl_rotate_vector_(uintptr_t *gr, mreal *Tet, mreal *x, mreal *y, mreal *z);\r
++/// Set perspective (in range [0,1)) for plot. Set to zero for switching off.\r
++void MGL_EXPORT mgl_perspective(HMGL gr, double val);\r
++void MGL_EXPORT mgl_perspective_(uintptr_t *gr, mreal *val);\r
++/// Ask to set perspective (in range [0,1)) for plot. Set to zero for switching off.\r
++void MGL_EXPORT mgl_ask_perspective(HMGL gr, double val);\r
++void MGL_EXPORT mgl_ask_perspective_(uintptr_t *gr, mreal *val);\r
++/// Set angle of view independently from Rotate().\r
++void MGL_EXPORT mgl_view(HMGL gr, double TetX,double TetZ,double TetY);\r
++void MGL_EXPORT mgl_view_(uintptr_t *gr, mreal *TetX, mreal *TetZ, mreal *TetY);\r
++/// Zoom in/out a part of picture (use mgl_zoom(0, 0, 1, 1) for restore default)\r
++void MGL_EXPORT mgl_zoom(HMGL gr, double x1, double y1, double x2, double y2);\r
++void MGL_EXPORT mgl_zoom_(uintptr_t *gr, mreal *x1, mreal *y1, mreal *x2, mreal *y2);\r
++\r
++//-----------------------------------------------------------------------------\r
++/// Callback function for mouse click\r
++void MGL_EXPORT mgl_set_click_func(HMGL gr, void (*func)(void *p));\r
++#if MGL_HAVE_PTHR_WIDGET\r
++/// Mutex for lock/unlock by widget\r
++void MGL_EXPORT mgl_wnd_set_mutex(HMGL gr, pthread_mutex_t *mutex);\r
++#endif\r
++\r
++/// Set callback functions for drawing and data reloading\r
++void MGL_EXPORT mgl_wnd_set_func(HMGL gr, int (*draw)(HMGL gr, void *p), void *par, void (*reload)(void *p));\r
++/// Set delay for animation in seconds\r
++void MGL_EXPORT mgl_wnd_set_delay(HMGL gr, double dt);\r
++void MGL_EXPORT mgl_wnd_set_delay_(uintptr_t *gr, mreal *dt);\r
++/// Get delay for animation in seconds\r
++double MGL_EXPORT mgl_wnd_get_delay(HMGL gr);\r
++double MGL_EXPORT mgl_wnd_get_delay_(uintptr_t *gr);\r
++/// Set window properties\r
++void MGL_EXPORT mgl_setup_window(HMGL gr, int clf_upd, int showpos);\r
++void MGL_EXPORT mgl_setup_window_(uintptr_t *gr, int *clf_upd, int *showpos);\r
++/// Switch on/off transparency (do not overwrite user settings)\r
++void MGL_EXPORT mgl_wnd_toggle_alpha(HMGL gr);\r
++void MGL_EXPORT mgl_wnd_toggle_alpha_(uintptr_t *gr);\r
++/// Switch on/off lighting (do not overwrite user settings)\r
++void MGL_EXPORT mgl_wnd_toggle_light(HMGL gr);\r
++void MGL_EXPORT mgl_wnd_toggle_light_(uintptr_t *gr);\r
++/// Switch on/off zooming by mouse\r
++void MGL_EXPORT mgl_wnd_toggle_zoom(HMGL gr);\r
++void MGL_EXPORT mgl_wnd_toggle_zoom_(uintptr_t *gr);\r
++/// Switch on/off rotation by mouse\r
++void MGL_EXPORT mgl_wnd_toggle_rotate(HMGL gr);\r
++void MGL_EXPORT mgl_wnd_toggle_rotate_(uintptr_t *gr);\r
++/// Switch off all zooming and rotation\r
++void MGL_EXPORT mgl_wnd_toggle_no(HMGL gr);\r
++void MGL_EXPORT mgl_wnd_toggle_no_(uintptr_t *gr);\r
++/// Update picture by calling user drawing function\r
++void MGL_EXPORT mgl_wnd_update(HMGL gr);\r
++void MGL_EXPORT mgl_wnd_update_(uintptr_t *gr);\r
++/// Reload user data and update picture\r
++void MGL_EXPORT mgl_wnd_reload(HMGL gr);\r
++void MGL_EXPORT mgl_wnd_reload_(uintptr_t *gr);\r
++/// Adjust size of bitmap to window size\r
++void MGL_EXPORT mgl_wnd_adjust(HMGL gr);\r
++void MGL_EXPORT mgl_wnd_adjust_(uintptr_t *gr);\r
++/// Show next frame (if one)\r
++void MGL_EXPORT mgl_wnd_next_frame(HMGL gr);\r
++void MGL_EXPORT mgl_wnd_next_frame_(uintptr_t *gr);\r
++/// Show previous frame (if one)\r
++void MGL_EXPORT mgl_wnd_prev_frame(HMGL gr);\r
++void MGL_EXPORT mgl_wnd_prev_frame_(uintptr_t *gr);\r
++/// Run slideshow (animation) of frames\r
++void MGL_EXPORT mgl_wnd_animation(HMGL gr);\r
++void MGL_EXPORT mgl_wnd_animation_(uintptr_t *gr);\r
++/// Get last mouse position\r
++void MGL_EXPORT mgl_get_last_mouse_pos(HMGL gr, mreal *x, mreal *y, mreal *z);\r
++void MGL_EXPORT mgl_get_last_mouse_pos_(uintptr_t *gr, mreal *x, mreal *y, mreal *z);\r
++//-----------------------------------------------------------------------------\r
++/// Create HMPR object for parsing MGL scripts\r
++HMPR MGL_EXPORT mgl_create_parser();\r
++uintptr_t MGL_EXPORT mgl_create_parser_();\r
++/// Change counter of HMPR uses (for advanced users only). Non-zero counter prevent automatic object removing.\r
++long MGL_EXPORT mgl_use_parser(HMPR p, int inc);\r
++long MGL_EXPORT mgl_use_parser_(uintptr_t* , int *inc);\r
++/// Delete HMPR object\r
++void MGL_EXPORT mgl_delete_parser(HMPR p);\r
++void MGL_EXPORT mgl_delete_parser_(uintptr_t* p);\r
++/// Set value for parameter $N\r
++void MGL_EXPORT mgl_parser_add_param(HMPR p, int id, const char *str);\r
++void MGL_EXPORT mgl_parser_add_param_(uintptr_t* p, int *id, const char *str, int);\r
++void MGL_EXPORT mgl_parser_add_paramw(HMPR p, int id, const wchar_t *str);\r
++\r
++/// Find variable with given name or add a new one\r
++/// NOTE !!! You must not delete obtained data arrays !!!\r
++MGL_EXPORT mglDataA *mgl_parser_add_var(HMPR p, const char *name);\r
++uintptr_t MGL_EXPORT mgl_parser_add_var_(uintptr_t* p, const char *name, int);\r
++MGL_EXPORT mglDataA *mgl_parser_add_varw(HMPR p, const wchar_t *name);\r
++/// Find variable with given name or return NULL if no one\r
++/// NOTE !!! You must not delete obtained data arrays !!!\r
++MGL_EXPORT mglDataA *mgl_parser_find_var(HMPR p, const char *name);\r
++uintptr_t MGL_EXPORT mgl_parser_find_var_(uintptr_t* p, const char *name, int);\r
++MGL_EXPORT mglDataA *mgl_parser_find_varw(HMPR p, const wchar_t *name);\r
++/// Get variable with given id\r
++/// NOTE !!! You must not delete obtained data arrays !!!\r
++MGL_EXPORT mglDataA *mgl_parser_get_var(HMPR p, unsigned long id);\r
++uintptr_t MGL_EXPORT mgl_parser_get_var_(uintptr_t* p, unsigned long *id);\r
++/// Get number of variables\r
++long MGL_EXPORT mgl_parser_num_var(HMPR p);\r
++long MGL_EXPORT mgl_parser_num_var_(uintptr_t* p);\r
++\r
++/// Get constant with given id\r
++/// NOTE !!! You must not delete obtained data arrays !!!\r
++MGL_EXPORT mglNum *mgl_parser_get_const(HMPR p, unsigned long id);\r
++uintptr_t MGL_EXPORT mgl_parser_get_const_(uintptr_t* p, unsigned long *id);\r
++/// Get number of constants\r
++long MGL_EXPORT mgl_parser_num_const(HMPR p);\r
++long MGL_EXPORT mgl_parser_num_const_(uintptr_t* p);\r
++\r
++/// Delete variable with name\r
++void MGL_EXPORT mgl_parser_del_var(HMPR p, const char *name);\r
++void MGL_EXPORT mgl_parser_del_var_(uintptr_t* p, const char *name, int);\r
++void MGL_EXPORT mgl_parser_del_varw(HMPR p, const wchar_t *name);\r
++/// Delete all data variables\r
++void MGL_EXPORT mgl_parser_del_all(HMPR p);\r
++void MGL_EXPORT mgl_parser_del_all_(uintptr_t *p);\r
++\r
++/// Load new commands from external dynamic Library (must have "const mglCommand *mgl_cmd_extra" variable)\r
++void MGL_EXPORT mgl_parser_load(HMPR pr, const char *dll_name);\r
++void MGL_EXPORT mgl_parser_load_(uintptr_t *pr, const char *dll_name,int);\r
++\r
++/// Apply one step for equation d vars[i]/dt = eqs[i] using Runge-Kutta method\r
++void MGL_EXPORT mgl_rk_step(HMPR pr, const char *eqs, const char *vars, mreal dt);\r
++void MGL_EXPORT mgl_rk_step_w(HMPR pr, const wchar_t *eqs, const wchar_t *vars, mreal dt);\r
++void MGL_EXPORT mgl_rk_step_(uintptr_t *p, const char *eqs, const char *vars, double *dt, int,int);\r
++\r
++// Open all data arrays from HDF file and assign it as variables of parser p\r
++void MGL_EXPORT mgl_parser_openhdf(HMPR p, const char *fname);\r
++void MGL_EXPORT mgl_parser_openhdf_(uintptr_t *p, const char *fname,int l);\r
++\r
++/// Parse and draw single line of the MGL script\r
++int MGL_EXPORT mgl_parse_line(HMGL gr, HMPR p, const char *str, int pos);\r
++int MGL_EXPORT mgl_parse_line_(uintptr_t* gr, uintptr_t* p, const char *str, int *pos, int);\r
++int MGL_EXPORT mgl_parse_linew(HMGL gr, HMPR p, const wchar_t *str, int pos);\r
++/// Execute and draw script from the file\r
++void MGL_EXPORT mgl_parse_file(HMGL gr, HMPR p, FILE *fp, int print);\r
++/// Execute MGL script text with '\n' separated lines\r
++void MGL_EXPORT mgl_parse_text(HMGL gr, HMPR p, const char *str);\r
++void MGL_EXPORT mgl_parse_text_(uintptr_t* gr, uintptr_t* p, const char *str, int);\r
++void MGL_EXPORT mgl_parse_textw(HMGL gr, HMPR p, const wchar_t *str);\r
++\r
++/// Restore once flag\r
++void MGL_EXPORT mgl_parser_restore_once(HMPR p);\r
++void MGL_EXPORT mgl_parser_restore_once_(uintptr_t* p);\r
++/// Allow changing size of the picture\r
++void MGL_EXPORT mgl_parser_allow_setsize(HMPR p, int a);\r
++void MGL_EXPORT mgl_parser_allow_setsize_(uintptr_t* p, int *a);\r
++/// Allow reading/saving files\r
++void MGL_EXPORT mgl_parser_allow_file_io(HMPR p, int a);\r
++void MGL_EXPORT mgl_parser_allow_file_io_(uintptr_t* p, int *a);\r
++/// Allow loading commands from external libraries\r
++void MGL_EXPORT mgl_parser_allow_dll_call(HMPR p, int a);\r
++void MGL_EXPORT mgl_parser_allow_dll_call_(uintptr_t* p, int *a);\r
++/// Set flag to stop script parsing\r
++void MGL_EXPORT mgl_parser_stop(HMPR p);\r
++void MGL_EXPORT mgl_parser_stop_(uintptr_t* p);\r
++/// Set variant of argument(s) separated by '?' to be used\r
++void MGL_EXPORT mgl_parser_variant(HMPR p, int var);\r
++void MGL_EXPORT mgl_parser_variant_(uintptr_t* p, int *var);\r
++<<<<<<< HEAD\r
++=======\r
++/// Set starting object ID\r
++void MGL_EXPORT mgl_parser_start_id(HMPR p, int id);\r
++void MGL_EXPORT mgl_parser_start_id_(uintptr_t* p, int *id);\r
++\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++\r
++/// Return type of command: 0 - not found, 1 - data plot, 2 - other plot,\r
++/// 3 - setup, 4 - data handle, 5 - data create, 6 - subplot, 7 - program\r
++/// 8 - 1d plot, 9 - 2d plot, 10 - 3d plot, 11 - dd plot, 12 - vector plot\r
++/// 13 - axis, 14 - primitives, 15 - axis setup, 16 - text/legend, 17 - data transform\r
++int MGL_EXPORT mgl_parser_cmd_type(HMPR pr, const char *name);\r
++int MGL_EXPORT mgl_parser_cmd_type_(uintptr_t* p, const char *name, int);\r
++/// Return description of MGL command\r
++MGL_EXPORT const char *mgl_parser_cmd_desc(HMPR pr, const char *name);\r
++/// Return string of command format (command name and its argument[s])\r
++MGL_EXPORT const char *mgl_parser_cmd_frmt(HMPR pr, const char *name);\r
++/// Get name of command with number n\r
++MGL_EXPORT const char *mgl_parser_cmd_name(HMPR pr, long id);\r
++/// Get number of defined commands\r
++long MGL_EXPORT mgl_parser_cmd_num(HMPR pr);\r
++\r
++/// Return result of formula evaluation\r
++HMDT MGL_EXPORT mgl_parser_calc(HMPR pr, const char *formula);\r
++uintptr_t MGL_EXPORT mgl_parser_calc_(uintptr_t *pr, const char *formula,int);\r
++HMDT MGL_EXPORT mgl_parser_calcw(HMPR pr, const wchar_t *formula);\r
++/// Return result of formula evaluation as complex data\r
++HADT MGL_EXPORT mgl_parser_calc_complex(HMPR pr, const char *formula);\r
++uintptr_t MGL_EXPORT mgl_parser_calc_complex_(uintptr_t *pr, const char *formula,int);\r
++HADT MGL_EXPORT mgl_parser_calc_complexw(HMPR pr, const wchar_t *formula);\r
++\r
++#ifdef __cplusplus\r
++}\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++#endif\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * data.h is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#ifndef _MGL_DATA_H_\r
++#define _MGL_DATA_H_\r
++\r
++#include "mgl2/data_cf.h"\r
++#include "mgl2/pde.h"\r
++//-----------------------------------------------------------------------------\r
++#include <stdarg.h>\r
++//-----------------------------------------------------------------------------\r
++mreal MGL_EXPORT mglLinear(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
++mreal MGL_EXPORT mglSpline3(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,mreal *dx=0, mreal *dy=0, mreal *dz=0);\r
++mreal MGL_EXPORT mglSpline3s(const mreal *a, long nx, long ny, long nz, mreal x, mreal y, mreal z);\r
++std::string MGL_EXPORT mgl_data_to_string(HCDT d, long ns);\r
++//-----------------------------------------------------------------------------\r
++/// Class for working with data array\r
++class MGL_EXPORT mglData : public mglDataA\r
++{\r
++public:\r
++using mglDataA::Momentum;\r
++ long nx; ///< number of points in 1st dimensions ('x' dimension)\r
++ long ny; ///< number of points in 2nd dimensions ('y' dimension)\r
++ long nz; ///< number of points in 3d dimensions ('z' dimension)\r
++ mreal *a; ///< data array\r
++ std::string id; ///< column (or slice) names\r
++ bool link; ///< use external data (i.e. don't free it)\r
++\r
++ /// Initiate by other mglData variable\r
++ mglData(const mglData &d) { a=0; mgl_data_set(this,&d); } // NOTE: must be constructor for mglData& to exclude copy one\r
++#if MGL_HAVE_RVAL\r
++ mglData(mglData &&d):nx(d.nx),ny(d.ny),nz(d.nz),a(d.a),id(d.id),link(d.link)\r
++ { s=d.s; temp=d.temp; func=d.func; o=d.o; d.a=0; d.func=0; }\r
++#endif\r
++ mglData(const mglDataA *d)\r
++ { a=0; if(d) mgl_data_set(this, d); else mgl_data_create(this,1,1,1); }\r
++ mglData(bool, mglData *d) // NOTE: Variable d will be deleted!!!\r
++ { if(d)\r
++ { nx=d->nx; ny=d->ny; nz=d->nz; a=d->a; d->a=0;\r
++ temp=d->temp; func=d->func; o=d->o; s=d->s;\r
++ id=d->id; link=d->link; delete d; }\r
++ else { a=0; Create(1); } }\r
++ /// Initiate by flat array\r
++ mglData(int size, const float *d) { a=0; Set(d,size); }\r
++ mglData(int rows, int cols, const float *d) { a=0; Set(d,cols,rows); }\r
++ mglData(int size, const double *d) { a=0; Set(d,size); }\r
++ mglData(int rows, int cols, const double *d) { a=0; Set(d,cols,rows); }\r
++ mglData(const double *d, int size) { a=0; Set(d,size); }\r
++ mglData(const double *d, int rows, int cols) { a=0; Set(d,cols,rows); }\r
++ mglData(const float *d, int size) { a=0; Set(d,size); }\r
++ mglData(const float *d, int rows, int cols) { a=0; Set(d,cols,rows); }\r
++ /// Allocate memory and copy data from std::vector<T>\r
++ mglData(const std::vector<int> &d) { a=0; Set(d); }\r
++ mglData(const std::vector<float> &d) { a=0; Set(d); }\r
++ mglData(const std::vector<double> &d) { a=0; Set(d); }\r
++ /// Read data from file\r
++ mglData(const char *fname) { a=0; Read(fname); }\r
++ /// Allocate the memory for data array and initialize it zero\r
++ mglData(long xx=1,long yy=1,long zz=1) { a=0; Create(xx,yy,zz); }\r
++ /// Delete the array\r
++ virtual ~mglData() { if(!link && a) delete []a; }\r
++\r
++ /// Move all data from variable d, and delete this variable.\r
++ inline void Move(mglData *d) // NOTE: Variable d will be deleted!!!\r
++ { if(d && d->GetNN()>1)\r
++ { bool l=link; mreal *b=a;\r
++ nx=d->nx; ny=d->ny; nz=d->nz; a=d->a; d->a=b;\r
++ temp=d->temp; func=d->func; o=d->o; s=d->s;\r
++ id=d->id; link=d->link; d->link=l; delete d; }\r
++ else if(d) { *this = d->a[0]; delete d; }\r
++ }\r
++\r
++ inline mreal GetVal(long i, long j=0, long k=0) const\r
++ { return mgl_data_get_value(this,i,j,k);}\r
++ inline void SetVal(mreal f, long i, long j=0, long k=0)\r
++ { mgl_data_set_value(this,f,i,j,k); }\r
++ /// Get sizes\r
++ long GetNx() const { return nx; }\r
++ long GetNy() const { return ny; }\r
++ long GetNz() const { return nz; }\r
++\r
++ /// Link external data array (don't delete it at exit)\r
++ inline void Link(mreal *A, long NX, long NY=1, long NZ=1)\r
++ { mgl_data_link(this,A,NX,NY,NZ); }\r
++ inline void Link(mglData &d) { Link(d.a,d.nx,d.ny,d.nz); }\r
++ /// Allocate memory and copy the data from the gsl_vector\r
++ inline void Set(gsl_vector *m) { mgl_data_set_vector(this,m); }\r
++ /// Allocate memory and copy the data from the gsl_matrix\r
++ inline void Set(gsl_matrix *m) { mgl_data_set_matrix(this,m); }\r
++\r
++ /// Allocate memory and copy the data from the (float *) array\r
++ inline void Set(const float *A,long NX,long NY=1,long NZ=1)\r
++ { mgl_data_set_float(this,A,NX,NY,NZ); }\r
++ /// Allocate memory and copy the data from the (double *) array\r
++ inline void Set(const double *A,long NX,long NY=1,long NZ=1)\r
++ { mgl_data_set_double(this,A,NX,NY,NZ); }\r
++ /// Allocate memory and copy the data from the (float **) array\r
++ inline void Set(float const * const *A,long N1,long N2)\r
++ { mgl_data_set_float2(this,A,N1,N2); }\r
++ /// Allocate memory and copy the data from the (double **) array\r
++ inline void Set(double const * const *A,long N1,long N2)\r
++ { mgl_data_set_double2(this,A,N1,N2); }\r
++ /// Allocate memory and copy the data from the (float ***) array\r
++ inline void Set(float const * const * const *A,long N1,long N2,long N3)\r
++ { mgl_data_set_float3(this,A,N1,N2,N3); }\r
++ /// Allocate memory and copy the data from the (double ***) array\r
++ inline void Set(double const * const * const *A,long N1,long N2,long N3)\r
++ { mgl_data_set_double3(this,A,N1,N2,N3); }\r
++ /// Allocate memory and scanf the data from the string\r
++ inline void Set(const char *str,long NX,long NY=1,long NZ=1)\r
++ { mgl_data_set_values(this,str,NX,NY,NZ); }\r
++ /// Import data from abstract type\r
++ inline void Set(HCDT dat) { mgl_data_set(this, dat); }\r
++ inline void Set(const mglDataA &dat) { mgl_data_set(this, &dat); }\r
++ /// Allocate memory and copy data from std::vector<T>\r
++ inline void Set(const std::vector<int> &d)\r
++ { if(d.size()>0) { Create(d.size()); for(long i=0;i<nx;i++) a[i] = d[i]; }\r
++ else Create(1); }\r
++ inline void Set(const std::vector<float> &d)\r
++ { if(d.size()>0) Set(&(d[0]),d.size()); else Create(1); }\r
++ inline void Set(const std::vector<double> &d)\r
++ { if(d.size()>0) Set(&(d[0]),d.size()); else Create(1); }\r
++ /// Allocate memory and set data from variable argument list of double values\r
++ inline void SetList(long n, ...)\r
++ {\r
++ if(n<1) return;\r
++ mgl_data_create(this,n,1,1);\r
++ va_list vl; va_start(vl,n);\r
++ for(long i=0;i<n;i++) a[i] = va_arg(vl,double);\r
++ va_end(vl);\r
++ }\r
++\r
++ /// Create or recreate the array with specified size and fill it by zero\r
++ inline void Create(long mx,long my=1,long mz=1)\r
++ { mgl_data_create(this,mx,my,mz); }\r
++ /// Rearange data dimensions\r
++ inline void Rearrange(long mx, long my=0, long mz=0)\r
++ { mgl_data_rearrange(this,mx,my,mz); }\r
++ /// Transpose dimensions of the data (generalization of Transpose)\r
++ inline void Transpose(const char *dim="yx")\r
++ { mgl_data_transpose(this,dim); }\r
++ /// Extend data dimensions\r
++ inline void Extend(long n1, long n2=0)\r
++ { mgl_data_extend(this,n1,n2); }\r
++ /// Reduce size of the data\r
++ inline void Squeeze(long rx,long ry=1,long rz=1,bool smooth=false)\r
++ { mgl_data_squeeze(this,rx,ry,rz,smooth); }\r
++ /// Crop the data\r
++ inline void Crop(long n1, long n2,char dir='x')\r
++ { mgl_data_crop(this,n1,n2,dir); }\r
++ /// Crop the data to be most optimal for FFT (i.e. to closest value of 2^n*3^m*5^l)\r
++ inline void Crop(const char *how="235x")\r
++ { mgl_data_crop_opt(this, how); }\r
++ /// Insert data rows/columns/slices\r
++ inline void Insert(char dir, long at=0, long num=1)\r
++ { mgl_data_insert(this,dir,at,num); }\r
++ /// Delete data rows/columns/slices\r
++ inline void Delete(char dir, long at=0, long num=1)\r
++ { mgl_data_delete(this,dir,at,num); }\r
++ /// Remove rows with duplicate values in column clmn\r
++ inline void Clean(long clmn)\r
++ { mgl_data_clean(this,clmn); }\r
++ /// Join with another data array\r
++ inline void Join(const mglDataA &d)\r
++ { mgl_data_join(this,&d); }\r
++\r
++ /// Modify the data by specified formula\r
++ inline void Modify(const char *eq,long dim=0)\r
++ { mgl_data_modify(this, eq, dim); }\r
++ /// Modify the data by specified formula\r
++ inline void Modify(const char *eq,const mglDataA &vdat, const mglDataA &wdat)\r
++ { mgl_data_modify_vw(this,eq,&vdat,&wdat); }\r
++ /// Modify the data by specified formula\r
++ inline void Modify(const char *eq,const mglDataA &vdat)\r
++ { mgl_data_modify_vw(this,eq,&vdat,0); }\r
++ /// Modify the data by specified formula assuming x,y,z in range [r1,r2]\r
++ inline void Fill(HMGL gr, const char *eq, const char *opt="")\r
++ { mgl_data_fill_eq(gr,this,eq,0,0,opt); }\r
++ inline void Fill(HMGL gr, const char *eq, const mglDataA &vdat, const char *opt="")\r
++ { mgl_data_fill_eq(gr,this,eq,&vdat,0,opt); }\r
++ inline void Fill(HMGL gr, const char *eq, const mglDataA &vdat, const mglDataA &wdat,const char *opt="")\r
++ { mgl_data_fill_eq(gr,this,eq,&vdat,&wdat,opt); }\r
++ /// Equidistantly fill the data to range [x1,x2] in direction dir\r
++ inline void Fill(mreal x1,mreal x2=mglNaN,char dir='x')\r
++ { mgl_data_fill(this,x1,x2,dir); }\r
++ /// Fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in range [p1,p2] using global spline\r
++ inline void RefillGS(const mglDataA &xdat, const mglDataA &vdat, mreal x1, mreal x2,long sl=-1)\r
++ { mgl_data_refill_gs(this,&xdat,&vdat,x1,x2,sl); }\r
++ /// Fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in range [p1,p2]\r
++ inline void Refill(const mglDataA &xdat, const mglDataA &vdat, mreal x1, mreal x2,long sl=-1)\r
++ { mgl_data_refill_x(this,&xdat,&vdat,x1,x2,sl); }\r
++ inline void Refill(const mglDataA &xdat, const mglDataA &vdat, mglPoint p1, mglPoint p2,long sl=-1)\r
++ { mgl_data_refill_x(this,&xdat,&vdat,p1.x,p2.x,sl); }\r
++ inline void Refill(const mglDataA &xdat, const mglDataA &ydat, const mglDataA &vdat, mglPoint p1, mglPoint p2,long sl=-1)\r
++ { mgl_data_refill_xy(this,&xdat,&ydat,&vdat,p1.x,p2.x,p1.y,p2.y,sl); }\r
++ inline void Refill(const mglDataA &xdat, const mglDataA &ydat, const mglDataA &zdat, const mglDataA &vdat, mglPoint p1, mglPoint p2)\r
++ { mgl_data_refill_xyz(this,&xdat,&ydat,&zdat,&vdat,p1.x,p2.x,p1.y,p2.y,p1.z,p2.z); }\r
++ /// Fill the data by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range of gr\r
++ inline void Refill(HMGL gr, const mglDataA &xdat, const mglDataA &vdat, long sl=-1, const char *opt="")\r
++ { mgl_data_refill_gr(gr,this,&xdat,0,0,&vdat,sl,opt); }\r
++ inline void Refill(HMGL gr, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &vdat, long sl=-1, const char *opt="")\r
++ { mgl_data_refill_gr(gr,this,&xdat,&ydat,0,&vdat,sl,opt); }\r
++ inline void Refill(HMGL gr, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &zdat, const mglDataA &vdat, const char *opt="")\r
++ { mgl_data_refill_gr(gr,this,&xdat,&ydat,&zdat,&vdat,-1,opt); }\r
++ /// Set the data by triangulated surface values assuming x,y,z in axis range of gr\r
++ inline void Grid(HMGL gr, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *opt="")\r
++ { mgl_data_grid(gr,this,&x,&y,&z,opt); }\r
++ /// Set the data by triangulated surface values assuming x,y,z in range [p1, p2]\r
++ inline void Grid(const mglDataA &xdat, const mglDataA &ydat, const mglDataA &vdat, mglPoint p1, mglPoint p2)\r
++ { mgl_data_grid_xy(this,&xdat,&ydat,&vdat,p1.x,p2.x,p1.y,p2.y); }\r
++ /// Put value to data element(s)\r
++ inline void Put(mreal val, long i=-1, long j=-1, long k=-1)\r
++ { mgl_data_put_val(this,val,i,j,k); }\r
++ /// Put array to data element(s)\r
++ inline void Put(const mglDataA &dat, long i=-1, long j=-1, long k=-1)\r
++ { mgl_data_put_dat(this,&dat,i,j,k); }\r
++ /// Set names for columns (slices)\r
++ inline void SetColumnId(const char *ids)\r
++ { mgl_data_set_id(this,ids); }\r
++ /// Make new id\r
++ inline void NewId() { id.clear(); }\r
++\r
++ /// Read data from tab-separated text file with auto determining size\r
++ inline bool Read(const char *fname)\r
++ { return mgl_data_read(this,fname); }\r
++ /// Read data from text file with specifeid size\r
++ inline bool Read(const char *fname,long mx,long my=1,long mz=1)\r
++ { return mgl_data_read_dim(this,fname,mx,my,mz); }\r
++ /// Import data array from PNG file according color scheme\r
++ inline void Import(const char *fname,const char *scheme,mreal v1=0,mreal v2=1)\r
++ { mgl_data_import(this,fname,scheme,v1,v2); }\r
++ /// Read data from tab-separated text files with auto determining size which filenames are result of sprintf(fname,templ,t) where t=from:step:to\r
++ inline bool ReadRange(const char *templ, double from, double to, double step=1, bool as_slice=false)\r
++ { return mgl_data_read_range(this,templ,from,to,step,as_slice); }\r
++ /// Read data from tab-separated text files with auto determining size which filenames are satisfied to template (like "t_*.dat")\r
++ inline bool ReadAll(const char *templ, bool as_slice=false)\r
++ { return mgl_data_read_all(this, templ, as_slice); }\r
++ /// Read data from text file with size specified at beginning of the file\r
++ inline bool ReadMat(const char *fname, long dim=2)\r
++ { return mgl_data_read_mat(this,fname,dim); }\r
++ /// Read data array from HDF file (parse HDF4 and HDF5 files)\r
++ inline int ReadHDF(const char *fname,const char *data)\r
++ { return mgl_data_read_hdf(this,fname,data); }\r
++ /// Scan textual file for template and fill data array\r
++ inline int ScanFile(const char *fname, const char *templ)\r
++ { return mgl_data_scan_file(this,fname, templ); }\r
++\r
++\r
++ /// Get column (or slice) of the data filled by formulas of named columns\r
++ inline mglData Column(const char *eq) const\r
++ { return mglData(true,mgl_data_column(this,eq)); }\r
++ /// Get momentum (1D-array) of data along direction 'dir'. String looks like "x1" for median in x-direction, "x2" for width in x-dir and so on.\r
++ inline mglData Momentum(char dir, const char *how) const\r
++ { return mglData(true,mgl_data_momentum(this,dir,how)); }\r
++ /// Get pulse properties: pulse maximum and its position, pulse duration near maximum and by half height, energy in first pulse.\r
++ inline mglData Pulse(char dir) const\r
++ { return mglData(true,mgl_data_pulse(this,dir)); }\r
++ /// Get sub-array of the data with given fixed indexes\r
++ inline mglData SubData(long xx,long yy=-1,long zz=-1) const\r
++ { return mglData(true,mgl_data_subdata(this,xx,yy,zz)); }\r
++ inline mglData SubData(const mglDataA &xx, const mglDataA &yy, const mglDataA &zz) const\r
++ { return mglData(true,mgl_data_subdata_ext(this,&xx,&yy,&zz)); }\r
++ inline mglData SubData(const mglDataA &xx, const mglDataA &yy) const\r
++ { return mglData(true,mgl_data_subdata_ext(this,&xx,&yy,0)); }\r
++ inline mglData SubData(const mglDataA &xx) const\r
++ { return mglData(true,mgl_data_subdata_ext(this,&xx,0,0)); }\r
++ /// Get data from sections ids, separated by value val along specified direction.\r
++ /** If section id is negative then reverse order is used (i.e. -1 give last section). */\r
++ inline mglData Section(const mglDataA &ids, char dir='y', mreal val=NAN) const\r
++ { return mglData(true,mgl_data_section(this,&ids,dir,val)); }\r
++ inline mglData Section(long id, char dir='y', mreal val=NAN) const\r
++ { return mglData(true,mgl_data_section_val(this,id,dir,val)); }\r
++\r
++ /// Get trace of the data array\r
++ inline mglData Trace() const\r
++ { return mglData(true,mgl_data_trace(this)); }\r
++ /// Create n-th points distribution of this data values in range [v1, v2]\r
++ inline mglData Hist(long n,mreal v1=0,mreal v2=1, long nsub=0) const\r
++ { return mglData(true,mgl_data_hist(this,n,v1,v2,nsub)); }\r
++ /// Create n-th points distribution of this data values in range [v1, v2] with weight w\r
++ inline mglData Hist(const mglDataA &w, long n,mreal v1=0,mreal v2=1, long nsub=0) const\r
++ { return mglData(true,mgl_data_hist_w(this,&w,n,v1,v2,nsub)); }\r
++ /// Get array which is result of summation in given direction or directions\r
++ inline mglData Sum(const char *dir) const\r
++ { return mglData(true,mgl_data_sum(this,dir)); }\r
++ /// Get array which is result of maximal values in given direction or directions\r
++ inline mglData Max(const char *dir) const\r
++ { return mglData(true,mgl_data_max_dir(this,dir)); }\r
++ /// Get array which is result of minimal values in given direction or directions\r
++ inline mglData Min(const char *dir) const\r
++ { return mglData(true,mgl_data_min_dir(this,dir)); }\r
++ /// Get the data which is direct multiplication (like, d[i,j] = this[i]*a[j] and so on)\r
++ inline mglData Combine(const mglDataA &dat) const\r
++ { return mglData(true,mgl_data_combine(this,&dat)); }\r
++ /// Resize the data to new size of box [x1,x2]*[y1,y2]*[z1,z2]\r
++ inline mglData Resize(long mx,long my=0,long mz=0, mreal x1=0,mreal x2=1, mreal y1=0,mreal y2=1, mreal z1=0,mreal z2=1) const\r
++ { return mglData(true,mgl_data_resize_box(this,mx,my,mz,x1,x2,y1,y2,z1,z2)); }\r
++ /// Get array which values is result of interpolation this for coordinates from other arrays\r
++ inline mglData Evaluate(const mglData &idat, bool norm=true) const\r
++ { return mglData(true,mgl_data_evaluate(this,&idat,0,0,norm)); }\r
++ inline mglData Evaluate(const mglData &idat, const mglData &jdat, bool norm=true) const\r
++ { return mglData(true,mgl_data_evaluate(this,&idat,&jdat,0,norm)); }\r
++ inline mglData Evaluate(const mglData &idat, const mglData &jdat, const mglData &kdat, bool norm=true) const\r
++ { return mglData(true,mgl_data_evaluate(this,&idat,&jdat,&kdat,norm)); }\r
++ /// Find roots for set of nonlinear equations defined by textual formula\r
++ inline mglData Roots(const char *eq, char var='x') const\r
++ { return mglData(true,mgl_data_roots(eq, this, var)); }\r
++ /// Find correlation with another data arrays\r
++ inline mglData Correl(const mglDataA &dat, const char *dir) const\r
++ { return mglData(true,mgl_data_correl(this,&dat,dir)); }\r
++ /// Find auto correlation function\r
++ inline mglData AutoCorrel(const char *dir) const\r
++ { return mglData(true,mgl_data_correl(this,this,dir)); }\r
++ /// Get curves, separated by NAN, for maximal values of array d as function of x coordinate.\r
++ /** Noises below lvl amplitude are ignored.\r
++ * Parameter dy \in [0,ny] set the "attraction" distance of points to curve. */\r
++ inline mglData Detect(mreal lvl, mreal dj, mreal di=0, mreal min_len=0) const\r
++ { return mglData(true,mgl_data_detect(this,lvl,dj,di,min_len)); }\r
++\r
++ /// Cumulative summation the data in given direction or directions\r
++ inline void CumSum(const char *dir) { mgl_data_cumsum(this,dir); }\r
++ /// Integrate (cumulative summation) the data in given direction or directions\r
++ inline void Integral(const char *dir) { mgl_data_integral(this,dir); }\r
++ /// Differentiate the data in given direction or directions\r
++ inline void Diff(const char *dir) { mgl_data_diff(this,dir); }\r
++ /// Differentiate the parametrically specified data along direction v1\r
++ inline void Diff(const mglDataA &v1)\r
++ { mgl_data_diff_par(this,&v1,0,0); }\r
++ /// Differentiate the parametrically specified data along direction v1 with v2=const\r
++ inline void Diff(const mglDataA &v1, const mglDataA &v2)\r
++ { mgl_data_diff_par(this,&v1,&v2,0); }\r
++ /// Differentiate the parametrically specified data along direction v1 with v2,v3=const\r
++ inline void Diff(const mglDataA &v1, const mglDataA &v2, const mglDataA &v3)\r
++ { mgl_data_diff_par(this,&v1,&v2,&v3); }\r
++ /// Double-differentiate (like Laplace operator) the data in given direction\r
++ inline void Diff2(const char *dir) { mgl_data_diff2(this,dir); }\r
++\r
++ /// Swap left and right part of the data in given direction (useful for Fourier spectrum)\r
++ inline void Swap(const char *dir) { mgl_data_swap(this,dir); }\r
++ /// Roll data along direction dir by num slices\r
++ inline void Roll(char dir, long num) { mgl_data_roll(this,dir,num); }\r
++ /// Mirror the data in given direction (useful for Fourier spectrum)\r
++ inline void Mirror(const char *dir) { mgl_data_mirror(this,dir); }\r
++ /// Sort rows (or slices) by values of specified column\r
++ inline void Sort(long idx, long idy=-1) { mgl_data_sort(this,idx,idy); }\r
++ /// Return dilated array of 0 or 1 for data values larger val\r
++ inline void Dilate(mreal val=1, long step=1)\r
++ { mgl_data_dilate(this, val, step); }\r
++ /// Return eroded array of 0 or 1 for data values larger val\r
++ inline void Erode(mreal val=1, long step=1)\r
++ { mgl_data_erode(this, val, step); }\r
++\r
++ /// Set as the data envelop\r
++ inline void Envelop(char dir='x')\r
++ { mgl_data_envelop(this,dir); }\r
++ /// Remove phase jump\r
++ inline void Sew(const char *dirs="xyz", mreal da=2*mglPi)\r
++ { mgl_data_sew(this,dirs,da); }\r
++ /// Smooth the data on specified direction or directions\r
++ /** String \a dir may contain:\r
++ * ‘x’, ‘y’, ‘z’ for 1st, 2nd or 3d dimension;\r
++ * ‘dN’ for linear averaging over N points;\r
++ * ‘3’ for linear averaging over 3 points;\r
++ * ‘5’ for linear averaging over 5 points.\r
++ * By default quadratic averaging over 5 points is used. */\r
++ inline void Smooth(const char *dirs="xyz",mreal delta=0)\r
++ { mgl_data_smooth(this,dirs,delta); }\r
++ /// Normalize the data to range [v1,v2]\r
++ inline void Norm(mreal v1=0,mreal v2=1,bool sym=false,long dim=0)\r
++ { mgl_data_norm(this,v1,v2,sym,dim); }\r
++ /// Normalize the data to range [v1,v2] slice by slice\r
++ inline void NormSl(mreal v1=0,mreal v2=1,char dir='z',bool keep_en=true,bool sym=false)\r
++ { mgl_data_norm_slice(this,v1,v2,dir,keep_en,sym); }\r
++ /// Limit the data to be inside [-v,v], keeping the original sign\r
++ inline void Limit(mreal v)\r
++ { mgl_data_limit(this, v); }\r
++\r
++ /// Apply Hankel transform\r
++ inline void Hankel(const char *dir) { mgl_data_hankel(this,dir); }\r
++ /// Apply Sin-Fourier transform\r
++ inline void SinFFT(const char *dir) { mgl_data_sinfft(this,dir); }\r
++ /// Apply Cos-Fourier transform\r
++ inline void CosFFT(const char *dir) { mgl_data_cosfft(this,dir); }\r
++ /// Fill data by coordinates/momenta samples for Hankel ('h') or Fourier ('f') transform\r
++ /** Parameter \a how may contain:\r
++ * ‘x‘,‘y‘,‘z‘ for direction (only one will be used),\r
++ * ‘k‘ for momenta samples,\r
++ * ‘h‘ for Hankel samples,\r
++ * ‘f‘ for Cartesian/Fourier samples (default). */\r
++ inline void FillSample(const char *how)\r
++ { mgl_data_fill_sample(this,how); }\r
++ /// Apply wavelet transform\r
++ /** Parameter \a dir may contain:\r
++ * ‘x‘,‘y‘,‘z‘ for directions,\r
++ * ‘d‘ for daubechies, ‘D‘ for centered daubechies,\r
++ * ‘h‘ for haar, ‘H‘ for centered haar,\r
++ * ‘b‘ for bspline, ‘B‘ for centered bspline,\r
++ * ‘i‘ for applying inverse transform. */\r
++ inline void Wavelet(const char *how, int k) { mgl_data_wavelet(this, how, k); }\r
++\r
++ /// Return an approximated x-value (root) when dat(x) = val\r
++ inline mreal Solve(mreal val, bool use_spline=true, long i0=0) const\r
++ { return mgl_data_solve_1d(this, val, use_spline, i0); }\r
++ /// Return an approximated value (root) when dat(x) = val\r
++ inline mglData Solve(mreal val, char dir, bool norm=true) const\r
++ { return mglData(true,mgl_data_solve(this, val, dir, 0, norm)); }\r
++ inline mglData Solve(mreal val, char dir, const mglData &i0, bool norm=true) const\r
++ { return mglData(true,mgl_data_solve(this, val, dir, &i0, norm)); }\r
++\r
++ /// Copy data from other mglData variable\r
++ inline const mglDataA &operator=(const mglDataA &d)\r
++ { if(this!=&d) mgl_data_set(this,&d); return d; }\r
++ inline const mglData &operator=(const mglData &d)\r
++ { if(this!=&d) mgl_data_set(this,&d); return d; }\r
++ inline mreal operator=(mreal val)\r
++ { mgl_data_fill(this,val,val,'x'); return val; }\r
++ /// Multiply the data by other one for each element\r
++ inline void operator*=(const mglDataA &d) { mgl_data_mul_dat(this,&d); }\r
++ /// Divide the data by other one for each element\r
++ inline void operator/=(const mglDataA &d) { mgl_data_div_dat(this,&d); }\r
++ /// Add the other data\r
++ inline void operator+=(const mglDataA &d) { mgl_data_add_dat(this,&d); }\r
++ /// Subtract the other data\r
++ inline void operator-=(const mglDataA &d) { mgl_data_sub_dat(this,&d); }\r
++ /// Multiply each element by the number\r
++ inline void operator*=(mreal d) { mgl_data_mul_num(this,d); }\r
++ /// Divide each element by the number\r
++ inline void operator/=(mreal d) { mgl_data_div_num(this,d); }\r
++ /// Add the number\r
++ inline void operator+=(mreal d) { mgl_data_add_num(this,d); }\r
++ /// Subtract the number\r
++ inline void operator-=(mreal d) { mgl_data_sub_num(this,d); }\r
++#ifndef SWIG\r
++ /// Direct access to the data cell\r
++ inline mreal &operator[](long i) { return a[i]; }\r
++ // NOTE see 13.10 for operator(), operator[] -- m.b. I should add it ???\r
++#endif\r
++\r
++#ifndef DEBUG\r
++ /// Get the value in given cell of the data\r
++ mreal v(long i,long j=0,long k=0) const { return a[i+nx*(j+ny*k)]; }\r
++ /// Set the value in given cell of the data\r
++ void set_v(mreal val, long i,long j=0,long k=0) { a[i+nx*(j+ny*k)]=val; }\r
++#else\r
++ /// Get the value in given cell of the data with border checking\r
++ mreal v(long i,long j=0,long k=0) const { return mgl_data_get_value(this,i,j,k); }\r
++ /// Set the value in given cell of the data\r
++ void set_v(mreal val, long i,long j=0,long k=0) { mgl_data_set_value(this,val,i,j,k); }\r
++#endif\r
++ /// Get the interpolated value and its derivatives in given data cell without border checking\r
++ mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
++ { return mglSpline3(a,nx,ny,nz,x,y,z,dx,dy,dz); }\r
++ /// Get the interpolated value in given data cell without border checking\r
++ mreal value(mreal x,mreal y=0,mreal z=0) const\r
++ { return mglSpline3s(a,nx,ny,nz,x,y,z); }\r
++ mreal vthr(long i) const { return a[i]; }\r
++ // add for speeding up !!!\r
++ mreal dvx(long i,long j=0,long k=0) const\r
++ { long i0=i+nx*(j+ny*k);\r
++ return i>0? (i<nx-1? (a[i0+1]-a[i0-1])/2:a[i0]-a[i0-1]) : a[i0+1]-a[i0]; }\r
++ mreal dvy(long i,long j=0,long k=0) const\r
++ { long i0=i+nx*(j+ny*k);\r
++ return j>0? (j<ny-1? (a[i0+nx]-a[i0-nx])/2:a[i0]-a[i0-nx]) : a[i0+nx]-a[i0];}\r
++ mreal dvz(long i,long j=0,long k=0) const\r
++ { long i0=i+nx*(j+ny*k), n=nx*ny;\r
++ return k>0? (k<nz-1? (a[i0+n]-a[i0-n])/2:a[i0]-a[i0-n]) : a[i0+n]-a[i0]; }\r
++};\r
++//-----------------------------------------------------------------------------\r
++#ifndef SWIG\r
++inline mglData operator*(const mglDataA &b, const mglDataA &d)\r
++{ mglData a(&b); a*=d; return a; }\r
++inline mglData operator*(mreal b, const mglDataA &d)\r
++{ mglData a(&d); a*=b; return a; }\r
++inline mglData operator*(const mglDataA &d, mreal b)\r
++{ mglData a(&d); a*=b; return a; }\r
++inline mglData operator-(const mglDataA &b, const mglDataA &d)\r
++{ mglData a(&b); a-=d; return a; }\r
++inline mglData operator-(mreal b, const mglDataA &d)\r
++{ mglData a(&d); a-=b; return a; }\r
++inline mglData operator-(const mglDataA &d, mreal b)\r
++{ mglData a(&d); a-=b; return a; }\r
++inline mglData operator+(const mglDataA &b, const mglDataA &d)\r
++{ mglData a(&b); a+=d; return a; }\r
++inline mglData operator+(mreal b, const mglDataA &d)\r
++{ mglData a(&d); a+=b; return a; }\r
++inline mglData operator+(const mglDataA &d, mreal b)\r
++{ mglData a(&d); a+=b; return a; }\r
++inline mglData operator/(const mglDataA &b, const mglDataA &d)\r
++{ mglData a(&b); a/=d; return a; }\r
++inline mglData operator/(const mglDataA &d, mreal b)\r
++{ mglData a(&d); a/=b; return a; }\r
++inline bool operator==(const mglData &b, const mglData &d)\r
++{ if(b.nx!=d.nx || b.ny!=d.ny || b.nz!=d.nz) return false;\r
++ return !memcmp(b.a,d.a,b.nx*b.ny*b.nz*sizeof(mreal)); }\r
++inline bool operator<(const mglDataA &b, const mglDataA &d)\r
++{ return b.Maximal()<d.Maximal(); }\r
++inline bool operator>(const mglDataA &b, const mglDataA &d)\r
++{ return b.Minimal()>d.Minimal(); }\r
++//-----------------------------------------------------------------------------\r
++/// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for amplitude and phase\r
++inline mglData mglTransformA(const mglDataA &am, const mglDataA &ph, const char *tr)\r
++{ return mglData(true,mgl_transform_a(&am,&ph,tr)); }\r
++/// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for real and imaginary parts\r
++inline mglData mglTransform(const mglDataA &re, const mglDataA &im, const char *tr)\r
++{ return mglData(true,mgl_transform(&re,&im,tr)); }\r
++/// Apply Fourier transform for the data and save result into it\r
++inline void mglFourier(mglData &re, mglData &im, const char *dir)\r
++{ mgl_data_fourier(&re,&im,dir); }\r
++/// Short time Fourier analysis for real and imaginary parts. Output is amplitude of partial Fourier (result will have size {dn, floor(nx/dn), ny} for dir='x'\r
++inline mglData mglSTFA(const mglDataA &re, const mglDataA &im, long dn, char dir='x')\r
++{ return mglData(true, mgl_data_stfa(&re,&im,dn,dir)); }\r
++//-----------------------------------------------------------------------------\r
++/// Saves result of PDE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini\r
++inline mglData mglPDE(HMGL gr, const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, mreal dz=0.1, mreal k0=100,const char *opt="")\r
++{ return mglData(true, mgl_pde_solve(gr,ham, &ini_re, &ini_im, dz, k0,opt)); }\r
++/// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau)\r
++inline mglData mglQO2d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mreal r=1, mreal k0=100)\r
++{ return mglData(true, mgl_qo2d_solve(ham, &ini_re, &ini_im, &ray, r, k0, 0, 0)); }\r
++inline mglData mglQO2d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mglData &xx, mglData &yy, mreal r=1, mreal k0=100)\r
++{ return mglData(true, mgl_qo2d_solve(ham, &ini_re, &ini_im, &ray, r, k0, &xx, &yy)); }\r
++/// Saves result of PDE solving for "Hamiltonian" ham with initial conditions ini along a curve ray (must have nx>=7 - x,y,z,px,py,pz,tau or nx=5 - x,y,px,py,tau)\r
++inline mglData mglQO3d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mreal r=1, mreal k0=100)\r
++{ return mglData(true, mgl_qo3d_solve(ham, &ini_re, &ini_im, &ray, r, k0, 0, 0, 0)); }\r
++inline mglData mglQO3d(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mglData &xx, mglData &yy, mglData &zz, mreal r=1, mreal k0=100)\r
++{ return mglData(true, mgl_qo3d_solve(ham, &ini_re, &ini_im, &ray, r, k0, &xx, &yy, &zz)); }\r
++/// Finds ray with starting point r0, p0 (and prepares ray data for mglQO2d)\r
++inline mglData mglRay(const char *ham, mglPoint r0, mglPoint p0, mreal dt=0.1, mreal tmax=10)\r
++{ return mglData(true, mgl_ray_trace(ham, r0.x, r0.y, r0.z, p0.x, p0.y, p0.z, dt, tmax)); }\r
++<<<<<<< HEAD\r
++/// Saves result of ODE solving (|u|^2) for "Hamiltonian" ham with initial conditions ini\r
++inline mglData mglODE(const char *df, const char *var, const mglDataA &ini, mreal dt=0.1, mreal tmax=10)\r
++{ return mglData(true, mgl_ode_solve_str(df,var, &ini, dt, tmax)); }\r
++=======\r
++/// Saves result of ODE solving for var complex variables with right part func (separated by ';') and initial conditions x0 over time interval [0,tmax] with time step dt\r
++inline mglData mglODE(const char *func, const char *var, const mglDataA &ini, mreal dt=0.1, mreal tmax=10)\r
++{ return mglData(true, mgl_ode_solve_str(func,var, &ini, dt, tmax)); }\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++//-----------------------------------------------------------------------------\r
++/// Get array as solution of tridiagonal system of equations a[i]*x[i-1]+b[i]*x[i]+c[i]*x[i+1]=d[i]\r
++/** String \a how may contain:\r
++ * 'x', 'y', 'z' for solving along x-,y-,z-directions, or\r
++ * 'h' for solving along hexagonal direction at x-y plain (need nx=ny),\r
++ * 'c' for using periodical boundary conditions,\r
++ * 'd' for diffraction/diffuse calculation. */\r
++inline mglData mglTridMat(const mglDataA &A, const mglDataA &B, const mglDataA &C, const mglDataA &D, const char *how)\r
++{ return mglData(true, mgl_data_tridmat(&A, &B, &C, &D, how)); }\r
++//-----------------------------------------------------------------------------\r
++/// Calculate Jacobian determinant for D{x(u,v), y(u,v)} = dx/du*dy/dv-dx/dv*dy/du\r
++inline mglData mglJacobian(const mglDataA &x, const mglDataA &y)\r
++{ return mglData(true, mgl_jacobian_2d(&x, &y)); }\r
++/// Calculate Jacobian determinant for D{x(u,v,w), y(u,v,w), z(u,v,w)}\r
++inline mglData mglJacobian(const mglDataA &x, const mglDataA &y, const mglDataA &z)\r
++{ return mglData(true, mgl_jacobian_3d(&x, &y, &z)); }\r
++/// Do something like Delone triangulation\r
++inline mglData mglTriangulation(const mglDataA &x, const mglDataA &y, const mglDataA &z)\r
++{ return mglData(true,mgl_triangulation_3d(&x,&y,&z)); }\r
++inline mglData mglTriangulation(const mglDataA &x, const mglDataA &y)\r
++{ return mglData(true,mgl_triangulation_2d(&x,&y)); }\r
++/// Get curves, separated by NAN, for maximal values of array d as function of x coordinate.\r
++/** Noises below lvl amplitude are ignored.\r
++ * Parameter dy \in [0,ny] set the "attraction" distance of points to curve. */\r
++inline mglData mglDetect(const mglDataA &d, mreal lvl, mreal dj, mreal di=0, mreal min_len=0)\r
++{ return mglData(true,mgl_data_detect(&d, lvl, dj, di, min_len)); }\r
++//-----------------------------------------------------------------------------\r
++/// Get array which is n-th pairs {x[i],y[i]} for iterated function system (fractal) generated by A\r
++inline mglData mglIFS2d(const mglDataA &A, long n, long skip=20)\r
++{ return mglData(true,mgl_data_ifs_2d(&A,n,skip)); }\r
++/// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) generated by A\r
++inline mglData mglIFS3d(const mglDataA &A, long n, long skip=20)\r
++{ return mglData(true,mgl_data_ifs_3d(&A,n,skip)); }\r
++/// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) defined in *.ifs file 'fname' and named as 'name'\r
++inline mglData mglIFSfile(const char *fname, const char *name, long n, long skip=20)\r
++{ return mglData(true,mgl_data_ifs_file(fname,name,n,skip)); }\r
++<<<<<<< HEAD\r
++/// Get array which is n-th pairs {x[i],y[i]} for flame fractal generated by A with functions F\r
++=======\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++/// Get array which is n-th pairs {x[i],y[i]} for Flame fractal generated by A with functions F\r
++/** NOTE: A.nx must be >= 7 and F.nx >= 2 and F.nz=A.ny.\r
++ * F[0,i,j] denote function id. F[1,i,j] give function weight, F(2:5,i,j) provide function parameters.\r
++ * Resulting point is {xnew,ynew} = sum_i F[1,i,j]*F[0,i,j]{IFS2d(A[j]){x,y}}. */\r
++inline mglData mglFlame2d(const mglDataA &A, const mglDataA &F, long n, long skip=20)\r
++{ return mglData(true,mgl_data_flame_2d(&A,&F,n,skip)); }\r
++//-----------------------------------------------------------------------------\r
++/// Get sub-array of the data with given fixed indexes\r
++inline mglData mglSubData(const mglDataA &dat, long xx, long yy=-1, long zz=-1)\r
++{ return mglData(true,mgl_data_subdata(&dat,xx,yy,zz)); }\r
++inline mglData mglSubData(const mglDataA &dat, const mglDataA &xx, const mglDataA &yy, const mglDataA &zz)\r
++{ return mglData(true,mgl_data_subdata_ext(&dat,&xx,&yy,&zz)); }\r
++inline mglData mglSubData(const mglDataA &dat, const mglDataA &xx, const mglDataA &yy)\r
++{ return mglData(true,mgl_data_subdata_ext(&dat,&xx,&yy,0)); }\r
++inline mglData mglSubData(const mglDataA &dat, const mglDataA &xx)\r
++{ return mglData(true,mgl_data_subdata_ext(&dat,&xx,0,0)); }\r
++//-----------------------------------------------------------------------------\r
++/// Prepare coefficients for global spline interpolation\r
++inline mglData mglGSplineInit(const mglDataA &xdat, const mglDataA &ydat)\r
++{ return mglData(true,mgl_gspline_init(&xdat, &ydat)); }\r
++/// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef\r
++inline mreal mglGSpline(const mglDataA &coef, mreal dx, mreal *d1=0, mreal *d2=0)\r
++{ return mgl_gspline(&coef, dx, d1,d2); }\r
++//-----------------------------------------------------------------------------\r
++/// Wrapper class for expression evaluating\r
++class MGL_EXPORT mglExpr\r
++{\r
++ HMEX ex;\r
++ mglExpr(const mglExpr &){} // copying is not allowed\r
++ const mglExpr &operator=(const mglExpr &t){return t;} // copying is not allowed\r
++public:\r
++ mglExpr(const char *expr) { ex = mgl_create_expr(expr); }\r
++#if MGL_HAVE_RVAL\r
++ mglExpr(mglExpr &&d):ex(d.ex) { d.ex=0; }\r
++#endif\r
++ ~mglExpr() { mgl_delete_expr(ex); }\r
++ /// Return value of expression for given x,y,z variables\r
++ inline double Eval(double x, double y=0, double z=0)\r
++ { return mgl_expr_eval(ex,x,y,z); }\r
++ /// Return value of expression differentiation over variable dir for given x,y,z variables\r
++ inline double Diff(char dir, double x, double y=0, double z=0)\r
++ { return mgl_expr_diff(ex,dir, x,y,z); }\r
++#ifndef SWIG\r
++ /// Return value of expression for given variables\r
++ inline double Eval(mreal var[26])\r
++ { return mgl_expr_eval_v(ex,var); }\r
++ /// Return value of expression differentiation over variable dir for given variables\r
++ inline double Diff(char dir, mreal var[26])\r
++ { return mgl_expr_diff_v(ex,dir, var); }\r
++#endif\r
++};\r
++//-----------------------------------------------------------------------------\r
++/// Class which present equidistantly distributed data\r
++class MGL_EXPORT mglDataV : public mglDataA\r
++{\r
++ long nx; ///< number of points in 1st dimensions ('x' dimension)\r
++ long ny; ///< number of points in 2nd dimensions ('y' dimension)\r
++ long nz; ///< number of points in 3d dimensions ('z' dimension)\r
++ mreal di, dj, dk, a0;\r
++public:\r
++ mglDataV(long xx=1,long yy=1,long zz=1,mreal x1=0,mreal x2=mglNaN,char dir='x'):nx(xx),ny(yy),nz(zz)\r
++ { Fill(x1,x2,dir); }\r
++ mglDataV(const mglDataV &d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk),a0(d.a0) {}\r
++#if MGL_HAVE_RVAL\r
++ mglDataV(mglDataV &&d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk),a0(d.a0)\r
++ { s=d.s; temp=d.temp; func=d.func; o=d.o; d.func=0; }\r
++#endif\r
++ virtual ~mglDataV() {}\r
++\r
++ /// Get sizes\r
++ long GetNx() const { return nx; }\r
++ long GetNy() const { return ny; }\r
++ long GetNz() const { return nz; }\r
++\r
++ /// Create or recreate the array with specified size and fill it by zero\r
++ inline void Create(long mx,long my=1,long mz=1)\r
++ { di=mx>1?di*(nx-1)/(mx-1):0; dj=my>1?dj*(ny-1)/(my-1):0;\r
++ dk=mz>1?dk*(nz-1)/(mz-1):0; nx=mx; ny=my; nz=mz; }\r
++ /// For going throw all elements\r
++ inline void All() { di=dj=dk=1; a0=0; }\r
++ /// Equidistantly fill the data to range [x1,x2] in direction dir\r
++ inline void Fill(mreal x1,mreal x2=mglNaN,char dir='x')\r
++ {\r
++ di=dj=dk=0; a0=x1;\r
++ if(mgl_isnum(x2))\r
++ {\r
++ if(dir=='x' && nx>1) di=(x2-x1)/(nx-1);\r
++ if(dir=='y' && ny>1) dj=(x2-x1)/(ny-1);\r
++ if(dir=='z' && nz>1) dk=(x2-x1)/(nz-1);\r
++ }\r
++ }\r
++ mreal Maximal() const\r
++ { return a0+mgl_max(mgl_max(di*(nx-1),dj*(ny-1)),mgl_max(dk*(nz-1),0)); }\r
++ mreal Minimal() const\r
++ { return a0+mgl_min(mgl_min(di*(nx-1),dj*(ny-1)),mgl_min(dk*(nz-1),0)); }\r
++\r
++ /// Copy data from other mglDataV variable\r
++ inline const mglDataV &operator=(const mglDataV &d)\r
++ { nx=d.nx; ny=d.ny; nz=d.nz; a0=d.a0;\r
++ di=d.di; dj=d.dj; dk=d.dk; return d; }\r
++ inline mreal operator=(mreal val)\r
++ { di=dj=dk=0; a0=val; return val; }\r
++ /// Get the interpolated value and its derivatives in given data cell without border checking\r
++ mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
++ { if(dx) *dx=di; if(dy) *dy=dj; if(dz) *dz=dk;\r
++ return a0+di*x+dj*y+dk*z; }\r
++ /// Get the interpolated value in given data cell without border checking\r
++ mreal value(mreal x,mreal y=0,mreal z=0) const { return a0+di*x+dj*y+dk*z; }\r
++ mreal v(long i,long j=0,long k=0) const { return a0+di*i+dj*j+dk*k; }\r
++ mreal vthr(long ii) const\r
++ { long i=ii%nx, j=(ii/nx)%ny, k=ii/(nx*ny); return a0+di*i+dj*j+dk*k; }\r
++ // add for speeding up !!!\r
++ mreal dvx(long ,long =0,long =0) const { return di; }\r
++ mreal dvy(long ,long =0,long =0) const { return dj; }\r
++ mreal dvz(long ,long =0,long =0) const { return dk; }\r
++};\r
++//-----------------------------------------------------------------------------\r
++/// Class which present FFT frequency as data array\r
++class MGL_EXPORT mglDataW : public mglDataA\r
++{\r
++ long nx; ///< number of points in 1st dimensions ('x' dimension)\r
++ long ny; ///< number of points in 2nd dimensions ('y' dimension)\r
++ long nz; ///< number of points in 3d dimensions ('z' dimension)\r
++ mreal di, dj, dk;\r
++public:\r
++\r
++ mglDataW(long xx=1,long yy=1,long zz=1,mreal dp=0,char dir='x'):nx(xx),ny(yy),nz(zz)\r
++ { Freq(dp,dir); }\r
++ mglDataW(const mglDataW &d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk) {}\r
++#if MGL_HAVE_RVAL\r
++ mglDataW(mglDataW &&d):nx(d.nx),ny(d.ny),nz(d.nz),di(d.di),dj(d.dj),dk(d.dk)\r
++ { s=d.s; temp=d.temp; func=d.func; o=d.o; d.func=0; }\r
++#endif\r
++ virtual ~mglDataW() {}\r
++\r
++ /// Get sizes\r
++ long GetNx() const { return nx; }\r
++ long GetNy() const { return ny; }\r
++ long GetNz() const { return nz; }\r
++\r
++ /// Create or recreate the array with specified size and fill it by zero\r
++ inline void Create(long mx,long my=1,long mz=1)\r
++ { nx=mx; ny=my; nz=mz; }\r
++ /// For going throw all elements\r
++ inline void All() { di=dj=dk=1; }\r
++ /// Equidistantly fill the data to range [x1,x2] in direction dir\r
++ inline void Freq(mreal dp,char dir='x')\r
++ {\r
++ di=dj=dk=0;\r
++ if(dir=='x') di=dp;\r
++ if(dir=='y') dj=dp;\r
++ if(dir=='z') dk=dp;\r
++ }\r
++ mreal Maximal() const\r
++ { return mgl_max(mgl_max(di*(nx-1),dj*(ny-1)),mgl_max(dk*(nz-1),0)); }\r
++ mreal Minimal() const\r
++ { return mgl_min(mgl_min(di*(nx-1),dj*(ny-1)),mgl_min(dk*(nz-1),0)); }\r
++\r
++ /// Copy data from other mglDataV variable\r
++ inline const mglDataW &operator=(const mglDataW &d)\r
++ { nx=d.nx; ny=d.ny; nz=d.nz; di=d.di; dj=d.dj; dk=d.dk; return d; }\r
++ /// Get the interpolated value and its derivatives in given data cell without border checking\r
++ mreal valueD(mreal x,mreal y=0,mreal z=0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
++ { if(dx) *dx=di; if(dy) *dy=dj; if(dz) *dz=dk;\r
++ return di*(x<nx/2?x:x-nx)+dj*(y<ny/2?y:y-ny)+dk*(z<nz/2?z:z-nz); }\r
++ /// Get the interpolated value in given data cell without border checking\r
++ mreal value(mreal x,mreal y=0,mreal z=0) const\r
++ { return di*(x<nx/2?x:x-nx)+dj*(y<ny/2?y:y-ny)+dk*(z<nz/2?z:z-nz); }\r
++ mreal v(long i,long j=0,long k=0) const\r
++ { return di*(i<nx/2?i:i-nx)+dj*(j<ny/2?j:j-ny)+dk*(k<nz/2?k:k-nz); }\r
++ mreal vthr(long ii) const\r
++ { long i=ii%nx, j=(ii/nx)%ny, k=ii/(nx*ny);\r
++ return di*(i<nx/2?i:i-nx)+dj*(j<ny/2?j:j-ny)+dk*(k<nz/2?k:k-nz); }\r
++ // add for speeding up !!!\r
++ mreal dvx(long ,long =0,long =0) const { return di; }\r
++ mreal dvy(long ,long =0,long =0) const { return dj; }\r
++ mreal dvz(long ,long =0,long =0) const { return dk; }\r
++};\r
++//-----------------------------------------------------------------------------\r
++/// Class which present function as data array\r
++class MGL_EXPORT mglDataF : public mglDataA\r
++{\r
++ long nx; ///< number of points in 1st dimensions ('x' dimension)\r
++ long ny; ///< number of points in 2nd dimensions ('y' dimension)\r
++ long nz; ///< number of points in 3d dimensions ('z' dimension)\r
++ std::string str; ///< function as string\r
++ mglPoint v1, v2; ///< ranges for coordinates\r
++ HMEX ex; ///< parsed variant\r
++ mreal dx,dy,dz;\r
++ inline void setD()\r
++ {\r
++ dx = nx>1?(v2.x-v1.x)/(nx-1):0;\r
++ dy = ny>1?(v2.y-v1.y)/(ny-1):0;\r
++ dz = nz>1?(v2.z-v1.z)/(nz-1):0;\r
++ }\r
++ mreal (*dfunc)(mreal i, mreal j, mreal k, void *par);\r
++ void *par;\r
++public:\r
++\r
++ mglDataF(long xx=1,long yy=1,long zz=1):nx(xx),ny(yy),nz(zz), dfunc(0),par(0)\r
++ { ex=0; v2.Set(1,1,1); setD(); }\r
++ mglDataF(const mglDataF &d) : nx(d.nx), ny(d.ny), nz(d.nz), str(d.str), v1(d.v1), v2(d.v2), dx(d.dx),dy(d.dy),dz(d.dz), dfunc(d.dfunc),par(d.par)\r
++ { ex = mgl_create_expr(str.c_str()); }\r
++#if MGL_HAVE_RVAL\r
++ mglDataF(mglDataF &&d):nx(d.nx),ny(d.ny),nz(d.nz), str(d.str), v1(d.v1),v2(d.v2), ex(d.ex), dx(d.dx),dy(d.dy),dz(d.dz), dfunc(d.dfunc),par(d.par)\r
++ { s=d.s; temp=d.temp; func=d.func; o=d.o; d.ex=0; d.func=0; }\r
++#endif\r
++ virtual ~mglDataF() { mgl_delete_expr(ex); }\r
++\r
++ /// Get sizes\r
++ long GetNx() const { return nx; }\r
++ long GetNy() const { return ny; }\r
++ long GetNz() const { return nz; }\r
++\r
++ /// Create or recreate the array with specified size and fill it by zero\r
++ inline void Create(long mx,long my=1,long mz=1) { nx=mx; ny=my; nz=mz; setD(); }\r
++ inline void SetRanges(mglPoint p1, mglPoint p2) { v1=p1; v2=p2; setD(); }\r
++ /// Set formula to be used as dfunction\r
++ inline void SetFormula(const char *eq)\r
++ {\r
++ mgl_delete_expr(ex); dfunc=0; par=0;\r
++ if(eq && *eq) { ex = mgl_create_expr(eq); str=eq; }\r
++ else { ex=0; str=""; }\r
++ }\r
++ /// Set function and coordinates range [r1,r2]\r
++ inline void SetFunc(mreal (*f)(mreal,mreal,mreal,void*), void *p=NULL)\r
++ { mgl_delete_expr(ex); ex=0; dfunc=f; par=p; }\r
++\r
++ /// Get the interpolated value and its derivatives in given data cell without border checking\r
++ mreal valueD(mreal i,mreal j=0,mreal k=0, mreal *di=0,mreal *dj=0,mreal *dk=0) const\r
++ {\r
++ mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
++ if(di) *di = 0;\r
++ if(dj) *dj = 0;\r
++ if(dk) *dk = 0;\r
++ if(dfunc)\r
++ {\r
++ res = dfunc(x,y,z, par);\r
++ if(di) *di = dfunc(x+dx,y,z, par)-res;\r
++ if(dj) *dj = dfunc(x,y+dy,z, par)-res;\r
++ if(dk) *dk = dfunc(x,y,z+dz, par)-res;\r
++ }\r
++ else if(ex)\r
++ {\r
++ if(di) *di = mgl_expr_diff(ex,'x',x,y,z)*dx;\r
++ if(dj) *dj = mgl_expr_diff(ex,'y',x,y,z)*dy;\r
++ if(dk) *dk = mgl_expr_diff(ex,'z',x,y,z)*dz;\r
++ res = mgl_expr_eval(ex,x,y,z);\r
++ }\r
++ return res;\r
++ }\r
++ /// Get the interpolated value in given data cell without border checking\r
++ mreal value(mreal i,mreal j=0,mreal k=0) const\r
++ {\r
++ mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
++ if(dfunc) res = dfunc(x,y,z, par);\r
++ else if(ex) res = mgl_expr_eval(ex,x,y,z);\r
++ return res;\r
++ }\r
++ /// Copy data from other mglDataV variable\r
++ inline const mglDataF &operator=(const mglDataF &d)\r
++ { nx=d.nx; ny=d.ny; nz=d.nz; v1=d.v1; v2=d.v2; setD(); mgl_delete_expr(ex);\r
++ str=d.str; ex = mgl_create_expr(str.c_str()); dfunc=d.dfunc; par=d.par; return d; }\r
++ /// Get the value in given cell of the data without border checking\r
++ mreal v(long i,long j=0,long k=0) const\r
++ {\r
++ mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
++ if(dfunc) res = dfunc(x,y,z, par);\r
++ else if(ex) res = mgl_expr_eval(ex,x,y,z);\r
++ return res;\r
++ }\r
++ mreal vthr(long i) const\r
++ {\r
++ mreal res=0, x=v1.x+dx*(i%nx), y=v1.y+dy*((i/nx)%ny), z=v1.z+dz*(i/(nx*ny));\r
++ if(dfunc) res = dfunc(x,y,z, par);\r
++ else if(ex) res = mgl_expr_eval(ex,x,y,z);\r
++ return res;\r
++ }\r
++ // add for speeding up !!!\r
++ mreal dvx(long i,long j=0,long k=0) const\r
++ {\r
++ mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
++ if(dfunc) res = dfunc(x+dx,y,z, par)-dfunc(x,y,z, par);\r
++ else if(ex) res = mgl_expr_eval(ex,x+dx,y,z)-mgl_expr_eval(ex,x,y,z);\r
++ return res;\r
++ }\r
++ mreal dvy(long i,long j=0,long k=0) const\r
++ {\r
++ mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
++ if(dfunc) res = dfunc(x,y+dy,z, par)-dfunc(x,y,z, par);\r
++ else if(ex) res = mgl_expr_eval(ex,x,y+dy,z)-mgl_expr_eval(ex,x,y,z);\r
++ return res;\r
++ }\r
++ mreal dvz(long i,long j=0,long k=0) const\r
++ {\r
++ mreal res=0, x=v1.x+dx*i, y=v1.y+dy*j, z=v1.z+dz*k;\r
++ if(dfunc) res = dfunc(x,y,z+dz, par)-dfunc(x,y,z, par);\r
++ else if(ex) res = mgl_expr_eval(ex,x,y,z+dz)-mgl_expr_eval(ex,x,y,z);\r
++ return res;\r
++ }\r
++};\r
++//-----------------------------------------------------------------------------\r
++/// Class which present column of another data as data array\r
++class MGL_EXPORT mglDataT : public mglDataA\r
++{\r
++ const mglDataA &dat;\r
++ long ind;\r
++ const mglDataT &operator=(const mglDataT &d) { return d; }\r
++public:\r
++ mglDataT(const mglDataT &d) : dat(d.dat), ind(d.ind) { s = d.s; }\r
++ mglDataT(const mglDataA &d, long col=0) : dat(d), ind(col) {}\r
++ mglDataT(HCDT d, long col=0) : dat(*d), ind(col) {}\r
++#if MGL_HAVE_RVAL\r
++ mglDataT(mglDataT &&d):dat(d.dat),ind(d.ind)\r
++ { s=d.s; temp=d.temp; func=d.func; o=d.o; d.func=0; }\r
++#endif\r
++ virtual ~mglDataT() {}\r
++\r
++ /// Get sizes\r
++ long GetNx() const { return dat.GetNy(); }\r
++ long GetNy() const { return dat.GetNz(); }\r
++ long GetNz() const { return 1; }\r
++\r
++ mreal Maximal() const\r
++ { return mglSubData(dat,ind).Maximal(); }\r
++ mreal Minimal() const\r
++ { return mglSubData(dat,ind).Minimal(); }\r
++ inline void SetInd(long i, const wchar_t *name)\r
++ { ind = i; s = name; }\r
++ inline void SetInd(long i, wchar_t name)\r
++ { ind = i; s = name; }\r
++\r
++ /// Get the interpolated value and its derivatives in given data cell without border checking\r
++ mreal valueD(mreal x,mreal y=0,mreal =0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
++ { if(dz) *dz=0; return dat.valueD(ind,x,y,0,dx,dy); }\r
++ /// Get the interpolated value in given data cell without border checking\r
++ mreal value(mreal x,mreal y=0,mreal =0) const\r
++ { return dat.value(ind,x,y); }\r
++ /// Get the value in given cell of the data without border checking\r
++ mreal v(long i,long j=0,long =0) const\r
++ { return dat.v(ind,i,j); }\r
++ mreal vthr(long i) const\r
++ { return dat.vthr(ind+dat.GetNx()*i); }\r
++ // add for speeding up !!!\r
++ mreal dvx(long i,long j=0,long =0) const\r
++ { return dat.dvy(ind,i,j); }\r
++ mreal dvy(long i,long j=0,long =0) const\r
++ { return dat.dvz(ind,i,j); }\r
++ mreal dvz(long ,long =0,long =0) const\r
++ { return 0; }\r
++};\r
++//-----------------------------------------------------------------------------\r
++/// Class which present row of another data as data array\r
++class MGL_EXPORT mglDataR : public mglDataA\r
++{\r
++ const mglDataA &dat;\r
++ long ind;\r
++ const mglDataR &operator=(const mglDataR &d) { return d; }\r
++public:\r
++ mglDataR(const mglDataR &d) : dat(d.dat), ind(d.ind) { s = d.s; }\r
++ mglDataR(const mglDataA &d, long row=0) : dat(d), ind(row) {}\r
++ mglDataR(HCDT d, long row=0) : dat(*d), ind(row) {}\r
++#if MGL_HAVE_RVAL\r
++ mglDataR(mglDataR &&d):dat(d.dat),ind(d.ind)\r
++ { s=d.s; temp=d.temp; func=d.func; o=d.o; d.func=0; }\r
++#endif\r
++ virtual ~mglDataR() {}\r
++\r
++ /// Get sizes\r
++ long GetNx() const { return dat.GetNx(); }\r
++ long GetNy() const { return 1; }\r
++ long GetNz() const { return 1; }\r
++\r
++ mreal Maximal() const\r
++ { return mglSubData(dat,-1,ind).Maximal(); }\r
++ mreal Minimal() const\r
++ { return mglSubData(dat,-1,ind).Minimal(); }\r
++ inline void SetInd(long i, const wchar_t *name)\r
++ { ind = i; s = name; }\r
++ inline void SetInd(long i, wchar_t name)\r
++ { ind = i; s = name; }\r
++\r
++ /// Get the interpolated value and its derivatives in given data cell without border checking\r
++ mreal valueD(mreal x,mreal =0,mreal =0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
++ { if(dy) *dy=0; if(dz) *dz=0; return dat.valueD(x,ind,0,dx); }\r
++ /// Get the interpolated value in given data cell without border checking\r
++ mreal value(mreal x,mreal =0,mreal =0) const\r
++ { return dat.value(x,ind,0); }\r
++ /// Get the value in given cell of the data without border checking\r
++ mreal v(long i,long =0,long =0) const\r
++ { return dat.v(i,ind,0); }\r
++ mreal vthr(long i) const\r
++ { return dat.vthr(i+dat.GetNx()*ind); }\r
++ // add for speeding up !!!\r
++ mreal dvx(long i,long =0,long =0) const\r
++ { return dat.dvx(i,ind,0); }\r
++ mreal dvy(long ,long =0,long =0) const\r
++ { return 0; }\r
++ mreal dvz(long ,long =0,long =0) const\r
++ { return 0; }\r
++};\r
++//-----------------------------------------------------------------------------\r
++/// Class which present std::vector as data array\r
++class MGL_EXPORT mglDataS : public mglDataA\r
++{\r
++public:\r
++ std::vector<mreal> dat;\r
++\r
++ mglDataS(const mglDataS &st) : dat(st.dat) {}\r
++ mglDataS(const std::vector<mreal> &d) : dat(d) {}\r
++ mglDataS(size_t s=1) { dat.resize(s); }\r
++ ~mglDataS() {}\r
++ inline void reserve(size_t num) { dat.reserve(num); }\r
++ inline void clear() { dat.clear(); }\r
++ inline double operator[](size_t i) { return dat[i]; }\r
++ inline void push_back(double t) { dat.push_back(t); }\r
++ inline size_t size() const { return dat.size(); }\r
++ const mglDataS &operator=(const mglDataS &st) { dat = st.dat; return st; }\r
++ const std::vector<mreal> &operator=(const std::vector<mreal> &st) { dat = st; return st; }\r
++\r
++ /// Get the interpolated value and its derivatives in given data cell without border checking\r
++ mreal valueD(mreal x,mreal =0,mreal =0,mreal *dx=0,mreal *dy=0,mreal *dz=0) const\r
++ { return mglSpline3(dat.data(),dat.size(),1,1,x,0,0,dx,dy,dz); }\r
++ /// Get the interpolated value in given data cell without border checking\r
++ mreal value(mreal x,mreal =0,mreal =0) const\r
++ { return mglSpline3s(dat.data(),dat.size(),1,1,x,0,0); }\r
++\r
++ mreal v(long i,long =0,long =0) const { return dat[i]; }\r
++<<<<<<< HEAD\r
++ mreal vthr(long i) const { return dat[i]; };\r
++=======\r
++ mreal vthr(long i) const { return dat[i]; }\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ long GetNx() const { return dat.size(); }\r
++ long GetNy() const { return 1; }\r
++ long GetNz() const { return 1; }\r
++ mreal dvx(long i,long =0,long =0) const\r
++ { return i>0? (i<long(dat.size()-1)? (dat[i+1]-dat[i-1])/2:dat[i]-dat[i-1]) : dat[i+1]-dat[i]; }\r
++<<<<<<< HEAD\r
++ mreal dvy(long ,long =0,long =0) const { return 1; }\r
++ mreal dvz(long ,long =0,long =0) const { return 1; }\r
++=======\r
++ mreal dvy(long ,long =0,long =0) const { return 0; }\r
++ mreal dvz(long ,long =0,long =0) const { return 0; }\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++};\r
++//-----------------------------------------------------------------------------\r
++#endif\r
++#endif\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * data_cf.h is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#ifndef _MGL_DATA_CF_H_\r
++#define _MGL_DATA_CF_H_\r
++//-----------------------------------------------------------------------------\r
++#include "mgl2/abstract.h"\r
++//-----------------------------------------------------------------------------\r
++#if MGL_HAVE_GSL\r
++#include <gsl/gsl_vector.h>\r
++#include <gsl/gsl_matrix.h>\r
++#else\r
++#ifdef __cplusplus\r
++struct gsl_vector;\r
++struct gsl_matrix;\r
++#else\r
++typedef void gsl_vector;\r
++typedef void gsl_matrix;\r
++#endif\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++#ifdef __cplusplus\r
++extern "C" {\r
++#endif\r
++/// Get integer power of x\r
++double MGL_EXPORT_CONST mgl_ipow(double x,int n);\r
++double MGL_EXPORT mgl_ipow_(mreal *x,int *n);\r
++/// Get number of seconds since 1970 for given string\r
++double MGL_EXPORT mgl_get_time(const char *time, const char *fmt);\r
++double MGL_EXPORT mgl_get_time_(const char *time, const char *fmt,int,int);\r
++\r
++/// Create HMDT object\r
++HMDT MGL_EXPORT mgl_create_data();\r
++uintptr_t MGL_EXPORT mgl_create_data_();\r
++/// Create HMDT object with specified sizes\r
++HMDT MGL_EXPORT mgl_create_data_size(long nx, long ny, long nz);\r
++uintptr_t MGL_EXPORT mgl_create_data_size_(int *nx, int *ny, int *nz);\r
++/// Create HMDT object with data from file\r
++HMDT MGL_EXPORT mgl_create_data_file(const char *fname);\r
++uintptr_t MGL_EXPORT mgl_create_data_file_(const char *fname, int len);\r
++/// Delete HMDT object\r
++void MGL_EXPORT mgl_delete_data(HMDT dat);\r
++void MGL_EXPORT mgl_delete_data_(uintptr_t *dat);\r
++\r
++/// Rearange data dimensions\r
++void MGL_EXPORT mgl_data_rearrange(HMDT dat, long mx,long my,long mz);\r
++void MGL_EXPORT mgl_data_rearrange_(uintptr_t *dat, int *mx, int *my, int *mz);\r
++/// Link external data array (don't delete it at exit)\r
++void MGL_EXPORT mgl_data_link(HMDT dat, mreal *A,long mx,long my,long mz);\r
++void MGL_EXPORT mgl_data_link_(uintptr_t *d, mreal *A, int *nx,int *ny,int *nz);\r
++/// Allocate memory and copy the data from the (float *) array\r
++void MGL_EXPORT mgl_data_set_float(HMDT dat, const float *A,long mx,long my,long mz);\r
++void MGL_EXPORT mgl_data_set_float_(uintptr_t *dat, const float *A,int *NX,int *NY,int *NZ);\r
++void MGL_EXPORT mgl_data_set_float1_(uintptr_t *d, const float *A,int *N1);\r
++/// Allocate memory and copy the data from the (double *) array\r
++void MGL_EXPORT mgl_data_set_double(HMDT dat, const double *A,long mx,long my,long mz);\r
++void MGL_EXPORT mgl_data_set_double_(uintptr_t *dat, const double *A,int *NX,int *NY,int *NZ);\r
++void MGL_EXPORT mgl_data_set_double1_(uintptr_t *d, const double *A,int *N1);\r
++/// Allocate memory and copy the data from the (float **) array\r
++void MGL_EXPORT mgl_data_set_float2(HMDT d, float const * const *A,long N1,long N2);\r
++void MGL_EXPORT mgl_data_set_float2_(uintptr_t *d, const float *A,int *N1,int *N2);\r
++/// Allocate memory and copy the data from the (double **) array\r
++void MGL_EXPORT mgl_data_set_double2(HMDT d, double const * const *A,long N1,long N2);\r
++void MGL_EXPORT mgl_data_set_double2_(uintptr_t *d, const double *A,int *N1,int *N2);\r
++/// Allocate memory and copy the data from the (float ***) array\r
++void MGL_EXPORT mgl_data_set_float3(HMDT d, float const * const * const *A,long N1,long N2,long N3);\r
++void MGL_EXPORT mgl_data_set_float3_(uintptr_t *d, const float *A,int *N1,int *N2,int *N3);\r
++/// Allocate memory and copy the data from the (double ***) array\r
++void MGL_EXPORT mgl_data_set_double3(HMDT d, double const * const * const *A,long N1,long N2,long N3);\r
++void MGL_EXPORT mgl_data_set_double3_(uintptr_t *d, const double *A,int *N1,int *N2,int *N3);\r
++/// Import data from abstract type\r
++void MGL_EXPORT mgl_data_set(HMDT dat, HCDT a);\r
++void MGL_EXPORT mgl_data_set_(uintptr_t *dat, uintptr_t *a);\r
++/// Allocate memory and copy the data from the gsl_vector\r
++void MGL_EXPORT mgl_data_set_vector(HMDT dat, gsl_vector *v);\r
++/// Allocate memory and copy the data from the gsl_matrix\r
++void MGL_EXPORT mgl_data_set_matrix(HMDT dat, gsl_matrix *m);\r
++/// Set value of data element [i,j,k]\r
++void MGL_EXPORT mgl_data_set_value(HMDT dat, mreal v, long i, long j, long k);\r
++void MGL_EXPORT mgl_data_set_value_(uintptr_t *d, mreal *v, int *i, int *j, int *k);\r
++/// Get value of data element [i,j,k]\r
++mreal MGL_EXPORT mgl_data_get_value(HCDT dat, long i, long j, long k);\r
++mreal MGL_EXPORT mgl_data_get_value_(uintptr_t *d, int *i, int *j, int *k);\r
++/// Allocate memory and scanf the data from the string\r
++void MGL_EXPORT mgl_data_set_values(HMDT dat, const char *val, long nx, long ny, long nz);\r
++void MGL_EXPORT mgl_data_set_values_(uintptr_t *d, const char *val, int *nx, int *ny, int *nz, int l);\r
++\r
++/// Read data array from HDF file (parse HDF4 and HDF5 files)\r
++int MGL_EXPORT mgl_data_read_hdf(HMDT d,const char *fname,const char *data);\r
++int MGL_EXPORT mgl_data_read_hdf_(uintptr_t *d, const char *fname, const char *data,int l,int n);\r
++/// Read data from tab-separated text file with auto determining size\r
++int MGL_EXPORT mgl_data_read(HMDT dat, const char *fname);\r
++int MGL_EXPORT mgl_data_read_(uintptr_t *d, const char *fname,int l);\r
++/// Read data from text file with size specified at beginning of the file\r
++int MGL_EXPORT mgl_data_read_mat(HMDT dat, const char *fname, long dim);\r
++int MGL_EXPORT mgl_data_read_mat_(uintptr_t *dat, const char *fname, int *dim, int);\r
++/// Read data from text file with specifeid size\r
++int MGL_EXPORT mgl_data_read_dim(HMDT dat, const char *fname,long mx,long my,long mz);\r
++int MGL_EXPORT mgl_data_read_dim_(uintptr_t *dat, const char *fname,int *mx,int *my,int *mz,int);\r
++/// Read data from tab-separated text files with auto determining size which filenames are result of sprintf(fname,templ,t) where t=from:step:to\r
++int MGL_EXPORT mgl_data_read_range(HMDT d, const char *templ, double n1, double n2, double step, int as_slice);\r
++int MGL_EXPORT mgl_data_read_range_(uintptr_t *d, const char *fname, mreal *n1, mreal *n2, mreal *step, int *as_slice,int l);\r
++/// Read data from tab-separated text files with auto determining size which filenames are satisfied to template (like "t_*.dat")\r
++int MGL_EXPORT mgl_data_read_all(HMDT dat, const char *templ, int as_slice);\r
++int MGL_EXPORT mgl_data_read_all_(uintptr_t *d, const char *fname, int *as_slice,int l);\r
++/// Import data array from PNG file according color scheme\r
++void MGL_EXPORT mgl_data_import(HMDT dat, const char *fname, const char *scheme,mreal v1,mreal v2);\r
++void MGL_EXPORT mgl_data_import_(uintptr_t *dat, const char *fname, const char *scheme,mreal *v1,mreal *v2,int,int);\r
++/// Scan textual file for template and fill data array\r
++int MGL_EXPORT mgl_data_scan_file(HMDT dat,const char *fname, const char *templ);\r
++int MGL_EXPORT mgl_data_scan_file_(uintptr_t *dat,const char *fname, const char *templ,int,int);\r
++/// Read data array from Tektronix WFM file\r
++/** Parse Tektronix TDS5000/B, TDS6000/B/C, TDS/CSA7000/B, MSO70000/C, DSA70000/B/C DPO70000/B/C DPO7000/ MSO/DPO5000. */\r
++int MGL_EXPORT mgl_data_read_wfm(HMDT d,const char *fname, long num, long step, long start);\r
++int MGL_EXPORT mgl_data_read_wfm_(uintptr_t *d, const char *fname, long *num, long *step, long *start,int l);\r
++/// Read data array from Matlab MAT file (parse versions 4 and 5)\r
++int MGL_EXPORT mgl_data_read_matlab(HMDT d,const char *fname,const char *data);\r
++int MGL_EXPORT mgl_data_read_matlab_(uintptr_t *d, const char *fname, const char *data,int l,int n);\r
++\r
++/// Create or recreate the array with specified size and fill it by zero\r
++void MGL_EXPORT mgl_data_create(HMDT dat, long nx,long ny,long nz);\r
++void MGL_EXPORT mgl_data_create_(uintptr_t *dat, int *nx,int *ny,int *nz);\r
++/// Transpose dimensions of the data (generalization of Transpose)\r
++void MGL_EXPORT mgl_data_transpose(HMDT dat, const char *dim);\r
++void MGL_EXPORT mgl_data_transpose_(uintptr_t *dat, const char *dim,int);\r
++/// Normalize the data to range [v1,v2]\r
++void MGL_EXPORT mgl_data_norm(HMDT dat, mreal v1,mreal v2,int sym,long dim);\r
++void MGL_EXPORT mgl_data_norm_(uintptr_t *dat, mreal *v1,mreal *v2,int *sym,int *dim);\r
++/// Normalize the data to range [v1,v2] slice by slice\r
++void MGL_EXPORT mgl_data_norm_slice(HMDT dat, mreal v1,mreal v2,char dir,long keep_en,long sym);\r
++void MGL_EXPORT mgl_data_norm_slice_(uintptr_t *dat, mreal *v1,mreal *v2,char *dir,int *keep_en,int *sym,int l);\r
++/// Limit the data to be inside [-v,v], keeping the original sign\r
++void MGL_EXPORT mgl_data_limit(HMDT dat, mreal v);\r
++void MGL_EXPORT mgl_data_limit_(uintptr_t *dat, mreal *v);\r
++/// Get sub-array of the data with given fixed indexes\r
++HMDT MGL_EXPORT mgl_data_subdata(HCDT dat, long xx,long yy,long zz);\r
++uintptr_t MGL_EXPORT mgl_data_subdata_(uintptr_t *dat, int *xx,int *yy,int *zz);\r
++/// Get sub-array of the data with given fixed indexes (like indirect access)\r
++HMDT MGL_EXPORT mgl_data_subdata_ext(HCDT dat, HCDT xx, HCDT yy, HCDT zz);\r
++uintptr_t MGL_EXPORT mgl_data_subdata_ext_(uintptr_t *dat, uintptr_t *xx,uintptr_t *yy,uintptr_t *zz);\r
++/// Get column (or slice) of the data filled by formulas of named columns\r
++HMDT MGL_EXPORT mgl_data_column(HCDT dat, const char *eq);\r
++uintptr_t MGL_EXPORT mgl_data_column_(uintptr_t *dat, const char *eq,int l);\r
++/// Get data from sections ids, separated by value val along specified direction.\r
++/** If section id is negative then reverse order is used (i.e. -1 give last section). */\r
++HMDT MGL_EXPORT mgl_data_section(HCDT dat, HCDT ids, char dir, mreal val);\r
++uintptr_t MGL_EXPORT mgl_data_section_(uintptr_t *d, uintptr_t *ids, const char *dir, mreal *val,int);\r
++/// Get data from section id, separated by value val along specified direction.\r
++/** If section id is negative then reverse order is used (i.e. -1 give last section). */\r
++HMDT MGL_EXPORT mgl_data_section_val(HCDT dat, long id, char dir, mreal val);\r
++uintptr_t MGL_EXPORT mgl_data_section_val_(uintptr_t *d, int *id, const char *dir, mreal *val,int);\r
++\r
++/// Set names for columns (slices)\r
++void MGL_EXPORT mgl_data_set_id(HMDT d, const char *id);\r
++void MGL_EXPORT mgl_data_set_id_(uintptr_t *dat, const char *id,int l);\r
++/// Equidistantly fill the data to range [x1,x2] in direction dir\r
++void MGL_EXPORT mgl_data_fill(HMDT dat, mreal x1,mreal x2,char dir);\r
++void MGL_EXPORT mgl_data_fill_(uintptr_t *dat, mreal *x1,mreal *x2,const char *dir,int);\r
++/// Modify the data by specified formula assuming x,y,z in range [r1,r2]\r
++void MGL_EXPORT mgl_data_fill_eq(HMGL gr, HMDT dat, const char *eq, HCDT vdat, HCDT wdat,const char *opt);\r
++void MGL_EXPORT mgl_data_fill_eq_(uintptr_t *gr, uintptr_t *dat, const char *eq, uintptr_t *vdat, uintptr_t *wdat,const char *opt, int, int);\r
++/// Fill dat by interpolated values of vdat parametrically depended on xdat for x in range [x1,x2] using global spline\r
++void MGL_EXPORT mgl_data_refill_gs(HMDT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl);\r
++void MGL_EXPORT mgl_data_refill_gs_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *vdat, mreal *x1, mreal *x2, long *sl);\r
++/// Fill dat by interpolated values of vdat parametrically depended on xdat for x in range [x1,x2]\r
++void MGL_EXPORT mgl_data_refill_x(HMDT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl);\r
++void MGL_EXPORT mgl_data_refill_x_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *vdat, mreal *x1, mreal *x2, long *sl);\r
++/// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat for x,y in range [x1,x2]*[y1,y2]\r
++void MGL_EXPORT mgl_data_refill_xy(HMDT dat, HCDT xdat, HCDT ydat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, long sl);\r
++void MGL_EXPORT mgl_data_refill_xy_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *vdat, mreal *x1, mreal *x2, mreal *y1, mreal *y2, long *sl);\r
++/// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in range [x1,x2]*[y1,y2]*[z1,z2]\r
++void MGL_EXPORT mgl_data_refill_xyz(HMDT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, mreal z1, mreal z2);\r
++void MGL_EXPORT mgl_data_refill_xyz_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, uintptr_t *vdat, mreal *x1, mreal *x2, mreal *y1, mreal *y2, mreal *z1, mreal *z2);\r
++/// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range\r
++void MGL_EXPORT mgl_data_refill_gr(HMGL gr, HMDT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, long sl, const char *opt);\r
++void MGL_EXPORT mgl_data_refill_gr_(uintptr_t *gr, uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, uintptr_t *vdat, long *sl, const char *opt,int);\r
++/// Set the data by triangulated surface values assuming x,y,z in range [r1,r2]\r
++void MGL_EXPORT mgl_data_grid(HMGL gr, HMDT d, HCDT xdat, HCDT ydat, HCDT zdat,const char *opt);\r
++void MGL_EXPORT mgl_data_grid_(uintptr_t *gr, uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, const char *opt,int);\r
++/// Set the data by triangulated surface values assuming x,y,z in range [x1,x2]*[y1,y2]\r
++void MGL_EXPORT mgl_data_grid_xy(HMDT d, HCDT xdat, HCDT ydat, HCDT zdat, mreal x1, mreal x2, mreal y1, mreal y2);\r
++void MGL_EXPORT mgl_data_grid_xy_(uintptr_t *dat, uintptr_t *xdat, uintptr_t *ydat, uintptr_t *zdat, mreal *x1, mreal *x2, mreal *y1, mreal *y2);\r
++/// Put value to data element(s)\r
++void MGL_EXPORT mgl_data_put_val(HMDT dat, mreal val, long i, long j, long k);\r
++void MGL_EXPORT mgl_data_put_val_(uintptr_t *dat, mreal *val, int *i, int *j, int *k);\r
++/// Put array to data element(s)\r
++void MGL_EXPORT mgl_data_put_dat(HMDT dat, HCDT val, long i, long j, long k);\r
++void MGL_EXPORT mgl_data_put_dat_(uintptr_t *dat, uintptr_t *val, int *i, int *j, int *k);\r
++/// Modify the data by specified formula\r
++void MGL_EXPORT mgl_data_modify(HMDT dat, const char *eq,long dim);\r
++void MGL_EXPORT mgl_data_modify_(uintptr_t *dat, const char *eq,int *dim,int);\r
++/// Modify the data by specified formula\r
++void MGL_EXPORT mgl_data_modify_vw(HMDT dat, const char *eq,HCDT vdat,HCDT wdat);\r
++void MGL_EXPORT mgl_data_modify_vw_(uintptr_t *dat, const char *eq, uintptr_t *vdat, uintptr_t *wdat,int);\r
++/// Reduce size of the data\r
++void MGL_EXPORT mgl_data_squeeze(HMDT dat, long rx,long ry,long rz,long smooth);\r
++void MGL_EXPORT mgl_data_squeeze_(uintptr_t *dat, int *rx,int *ry,int *rz,int *smooth);\r
++\r
++/// Get array which is n-th pairs {x[i],y[i]} for iterated function system (fractal) generated by A\r
++/** NOTE: A.nx must be >= 7. */\r
++HMDT MGL_EXPORT mgl_data_ifs_2d(HCDT A, long n, long skip);\r
++uintptr_t MGL_EXPORT mgl_data_ifs_2d_(uintptr_t *A, long *n, long *skip);\r
++/// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) generated by A\r
++/** NOTE: A.nx must be >= 13. */\r
++HMDT MGL_EXPORT mgl_data_ifs_3d(HCDT A, long n, long skip);\r
++uintptr_t MGL_EXPORT mgl_data_ifs_3d_(uintptr_t *A, long *n, long *skip);\r
++/// Get array which is n-th points {x[i],y[i],z[i]} for iterated function system (fractal) defined in *.ifs file 'fname' and named as 'name'\r
++HMDT MGL_EXPORT mgl_data_ifs_file(const char *fname, const char *name, long n, long skip);\r
++uintptr_t mgl_data_ifs_file_(const char *fname, const char *name, long *n, long *skip,int l,int m);\r
++/// Codes for flame fractal functions\r
++enum {\r
++<<<<<<< HEAD\r
++ mglFlameLinear=0, mglFlameSin, mglFlameSphere, mglFlameSwirl, mglFlameHorseshoe,\r
++ mglFlamePolar, mglFlameHandkerchief, mglFlameHeart, mglFlameDisk, mglFlameSpiral,\r
++ mglFlameHyperbolic, mglFlameDiamond, mglFlameEx, mglFlameJulia, mglFlameBent,\r
++ mglFlameWaves, mglFlameFishEye, mglFlamePopcorn, mglFlameExponent, mglFlamePower,\r
++ mglFlameCos, mglFlameRings, mglFlameFan, mglFlameBlob, mglFlamePdj,\r
++ mglFlameFan2, mglFlameRings2, mglFlameEyefish, mglFlameBubble, mglFlameCylinder,\r
++ mglFlamePerspective, mglFlameNoise, mglFlameJuliaN, mglFlameJuliaScope, mglFlameBlur,\r
++ mglFlameGaussian, mglFlameRadialBlur, mglFlamePie, mglFlameNgon, mglFlameCurl,\r
++ mglFlameRectangles, mglFlameArch, mglFlameTangent, mglFlameSquare, mglFlameRays,\r
++ mglFlameBlade, mglFlameSecant, mglFlameTwintrian, mglFlameCross, mglFlameLAST\r
++=======\r
++ mglFlame2d_linear=0, mglFlame2d_sinusoidal, mglFlame2d_spherical, mglFlame2d_swirl, mglFlame2d_horseshoe,\r
++ mglFlame2d_polar, mglFlame2d_handkerchief,mglFlame2d_heart, mglFlame2d_disc, mglFlame2d_spiral,\r
++ mglFlame2d_hyperbolic, mglFlame2d_diamond, mglFlame2d_ex, mglFlame2d_julia, mglFlame2d_bent,\r
++ mglFlame2d_waves, mglFlame2d_fisheye, mglFlame2d_popcorn, mglFlame2d_exponential, mglFlame2d_power,\r
++ mglFlame2d_cosine, mglFlame2d_rings, mglFlame2d_fan, mglFlame2d_blob, mglFlame2d_pdj,\r
++ mglFlame2d_fan2, mglFlame2d_rings2, mglFlame2d_eyefish, mglFlame2d_bubble, mglFlame2d_cylinder,\r
++ mglFlame2d_perspective, mglFlame2d_noise, mglFlame2d_juliaN, mglFlame2d_juliaScope, mglFlame2d_blur,\r
++ mglFlame2d_gaussian, mglFlame2d_radialBlur, mglFlame2d_pie, mglFlame2d_ngon, mglFlame2d_curl,\r
++ mglFlame2d_rectangles, mglFlame2d_arch, mglFlame2d_tangent, mglFlame2d_square, mglFlame2d_blade,\r
++ mglFlame2d_secant, mglFlame2d_rays, mglFlame2d_twintrian, mglFlame2d_cross, mglFlame2d_disc2,\r
++ mglFlame2d_supershape, mglFlame2d_flower, mglFlame2d_conic, mglFlame2d_parabola, mglFlame2d_bent2,\r
++ mglFlame2d_bipolar, mglFlame2d_boarders, mglFlame2d_butterfly, mglFlame2d_cell, mglFlame2d_cpow,\r
++ mglFlame2d_curve, mglFlame2d_edisc, mglFlame2d_elliptic, mglFlame2d_escher, mglFlame2d_foci,\r
++ mglFlame2d_lazySusan, mglFlame2d_loonie, mglFlame2d_preBlur, mglFlame2d_modulus, mglFlame2d_oscope,\r
++ mglFlame2d_polar2, mglFlame2d_popcorn2, mglFlame2d_scry, mglFlame2d_separation, mglFlame2d_split,\r
++ mglFlame2d_splits, mglFlame2d_stripes, mglFlame2d_wedge, mglFlame2d_wedgeJulia, mglFlame2d_wedgeSph,\r
++ mglFlame2d_whorl, mglFlame2d_waves2, mglFlame2d_exp, mglFlame2d_log, mglFlame2d_sin,\r
++ mglFlame2d_cos, mglFlame2d_tan, mglFlame2d_sec, mglFlame2d_csc, mglFlame2d_cot,\r
++ mglFlame2d_sinh, mglFlame2d_cosh, mglFlame2d_tanh, mglFlame2d_sech, mglFlame2d_csch,\r
++ mglFlame2d_coth, mglFlame2d_auger, mglFlame2d_flux, mglFlame2dLAST\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++};\r
++/// Get array which is n-th pairs {x[i],y[i]} for Flame fractal generated by A with functions F\r
++/** NOTE: A.nx must be >= 7 and F.nx >= 2 and F.nz=A.ny.\r
++ * F[0,i,j] denote function id. F[1,i,j] give function weight. F(2:5,i,j) provide function parameters.\r
++ * Resulting point is {xnew,ynew} = sum_i F[1,i,j]*F[0,i,j]{IFS2d(A[j]){x,y}}. */\r
++HMDT MGL_EXPORT mgl_data_flame_2d(HCDT A, HCDT F, long n, long skip);\r
++uintptr_t MGL_EXPORT mgl_data_flame_2d_(uintptr_t *A, uintptr_t *F, long *n, long *skip);\r
++\r
++<<<<<<< HEAD\r
++=======\r
++/// Get curves, separated by NAN, for maximal values of array d as function of x coordinate.\r
++/** Noises below lvl amplitude are ignored.\r
++ * Parameter dy \in [0,ny] set the "attraction" distance of points to curve. */\r
++HMDT MGL_EXPORT mgl_data_detect(HCDT d, mreal lvl, mreal dj, mreal di, mreal min_len);\r
++uintptr_t MGL_EXPORT mgl_data_detect_(uintptr_t *d, mreal *lvl, mreal *dj, mreal *di, mreal *min_len);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++\r
++/// Get array as solution of tridiagonal matrix solution a[i]*x[i-1]+b[i]*x[i]+c[i]*x[i+1]=d[i]\r
++/** String \a how may contain:\r
++ * 'x', 'y', 'z' for solving along x-,y-,z-directions, or\r
++ * 'h' for solving along hexagonal direction at x-y plain (need nx=ny),\r
++ * 'c' for using periodical boundary conditions,\r
++ * 'd' for diffraction/diffuse calculation.\r
++ * NOTE: It work for flat data model only (i.e. for a[i,j]==a[i+nx*j]) */\r
++HMDT MGL_EXPORT mgl_data_tridmat(HCDT A, HCDT B, HCDT C, HCDT D, const char *how);\r
++uintptr_t MGL_EXPORT mgl_data_tridmat_(uintptr_t *A, uintptr_t *B, uintptr_t *C, uintptr_t *D, const char *how, int);\r
++\r
++/// Returns pointer to data element [i,j,k]\r
++MGL_EXPORT mreal *mgl_data_value(HMDT dat, long i,long j,long k);\r
++/// Returns pointer to internal data array\r
++MGL_EXPORT mreal *mgl_data_data(HMDT dat);\r
++\r
++/// Gets the x-size of the data.\r
++long MGL_EXPORT mgl_data_get_nx(HCDT d);\r
++long MGL_EXPORT mgl_data_get_nx_(uintptr_t *d);\r
++/// Gets the y-size of the data.\r
++long MGL_EXPORT mgl_data_get_ny(HCDT d);\r
++long MGL_EXPORT mgl_data_get_ny_(uintptr_t *d);\r
++/// Gets the z-size of the data.\r
++long MGL_EXPORT mgl_data_get_nz(HCDT d);\r
++long MGL_EXPORT mgl_data_get_nz_(uintptr_t *d);\r
++\r
++/// Get the data which is direct multiplication (like, d[i,j] = this[i]*a[j] and so on)\r
++HMDT MGL_EXPORT mgl_data_combine(HCDT dat1, HCDT dat2);\r
++uintptr_t MGL_EXPORT mgl_data_combine_(uintptr_t *dat1, uintptr_t *dat2);\r
++/// Extend data dimensions\r
++void MGL_EXPORT mgl_data_extend(HMDT dat, long n1, long n2);\r
++void MGL_EXPORT mgl_data_extend_(uintptr_t *dat, int *n1, int *n2);\r
++/// Insert data rows/columns/slices\r
++void MGL_EXPORT mgl_data_insert(HMDT dat, char dir, long at, long num);\r
++void MGL_EXPORT mgl_data_insert_(uintptr_t *dat, const char *dir, int *at, int *num, int);\r
++/// Delete data rows/columns/slices\r
++void MGL_EXPORT mgl_data_delete(HMDT dat, char dir, long at, long num);\r
++void MGL_EXPORT mgl_data_delete_(uintptr_t *dat, const char *dir, int *at, int *num, int);\r
++/// Joind another data array\r
++void MGL_EXPORT mgl_data_join(HMDT dat, HCDT d);\r
++void MGL_EXPORT mgl_data_join_(uintptr_t *dat, uintptr_t *d);\r
++\r
++/// Smooth the data on specified direction or directions\r
++/** String \a dir may contain:\r
++ * ‘x’, ‘y’, ‘z’ for 1st, 2nd or 3d dimension;\r
++ * ‘dN’ for linear averaging over N points;\r
++ * ‘3’ for linear averaging over 3 points;\r
++ * ‘5’ for linear averaging over 5 points.\r
++ * By default quadratic averaging over 5 points is used. */\r
++void MGL_EXPORT mgl_data_smooth(HMDT d, const char *dirs, mreal delta);\r
++void MGL_EXPORT mgl_data_smooth_(uintptr_t *dat, const char *dirs, mreal *delta,int);\r
++/// Get array which is result of summation in given direction or directions\r
++HMDT MGL_EXPORT mgl_data_sum(HCDT dat, const char *dir);\r
++uintptr_t MGL_EXPORT mgl_data_sum_(uintptr_t *dat, const char *dir,int);\r
++/// Get array which is result of maximal values in given direction or directions\r
++HMDT MGL_EXPORT mgl_data_max_dir(HCDT dat, const char *dir);\r
++uintptr_t MGL_EXPORT mgl_data_max_dir_(uintptr_t *dat, const char *dir,int);\r
++/// Get array which is result of minimal values in given direction or directions\r
++HMDT MGL_EXPORT mgl_data_min_dir(HCDT dat, const char *dir);\r
++uintptr_t MGL_EXPORT mgl_data_min_dir_(uintptr_t *dat, const char *dir,int);\r
++/// Cumulative summation the data in given direction or directions\r
++void MGL_EXPORT mgl_data_cumsum(HMDT dat, const char *dir);\r
++void MGL_EXPORT mgl_data_cumsum_(uintptr_t *dat, const char *dir,int);\r
++/// Integrate (cumulative summation) the data in given direction or directions\r
++void MGL_EXPORT mgl_data_integral(HMDT dat, const char *dir);\r
++void MGL_EXPORT mgl_data_integral_(uintptr_t *dat, const char *dir,int);\r
++/// Differentiate the data in given direction or directions\r
++void MGL_EXPORT mgl_data_diff(HMDT dat, const char *dir);\r
++void MGL_EXPORT mgl_data_diff_(uintptr_t *dat, const char *dir,int);\r
++/// Differentiate the parametrically specified data along direction v1 with v2,v3=const (v3 can be NULL)\r
++void MGL_EXPORT mgl_data_diff_par(HMDT dat, HCDT v1, HCDT v2, HCDT v3);\r
++void MGL_EXPORT mgl_data_diff_par_(uintptr_t *dat, uintptr_t *v1, uintptr_t *v2, uintptr_t *v3);\r
++/// Double-differentiate (like Laplace operator) the data in given direction\r
++void MGL_EXPORT mgl_data_diff2(HMDT dat, const char *dir);\r
++void MGL_EXPORT mgl_data_diff2_(uintptr_t *dat, const char *dir,int);\r
++/// Swap left and right part of the data in given direction (useful for Fourier spectrum)\r
++void MGL_EXPORT mgl_data_swap(HMDT dat, const char *dir);\r
++void MGL_EXPORT mgl_data_swap_(uintptr_t *dat, const char *dir,int);\r
++/// Roll data along direction dir by num slices\r
++void MGL_EXPORT mgl_data_roll(HMDT dat, char dir, long num);\r
++void MGL_EXPORT mgl_data_roll_(uintptr_t *dat, const char *dir, int *num, int);\r
++/// Mirror the data in given direction (useful for Fourier spectrum)\r
++void MGL_EXPORT mgl_data_mirror(HMDT dat, const char *dir);\r
++void MGL_EXPORT mgl_data_mirror_(uintptr_t *dat, const char *dir,int);\r
++/// Sort rows (or slices) by values of specified column\r
++void MGL_EXPORT mgl_data_sort(HMDT dat, long idx, long idy);\r
++void MGL_EXPORT mgl_data_sort_(uintptr_t *dat, int *idx, int *idy);\r
++/// Return dilated array of 0 or 1 for data values larger val\r
++void MGL_EXPORT mgl_data_dilate(HMDT dat, mreal val, long step);\r
++void MGL_EXPORT mgl_data_dilate_(uintptr_t *dat, mreal *val, int *step);\r
++/// Return eroded array of 0 or 1 for data values larger val\r
++void MGL_EXPORT mgl_data_erode(HMDT dat, mreal val, long step);\r
++void MGL_EXPORT mgl_data_erode_(uintptr_t *dat, mreal *val, int *step);\r
++\r
++/// Apply Hankel transform\r
++void MGL_EXPORT mgl_data_hankel(HMDT dat, const char *dir);\r
++void MGL_EXPORT mgl_data_hankel_(uintptr_t *dat, const char *dir,int);\r
++/// Apply Sin-Fourier transform\r
++void MGL_EXPORT mgl_data_sinfft(HMDT dat, const char *dir);\r
++void MGL_EXPORT mgl_data_sinfft_(uintptr_t *dat, const char *dir,int);\r
++/// Apply Cos-Fourier transform\r
++void MGL_EXPORT mgl_data_cosfft(HMDT dat, const char *dir);\r
++void MGL_EXPORT mgl_data_cosfft_(uintptr_t *dat, const char *dir,int);\r
++/// Fill data by coordinates/momenta samples for Hankel ('h') or Fourier ('f') transform\r
++/** Parameter \a how may contain:\r
++ * ‘x‘,‘y‘,‘z‘ for direction (only one will be used),\r
++ * ‘k‘ for momenta samples,\r
++ * ‘h‘ for Hankel samples,\r
++ * ‘f‘ for Cartesian/Fourier samples (default). */\r
++void MGL_EXPORT mgl_data_fill_sample(HMDT dat, const char *how);\r
++void MGL_EXPORT mgl_data_fill_sample_(uintptr_t *dat, const char *how,int);\r
++/// Find correlation between 2 data arrays\r
++HMDT MGL_EXPORT mgl_data_correl(HCDT dat1, HCDT dat2, const char *dir);\r
++uintptr_t MGL_EXPORT mgl_data_correl_(uintptr_t *dat1, uintptr_t *dat2, const char *dir,int);\r
++/// Apply wavelet transform\r
++/** Parameter \a dir may contain:\r
++ * ‘x‘,‘y‘,‘z‘ for directions,\r
++ * ‘d‘ for daubechies, ‘D‘ for centered daubechies,\r
++ * ‘h‘ for haar, ‘H‘ for centered haar,\r
++ * ‘b‘ for bspline, ‘B‘ for centered bspline,\r
++ * ‘i‘ for applying inverse transform. */\r
++void MGL_EXPORT mgl_data_wavelet(HMDT dat, const char *how, int k);\r
++void MGL_EXPORT mgl_data_wavelet_(uintptr_t *d, const char *dir, int *k,int);\r
++\r
++/// Allocate and prepare data for Fourier transform by nthr threads\r
++MGL_EXPORT void *mgl_fft_alloc(long n, void **space, long nthr);\r
++MGL_EXPORT void *mgl_fft_alloc_thr(long n);\r
++/// Free data for Fourier transform\r
++void MGL_EXPORT mgl_fft_free(void *wt, void **ws, long nthr);\r
++void MGL_EXPORT mgl_fft_free_thr(void *wt);\r
++/// Make Fourier transform of data x of size n and step s between points\r
++void MGL_EXPORT mgl_fft(double *x, long s, long n, const void *wt, void *ws, int inv);\r
++/// Clear internal data for speeding up FFT and Hankel transforms\r
++void MGL_EXPORT mgl_clear_fft();\r
++\r
++/// Interpolate by cubic spline the data to given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
++mreal MGL_EXPORT mgl_data_spline(HCDT dat, mreal x,mreal y,mreal z);\r
++mreal MGL_EXPORT mgl_data_spline_(uintptr_t *dat, mreal *x,mreal *y,mreal *z);\r
++/// Interpolate by cubic spline the data and return its derivatives at given point x=[0...nx-1], y=[0...ny-1], z=[0...nz-1]\r
++mreal MGL_EXPORT mgl_data_spline_ext(HCDT dat, mreal x,mreal y,mreal z, mreal *dx,mreal *dy,mreal *dz);\r
++mreal MGL_EXPORT mgl_data_spline_ext_(uintptr_t *dat, mreal *x,mreal *y,mreal *z, mreal *dx,mreal *dy,mreal *dz);\r
++/// Prepare coefficients for global spline interpolation\r
++HMDT MGL_EXPORT mgl_gspline_init(HCDT x, HCDT v);\r
++uintptr_t MGL_EXPORT mgl_gspline_init_(uintptr_t *x, uintptr_t *v);\r
++/// Evaluate global spline (and its derivatives d1, d2 if not NULL) using prepared coefficients \a coef\r
++mreal MGL_EXPORT mgl_gspline(HCDT coef, mreal dx, mreal *d1, mreal *d2);\r
++mreal MGL_EXPORT mgl_gspline_(uintptr_t *c, mreal *dx, mreal *d1, mreal *d2);\r
++/// Return an approximated x-value (root) when dat(x) = val\r
++mreal MGL_EXPORT mgl_data_solve_1d(HCDT dat, mreal val, int spl, long i0);\r
++mreal MGL_EXPORT mgl_data_solve_1d_(uintptr_t *dat, mreal *val, int *spl, int *i0);\r
++/// Return an approximated value (root) when dat(x) = val\r
++HMDT MGL_EXPORT mgl_data_solve(HCDT dat, mreal val, char dir, HCDT i0, int norm);\r
++uintptr_t MGL_EXPORT mgl_data_solve_(uintptr_t *dat, mreal *val, const char *dir, uintptr_t *i0, int *norm,int);\r
++\r
++/// Get trace of the data array\r
++HMDT MGL_EXPORT mgl_data_trace(HCDT d);\r
++uintptr_t MGL_EXPORT mgl_data_trace_(uintptr_t *d);\r
++/// Resize the data to new sizes\r
++HMDT MGL_EXPORT mgl_data_resize(HCDT dat, long mx,long my,long mz);\r
++uintptr_t MGL_EXPORT mgl_data_resize_(uintptr_t *dat, int *mx,int *my,int *mz);\r
++/// Resize the data to new sizes of box [x1,x2]*[y1,y2]*[z1,z2]\r
++HMDT MGL_EXPORT mgl_data_resize_box(HCDT dat, long mx,long my,long mz,mreal x1,mreal x2,mreal y1,mreal y2,mreal z1,mreal z2);\r
++uintptr_t MGL_EXPORT mgl_data_resize_box_(uintptr_t *dat, int *mx,int *my,int *mz,mreal *x1,mreal *x2,mreal *y1,mreal *y2,mreal *z1,mreal *z2);\r
++/// Create n-th points distribution of this data values in range [v1, v2]\r
++HMDT MGL_EXPORT mgl_data_hist(HCDT dat, long n, mreal v1, mreal v2, long nsub);\r
++uintptr_t MGL_EXPORT mgl_data_hist_(uintptr_t *dat, int *n, mreal *v1, mreal *v2, int *nsub);\r
++/// Create n-th points distribution of this data values in range [v1, v2] with weight w\r
++HMDT MGL_EXPORT mgl_data_hist_w(HCDT dat, HCDT weight, long n, mreal v1, mreal v2, long nsub);\r
++uintptr_t MGL_EXPORT mgl_data_hist_w_(uintptr_t *dat, uintptr_t *weight, int *n, mreal *v1, mreal *v2, int *nsub);\r
++/// Get momentum (1D-array) of data along direction 'dir'. String looks like "x1" for median in x-direction, "x2" for width in x-dir and so on.\r
++HMDT MGL_EXPORT mgl_data_momentum(HCDT dat, char dir, const char *how);\r
++uintptr_t MGL_EXPORT mgl_data_momentum_(uintptr_t *dat, char *dir, const char *how, int,int);\r
++/// Get pulse properties: pulse maximum and its position, pulse duration near maximum and by half height.\r
++HMDT MGL_EXPORT mgl_data_pulse(HCDT dat, char dir);\r
++uintptr_t MGL_EXPORT mgl_data_pulse_(uintptr_t *dat, char *dir,int);\r
++/// Get array which values is result of interpolation this for coordinates from other arrays\r
++HMDT MGL_EXPORT mgl_data_evaluate(HCDT dat, HCDT idat, HCDT jdat, HCDT kdat, int norm);\r
++uintptr_t MGL_EXPORT mgl_data_evaluate_(uintptr_t *dat, uintptr_t *idat, uintptr_t *jdat, uintptr_t *kdat, int *norm);\r
++/// Set as the data envelop\r
++void MGL_EXPORT mgl_data_envelop(HMDT dat, char dir);\r
++void MGL_EXPORT mgl_data_envelop_(uintptr_t *dat, const char *dir, int);\r
++/// Remove phase jump\r
++void MGL_EXPORT mgl_data_sew(HMDT dat, const char *dirs, mreal da);\r
++void MGL_EXPORT mgl_data_sew_(uintptr_t *dat, const char *dirs, mreal *da, int);\r
++/// Crop the data\r
++void MGL_EXPORT mgl_data_crop(HMDT dat, long n1, long n2, char dir);\r
++void MGL_EXPORT mgl_data_crop_(uintptr_t *dat, int *n1, int *n2, const char *dir,int);\r
++/// Crop the data to be most optimal for FFT (i.e. to closest value of 2^n*3^m*5^l)\r
++void MGL_EXPORT mgl_data_crop_opt(HMDT dat, const char *how);\r
++void MGL_EXPORT mgl_data_crop_opt_(uintptr_t *dat, const char *how,int);\r
++/// Remove rows with duplicate values in column id\r
++void MGL_EXPORT mgl_data_clean(HMDT dat, long id);\r
++void MGL_EXPORT mgl_data_clean_(uintptr_t *dat, int *id);\r
++\r
++/// Multiply the data by other one for each element\r
++void MGL_EXPORT mgl_data_mul_dat(HMDT dat, HCDT d);\r
++void MGL_EXPORT mgl_data_mul_dat_(uintptr_t *dat, uintptr_t *d);\r
++/// Divide the data by other one for each element\r
++void MGL_EXPORT mgl_data_div_dat(HMDT dat, HCDT d);\r
++void MGL_EXPORT mgl_data_div_dat_(uintptr_t *dat, uintptr_t *d);\r
++/// Add the other data\r
++void MGL_EXPORT mgl_data_add_dat(HMDT dat, HCDT d);\r
++void MGL_EXPORT mgl_data_add_dat_(uintptr_t *dat, uintptr_t *d);\r
++/// Subtract the other data\r
++void MGL_EXPORT mgl_data_sub_dat(HMDT dat, HCDT d);\r
++void MGL_EXPORT mgl_data_sub_dat_(uintptr_t *dat, uintptr_t *d);\r
++/// Multiply each element by the number\r
++void MGL_EXPORT mgl_data_mul_num(HMDT dat, mreal d);\r
++void MGL_EXPORT mgl_data_mul_num_(uintptr_t *dat, mreal *d);\r
++/// Divide each element by the number\r
++void MGL_EXPORT mgl_data_div_num(HMDT dat, mreal d);\r
++void MGL_EXPORT mgl_data_div_num_(uintptr_t *dat, mreal *d);\r
++/// Add the number\r
++void MGL_EXPORT mgl_data_add_num(HMDT dat, mreal d);\r
++void MGL_EXPORT mgl_data_add_num_(uintptr_t *dat, mreal *d);\r
++/// Subtract the number\r
++void MGL_EXPORT mgl_data_sub_num(HMDT dat, mreal d);\r
++void MGL_EXPORT mgl_data_sub_num_(uintptr_t *dat, mreal *d);\r
++\r
++/// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for amplitude and phase\r
++HMDT MGL_EXPORT mgl_transform_a(HCDT am, HCDT ph, const char *tr);\r
++uintptr_t MGL_EXPORT mgl_transform_a_(uintptr_t *am, uintptr_t *ph, const char *tr, int);\r
++/// Integral data transformation (like Fourier 'f' or 'i', Hankel 'h' or None 'n') for real and imaginary parts\r
++HMDT MGL_EXPORT mgl_transform(HCDT re, HCDT im, const char *tr);\r
++uintptr_t MGL_EXPORT mgl_transform_(uintptr_t *re, uintptr_t *im, const char *tr, int);\r
++/// Apply Fourier transform for the data and save result into it\r
++void MGL_EXPORT mgl_data_fourier(HMDT re, HMDT im, const char *dir);\r
++void MGL_EXPORT mgl_data_fourier_(uintptr_t *re, uintptr_t *im, const char *dir, int l);\r
++/// Short time Fourier analysis for real and imaginary parts. Output is amplitude of partial Fourier (result will have size {dn, floor(nx/dn), ny} for dir='x'\r
++HMDT MGL_EXPORT mgl_data_stfa(HCDT re, HCDT im, long dn, char dir);\r
++uintptr_t MGL_EXPORT mgl_data_stfa_(uintptr_t *re, uintptr_t *im, int *dn, char *dir, int);\r
++\r
++/// Do something like Delone triangulation for 3d points\r
++HMDT MGL_EXPORT mgl_triangulation_3d(HCDT x, HCDT y, HCDT z);\r
++uintptr_t MGL_EXPORT mgl_triangulation_3d_(uintptr_t *x, uintptr_t *y, uintptr_t *z);\r
++/// Do Delone triangulation for 2d points\r
++HMDT MGL_EXPORT mgl_triangulation_2d(HCDT x, HCDT y);\r
++uintptr_t MGL_EXPORT mgl_triangulation_2d_(uintptr_t *x, uintptr_t *y);\r
++\r
++/// Find root for nonlinear equation\r
++mreal MGL_EXPORT mgl_find_root(mreal (*func)(mreal val, void *par), mreal ini, void *par);\r
++/// Find root for nonlinear equation defined by textual formula\r
++mreal MGL_EXPORT mgl_find_root_txt(const char *func, mreal ini, char var_id);\r
++mreal MGL_EXPORT mgl_find_root_txt_(const char *func, mreal *ini, const char *var_id,int,int);\r
++/// Find roots for nonlinear equation defined by textual formula\r
++HMDT MGL_EXPORT mgl_data_roots(const char *func, HCDT ini, char var_id);\r
++uintptr_t MGL_EXPORT mgl_data_roots_(const char *func, uintptr_t *ini, const char *var_id,int,int);\r
++\r
++//-----------------------------------------------------------------------------\r
++/// Create HMEX object for expression evaluating\r
++HMEX MGL_EXPORT mgl_create_expr(const char *expr);\r
++uintptr_t MGL_EXPORT mgl_create_expr_(const char *expr, int);\r
++/// Delete HMEX object\r
++void MGL_EXPORT mgl_delete_expr(HMEX ex);\r
++void MGL_EXPORT mgl_delete_expr_(uintptr_t *ex);\r
++/// Return value of expression for given x,y,z variables\r
++double MGL_EXPORT mgl_expr_eval(HMEX ex, double x, double y,double z);\r
++double MGL_EXPORT mgl_expr_eval_(uintptr_t *ex, mreal *x, mreal *y, mreal *z);\r
++/// Return value of expression for given variables\r
++double MGL_EXPORT mgl_expr_eval_v(HMEX ex, mreal *vars);\r
++/// Return value of expression differentiation over variable dir for given x,y,z variables\r
++double MGL_EXPORT mgl_expr_diff(HMEX ex, char dir, double x, double y,double z);\r
++double MGL_EXPORT mgl_expr_diff_(uintptr_t *ex, const char *dir, mreal *x, mreal *y, mreal *z, int);\r
++/// Return value of expression differentiation over variable dir for given variables\r
++double MGL_EXPORT mgl_expr_diff_v(HMEX ex, char dir, mreal *vars);\r
++//-----------------------------------------------------------------------------\r
++#ifdef __cplusplus\r
++}\r
++#endif\r
++#endif\r
++//-----------------------------------------------------------------------------\r
{ return mglDataC(true, mgl_qo3d_solve_c(ham, &ini_re, &ini_im, &ray, r, k0, 0, 0, 0)); }\r
inline mglDataC mglQO3dc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, const mglDataA &ray, mglData &xx, mglData &yy, mglData &zz, mreal r=1, mreal k0=100)\r
{ return mglDataC(true, mgl_qo3d_solve_c(ham, &ini_re, &ini_im, &ray, r, k0, &xx, &yy, &zz)); }\r
+ /// Saves result of ODE solving for var complex variables with right part func (separated by ';') and initial conditions x0 over time interval [0,tmax] with time step dt\r
+ inline mglDataC mglODEc(const char *func, const char *var, const mglDataA &ini, mreal dt=0.1, mreal tmax=10)\r
+ { return mglDataC(true, mgl_ode_solve_str_c(func,var, &ini, dt, tmax)); }\r
+ //-----------------------------------------------------------------------------\r
++/// Get array as solution of tridiagonal system of equations a[i]*x[i-1]+b[i]*x[i]+c[i]*x[i+1]=d[i]\r
++/** String \a how may contain:\r
++ * 'x', 'y', 'z' for solving along x-,y-,z-directions, or\r
++ * 'h' for solving along hexagonal direction at x-y plain (need nx=ny),\r
++ * 'c' for using periodical boundary conditions,\r
++ * 'd' for diffraction/diffuse calculation. */\r
++inline mglDataC mglTridMatC(const mglDataA &A, const mglDataA &B, const mglDataA &C, const mglDataC &D, const char *how)\r
++{ return mglDataC(true, mgl_datac_tridmat(&A, &B, &C, &D, how)); }\r
+//-----------------------------------------------------------------------------\r
/// Get array as solution of tridiagonal system of equations a[i]*x[i-1]+b[i]*x[i]+c[i]*x[i+1]=d[i]\r
/** String \a how may contain:\r
* 'x', 'y', 'z' for solving along x-,y-,z-directions, or\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * define.h is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#ifndef _MGL_DEFINE_H_\r
++#define _MGL_DEFINE_H_\r
++//-----------------------------------------------------------------------------\r
++// Disable warnings for MSVC:\r
++// 4190 - C-linkage of std::complex,\r
++// 4996 - deprecated abi functions\r
++// 4786 - disable warnings on 255 char debug symbols\r
++// 4231 - disable warnings on extern before template instantiation\r
++// 4800 - "int,uint32_t,etc" forcing value to bool 'true' or 'false' (performance warning)\r
++// 4244 - conversion from 'mreal,double' to 'float', possible loss of data\r
++// 4267 - conversion from 'size_t' to 'long,int,etc', possible loss of data\r
++// 4305 - truncation from 'double' to 'float'\r
++#if defined(_MSC_VER)\r
++#pragma warning(disable: 4996 4190 4786 4231 4800 4244 4267 4305)\r
++#endif\r
++\r
++#include "mgl2/config.h"\r
++#ifndef SWIG\r
++\r
++#if MGL_HAVE_PTHR_WIDGET|MGL_HAVE_PTHREAD\r
++#include <pthread.h>\r
++#endif\r
++\r
++#include "mgl2/dllexport.h"\r
++#if defined(_MSC_VER)\r
++#define MGL_OBSOLETE MGL_NO_EXPORT\r
++#else\r
++#define MGL_OBSOLETE MGL_EXPORT\r
++#endif\r
++\r
++#if MGL_HAVE_ATTRIBUTE\r
++#define MGL_FUNC_CONST __attribute__((const))\r
++#define MGL_FUNC_PURE __attribute__((pure))\r
++#else\r
++#define MGL_FUNC_CONST\r
++#define MGL_FUNC_PURE\r
++#endif\r
++#define MGL_EXPORT_CONST MGL_EXPORT MGL_FUNC_CONST\r
++#define MGL_EXPORT_PURE MGL_EXPORT MGL_FUNC_PURE\r
++#define MGL_LOCAL_CONST MGL_NO_EXPORT MGL_FUNC_CONST\r
++#define MGL_LOCAL_PURE MGL_NO_EXPORT MGL_FUNC_PURE\r
++\r
++#if MGL_HAVE_RVAL // C++11 don't support register keyword\r
++#if (!defined(_MSC_VER)) || (defined(_MSC_VER) && (_MSC_VER < 1310))\r
++#define register\r
++#endif\r
++#endif\r
++\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++#ifdef WIN32 //_MSC_VER needs this before math.h\r
++#define _USE_MATH_DEFINES\r
++#endif\r
++\r
++#ifdef MGL_SRC\r
++\r
++#if MGL_USE_GETTEXT\r
++ #include <libintl.h>\r
++ #define _(x) gettext(x)\r
++#else\r
++ #define _(x) (x)\r
++#endif\r
++\r
++\r
++#if MGL_HAVE_ZLIB\r
++#include <zlib.h>\r
++#ifndef Z_BEST_COMPRESSION\r
++#define Z_BEST_COMPRESSION 9\r
++#endif\r
++#else\r
++#define gzFile FILE*\r
++#define gzread(fp,buf,size) fread(buf,1,size,fp)\r
++#define gzopen fopen\r
++#define gzclose fclose\r
++#define gzprintf fprintf\r
++#define gzgets(fp,str,size) fgets(str,size,fp)\r
++#define gzgetc fgetc\r
++#endif\r
++#endif\r
++\r
++#if (defined(_MSC_VER) && (_MSC_VER<1600)) || defined(__BORLANDC__)\r
++typedef signed char int8_t;\r
++typedef signed short int16_t;\r
++typedef signed long int32_t;\r
++typedef signed long long int64_t;\r
++typedef unsigned char uint8_t;\r
++typedef unsigned short uint16_t;\r
++typedef unsigned long uint32_t;\r
++typedef unsigned long long uint64_t;\r
++#else\r
++#include <stdint.h>\r
++#endif\r
++#if defined(__BORLANDC__)\r
++typedef unsigned long uintptr_t;\r
++#endif\r
++\r
++#include <math.h>\r
++#include <stdio.h>\r
++#include <stdlib.h>\r
++#include <string.h>\r
++#include <wchar.h>\r
++\r
++#if defined(_MSC_VER)\r
++#define collapse(a) // MSVS don't support OpenMP 3.*\r
++#if (_MSC_VER<=1800)\r
++#define strtoull _strtoui64\r
++//#define hypot _hypot\r
++#define getcwd _getcwd\r
++#define chdir _chdir // BORLAND has chdir\r
++#endif\r
++#define snprintf _snprintf\r
++#if (_MSC_VER<1600) // based on https://hg.python.org/cpython/rev/9aedb876c2d7\r
++#define hypot _hypot\r
++#endif\r
++#endif\r
++\r
++#if !MGL_SYS_NAN\r
++#include <float.h>\r
++#include <math.h>\r
++const unsigned long long mgl_nan[2] = {0x7fffffffffffffff, 0x7fffffff};\r
++const unsigned long long mgl_inf[2] = {0x7ff0000000000000, 0x7f800000};\r
++#define NANd (*(double*)mgl_nan)\r
++#define NANf (*(float*)(mgl_nan+1))\r
++#define INFd (*(double*)mgl_inf)\r
++#define INFf (*(float*)(mgl_inf+1))\r
++\r
++#if !defined(NAN)\r
++#if MGL_USE_DOUBLE\r
++#define NAN NANd\r
++#else\r
++#define NAN NANf\r
++#endif\r
++#endif\r
++\r
++#if !defined(INFINITY)\r
++#if MGL_USE_DOUBLE\r
++#define INFINITY INFd\r
++#else\r
++#define INFINITY INFf\r
++#endif\r
++#endif\r
++#endif // !MGL_SYS_NAN\r
++\r
++#ifndef M_PI\r
++#define M_PI 3.14159265358979323846 /* pi */\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++#ifdef WIN32\r
++#define mglprintf _snwprintf\r
++#else\r
++#define mglprintf swprintf\r
++#endif\r
++//#define FLT_EPS 1.1920928955078125e-07\r
++//-----------------------------------------------------------------------------\r
++#if MGL_USE_DOUBLE\r
++typedef double mreal;\r
++#define MGL_EPSILON (1.+1e-10)\r
++#define MGL_MIN_VAL 1e-307\r
++#else\r
++typedef float mreal;\r
++#define MGL_EPSILON (1.+1e-5)\r
++#define MGL_MIN_VAL 1e-37\r
++#endif\r
++#define MGL_FEPSILON (1.+1e-5)\r
++//-----------------------------------------------------------------------------\r
++#ifndef MGL_CMAP_COLOR\r
++#define MGL_CMAP_COLOR 32\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++#ifndef MGL_DEF_VIEWER\r
++#define MGL_DEF_VIEWER "evince"\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++enum{ // types of predefined curvelinear coordinate systems\r
++ mglCartesian = 0, // no transformation\r
++ mglPolar,\r
++ mglSpherical,\r
++ mglParabolic,\r
++ mglParaboloidal,\r
++ mglOblate,\r
++ mglProlate,\r
++ mglElliptic,\r
++ mglToroidal,\r
++ mglBispherical,\r
++ mglBipolar,\r
++ mglLogLog,\r
++ mglLogX,\r
++ mglLogY\r
++};\r
++//-----------------------------------------------------------------------------\r
++// types of drawing\r
++#define MGL_DRAW_WIRE 0 // fastest, no faces\r
++#define MGL_DRAW_FAST 1 // fast, no color interpolation\r
++#define MGL_DRAW_NORM 2 // high quality, slower\r
++#define MGL_DRAW_LMEM 4 // low memory usage (direct to pixel)\r
++#define MGL_DRAW_DOTS 8 // draw dots instead of primitives\r
++#define MGL_DRAW_NONE 9 // no ouput (for testing only)\r
++//-----------------------------------------------------------------------------\r
++enum{ // Codes for warnings/messages\r
++ mglWarnNone = 0,// Everything OK\r
++ mglWarnDim, // Data dimension(s) is incompatible\r
++ mglWarnLow, // Data dimension(s) is too small\r
++ mglWarnNeg, // Minimal data value is negative\r
++ mglWarnFile, // No file or wrong data dimensions\r
++ mglWarnMem, // Not enough memory\r
++ mglWarnZero, // Data values are zero\r
++ mglWarnLeg, // No legend entries\r
++ mglWarnSlc, // Slice value is out of range\r
++ mglWarnCnt, // Number of contours is zero or negative\r
++ mglWarnOpen, // Couldn't open file\r
++ mglWarnLId, // Light: ID is out of range\r
++ mglWarnSize, // Setsize: size(s) is zero or negative\r
++ mglWarnFmt, // Format is not supported for that build\r
++ mglWarnTern, // Axis ranges are incompatible\r
++ mglWarnNull, // Pointer is NULL\r
++ mglWarnSpc, // Not enough space for plot\r
++ mglScrArg, // Wrong argument(s) in MGL script\r
++ mglScrCmd, // Wrong command in MGL script\r
++ mglScrLong, // Too long line in MGL script\r
++ mglScrStr, // Unbalanced ' in MGL script\r
++ mglScrTemp, // Change temporary data in MGL script\r
++ mglWarnEnd // Maximal number of warnings (must be last)\r
++};\r
++//-----------------------------------------------------------------------------\r
++#define MGL_DEF_PAL "bgrcmyhlnqeupH" // default palette\r
++#define MGL_DEF_SCH "BbcyrR" // default palette\r
++#define MGL_COLORS "kwrgbcymhWRGBCYMHlenpquLENPQU"\r
++//-----------------------------------------------------------------------------\r
++/// Brushes for mask with symbol "-+=;oOsS~<>jdD*^" correspondingly\r
++extern MGL_EXPORT uint64_t mgl_mask_val[16];\r
++#define MGL_MASK_ID "-+=;oOsS~<>jdD*^"\r
++#define MGL_SOLID_MASK 0xffffffffffffffff\r
++//-----------------------------------------------------------------------------\r
++#define MGL_TRANSP_NORM 0x000000\r
++#define MGL_TRANSP_GLASS 0x000001\r
++#define MGL_TRANSP_LAMP 0x000002\r
++#define MGL_ENABLE_CUT 0x000004 ///< Flag which determines how points outside bounding box are drown.\r
++#define MGL_ENABLE_RTEXT 0x000008 ///< Use text rotation along axis\r
++#define MGL_AUTO_FACTOR 0x000010 ///< Enable autochange PlotFactor\r
++#define MGL_ENABLE_ALPHA 0x000020 ///< Flag that Alpha is used\r
++#define MGL_ENABLE_LIGHT 0x000040 ///< Flag of using lightning\r
++#define MGL_TICKS_ROTATE 0x000080 ///< Allow ticks rotation\r
++#define MGL_TICKS_SKIP 0x000100 ///< Allow ticks rotation\r
++// flags for internal use only\r
++#define MGL_DISABLE_SCALE 0x000200 ///< Temporary flag for disable scaling (used for axis)\r
++#define MGL_FINISHED 0x000400 ///< Flag that final picture (i.e. mglCanvas::G) is ready\r
++#define MGL_USE_GMTIME 0x000800 ///< Use gmtime instead of localtime\r
++#define MGL_SHOW_POS 0x001000 ///< Switch to show or not mouse click position\r
++#define MGL_CLF_ON_UPD 0x002000 ///< Clear plot before Update()\r
++#define MGL_NOSUBTICKS 0x004000 ///< Disable subticks drawing (for bounding box)\r
++#define MGL_LOCAL_LIGHT 0x008000 ///< Keep light sources for each inplot\r
++#define MGL_VECT_FRAME 0x010000 ///< Use DrwDat to remember all data of frames\r
++#define MGL_REDUCEACC 0x020000 ///< Reduce accuracy of points (to reduc size of output files)\r
++#define MGL_PREFERVC 0x040000 ///< Prefer vertex color instead of texture if output format supports\r
++#define MGL_ONESIDED 0x080000 ///< Render only front side of surfaces if output format supports (for debugging)\r
++#define MGL_NO_ORIGIN 0x100000 ///< Don't draw tick labels at axis origin\r
++<<<<<<< HEAD\r
++#define MGL_GRAY_MODE 0x100000 ///< Convert all colors to gray ones\r
++=======\r
++#define MGL_GRAY_MODE 0x200000 ///< Convert all colors to gray ones\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++//-----------------------------------------------------------------------------\r
++#if MGL_HAVE_C99_COMPLEX\r
++#include <complex.h>\r
++#if MGL_USE_DOUBLE\r
++typedef double _Complex mdual;\r
++#else\r
++typedef float _Complex mdual;\r
++#endif\r
++#ifndef _Complex_I\r
++#define _Complex_I 1.0i\r
++#endif\r
++const mdual mgl_I=_Complex_I;\r
++#define mgl_abs(x) cabs(x)\r
++#endif\r
++#ifdef __cplusplus\r
++#include <string>\r
++#include <vector>\r
++#if defined(_MSC_VER)\r
++template class MGL_EXPORT std::allocator<char>;\r
++template class MGL_EXPORT std::allocator<wchar_t>;\r
++template struct MGL_EXPORT std::char_traits<char>;\r
++template struct MGL_EXPORT std::char_traits<wchar_t>;\r
++template class MGL_EXPORT std::basic_string< char, std::char_traits<char>, std::allocator<char> >;\r
++template class MGL_EXPORT std::basic_string< wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >;\r
++template class MGL_EXPORT std::vector<long>;\r
++template class MGL_EXPORT std::vector<mreal>;\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++extern float mgl_cos[360]; ///< contain cosine with step 1 degree\r
++//-----------------------------------------------------------------------------\r
++#include <complex>\r
++#if defined(_MSC_VER)\r
++template class MGL_EXPORT std::complex<float>;\r
++template class MGL_EXPORT std::complex<double>;\r
++#endif\r
++typedef std::complex<mreal> dual;\r
++typedef std::complex<double> ddual;\r
++#if !MGL_HAVE_C99_COMPLEX\r
++#define mdual dual\r
++#define mgl_I dual(0,1)\r
++#define mgl_abs(x) abs(x)\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++inline bool mgl_isrange(double a, double b)\r
++{ return fabs(a-b)>MGL_MIN_VAL && a-a==0. && b-b==0.; }\r
++inline bool mgl_isbad(double a) { return a-a!=0; }\r
++inline bool mgl_isbad(dual a) { return a-a!=mreal(0); }\r
++inline bool mgl_isfin(double a) { return a-a==0; }\r
++inline bool mgl_isfin(dual a) { return a-a==mreal(0); }\r
++inline bool mgl_isnum(double a) { return a==a; }\r
++inline bool mgl_isnum(dual a) { return a==a; }\r
++inline bool mgl_isnan(double a) { return a!=a; }\r
++inline bool mgl_isnan(dual a) { return a!=a; }\r
++inline int mgl_sign(double a) { return a<0?-1:1; }\r
++inline long mgl_int(double a) { return long(a+(a>=0?0.5:-0.5)); }\r
++inline double mgl_min(double a, double b) { return a>b?b:a; }\r
++inline double mgl_max(double a, double b) { return a>b?a:b; }\r
++inline void mgl_strncpy(char *a, const char *b, size_t s) { strncpy(a,b,s); a[s-1]=0; }\r
++//-----------------------------------------------------------------------------\r
++extern "C" {\r
++#else\r
++#include <complex.h>\r
++typedef double _Complex ddual;\r
++#define dual mdual\r
++#endif\r
++/// Find length of wchar_t string (bypass standard wcslen bug)\r
++double MGL_EXPORT_CONST mgl_hypot(double x, double y);\r
++/// Find length of wchar_t string (bypass standard wcslen bug)\r
++size_t MGL_EXPORT mgl_wcslen(const wchar_t *str);\r
++/// Get RGB values for given color id or fill by -1 if no one found\r
++void MGL_EXPORT mgl_chrrgb(char id, float rgb[3]);\r
++/// Get number of colors in the string\r
++size_t MGL_EXPORT mgl_get_num_color(const char *s, int smooth);\r
++/// Check if string contain color id and return its number\r
++long MGL_EXPORT mgl_have_color(const char *stl);\r
++/// Find symbol in string excluding {} and return its position or NULL\r
++MGL_EXPORT const char *mglchr(const char *str, char ch);\r
++/// Find any symbol from chr in string excluding {} and return its position or NULL\r
++MGL_EXPORT const char *mglchrs(const char *str, const char *chr);\r
++/// Set number of thread for plotting and data handling (for pthread version only)\r
++void MGL_EXPORT mgl_set_num_thr(int n);\r
++void MGL_EXPORT mgl_set_num_thr_(int *n);\r
++void MGL_EXPORT mgl_test_txt(const char *str, ...);\r
++void MGL_EXPORT mgl_set_test_mode(int enable);\r
++/// Remove spaces at begining and at the end of the string\r
++void MGL_EXPORT mgl_strtrim(char *str);\r
++void MGL_EXPORT mgl_wcstrim(wchar_t *str);\r
++/** Change register to lowercase (only for ANSI symbols) */\r
++void MGL_EXPORT mgl_strlwr(char *str);\r
++void MGL_EXPORT mgl_wcslwr(wchar_t *str);\r
++/// Convert wchar_t* string into char* one\r
++void MGL_EXPORT mgl_wcstombs(char *dst, const wchar_t *src, int size);\r
++/// Clear internal data for speeding up FFT and Hankel transforms\r
++void MGL_EXPORT mgl_clear_fft();\r
++/// Set global warning message\r
++void MGL_EXPORT mgl_set_global_warn(const char *text);\r
++void MGL_EXPORT mgl_set_global_warn_(const char *text,int);\r
++/// Get text of global warning message(s)\r
++MGL_EXPORT const char *mgl_get_global_warn();\r
++int MGL_EXPORT mgl_get_global_warn_(char *out, int len);\r
++/// Setup gettext usage. NOTE: Russian translation MUST be installed.\r
++void MGL_EXPORT mgl_textdomain(const char *argv0, const char *locale);\r
++void MGL_EXPORT mgl_textdomain_(const char *locale, int);\r
++/// size of var array\r
++const int MGL_VS = 'z'-'a'+1;\r
++#ifdef __cplusplus\r
++}\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++#endif\r
++//-----------------------------------------------------------------------------\r
/// Set variant of argument(s) separated by '?' to be used in further commands\r
inline void SetVariant(int var=0)\r
{ mgl_parser_variant(pr, var); }\r
-\r
+ /// Set starting object ID\r
+ inline void StartID(int id=0)\r
+ { mgl_parser_start_id(pr, id); }\r
+ \r
/// Return result of formula evaluation\r
inline mglData Calc(const char *formula)\r
{ return mglData(true,mgl_parser_calc(pr,formula)); }\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * mgl.h is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU General Public License as published by *\r
++ * the Free Software Foundation; either version 2 of the License, or *\r
++ * (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU General Public License *\r
++ * along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#ifndef _MGL_H_\r
++#define _MGL_H_\r
++\r
++#include "mgl2/mgl_cf.h"\r
++#ifdef __cplusplus\r
++#include "mgl2/data.h"\r
++#include "mgl2/datac.h"\r
++#include <sys/stat.h>\r
++//-----------------------------------------------------------------------------\r
++/// Wrapper class for all graphics\r
++class MGL_EXPORT mglGraph\r
++{\r
++ mglGraph(const mglGraph &) {} // copying is not allowed\r
++ const mglGraph &operator=(const mglGraph &t) { return t; }\r
++protected:\r
++ HMGL gr;\r
++public:\r
++ HMPR pr; ///< Pointer to associated MGL parser\r
++ mglGraph(int kind=0, int width=600, int height=400)\r
++ { pr = NULL;\r
++ if(kind==-1) gr=NULL;\r
++#if MGL_HAVE_OPENGL\r
++ else if(kind==1) gr=mgl_create_graph_gl();\r
++#else\r
++ else if(kind==1)\r
++ { gr=mgl_create_graph(width, height);\r
++ SetGlobalWarn("OpenGL support was disabled. Please, enable it and rebuild MathGL."); }\r
++#endif\r
++ else gr=mgl_create_graph(width, height);\r
++ }\r
++ mglGraph(HMGL graph)\r
++ { pr = NULL; gr = graph; mgl_use_graph(gr,1); }\r
++ virtual ~mglGraph()\r
++ { if(mgl_use_graph(gr,-1)<1) mgl_delete_graph(gr); }\r
++ /// Get pointer to internal HMGL object\r
++ inline HMGL Self() { return gr; }\r
++ /// Set default parameters for plotting\r
++ inline void DefaultPlotParam() { mgl_set_def_param(gr); }\r
++ /// Set name of plot for saving filename\r
++ inline void SetPlotId(const char *id) { mgl_set_plotid(gr,id); }\r
++ /// Get name of plot for saving filename\r
++ inline const char *GetPlotId() { return mgl_get_plotid(gr); }\r
++\r
++ /// Ask to stop drawing\r
++ inline void Stop(bool stop=true) { mgl_ask_stop(gr, stop); }\r
++ /// Check if plot termination is asked\r
++ inline bool NeedStop() { return mgl_need_stop(gr); }\r
++ /// Set callback function for event processing\r
++ inline void SetEventFunc(void (*func)(void *), void *par=NULL)\r
++ { mgl_set_event_func(gr, func, par); }\r
++\r
++ /// Set the transparency on/off.\r
++ inline void Alpha(bool enable) { mgl_set_alpha(gr, enable); }\r
++ /// Set the gray-scale mode on/off.\r
++ inline void Gray(bool enable) { mgl_set_gray(gr, enable); }\r
++ /// Set default value of alpha-channel\r
++ inline void SetAlphaDef(double alpha) { mgl_set_alpha_default(gr, alpha); }\r
++ /// Set the transparency type (0 - usual, 1 - glass, 2 - lamp)\r
++ inline void SetTranspType(int type) { mgl_set_transp_type(gr, type); }\r
++ /// Set the size of semi-transparent area around lines, marks, glyphs, ... Default is 1.\r
++ inline void SetPenDelta(double d) { mgl_pen_delta(gr,d); }\r
++\r
++ /// Set the using of light on/off.\r
++ inline void Light(bool enable) { mgl_set_light(gr, enable); }\r
++ /// Switch on/off the specified light source.\r
++ inline void Light(int n,bool enable) { mgl_set_light_n(gr, n, enable); }\r
++ /// Use diffusive light (only for local light sources) -- OBSOLETE\r
++ inline void SetDifLight(bool dif) { mgl_set_light_dif(gr, dif); }\r
++ /// Set to attach light settings to inplot.\r
++ inline void AttachLight(bool enable) { mgl_set_attach_light(gr, enable); }\r
++ /// Add a light source.\r
++ inline void AddLight(int n, mglPoint p, char col='w', double bright=0.5, double ap=0)\r
++ { mgl_add_light_ext(gr, n, p.x, p.y, p.z, col, bright, ap); }\r
++ inline void AddLight(int n, mglPoint r, mglPoint p, char col='w', double bright=0.5, double ap=0)\r
++ { mgl_add_light_loc(gr, n, r.x, r.y, r.z, p.x, p.y, p.z, col, bright, ap); }\r
++ /// Set ambient light brightness\r
++ inline void SetAmbient(double i) { mgl_set_ambbr(gr, i); }\r
++ /// Set diffusive light brightness\r
++ inline void SetDiffuse(double i) { mgl_set_difbr(gr, i); }\r
++ /// Set the fog distance or switch it off (if d=0).\r
++ inline void Fog(double d, double dz=0.25) { mgl_set_fog(gr, d, dz); }\r
++\r
++ /// Set relative width of rectangles in Bars, Barh, BoxPlot, Candle, OHLC (default is 0.7)\r
++ inline void SetBarWidth(double width) { mgl_set_bar_width(gr, width); }\r
++ /// Set default size of marks (locally you can use "size" option)\r
++ inline void SetMarkSize(double size) { mgl_set_mark_size(gr, size); }\r
++ /// Set default size of arrows (locally you can use "size" option)\r
++ inline void SetArrowSize(double size) { mgl_set_arrow_size(gr, size); }\r
++ /// Set number of mesh lines (use 0 to draw all of them)\r
++ inline void SetMeshNum(int num) { mgl_set_meshnum(gr, num); }\r
++ /// Set number of visible faces (use 0 to draw all of them)\r
++ inline void SetFaceNum(int num) { mgl_set_facenum(gr, num); }\r
++\r
++ /// Set cutting for points outside of bounding box\r
++ inline void SetCut(bool cut) { mgl_set_cut(gr, cut); }\r
++ /// Set additional cutting box\r
++ inline void SetCutBox(mglPoint p1, mglPoint p2)\r
++ { mgl_set_cut_box(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z); }\r
++ /// Set the cutting off condition (formula)\r
++ inline void CutOff(const char *EqC) { mgl_set_cutoff(gr, EqC); }\r
++\r
++ /// Set default font size\r
++ inline void SetFontSize(double size) { mgl_set_font_size(gr, size); }\r
++ /// Set default font style and color\r
++ inline void SetFontDef(const char *fnt) { mgl_set_font_def(gr, fnt); }\r
++ /// Set FontSize by size in pt and picture DPI (default is 16 pt for dpi=72)\r
++ virtual void SetFontSizePT(double pt, int dpi=72) { SetFontSize(pt*27.f/dpi); }\r
++ /// Set FontSize by size in centimeters and picture DPI (default is 0.56 cm = 16 pt)\r
++ inline void SetFontSizeCM(double cm, int dpi=72) { SetFontSizePT(cm*28.45f,dpi); }\r
++ /// Set FontSize by size in inch and picture DPI (default is 0.22 in = 16 pt)\r
++ inline void SetFontSizeIN(double in, int dpi=72) { SetFontSizePT(in*72.27f,dpi); }\r
++ /// Load font from file\r
++ inline void LoadFont(const char *name, const char *path=NULL)\r
++ { mgl_load_font(gr, name, path); }\r
++ /// Copy font from another mglGraph instance\r
++ inline void CopyFont(const mglGraph *GR) { mgl_copy_font(gr, GR->gr);}\r
++ /// Restore font (load default font for new HMGL objects)\r
++ inline void RestoreFont() { mgl_restore_font(gr); }\r
++ /// Set to use or not text rotation\r
++ inline void SetRotatedText(bool rotated) { mgl_set_rotated_text(gr, rotated); }\r
++ /// Set default font for all new HMGL and mglGraph objects\r
++ static inline void SetDefFont(const char *name, const char *path=NULL) { mgl_def_font(name,path); }\r
++ /// Add user-defined glyph for symbol and set its optional id\r
++ inline void DefineSymbol(char id, const mglDataA &x, const mglDataA &y)\r
++ { mgl_define_symbol(gr, id, &x, &y); }\r
++\r
++ /// Set default palette\r
++ inline void SetPalette(const char *colors) { mgl_set_palette(gr, colors); }\r
++ /// Set default color scheme\r
++ inline void SetDefScheme(const char *sch) { mgl_set_def_sch(gr, sch); }\r
++\r
++ /// Sets RGB values for color with given id\r
++ static inline void SetColor(char id, double r, double g, double b) { mgl_set_color(id, r, g, b); }\r
++ /// Set mask for face coloring as array of type 'unsigned char[8]'\r
++ static inline void SetMask(char id, const char *mask) { mgl_set_mask(id, mask); }\r
++ /// Set mask for face coloring as uint64_t number\r
++ static inline void SetMask(char id, uint64_t mask) { mgl_set_mask_val(id, mask); }\r
++ /// Set default mask rotation angle\r
++ inline void SetMaskAngle(int angle) { mgl_set_mask_angle(gr, angle); }\r
++\r
++ /// Get last warning code\r
++ inline int GetWarn() { return mgl_get_warn(gr);}\r
++ /// Set warning code ant fill message\r
++ inline void SetWarn(int code, const char *info) { mgl_set_warn(gr,code,info); }\r
++ /// Get text of warning message(s)\r
++ inline const char *Message() { return mgl_get_mess(gr); }\r
++ /// Set global warning message\r
++ static inline void SetGlobalWarn(const char *text) { mgl_set_global_warn(text); }\r
++ /// Get text of global warning message(s)\r
++ static inline const char *GlobalWarn() { return mgl_get_global_warn(); }\r
++ /// Suppress printing warnings to stderr\r
++ static inline void SuppressWarn(bool on) { mgl_suppress_warn(on); }\r
++ /// Check if MathGL version is valid (return false) or not (return true)\r
++ static inline bool CheckVersion(const char *ver) { return mgl_check_version(ver); }\r
++\r
++ /// Set axis range scaling -- simplified way to shift/zoom axis range -- need to replot whole image!\r
++ inline void ZoomAxis(mglPoint p1=mglPoint(0,0,0,0), mglPoint p2=mglPoint(1,1,1,1))\r
++ { mgl_zoom_axis(gr, p1.x,p1.y,p1.z,p1.c, p2.x,p2.y,p2.z,p2.c); }\r
++ /// Add [v1, v2] to the current range in direction dir\r
++ inline void AddRange(char dir, double v1, double v2)\r
++ { mgl_add_range_val(gr, dir, v1, v2); }\r
++ /// Set range in direction dir as [v1, v2]\r
++ inline void SetRange(char dir, double v1, double v2)\r
++ { mgl_set_range_val(gr, dir, v1, v2); }\r
++ /// Set range in direction dir as minimal and maximal values of data a\r
++ inline void SetRange(char dir, const mglDataA &dat, bool add=false)\r
++ { mgl_set_range_dat(gr, dir, &dat, add); }\r
++ /// Set values of axis range as minimal and maximal values of corresponding data\r
++ inline void SetRanges(const mglDataA &xx, const mglDataA &yy, const mglDataA &zz, const mglDataA &cc)\r
++ { mgl_set_range_dat(gr,'x',&xx,0); mgl_set_range_dat(gr,'y',&yy,0);\r
++ mgl_set_range_dat(gr,'z',&zz,0); mgl_set_range_dat(gr,'c',&cc,0); }\r
++ /// Set values of axis range as minimal and maximal values of corresponding data\r
++ inline void SetRanges(const mglDataA &xx, const mglDataA &yy, const mglDataA &zz)\r
++ { mgl_set_range_dat(gr,'x',&xx,0); mgl_set_range_dat(gr,'y',&yy,0);\r
++ mgl_set_range_dat(gr,'z',&zz,0); mgl_set_range_dat(gr,'c',&zz,0); }\r
++ /// Set values of axis range as minimal and maximal values of corresponding data\r
++ inline void SetRanges(const mglDataA &xx, const mglDataA &yy)\r
++ { mgl_set_range_dat(gr,'x',&xx,0); mgl_set_range_dat(gr,'y',&yy,0); }\r
++ /// Set values of axis ranges\r
++ inline void SetRanges(double x1, double x2, double y1, double y2, double z1=0, double z2=0)\r
++ { mgl_set_ranges(gr, x1, x2, y1, y2, z1, z2); }\r
++ /// Set values of axis ranges\r
++ inline void SetRanges(mglPoint p1, mglPoint p2)\r
++ { mgl_set_ranges(gr, p1.x, p2.x, p1.y, p2.y, p1.z, p2.z); }\r
++ /// Set ranges for automatic variables\r
++ inline void SetAutoRanges(double x1, double x2, double y1=0, double y2=0, double z1=0, double z2=0, double c1=0, double c2=0)\r
++ { mgl_set_auto_ranges(gr, x1, x2, y1, y2, z1, z2, c1, c2); }\r
++ /// Set ranges for automatic variables\r
++ inline void SetAutoRanges(mglPoint p1, mglPoint p2)\r
++ { mgl_set_auto_ranges(gr, p1.x, p2.x, p1.y, p2.y, p1.z, p2.z, p1.c, p2.c); }\r
++ /// Set axis origin\r
++ inline void SetOrigin(mglPoint p)\r
++ { mgl_set_origin(gr, p.x, p.y, p.z); }\r
++ inline void SetOrigin(double x0, double y0, double z0=mglNaN)\r
++ { mgl_set_origin(gr, x0, y0, z0); }\r
++\r
++ /// Set the transformation formulas for coordinate. Use "" or NULL for built-in ones\r
++ inline void SetFunc(const char *EqX, const char *EqY, const char *EqZ=NULL, const char *EqA=NULL)\r
++ { mgl_set_func(gr, EqX, EqY, EqZ, EqA); }\r
++ /// Set one of predefined transformation rule\r
++ inline void SetCoor(int how) { mgl_set_coor(gr, how); }\r
++ /// Set to draw Ternary axis (triangle like axis, grid and so on)\r
++ /** val=1 for Ternary axis (a+b+c=1, z=z),\r
++ * val=2 for Quaternary axis (a+b+c+d=1),\r
++ * val|4 for projections. */\r
++ inline void Ternary(int val) { mgl_set_ternary(gr, val); }\r
++\r
++ /// Set to use or not tick labels rotation\r
++ inline void SetTickRotate(bool val) { mgl_set_tick_rotate(gr,val); }\r
++ /// Set to use or not tick labels skipping\r
++ inline void SetTickSkip(bool val) { mgl_set_tick_skip(gr,val); }\r
++ /// Set tick length\r
++ inline void SetTickLen(double len, double stt=1)\r
++ { mgl_set_tick_len(gr, len, stt); }\r
++ /// Set axis and ticks style\r
++ inline void SetAxisStl(const char *stl="k", const char *tck=0, const char *sub=0)\r
++ { mgl_set_axis_stl(gr, stl, tck, sub); }\r
++\r
++ /// Set time templates for ticks\r
++ inline void SetTicksTime(char dir, double d=0, const char *t="")\r
++ { mgl_set_ticks_time(gr,dir,d,t); }\r
++ /// Set ticks text (\n separated). Use "" to disable this feature.\r
++ inline void SetTicksVal(char dir, const char *lbl, bool add=false)\r
++ { mgl_set_ticks_str(gr,dir,lbl,add); }\r
++ inline void SetTicksVal(char dir, const wchar_t *lbl, bool add=false)\r
++ { mgl_set_ticks_wcs(gr,dir,lbl,add); }\r
++ /// Set ticks position and text (\n separated). Use "" to disable this feature.\r
++ inline void SetTicksVal(char dir, const mglDataA &v, const char *lbl, bool add=false)\r
++ { mgl_set_ticks_val(gr,dir,&v,lbl,add); }\r
++ inline void SetTicksVal(char dir, const mglDataA &v, const wchar_t *lbl, bool add=false)\r
++ { mgl_set_ticks_valw(gr,dir,&v,lbl,add); }\r
++ /// Add manual tick at given position. Use "" to disable this feature.\r
++ inline void AddTick(char dir, double val, const char *lbl)\r
++ { mgl_add_tick(gr,dir,val,lbl); }\r
++ inline void AddTick(char dir, double val, const wchar_t *lbl)\r
++ { mgl_add_tickw(gr,dir,val,lbl); }\r
++ /// Set the ticks parameters and string for its factor\r
++ inline void SetTicks(char dir, double d=0, int ns=0, double org=mglNaN, const char *factor="")\r
++ { mgl_set_ticks_fact(gr, dir, d, ns, org, factor); }\r
++ inline void SetTicks(char dir, double d, int ns, double org, const wchar_t *factor)\r
++ { mgl_set_ticks_factw(gr, dir, d, ns, org, factor); }\r
++ /// Auto adjust ticks\r
++ inline void Adjust(const char *dir="xyzc")\r
++ { mgl_adjust_ticks(gr, dir); }\r
++ /// Set templates for ticks\r
++ inline void SetTickTempl(char dir, const char *t)\r
++ { mgl_set_tick_templ(gr,dir,t); }\r
++ inline void SetTickTempl(char dir, const wchar_t *t)\r
++ { mgl_set_tick_templw(gr,dir,t); }\r
++ /// Tune ticks (tune|1 for common multiplier, tune|2 for common component)\r
++ inline void SetTuneTicks(int tune, double fact_pos=1.15)\r
++ { mgl_tune_ticks(gr, tune, fact_pos); }\r
++ /// Set additional shift of tick labels\r
++ inline void SetTickShift(mglPoint p)\r
++ { mgl_set_tick_shift(gr,p.x,p.y,p.z,p.c); }\r
++ /// Set to use UTC time instead of local time\r
++ inline void SetTimeUTC(bool enable)\r
++ { mgl_set_flag(gr,enable, MGL_USE_GMTIME); }\r
++ /// Set to draw tick labels at axis origin\r
++ inline void SetOriginTick(bool enable=true)\r
++ { mgl_set_flag(gr,!enable, MGL_NO_ORIGIN); }\r
++\r
++ /// Put further plotting in m-th cell of nx*ny grid of the image.\r
++ /** String \a style may contain:\r
++ * '<' for reserving space at left\r
++ * '>' for reserving space at right\r
++ * '^' for reserving space at top\r
++ * '_' for reserving space at bottom\r
++ * '#' for using whole region. */\r
++ inline void SubPlot(int nx,int ny,int m,const char *style="<>_^", double dx=0, double dy=0)\r
++ { mgl_subplot_d(gr, nx, ny, m, style, dx, dy); }\r
++ /// Put further plotting in rectangle of dx*dy cells starting from m-th cell of nx*ny grid of the image and shift it by distance {sx,sy}.\r
++ /** String \a style may contain:\r
++ * '<' for reserving space at left\r
++ * '>' for reserving space at right\r
++ * '^' for reserving space at top\r
++ * '_' for reserving space at bottom\r
++ * '#' for using whole region. */\r
++ inline void MultiPlot(int nx,int ny,int m, int dx, int dy, const char *style="<>_^", double sx=0, double sy=0)\r
++ { mgl_multiplot_d(gr, nx, ny, m, dx, dy, style, sx, sy); }\r
++ /// Put further plotting in a region [x1,x2]*[y1,y2] of the image or subplot (x1,x2,y1,y2 in range [0, 1]).\r
++ inline void InPlot(double x1,double x2,double y1,double y2, bool rel=true)\r
++ { if(rel) mgl_relplot(gr, x1, x2, y1, y2);\r
++ else mgl_inplot(gr, x1, x2, y1, y2); }\r
++ /// Put further plotting in column cell of previous subplot\r
++ inline void ColumnPlot(int num, int ind, double d=0)\r
++ { mgl_columnplot(gr,num,ind,d); }\r
++ /// Put further plotting in matrix cell of previous subplot\r
++ inline void GridPlot(int nx, int ny, int ind, double d=0)\r
++ { mgl_gridplot(gr,nx,ny,ind,d); }\r
++ /// Put further plotting in cell of stick rotated on angles tet, phi\r
++ inline void StickPlot(int num, int i, double tet, double phi)\r
++ { mgl_stickplot(gr,num,i,tet,phi); }\r
++ /// Put further plotting in cell of stick sheared on sx, sy.\r
++ inline void ShearPlot(int num, int i, mreal sx, mreal sy, mreal xd=1, mreal yd=0)\r
++ { mgl_shearplot(gr,num,i,sx,sy,xd,yd); }\r
++\r
++ /// Set factor of plot size\r
++ inline void SetPlotFactor(double val)\r
++ { mgl_set_plotfactor(gr,val); }\r
++ /// Push transformation matrix into stack\r
++ inline void Push() { mgl_mat_push(gr); }\r
++ /// Pop transformation matrix from stack\r
++ inline void Pop() { mgl_mat_pop(gr); }\r
++\r
++ /// Add title for current subplot/inplot\r
++ /** Style '#' draw box around the title. */\r
++ inline void Title(const char *title,const char *stl="",double size=-2)\r
++ { mgl_title(gr,title,stl,size); }\r
++ /// Add title for current subplot/inplot\r
++ /** Style '#' draw box around the title. */\r
++ inline void Title(const wchar_t *title,const char *stl="",double size=-2)\r
++ { mgl_titlew(gr,title,stl,size); }\r
++ /// Set aspect ratio for further plotting.\r
++ inline void Aspect(double Ax,double Ay,double Az=1)\r
++ { mgl_aspect(gr, Ax, Ay, Az); }\r
++ /// Shear a further plotting.\r
++ inline void Shear(double Sx,double Sy)\r
++ { mgl_shear(gr, Sx, Sy); }\r
++ /// Rotate a further plotting.\r
++ inline void Rotate(double TetX,double TetZ=0,double TetY=0)\r
++ { mgl_rotate(gr, TetX, TetZ, TetY); }\r
++ /// Rotate a further plotting around vector {x,y,z}.\r
++ inline void RotateN(double Tet,double x,double y,double z)\r
++ { mgl_rotate_vector(gr, Tet, x, y, z); }\r
++ /// Set perspective (in range [0,1)) for plot. Set to zero for switching off.\r
++ inline void Perspective(double val)\r
++ { mgl_perspective(gr, val); }\r
++ /// Set angle of view independently from Rotate().\r
++ inline void View(double TetX,double TetZ=0,double TetY=0)\r
++ { mgl_view(gr, TetX, TetZ, TetY); }\r
++ /// Set angle of view independently from Rotate().\r
++ inline void ViewAsRotate(double TetZ,double TetX,double TetY=0)\r
++ { mgl_view(gr, -TetX, -TetZ, -TetY); }\r
++ /// Zoom in/out a part of picture (use Zoom(0, 0, 1, 1) for restore default)\r
++ inline void Zoom(double x1, double y1, double x2, double y2)\r
++ { mgl_zoom(gr, x1, y1, x2, y2); }\r
++\r
++ /// Set size of frame in pixels. Normally this function is called internally.\r
++ inline void SetSize(int width, int height, bool clf=true)\r
++ { if(clf) mgl_set_size(gr, width, height);\r
++ else mgl_scale_size(gr, width, height); }\r
++ /// Scaling for all further set size calls.\r
++ static inline void SetSizeScl(double scl) { mgl_set_size_scl(scl); }\r
++ /// Set plot quality\r
++ /** qual=0 -- no face drawing (fastest),\r
++ * qual=1 -- no color interpolation (fast),\r
++ * qual=2 -- high quality (normal),\r
++ * qual|4 -- direct bitmap drawing (low memory usage);\r
++ * qual|8 for dots drawing instead of primitives (extremely fast). */\r
++ inline void SetQuality(int qual=MGL_DRAW_NORM) { mgl_set_quality(gr, qual); }\r
++ /// Get plot quality\r
++ inline int GetQuality() { return mgl_get_quality(gr); }\r
++ /// Set drawing region for Quality&4\r
++ inline void SetDrawReg(long nx=1, long ny=1, long m=0) { mgl_set_draw_reg(gr,nx,ny,m); }\r
++ /// Start group of objects\r
++ inline void StartGroup(const char *name) { mgl_start_group(gr, name); }\r
++ /// End group of objects\r
++ inline void EndGroup() { mgl_end_group(gr); }\r
++ /// Highlight objects with given id\r
++ inline void Highlight(int id) { mgl_highlight(gr, id); }\r
++ /// Set boundary box for export graphics into 2D file formats.\r
++ /** If x2<0 (y2<0) then full width (height) will be used.\r
++ * If x1<0 or y1<0 or x1>=x2|Width or y1>=y2|Height then cropping will be disabled. */\r
++ inline void SetBBox(int x1=0, int y1=0, int x2=-1, int y2=-1)\r
++ { mgl_set_bbox(gr,x1,y1,x2,y2); }\r
++\r
++ /// Show current image\r
++ inline void ShowImage(const char *viewer, bool keep=0)\r
++ { mgl_show_image(gr, viewer, keep); }\r
++ /// Write the frame in file (depending extension, write current frame if fname is empty)\r
++ inline void WriteFrame(const char *fname=0,const char *descr="")\r
++ { mgl_write_frame(gr, fname, descr); }\r
++ /// Write the frame in file using JPEG format\r
++ inline void WriteJPEG(const char *fname,const char *descr="")\r
++ { mgl_write_jpg(gr, fname, descr); }\r
++ /// Write the frame in file using PNG format with transparency\r
++ inline void WritePNG(const char *fname,const char *descr="", bool alpha=true)\r
++ { if(alpha) mgl_write_png(gr, fname, descr);\r
++ else mgl_write_png_solid(gr, fname, descr); }\r
++ /// Write the frame in file using BMP format\r
++ inline void WriteBMP(const char *fname,const char *descr="")\r
++ { mgl_write_bmp(gr, fname, descr); }\r
++ /// Write the frame in file using BMP format\r
++ inline void WriteTGA(const char *fname,const char *descr="")\r
++ { mgl_write_tga(gr, fname, descr); }\r
++ /// Write the frame in file using PostScript format\r
++ inline void WriteEPS(const char *fname,const char *descr="")\r
++ { mgl_write_eps(gr, fname, descr); }\r
++ /// Write the frame in file using LaTeX format\r
++ inline void WriteTEX(const char *fname,const char *descr="")\r
++ { mgl_write_tex(gr, fname, descr); }\r
++ /// Write the frame in file using PostScript format as bitmap\r
++ inline void WriteBPS(const char *fname,const char *descr="")\r
++ { mgl_write_bps(gr, fname, descr); }\r
++ /// Write the frame in file using SVG format\r
++ inline void WriteSVG(const char *fname,const char *descr="")\r
++ { mgl_write_svg(gr, fname, descr); }\r
++ /// Write the frame in file using GIF format (only for current frame!)\r
++ inline void WriteGIF(const char *fname,const char *descr="")\r
++ { mgl_write_gif(gr, fname, descr); }\r
++\r
++ /// Write the frame in file using OBJ format\r
++ inline void WriteOBJ(const char *fname,const char *descr="",bool use_png=true)\r
++ { mgl_write_obj(gr, fname, descr, use_png); }\r
++ /// Write the frame in file using OBJ format - Balakin way\r
++ inline void WriteOBJold(const char *fname,const char *descr="",bool use_png=true)\r
++ { mgl_write_obj_old(gr, fname, descr, use_png); }\r
++ /// Write the frame in file using XYZ format\r
++ inline void WriteXYZ(const char *fname,const char *descr="")\r
++ { mgl_write_xyz(gr, fname, descr); }\r
++ /// Write the frame in file using STL format (faces only)\r
++ inline void WriteSTL(const char *fname,const char *descr="")\r
++ { mgl_write_stl(gr, fname, descr); }\r
++ /// Write the frame in file using OFF format\r
++ inline void WriteOFF(const char *fname,const char *descr="", bool colored=false)\r
++ { mgl_write_off(gr, fname, descr,colored); }\r
++// /// Write the frame in file using X3D format\r
++// inline void WriteX3D(const char *fname,const char *descr="")\r
++// { mgl_write_x3d(gr, fname, descr); }\r
++ /// Write the frame in file using PRC format\r
++ inline void WritePRC(const char *fname,const char *descr="",bool make_pdf=true)\r
++ { mgl_write_prc(gr, fname, descr, make_pdf); }\r
++ /// Export in JSON format suitable for later drawing by JavaScript\r
++ inline void WriteJSON(const char *fname,const char *descr="",bool force_z=false)\r
++ { if(force_z) mgl_write_json_z(gr, fname, descr);\r
++ else mgl_write_json(gr, fname, descr); }\r
++ /// Return string of JSON data suitable for later drawing by JavaScript\r
++ inline const char *GetJSON() { return mgl_get_json(gr); }\r
++\r
++ /// Force preparing the image. It can be useful for OpenGL mode mostly.\r
++ inline void Finish() { mgl_finish(gr); }\r
++ /// Create new frame.\r
++ inline void NewFrame() { mgl_new_frame(gr); }\r
++ /// Finish frame drawing\r
++ inline void EndFrame() { mgl_end_frame(gr); }\r
++ /// Get the number of created frames\r
++ inline int GetNumFrame() { return mgl_get_num_frame(gr); }\r
++ /// Reset frames counter (start it from zero)\r
++ inline void ResetFrames() { mgl_reset_frames(gr); }\r
++ /// Delete primitives for i-th frame (work if MGL_VECT_FRAME is set on)\r
++ inline void DelFrame(int i) { mgl_del_frame(gr, i); }\r
++ /// Get drawing data for i-th frame (work if MGL_VECT_FRAME is set on)\r
++ inline void GetFrame(int i) { mgl_get_frame(gr, i); }\r
++ /// Set drawing data for i-th frame (work if MGL_VECT_FRAME is set on). Work as EndFrame() but don't add frame to GIF image.\r
++ inline void SetFrame(int i) { mgl_set_frame(gr, i); }\r
++ /// Append drawing data from i-th frame (work if MGL_VECT_FRAME is set on)\r
++ inline void ShowFrame(int i){ mgl_show_frame(gr, i); }\r
++ /// Clear list of primitives for current drawing\r
++ inline void ClearFrame() { mgl_clear_frame(gr); }\r
++\r
++ /// Start write frames to cinema using GIF format\r
++ inline void StartGIF(const char *fname, int ms=100)\r
++ { mgl_start_gif(gr, fname,ms); }\r
++ /// Stop writing cinema using GIF format\r
++ inline void CloseGIF() { mgl_close_gif(gr); }\r
++ /// Export points and primitives in file using MGLD format\r
++ inline void ExportMGLD(const char *fname, const char *descr=0)\r
++ { mgl_export_mgld(gr, fname, descr); }\r
++ /// Import points and primitives from file using MGLD format\r
++ inline void ImportMGLD(const char *fname, bool add=false)\r
++ { mgl_import_mgld(gr, fname, add); }\r
++\r
++ /// Copy RGB values into array which is allocated by user\r
++ /** Position of element {i,j} is [3*i + 3*Width*j]. */\r
++ inline bool GetRGB(char *imgdata, int imglen)\r
++ {\r
++ long w=mgl_get_width(gr), h=mgl_get_height(gr);\r
++ if(imglen>=3*w*h) memcpy(imgdata, mgl_get_rgb(gr),3*w*h);\r
++ return imglen>=3*w*h;\r
++ }\r
++ /// Get RGB values of current bitmap\r
++ /** Position of element {i,j} is [3*i + 3*Width*j]. */\r
++ inline const unsigned char *GetRGB() { return mgl_get_rgb(gr); }\r
++ /// Copy RGBA values into array which is allocated by user\r
++ /** Position of element {i,j} is [4*i + 4*Width*j]. */\r
++ inline bool GetRGBA(char *imgdata, int imglen)\r
++ {\r
++ long w=mgl_get_width(gr), h=mgl_get_height(gr);\r
++ if(imglen>=4*w*h) memcpy(imgdata, mgl_get_rgba(gr),4*w*h);\r
++ return imglen>=4*w*h;\r
++ }\r
++ /// Get RGBA values of current bitmap\r
++ /** Position of element {i,j} is [4*i + 4*Width*j]. */\r
++ inline const unsigned char *GetRGBA() { return mgl_get_rgba(gr); }\r
++ /// Copy BGRN values into array which is allocated by user\r
++ inline bool GetBGRN(unsigned char *imgdata, int imglen)\r
++ {\r
++ long w=mgl_get_width(gr), h=mgl_get_height(gr), i;\r
++ const unsigned char *buf=mgl_get_rgb(gr);\r
++ if(imglen>=4*w*h) for(i=0;i<w*h;i++)\r
++ {\r
++ imgdata[4*i] = buf[3*i+2];\r
++ imgdata[4*i+1] = buf[3*i+1];\r
++ imgdata[4*i+2] = buf[3*i];\r
++ imgdata[4*i+3] = 255;\r
++ }\r
++ return imglen>=4*w*h;\r
++ }\r
++ /// Copy RGBA values of background image into array which is allocated by user\r
++ /** Position of element {i,j} is [4*i + 4*Width*j]. */\r
++ inline bool GetBackground(char *imgdata, int imglen)\r
++ {\r
++ long w=mgl_get_width(gr), h=mgl_get_height(gr);\r
++ if(imglen>=4*w*h) memcpy(imgdata, mgl_get_background(gr),4*w*h);\r
++ return imglen>=4*w*h;\r
++ }\r
++ /// Get RGBA values of background image\r
++ /** Position of element {i,j} is [4*i + 4*Width*j]. */\r
++ inline const unsigned char *GetBackground() { return mgl_get_background(gr); }\r
++ /// Get width of the image\r
++ inline int GetWidth() { return mgl_get_width(gr); }\r
++ /// Get height of the image\r
++ inline int GetHeight() { return mgl_get_height(gr);}\r
++ /// Calculate 3D coordinate {x,y,z} for screen point {xs,ys}\r
++ inline mglPoint CalcXYZ(int xs, int ys)\r
++ {\r
++ mreal x,y,z;\r
++ mgl_calc_xyz(gr,xs,ys,&x,&y,&z);\r
++ return mglPoint(x,y,z);\r
++ }\r
++ /// Calculate screen point {xs,ys} for 3D coordinate {x,y,z}\r
++ inline mglPoint CalcScr(mglPoint p)\r
++ {\r
++ int xs,ys;\r
++ mgl_calc_scr(gr,p.x,p.y,p.z,&xs,&ys);\r
++ return mglPoint(xs,ys);\r
++ }\r
++ /// Set object/subplot id\r
++ inline void SetObjId(int id) { mgl_set_obj_id(gr,id); }\r
++ /// Get object id\r
++ inline int GetObjId(long x,long y) { return mgl_get_obj_id(gr,x,y); }\r
++ /// Get subplot id\r
++ inline int GetSplId(long x,long y) { return mgl_get_spl_id(gr,x,y); }\r
++ /// Check if {\a xs,\a ys} is close to active point with accuracy d, and return its position or -1\r
++ inline long IsActive(int xs, int ys, int d=1) { return mgl_is_active(gr,xs,ys,d); }\r
++\r
++ /// Combine plots from 2 canvases. Result will be saved into this\r
++ inline void Combine(const mglGraph *g) { mgl_combine_gr(gr,g->gr); }\r
++\r
++ /// Clear up the frame and fill background by specified color\r
++ inline void Clf(double r, double g, double b) { mgl_clf_rgb(gr, r, g, b); }\r
++ /// Clear up the frame and fill background by specified color with manual transparency\r
++ inline void Clf(const char *col) { mgl_clf_str(gr, col); }\r
++ /// Clear up the frame and fill background by specified color\r
++ inline void Clf(char col) { mgl_clf_chr(gr, col); }\r
++ /// Clear up the frame\r
++ inline void Clf() { mgl_clf(gr); }\r
++ /// Clear unused points and primitives. Useful only in combination with SetFaceNum().\r
++ inline void ClearUnused() { mgl_clear_unused(gr); }\r
++\r
++ /// Load background image\r
++ inline void LoadBackground(const char *fname, double alpha=1)\r
++ { mgl_load_background(gr,fname,alpha); }\r
++ /// Force drawing the image and use it as background one\r
++ inline void Rasterize() { mgl_rasterize(gr); }\r
++\r
++ /// Draws the point (ball) at position {x,y,z} with color c\r
++ inline void Ball(mglPoint p, char c='r')\r
++ { char s[3]={'.',c,0}; mgl_mark(gr, p.x, p.y, p.z, s); }\r
++ /// Draws the mark at position p\r
++ inline void Mark(mglPoint p, const char *mark)\r
++ { mgl_mark(gr, p.x, p.y, p.z, mark); }\r
++ /// Draws the line between points by specified pen\r
++ /** Large \a n (for example, n=100) should be used for geodesic line in curved coordinates */\r
++ inline void Line(mglPoint p1, mglPoint p2, const char *pen="B",int n=2)\r
++ { mgl_line(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, pen, n); }\r
++ /// Draws the spline curve between points by specified pen\r
++ inline void Curve(mglPoint p1, mglPoint d1, mglPoint p2, mglPoint d2, const char *pen="B", int n=100)\r
++ { mgl_curve(gr, p1.x, p1.y, p1.z, d1.x, d1.y, d1.z, p2.x, p2.y, p2.z, d2.x, d2.y, d2.z, pen, n); }\r
++ /// Draws the 3d error box e for point p\r
++ inline void Error(mglPoint p, mglPoint e, const char *pen="k")\r
++ { mgl_error_box(gr, p.x, p.y, p.z, e.x, e.y, e.z, pen); }\r
++\r
++ /// Draws Lamerey diagram for mapping x_new = f(x_old)\r
++ /** String \a stl may contain: ‘v’ for drawing arrows; ‘~’ for disable 1st segment.\r
++ * Option value set the number of segments (default is 20).*/\r
++ inline void Lamerey(double x0, const mglDataA &f, const char *stl="", const char *opt="")\r
++ { mgl_lamerey_dat(gr,x0,&f,stl,opt); }\r
++ inline void Lamerey(double x0, const char *func, const char *stl="", const char *opt="")\r
++ { mgl_lamerey_str(gr,x0,func,stl,opt); }\r
++ /// Draws Bifurcation diagram for mapping x_new = f(x_old) in x-axis range\r
++ /** Option value set the number of stationary points (default is 1024).*/\r
++ inline void Bifurcation(double dx, const mglDataA &f, const char *stl="", const char *opt="")\r
++ { mgl_bifurcation_dat(gr,dx,&f,stl,opt); }\r
++ inline void Bifurcation(double dx, const char *func, const char *stl="", const char *opt="")\r
++ { mgl_bifurcation_str(gr,dx,func,stl,opt); }\r
++\r
++ /// Draws Iris plots for determining cross-dependences of data arrays\r
++ /** NOTE: using the same ranges and empty ids will not draw axis. This will add data to existing Iris plot.\r
++ * Option value set the size of data labels ids, separated by ';'.*/\r
++ inline void Iris(mglDataA &dats, const char *ids, const char *stl="", const char *opt="")\r
++ { mgl_iris_1(gr,&dats,ids,stl,opt); }\r
++ inline void Iris(mglDataA &dats, const wchar_t *ids, const char *stl="", const char *opt="")\r
++ { mgl_irisw_1(gr,&dats,ids,stl,opt); }\r
++ inline void Iris(mglDataA &dats, mglDataA &ranges, const char *ids, const char *stl="", const char *opt="")\r
++ { mgl_iris(gr,&dats,&ranges,ids,stl,opt); }\r
++ inline void Iris(mglDataA &dats, mglDataA &ranges, const wchar_t *ids, const char *stl="", const char *opt="")\r
++ { mgl_irisw(gr,&dats,&ranges,ids,stl,opt); }\r
++\r
++ /// Draws the face between points with color stl (include interpolation up to 4 colors).\r
++ inline void Face(mglPoint p1, mglPoint p2, mglPoint p3, mglPoint p4, const char *stl="r")\r
++ { mgl_face(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, p3.x, p3.y, p3.z, p4.x, p4.y, p4.z, stl); }\r
++ /// Draws the face in y-z plane at point p with color stl (include interpolation up to 4 colors).\r
++ inline void FaceX(mglPoint p, double wy, double wz, const char *stl="w", double dx=0, double dy=0)\r
++ { mgl_facex(gr, p.x, p.y, p.z, wy, wz, stl, dx, dy); }\r
++ /// Draws the face in x-z plane at point p with color stl (include interpolation up to 4 colors).\r
++ inline void FaceY(mglPoint p, double wx, double wz, const char *stl="w", double dx=0, double dy=0)\r
++ { mgl_facey(gr, p.x, p.y, p.z, wx, wz, stl, dx, dy); }\r
++ /// Draws the face in x-y plane at point p with color stl (include interpolation up to 4 colors).\r
++ inline void FaceZ(mglPoint p, double wx, double wy, const char *stl="w", double dx=0, double dy=0)\r
++ { mgl_facez(gr, p.x, p.y, p.z, wx, wy, stl, dx, dy); }\r
++ /// Draws the drop at point p in direction d with color col and radius r\r
++ /** Parameter \a shift set the degree of drop oblongness: ‘0’ is sphere, ‘1’ is maximally oblongness drop. Parameter \a ap set relative width of the drop (this is analogue of “ellipticity” for the sphere).*/\r
++ inline void Drop(mglPoint p, mglPoint d, double r, const char *col="r", double shift=1, double ap=1)\r
++ { mgl_drop(gr, p.x, p.y, p.z, d.x, d.y, d.z, r, col, shift, ap); }\r
++ /// Draws the sphere at point p with color col and radius r\r
++ inline void Sphere(mglPoint p, double r, const char *col="r")\r
++ { mgl_sphere(gr, p.x, p.y, p.z, r, col); }\r
++ /// Draws the cone between points p1,p2 with radius r1,r2 and with style stl\r
++ /** Parameter \a stl can contain:\r
++ * ‘@’ for drawing edges;\r
++ * ‘#’ for wired cones;\r
++ * ‘t’ for drawing tubes/cylinder instead of cones/prisms;\r
++ * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones.*/\r
++ inline void Cone(mglPoint p1, mglPoint p2, double r1, double r2=-1, const char *stl="r@")\r
++ { mgl_cone(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z,r1,r2,stl); }\r
++ /// Draws the ellipse between points p1,p2 with color stl and width r\r
++ /** Parameter \a stl can contain:\r
++ * ‘#’ for wired figure (boundary only);\r
++ * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/\r
++ inline void Ellipse(mglPoint p1, mglPoint p2, double r, const char *stl="r")\r
++ { mgl_ellipse(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, r,stl); }\r
++ /// Draws the circle at point p with color stl and radius r\r
++ /** Parameter \a stl can contain:\r
++ * ‘#’ for wired figure (boundary only);\r
++ * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/\r
++ inline void Circle(mglPoint p, double r, const char *stl="r")\r
++ { mgl_ellipse(gr, p.x, p.y, p.z, p.x, p.y, p.z, r,stl); }\r
++ /// Draws the rhomb between points p1,p2 with color stl and width r\r
++ /** Parameter \a stl can contain:\r
++ * ‘#’ for wired figure (boundary only);\r
++ * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/\r
++ inline void Rhomb(mglPoint p1, mglPoint p2, double r, const char *stl="r")\r
++ { mgl_rhomb(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, r,stl); }\r
++ /// Draws the polygon based on points p1,p2 with color stl\r
++ /** Parameter \a stl can contain:\r
++ * ‘#’ for wired figure (boundary only);\r
++ * ‘@’ for filled figure and with boundary (second color or black one is used for boundary).*/\r
++ inline void Polygon(mglPoint p1, mglPoint p2, int n, const char *stl="r")\r
++ { mgl_polygon(gr, p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, n,stl); }\r
++ /// Draws the arc around axis pr with center at p0 and starting from p1, by color stl and angle a (in degrees)\r
++ inline void Arc(mglPoint p0, mglPoint pa, mglPoint p1, double a, const char *stl="r")\r
++ { mgl_arc_ext(gr, p0.x,p0.y,p0.z, pa.x,pa.y,pa.z, p1.x,p1.y,p1.z, a,stl); }\r
++ /// Draws the arc around axis 'z' with center at p0 and starting from p1, by color stl and angle a (in degrees)\r
++ inline void Arc(mglPoint p0, mglPoint p1, double a, const char *stl="r")\r
++ { mgl_arc_ext(gr, p0.x,p0.y,p0.z, 0,0,1, p1.x,p1.y,p0.z, a,stl); }\r
++ /// Draws bitmap (logo) which is stretched along whole axis range\r
++ inline void Logo(long w, long h, const unsigned char *rgba, bool smooth=false, const char *opt="")\r
++ { mgl_logo(gr, w, h, rgba, smooth, opt); }\r
++ inline void Logo(const char *fname, bool smooth=false, const char *opt="")\r
++ { mgl_logo_file(gr, fname, smooth, opt); }\r
++\r
++ /// Draw user-defined symbol in position p\r
++ inline void Symbol(mglPoint p, char id, const char *how="", double size=-1)\r
++ { mgl_symbol(gr, p.x, p.y, p.z, id, how, size); }\r
++ /// Draw user-defined symbol in position p along direction d\r
++ inline void Symbol(mglPoint p, mglPoint d, char id, const char *how="", double size=-1)\r
++ { mgl_symbol_dir(gr, p.x, p.y, p.z, d.x, d.y, d.z, id, how, size); }\r
++\r
++ /// Print text in position p with specified font\r
++ inline void Putsw(mglPoint p,const wchar_t *text,const char *font=":C",double size=-1)\r
++ { mgl_putsw(gr, p.x, p.y, p.z, text, font, size); }\r
++ /// Print text in position p with specified font\r
++ inline void Puts(mglPoint p,const char *text,const char *font=":C",double size=-1)\r
++ { mgl_puts(gr, p.x, p.y, p.z, text, font, size); }\r
++ /// Print text in position p with specified font\r
++ inline void Putsw(double x, double y,const wchar_t *text,const char *font=":AC",double size=-1)\r
++ { mgl_putsw(gr, x, y, 0, text, font, size); }\r
++ /// Print text in position p with specified font\r
++ inline void Puts(double x, double y,const char *text,const char *font=":AC",double size=-1)\r
++ { mgl_puts(gr, x, y, 0, text, font, size); }\r
++ /// Print text in position p along direction d with specified font\r
++ inline void Putsw(mglPoint p, mglPoint d, const wchar_t *text, const char *font=":L", double size=-1)\r
++ { mgl_putsw_dir(gr, p.x, p.y, p.z, d.x, d.y, d.z, text, font, size); }\r
++ /// Print text in position p along direction d with specified font\r
++ inline void Puts(mglPoint p, mglPoint d, const char *text, const char *font=":L", double size=-1)\r
++ { mgl_puts_dir(gr, p.x, p.y, p.z, d.x, d.y, d.z, text, font, size); }\r
++\r
++ /// Print text along the curve\r
++ inline void Text(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *text, const char *font="", const char *opt="")\r
++ { mgl_text_xyz(gr, &x, &y, &z, text, font, opt); }\r
++ /// Print text along the curve\r
++ inline void Text(const mglDataA &x, const mglDataA &y, const char *text, const char *font="", const char *opt="")\r
++ { mgl_text_xy(gr, &x, &y, text, font, opt); }\r
++ /// Print text along the curve\r
++ inline void Text(const mglDataA &y, const char *text, const char *font="", const char *opt="")\r
++ { mgl_text_y(gr, &y, text, font, opt); }\r
++ /// Print text along the curve\r
++ inline void Text(const mglDataA &x, const mglDataA &y, const mglDataA &z, const wchar_t *text, const char *font="", const char *opt="")\r
++ { mgl_textw_xyz(gr, &x, &y, &z, text, font, opt); }\r
++ /// Print text along the curve\r
++ inline void Text(const mglDataA &x, const mglDataA &y, const wchar_t *text, const char *font="", const char *opt="")\r
++ { mgl_textw_xy(gr, &x, &y, text, font, opt); }\r
++ /// Print text along the curve\r
++ inline void Text(const mglDataA &y, const wchar_t *text, const char *font="", const char *opt="")\r
++ { mgl_textw_y(gr, &y, text, font, opt); }\r
++\r
++ /// Draws bounding box outside the plotting volume with color c.\r
++ /** Style ‘@’ produce filled back faces. */\r
++ inline void Box(const char *col="", bool ticks=true)\r
++ { mgl_box_str(gr, col, ticks); }\r
++ /// Draw axises with ticks in direction(s) dir.\r
++ /** Parameter \a dir may contain:\r
++ * ‘xyzt’for drawing axis in corresponding direction;\r
++ * ‘XYZT’ for drawing axis in corresponding direction but with inverted positions of labels;\r
++ * ‘~’, ‘_’ for disabling tick labels;\r
++ * ‘U’ for disabling rotation of tick labels;\r
++ * ‘^’ for inverting default axis origin;\r
++ * ‘!’ for disabling ticks tuning;\r
++ * ‘AKDTVISO’ for drawing arrow at the end of axis;\r
++ * ‘a’ for forced adjusting of axis ticks;\r
++ * ‘f’ for printing ticks labels in fixed format;\r
++ * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;\r
++ * ‘F’ for printing ticks labels in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive ticks;\r
++ * ‘-’ for printing usual ‘-’ in ticks labels;\r
++ * ‘0123456789’ for precision at printing ticks labels.\r
++ * Option "value" set the manual rotation angle for the ticks. */\r
++ inline void Axis(const char *dir="xyzt", const char *stl="", const char *opt="")\r
++ { mgl_axis(gr, dir,stl,opt); }\r
++ /// Draw grid lines perpendicular to direction(s) dir.\r
++ inline void Grid(const char *dir="xyzt",const char *pen="B", const char *opt="")\r
++ { mgl_axis_grid(gr, dir, pen, opt); }\r
++ /// Print the label text for axis dir.\r
++ /** Option "value" set additional shifting of the label. */\r
++ inline void Label(char dir, const char *text, double pos=+1, const char *opt="")\r
++ { mgl_label(gr, dir, text, pos, opt); }\r
++ /// Print the label text for axis dir.\r
++ /** Option "value" set additional shifting of the label. */\r
++ inline void Label(char dir, const wchar_t *text, double pos=+1, const char *opt="")\r
++ { mgl_labelw(gr, dir, text, pos, opt); }\r
++\r
++ /// Draw colorbar at edge of axis\r
++ /** Parameter \a sch may contain:\r
++ * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly;\r
++ * ‘I’ for positioning near bounding (by default, at edges of subplot);\r
++ * ‘A’ for using absolute coordinates;\r
++ * ‘~’ for disabling tick labels.\r
++ * ‘!’ for disabling ticks tuning;\r
++ * ‘f’ for printing ticks labels in fixed format;\r
++ * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;\r
++ * ‘F’ for printing ticks labels in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive ticks;\r
++ * ‘-’ for printing usual ‘-’ in ticks labels;\r
++ * ‘0123456789’ for precision at printing ticks labels.*/\r
++ inline void Colorbar(const char *sch="")\r
++ { mgl_colorbar(gr, sch); }\r
++ /// Draw colorbar at manual position\r
++ /** Parameter \a sch may contain:\r
++ * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly;\r
++ * ‘I’ for positioning near bounding (by default, at edges of subplot);\r
++ * ‘A’ for using absolute coordinates;\r
++ * ‘~’ for disabling tick labels.\r
++ * ‘!’ for disabling ticks tuning;\r
++ * ‘f’ for printing ticks labels in fixed format;\r
++ * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;\r
++ * ‘F’ for printing ticks labels in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive ticks;\r
++ * ‘-’ for printing usual ‘-’ in ticks labels;\r
++ * ‘0123456789’ for precision at printing ticks labels.*/\r
++ inline void Colorbar(const char *sch,double x,double y,double w=1,double h=1)\r
++ { mgl_colorbar_ext(gr, sch, x,y,w,h); }\r
++ /// Draw colorbar with manual colors at edge of axis\r
++ /** Parameter \a sch may contain:\r
++ * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly;\r
++ * ‘I’ for positioning near bounding (by default, at edges of subplot);\r
++ * ‘A’ for using absolute coordinates;\r
++ * ‘~’ for disabling tick labels.\r
++ * ‘!’ for disabling ticks tuning;\r
++ * ‘f’ for printing ticks labels in fixed format;\r
++ * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;\r
++ * ‘F’ for printing ticks labels in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive ticks;\r
++ * ‘-’ for printing usual ‘-’ in ticks labels;\r
++ * ‘0123456789’ for precision at printing ticks labels.*/\r
++ inline void Colorbar(const mglDataA &val, const char *sch="")\r
++ { mgl_colorbar_val(gr, &val, sch); }\r
++ /// Draw colorbar with manual colors at manual position\r
++ /** Parameter \a sch may contain:\r
++ * ‘<>^_’ for positioning at left, at right, at top or at bottom correspondingly;\r
++ * ‘I’ for positioning near bounding (by default, at edges of subplot);\r
++ * ‘A’ for using absolute coordinates;\r
++ * ‘~’ for disabling tick labels.\r
++ * ‘!’ for disabling ticks tuning;\r
++ * ‘f’ for printing ticks labels in fixed format;\r
++ * ‘E’ for using ‘E’ instead of ‘e’ in ticks labels;\r
++ * ‘F’ for printing ticks labels in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive ticks;\r
++ * ‘-’ for printing usual ‘-’ in ticks labels;\r
++ * ‘0123456789’ for precision at printing ticks labels.*/\r
++ inline void Colorbar(const mglDataA &val, const char *sch,double x,double y,double w=1,double h=1)\r
++ { mgl_colorbar_val_ext(gr, &val, sch, x,y,w,h); }\r
++\r
++ /// Add string to legend\r
++ inline void AddLegend(const char *text,const char *style)\r
++ { mgl_add_legend(gr, text, style); }\r
++ inline void AddLegend(const wchar_t *text,const char *style)\r
++ { mgl_add_legendw(gr, text, style); }\r
++ /// Clear saved legend string\r
++ inline void ClearLegend()\r
++ { mgl_clear_legend(gr); }\r
++ /// Draw legend of accumulated strings at position {x,y}\r
++ /** Parameter fnt may contain:\r
++ * font style for legend text;\r
++ * colors for background (first one), border (second one) and text (last one);\r
++ * ‘A’ for positioning in absolute coordinates;\r
++ * ‘^’ for positioning outside of specified point;\r
++ * ‘-’ for arranging entries horizontally;\r
++ * ‘#’ for drawing box around legend.\r
++ * Option value set the space between line samples and text (default is 0.1).*/\r
++ inline void Legend(double x, double y, const char *font="#", const char *opt="")\r
++ { mgl_legend_pos(gr, x, y, font, opt); }\r
++ /// Draw legend of accumulated strings\r
++ /** Parameter fnt may contain:\r
++ * font style for legend text;\r
++ * colors for background (first one), border (second one) and text (last one);\r
++ * ‘A’ for positioning in absolute coordinates;\r
++ * ‘^’ for positioning outside of specified point;\r
++ * ‘-’ for arranging entries horizontally;\r
++ * ‘#’ for drawing box around legend.\r
++ * Option value set the space between line samples and text (default is 0.1).\r
++ * Parameter \a where sets position: 0 at bottom-left, 1 at bottom-right, 2 at top-left, 3 at top-right (default).*/\r
++ inline void Legend(int where=3, const char *font="#", const char *opt="")\r
++ { mgl_legend(gr, where, font, opt); }\r
++ /// Set number of marks in legend sample\r
++ inline void SetLegendMarks(int num) { mgl_set_legend_marks(gr, num); }\r
++\r
++ /// Draw usual curve {x,y,z}\r
++ inline void Plot(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="", const char *opt="")\r
++ { mgl_plot_xyz(gr, &x, &y, &z, pen, opt); }\r
++ /// Draw usual curve {x,y}\r
++ inline void Plot(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_plot_xy(gr, &x, &y, pen,opt); }\r
++ /// Draw usual curve {x,y} with x in x-axis range\r
++ inline void Plot(const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_plot(gr, &y, pen,opt); }\r
++ /// Draw tapes which rotates as (bi-)normales of curve {x,y,z}\r
++ /** The width of tape is proportional to barwidth and can be changed by option "value".*/\r
++ inline void Tape(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="", const char *opt="")\r
++ { mgl_tape_xyz(gr, &x, &y, &z, pen, opt); }\r
++ /// Draw tapes which rotates as (bi-)normales of curve {x,y}\r
++ /** The width of tape is proportional to barwidth and can be changed by option "value".*/\r
++ inline void Tape(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_tape_xy(gr, &x, &y, pen,opt); }\r
++ /// Draw tapes which rotates as (bi-)normales of curve {x,y} with x in x-axis range\r
++ /** The width of tape is proportional to barwidth and can be changed by option "value".*/\r
++ inline void Tape(const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_tape(gr, &y, pen,opt); }\r
++ /// Draw radar chart (plot in curved coordinates)\r
++ /** Option "value" set the additional shift of data (i.e. the data a+value is used instead of a).*/\r
++ inline void Radar(const mglDataA &a, const char *pen="", const char *opt="")\r
++ { mgl_radar(gr, &a, pen, opt); }\r
++\r
++ /// Draw stairs for points in arrays {x,y,z}\r
++ inline void Step(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="", const char *opt="")\r
++ { mgl_step_xyz(gr, &x, &y, &z, pen, opt); }\r
++ /// Draw stairs for points in arrays {x,y}\r
++ inline void Step(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_step_xy(gr, &x, &y, pen, opt); }\r
++ /// Draw stairs for points in arrays {x,y} with x in x-axis range\r
++ inline void Step(const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_step(gr, &y, pen, opt); }\r
++\r
++ /// Draw curve {x,y,z} which is colored by c (like tension plot)\r
++ inline void Tens(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *pen="", const char *opt="")\r
++ { mgl_tens_xyz(gr, &x, &y, &z, &c, pen, opt); }\r
++ /// Draw curve {x,y} which is colored by c (like tension plot)\r
++ inline void Tens(const mglDataA &x, const mglDataA &y, const mglDataA &c, const char *pen="", const char *opt="")\r
++ { mgl_tens_xy(gr, &x, &y, &c, pen, opt); }\r
++ /// Draw curve {x,y} with x in x-axis range which is colored by c (like tension plot)\r
++ inline void Tens(const mglDataA &y, const mglDataA &c, const char *pen="", const char *opt="")\r
++ { mgl_tens(gr, &y, &c, pen, opt); }\r
++\r
++ /// Fill area between curve {x,y,z} and axis plane\r
++ /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Area(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="", const char *opt="")\r
++ { mgl_area_xyz(gr, &x, &y, &z, pen, opt); }\r
++ /// Fill area between curve {x,y} and axis plane\r
++ /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Area(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_area_xy(gr, &x, &y, pen, opt); }\r
++ /// Fill area between curve {x,y} with x in x-axis range and axis plane\r
++ /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Area(const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_area(gr, &y, pen, opt); }\r
++\r
++ /// Fill area between curves {x,y1} and {x,y2} with x in x-axis range\r
++ /** Style 'i' will fill area only if y1 < y2.\r
++ * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Region(const mglDataA &y1, const mglDataA &y2, const char *pen="", const char *opt="")\r
++ { mgl_region(gr, &y1, &y2, pen, opt); }\r
++ /// Fill area between curves {x,y1} and {x,y2}\r
++ /** Style 'i' will fill area only if y1 < y2.\r
++ * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Region(const mglDataA &x, const mglDataA &y1, const mglDataA &y2, const char *pen="", const char *opt="")\r
++ { mgl_region_xy(gr, &x, &y1, &y2, pen, opt); }\r
++ /// Fill area (draw ribbon) between curves {x1,y1,z1} and {x2,y2,z2}\r
++ /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Region(const mglDataA &x1, const mglDataA &y1, const mglDataA &z1, const mglDataA &x2, const mglDataA &y2, const mglDataA &z2, const char *pen="", const char *opt="")\r
++ { mgl_region_3d(gr, &x1, &y1, &z1, &x2, &y2, &z2, pen, opt); }\r
++ /// Fill area (draw ribbon) between curves {x1,y1} and {x2,y2}\r
++ /** Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Region(const mglDataA &x1, const mglDataA &y1, const mglDataA &x2, const mglDataA &y2, const char *pen="", const char *opt="")\r
++ { mgl_region_3d(gr, &x1, &y1, NULL, &x2, &y2, NULL, pen, opt); }\r
++\r
++ /// Draw vertical lines from points {x,y,z} to axis plane\r
++ inline void Stem(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="", const char *opt="")\r
++ { mgl_stem_xyz(gr, &x, &y, &z, pen, opt); }\r
++ /// Draw vertical lines from points {x,y} to axis plane\r
++ inline void Stem(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_stem_xy(gr, &x, &y, pen, opt); }\r
++ /// Draw vertical lines from points {x,y} with x in x-axis range to axis plane\r
++ inline void Stem(const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_stem(gr, &y, pen, opt); }\r
++\r
++ /// Draw vertical bars from points {x,y,z} to axis plane\r
++ /** String \a pen may contain:\r
++ * ‘a’ for drawing boxes one above another (like summation);\r
++ * ‘f’ for waterfall chart;\r
++ * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.\r
++ * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Bars(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="", const char *opt="")\r
++ { mgl_bars_xyz(gr, &x, &y, &z, pen, opt); }\r
++ /// Draw vertical bars from points {x,y} to axis plane\r
++ /** String \a pen may contain:\r
++ * ‘a’ for drawing boxes one above another (like summation);\r
++ * ‘f’ for waterfall chart;\r
++ * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.\r
++ * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Bars(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_bars_xy(gr, &x, &y, pen, opt); }\r
++ /// Draw vertical bars from points {x,y} with x in x-axis range to axis plane\r
++ /** String \a pen may contain:\r
++ * ‘a’ for drawing boxes one above another (like summation);\r
++ * ‘f’ for waterfall chart;\r
++ * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.\r
++ * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Bars(const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_bars(gr, &y, pen, opt); }\r
++ /// Draw horizontal bars from points {x,y} to axis plane\r
++ /** String \a pen may contain:\r
++ * ‘a’ for drawing boxes one above another (like summation);\r
++ * ‘f’ for waterfall chart;\r
++ * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.\r
++ * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Barh(const mglDataA &y, const mglDataA &v, const char *pen="", const char *opt="")\r
++ { mgl_barh_yx(gr, &y, &v, pen, opt); }\r
++ /// Draw horizontal bars from points {x,y} with y in y-axis range to axis plane\r
++ /** String \a pen may contain:\r
++ * ‘a’ for drawing boxes one above another (like summation);\r
++ * ‘f’ for waterfall chart;\r
++ * ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.\r
++ * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Barh(const mglDataA &v, const char *pen="", const char *opt="")\r
++ { mgl_barh(gr, &v, pen, opt); }\r
++ /// Draw chart for data a\r
++ /** Space denote transparent color. Style '#' draw black borders. */\r
++ inline void Chart(const mglDataA &a, const char *colors="", const char *opt="")\r
++ { mgl_chart(gr, &a, colors,opt); }\r
++\r
++ /// Draw Open-High-Low-Close (OHLC) diagram\r
++ /** Different colors for up and down values are used if number of specified colors is equal to 2*number of curves. */\r
++ inline void OHLC(const mglDataA &x, const mglDataA &open, const mglDataA &high, const mglDataA &low, const mglDataA &close, const char *pen="", const char *opt="")\r
++ { mgl_ohlc_x(gr, &x, &open,&high,&low,&close,pen,opt); }\r
++ /// Draw Open-High-Low-Close (OHLC) diagram with x in x-axis range\r
++ /** Different colors for up and down values are used if number of specified colors is equal to 2*number of curves. */\r
++ inline void OHLC(const mglDataA &open, const mglDataA &high, const mglDataA &low, const mglDataA &close, const char *pen="", const char *opt="")\r
++ { mgl_ohlc(gr, &open,&high,&low,&close,pen,opt); }\r
++\r
++ /// Draw box-plot (special 5-value plot used in statistic)\r
++ /** String \a pen may contain ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.*/\r
++ inline void BoxPlot(const mglDataA &x, const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_boxplot_xy(gr, &x, &y, pen,opt); }\r
++ /// Draw box-plot (special 5-value plot used in statistic) with x in x-axis range\r
++ /** String \a pen may contain ‘<’, ‘^’, ‘>’ for aligning boxes: at left, centered, at right.*/\r
++ inline void BoxPlot(const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_boxplot(gr, &y, pen,opt); }\r
++\r
++ /// Draw candle plot\r
++ /** Different colors are used for up and down values if 2 colors are specified.\r
++ * Style ‘#’ force drawing wire candle even for 2-color scheme. */\r
++ inline void Candle(const mglDataA &x, const mglDataA &v1, const mglDataA &v2, const mglDataA &y1, const mglDataA &y2, const char *pen="", const char *opt="")\r
++ { mgl_candle_xyv(gr, &x, &v1, &v2, &y1, &y2, pen, opt); }\r
++ /// Draw candle plot with x in x-axis range\r
++ /** Different colors are used for up and down values if 2 colors are specified.\r
++ * Style ‘#’ force drawing wire candle even for 2-color scheme. */\r
++ inline void Candle(const mglDataA &v1, const mglDataA &v2, const mglDataA &y1, const mglDataA &y2, const char *pen="", const char *opt="")\r
++ { mgl_candle_yv(gr, &v1, &v2, &y1, &y2, pen, opt); }\r
++ inline void Candle(const mglDataA &v1, const mglDataA &v2, const char *pen="", const char *opt="")\r
++ { mgl_candle_yv(gr, &v1, &v2, NULL, NULL, pen, opt); }\r
++ /// Draw candle plot with v1=v[i], v2=v[i+1]\r
++ /** Different colors are used for up and down values if 2 colors are specified.\r
++ * Style ‘#’ force drawing wire candle even for 2-color scheme. */\r
++ inline void Candle(const mglDataA &y, const mglDataA &y1, const mglDataA &y2, const char *pen="", const char *opt="")\r
++ { mgl_candle(gr, &y, &y1, &y2, pen, opt); }\r
++ /// Draw candle plot with v1=v[i], v2=v[i+1]\r
++ /** Different colors are used for up and down values if 2 colors are specified.\r
++ * Style ‘#’ force drawing wire candle even for 2-color scheme. */\r
++ inline void Candle(const mglDataA &y, const char *pen="", const char *opt="")\r
++ { mgl_candle(gr, &y, NULL, NULL, pen, opt); }\r
++\r
++ /// Draw cones from points {x,y,z} to axis plane\r
++ /** String \a pen may contain:\r
++ * ‘@’ for drawing edges;\r
++ * ‘#’ for wired cones;\r
++ * ‘t’ for drawing tubes/cylinders instead of cones/prisms;\r
++ * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones;\r
++ * ‘<’, ‘^’ or ‘>’ for aligning cones left, right or centering them at its x-coordinates.\r
++ * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Cones(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *pen="@", const char *opt="")\r
++ { mgl_cones_xyz(gr, &x, &y, &z, pen, opt); }\r
++ /// Draw cones from points {x,z} to axis plane\r
++ /** String \a pen may contain:\r
++ * ‘@’ for drawing edges;\r
++ * ‘#’ for wired cones;\r
++ * ‘t’ for drawing tubes/cylinders instead of cones/prisms;\r
++ * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones;\r
++ * ‘<’, ‘^’ or ‘>’ for aligning cones left, right or centering them at its x-coordinates.\r
++ * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Cones(const mglDataA &x, const mglDataA &z, const char *pen="@", const char *opt="")\r
++ { mgl_cones_xz(gr, &x, &z, pen, opt); }\r
++ /// Draw cones from points {x,z} with x in x-axis range to axis plane\r
++ /** String \a pen may contain:\r
++ * ‘@’ for drawing edges;\r
++ * ‘#’ for wired cones;\r
++ * ‘t’ for drawing tubes/cylinders instead of cones/prisms;\r
++ * ‘4’, ‘6’, ‘8’ for drawing square, hex- or octo-prism instead of cones;\r
++ * ‘<’, ‘^’ or ‘>’ for aligning cones left, right or centering them at its x-coordinates.\r
++ * Gradient filling is used if number of specified colors is equal to 2*number of curves.*/\r
++ inline void Cones(const mglDataA &z, const char *pen="@", const char *opt="")\r
++ { mgl_cones(gr, &z, pen, opt); }\r
++\r
++ /// Draw error boxes {ey} at points {x,y} with x in x-axis range\r
++ /** Style ‘@’ set to draw large semitransparent mark instead of error box.*/\r
++ inline void Error(const mglDataA &y, const mglDataA &ey, const char *pen="", const char *opt="")\r
++ { mgl_error(gr, &y, &ey, pen, opt); }\r
++ /// Draw error boxes {ey} at points {x,y}\r
++ /** Style ‘@’ set to draw large semitransparent mark instead of error box.*/\r
++ inline void Error(const mglDataA &x, const mglDataA &y, const mglDataA &ey, const char *pen="", const char *opt="")\r
++ { mgl_error_xy(gr, &x, &y, &ey, pen, opt); }\r
++ /// Draw error boxes {ex,ey} at points {x,y}\r
++ /** Style ‘@’ set to draw large semitransparent mark instead of error box.*/\r
++ inline void Error(const mglDataA &x, const mglDataA &y, const mglDataA &ex, const mglDataA &ey, const char *pen="", const char *opt="")\r
++ { mgl_error_exy(gr, &x, &y, &ex, &ey, pen, opt); }\r
++\r
++ /// Draw marks with size r at points {x,y,z}\r
++ inline void Mark(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const char *pen, const char *opt="")\r
++ { mgl_mark_xyz(gr, &x, &y, &z, &r, pen, opt); }\r
++ /// Draw marks with size r at points {x,y}\r
++ inline void Mark(const mglDataA &x, const mglDataA &y, const mglDataA &r, const char *pen, const char *opt="")\r
++ { mgl_mark_xy(gr, &x, &y, &r, pen, opt); }\r
++ /// Draw marks with size r at points {x,y} with x in x-axis range\r
++ inline void Mark(const mglDataA &y, const mglDataA &r, const char *pen, const char *opt="")\r
++ { mgl_mark_y(gr, &y, &r, pen, opt); }\r
++\r
++ /// Draw Poincare map at condition s==0 for curve {x,y,z}\r
++ inline void Pmap(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &s, const char *pen, const char *opt="")\r
++ { mgl_pmap_xyz(gr, &x, &y, &z, &s, pen, opt); }\r
++ /// Draw Poincare map at condition s==0 for curve {x,y}\r
++ inline void Pmap(const mglDataA &x, const mglDataA &y, const mglDataA &s, const char *pen, const char *opt="")\r
++ { mgl_pmap_xy(gr, &x, &y, &s, pen, opt); }\r
++ /// Draw Poincare map at condition s==0 for curve {x,y} with x in x-axis range\r
++ inline void Pmap(const mglDataA &y, const mglDataA &s, const char *pen, const char *opt="")\r
++ { mgl_pmap(gr, &y, &s, pen, opt); }\r
++\r
++ /// Draw textual marks with size r at points {x,y,z}\r
++ inline void TextMark(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const char *text, const char *fnt="", const char *opt="")\r
++ { mgl_textmark_xyzr(gr, &x, &y, &z, &r, text, fnt, opt); }\r
++ /// Draw textual marks with size r at points {x,y}\r
++ inline void TextMark(const mglDataA &x, const mglDataA &y, const mglDataA &r, const char *text, const char *fnt="", const char *opt="")\r
++ { mgl_textmark_xyr(gr, &x, &y, &r, text, fnt, opt); }\r
++ /// Draw textual marks with size r at points {x,y} with x in x-axis range\r
++ inline void TextMark(const mglDataA &y, const mglDataA &r, const char *text, const char *fnt="", const char *opt="")\r
++ { mgl_textmark_yr(gr, &y, &r, text, fnt, opt); }\r
++ /// Draw textual marks at points {x,y} with x in x-axis range\r
++ inline void TextMark(const mglDataA &y, const char *text, const char *fnt="", const char *opt="")\r
++ { mgl_textmark(gr, &y, text, fnt, opt); }\r
++ /// Draw textual marks with size r at points {x,y,z}\r
++ inline void TextMark(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const wchar_t *text, const char *fnt="", const char *opt="")\r
++ { mgl_textmarkw_xyzr(gr, &x, &y, &z, &r, text, fnt, opt); }\r
++ /// Draw textual marks with size r at points {x,y}\r
++ inline void TextMark(const mglDataA &x, const mglDataA &y, const mglDataA &r, const wchar_t *text, const char *fnt="", const char *opt="")\r
++ { mgl_textmarkw_xyr(gr, &x, &y, &r, text, fnt, opt); }\r
++ /// Draw textual marks with size r at points {x,y} with x in x-axis range\r
++ inline void TextMark(const mglDataA &y, const mglDataA &r, const wchar_t *text, const char *fnt="", const char *opt="")\r
++ { mgl_textmarkw_yr(gr, &y, &r, text, fnt, opt); }\r
++ /// Draw textual marks at points {x,y} with x in x-axis range\r
++ inline void TextMark(const mglDataA &y, const wchar_t *text, const char *fnt="", const char *opt="")\r
++ { mgl_textmarkw(gr, &y, text, fnt, opt); }\r
++\r
++ /// Draw labels for points coordinate(s) at points {x,y,z}\r
++ /** String \a fnt may contain:\r
++ * ‘f’ for fixed format of printed numbers;\r
++ * ‘E’ for using ‘E’ instead of ‘e’;\r
++ * ‘F’ for printing in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive numbers;\r
++ * ‘-’ for printing usual ‘-’;\r
++ * ‘0123456789’ for precision at printing numbers.*/\r
++ inline void Label(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *text, const char *fnt="", const char *opt="")\r
++ { mgl_label_xyz(gr, &x, &y, &z, text, fnt, opt); }\r
++ /// Draw labels for points coordinate(s) at points {x,y}\r
++ /** String \a fnt may contain:\r
++ * ‘f’ for fixed format of printed numbers;\r
++ * ‘E’ for using ‘E’ instead of ‘e’;\r
++ * ‘F’ for printing in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive numbers;\r
++ * ‘-’ for printing usual ‘-’;\r
++ * ‘0123456789’ for precision at printing numbers.*/\r
++ inline void Label(const mglDataA &x, const mglDataA &y, const char *text, const char *fnt="", const char *opt="")\r
++ { mgl_label_xy(gr, &x, &y, text, fnt, opt); }\r
++ /// Draw labels for points coordinate(s) at points {x,y} with x in x-axis range\r
++ /** String \a fnt may contain:\r
++ * ‘f’ for fixed format of printed numbers;\r
++ * ‘E’ for using ‘E’ instead of ‘e’;\r
++ * ‘F’ for printing in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive numbers;\r
++ * ‘-’ for printing usual ‘-’;\r
++ * ‘0123456789’ for precision at printing numbers.*/\r
++ inline void Label(const mglDataA &y, const char *text, const char *fnt="", const char *opt="")\r
++ { mgl_label_y(gr, &y, text, fnt, opt); }\r
++ /// Draw labels for points coordinate(s) at points {x,y,z}\r
++ /** String \a fnt may contain:\r
++ * ‘f’ for fixed format of printed numbers;\r
++ * ‘E’ for using ‘E’ instead of ‘e’;\r
++ * ‘F’ for printing in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive numbers;\r
++ * ‘-’ for printing usual ‘-’;\r
++ * ‘0123456789’ for precision at printing numbers.*/\r
++ inline void Label(const mglDataA &x, const mglDataA &y, const mglDataA &z, const wchar_t *text, const char *fnt="", const char *opt="")\r
++ { mgl_labelw_xyz(gr, &x, &y, &z, text, fnt, opt); }\r
++ /// Draw labels for points coordinate(s) at points {x,y}\r
++ /** String \a fnt may contain:\r
++ * ‘f’ for fixed format of printed numbers;\r
++ * ‘E’ for using ‘E’ instead of ‘e’;\r
++ * ‘F’ for printing in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive numbers;\r
++ * ‘-’ for printing usual ‘-’;\r
++ * ‘0123456789’ for precision at printing numbers.*/\r
++ inline void Label(const mglDataA &x, const mglDataA &y, const wchar_t *text, const char *fnt="", const char *opt="")\r
++ { mgl_labelw_xy(gr, &x, &y, text, fnt, opt); }\r
++ /// Draw labels for points coordinate(s) at points {x,y} with x in x-axis range\r
++ /** String \a fnt may contain:\r
++ * ‘f’ for fixed format of printed numbers;\r
++ * ‘E’ for using ‘E’ instead of ‘e’;\r
++ * ‘F’ for printing in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive numbers;\r
++ * ‘-’ for printing usual ‘-’;\r
++ * ‘0123456789’ for precision at printing numbers.*/\r
++ inline void Label(const mglDataA &y, const wchar_t *text, const char *fnt="", const char *opt="")\r
++ { mgl_labelw_y(gr, &y, text, fnt, opt); }\r
++\r
++ /// Draw table for values val along given direction with row labels text\r
++ /** String \a fnt may contain:\r
++ * ‘#’ for drawing cell borders;\r
++ * ‘|’ for limiting table widh by subplot one (equal to option ‘value 1’);\r
++ * ‘=’ for equal width of all cells;\r
++ * ‘f’ for fixed format of printed numbers;\r
++ * ‘E’ for using ‘E’ instead of ‘e’;\r
++ * ‘F’ for printing in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive numbers;\r
++ * ‘-’ for printing usual ‘-’;\r
++ * ‘0123456789’ for precision at printing numbers.\r
++ * Option value set the width of the table (default is 1).*/\r
++ inline void Table(const mglDataA &val, const char *text, const char *fnt="#|", const char *opt="")\r
++ { mgl_table(gr, 0, 0, &val, text, fnt, opt); }\r
++ /// Draw table for values val along given direction with row labels text\r
++ /** String \a fnt may contain:\r
++ * ‘#’ for drawing cell borders;\r
++ * ‘|’ for limiting table widh by subplot one (equal to option ‘value 1’);\r
++ * ‘=’ for equal width of all cells;\r
++ * ‘f’ for fixed format of printed numbers;\r
++ * ‘E’ for using ‘E’ instead of ‘e’;\r
++ * ‘F’ for printing in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive numbers;\r
++ * ‘-’ for printing usual ‘-’;\r
++ * ‘0123456789’ for precision at printing numbers.\r
++ * Option value set the width of the table (default is 1).*/\r
++ inline void Table(const mglDataA &val, const wchar_t *text, const char *fnt="#|", const char *opt="")\r
++ { mgl_tablew(gr, 0, 0, &val, text, fnt, opt); }\r
++ /// Draw table for values val along given direction with row labels text at given position\r
++ /** String \a fnt may contain:\r
++ * ‘#’ for drawing cell borders;\r
++ * ‘|’ for limiting table widh by subplot one (equal to option ‘value 1’);\r
++ * ‘=’ for equal width of all cells;\r
++ * ‘f’ for fixed format of printed numbers;\r
++ * ‘E’ for using ‘E’ instead of ‘e’;\r
++ * ‘F’ for printing in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive numbers;\r
++ * ‘-’ for printing usual ‘-’;\r
++ * ‘0123456789’ for precision at printing numbers.\r
++ * Option value set the width of the table (default is 1).*/\r
++ inline void Table(double x, double y, const mglDataA &val, const char *text, const char *fnt="#|", const char *opt="")\r
++ { mgl_table(gr, x, y, &val, text, fnt, opt); }\r
++ /// Draw table for values val along given direction with row labels text at given position\r
++ /** String \a fnt may contain:\r
++ * ‘#’ for drawing cell borders;\r
++ * ‘|’ for limiting table widh by subplot one (equal to option ‘value 1’);\r
++ * ‘=’ for equal width of all cells;\r
++ * ‘f’ for fixed format of printed numbers;\r
++ * ‘E’ for using ‘E’ instead of ‘e’;\r
++ * ‘F’ for printing in LaTeX format;\r
++ * ‘+’ for printing ‘+’ for positive numbers;\r
++ * ‘-’ for printing usual ‘-’;\r
++ * ‘0123456789’ for precision at printing numbers.\r
++ * Option value set the width of the table (default is 1).*/\r
++ inline void Table(double x, double y, const mglDataA &val, const wchar_t *text, const char *fnt="#|", const char *opt="")\r
++ { mgl_tablew(gr, x, y, &val, text, fnt, opt); }\r
++\r
++ /// Draw tube with radius r around curve {x,y,z}\r
++ inline void Tube(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const char *pen="", const char *opt="")\r
++ { mgl_tube_xyzr(gr, &x, &y, &z, &r, pen, opt); }\r
++ /// Draw tube with radius r around curve {x,y,z}\r
++ inline void Tube(const mglDataA &x, const mglDataA &y, const mglDataA &z, double r, const char *pen="", const char *opt="")\r
++ { mgl_tube_xyz(gr, &x, &y, &z, r, pen, opt); }\r
++ /// Draw tube with radius r around curve {x,y}\r
++ inline void Tube(const mglDataA &x, const mglDataA &y, const mglDataA &r, const char *pen="", const char *opt="")\r
++ { mgl_tube_xyr(gr, &x, &y, &r, pen, opt); }\r
++ /// Draw tube with radius r around curve {x,y}\r
++ inline void Tube(const mglDataA &x, const mglDataA &y, double r, const char *pen="", const char *opt="")\r
++ { mgl_tube_xy(gr, &x, &y, r, pen, opt); }\r
++ /// Draw tube with radius r around curve {x,y} with x in x-axis range\r
++ inline void Tube(const mglDataA &y, const mglDataA &r, const char *pen="", const char *opt="")\r
++ { mgl_tube_r(gr, &y, &r, pen, opt); }\r
++ /// Draw tube with radius r around curve {x,y} with x in x-axis range\r
++ inline void Tube(const mglDataA &y, double r, const char *pen="", const char *opt="")\r
++ { mgl_tube(gr, &y, r, pen, opt); }\r
++ /// Draw surface of curve {r,z} rotation around axis\r
++ /** Style ‘#’ produce wire plot. Style ‘.’ produce plot by dots.*/\r
++ inline void Torus(const mglDataA &r, const mglDataA &z, const char *pen="", const char *opt="")\r
++ { mgl_torus(gr, &r, &z, pen,opt); }\r
++\r
++ /// Draw mesh lines for 2d data specified parametrically\r
++ inline void Mesh(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_mesh_xy(gr, &x, &y, &z, stl, opt); }\r
++ /// Draw mesh lines for 2d data\r
++ inline void Mesh(const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_mesh(gr, &z, stl, opt); }\r
++\r
++ /// Draw waterfall plot for 2d data specified parametrically\r
++ /** Style 'x' draw lines in x-direction. */\r
++ inline void Fall(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_fall_xy(gr, &x, &y, &z, stl, opt); }\r
++ /// Draw waterfall plot for 2d data\r
++ /** Style 'x' draw lines in x-direction. */\r
++ inline void Fall(const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_fall(gr, &z, stl, opt); }\r
++\r
++ /// Draw belts for 2d data specified parametrically\r
++ /** Style 'x' draw belts in x-direction. */\r
++ inline void Belt(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_belt_xy(gr, &x, &y, &z, stl, opt); }\r
++ /// Draw belts for 2d data\r
++ /** Style 'x' draw belts in x-direction. */\r
++ inline void Belt(const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_belt(gr, &z, stl, opt); }\r
++ /// Draw belts for 2d data specified parametrically with color proportional to c\r
++ /** Style 'x' draw belts in x-direction. */\r
++ inline void BeltC(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *stl="", const char *opt="")\r
++ { mgl_beltc_xy(gr, &x, &y, &z, &c, stl, opt); }\r
++ /// Draw belts for 2d data with color proportional to c\r
++ /** Style 'x' draw belts in x-direction. */\r
++ inline void BeltC(const mglDataA &z, const mglDataA &c, const char *stl="", const char *opt="")\r
++ { mgl_beltc(gr, &z, &c, stl, opt); }\r
++\r
++ /// Draw surface for 2d data specified parametrically with color proportional to z\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void Surf(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_surf_xy(gr, &x, &y, &z, stl, opt); }\r
++ /// Draw surface for 2d data with color proportional to z\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void Surf(const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_surf(gr, &z, stl, opt); }\r
++\r
++ /// Draw grid lines for density plot of 2d data specified parametrically\r
++ inline void Grid(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_grid_xy(gr, &x, &y, &z, stl, opt); }\r
++ /// Draw grid lines for density plot of 2d data\r
++ inline void Grid(const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_grid(gr, &z, stl, opt); }\r
++\r
++ /// Draw vertical tiles with manual colors c for 2d data specified parametrically\r
++ inline void Tile(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *stl="", const char *opt="")\r
++ { mgl_tile_xyc(gr, &x, &y, &z, &c, stl, opt); }\r
++ /// Draw vertical tiles for 2d data specified parametrically\r
++ inline void Tile(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_tile_xy(gr, &x, &y, &z, stl, opt); }\r
++ /// Draw vertical tiles for 2d data\r
++ inline void Tile(const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_tile(gr, &z, stl, opt); }\r
++\r
++ /// Draw density plot for 2d data specified parametrically\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void Dens(const mglDataA &x, const mglDataA &y, const mglDataA &c, const char *stl="", const char *opt="")\r
++ { mgl_dens_xy(gr, &x, &y, &c, stl, opt); }\r
++ /// Draw density plot for 2d data\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void Dens(const mglDataA &c, const char *stl="", const char *opt="")\r
++ { mgl_dens(gr, &c, stl, opt); }\r
++\r
++ /// Draw vertical boxes for 2d data specified parametrically\r
++ /** Style ‘#’ draw filled boxes. */\r
++ inline void Boxs(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_boxs_xy(gr, &x, &y, &z, stl, opt); }\r
++ /// Draw vertical boxes for 2d data\r
++ /** Style ‘#’ draw filled boxes. */\r
++ inline void Boxs(const mglDataA &z, const char *stl="", const char *opt="")\r
++ { mgl_boxs(gr, &z, stl, opt); }\r
++\r
++ /// Draw contour lines on parametric surface at manual levels for 2d data specified parametrically\r
++ /** Style ‘f’ to draw solid contours.\r
++ * Style 't'/'T' draw contour labels below/above contours.*/\r
++ inline void ContP(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="")\r
++ { mgl_contp_val(gr, &v, &x, &y, &z, &a, sch, opt); }\r
++ /// Draw contour lines on parametric surface at manual levels for 2d data specified parametrically\r
++ /** Style ‘f’ to draw solid contours.\r
++ * Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContP(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="")\r
++ { mgl_contp(gr, &x, &y, &z, &a, sch, opt); }\r
++\r
++\r
++ /// Draw contour lines at manual levels for 2d data specified parametrically\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Style 't'/'T' draw contour labels below/above contours.*/\r
++ inline void Cont(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_cont_xy_val(gr, &v, &x, &y, &z, sch, opt); }\r
++ /// Draw contour lines for 2d data\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Style 't'/'T' draw contour labels below/above contours.*/\r
++ inline void Cont(const mglDataA &v, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_cont_val(gr, &v, &z, sch, opt); }\r
++ /// Draw contour lines at manual levels for 2d data specified parametrically\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void Cont(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_cont_xy(gr, &x, &y, &z, sch, opt); }\r
++ /// Draw contour lines for 2d data\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void Cont(const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_cont(gr, &z, sch, opt); }\r
++\r
++ /// Draw solid contours at manual levels for 2d data specified parametrically\r
++ /** Style ‘_’ to draw contours at bottom of axis box. */\r
++ inline void ContF(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_contf_xy_val(gr, &v, &x, &y, &z, sch, opt); }\r
++ /// Draw solid contours at manual levels for 2d data\r
++ /** Style ‘_’ to draw contours at bottom of axis box. */\r
++ inline void ContF(const mglDataA &v, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_contf_val(gr, &v, &z, sch, opt); }\r
++ /// Draw solid contours for 2d data specified parametrically\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContF(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_contf_xy(gr, &x, &y, &z, sch, opt); }\r
++ /// Draw solid contours for 2d data\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContF(const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_contf(gr, &z, sch, opt); }\r
++\r
++ /// Draw solid contours at manual levels for 2d data specified parametrically with specified colors\r
++ /** Style ‘_’ to draw contours at bottom of axis box. */\r
++ inline void ContD(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_contd_xy_val(gr, &v, &x, &y, &z, sch, opt); }\r
++ /// Draw solid contours at manual levels for 2d data with specified colors\r
++ /** Style ‘_’ to draw contours at bottom of axis box. */\r
++ inline void ContD(const mglDataA &v, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_contd_val(gr, &v, &z, sch, opt); }\r
++ /// Draw solid contours for 2d data specified parametrically with specified colors\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContD(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_contd_xy(gr, &x, &y, &z, sch, opt); }\r
++ /// Draw solid contours for 2d data with specified colors\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContD(const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_contd(gr, &z, sch, opt); }\r
++\r
++ /// Draw contour tubes between manual levels for 2d data specified parametrically\r
++ /** Style ‘_’ to draw contours at bottom of axis box. */\r
++ inline void ContV(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_contv_xy_val(gr, &v, &x, &y, &z, sch, opt); }\r
++ /// Draw contour tubes between manual levels for 2d data\r
++ /** Style ‘_’ to draw contours at bottom of axis box. */\r
++ inline void ContV(const mglDataA &v, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_contv_val(gr, &v, &z, sch, opt); }\r
++ /// Draw contour tubes for 2d data specified parametrically\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContV(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_contv_xy(gr, &x, &y, &z, sch, opt); }\r
++ /// Draw contour tubes for 2d data\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContV(const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_contv(gr, &z, sch, opt); }\r
++\r
++ /// Draw axial-symmetric isosurfaces at manual levels for 2d data specified parametrically\r
++ /** String \a sch may contain:\r
++ * ‘#’ for wired plot;\r
++ * ‘.’ for plot by dots;\r
++ * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis). */\r
++ inline void Axial(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_axial_xy_val(gr, &v, &x, &y, &z, sch,opt); }\r
++ /// Draw axial-symmetric isosurfaces at manual levels for 2d data\r
++ /** String \a sch may contain:\r
++ * ‘#’ for wired plot;\r
++ * ‘.’ for plot by dots;\r
++ * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis). */\r
++ inline void Axial(const mglDataA &v, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_axial_val(gr, &v, &z, sch, opt); }\r
++ /// Draw axial-symmetric isosurfaces for 2d data specified parametrically\r
++ /** String \a sch may contain:\r
++ * ‘#’ for wired plot;\r
++ * ‘.’ for plot by dots;\r
++ * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis).\r
++ * Option "value" set the number of isosurfaces (default is 3). */\r
++ inline void Axial(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_axial_xy(gr, &x, &y, &z, sch, opt); }\r
++ /// Draw axial-symmetric isosurfaces for 2d data\r
++ /** String \a sch may contain:\r
++ * ‘#’ for wired plot;\r
++ * ‘.’ for plot by dots;\r
++ * ‘x’, ‘z’ for rotation around x-, z-axis correspondingly (default is y-axis).\r
++ * Option "value" set the number of isosurfaces (default is 3). */\r
++ inline void Axial(const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_axial(gr, &z, sch, opt); }\r
++\r
++ /// Draw grid lines for density plot at slice for 3d data specified parametrically\r
++ /** Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/\r
++ inline void Grid3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *stl="", double sVal=-1, const char *opt="")\r
++ { mgl_grid3_xyz(gr, &x, &y, &z, &a, stl, sVal, opt); }\r
++ /// Draw grid lines for density plot at slice for 3d data\r
++ /** Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/\r
++ inline void Grid3(const mglDataA &a, const char *stl="", double sVal=-1, const char *opt="")\r
++ { mgl_grid3(gr, &a, stl, sVal, opt); }\r
++\r
++ /// Draw density plot at slice for 3d data specified parametrically\r
++ /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/\r
++ inline void Dens3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *stl="", double sVal=-1, const char *opt="")\r
++ { mgl_dens3_xyz(gr, &x, &y, &z, &a, stl, sVal, opt); }\r
++ /// Draw density plot at slice for 3d data\r
++ /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.*/\r
++ inline void Dens3(const mglDataA &a, const char *stl="", double sVal=-1, const char *opt="")\r
++ { mgl_dens3(gr, &a, stl, sVal, opt); }\r
++\r
++ /// Draw isosurface for 3d data specified parametrically\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.*/\r
++ inline void Surf3(double Val, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *stl="", const char *opt="")\r
++ { mgl_surf3_xyz_val(gr, Val, &x, &y, &z, &a, stl, opt); }\r
++ /// Draw isosurface for 3d data\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.*/\r
++ inline void Surf3(double Val, const mglDataA &a, const char *stl="", const char *opt="")\r
++ { mgl_surf3_val(gr, Val, &a, stl, opt); }\r
++ /// Draw isosurfaces for 3d data specified parametrically\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.\r
++ * Option "value" set the number of isosurfaces (default is 3). */\r
++ inline void Surf3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *stl="", const char *opt="")\r
++ { mgl_surf3_xyz(gr, &x, &y, &z, &a, stl, opt); }\r
++ /// Draw isosurfaces for 3d data\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.\r
++ * Option "value" set the number of isosurfaces (default is 3). */\r
++ inline void Surf3(const mglDataA &a, const char *stl="", const char *opt="")\r
++ { mgl_surf3(gr, &a, stl, opt); }\r
++\r
++ /// Draw a semi-transparent cloud for 3d data specified parametrically\r
++ /** Style ‘.’ produce plot by dots. Style ‘i’ use inverted values for transparency. */\r
++ inline void Cloud(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *stl="", const char *opt="")\r
++ { mgl_cloud_xyz(gr, &x, &y, &z, &a, stl, opt); }\r
++ /// Draw a semi-transparent cloud for 3d data\r
++ /** Style ‘.’ produce plot by dots. Style ‘i’ use inverted values for transparency. */\r
++ inline void Cloud(const mglDataA &a, const char *stl="", const char *opt="")\r
++ { mgl_cloud(gr, &a, stl, opt); }\r
++\r
++ /// Draw contour lines at manual levels along slice for 3d data specified parametrically\r
++ /** Style ‘#’ draw grid lines.\r
++ * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.\r
++ * Style ‘t’/‘T’ draw contour labels below/above contours. */\r
++ inline void Cont3(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="")\r
++ { mgl_cont3_xyz_val(gr, &v, &x, &y, &z, &a, sch, sVal, opt); }\r
++ /// Draw contour lines at manual levels along slice for 3d data\r
++ /** Style ‘#’ draw grid lines.\r
++ * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.\r
++ * Style ‘t’/‘T’ draw contour labels below/above contours. */\r
++ inline void Cont3(const mglDataA &v, const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="")\r
++ { mgl_cont3_val(gr, &v, &a, sch, sVal, opt); }\r
++ /// Draw contour lines along slice for 3d data specified parametrically\r
++ /** Style ‘#’ draw grid lines.\r
++ * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.\r
++ * Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void Cont3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="")\r
++ { mgl_cont3_xyz(gr, &x, &y, &z, &a, sch, sVal, opt); }\r
++ /// Draw contour lines along slice for 3d data\r
++ /** Style ‘#’ draw grid lines.\r
++ * Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.\r
++ * Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void Cont3(const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="")\r
++ { mgl_cont3(gr, &a, sch, sVal, opt); }\r
++\r
++ /// Draw solid contours at manual levels along slice for 3d data specified parametrically\r
++ /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. */\r
++ inline void ContF3(const mglDataA &v, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="")\r
++ { mgl_contf3_xyz_val(gr, &v, &x, &y, &z, &a, sch, sVal, opt); }\r
++ /// Draw solid contours at manual levels along slice for 3d data\r
++ /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly. */\r
++ inline void ContF3(const mglDataA &v, const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="")\r
++ { mgl_contf3_val(gr, &v, &a, sch, sVal, opt); }\r
++ /// Draw solid contours along slice for 3d data specified parametrically\r
++ /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.\r
++ * Option "value" set the number of contour levels (default is 7).*/\r
++ inline void ContF3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="")\r
++ { mgl_contf3_xyz(gr, &x, &y, &z, &a, sch, sVal, opt); }\r
++ /// Draw solid contours along slice for 3d data\r
++ /** Style ‘#’ draw grid lines. Style ‘x’ or ‘z’ produce plot perpendicular to x- or z-direction correspondingly.\r
++ * Option "value" set the number of contour levels (default is 7).*/\r
++ inline void ContF3(const mglDataA &a, const char *sch="", double sVal=-1, const char *opt="")\r
++ { mgl_contf3(gr, &a, sch, sVal, opt); }\r
++\r
++ /// Draw several isosurfaces for 3d beam in curvilinear coordinates\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.\r
++ * Variable \a flag is bitwise:\r
++ * ‘0x1’ - draw in accompanied (not laboratory) coordinates;\r
++ * ‘0x2’ - draw projection to \rho-z plane;\r
++ * ‘0x4’ - draw normalized in each slice field.*/\r
++ inline void Beam(const mglDataA &tr, const mglDataA &g1, const mglDataA &g2, const mglDataA &a, double r, const char *stl=0, int flag=0, int num=3)\r
++ { mgl_beam(gr, &tr,&g1,&g2,&a,r,stl,flag,num); }\r
++ /// Draw isosurface at value \a val for 3d beam in curvilinear coordinates\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.\r
++ * Variable \a flag is bitwise:\r
++ * ‘0x1’ - draw in accompanied (not laboratory) coordinates;\r
++ * ‘0x2’ - draw projection to \rho-z plane;\r
++ * ‘0x4’ - draw normalized in each slice field.*/\r
++ inline void Beam(double val, const mglDataA &tr, const mglDataA &g1, const mglDataA &g2, const mglDataA &a, double r, const char *stl=NULL, int flag=0)\r
++ { mgl_beam_val(gr,val,&tr,&g1,&g2,&a,r,stl,flag); }\r
++\r
++ /// Draw vertical tiles with variable size r and manual colors c for 2d data specified parametrically\r
++ inline void TileS(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const mglDataA &c, const char *stl="", const char *opt="")\r
++ { mgl_tiles_xyc(gr, &x, &y, &z, &r, &c, stl, opt); }\r
++ /// Draw vertical tiles with variable size r for 2d data specified parametrically\r
++ inline void TileS(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &r, const char *stl="", const char *opt="")\r
++ { mgl_tiles_xy(gr, &x, &y, &z, &r, stl, opt); }\r
++ /// Draw vertical tiles with variable size r for 2d data\r
++ inline void TileS(const mglDataA &z, const mglDataA &r, const char *stl="", const char *opt="")\r
++ { mgl_tiles(gr, &z, &r, stl, opt); }\r
++\r
++ /// Draw surface for 2d data specified parametrically with color proportional to c\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void SurfC(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *sch="", const char *opt="")\r
++ { mgl_surfc_xy(gr, &x, &y, &z, &c, sch,opt); }\r
++ /// Draw surface for 2d data with color proportional to c\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void SurfC(const mglDataA &z, const mglDataA &c, const char *sch="", const char *opt="")\r
++ { mgl_surfc(gr, &z, &c, sch,opt); }\r
++\r
++ /// Draw surface for 2d data specified parametrically with alpha proportional to c\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void SurfA(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *sch="", const char *opt="")\r
++ { mgl_surfa_xy(gr, &x, &y, &z, &c, sch,opt); }\r
++ /// Draw surface for 2d data with alpha proportional to c\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void SurfA(const mglDataA &z, const mglDataA &c, const char *sch="", const char *opt="")\r
++ { mgl_surfa(gr, &z, &c, sch,opt); }\r
++\r
++ /// Draw surface for 2d data specified parametrically with color proportional to c and alpha proportional to a\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void SurfCA(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const mglDataA &a, const char *sch="", const char *opt="")\r
++ { mgl_surfca_xy(gr, &x, &y, &z, &c, &a, sch,opt); }\r
++ /// Draw surface for 2d data with color proportional to c and alpha proportional to a\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void SurfCA(const mglDataA &z, const mglDataA &c, const mglDataA &a, const char *sch="", const char *opt="")\r
++ { mgl_surfca(gr, &z, &c, &a, sch,opt); }\r
++\r
++ /// Color map of matrix a to matrix b, both matrix can parametrically depend on coordinates\r
++ /** Style ‘.’ produce plot by dots. */\r
++ inline void Map(const mglDataA &x, const mglDataA &y, const mglDataA &a, const mglDataA &b, const char *sch="", const char *opt="")\r
++ { mgl_map_xy(gr, &x, &y, &a, &b, sch, opt); }\r
++ /// Color map of matrix a to matrix b\r
++ /** Style ‘.’ produce plot by dots. */\r
++ inline void Map(const mglDataA &a, const mglDataA &b, const char *sch="", const char *opt="")\r
++ { mgl_map(gr, &a, &b, sch, opt); }\r
++\r
++ /// Draw density plot for spectra-gramm specified parametrically\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void STFA(const mglDataA &x, const mglDataA &y, const mglDataA &re, const mglDataA &im, int dn, const char *sch="", const char *opt="")\r
++ { mgl_stfa_xy(gr, &x, &y, &re, &im, dn, sch, opt); }\r
++ /// Draw density plot for spectra-gramm\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void STFA(const mglDataA &re, const mglDataA &im, int dn, const char *sch="", const char *opt="")\r
++ { mgl_stfa(gr, &re, &im, dn, sch, opt); }\r
++\r
++ /// Draw isosurface for 3d data specified parametrically with alpha proportional to b\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */\r
++ inline void Surf3A(double Val, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &b, const char *stl="", const char *opt="")\r
++ { mgl_surf3a_xyz_val(gr, Val, &x, &y, &z, &a, &b, stl, opt); }\r
++ /// Draw isosurface for 3d data with alpha proportional to b\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */\r
++ inline void Surf3A(double Val, const mglDataA &a, const mglDataA &b, const char *stl="", const char *opt="")\r
++ { mgl_surf3a_val(gr, Val, &a, &b, stl, opt); }\r
++ /// Draw isosurfaces for 3d data specified parametrically with alpha proportional to b\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.\r
++ * Option "value" set the number of isosurfaces (default is 3). */\r
++ inline void Surf3A(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &b, const char *stl="", const char *opt="")\r
++ { mgl_surf3a_xyz(gr, &x, &y, &z, &a, &b, stl, opt); }\r
++ /// Draw isosurfaces for 3d data with alpha proportional to b\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.\r
++ * Option "value" set the number of isosurfaces (default is 3). */\r
++ inline void Surf3A(const mglDataA &a, const mglDataA &b, const char *stl="", const char *opt="")\r
++ { mgl_surf3a(gr, &a, &b, stl, opt); }\r
++\r
++ /// Draw isosurface for 3d data specified parametrically with color proportional to c\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */\r
++ inline void Surf3C(double Val, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &c, const char *stl="", const char *opt="")\r
++ { mgl_surf3c_xyz_val(gr, Val, &x, &y, &z, &a, &c, stl,opt); }\r
++ /// Draw isosurface for 3d data with color proportional to c\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */\r
++ inline void Surf3C(double Val, const mglDataA &a, const mglDataA &c, const char *stl="", const char *opt="")\r
++ { mgl_surf3c_val(gr, Val, &a, &c, stl, opt); }\r
++ /// Draw isosurfaces for 3d data specified parametrically with color proportional to c\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.\r
++ * Option "value" set the number of isosurfaces (default is 3). */\r
++ inline void Surf3C(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &c, const char *stl="", const char *opt="")\r
++ { mgl_surf3c_xyz(gr, &x, &y, &z, &a, &c, stl, opt); }\r
++ /// Draw isosurfaces for 3d data specified parametrically with color proportional to c\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.\r
++ * Option "value" set the number of isosurfaces (default is 3). */\r
++ inline void Surf3C(const mglDataA &a, const mglDataA &c, const char *stl="", const char *opt="")\r
++ { mgl_surf3c(gr, &a, &c, stl, opt); }\r
++\r
++ /// Draw isosurface for 3d data specified parametrically with color proportional to c and alpha proportional to b\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */\r
++ inline void Surf3CA(double Val, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &c, const mglDataA &b, const char *stl="", const char *opt="")\r
++ { mgl_surf3ca_xyz_val(gr, Val, &x, &y, &z, &a, &c, &b, stl,opt); }\r
++ /// Draw isosurface for 3d data with color proportional to c and alpha proportional to b\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots. */\r
++ inline void Surf3CA(double Val, const mglDataA &a, const mglDataA &c, const mglDataA &b, const char *stl="", const char *opt="")\r
++ { mgl_surf3ca_val(gr, Val, &a, &c, &b, stl, opt); }\r
++ /// Draw isosurfaces for 3d data specified parametrically with color proportional to c and alpha proportional to b\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.\r
++ * Option "value" set the number of isosurfaces (default is 3). */\r
++ inline void Surf3CA(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &c, const mglDataA &b, const char *stl="", const char *opt="")\r
++ { mgl_surf3ca_xyz(gr, &x, &y, &z, &a, &c, &b, stl, opt); }\r
++ /// Draw isosurfaces for 3d data with color proportional to c and alpha proportional to b\r
++ /** Style ‘#’ draw wired plot. Style ‘.’ produce plot by dots.\r
++ * Option "value" set the number of isosurfaces (default is 3). */\r
++ inline void Surf3CA(const mglDataA &a, const mglDataA &c, const mglDataA &b, const char *stl="", const char *opt="")\r
++ { mgl_surf3ca(gr, &a, &c, &b, stl, opt); }\r
++\r
++ /// Plot dew drops for vector field {ax,ay} parametrically depended on coordinate {x,y}\r
++ inline void Dew(const mglDataA &x, const mglDataA &y, const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="")\r
++ { mgl_dew_xy(gr, &x, &y, &ax, &ay, sch, opt); }\r
++ /// Plot dew drops for vector field {ax,ay}\r
++ inline void Dew(const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="")\r
++ { mgl_dew_2d(gr, &ax, &ay, sch, opt); }\r
++\r
++ /// Plot vectors at position {x,y} along {ax,ay} with length/color proportional to |a|\r
++ /** Option value set the vector length factor (if non-zero) or vector length to be proportional the distance between curve points (if value=0). */\r
++ inline void Traj(const mglDataA &x, const mglDataA &y, const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="")\r
++ { mgl_traj_xy(gr, &x, &y, &ax, &ay, sch, opt); }\r
++ /// Plot vectors at position {x,y,z} along {ax,ay,az} with length/color proportional to |a|\r
++ /** Option value set the vector length factor (if non-zero) or vector length to be proportional the distance between curve points (if value=0). */\r
++ inline void Traj(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="")\r
++ { mgl_traj_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, opt); }\r
++\r
++ /// Plot vector field {ax,ay} parametrically depended on coordinate {x,y} with length/color proportional to |a|\r
++ /** String \a sch may contain:\r
++ * ‘f’ for drawing arrows with fixed lengths,\r
++ * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering),\r
++ * ‘.’ for drawing hachures with dots instead of arrows,\r
++ * ‘=’ for enabling color gradient along arrows. */\r
++ inline void Vect(const mglDataA &x, const mglDataA &y, const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="")\r
++ { mgl_vect_xy(gr, &x, &y, &ax, &ay, sch, opt); }\r
++ /// Plot vector field {ax,ay} with length/color proportional to |a|\r
++ /** String \a sch may contain:\r
++ * ‘f’ for drawing arrows with fixed lengths,\r
++ * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering),\r
++ * ‘.’ for drawing hachures with dots instead of arrows,\r
++ * ‘=’ for enabling color gradient along arrows. */\r
++ inline void Vect(const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="")\r
++ { mgl_vect_2d(gr, &ax, &ay, sch, opt); }\r
++ /// Plot vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with length/color proportional to |a|\r
++ /** String \a sch may contain:\r
++ * ‘f’ for drawing arrows with fixed lengths,\r
++ * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering),\r
++ * ‘.’ for drawing hachures with dots instead of arrows,\r
++ * ‘=’ for enabling color gradient along arrows. */\r
++ inline void Vect(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="")\r
++ { mgl_vect_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, opt); }\r
++ /// Plot vector field {ax,ay,az} with length/color proportional to |a|\r
++ /** String \a sch may contain:\r
++ * ‘f’ for drawing arrows with fixed lengths,\r
++ * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering),\r
++ * ‘.’ for drawing hachures with dots instead of arrows,\r
++ * ‘=’ for enabling color gradient along arrows. */\r
++ inline void Vect(const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="")\r
++ { mgl_vect_3d(gr, &ax, &ay, &az, sch, opt); }\r
++\r
++ /// Draw vector plot along slice for 3d data specified parametrically\r
++ /** String \a sch may contain:\r
++ * ‘f’ for drawing arrows with fixed lengths,\r
++ * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering),\r
++ * ‘.’ for drawing hachures with dots instead of arrows,\r
++ * ‘=’ for enabling color gradient along arrows,\r
++ * ‘ x’, ‘z’ for producing plot perpendicular to x- or z-direction correspondingly. */\r
++ inline void Vect3(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *stl="", double sVal=-1, const char *opt="")\r
++ { mgl_vect3_xyz(gr, &x, &y, &z, &ax,&ay,&az, stl, sVal, opt); }\r
++ /// Draw vector plot along slice for 3d data\r
++ /** String \a sch may contain:\r
++ * ‘f’ for drawing arrows with fixed lengths,\r
++ * ‘ >’, ‘<’ for drawing arrows to or from the ce*ll point (default is centering),\r
++ * ‘.’ for drawing hachures with dots instead of arrows,\r
++ * ‘=’ for enabling color gradient along arrows,\r
++ * ‘ x’, ‘z’ for producing plot perpendicular to x- or z-direction correspondingly. */\r
++ inline void Vect3(const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *stl="", double sVal=-1, const char *opt="")\r
++ { mgl_vect3(gr, &ax,&ay,&az, stl, sVal, opt); }\r
++\r
++ /// Plot flows for vector field {ax,ay} parametrically depended on coordinate {x,y} with color proportional to |a|\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘v’ for drawing arrows on the threads;\r
++ * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.\r
++ * Option "value" sets the number of threads (default is 5). */\r
++ inline void Flow(const mglDataA &x, const mglDataA &y, const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="")\r
++ { mgl_flow_xy(gr, &x, &y, &ax, &ay, sch, opt); }\r
++ /// Plot flows for vector field {ax,ay} with color proportional to |a|\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘v’ for drawing arrows on the threads;\r
++ * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.\r
++ * Option "value" sets the number of threads (default is 5). */\r
++ inline void Flow(const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="")\r
++ { mgl_flow_2d(gr, &ax, &ay, sch, opt); }\r
++ /// Plot flows for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color proportional to |a|\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘v’ for drawing arrows on the threads;\r
++ * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.\r
++ * Option "value" sets the number of threads (default is 5). */\r
++ inline void Flow(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="")\r
++ { mgl_flow_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, opt); }\r
++ /// Plot flows for vector field {ax,ay,az} with color proportional to |a|\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘v’ for drawing arrows on the threads;\r
++ * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.\r
++ * Option "value" sets the number of threads (default is 5). */\r
++ inline void Flow(const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="")\r
++ { mgl_flow_3d(gr, &ax, &ay, &az, sch, opt); }\r
++\r
++ /// Plot flow from point p for vector field {ax,ay} parametrically depended on coordinate {x,y} with color proportional to |a|\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘v’ for drawing arrows on the threads. */\r
++ inline void FlowP(mglPoint p, const mglDataA &x, const mglDataA &y, const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="")\r
++ { mgl_flowp_xy(gr, p.x, p.y, p.z, &x, &y, &ax, &ay, sch, opt); }\r
++ /// Plot flow from point p for vector field {ax,ay} with color proportional to |a|\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘v’ for drawing arrows on the threads. */\r
++ inline void FlowP(mglPoint p, const mglDataA &ax, const mglDataA &ay, const char *sch="", const char *opt="")\r
++ { mgl_flowp_2d(gr, p.x, p.y, p.z, &ax, &ay, sch, opt); }\r
++ /// Plot flow from point p for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color proportional to |a|\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘v’ for drawing arrows on the threads;\r
++ * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. */\r
++ inline void FlowP(mglPoint p, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="")\r
++ { mgl_flowp_xyz(gr, p.x, p.y, p.z, &x, &y, &z, &ax, &ay, &az, sch, opt); }\r
++ /// Plot flow from point p for vector field {ax,ay,az} with color proportional to |a|\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘v’ for drawing arrows on the threads;\r
++ * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly. */\r
++ inline void FlowP(mglPoint p, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", const char *opt="")\r
++ { mgl_flowp_3d(gr, p.x, p.y, p.z, &ax, &ay, &az, sch, opt); }\r
++\r
++ /// Plot flows for gradient of scalar field phi parametrically depended on coordinate {x,y,z}\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘v’ for drawing arrows on the threads;\r
++ * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.\r
++ * Option "value" sets the number of threads (default is 5). */\r
++ inline void Grad(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &phi, const char *sch="", const char *opt="")\r
++ { mgl_grad_xyz(gr,&x,&y,&z,&phi,sch,opt); }\r
++ /// Plot flows for gradient of scalar field phi parametrically depended on coordinate {x,y}\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘v’ for drawing arrows on the threads;\r
++ * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.\r
++ * Option "value" sets the number of threads (default is 5). */\r
++ inline void Grad(const mglDataA &x, const mglDataA &y, const mglDataA &phi, const char *sch="", const char *opt="")\r
++ { mgl_grad_xy(gr,&x,&y,&phi,sch,opt); }\r
++ /// Plot flows for gradient of scalar field phi\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘v’ for drawing arrows on the threads;\r
++ * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.\r
++ * Option "value" sets the number of threads (default is 5). */\r
++ inline void Grad(const mglDataA &phi, const char *sch="", const char *opt="")\r
++ { mgl_grad(gr,&phi,sch,opt); }\r
++\r
++ /// Plot flow pipes for vector field {ax,ay} parametrically depended on coordinate {x,y} with color and radius proportional to |a|\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘i’ for pipe radius to be inverse proportional to amplitude.\r
++ * Option "value" sets the number of threads (default is 5). */\r
++ inline void Pipe(const mglDataA &x, const mglDataA &y, const mglDataA &ax, const mglDataA &ay, const char *sch="", double r0=0.05, const char *opt="")\r
++ { mgl_pipe_xy(gr, &x, &y, &ax, &ay, sch, r0, opt); }\r
++ /// Plot flow pipes for vector field {ax,ay} with color and radius proportional to |a|\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘i’ for pipe radius to be inverse proportional to amplitude.\r
++ * Option "value" sets the number of threads (default is 5). */\r
++ inline void Pipe(const mglDataA &ax, const mglDataA &ay, const char *sch="", double r0=0.05, const char *opt="")\r
++ { mgl_pipe_2d(gr, &ax, &ay, sch, r0, opt); }\r
++ /// Plot flow pipes for vector field {ax,ay,az} parametrically depended on coordinate {x,y,z} with color and radius proportional to |a|\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘i’ for pipe radius to be inverse proportional to amplitude;\r
++ * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.\r
++ * Option "value" sets the number of threads (default is 5). */\r
++ inline void Pipe(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", double r0=0.05, const char *opt="")\r
++ { mgl_pipe_xyz(gr, &x, &y, &z, &ax, &ay, &az, sch, r0, opt); }\r
++ /// Plot flow pipes for vector field {ax,ay,az} with color and radius proportional to |a|\r
++ /** String \a sch may contain:\r
++ * color scheme: up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);\r
++ * ‘#’ for starting threads from edges only;\r
++ * ‘i’ for pipe radius to be inverse proportional to amplitude;\r
++ * ‘x’, ‘z’ for drawing tapes of normals in x-y and y-z planes correspondingly.\r
++ * Option "value" sets the number of threads (default is 5). */\r
++ inline void Pipe(const mglDataA &ax, const mglDataA &ay, const mglDataA &az, const char *sch="", double r0=0.05, const char *opt="")\r
++ { mgl_pipe_3d(gr, &ax, &ay, &az, sch, r0, opt); }\r
++\r
++ /// Draw density plot for data at x = sVal\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void DensX(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_dens_x(gr, &a, stl, sVal, opt); }\r
++ /// Draw density plot for data at y = sVal\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void DensY(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_dens_y(gr, &a, stl, sVal, opt); }\r
++ /// Draw density plot for data at z = sVal\r
++ /** Style ‘#’ draw grid lines. Style ‘.’ produce plot by dots.*/\r
++ inline void DensZ(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_dens_z(gr, &a, stl, sVal, opt); }\r
++\r
++ /// Draw contour lines for data at x = sVal\r
++ /** Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContX(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_cont_x(gr, &a, stl, sVal, opt); }\r
++ /// Draw contour lines at manual levels for data at x = sVal\r
++ /** Style ‘t’/‘T’ draw contour labels below/above contours. */\r
++ inline void ContX(const mglDataA &v, const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_cont_x_val(gr, &v, &a, stl, sVal, opt); }\r
++ /// Draw contour lines for data at y = sVal\r
++ /** Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContY(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_cont_y(gr, &a, stl, sVal, opt); }\r
++ /// Draw contour lines at manual levels for data at y = sVal\r
++ /** Style ‘t’/‘T’ draw contour labels below/above contours. */\r
++ inline void ContY(const mglDataA &v, const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_cont_y_val(gr, &v, &a, stl, sVal, opt); }\r
++ /// Draw contour lines for data at z = sVal\r
++ /** Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContZ(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_cont_z(gr, &a, stl, sVal, opt); }\r
++ /// Draw contour lines at manual levels for data at z = sVal\r
++ /** Style ‘t’/‘T’ draw contour labels below/above contours. */\r
++ inline void ContZ(const mglDataA &v, const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_cont_z_val(gr, &v, &a, stl, sVal, opt); }\r
++\r
++ /// Draw solid contours for data at x = sVal\r
++ /** Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContFX(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_contf_x(gr, &a, stl, sVal, opt); }\r
++ /// Draw solid contours at manual levels for data at x = sVal\r
++ inline void ContFX(const mglDataA &v, const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_contf_x_val(gr, &v, &a, stl, sVal, opt); }\r
++ /// Draw solid contours for data at y = sVal\r
++ /** Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContFY(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_contf_y(gr, &a, stl, sVal, opt); }\r
++ /// Draw solid contours at manual levels for data at y = sVal\r
++ inline void ContFY(const mglDataA &v, const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_contf_y_val(gr, &v, &a, stl, sVal, opt); }\r
++ /// Draw solid contours for data at z = sVal\r
++ /** Option "value" set the number of contour levels (default is 7). */\r
++ inline void ContFZ(const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_contf_z(gr, &a, stl, sVal, opt); }\r
++ /// Draw solid contours at manual levels for data at z = sVal\r
++ inline void ContFZ(const mglDataA &v, const mglDataA &a, const char *stl="", double sVal=mglNaN, const char *opt="")\r
++ { mgl_contf_z_val(gr, &v, &a, stl, sVal, opt); }\r
++\r
++ /// Draw curve for formula with x in x-axis range\r
++ /** Option "value" set initial number of points. */\r
++ inline void FPlot(const char *fy, const char *stl="", const char *opt="")\r
++ { mgl_fplot(gr, fy, stl, opt); }\r
++ /// Draw curve for formulas parametrically depended on t in range [0,1]\r
++ /** Option "value" set initial number of points. */\r
++ inline void FPlot(const char *fx, const char *fy, const char *fz, const char *stl, const char *opt="")\r
++ { mgl_fplot_xyz(gr, fx, fy, fz, stl, opt); }\r
++ /// Draw surface by formula with x,y in axis range\r
++ /** Option "value" set initial number of points. */\r
++ inline void FSurf(const char *fz, const char *stl="", const char *opt="")\r
++ { mgl_fsurf(gr, fz, stl, opt); }\r
++ /// Draw surface by formulas parametrically depended on u,v in range [0,1]\r
++ /** Option "value" set initial number of points. */\r
++ inline void FSurf(const char *fx, const char *fy, const char *fz, const char *stl, const char *opt="")\r
++ { mgl_fsurf_xyz(gr, fx, fy, fz, stl, opt); }\r
++\r
++ /// Draw triangle mesh for points in arrays {x,y,z} with specified color c.\r
++ /** Style ‘#’ produce wire plot. If id.ny=c.nx then c set the triangle colors, else vertex colors. */\r
++ inline void TriPlot(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *sch="", const char *opt="")\r
++ { mgl_triplot_xyzc(gr, &nums, &x, &y, &z, &c, sch, opt); }\r
++ /// Draw triangle mesh for points in arrays {x,y,z}\r
++ /** Style ‘#’ produce wire plot. */\r
++ inline void TriPlot(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_triplot_xyz(gr, &nums, &x, &y, &z, sch, opt); }\r
++ /// Draw triangle mesh for points in arrays {x,y}\r
++ /** Style ‘#’ produce wire plot. */\r
++ inline void TriPlot(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const char *sch="", const char *opt="")\r
++ { mgl_triplot_xy(gr, &nums, &x, &y, sch, opt); }\r
++\r
++ /// Draw quad mesh for points in arrays {x,y,z} with specified color c\r
++ /** Style ‘#’ produce wire plot. If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */\r
++ inline void QuadPlot(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const char *sch="", const char *opt="")\r
++ { mgl_quadplot_xyzc(gr, &nums, &x, &y, &z, &c, sch, opt); }\r
++ /// Draw quad mesh for points in arrays {x,y,z}\r
++ /** Style ‘#’ produce wire plot. */\r
++ inline void QuadPlot(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_quadplot_xyz(gr, &nums, &x, &y, &z, sch, opt); }\r
++ /// Draw quad mesh for points in arrays {x,y}\r
++ /** Style ‘#’ produce wire plot. */\r
++ inline void QuadPlot(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const char *sch="", const char *opt="")\r
++ { mgl_quadplot_xy(gr, &nums, &x, &y, sch, opt); }\r
++\r
++ /// Draw contour lines for triangle mesh for points in arrays {x,y,z}\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */\r
++ inline void TriCont(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_tricont_xyc(gr, &nums, &x, &y, &z, sch, opt); }\r
++ /// Draw contour lines for triangle mesh for points in arrays {x,y,z}\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * If id.ny=c.nx then c set the quadrangle colors, else vertex colors.\r
++ * Option "value" set the number of contour levels (default is 7). */\r
++ inline void TriContV(const mglDataA &v, const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_tricont_xycv(gr, &v, &nums, &x, &y, &z, sch, opt); }\r
++ /// Draw contour lines for triangle mesh for points in arrays {x,y,z} with specified color c.\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */\r
++ inline void TriCont(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="")\r
++ { mgl_tricont_xyzc(gr, &nums, &x, &y, &z, &a, sch, opt); }\r
++ /// Draw contour lines for triangle mesh for points in arrays {x,y,z} with specified color c.\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */\r
++ inline void TriContV(const mglDataA &v, const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="")\r
++ { mgl_tricont_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt); }\r
++ /// Draw contour lines for triangle mesh for points in arrays {x,y,z} with specified color c.\r
++ /** Style ‘_’ to draw contours at bottom of axis box.\r
++ * Style ‘t’/‘T’ draw contour labels below/above contours.\r
++ * If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */\r
++ inline void TriCont(const mglDataA &v, const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="")\r
++ { mgl_tricont_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt); }\r
++\r
++ /// Draw contour tubes for triangle mesh for points in arrays {x,y,z}\r
++ /** Option "value" set the number of contour levels (default is 7). */\r
++ inline void TriContVt(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_tricontv_xyc(gr, &nums, &x, &y, &z, sch, opt); }\r
++ /// Draw contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c\r
++ /** Option "value" set the number of contour levels (default is 7). */\r
++ inline void TriContVt(const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="")\r
++ { mgl_tricontv_xyzc(gr, &nums, &x, &y, &z, &a, sch, opt); }\r
++ /// Draw contour tubes for triangle mesh for points in arrays {x,y,z} with specified color c\r
++ /** If id.ny=c.nx then c set the quadrangle colors, else vertex colors. */\r
++ inline void TriContVt(const mglDataA &v, const mglDataA &nums, const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="")\r
++ { mgl_tricontv_xyzcv(gr, &v, &nums, &x, &y, &z, &a, sch, opt); }\r
++\r
++ /// Draw dots in points {x,y,z}.\r
++ inline void Dots(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_dots(gr, &x, &y, &z, sch, opt); }\r
++ /// Draw semitransparent dots in points {x,y,z} with specified alpha a.\r
++ inline void Dots(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *sch="", const char *opt="")\r
++ { mgl_dots_a(gr, &x, &y, &z, &a, sch, opt); }\r
++ /// Draw semitransparent dots in points {x,y,z} with specified color c and alpha a.\r
++ inline void Dots(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &c, const mglDataA &a, const char *sch="", const char *opt="")\r
++ { mgl_dots_ca(gr, &x, &y, &z, &c, &a, sch, opt); }\r
++ /// Draw surface reconstructed for points in arrays {x,y,z}.\r
++ /** Style ‘#’ produce wired plot. */\r
++ inline void Crust(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *sch="", const char *opt="")\r
++ { mgl_crust(gr, &x, &y, &z, sch, opt); }\r
++\r
++ /// Fit data along x-direction for each data row. Return array with values for found formula.\r
++ inline mglData Fit(const mglDataA &y, const char *eq, const char *vars, const char *opt="")\r
++ { return mglData(true,mgl_fit_1(gr, &y, eq,vars,0, opt)); }\r
++ /// Fit data along x-direction for each data row starting from \a ini values. Return array with values for found formula.\r
++ inline mglData Fit(const mglDataA &y, const char *eq, const char *vars, mglData &ini, const char *opt="")\r
++ { return mglData(true,mgl_fit_1(gr, &y, eq, vars, &ini, opt)); }\r
++ /// Fit data along x-, y-directions for each data slice. Return array with values for found formula.\r
++ inline mglData Fit2(const mglDataA &z, const char *eq, const char *vars, const char *opt="")\r
++ { return mglData(true,mgl_fit_2(gr, &z, eq, vars,0, opt)); }\r
++ /// Fit data along x-, y-direction for each data slice starting from \a ini values. Return array with values for found formula.\r
++ inline mglData Fit2(const mglDataA &z, const char *eq, const char *vars, mglData &ini, const char *opt="")\r
++ { return mglData(true,mgl_fit_2(gr, &z, eq, vars, &ini, opt)); }\r
++ /// Fit data along along all directions. Return array with values for found formula.\r
++ inline mglData Fit3(const mglDataA &a, const char *eq, const char *vars, const char *opt="")\r
++ { return mglData(true,mgl_fit_3(gr, &a, eq, vars,0, opt)); }\r
++ /// Fit data along all directions starting from \a ini values. Return array with values for found formula.\r
++ inline mglData Fit3(const mglDataA &a, const char *eq, const char *vars, mglData &ini, const char *opt="")\r
++ { return mglData(true,mgl_fit_3(gr, &a, eq, vars, &ini, opt)); }\r
++\r
++ /// Fit data along x-direction for each data row. Return array with values for found formula.\r
++ inline mglData Fit(const mglDataA &x, const mglDataA &y, const char *eq, const char *vars, const char *opt="")\r
++ { return mglData(true,mgl_fit_xy(gr, &x, &y, eq, vars,0, opt)); }\r
++ /// Fit data along x-direction for each data row starting from \a ini values. Return array with values for found formula.\r
++ inline mglData Fit(const mglDataA &x, const mglDataA &y, const char *eq, const char *vars, mglData &ini, const char *opt="")\r
++ { return mglData(true,mgl_fit_xy(gr, &x, &y, eq, vars, &ini, opt)); }\r
++ /// Fit data along x-, y-directions for each data slice. Return array with values for found formula.\r
++ inline mglData Fit(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *eq, const char *vars, const char *opt="")\r
++ { return mglData(true,mgl_fit_xyz(gr, &x, &y, &z, eq, vars,0, opt)); }\r
++ /// Fit data along x-, y-directions for each data slice starting from \a ini values. Return array with values for found formula.\r
++ inline mglData Fit(const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *eq, const char *vars, mglData &ini, const char *opt="")\r
++ { return mglData(true,mgl_fit_xyz(gr, &x, &y, &z, eq, vars, &ini, opt)); }\r
++ /// Fit data along along all directions. Return array with values for found formula.\r
++ inline mglData Fit(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *eq, const char *vars, const char *opt="")\r
++ { return mglData(true,mgl_fit_xyza(gr, &x, &y, &z, &a, eq, vars,0, opt)); }\r
++ /// Fit data along along all directions starting from \a ini values. Return array with values for found formula.\r
++ inline mglData Fit(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *eq, const char *vars, mglData &ini, const char *opt="")\r
++ { return mglData(true,mgl_fit_xyza(gr, &x, &y, &z, &a, eq,vars, &ini, opt)); }\r
++\r
++ /// Fit data with dispersion s along x-direction for each data row. Return array with values for found formula.\r
++ inline mglData FitS(const mglDataA &y, const mglDataA &s, const char *eq, const char *vars, const char *opt="")\r
++ { return mglData(true,mgl_fit_ys(gr, &y, &s, eq, vars,0, opt)); }\r
++ /// Fit data with dispersion s along x-direction for each data row starting from \a ini values. Return array with values for found formula.\r
++ inline mglData FitS(const mglDataA &y, const mglDataA &s, const char *eq, const char *vars, mglData &ini, const char *opt="")\r
++ { return mglData(true,mgl_fit_ys(gr, &y, &s, eq, vars, &ini, opt)); }\r
++ /// Fit data with dispersion s along x-direction for each data row. Return array with values for found formula.\r
++ inline mglData FitS(const mglDataA &x, const mglDataA &y, const mglDataA &s, const char *eq, const char *vars, const char *opt="")\r
++ { return mglData(true,mgl_fit_xys(gr, &x, &y, &s, eq, vars,0, opt)); }\r
++ /// Fit data with dispersion s along x-direction for each data row starting from \a ini values. Return array with values for found formula.\r
++ inline mglData FitS(const mglDataA &x, const mglDataA &y, const mglDataA &s, const char *eq, const char *vars, mglData &ini, const char *opt="")\r
++ { return mglData(true,mgl_fit_xys(gr, &x, &y, &s, eq, vars, &ini, opt)); }\r
++ /// Fit data with dispersion s along x-, y-directions for each data slice. Return array with values for found formula.\r
++ inline mglData FitS(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &s, const char *eq, const char *vars, const char *opt="")\r
++ { return mglData(true,mgl_fit_xyzs(gr, &x, &y, &z, &s, eq, vars,0, opt)); }\r
++ /// Fit data with dispersion s along x-, y-directions for each data slice starting from \a ini values. Return array with values for found formula.\r
++ inline mglData FitS(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &s, const char *eq, const char *vars, mglData &ini, const char *opt="")\r
++ { return mglData(true,mgl_fit_xyzs(gr, &x, &y, &z, &s, eq, vars, &ini, opt)); }\r
++ /// Fit data with dispersion s along all directions. Return array with values for found formula.\r
++ inline mglData FitS(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &s, const char *eq, const char *vars, const char *opt="")\r
++ { return mglData(true,mgl_fit_xyzas(gr, &x, &y, &z, &a, &s, eq, vars,0, opt)); }\r
++ /// Fit data with dispersion s along all directions starting from \a ini values. Return array with values for found formula.\r
++ inline mglData FitS(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const mglDataA &s, const char *eq, const char *vars, mglData &ini, const char *opt="")\r
++ { return mglData(true,mgl_fit_xyzas(gr, &x, &y, &z, &a, &s, eq, vars, &ini, opt)); }\r
++\r
++ /// Print fitted last formula (with coefficients)\r
++ inline void PutsFit(mglPoint p, const char *prefix=0, const char *font="", double size=-1)\r
++ { mgl_puts_fit(gr, p.x, p.y, p.z, prefix, font, size); }\r
++ /// Get last fitted formula\r
++ inline const char *GetFit() const\r
++ { return mgl_get_fit(gr); }\r
++ /// Get chi for last fitted formula\r
++ static inline mreal GetFitChi()\r
++ { return mgl_get_fit_chi(); }\r
++ /// Get covariance matrix for last fitted formula\r
++ static inline mglData GetFitCovar()\r
++ { return mglData(mgl_get_fit_covar()); }\r
++\r
++ /// Solve PDE with x,y,z in range axis range\r
++ inline mglData PDE(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, double dz=0.1, double k0=100, const char *opt="")\r
++ { return mglData(true,mgl_pde_solve(gr,ham,&ini_re,&ini_im,dz,k0, opt)); }\r
++ /// Solve PDE with x,y,z in range axis range\r
++ inline mglDataC PDEc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, double dz=0.1, double k0=100, const char *opt="")\r
++ { return mglDataC(true,mgl_pde_solve_c(gr,ham,&ini_re,&ini_im,dz,k0, opt)); }\r
++\r
++ /// Solve PDE with x,y,z in range axis range using advanced (slow!!!) method (2d only)\r
++ inline mglData APDE(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, double dz=0.1, double k0=100, const char *opt="")\r
++ { return mglData(true,mgl_pde_adv(gr,ham,&ini_re,&ini_im,dz,k0, opt)); }\r
++ /// Solve PDE with x,y,z in range axis range using advanced (slow!!!) method (2d only)\r
++ inline mglDataC APDEc(const char *ham, const mglDataA &ini_re, const mglDataA &ini_im, double dz=0.1, double k0=100, const char *opt="")\r
++ { return mglDataC(true,mgl_pde_adv_c(gr,ham,&ini_re,&ini_im,dz,k0, opt)); }\r
++\r
++ /// Fill data by formula with x,y,z in range axis range\r
++ inline void Fill(mglData &u, const char *eq, const char *opt="")\r
++ { mgl_data_fill_eq(gr, &u, eq, 0, 0, opt); }\r
++ inline void Fill(mglData &u, const char *eq, const mglDataA &v, const char *opt="")\r
++ { mgl_data_fill_eq(gr, &u, eq, &v, 0, opt); }\r
++ inline void Fill(mglData &u, const char *eq, const mglDataA &v, const mglDataA &w, const char *opt="")\r
++ { mgl_data_fill_eq(gr, &u, eq, &v, &w, opt); }\r
++ /// Fill data by formula with x,y,z in range axis range\r
++ inline void Fill(mglDataC &u, const char *eq, const char *opt="")\r
++ { mgl_datac_fill_eq(gr, &u, eq, 0, 0, opt); }\r
++ inline void Fill(mglDataC &u, const char *eq, const mglDataA &v, const char *opt="")\r
++ { mgl_datac_fill_eq(gr, &u, eq, &v, 0, opt); }\r
++ inline void Fill(mglDataC &u, const char *eq, const mglDataA &v, const mglDataA &w, const char *opt="")\r
++ { mgl_datac_fill_eq(gr, &u, eq, &v, &w, opt); }\r
++\r
++ /// Fill dat by interpolated values of vdat parametrically depended on xdat for x in axis range\r
++ inline void Refill(mglData &dat, const mglDataA &xdat, const mglDataA &vdat, long sl=-1, const char *opt="")\r
++ { mgl_data_refill_gr(gr,&dat,&xdat,0,0,&vdat,sl,opt); }\r
++ /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat for x,y in axis range\r
++ inline void Refill(mglData &dat, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &vdat, long sl=-1, const char *opt="")\r
++ { mgl_data_refill_gr(gr,&dat,&xdat,&ydat,0,&vdat,sl,opt); }\r
++ /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range\r
++ inline void Refill(mglData &dat, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &zdat, const mglDataA &vdat, const char *opt="")\r
++ { mgl_data_refill_gr(gr,&dat,&xdat,&ydat,&zdat,&vdat,-1,opt); }\r
++\r
++ /// Fill dat by interpolated values of vdat parametrically depended on xdat for x in axis range\r
++ inline void Refill(mglDataC &dat, const mglDataA &xdat, const mglDataA &vdat, long sl=-1, const char *opt="")\r
++ { mgl_datac_refill_gr(gr,&dat,&xdat,0,0,&vdat,sl,opt); }\r
++ /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat for x,y in axis range\r
++ inline void Refill(mglDataC &dat, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &vdat, long sl=-1, const char *opt="")\r
++ { mgl_datac_refill_gr(gr,&dat,&xdat,&ydat,0,&vdat,sl,opt); }\r
++ /// Fill dat by interpolated values of vdat parametrically depended on xdat,ydat,zdat for x,y,z in axis range\r
++ inline void Refill(mglDataC &dat, const mglDataA &xdat, const mglDataA &ydat, const mglDataA &zdat, const mglDataA &vdat, const char *opt="")\r
++ { mgl_datac_refill_gr(gr,&dat,&xdat,&ydat,&zdat,&vdat,-1,opt); }\r
++\r
++ /// Set the data by triangulated surface values assuming x,y,z in range axis range\r
++ inline void DataGrid(mglData &d, const mglDataA &x, const mglDataA &y, const mglDataA &z, const char *opt="")\r
++ { mgl_data_grid(gr,&d,&x,&y,&z,opt); }\r
++\r
++ /// Make histogram (distribution) of data. This function do not plot data.\r
++ /** Option "value" sets the size of output array (default is mglFitPnts=100). */\r
++ inline mglData Hist(const mglDataA &x, const mglDataA &a, const char *opt="")\r
++ { return mglData(true, mgl_hist_x(gr, &x, &a, opt)); }\r
++ /// Make histogram (distribution) of data. This function do not plot data.\r
++ /** Option "value" sets the size of output array (default is mglFitPnts=100). */\r
++ inline mglData Hist(const mglDataA &x, const mglDataA &y, const mglDataA &a, const char *opt="")\r
++ { return mglData(true, mgl_hist_xy(gr, &x, &y, &a, opt)); }\r
++ /// Make histogram (distribution) of data. This function do not plot data.\r
++ /** Option "value" sets the size of output array (default is mglFitPnts=100). */\r
++ inline mglData Hist(const mglDataA &x, const mglDataA &y, const mglDataA &z, const mglDataA &a, const char *opt="")\r
++ { return mglData(true, mgl_hist_xyz(gr, &x, &y, &z, &a, opt)); }\r
++\r
++ inline void Compression(bool){} // NOTE: Add later -- IDTF\r
++ /// Set the preference for vertex color on/off (for formats that support it, now only PRC does).\r
++ inline void VertexColor(bool enable) { mgl_set_flag(gr,enable, MGL_PREFERVC); }\r
++ /// Render only front side of surfaces for dubugging purposes (for formats that support it, now only PRC does).\r
++ inline void DoubleSided(bool enable) { mgl_set_flag(gr,!enable, MGL_ONESIDED); }\r
++// inline void TextureColor(bool){} // NOTE: Add later -- IDTF\r
++};\r
++//-----------------------------------------------------------------------------\r
++/// Wrapper class for MGL parsing\r
++class MGL_EXPORT mglParse\r
++{\r
++ HMPR pr;\r
++ mglParse &operator=(mglParse &p)\r
++ { pr = p.pr; mgl_use_parser(pr,1); return p; }\r
++public:\r
++ mglParse(HMPR p) { pr = p; mgl_use_parser(pr,1); }\r
++ mglParse(mglParse &p) { pr = p.pr; mgl_use_parser(pr,1); }\r
++ mglParse(bool setsize=false)\r
++ { pr=mgl_create_parser(); mgl_parser_allow_setsize(pr, setsize); }\r
++ virtual ~mglParse()\r
++ {\r
++#pragma omp critical\r
++ if(mgl_use_parser(pr,-1)<1) mgl_delete_parser(pr);\r
++ }\r
++ /// Get pointer to internal mglParser object\r
++ inline HMPR Self() { return pr; }\r
++ /// Parse and draw single line of the MGL script\r
++ inline int Parse(mglGraph *gr, const char *str, int pos)\r
++ { return mgl_parse_line(gr->Self(), pr, str, pos); }\r
++ inline int Parse(mglGraph *gr, const wchar_t *str, int pos)\r
++ { return mgl_parse_linew(gr->Self(), pr, str, pos); }\r
++ /// Execute MGL script text with '\n' separated lines\r
++ inline void Execute(mglGraph *gr, const char *str)\r
++ { mgl_parse_text(gr->Self(), pr, str); }\r
++ inline void Execute(mglGraph *gr, const wchar_t *str)\r
++ { mgl_parse_textw(gr->Self(), pr, str); }\r
++ /// Execute and draw script from the file\r
++ inline void Execute(mglGraph *gr, FILE *fp, bool print=false)\r
++ { mgl_parse_file(gr->Self(), pr, fp, print); }\r
++\r
++ /// Return type of command: 0 - not found, 1 - other data plot, 2 - func plot,\r
++ /// 3 - setup, 4 - data handle, 5 - data create, 6 - subplot, 7 - program\r
++ /// 8 - 1d plot, 9 - 2d plot, 10 - 3d plot, 11 - dd plot, 12 - vector plot\r
++ /// 13 - axis, 14 - primitives, 15 - axis setup, 16 - text/legend, 17 - data transform\r
++ inline int CmdType(const char *name)\r
++ { return mgl_parser_cmd_type(pr, name); }\r
++ /// Return string of command format (command name and its argument[s])\r
++ inline const char *CmdFormat(const char *name)\r
++ { return mgl_parser_cmd_frmt(pr, name); }\r
++ /// Return description of MGL command\r
++ inline const char *CmdDesc(const char *name)\r
++ { return mgl_parser_cmd_desc(pr, name); }\r
++ /// Get name of command with number n\r
++ inline const char *GetCmdName(long n)\r
++ { return mgl_parser_cmd_name(pr,n); }\r
++ /// Get number of defined commands\r
++ inline long GetCmdNum()\r
++ { return mgl_parser_cmd_num(pr); }\r
++ /// Load new commands from external dynamic Library (must have "const mglCommand *mgl_cmd_extra" variable)\r
++ inline void LoadDLL(const char *fname)\r
++ { mgl_parser_load(pr, fname); }\r
++ /// Apply one step for equation d vars[i]/dt = eqs[i] using Runge-Kutta method\r
++ inline void RK_Step(const char *eqs, const char *vars, mreal dt=1)\r
++ { mgl_rk_step(pr, eqs, vars, dt); }\r
++ inline void RK_Step(const wchar_t *eqs, const wchar_t *vars, mreal dt=1)\r
++ { mgl_rk_step_w(pr, eqs, vars, dt); }\r
++ // Open all data arrays from HDF file and assign it as variables of parser p\r
++ inline void OpenHDF(const char *fname)\r
++ { mgl_parser_openhdf(pr, fname); }\r
++\r
++ /// Set value for parameter $N\r
++ inline void AddParam(int id, const char *str)\r
++ { mgl_parser_add_param(pr, id, str); }\r
++ inline void AddParam(int id, const wchar_t *str)\r
++ { mgl_parser_add_paramw(pr, id, str); }\r
++ /// Restore once flag\r
++ inline void RestoreOnce() { mgl_parser_restore_once(pr); }\r
++ /// Allow changing size of the picture\r
++ inline void AllowSetSize(bool allow) { mgl_parser_allow_setsize(pr, allow); }\r
++ /// Allow reading/saving files\r
++ inline void AllowFileIO(bool allow) { mgl_parser_allow_file_io(pr, allow); }\r
++ /// Allow loading commands from external libraries\r
++ inline void AllowDllCall(bool allow) { mgl_parser_allow_dll_call(pr, allow); }\r
++ /// Set flag to stop script parsing\r
++ inline void Stop() { mgl_parser_stop(pr); }\r
++ /// Set variant of argument(s) separated by '?' to be used in further commands\r
++ inline void SetVariant(int var=0)\r
++ { mgl_parser_variant(pr, var); }\r
++<<<<<<< HEAD\r
++ \r
++=======\r
++ /// Set starting object ID\r
++ inline void StartID(int id=0)\r
++ { mgl_parser_start_id(pr, id); }\r
++\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ /// Return result of formula evaluation\r
++ inline mglData Calc(const char *formula)\r
++ { return mglData(true,mgl_parser_calc(pr,formula)); }\r
++ inline mglData Calc(const wchar_t *formula)\r
++ { return mglData(true,mgl_parser_calcw(pr,formula)); }\r
++\r
++ /// Return result of formula evaluation as complex data\r
++ inline mglDataC CalcComplex(const char *formula)\r
++ { return mglDataC(true,mgl_parser_calc_complex(pr,formula)); }\r
++ inline mglDataC CalcComplex(const wchar_t *formula)\r
++ { return mglDataC(true,mgl_parser_calc_complexw(pr,formula)); }\r
++\r
++ /// Find variable with given name or add a new one\r
++ /// NOTE !!! You must not delete obtained data arrays !!!\r
++ inline mglDataA *AddVar(const char *name)\r
++ { return mgl_parser_add_var(pr, name); }\r
++ inline mglDataA *AddVar(const wchar_t *name)\r
++ { return mgl_parser_add_varw(pr, name); }\r
++ /// Find variable with given name or return NULL if no one\r
++ /// NOTE !!! You must not delete obtained data arrays !!!\r
++ inline mglDataA *FindVar(const char *name)\r
++ { return mgl_parser_find_var(pr, name); }\r
++ inline mglDataA *FindVar(const wchar_t *name)\r
++ { return mgl_parser_find_varw(pr, name); }\r
++ /// Get variable with given id. Can be NULL for temporary ones.\r
++ /// NOTE !!! You must not delete obtained data arrays !!!\r
++ inline mglDataA *GetVar(unsigned long id)\r
++ { return mgl_parser_get_var(pr,id); }\r
++ /// Get number of variables\r
++ inline long GetNumVar()\r
++ { return mgl_parser_num_var(pr); }\r
++ /// Delete variable with name\r
++ inline void DeleteVar(const char *name) { mgl_parser_del_var(pr, name); }\r
++ inline void DeleteVar(const wchar_t *name) { mgl_parser_del_varw(pr, name); }\r
++ /// Delete all data variables\r
++ void DeleteAll() { mgl_parser_del_all(pr); }\r
++\r
++ /// Get constant with given id. Can be NULL if not found.\r
++ /// NOTE !!! You must not delete obtained data arrays !!!\r
++ inline mglNum *GetConst(unsigned long id)\r
++ { return mgl_parser_get_const(pr,id); }\r
++ /// Get number of constants\r
++ inline long GetNumConst()\r
++ { return mgl_parser_num_const(pr); }\r
++};\r
++//-----------------------------------------------------------------------------\r
++#endif\r
++#endif\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * parser.h is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#ifndef _MGL_PARSER_H_\r
++#define _MGL_PARSER_H_\r
++\r
++#ifdef __cplusplus\r
++#include "mgl2/mgl.h"\r
++#if MGL_HAVE_LTDL\r
++#include <ltdl.h>\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++/// Structure for the command argument.\r
++struct mglArg\r
++{\r
++ int type; ///< Type of argument {0-data,1-string,2-number}\r
++ mglDataA *d; ///< Pointer to data (used if type==0)\r
++ std::wstring w; ///< String with parameters\r
++ std::string s; ///< String with parameters\r
++ mreal v; ///< Numerical value (used if type==2)\r
++ dual c; ///< Numerical complex value (used if type==2)\r
++ mglArg():type(-1),d(0),v(0),c(0.) {}\r
++};\r
++//-----------------------------------------------------------------------------\r
++/// Structure for MGL command\r
++struct mglCommand\r
++{\r
++ const char *name; ///< Name of command\r
++ const char *desc; ///< Short command description (can be NULL)\r
++ const char *form; ///< Format of command arguments (can be NULL)\r
++ /// Function for executing (plotting)\r
++ int (*exec)(mglGraph *gr, long n, mglArg *a, const char *k, const char *opt);\r
++ /// Type of command: 0 - special plot, 1 - other plot,\r
++ /// 2 - setup, 3 - data handle, 4 - data create, 5 - subplot, 6 - program\r
++ /// 7 - 1d plot, 8 - 2d plot, 9 - 3d plot, 10 - dd plot, 11 - vector plot\r
++ /// 12 - axis, 13 - primitives, 14 - axis setup, 15 - text/legend, 16 - data transform\r
++ int type;\r
++};\r
++extern mglCommand mgls_prg_cmd[], mgls_dat_cmd[], mgls_grf_cmd[], mgls_set_cmd[], mgls_prm_cmd[];\r
++//-----------------------------------------------------------------------------\r
++/// Structure for function name and position.\r
++struct mglFunc\r
++{\r
++ long pos;\r
++ int narg;\r
++ std::wstring func;\r
++ mglFunc(long p, const wchar_t *f);\r
++ mglFunc(const mglFunc &f):pos(f.pos),narg(f.narg),func(f.func) {}\r
++ mglFunc():pos(-1),narg(-1) {}\r
++ const mglFunc &operator=(const mglFunc &f)\r
++ { pos=f.pos; narg=f.narg; func=f.func; return f; }\r
++};\r
++//-----------------------------------------------------------------------------\r
++/// Structure for stack of functions and its arguments.\r
++struct mglFnStack\r
++{\r
++ long pos;\r
++ std::wstring par[10];\r
++ mglFnStack():pos(0) {}\r
++};\r
++//-----------------------------------------------------------------------------\r
++/// Function for asking question in console mode\r
++void MGL_EXPORT mgl_ask_gets(const wchar_t *quest, wchar_t *res);\r
++//-----------------------------------------------------------------------------\r
++/// Structure for the command argument (see mglGraph::Exec()).\r
++class mglParser\r
++{\r
++friend void mgl_export(wchar_t *out, const wchar_t *in, int type);\r
++public:\r
++#if MGL_HAVE_LTDL\r
++ std::vector<lt_dlhandle> DllOpened; ///< Opened external DLL (keep )\r
++#endif\r
++ std::vector<mglDataA*> DataList; ///< List with data and its names\r
++ std::vector<mglNum*> NumList; ///< List with numbers and its names\r
++ bool AllowDllCall; ///< Allow calls from external dynamic libraries\r
++ bool AllowSetSize; ///< Allow using setsize command\r
++ bool AllowFileIO; ///< Allow reading/saving files\r
++ volatile bool Stop; ///< Stop command was. Flag prevent further execution\r
++ mglCommand *Cmd; ///< Table of MGL commands (can be changed by user). It MUST be sorted by 'name'!!!\r
++ long InUse; ///< Smart pointer (number of users)\r
++ const mglBase *curGr; ///< Current grapher\r
++ int StarObhID; ///< staring object id\r
++\r
++ mglParser(bool setsize=false);\r
++ virtual ~mglParser();\r
++ /// Find the command by the keyword name\r
++ const mglCommand *FindCommand(const char *name) const MGL_FUNC_PURE;\r
++ const mglCommand *FindCommand(const wchar_t *name) const MGL_FUNC_PURE;\r
++ /// Parse and execute the string of MGL script\r
++ inline int Parse(HMGL gr, const char *str, long pos=0)\r
++ { mglGraph GR(gr); return Parse(&GR,str,pos); }\r
++ int Parse(mglGraph *gr, const char *str, long pos=0);\r
++ /// Parse and execute the unicode string of MGL script\r
++ inline int Parse(HMGL gr, const wchar_t *str, long pos=0)\r
++ { mglGraph GR(gr); return Parse(&GR,str,pos); }\r
++ int Parse(mglGraph *gr, std::wstring str, long pos=0);\r
++ /// Execute MGL script file fname\r
++ inline void Execute(HMGL gr, FILE *fp, bool print=false)\r
++ { mglGraph GR(gr); Execute(&GR,fp,print); }\r
++ void Execute(mglGraph *gr, FILE *fp, bool print=false);\r
++ /// Execute MGL script from array of lines\r
++ inline void Execute(HMGL gr, int num, const wchar_t **text)\r
++ { mglGraph GR(gr); Execute(&GR,num,text); }\r
++ void Execute(mglGraph *gr, int num, const wchar_t **text);\r
++ /// Execute MGL script text with '\n' separated lines\r
++ inline void Execute(HMGL gr, const wchar_t *text)\r
++ { mglGraph GR(gr); Execute(&GR,text); }\r
++ void Execute(mglGraph *gr, const wchar_t *text);\r
++ /// Execute MGL script text with '\n' separated lines\r
++ inline void Execute(HMGL gr, const char *text)\r
++ { mglGraph GR(gr); Execute(&GR,text); }\r
++ void Execute(mglGraph *gr, const char *text);\r
++ /// Scan for functions (use NULL for reset)\r
++ void ScanFunc(const wchar_t *line);\r
++ /// Check if name is function and return its address (or 0 if no)\r
++ long IsFunc(const std::wstring &name, int *narg=0);\r
++ /// Find variable or return 0 if absent\r
++ mglDataA *FindVar(const char *name) MGL_FUNC_PURE;\r
++ mglDataA *FindVar(const wchar_t *name) MGL_FUNC_PURE;\r
++ /// Find variable or create it if absent\r
++ mglDataA *AddVar(const char *name);\r
++ mglDataA *AddVar(const wchar_t *name);\r
++ /// Find number or return 0 if absent\r
++ mglNum *FindNum(const char *name) MGL_FUNC_PURE;\r
++ mglNum *FindNum(const wchar_t *name) MGL_FUNC_PURE;\r
++ /// Find number or create it if absent\r
++ mglNum *AddNum(const char *name);\r
++ mglNum *AddNum(const wchar_t *name);\r
++ /// Add string for parameter $1, ..., $9\r
++ void AddParam(int n, const char *str);\r
++ void AddParam(int n, const wchar_t *str);\r
++ /// Add new MGL command(s) (last command MUST HAVE name[0]=0 !!!)\r
++ void AddCommand(const mglCommand *cmd);\r
++ /// Restore Once flag\r
++ inline void RestoreOnce() { Once = true; }\r
++ /// Delete variable by its name\r
++ void DeleteVar(const char *name);\r
++ void DeleteVar(const wchar_t *name);\r
++ /// Delete all data variables\r
++ void DeleteAll();\r
++ /// Set variant of argument(s) separated by '?' to be used\r
++ inline void SetVariant(int var=0) { Variant = var<=0?0:var; }\r
++<<<<<<< HEAD\r
++=======\r
++protected:\r
++ static mglCommand *BaseCmd; ///< Base table of MGL commands. It MUST be sorted by 'name'!!!\r
++ static void FillBaseCmd(); ///< Fill BaseCmd at initialization stage\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++private:\r
++// long parlen; ///< Length of parameter strings\r
++ std::wstring par[40]; ///< Parameter for substituting instead of $1, ..., $9\r
++ bool Once; ///< Flag for command which should be executed only once\r
++ bool Skip; ///< Flag that commands should be skiped (inside 'once' block)\r
++ int if_stack[40]; ///< Stack for if-else-endif commands\r
++ int if_pos; ///< position in if_stack\r
++ std::vector<mglFunc> func; ///< function names and position\r
++ std::vector<mglFnStack> fn_stack; ///< function calls stack\r
++// int fn_pos; ///< position in function stack\r
++ int if_for[40]; ///< position in if_stack for for-cycle start\r
++ mglData *fval; ///< Values for for-cycle. Note that nx - number of elements, ny - next element, nz - address (or string number) of first cycle command\r
++ int for_stack[40]; ///< The order of for-variables\r
++ int for_addr; ///< Flag for saving address in variable (for_addr-1)\r
++<<<<<<< HEAD\r
++ bool for_br; ///< Break is switched on (skip all comands until 'next')\r
++=======\r
++ bool for_br; ///< Break is switched on (skip all commands until 'next')\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ unsigned Variant; ///< Select variant of argument(s) separated by '?'\r
++\r
++ /// Parse command\r
++ int Exec(mglGraph *gr, const wchar_t *com, long n, mglArg *a, const std::wstring &var, const wchar_t *opt);\r
++ /// Fill arguments a from strings\r
++ void FillArg(mglGraph *gr, int n, std::wstring *arg, mglArg *a);\r
++ /// PreExecute stage -- parse some commands and create variables\r
++ int PreExec(mglGraph *gr, long n, std::wstring *arg, mglArg *a);\r
++ /// Execute program-flow control commands\r
++ int FlowExec(mglGraph *gr, const std::wstring &com, long n, mglArg *a);\r
++ /// Parse and execute the unicode string of MGL script\r
++ int ParseDat(mglGraph *gr, std::wstring str, mglData &res);\r
++ /// Define '$' parameters or start for loop\r
++ int ParseDef(std::wstring &str);\r
++ /// Parse $N arguments\r
++ void PutArg(std::wstring &str, bool def);\r
++ /// In skip mode\r
++ bool inline ifskip() { return (if_pos>0 && !(if_stack[if_pos-1]&1)); }\r
++ bool inline skip() { return (Skip || ifskip() || for_br); }\r
++ bool CheckForName(const std::wstring &s); // check if name is valid for new data\r
++};\r
++//-----------------------------------------------------------------------------\r
++#endif\r
++#endif\r
--- /dev/null
--- /dev/null
++#include <QMessageBox>
++#include <QTextStream>
++#include <QFile>
++#include <QDebug>
++#include "Backend.hpp"
++#include <mgl2/mgl.h>
++#undef sprintf // fix libintl bug of defining sprintf
++//-----------------------------------------------------------------------------
++Backend::Backend(QObject *parent) : QObject(parent) { }
++//-----------------------------------------------------------------------------
++QString Backend::show(const QString& text) const
++{
++ qDebug() << __FUNCTION__;
++ const char *tmp = tmpnam(0);
++ wchar_t *wtext;
++ mglGraph gr;
++ gr.SetFaceNum(200);
++ mglParse pr;
++ pr.AllowSetSize(true);
++<<<<<<< HEAD
++ setlocale(LC_CTYPE, "");
++ setlocale(LC_NUMERIC, "C");
++=======
++ setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C");
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ wtext = new wchar_t[text.size()+1];
++ text.toWCharArray(wtext);
++ wtext[text.size()] = 0;
++ pr.Execute(&gr,wtext);
++ delete[] wtext;
++ gr.WriteJSON(tmp);
++ setlocale(LC_NUMERIC, "");
++
++ QFile f(tmp);
++ f.open(QIODevice::ReadOnly);
++ QTextStream ts(&f);
++ ts.setAutoDetectUnicode(true);
++ const QString json = ts.readAll();
++ f.remove();
++ return json;
++}
++//-----------------------------------------------------------------------------
++QString Backend::coor(const QString& xy, const QString& text) const
++{
++ wchar_t *wtext;
++ qDebug() << __FUNCTION__;
++ mglGraph gr;
++ mglParse pr;
++ pr.AllowSetSize(true);
++<<<<<<< HEAD
++ setlocale(LC_CTYPE, "");
++ setlocale(LC_NUMERIC, "C");
++=======
++ setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C");
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ wtext = new wchar_t[text.size()+1];
++ text.toWCharArray(wtext);
++ wtext[text.size()] = 0;
++ pr.Execute(&gr,wtext);
++ delete[] wtext;
++ gr.Finish();
++
++ int x = (int)xy.section(" ",0,0).toDouble();
++ int y = (int)xy.section(" ",1,1).toDouble();
++ mglPoint p = gr.CalcXYZ(x,y);
++ QString res;
++ res.sprintf("x = %g, y = %g, z = %g for point (%d, %d)\n", p.x, p.y, p.z, x,y);
++ qDebug() << res+"\nask"+xy;
++ return res+"\nask"+xy;
++}
++//-----------------------------------------------------------------------------
++QString Backend::geometry(const QString& mgl) const
++{
++ qDebug() << __FUNCTION__;
++ const char *tmp = tmpnam(0);
++ wchar_t *wmgl;
++ mglGraph gr;
++#if 0
++ gr.SetFaceNum(200);
++#endif
++ mglParse pr;
++ pr.AllowSetSize(true);
++<<<<<<< HEAD
++ setlocale(LC_CTYPE, "");
++ setlocale(LC_NUMERIC, "C");
++=======
++ setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C");
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ wmgl = new wchar_t[mgl.size()+1];
++ mgl.toWCharArray(wmgl);
++ wmgl[mgl.size()] = 0;
++ pr.Execute(&gr,wmgl);
++ delete[] wmgl;
++ gr.WriteJSON(tmp);
++ setlocale(LC_NUMERIC, "");
++
++ QFile f(tmp);
++ f.open(QIODevice::ReadOnly);
++ QTextStream ts(&f);
++ ts.setAutoDetectUnicode(true);
++ const QString json = ts.readAll();
++ f.remove();
++ return json;
++}
++//-----------------------------------------------------------------------------
--- /dev/null
--- /dev/null
++if(enable-qt5)
++ include(../scripts/qt5.cmake)
++
++ find_qt5_libs(OFF ON Network)
++ if(TARGET Qt5::Network)
++ set(MGL_QT5_LIBS ${MGL_QT5_LIBS} Qt5::Network)
++ find_qt5_libs(OFF OFF WebKitWidgets WebEngineWidgets)
++ if(enable-json-sample-we)
++ if(TARGET Qt5::WebEngineWidgets)
++ set(MGL_QT5_LIBS ${MGL_QT5_LIBS} Qt5::WebEngineWidgets)
++ set(mgl_qt_def MGL_USE_QT5_WE)
++ else(TARGET Qt5::WebEngineWidgets)
++ message(STATUS "Couldn't find Qt5 WebEngineWidgets library. Trying WebKit.")
++ set(enable-json-sample-we OFF)
++ endif(TARGET Qt5::WebEngineWidgets)
++ endif(enable-json-sample-we)
++ if(TARGET Qt5::WebKitWidgets)
++ set(MGL_QT5_LIBS ${MGL_QT5_LIBS} Qt5::WebKitWidgets)
++ else(TARGET Qt5::WebKitWidgets)
++ message(STATUS "Couldn't find Qt5 WebKitWidgets library. JSON sample disabled.")
++ set(enable-json-sample OFF)
++ endif(TARGET Qt5::WebKitWidgets)
++ else(TARGET Qt5::Network)
++ message(STATUS "Couldn't find Qt5 Network library. JSON sample disabled.")
++ set(enable-json-sample OFF)
++ endif(TARGET Qt5::Network)
++else(enable-qt5)
++ include(../scripts/qt4.cmake)
++
++ foreach(mgl_qt4_lib ${MGL_QT4_LIBS_FIND_JSON})
++ if(TARGET Qt4::${mgl_qt4_lib})
++ set(MGL_QT4_LIBS ${MGL_QT4_LIBS} Qt4::${mgl_qt4_lib})
++ else(TARGET Qt4::${mgl_qt4_lib})
++ message(STATUS "Couldn't find Qt4 ${mgl_qt4_lib} library. JSON sample disabled.")
++ set(enable-json-sample OFF)
++ endif(TARGET Qt4::${mgl_qt4_lib})
++ endforeach(mgl_qt4_lib)
++endif(enable-qt5)
++
++if(enable-json-sample)
++
++set(json_src Backend.cpp MainWindow.cpp MainWindow.ui)
++set(json_moc_hdr Backend.hpp MainWindow.hpp)
++
++include_directories(${MathGL2_BINARY_DIR}/json)
++add_executable(MglForJsTestBench ${json_src} ${json_moc_hdr})
++if(enable-qt5)
++<<<<<<< HEAD
++ target_compile_definitions(MglForJsTestBench PUBLIC MGL_USE_QT5)
++=======
++ target_compile_definitions(MglForJsTestBench PUBLIC MGL_USE_QT5 ${mgl_qt_def})
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ target_link_libraries(MglForJsTestBench mgl-qt5 ${MGL_QT5_LIBS})
++else(enable-qt5)
++ target_link_libraries(MglForJsTestBench mgl-qt4 ${MGL_QT4_LIBS})
++endif(enable-qt5)
++
++endif(enable-json-sample)
--- /dev/null
--- /dev/null
++set(mgl_src
++ addon.cpp axis.cpp base_cf.cpp base.cpp canvas_cf.cpp canvas.cpp cont.cpp crust.cpp
++ complex.cpp complex_ex.cpp complex_io.cpp fft.cpp data_gr.cpp
++ data.cpp data_io.cpp data_ex.cpp data_png.cpp
++<<<<<<< HEAD
++ export_2d.cpp export_3d.cpp eval.cpp evalp.cpp exec.cpp export.cpp
++ fit.cpp font.cpp obj.cpp other.cpp parser.cpp pde.cpp pixel.cpp
++ plot.cpp prim.cpp surf.cpp vect.cpp volume.cpp evalc.cpp
++ s_hull/s_hull_pro.cpp window.cpp fractal.cpp
++=======
++ export_2d.cpp export_3d.cpp eval.cpp evalp.cpp export.cpp
++ fit.cpp font.cpp obj.cpp other.cpp parser.cpp pde.cpp pixel.cpp pixel_gen.cpp
++ plot.cpp prim.cpp surf.cpp vect.cpp volume.cpp evalc.cpp
++ s_hull/s_hull_pro.cpp window.cpp fractal.cpp
++ exec_dat.cpp exec_gr.cpp exec_set.cpp exec_prm.cpp
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++)
++
++set(mgl_hdr
++ ../include/mgl2/base_cf.h ../include/mgl2/fit.h ../include/mgl2/plot.h
++ ../include/mgl2/base.h ../include/mgl2/prim.h ../include/mgl2/canvas_cf.h
++ ../include/mgl2/font.h ../include/mgl2/canvas.h ../include/mgl2/surf.h
++ ../include/mgl2/mgl_cf.h ../include/mgl2/type.h ${MathGL2_BINARY_DIR}/include/mgl2/config.h
++${MathGL2_BINARY_DIR}/include/mgl2/dllexport.h cont.hpp
++ ../include/mgl2/cont.h ../include/mgl2/mgl.h ../include/mgl2/vect.h
++ ../include/mgl2/data.h ../include/mgl2/volume.h ../include/mgl2/data_cf.h
++ ../include/mgl2/define.h ../include/mgl2/other.h ../include/mgl2/eval.h
++ ../include/mgl2/parser.h ../include/mgl2/addon.h ../include/mgl2/evalc.h
++ s_hull/s_hull_pro.h ../include/mgl2/wnd.h ../include/mgl2/canvas_wnd.h
++ ../include/mgl2/thread.h ../include/mgl2/abstract.h ../include/mgl2/pde.h
++# tex_table.cc def_font.cc
++)
++
++if(MGL_HAVE_GSL2)
++ add_definitions(-DMGL_HAVE_GSL2)
++endif(MGL_HAVE_GSL2)
++
++if(MGL_HAVE_PNG)
++ set(prc_src prc/PRCbitStream.cc prc/PRCdouble.cc prc/oPRCFile.cc prc/writePRC.cc prc.cpp )
++ set(prc_hdr prc/PRC.h prc/PRCbitStream.h prc/PRCdouble.h prc/oPRCFile.h prc/writePRC.h )
++
++ set(mgl_src ${mgl_src} ${prc_src} )
++ set(mgl_hdr ${mgl_hdr} ${prc_hdr} )
++ include_directories(prc)
++endif(MGL_HAVE_PNG)
++
++if(MGL_HAVE_OPENGL)
++ set(mgl_src ${mgl_src} opengl.cpp )
++ set(mgl_hdr ${mgl_hdr} ../include/mgl2/opengl.h )
++endif(MGL_HAVE_OPENGL)
++
++include(GenerateExportHeader)
++mgl_add_lib(mgl ${mgl_src} ${mgl_hdr})
++generate_export_header(mgl EXPORT_FILE_NAME ../include/mgl2/dllexport.h)
++
++target_link_libraries(mgl ${MGL_DEP_LIBS})
++target_link_libraries(mgl-static ${MGL_DEP_LIBS})
++<<<<<<< HEAD
++=======
++
++mgl_po_src(${mgl_src} ${mgl_hdr})
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++if(MGL_HAVE_MPI)
++ mgl_add_lib(mpi mpi.cpp ../include/mgl2/mpi.h)
++ target_link_libraries(mgl-mpi ${MPI_LIBRARIES} )
++ target_link_libraries(mgl-mpi-static ${MPI_LIBRARIES} )
++ target_include_directories(mgl-mpi SYSTEM PUBLIC ${MPI_CXX_INCLUDE_PATH})
++endif(MGL_HAVE_MPI)
++
++install(FILES ${MathGL2_BINARY_DIR}/include/mgl2/dllexport.h DESTINATION ${MGL_INCLUDE_PATH})
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * canvas.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include <limits.h>\r
++#include "mgl2/font.h"\r
++#include "mgl2/canvas.h"\r
++//-----------------------------------------------------------------------------\r
++MGL_EXPORT std::string mglGlobalMess; ///< Buffer for receiving global messages\r
++//-----------------------------------------------------------------------------\r
++mglCanvas::mglCanvas(int w, int h) : mglBase()\r
++{\r
++ clr(MGL_DISABLE_SCALE);\r
++ set(MGL_VECT_FRAME); // NOTE: require a lot of memory!\r
++ Z=0; C=G=G4=GB=0; OI=0; gif=0;\r
++ CurFrameId=0; Delay=0.5;\r
++ Width=Height=Depth=0; ObjId=-1;\r
++ fscl=ftet=0; PlotId = _("frame");\r
++ pnt_col = 0;\r
++\r
++ ac.ch='c';\r
++ ax.dir.Set(1,0,0); ax.a.Set(0,1,0); ax.b.Set(0,0,1); ax.ch='x';\r
++ ay.dir.Set(0,1,0); ay.a.Set(1,0,0); ay.b.Set(0,0,1); ay.ch='y';\r
++ az.dir.Set(0,0,1); az.a.Set(0,1,0); az.b.Set(1,0,0); az.ch='z';\r
++\r
++ SetSize(w,h); SetQuality(MGL_DRAW_NORM); DefaultPlotParam();\r
++}\r
++//-----------------------------------------------------------------------------\r
++mglCanvas::~mglCanvas()\r
++{\r
++ if(G) { delete []G; delete []C; delete []Z; delete []G4;delete []GB;delete []OI; }\r
++ if(pnt_col) delete []pnt_col;\r
++}\r
++//-----------------------------------------------------------------------------\r
++long mglCanvas::PushDrwDat()\r
++{\r
++ mglDrawDat d;\r
++ d.Pnt=Pnt; d.Prm=Prm; d.Sub=Sub; d.Glf=Glf; d.Ptx=Ptx; d.Txt=Txt;\r
++#pragma omp critical(drw)\r
++ MGL_PUSH(DrwDat,d,mutexDrw);\r
++ return DrwDat.size();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::ResetFrames() { CurFrameId=0; DrwDat.clear(); }\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::SetFrame(long i)\r
++{\r
++ if(get(MGL_VECT_FRAME) && i>=0 && i<long(DrwDat.size()))\r
++ {\r
++ Finish(); CurFrameId--;\r
++ mglDrawDat d;\r
++ d.Pnt=Pnt; d.Prm=Prm; d.Sub=Sub; d.Glf=Glf; d.Ptx=Ptx; d.Txt=Txt;\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_lock(&mutexDrw);\r
++ DrwDat[i] = d;\r
++ pthread_mutex_unlock(&mutexDrw);\r
++#else\r
++#pragma omp critical(drw)\r
++ DrwDat[i] = d;\r
++#endif\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::GetFrame(long k)\r
++{\r
++ if(k<0 || (size_t)k>=DrwDat.size()) return;\r
++ ClearFrame();\r
++ const mglDrawDat &d=DrwDat[k];\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_lock(&mutexPnt);\r
++ pthread_mutex_lock(&mutexPrm);\r
++ pthread_mutex_lock(&mutexSub);\r
++ pthread_mutex_lock(&mutexGlf);\r
++ pthread_mutex_lock(&mutexPtx);\r
++ pthread_mutex_lock(&mutexTxt);\r
++#endif\r
++#pragma omp critical\r
++ { Pnt=d.Pnt; Prm=d.Prm; Sub=d.Sub; Glf=d.Glf; Ptx=d.Ptx; Txt=d.Txt; ClearPrmInd(); }\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_unlock(&mutexTxt);\r
++ pthread_mutex_unlock(&mutexPtx);\r
++ pthread_mutex_unlock(&mutexGlf);\r
++ pthread_mutex_unlock(&mutexSub);\r
++ pthread_mutex_unlock(&mutexPrm);\r
++ pthread_mutex_unlock(&mutexPnt);\r
++#endif\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::ClearFrame()\r
++{\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_lock(&mutexPnt);\r
++ pthread_mutex_lock(&mutexPrm);\r
++ pthread_mutex_lock(&mutexGlf);\r
++ pthread_mutex_lock(&mutexPtx);\r
++ pthread_mutex_lock(&mutexTxt);\r
++ pthread_mutex_lock(&mutexSub);\r
++ pthread_mutex_lock(&mutexLeg);\r
++ pthread_mutex_lock(&mutexGrp);\r
++ pthread_mutex_lock(&mutexAct);\r
++#endif\r
++\r
++#pragma omp critical\r
++ {\r
++ StartAutoGroup(NULL);\r
++ Leg.clear(); Grp.clear(); Act.clear(); Glf.clear();\r
++ Pnt.clear(); Prm.clear(); Ptx.clear(); ClearPrmInd();\r
++ Txt.clear(); Txt.reserve(3);\r
++// mglBlock inpl = Sub[0]; Sub.clear(); Sub.push_back(inpl); // NOTE at least one inplot should present!!!\r
++ mglTexture t1(MGL_DEF_PAL,-1), t2(MGL_DEF_SCH,1);\r
++ Txt.push_back(t1); Txt.push_back(t2); // No extra lock is required\r
++ }\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_unlock(&mutexAct);\r
++ pthread_mutex_unlock(&mutexGrp);\r
++ pthread_mutex_unlock(&mutexLeg);\r
++ pthread_mutex_unlock(&mutexSub);\r
++ pthread_mutex_unlock(&mutexTxt);\r
++ pthread_mutex_unlock(&mutexPtx);\r
++ pthread_mutex_unlock(&mutexGlf);\r
++ pthread_mutex_unlock(&mutexPrm);\r
++ pthread_mutex_unlock(&mutexPnt);\r
++#endif\r
++ ClfZB(true);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::ShowFrame(long k)\r
++{\r
++ if(k<0 || (size_t)k>=DrwDat.size()) return;\r
++ ClfZB();\r
++ size_t npnt=Pnt.size(), nglf=Glf.size(), nptx=Ptx.size(), ntxt=Txt.size(), nsub=Sub.size();\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_lock(&mutexPnt);\r
++ pthread_mutex_lock(&mutexPrm);\r
++ pthread_mutex_lock(&mutexSub);\r
++ pthread_mutex_lock(&mutexGlf);\r
++ pthread_mutex_lock(&mutexPtx);\r
++ pthread_mutex_lock(&mutexTxt);\r
++#endif\r
++#pragma omp critical\r
++ {\r
++ const mglDrawDat &d=DrwDat[k];\r
++ Glf.resize(d.Glf.size()); for(size_t i=0;i<d.Glf.size();i++) Glf.push_back(d.Glf[i]);\r
++ Ptx.resize(d.Ptx.size()); for(size_t i=0;i<d.Ptx.size();i++) Ptx.push_back(d.Ptx[i]);\r
++ Sub.resize(d.Sub.size()); for(size_t i=0;i<d.Sub.size();i++) Sub.push_back(d.Sub[i]);\r
++ Txt.reserve(d.Pnt.size()); for(size_t i=0;i<d.Txt.size();i++) Txt.push_back(d.Txt[i]);\r
++ Pnt.reserve(d.Pnt.size()); ClearPrmInd();\r
++ for(size_t i=0;i<d.Pnt.size();i++)\r
++ {\r
++ mglPnt p = d.Pnt[i]; p.c += ntxt;\r
++ if(p.sub>=0) p.sub += nsub;\r
++ else p.sub -= nsub;\r
++ Pnt.push_back(p);\r
++ }\r
++ Prm.reserve(d.Prm.size());\r
++ for(size_t i=0;i<d.Prm.size();i++)\r
++ {\r
++ mglPrim p = d.Prm[i];\r
++ p.n1 += npnt;\r
++\r
++ switch(p.type)\r
++ {\r
++ case 1: p.n2 += npnt; break;\r
++ case 2: p.n2 += npnt; p.n3 += npnt; break;\r
++ case 3: p.n2 += npnt; p.n3 += npnt; p.n4 += npnt; break;\r
++ case 4: p.n4 += nglf; break;\r
++ case 5: p.n2 += npnt; break;\r
++ case 6: p.n3 += nptx; break;\r
++ }\r
++ Prm.push_back(p);\r
++ }\r
++ }\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_unlock(&mutexPnt);\r
++ pthread_mutex_unlock(&mutexPrm);\r
++ pthread_mutex_unlock(&mutexSub);\r
++ pthread_mutex_unlock(&mutexGlf);\r
++ pthread_mutex_unlock(&mutexPtx);\r
++ pthread_mutex_unlock(&mutexTxt);\r
++#endif\r
++}\r
++//-----------------------------------------------------------------------------\r
++const unsigned char *mglCanvas::GetBits() { Finish(); return G; }\r
++//-----------------------------------------------------------------------------\r
++mreal mglCanvas::GetRatio() const { return inW/inH; }\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::add_prim(mglPrim &a)\r
++{\r
++ if(a.n1>=0)\r
++ {\r
++ a.z = Pnt[a.n1].z; // this is a bit less accurate but simpler for transformation\r
++ a.id = ObjId;\r
++#pragma omp critical(prm)\r
++ MGL_PUSH(Prm,a,mutexPrm);\r
++ ClearPrmInd(); clr(MGL_FINISHED);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++extern uint64_t mgl_mask_def[16];\r
++void mglCanvas::DefaultPlotParam()\r
++{\r
++/* NOTE: following variables and mutex will not be changed by DefaultPlotParam()\r
++long InUse; ///< Smart pointer (number of users)\r
++mglFont *fnt; ///< Class for printing vector text\r
++int Quality; ///< Quality of plot (0x0-pure, 0x1-fast; 0x2-fine; 0x4 - low memory)\r
++int Width; ///< Width of the image\r
++int Height; ///< Height of the image\r
++int Depth; ///< Depth of the image\r
++int CurFrameId; ///< Number of automaticle created frames\r
++GifFileType *gif;*/\r
++ SetDrawReg(1,1,0); Perspective(0); SetPenDelta(1); SetBBox();\r
++ memcpy(mgl_mask_val, mgl_mask_def, 16*sizeof(uint64_t)); // should be > 16*8\r
++ ax.Clear(); ay.Clear(); az.Clear(); ac.Clear();\r
++ mgl_clear_fft(); DefMaskAn=0; ResetMask();\r
++ SetTickRotate(true); SetTickSkip(true);\r
++ SetWarn(mglWarnNone,""); mglGlobalMess = "";\r
++ ObjId = -1; HighId = INT_MIN;\r
++ SetFunc(0,0); CutOff(0); Ternary(0);\r
++ Stop=false; event_cb = NULL; event_par=NULL;\r
++ SetRanges(mglPoint(-1,-1,-1,-1), mglPoint(1,1,1,1));\r
++ SetOrigin(NAN,NAN,NAN,NAN);\r
++ SetBarWidth(0.7); SetMarkSize(1); SetArrowSize(1);\r
++ SetAlphaDef(0.5); FontDef[0]=0;\r
++ SetTranspType(0); SetMeshNum(0); // NOTE: default MeshNum=0\r
++ SetRotatedText(true); CurrPal = 0;\r
++ SetLegendMarks(); SetFontSize(4);\r
++ SetTuneTicks(3); SetAmbient(); SetDiffuse();\r
++ clr(MGL_DISABLE_SCALE);\r
++ clr(MGL_USE_GMTIME); clr(MGL_NOSUBTICKS);\r
++ SetDifLight(false); SetReduceAcc(false);\r
++ SetDefScheme(MGL_DEF_SCH); SetPalette(MGL_DEF_PAL);\r
++ SetPenPal("k-1"); Alpha(false);\r
++ stack.clear(); Restore(); DefColor('k');\r
++ SetPlotFactor(0); Sub.clear();\r
++ InPlot(0,1,0,1,false);\r
++ SetTickLen(0); SetCut(true);\r
++ AdjustTicks("xyzc",true); Clf('w');\r
++\r
++ for(int i=0;i<10;i++) { AddLight(i, mglPoint(0,0,1)); Light(i,false); }\r
++ Light(0,true); Light(false); SetDifLight(true);\r
++}\r
++//-----------------------------------------------------------------------------\r
++// Optimal axis position\r
++//-----------------------------------------------------------------------------\r
++mreal mglCanvas::FindOptOrg(char dir, int ind) const\r
++{\r
++ static mglPoint px, py, pz;\r
++ static mglMatrix bb;\r
++ mglPoint nn[8]={mglPoint(0,0,0), mglPoint(0,0,1), mglPoint(0,1,0,0), mglPoint(0,1,1),\r
++ mglPoint(1,0,0), mglPoint(1,0,1), mglPoint(1,1,0), mglPoint(1,1,1)}, pp[8];\r
++ memcpy(pp, nn, 8*sizeof(mglPoint));\r
++ // do nothing if transformation matrix is the same\r
++ if(B!=bb)\r
++ {\r
++ bb = B;\r
++ for(long i=0;i<8;i++) PostScale(&B,pp[i]);\r
++ // find point with minimal y\r
++ long j=0;\r
++ for(long i=1;i<8;i++) if(pp[i].y<pp[j].y) j=i;\r
++ pp[0]=pp[j];\r
++ // first select 3 closest points\r
++ pp[1].x=1-nn[j].x; pp[1].y=nn[j].y; pp[1].z=nn[j].z; PostScale(&B,pp[1]); pp[1]-=pp[0];\r
++ pp[2].x=nn[j].x; pp[2].y=1-nn[j].y; pp[2].z=nn[j].z; PostScale(&B,pp[2]); pp[2]-=pp[0];\r
++ pp[3].x=nn[j].x; pp[3].y=nn[j].y; pp[3].z=1-nn[j].z; PostScale(&B,pp[3]); pp[3]-=pp[0];\r
++ // find cosine of axis projection\r
++ mreal tx=fabs(pp[1].x/pp[1].y), ty=fabs(pp[2].x/pp[2].y), tz=fabs(pp[3].x/pp[3].y);\r
++ px=py=pz=nn[j];\r
++ if(tz==0 && (ty==0 || tx==0)) // (x- & z-) or (y- & z-) axis are vertical\r
++ { if(pp[1].x>pp[2].x) pz.y=1-pz.y; else pz.x=1-pz.x; }\r
++ else if(tx==0 && ty==0) // x- && y-axis is vertical\r
++ {\r
++ py.x=1-py.x;\r
++ if(pp[1].x>pp[3].x)\r
++ { px.z=1-px.z; py.z=1-py.z; }\r
++ }\r
++ else if(tz<tx && tz<ty) // z-axis is vertical\r
++ { if(pp[1].x>pp[2].x) pz.y=1-pz.y; else pz.x=1-pz.x; }\r
++ else if(ty<tx && ty<tz) // y-axis is vertical\r
++ { if(pp[1].x>pp[3].x) py.z=1-py.z; else py.x=1-py.x; }\r
++ else if(tx<ty && tx<tz) // x-axis is vertical\r
++ { if(pp[3].x>pp[2].x) px.y=1-px.y; else px.z=1-px.z; }\r
++ }\r
++ // return to normal variables\r
++ mglPoint rx = Min+(Max-Min)/px;\r
++ mglPoint ry = Min+(Max-Min)/py;\r
++ mglPoint rz = Min+(Max-Min)/pz;\r
++ mreal res = rx.val(ind);\r
++ if(dir=='y') res = ry.val(ind);\r
++ if(dir=='z') res = rz.val(ind);\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++mreal mglCanvas::GetOrgX(char dir, bool inv) const\r
++{\r
++ mreal res = Org.x;\r
++ if(mgl_isnan(res))\r
++ {\r
++ if(strchr("xyz",dir)) res = FindOptOrg(dir,0);\r
++ else if(dir=='t') res = Min.x;\r
++ else res = B.b[6]>0 ? Max.x:Min.x;\r
++ if(inv) res = Min.x+Max.x-res;\r
++ }\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++mreal mglCanvas::GetOrgY(char dir, bool inv) const\r
++{\r
++ mreal res = Org.y;\r
++ if(mgl_isnan(res))\r
++ {\r
++ if(strchr("xyz",dir)) res = FindOptOrg(dir,1);\r
++ else if(dir=='t') res = Min.y;\r
++ else res = B.b[7]>0 ? Max.y:Min.y;\r
++ if(inv) res = Min.y+Max.y-res;\r
++ }\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++mreal mglCanvas::GetOrgZ(char dir, bool inv) const\r
++{\r
++ mreal res = Org.z;\r
++ if(mgl_isnan(res))\r
++ {\r
++ if(strchr("xyz",dir)) res = FindOptOrg(dir,2);\r
++ else if(dir=='t') res = Min.z;\r
++ else res = B.b[8]>0 ? Max.z:Min.z;\r
++ if(inv) res = Min.z+Max.z-res;\r
++ }\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++// Put primitives\r
++//-----------------------------------------------------------------------------\r
++#define MGL_MARK_PLOT if(Quality&MGL_DRAW_LMEM) \\r
++ { mglDrawReg d; d.set(this,dr_x,dr_y,dr_p); d.PenWidth=pw; \\r
++ d.PDef = PDef; d.pPos = pPos; mark_draw(Pnt[p],type,size,&d); }\\r
++ else{ mglPrim a; a.w = pw; a.s = size; \\r
++ a.n1 = p; a.n4 = type; a.angl=0; add_prim(a); }\r
++void mglCanvas::mark_plot(long p, char type, mreal size)\r
++{\r
++ if(p<0 || mgl_isnan(Pnt[p].x) || mgl_isnan(size)) return;\r
++ if(type>128 || type<0)\r
++ { smbl_plot(p,type-128,20*MarkSize*(size?fabs(size):1)); return; }\r
++ long pp=p;\r
++ mreal pw = 0.15/sqrt(font_factor);\r
++ size = size?fabs(size):1;\r
++ size *= MarkSize*0.35*font_factor;\r
++ if(type=='.') size = fabs(PenWidth)*sqrt(font_factor/400);\r
++ if(TernAxis&12) for(int i=0;i<4;i++)\r
++ { p = ProjScale(i, pp); if(p>=0) {MGL_MARK_PLOT} }\r
++ else { MGL_MARK_PLOT }\r
++}\r
++//-----------------------------------------------------------------------------\r
++#define MGL_LINE_PLOT if(Quality&MGL_DRAW_LMEM) \\r
++ { mglDrawReg d; d.set(this,dr_x,dr_y,dr_p); d.PenWidth=pw; \\r
++ d.PDef = PDef; d.pPos = pPos; line_draw(Pnt[p1],Pnt[p2],&d); }\\r
++ else { mglPrim a(1); a.n3=PDef; a.s = pPos; \\r
++ a.n1 = p1; a.n2 = p2; a.w = pw; a.angl=0; add_prim(a); }\r
++void mglCanvas::line_plot(long p1, long p2)\r
++{\r
++ if(PDef==0) return;\r
++ if(p1<0 || p2<0 || mgl_isnan(Pnt[p1].x) || mgl_isnan(Pnt[p2].x) || SamePnt(p1,p2)) return;\r
++ if(p1>p2) { long kk=p1; p1=p2; p2=kk; } // rearrange start/end for proper dashing\r
++ long pp1=p1,pp2=p2;\r
++ mreal pw = fabs(PenWidth)*sqrt(font_factor/400), d=0;\r
++ if(TernAxis&12) for(int i=0;i<4;i++)\r
++ { p1 = ProjScale(i, pp1); p2 = ProjScale(i, pp2);\r
++ if(p1>=0&&p2>=0)\r
++ {\r
++ d += hypot(Pnt[p1].x-Pnt[p2].x, Pnt[p1].y-Pnt[p2].y);\r
++ MGL_LINE_PLOT\r
++ pPos = fmod(pPos+d/pw/1.5, 16);\r
++ }\r
++ }\r
++ else\r
++ {\r
++ d = hypot(Pnt[p1].x-Pnt[p2].x, Pnt[p1].y-Pnt[p2].y);\r
++ MGL_LINE_PLOT\r
++ pPos = fmod(pPos+d/pw/1.5, 16);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++#define MGL_TRIG_PLOT if(Quality&MGL_DRAW_LMEM) \\r
++ { mglDrawReg d; d.set(this,dr_x,dr_y,dr_p); d.PenWidth=pw; \\r
++ trig_draw(Pnt[p1],Pnt[p2],Pnt[p3],true,&d); }\\r
++ else{ mglPrim a(2); a.n1 = p1; a.n2 = p2; a.n3 = p3; \\r
++ a.m=mask; a.angl=MaskAn; a.w = pw; add_prim(a);}\r
++void mglCanvas::trig_plot(long p1, long p2, long p3)\r
++{\r
++ if(p1<0 || p2<0 || p3<0 || mgl_isnan(Pnt[p1].x) || mgl_isnan(Pnt[p2].x) || mgl_isnan(Pnt[p3].x)) return;\r
++ if(SamePnt(p1,p2) || SamePnt(p1,p3)) return;\r
++ long pp1=p1,pp2=p2,pp3=p3;\r
++ mreal pw = fabs(PenWidth)*sqrt(font_factor/400);\r
++ if(TernAxis&12) for(int i=0;i<4;i++)\r
++ { p1 = ProjScale(i, pp1); p2 = ProjScale(i, pp2);\r
++ p3 = ProjScale(i, pp3); if(p1>=0&&p2>=0&&p3>=0) {MGL_TRIG_PLOT} }\r
++ else { MGL_TRIG_PLOT }\r
++}\r
++//-----------------------------------------------------------------------------\r
++#define MGL_QUAD_PLOT if(Quality&MGL_DRAW_LMEM) \\r
++ { mglDrawReg d; d.set(this,dr_x,dr_y,dr_p); d.PenWidth=pw; \\r
++ quad_draw(Pnt[p1],Pnt[p2],Pnt[p3],Pnt[p4],&d); }\\r
++ else{ mglPrim a(3); a.n1 = p1; a.n2 = p2; a.n3 = p3; a.n4 = p4; \\r
++ a.m=mask; a.angl=MaskAn; a.w = pw; add_prim(a); }\r
++void mglCanvas::quad_plot(long p1, long p2, long p3, long p4)\r
++{\r
++ if(p1<0 || mgl_isnan(Pnt[p1].x) || SamePnt(p1,p2)) { trig_plot(p4,p2,p3); return; }\r
++ if(p2<0 || mgl_isnan(Pnt[p2].x) || SamePnt(p2,p4)) { trig_plot(p1,p4,p3); return; }\r
++ if(p3<0 || mgl_isnan(Pnt[p3].x) || SamePnt(p1,p3)) { trig_plot(p1,p2,p4); return; }\r
++ if(p4<0 || mgl_isnan(Pnt[p4].x) || SamePnt(p3,p4)) { trig_plot(p1,p2,p3); return; }\r
++ long pp1=p1,pp2=p2,pp3=p3,pp4=p4;\r
++ mreal pw = fabs(PenWidth)*sqrt(font_factor/400);\r
++ if(TernAxis&12) for(int i=0;i<4;i++)\r
++ { p1 = ProjScale(i, pp1); p2 = ProjScale(i, pp2);\r
++ p3 = ProjScale(i, pp3); p4 = ProjScale(i, pp4);\r
++ if(p1>=0&&p2>=0&&p3>=0&&p4>=0) {MGL_QUAD_PLOT} }\r
++ else { MGL_QUAD_PLOT }\r
++}\r
++//-----------------------------------------------------------------------------\r
++mreal mglCanvas::text_plot(long p,const wchar_t *text,const char *font,mreal size,mreal sh,mreal col,bool rot)\r
++{\r
++ if(p<0 || mgl_isnan(Pnt[p].x) || !text || *text==0) return 0;\r
++ if(size<0) size *= -FontSize;\r
++ if(!font) font="";\r
++\r
++ if(TernAxis&4) // text at projections\r
++ {\r
++ mreal res;\r
++ TernAxis = TernAxis&(~4);\r
++ for(int i=0;i<4;i++)\r
++ res = text_plot(ProjScale(i,p,true),text,font,size/2,sh,col,rot);\r
++ TernAxis = TernAxis|4;\r
++ return res;\r
++ }\r
++ else if(TernAxis&8) // text at projections\r
++ {\r
++ mreal res;\r
++ TernAxis = TernAxis&(~8);\r
++// for(int i=0;i<4;i++)\r
++ res = text_plot(ProjScale(3,p,true),text,font,size/2,sh,col,rot);\r
++ TernAxis = TernAxis|8;\r
++ return res;\r
++ }\r
++\r
++\r
++ mglPnt q=Pnt[p];\r
++ mreal ll = q.u*q.u+q.v*q.v;\r
++ bool inv=false;\r
++// if(rot && (q.u<0 || (q.u==0 && q.v<0))) // NOTE this is 1st part of rotation changes (see also GetGlyphPhi())\r
++// { q.u=-q.u; q.v=-q.v; q.w=-q.w; inv=true; }\r
++\r
++ mreal fsize=size/6.5*font_factor, h = fnt->Height(font)*fsize, w, shift = -(sh+0.02)*h;\r
++ // text drawing itself\r
++\r
++#if MGL_HAVE_PTHREAD\r
++pthread_mutex_lock(&mutexPtx);\r
++#endif\r
++#pragma omp critical(ptx)\r
++ {\r
++ Bt = B; Bt.norot=(q.sub<0); // NOTE check this later for mglInPlot\r
++ inv = inv ^ (strchr(font,'T')!=0);\r
++ if(strchr(font,'V')) shift = 0.1*h;\r
++ else\r
++ {\r
++ if(inv) shift = 0.2*h-shift;\r
++ shift += 0.015*h; // Correction for glyph rotation around proper point\r
++ }\r
++\r
++ int align;\r
++ mreal col1=col, col2=col;\r
++ if(mglGetStyle(font,0,&align))\r
++ {\r
++ col1 = AddTexture(font);\r
++ col2 = col1+1/MGL_FEPSILON;\r
++ }\r
++ else if(col<0)\r
++ col1 = col2 = AddTexture(char(0.5-col));\r
++ align = align&3;\r
++\r
++ Bt.x = q.x; Bt.y = q.y - shift; Bt.z = q.z;\r
++ if(ll>0)\r
++ {\r
++ Bt.x += shift*q.v/sqrt(ll); Bt.y += shift*(1-q.u/sqrt(ll));\r
++ if(q.u==0 && !get(MGL_ENABLE_RTEXT)) Bt.y -= 0.1*h;\r
++ }\r
++ fscl = fsize; forg = p;\r
++\r
++ if(mgl_isnan(ll) || !get(MGL_ENABLE_RTEXT)) ftet = 0;\r
++ else if(ll) ftet = -180*atan2(q.v,q.u)/M_PI;\r
++ else ftet = NAN;\r
++\r
++ if(!(Quality&MGL_DRAW_LMEM)) // add text itself\r
++ {\r
++ mglColor mc = Txt[long(col1)].GetC(col1);\r
++ mglPrim a(6); a.n1 = p;\r
++ a.n2 = int(255*mc.r) + 256*(int(255*mc.g) + 256*int(255*mc.b));\r
++ a.n3 = Ptx.size(); Ptx.push_back(mglText(text,font));\r
++ a.s = size; a.w = shift; a.p=ftet;\r
++ add_prim(a);\r
++ }\r
++\r
++ q.c=col1; q.t=0; Txt[long(col1)].GetC(col1,0,q);\r
++ q.u = q.v = NAN; q.a=q.t=q.ta=1;\r
++ memset(Bt.b,0,9*sizeof(mreal));\r
++ Bt.b[0] = Bt.b[4] = Bt.b[8] = fscl;\r
++ mreal opf = Bt.pf;\r
++ Bt.RotateN(ftet,0,0,1); Bt.pf = Bt.norot?1.55:opf;\r
++ if(strchr(font,'@')) // draw box around text\r
++ {\r
++ long k1,k2,k3,k4; mglPnt pt; mglPoint pp;\r
++ w = fnt->Width(text,font); h = fnt->Height(font);\r
++ mreal d=-w*align/2.-h*0.2; w+=h*0.4;\r
++ pt = q; pp.Set(d,-h*0.4); PostScale(&Bt,pp);\r
++ pt.x=pt.xx=pp.x; pt.y=pt.yy=pp.y;\r
++#pragma omp critical(pnt)\r
++ {k1=Pnt.size(); MGL_PUSH(Pnt,pt,mutexPnt);}\r
++ pt = q; pp.Set(w+d,-h*0.4); PostScale(&Bt,pp);\r
++ pt.x=pt.xx=pp.x; pt.y=pt.yy=pp.y;\r
++#pragma omp critical(pnt)\r
++ {k2=Pnt.size(); MGL_PUSH(Pnt,pt,mutexPnt);}\r
++ pt = q; pp.Set(d,h*1.2); PostScale(&Bt,pp);\r
++ pt.x=pt.xx=pp.x; pt.y=pt.yy=pp.y;\r
++#pragma omp critical(pnt)\r
++ {k3=Pnt.size(); MGL_PUSH(Pnt,pt,mutexPnt);}\r
++ pt = q; pp.Set(w+d,h*1.2); PostScale(&Bt,pp);\r
++ pt.x=pt.xx=pp.x; pt.y=pt.yy=pp.y;\r
++#pragma omp critical(pnt)\r
++ {k4=Pnt.size(); MGL_PUSH(Pnt,pt,mutexPnt);}\r
++ PDef = 0xffff; // reset to solid line\r
++ line_plot(k1,k2); line_plot(k1,k3);\r
++ line_plot(k4,k2); line_plot(k4,k3);\r
++ mreal bl = AddTexture('w');\r
++ k1 = CopyNtoC(k1,bl); k2 = CopyNtoC(k2,bl);\r
++ k3 = CopyNtoC(k3,bl); k4 = CopyNtoC(k4,bl);\r
++ quad_plot(k1,k2,k3,k4);\r
++ }\r
++ const char *ffont = font;\r
++ while(*ffont && *ffont!=':') ffont++;\r
++ fsize *= fnt->Puts(text,ffont,col1,col2)/2;\r
++ }\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_unlock(&mutexPtx);\r
++#endif\r
++ return fsize;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Glyph(mreal x, mreal y, mreal f, int s, long j, mreal col)\r
++{\r
++ mglPrim a(4); // NOTE: no projection since text_plot() did it\r
++ a.s = fscl/Bt.pf;\r
++ a.w = get(MGL_ENABLE_RTEXT)?ftet:1e5;\r
++ a.p = f/fnt->GetFact(s&3);\r
++ mreal cc = col<0 ? AddTexture(char(0.5-col)):col;\r
++ if(cc<0) cc = CDef;\r
++ a.n1 = AddPnt(&Bt, mglPoint(Bt.x,Bt.y,Bt.z), cc, mglPoint(x,y,NAN), -1, -1);\r
++ a.n2 = forg; a.n3 = s; a.n4 = AddGlyph(s,j);\r
++ if(a.n1<0) return;\r
++\r
++ if(Quality&MGL_DRAW_LMEM)\r
++ {\r
++ mglDrawReg d; d.set(this,dr_x,dr_y,dr_p);\r
++ d.PDef = s; d.pPos = a.s; d.PenWidth=a.w;\r
++ glyph_draw(a,&d);\r
++ }\r
++ else add_prim(a);\r
++}\r
++//-----------------------------------------------------------------------------\r
++#define MGL_GLYPH_PLOT if(Quality&MGL_DRAW_LMEM) glyph_draw(a,&d);\\r
++ else add_prim(a);\r
++void mglCanvas::smbl_plot(long p1, char id, double size)\r
++{\r
++ if(p1<0) return;\r
++ mglPnt q=Pnt[p1];\r
++ mreal ftet=NAN, ll = q.u*q.u+q.v*q.v;\r
++ if(mgl_isnan(ll) || !get(MGL_ENABLE_RTEXT)) ftet = 0;\r
++ else if(ll) ftet = -180*atan2(q.v,q.u)/M_PI;\r
++ long pk; q.u=q.v=0; q.w=NAN;\r
++#pragma omp critical(pnt)\r
++ {pk=Pnt.size(); MGL_PUSH(Pnt,q,mutexPnt);}\r
++\r
++ mglPrim a(4);\r
++ a.s = fabs(size)/6.5*font_factor/B.pf;\r
++ a.w = get(MGL_ENABLE_RTEXT)?ftet:1e5;\r
++ a.p = 1./(mgl_fact*mgl_fgen);\r
++ a.n1 = pk; a.n2 = p1; a.n3 = size<0?4:0; a.n4 = AddGlyph(id);\r
++ if(a.n4<0) return; // no symbol is defined by user\r
++ mglDrawReg d; d.set(this,dr_x,dr_y,dr_p);\r
++ d.PDef = size<0?4:0; d.pPos = a.s; d.PenWidth=a.w;\r
++ if(TernAxis&12) for(int i=0;i<4;i++)\r
++ { a.n1 = ProjScale(i, pk); MGL_GLYPH_PLOT }\r
++ else { MGL_GLYPH_PLOT }\r
++}\r
++//-----------------------------------------------------------------------------\r
++// Plot positioning functions\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::InPlot(mreal x1,mreal x2,mreal y1,mreal y2, const char *st)\r
++{\r
++ if(Width<=0 || Height<=0 || Depth<=0) return;\r
++ if(!st) { InPlot(x1,x2,y1,y2,false); return; }\r
++ inW = Width*(x2-x1); inH = Height*(y2-y1);\r
++ inX=Width*x1; inY=Height*y1; ZMin=1;\r
++\r
++ if(strchr(st,'T')) { y1*=0.9; y2*=0.9; } // general title\r
++ bool r = !(strchr(st,'r') || strchr(st,'R') || strchr(st,'>') || strchr(st,'g'));\r
++ bool l = !(strchr(st,'l') || strchr(st,'L') || strchr(st,'<') || strchr(st,'g'));\r
++ bool u = !(strchr(st,'u') || strchr(st,'U') || strchr(st,'_') || strchr(st,'g'));\r
++ bool a = !(strchr(st,'a') || strchr(st,'A') || strchr(st,'^') || strchr(st,'g') || strchr(st,'t'));\r
++ // let use simplified scheme -- i.e. no differences between axis, colorbar and/or title\r
++ mreal xs=(x1+x2)/2, ys=(y1+y2)/2, f1 = 1.3, f2 = 1.1;\r
++ if(strchr(st,'#')) f1=f2=1.55;\r
++ if(r && l) { x2=xs+(x2-xs)*f1; x1=xs+(x1-xs)*f1; }\r
++ else if(r) { x2=xs+(x2-xs)*f1; x1=xs+(x1-xs)*f2; }\r
++ else if(l) { x2=xs+(x2-xs)*f2; x1=xs+(x1-xs)*f1; }\r
++ if(a && u) { y2=ys+(y2-ys)*f1; y1=ys+(y1-ys)*f1; }\r
++ else if(a) { y2=ys+(y2-ys)*f1; y1=ys+(y1-ys)*f2; }\r
++ else if(u) { y2=ys+(y2-ys)*f2; y1=ys+(y1-ys)*f1; }\r
++\r
++ B.clear();\r
++ if(get(MGL_AUTO_FACTOR)) B.pf = 1.55; // Automatically change plot factor !!!\r
++ B.x = (x1+x2)/2*Width;\r
++ B.y = (y1+y2)/2*Height;\r
++ B.b[0] = Width*(x2-x1); B.b[4] = Height*(y2-y1);\r
++ B.b[8] = sqrt(B.b[0]*B.b[4]);\r
++ B.z = (1.f-B.b[8]/(2*Depth))*Depth;\r
++ B1=B; font_factor = B.b[0] < B.b[4] ? B.b[0] : B.b[4];\r
++\r
++ mglBlock p; p.AmbBr = AmbBr; p.DifBr = DifBr; p.B = B;\r
++ for(int i=0;i<10;i++) p.light[i] = light[i];\r
++ p.id = ObjId; p.n1=x1*Width; p.n2=x2*Width; p.n3=y1*Height; p.n4=y2*Height;\r
++#pragma omp critical(sub)\r
++ MGL_PUSH(Sub,p,mutexSub);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::InPlot(mglMatrix &M,mreal x1,mreal x2,mreal y1,mreal y2, bool rel)\r
++{\r
++ if(Width<=0 || Height<=0 || Depth<=0) return;\r
++ M.clear();\r
++ if(get(MGL_AUTO_FACTOR)) M.pf = 1.55; // Automatically change plot factor !!!\r
++ if(rel)\r
++ {\r
++ M.x = B1.x + (x1+x2-1)/2*B1.b[0]/1.55;\r
++ M.y = B1.y + (y1+y2-1)/2*B1.b[4]/1.55;\r
++ M.b[0] = B1.b[0]*(x2-x1); M.b[4] = B1.b[4]*(y2-y1);\r
++ M.b[8] = sqrt(M.b[0]*M.b[4]);\r
++ M.z = B1.z + (1.f-M.b[8]/(2*Depth))*B1.b[8];\r
++ }\r
++ else\r
++ {\r
++ M.x = (x1+x2)/2*Width;\r
++ M.y = (y1+y2)/2*Height;\r
++ M.b[0] = Width*(x2-x1); M.b[4] = Height*(y2-y1);\r
++ M.b[8] = sqrt(M.b[0]*M.b[4]);\r
++ M.z = (1.f-M.b[8]/(2*Depth))*Depth;\r
++ B1=M;\r
++ }\r
++ inW=M.b[0]; inH=M.b[4]; ZMin=1;\r
++ inX=Width*x1; inY=Height*y1;\r
++ font_factor = M.b[0] < M.b[4] ? M.b[0] : M.b[4];\r
++\r
++ mglBlock p; p.AmbBr = AmbBr; p.DifBr = DifBr; p.B = M;\r
++ for(int i=0;i<10;i++) p.light[i] = light[i];\r
++ p.id = ObjId; p.n1=x1*Width; p.n2=x2*Width; p.n3=y1*Height; p.n4=y2*Height;\r
++#pragma omp critical(sub)\r
++ MGL_PUSH(Sub,p,mutexSub);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::StickPlot(int num, int id, mreal tet, mreal phi)\r
++{\r
++ mreal dx,dy,wx,wy,x1,y1,f1,f2;\r
++ mglPoint p1(-1,0,0), p2(1,0,0);\r
++ // first iteration\r
++ InPlot(0,1,0,1,true); Rotate(tet, phi);\r
++ PostScale(GetB(),p1); PostScale(GetB(),p2); f1 = B.pf;\r
++ dx=(p2.x-p1.x)*1.55/B1.b[0]; dy=(p2.y-p1.y)*1.55/B1.b[4];\r
++ wx=1/(1+(num-1)*fabs(dx)); wy=1/(1+(num-1)*fabs(dy));\r
++ x1=dx>0?dx*id:dx*(id-num+1); y1=dy>0?dy*id:dy*(id-num+1);\r
++ InPlot(x1*wx,(x1+1)*wx,y1*wy,(y1+1)*wy,true); Rotate(tet,phi);\r
++ f2 = B.pf; dx*=f1/f2; dy*=f1/f2; // add correction due to PlotFactor\r
++ wx=1/(1+(num-1)*fabs(dx)); wy=1/(1+(num-1)*fabs(dy));\r
++ x1=dx>0?dx*id:dx*(id-num+1); y1=dy>0?dy*id:dy*(id-num+1);\r
++ InPlot(x1*wx,(x1+1)*wx,y1*wy,(y1+1)*wy,true); Rotate(tet,phi);\r
++ f1=f2; f2 = B.pf; dx*=f1/f2; dy*=f1/f2; // add correction due to PlotFactor\r
++ wx=1/(1+(num-1)*fabs(dx)); wy=1/(1+(num-1)*fabs(dy));\r
++ x1=dx>0?dx*id:dx*(id-num+1); y1=dy>0?dy*id:dy*(id-num+1);\r
++ InPlot(x1*wx,(x1+1)*wx,y1*wy,(y1+1)*wy,true); Rotate(tet,phi);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Rotate(mreal tetz,mreal tetx,mreal tety)\r
++{\r
++ B.Rotate(tetz,tetx,tety);\r
++ if(get(MGL_AUTO_FACTOR))\r
++ {\r
++ mreal w=(fabs(B.b[3])+fabs(B.b[4])+fabs(B.b[5]))/B1.b[4];\r
++ mreal h=(fabs(B.b[0])+fabs(B.b[1])+fabs(B.b[2]))/B1.b[0];\r
++ B.pf = 1.55+0.6147*(w<h ? (h-1):(w-1));\r
++ }\r
++ size_t n = Sub.size(); if(n>0) Sub[n-1].B = B;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglMatrix::Rotate(mreal tetz,mreal tetx,mreal tety)\r
++{\r
++// RotateN(TetX,1.,0.,0.);\r
++// RotateN(TetY,0.,1.,0.);\r
++// RotateN(TetZ,0.,0.,1.);\r
++ mreal R[9], O[9];\r
++ mreal cx=cos(tetx*M_PI/180), sx=-sin(tetx*M_PI/180), cy=cos(tety*M_PI/180), sy=-sin(tety*M_PI/180), cz=cos(tetz*M_PI/180), sz=-sin(tetz*M_PI/180);\r
++ R[0] = cx*cy; R[1] = -cy*sx; R[2] = sy;\r
++ R[3] = cx*sy*sz+cz*sx; R[4] = cx*cz-sx*sy*sz; R[5] =-cy*sz;\r
++ R[6] = sx*sz-cx*cz*sy; R[7] = cx*sz+cz*sx*sy; R[8] = cy*cz;\r
++ memcpy(O,b,9*sizeof(mreal));\r
++ b[0] = R[0]*O[0] + R[3]*O[1] + R[6]*O[2];\r
++ b[1] = R[1]*O[0] + R[4]*O[1] + R[7]*O[2];\r
++ b[2] = R[2]*O[0] + R[5]*O[1] + R[8]*O[2];\r
++ b[3] = R[0]*O[3] + R[3]*O[4] + R[6]*O[5];\r
++ b[4] = R[1]*O[3] + R[4]*O[4] + R[7]*O[5];\r
++ b[5] = R[2]*O[3] + R[5]*O[4] + R[8]*O[5];\r
++ b[6] = R[0]*O[6] + R[3]*O[7] + R[6]*O[8];\r
++ b[7] = R[1]*O[6] + R[4]*O[7] + R[7]*O[8];\r
++ b[8] = R[2]*O[6] + R[5]*O[7] + R[8]*O[8];\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::RotateN(mreal Tet,mreal x,mreal y,mreal z)\r
++{\r
++ B.RotateN(Tet,x,y,z);\r
++ if(get(MGL_AUTO_FACTOR))\r
++ {\r
++ mreal w=(fabs(B.b[3])+fabs(B.b[4])+fabs(B.b[5]))/B1.b[4];\r
++ mreal h=(fabs(B.b[0])+fabs(B.b[1])+fabs(B.b[2]))/B1.b[0];\r
++ B.pf = 1.55+0.6147*(w<h ? (h-1):(w-1));\r
++ }\r
++ size_t n = Sub.size(); if(n>0) Sub[n-1].B = B;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglMatrix::RotateN(mreal Tet,mreal vx,mreal vy,mreal vz)\r
++{\r
++ mreal R[9],T[9],c=cos(Tet*M_PI/180),s=-sin(Tet*M_PI/180),r=1-c,n=sqrt(vx*vx+vy*vy+vz*vz);\r
++ vx/=n; vy/=n; vz/=n;\r
++ T[0] = vx*vx*r+c; T[1] = vx*vy*r-vz*s; T[2] = vx*vz*r+vy*s;\r
++ T[3] = vx*vy*r+vz*s; T[4] = vy*vy*r+c; T[5] = vy*vz*r-vx*s;\r
++ T[6] = vx*vz*r-vy*s; T[7] = vy*vz*r+vx*s; T[8] = vz*vz*r+c;\r
++ memcpy(R,b,9*sizeof(mreal));\r
++ b[0] = T[0]*R[0] + T[3]*R[1] + T[6]*R[2];\r
++ b[1] = T[1]*R[0] + T[4]*R[1] + T[7]*R[2];\r
++ b[2] = T[2]*R[0] + T[5]*R[1] + T[8]*R[2];\r
++ b[3] = T[0]*R[3] + T[3]*R[4] + T[6]*R[5];\r
++ b[4] = T[1]*R[3] + T[4]*R[4] + T[7]*R[5];\r
++ b[5] = T[2]*R[3] + T[5]*R[4] + T[8]*R[5];\r
++ b[6] = T[0]*R[6] + T[3]*R[7] + T[6]*R[8];\r
++ b[7] = T[1]*R[6] + T[4]*R[7] + T[7]*R[8];\r
++ b[8] = T[2]*R[6] + T[5]*R[7] + T[8]*R[8];\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::View(mreal tetx,mreal tetz,mreal tety)\r
++{ Bp.Rotate(-tetz,-tetx,-tety); }\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Zoom(mreal x1, mreal y1, mreal x2, mreal y2)\r
++{\r
++ Bp.pf=0; Bp.clear(); ClfZB();\r
++ if(x1==x2 || y1==y2) { x1=y1=0; x2=y2=1; }\r
++ x1=2*x1-1; x2=2*x2-1; y1=2*y1-1; y2=2*y2-1;\r
++ Bp.b[0]=2/fabs(x2-x1); Bp.b[4]=2/fabs(y2-y1);\r
++ Bp.x=(x1+x2)/fabs(x2-x1);Bp.y=(y1+y2)/fabs(y2-y1);\r
++}\r
++//-----------------------------------------------------------------------------\r
++int mglCanvas::GetSplId(long x,long y) const\r
++{\r
++ long id=-1;\r
++ for(long i=Sub.size()-1;i>=0;i--)\r
++ {\r
++ const mglBlock &p = Sub[i];\r
++ if(p.n1<=x && p.n2>=x && p.n3<=y && p.n4>=y)\r
++ { id=p.id; break; }\r
++ }\r
++ return id;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Aspect(mreal Ax,mreal Ay,mreal Az)\r
++{\r
++ if(mgl_isnan(Ax))\r
++ {\r
++ mreal dy = (Max.y-Min.y), dx = (Max.x-Min.x), dz = (Max.z-Min.z);\r
++ if(mgl_islog(Min.x,Max.x) && fx) dx = log10(Max.x/Min.x);\r
++ if(mgl_islog(Min.y,Max.y) && fy) dy = log10(Max.y/Min.y);\r
++ if(mgl_islog(Min.z,Max.z) && fz) dz = log10(Max.z/Min.z);\r
++<<<<<<< HEAD\r
++ mreal fy=exp(M_LN10*floor(0.5+log10(fabs(dy/dx))));\r
++ mreal fz=exp(M_LN10*floor(0.5+log10(fabs(dz/dx))));\r
++ if(Ay>0) fy*=Ay;\r
++ if(Az>0) fz*=Az;\r
++ Ax = inH*dx; Ay = inW*dy*fy; Az = sqrt(inW*inH)*dz*fz;\r
++=======\r
++ mreal gy=exp(M_LN10*floor(0.5+log10(fabs(dy/dx))));\r
++ mreal gz=exp(M_LN10*floor(0.5+log10(fabs(dz/dx))));\r
++ if(Ay>0) gy*=Ay;\r
++ if(Az>0) gz*=Az;\r
++ Ax = inH*dx; Ay = inW*dy*gy; Az = sqrt(inW*inH)*dz*gz;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ }\r
++ mreal a = fabs(Ax) > fabs(Ay) ? fabs(Ax) : fabs(Ay);\r
++ a = a > fabs(Az) ? a : fabs(Az);\r
++ if(a==0) { SetWarn(mglWarnZero,"Aspect"); return; }\r
++ Ax/=a; Ay/=a; Az/=a;\r
++ B.b[0] *= Ax; B.b[3] *= Ax; B.b[6] *= Ax;\r
++ B.b[1] *= Ay; B.b[4] *= Ay; B.b[7] *= Ay;\r
++ B.b[2] *= Az; B.b[5] *= Az; B.b[8] *= Az;\r
++ size_t n = Sub.size(); if(n>0) Sub[n-1].B = B;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Shear(mreal Sx,mreal Sy)\r
++{\r
++ mreal R[6], Fx=1+fabs(Sx)*inH/inW, Fy=1+fabs(Sy)*inW/inH;\r
++ memcpy(R,B.b,6*sizeof(mreal));\r
++ B.b[0] = (R[0]+Sx*R[3])/Fx; B.b[1] = (R[1]+Sx*R[4])/Fx; B.b[2] = (R[2]+Sx*R[5])/Fx;\r
++ B.b[3] = (R[3]+Sy*R[0])/Fy; B.b[4] = (R[4]+Sy*R[1])/Fy; B.b[5] = (R[5]+Sy*R[2])/Fy;\r
++ size_t n = Sub.size(); if(n>0) Sub[n-1].B = B;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::ShearPlot(int num, int id, mreal sx, mreal sy, mreal xd, mreal yd)\r
++{\r
++ InPlot(0,1,0,1,true);\r
++ if(!(fabs(xd)<=1 && fabs(yd)<=1)) { xd=1; yd=0; }\r
++ mreal wx,wy,dx,dy,wf,hf,x1,y1;\r
++ int ix=sy>=0?id:num-id-1, iy=sx>=0?id:num-id-1;\r
++ for(int i=0;i<3;i++) // iterations to solve cubic equation\r
++ {\r
++ wx = fabs(sx)*inH/inW; dx = xd + yd*wx; wf = 1+wx+(num-1)*fabs(dx);\r
++ wy = fabs(sy)*inW/inH; dy = yd + xd*wy; hf = 1+wy+(num-1)*fabs(dy);\r
++ x1=(dx>=0?ix:(ix-num+1))*dx;\r
++ y1=(dy>=0?iy:(iy-num+1))*dy;\r
++ InPlot(x1/wf,(x1+1+wx)/wf,y1/hf,(y1+1+wy)/hf,true);\r
++ }\r
++ Shear(sx,sy);\r
++}\r
++//-----------------------------------------------------------------------------\r
++// Lighting and transparency\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Fog(mreal d, mreal dz) { FogDist=d; FogDz = dz; }\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Light(int n, bool enable)\r
++{\r
++ if(n<0 || n>9) { SetWarn(mglWarnLId,"Light"); return; }\r
++ light[n].n = enable;\r
++ size_t m=Sub.size(); if(m>0) Sub[m-1].light[n].n = enable;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::AddLight(int n, mglPoint r, mglPoint d, char col, mreal br, mreal ap)\r
++{\r
++ if(n<0 || n>9) { SetWarn(mglWarnLId,"AddLight"); return; }\r
++ light[n].n = true; light[n].a = ap>0?ap*ap:3;\r
++ light[n].b = br; light[n].r = r;\r
++ light[n].d = d; light[n].c.Set(col);\r
++ size_t m=Sub.size(); if(m>0) Sub[m-1].light[n] = light[n];\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::arrow_plot(long n1, long n2, char st)\r
++{\r
++ if(n1<0 || n2<0 || !strchr("AVKSDTIOX",st)) return;\r
++ float ll = PenWidth*ArrowSize*0.35*font_factor;\r
++ uint64_t m=mask; int ma=MaskAn;\r
++ ResetMask();\r
++ if((Quality&3)==3)\r
++ arrow_plot_3d(n1, n2, st, ll);\r
++ else\r
++ arrow_draw(n1, n2, st, ll);\r
++ mask=m; MaskAn=ma;\r
++}\r
++//-----------------------------------------------------------------------------\r
++std::wstring MGL_EXPORT mgl_ftoa(double v, const char *fmt)\r
++{\r
++ char se[70], sf[70], ff[8]="%.3f", ee[8]="%.3e";\r
++ int dig=3;\r
++ for(const char *s="0123456789";*s;s++) if(mglchr(fmt,*s)) dig = *s-'0';\r
++ if(mglchr(fmt,'E')) ee[3] = 'E';\r
++ bool plus = mglchr(fmt,'+');\r
++ bool tex = mglchr(fmt,'F');\r
++ int fdig = int(log10(v)); fdig = fdig>0?(fdig<dig?dig-fdig:0):dig;\r
++ ff[2] = fdig+'0'; ee[2] = dig+'0';\r
++ snprintf(se,64,ee,v); snprintf(sf,64,ff,v);\r
++ se[63] = sf[63] = 0;\r
++ long le=strlen(se), lf=strlen(sf), i;\r
++\r
++ // clear fix format\r
++ for(i=lf-1;i>=lf-fdig && sf[i]=='0';i--) sf[i]=0;\r
++ if(sf[i]=='.') sf[i]=0;\r
++ lf = strlen(sf);\r
++ // parse -nan numbers\r
++ if(!strcmp(sf,"-nan")) memcpy(sf,"nan",4);\r
++\r
++\r
++ // clear exp format\r
++ int st = se[0]=='-'?1:0;\r
++ if(strcmp(sf,"nan"))\r
++ {\r
++ if(plus || se[3+st+dig]=='-') // first remove zeros after 'e'\r
++ {\r
++ for(i=(dig>0?4:3)+st+dig;i<le && se[i]=='0';i++);\r
++ memmove(se+(dig>0?4:3)+st+dig,se+i,le-i+1);\r
++ }\r
++ else\r
++ {\r
++ for(i=(dig>0?3:2)+st+dig;i<le && (se[i]=='0' || se[i]=='+');i++);\r
++ memmove(se+(dig>0?3:2)+st+dig,se+i,le-i+1);\r
++ }\r
++ }\r
++ le=strlen(se);\r
++ // don't allow '+' at the end\r
++ if(le>0 && se[le-1]=='+') se[--le]=0;\r
++ // remove single 'e'\r
++ if(le>0 && (se[le-1]=='e' || se[le-1]=='E')) se[--le]=0;\r
++ for(i=1+st+dig;i>st && se[i]=='0';i--); // remove final '0'\r
++ if(se[i]=='.') i--;\r
++ memmove(se+i+1,se+2+st+dig,le-dig); le=strlen(se);\r
++ // add '+' sign if required\r
++ if(plus && !strchr("-0niNI",se[0]))\r
++ { memmove(se+1,se,le+1); se[0]='+';\r
++ memmove(sf+1,sf,lf+1); sf[0]='+'; }\r
++ if((lf>le && !mglchr(fmt,'f')) || !strcmp(sf,"0") || !strcmp(sf,"-0")) strcpy(sf,se);\r
++ lf = strlen(sf);\r
++ std::wstring res; res.reserve(lf+8);\r
++\r
++ if(mglchr(fmt,'-') && !(plus||tex)) // replace '-' by "\minus"\r
++ for(i=0;i<lf;i++) res += sf[i];\r
++ else\r
++ for(i=0;i<lf;i++) res += sf[i]!='-'?wchar_t(sf[i]):0x2212;\r
++ if(tex) // TeX notation: 'e' -> "\cdot 10^{...}"\r
++ {\r
++ if(res[0]=='1' && (res[1]=='e' || res[1]=='E'))\r
++ { res.replace(0,2,L"10^{"); res += L'}'; }\r
++ else if(wcschr(L"+-\u2212",res[0]) && res[1]=='1' && (res[2]=='e' || res[2]=='E'))\r
++ { res.replace(1,2,L"10^{"); res += L'}'; }\r
++ else\r
++ {\r
++ size_t p;\r
++ for(p=1;p<res.length();p++) if(res[p]==L'e' || res[p]==L'E') break;\r
++ if(p<res.length())\r
++ { res.replace(p,1,L"⋅10^{"); res += L'}'; }\r
++ }\r
++ }\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Legend(const std::vector<mglText> &leg, mreal x, mreal y, const char *font, const char *opt)\r
++{\r
++ long n=leg.size();\r
++ mreal iw, ih;\r
++ if(n<1) { SetWarn(mglWarnLeg,"Legend"); return; }\r
++ mreal ll = SaveState(opt); if(mgl_isnan(ll)) ll=0.1;\r
++ if(saved) MarkSize=MSS; // restore back size of marks\r
++ static int cgid=1; StartGroup("Legend",cgid++);\r
++ if(ll<=0 || mgl_isnan(ll)) ll=0.1;\r
++ ll *=font_factor;\r
++ mreal size = 0.8*FontSize;\r
++ // setup font and parse absolute coordinates\r
++ if(!font) font="#";\r
++ char *pA, *ff = new char[strlen(font)+3];\r
++ const char *fmt = strchr(font,':');\r
++ strcpy(ff,fmt?fmt:""); strcat(ff,":L"); Push();\r
++ if((pA=strchr(ff,'A')))\r
++ { *pA = ' '; InPlot(0,1,0,1,false); iw=B1.b[0]; ih=B1.b[4]; }\r
++ else if(mglchr(font,'A'))\r
++ { InPlot(0,1,0,1,false); iw=B1.b[0]; ih=B1.b[4]; }\r
++ else { iw=B1.b[0]/B1.pf; ih=B1.b[4]/B1.pf; }\r
++ // find sizes\r
++ mreal h=TextHeight(font,size);\r
++ mreal dx = 0.03*iw, dy = 0.03*ih, w=0, t, sp=TextWidth(" ",font,size);\r
++ for(long i=0;i<n;i++) // find text length\r
++ {\r
++ t = TextWidth(leg[i].text.c_str(),font,size)+sp;\r
++ if(leg[i].stl.empty()) t -= ll;\r
++ w = w>t ? w:t;\r
++ }\r
++ w += ll+0.01*iw; // add space for lines\r
++ long j = long((ih*0.95)/h); if(j<1) j=1;\r
++ long ncol = 1+(n-1)/j, nrow = (n+ncol-1)/ncol;\r
++ if(strchr(font,'-')) // horizontal legend\r
++ {\r
++ j = long((iw*0.95)/w); if(j<1) j=1;\r
++ nrow = 1+(n-1)/j;\r
++ ncol = (n+nrow-1)/nrow;\r
++ }\r
++ if(mglchr(font,'^')) // use "external" positioning\r
++ {\r
++ x = x>=0.5 ? x*iw : x*iw-w*ncol-2*dx;\r
++ y = y>=0.5 ? y*ih : y*ih-h*nrow-2*dy;\r
++ }\r
++ else\r
++ {\r
++ x *= iw-w*ncol-2*dx;\r
++ y *= ih-h*nrow-2*dy;\r
++ }\r
++ x += B.x-iw/2+dx; y += B.y-ih/2+dy;\r
++ // draw it\r
++ mglPoint p,q(NAN,NAN,NAN);\r
++\r
++ mreal cc = AddTexture(font);\r
++ mreal c1,c2; //=AddTexture(char(k1?k1:'w')), c2=AddTexture(char(k2?k2:'k'));\r
++ if(cc<2 || Txt[long(cc+0.5)].n==0)\r
++ { c1 = AddTexture('w'); cc = c2 = AddTexture('k'); }\r
++ else switch(Txt[long(cc+0.5)].n)\r
++ {\r
++ case 1: c1 = AddTexture('w'); c2 = AddTexture('k'); break;\r
++ case 2: c1 = cc; cc+=1/MGL_FEPSILON; c2 = AddTexture('k'); break;\r
++ default: c1 = cc; c2 = cc+0.5; cc += 1/MGL_FEPSILON; break;\r
++ }\r
++ if((Flag&3)==2) { mreal tt=c1; c2=c1; c1=tt; }\r
++\r
++ mglMatrix M=B; M.norot=true;\r
++ if(strchr(font,'#')) // draw bounding box\r
++ {\r
++ SetPenPal("k-");\r
++ long k1=AddPnt(&M,mglPoint(x,y,Depth/1.01),c1,q,1,0);\r
++ long k2=AddPnt(&M,mglPoint(x+w*ncol,y,Depth/1.01),c1,q,1,0);\r
++ long k3=AddPnt(&M,mglPoint(x,y+h*nrow,Depth/1.01),c1,q,1,0);\r
++ long k4=AddPnt(&M,mglPoint(x+w*ncol,y+h*nrow,Depth/1.01),c1,q,1,0);\r
++ quad_plot(k1,k2,k3,k4);\r
++ k1=CopyNtoC(k1,c2); k2=CopyNtoC(k2,c2);\r
++ k3=CopyNtoC(k3,c2); k4=CopyNtoC(k4,c2);\r
++ line_plot(k1,k2); line_plot(k2,k4);\r
++ line_plot(k4,k3); line_plot(k3,k1);\r
++ }\r
++ for(long i=0;i<n;i++) // draw lines and legend\r
++ {\r
++ long iy=nrow-(i%nrow)-1,ix=i/nrow;\r
++ char m=SetPenPal(leg[i].stl.c_str());\r
++ long k1=AddPnt(&M,mglPoint(x+ix*w+0.1*ll,y+iy*h+0.45*h,Depth),CDef,q,-1,0);\r
++ long k2=AddPnt(&M,mglPoint(x+ix*w+0.9*ll,y+iy*h+0.45*h,Depth),CDef,q,-1,0); pPos=0;\r
++ if(!leg[i].stl.empty()) line_plot(k1,k2);\r
++ if(m) for(j=0;j<LegendMarks;j++)\r
++ {\r
++ p.Set(x+ix*w+0.1f*ll + (j+1)*0.8f*ll/(1.+LegendMarks),y+iy*h+0.45*h,Depth);\r
++ mark_plot(AddPnt(&M,p,CDef,q,-1,0),m);\r
++ }\r
++ p.Set(x+ix*w+((!leg[i].stl.empty())?ll:0.01*iw), y+iy*h+0.15*h, Depth);\r
++ text_plot(AddPnt(&M,p,-1,q,-1,0), leg[i].text.c_str(), ff, size,0,cc);\r
++ }\r
++ Pop(); EndGroup(); delete []ff;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Table(mreal x, mreal y, HCDT val, const wchar_t *text, const char *frm, const char *opt)\r
++{\r
++// if(x>=1) { SetWarn(mglWarnSpc,"Table"); return; }\r
++ long i,j,m=val->GetNy(),n=val->GetNx();\r
++// mreal pos=SaveState(opt);\r
++ mreal vw = SaveState(opt);\r
++ static int cgid=1; StartGroup("Table",cgid++);\r
++ bool grid = mglchr(frm,'#'), eqd = mglchr(frm,'='), lim = mglchr(frm,'|');\r
++ if(mgl_isnan(vw)) vw=1; else lim = true;\r
++ if(!text) text=L"";\r
++ x=x<0?0:x; y=y<0?0:y; y=y>1?1:y;\r
++// if(vw>1-x) vw=1-x;\r
++\r
++ char fmt[8]="3",ss[2]=" ";\r
++ for(const char *s="0123456789";*s;s++) if(mglchr(frm,*s)) fmt[0]=*s;\r
++ for(const char *s="f+E-F";*s;s++) if(mglchr(frm,*s))\r
++ { ss[0] = *s; strcat(fmt,ss); }\r
++ std::vector<std::wstring> str;\r
++ for(i=0;i<n;i++) // prepare list of strings first\r
++ {\r
++ std::wstring buf;\r
++ for(j=0;j+1<m;j++)\r
++ buf += mgl_ftoa(val->v(i,j),fmt)+L'\n';\r
++ buf += mgl_ftoa(val->v(i,m-1),fmt);\r
++ str.push_back(buf);\r
++ }\r
++\r
++ mreal sp=2*TextWidth(" ",frm,-1), w=*text ? sp+TextWidth(text,frm,-1):0, w1=0, ww, h;\r
++ for(i=0;i<n;i++) // find width for given font size\r
++ {\r
++ ww = TextWidth(str[i].c_str(),frm,-1)+sp;\r
++ w1 = w1<ww?ww:w1;\r
++ if(!eqd) w += ww;\r
++ }\r
++ if(eqd) w += n*w1;\r
++ // reduce font size if table have to be inside inplot\r
++ mreal fsize=FontSize;\r
++ if(lim && w>vw*inW)\r
++ { h=vw*inW/w; SetFontSize(-h); w*=h; w1*=h; sp*=h; }\r
++ h = TextHeight(frm,-1); // now we can determine text height\r
++\r
++ x = x*(inW-w)+B.x-inW/2;\r
++ y = y*(inH-h*m)+B.y-inH/2;\r
++\r
++ mglPoint p,q(NAN,NAN);\r
++ mreal xx,yy;\r
++ if(grid) // draw bounding box\r
++ {\r
++ SetPenPal("k-");\r
++ long k1,k2;\r
++ k1=AddPnt(&B,mglPoint(x,y,Depth),-1,q,-1,0);\r
++ k2=AddPnt(&B,mglPoint(x,y+m*h,Depth),-1,q,-1,0);\r
++ line_plot(k1,k2);\r
++ ww = *text ? TextWidth(text,frm,-1)+sp:0;\r
++ k1=AddPnt(&B,mglPoint(x+ww,y,Depth),-1,q,-1,0);\r
++ k2=AddPnt(&B,mglPoint(x+ww,y+m*h,Depth),-1,q,-1,0);\r
++ line_plot(k1,k2);\r
++ for(i=0,xx=x+ww,yy=y;i<n;i++)\r
++ {\r
++ xx += eqd ? w1:(TextWidth(str[i].c_str(),frm,-1)+sp);\r
++ k1=AddPnt(&B,mglPoint(xx,yy,Depth),-1,q,-1,0);\r
++ k2=AddPnt(&B,mglPoint(xx,yy+m*h,Depth),-1,q,-1,0);\r
++ line_plot(k1,k2);\r
++ }\r
++ for(i=0,xx=x,yy=y;i<=m;i++)\r
++ {\r
++ k1=AddPnt(&B,mglPoint(xx,yy,Depth),-1,q,-1,0);\r
++ k2=AddPnt(&B,mglPoint(xx+w,yy,Depth),-1,q,-1,0);\r
++ line_plot(k1,k2); yy += h;\r
++ }\r
++ }\r
++ int align; mglGetStyle(frm, 0, &align);\r
++ if(*text)\r
++ {\r
++ ww = TextWidth(text,frm,-1)+sp;\r
++ long k1=AddPnt(&B,mglPoint(x+ww*align/2.,y+h*(m-0.9),Depth),-1,q,-1,0);\r
++ text_plot(k1,text,frm);\r
++ }\r
++ else ww = 0;\r
++ for(i=0,xx=x+ww,yy=y+h*(m-0.9);i<n;i++) // draw lines and legend\r
++ {\r
++ ww = eqd ? w1:(TextWidth(str[i].c_str(),frm,-1)+sp);\r
++ long k1=AddPnt(&B,mglPoint(xx+ww*align/2.,yy,Depth),-1,q,-1,0);\r
++ text_plot(k1,str[i].c_str(),frm); xx += ww;\r
++ }\r
++ FontSize = fsize; EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Title(const char *title,const char *stl,mreal size)\r
++{\r
++ if(!title) title="";\r
++ MGL_TO_WCS(title,Title(wcs, stl,size));\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Title(const wchar_t *title,const char *stl,mreal size)\r
++{\r
++ mreal s = size>0 ? size/FontSize:-size, h=TextHeight(stl,size)*s/2;\r
++ if(h>=inH) { SetWarn(mglWarnSpc,"Title"); return; }\r
++ static int cgid=1; StartGroup("Title",cgid++);\r
++ int align;\r
++ bool box=mglchr(stl,'#'), col = mglGetStyle(stl,0,&align);\r
++ align = align&3;\r
++ mreal y=inY+inH-h;\r
++ mglPoint p(inX + inW*align/2.,y,3*Depth),q(NAN,NAN,NAN);\r
++ mglMatrix M=B; M.norot=true;\r
++ if(title) text_plot(AddPnt(&M,p,-1,q,-1,0),title,stl,size);\r
++ if(box) // draw boungind box\r
++ {\r
++ mreal c1=AddTexture('w'), c2=col?AddTexture(stl):AddTexture('k');\r
++ if((Flag&3)==2 && !col) { mreal cc=c1; c2=c1; c1=cc; }\r
++ else if((Flag&3)==2) c1=AddTexture('k');\r
++ long k1,k2,k3,k4;\r
++ k1=AddPnt(&M,mglPoint(inX,y-h*0.4,3*Depth),c1,q,-1,0);\r
++ k2=AddPnt(&M,mglPoint(inX+inW,y-h*0.4,3*Depth),c1,q,-1,0);\r
++ k3=AddPnt(&M,mglPoint(inX,y+h,3*Depth),c1,q,-1,0);\r
++ k4=AddPnt(&M,mglPoint(inX+inW,y+h,3*Depth),c1,q,-1,0);\r
++ quad_plot(k1,k2,k3,k4);\r
++ k1=CopyNtoC(k1,c2); k2=CopyNtoC(k2,c2);\r
++ k3=CopyNtoC(k3,c2); k4=CopyNtoC(k4,c2);\r
++ line_plot(k1,k2); line_plot(k2,k4);\r
++ line_plot(k4,k3); line_plot(k3,k1);\r
++ }\r
++ B1.y -= h/2; B1.b[4] -= h; B=B1;\r
++ inH-=h; font_factor = B.b[0] < B.b[4] ? B.b[0] : B.b[4];\r
++ EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::StartAutoGroup (const char *lbl)\r
++{\r
++ static int id=1;\r
++ if(lbl==NULL) { id=1; grp_counter=0; return; }\r
++ grp_counter++;\r
++ if(grp_counter>1) return; // do nothing in "subgroups"\r
++ if(ObjId<0) { ObjId = -id; id++; }\r
++ size_t len = Grp.size();\r
++ if(ObjId>=0 && (len==0 || (len>0 && ObjId!=Grp[len-1].Id)))\r
++#pragma omp critical(grp)\r
++ { MGL_PUSH(Grp,mglGroup(lbl,ObjId),mutexGrp);}\r
++ else if(ObjId<0)\r
++#pragma omp critical(grp)\r
++ { MGL_PUSH(Grp,mglGroup(lbl,ObjId),mutexGrp);}\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::EndGroup()\r
++{\r
++ LoadState();\r
++ if(Quality&MGL_DRAW_LMEM)\r
++ {\r
++ Pnt.clear(); Prm.clear(); Ptx.clear(); ClearPrmInd();\r
++ Glf.clear(); Act.clear(); Grp.clear();\r
++ }\r
++ if(grp_counter>0) grp_counter--;\r
++}\r
++//-----------------------------------------------------------------------------\r
++int mglCanvas::IsActive(int xs, int ys,int &n)\r
++{\r
++ long i, h = (Width>Height ? Height:Width)/100;\r
++ for(i=0;i<(long)Act.size();i++)\r
++ {\r
++ const mglActivePos &p=Act[i];\r
++ if(abs(xs-p.x)<=h && abs(ys-p.y)<=h)\r
++ { n=p.n; return p.id; }\r
++ }\r
++ n=-1; return GetObjId(xs,ys);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Push()\r
++{\r
++#pragma omp critical(stk)\r
++ {MGL_PUSH(stack,B,mutexStk);}\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Pop()\r
++{\r
++ B = stack.back(); \r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_lock(&m);\r
++ stack.pop_back();\r
++ pthread_mutex_unlock(&m);\r
++#else\r
++#pragma omp critical(stk)\r
++ stack.pop_back();\r
++#endif\r
++}\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * complex.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include "mgl2/datac.h"\r
++#include "mgl2/evalc.h"\r
++#include "mgl2/thread.h"\r
++\r
++#include "interp.hpp"\r
++#define mgl2 mreal(2)\r
++#define mgl3 mreal(3)\r
++#define mgl4 mreal(4)\r
++\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mglStartThreadC(void *(*func)(void *), void (*post)(mglThreadC *,dual *), long n,\r
++ dual *a, const dual *b, const dual *c, const long *p,\r
++ const void *v, const dual *d, const dual *e, const char *s)\r
++{\r
++ if(!func) return;\r
++#if MGL_HAVE_PTHREAD\r
++ if(mglNumThr<1) mgl_set_num_thr(0);\r
++ if(mglNumThr>1)\r
++ {\r
++ pthread_t *tmp=new pthread_t[mglNumThr];\r
++ mglThreadC *par=new mglThreadC[mglNumThr];\r
++ for(long i=0;i<mglNumThr;i++) // put parameters into the structure\r
++ { par[i].n=n; par[i].a=a; par[i].b=b; par[i].c=c; par[i].d=d;\r
++ par[i].p=p; par[i].v=v; par[i].s=s; par[i].e=e; par[i].id=i; }\r
++ for(long i=0;i<mglNumThr;i++) pthread_create(tmp+i, 0, func, par+i);\r
++ for(long i=0;i<mglNumThr;i++) pthread_join(tmp[i], 0);\r
++ if(post) post(par,a);\r
++ delete []tmp; delete []par;\r
++ }\r
++ else\r
++#endif\r
++ {\r
++ mglNumThr = 1;\r
++ mglThreadC par;\r
++ par.n=n; par.a=a; par.b=b; par.c=c; par.d=d;\r
++ par.p=p; par.v=v; par.s=s; par.e=e; par.id=0;\r
++ func(&par);\r
++ if(post) post(&par,a);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mglStartThreadV(void *(*func)(void *), long n, dual *a, const void *b,\r
++ const void *c, const long *p, const void *v, const mreal *d)\r
++{\r
++ if(!func) return;\r
++#if MGL_HAVE_PTHREAD\r
++ if(mglNumThr<1) mgl_set_num_thr(0);\r
++ if(mglNumThr>1)\r
++ {\r
++ pthread_t *tmp=new pthread_t[mglNumThr];\r
++ mglThreadV *par=new mglThreadV[mglNumThr];\r
++ for(long i=0;i<mglNumThr;i++) // put parameters into the structure\r
++ { par[i].n=n; par[i].a=0; par[i].b=b; par[i].c=c; par[i].d=d;\r
++ par[i].p=p; par[i].v=v; par[i].id=i;par[i].aa=a; }\r
++ for(long i=0;i<mglNumThr;i++) pthread_create(tmp+i, 0, func, par+i);\r
++ for(long i=0;i<mglNumThr;i++) pthread_join(tmp[i], 0);\r
++ delete []tmp; delete []par;\r
++ }\r
++ else\r
++#endif\r
++ {\r
++ mglNumThr = 1;\r
++ mglThreadV par;\r
++ par.n=n; par.a=0; par.b=b; par.c=c; par.d=d;\r
++ par.p=p; par.v=v; par.id=0; par.aa=a;\r
++ func(&par);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++mdual MGL_EXPORT_CONST mgl_expi(dual a)\r
++{\r
++ dual r = exp(dual(0,1)*dual(a));\r
++ return r.real()+r.imag()*mgl_I;\r
++}\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_csmth_x(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0], kind=t->p[2];\r
++ dual *b=t->a;\r
++ const dual *a=t->b;\r
++ if(kind>0)\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<t->n;i+=mglNumThr)\r
++ {\r
++ long j = i%nx;\r
++ if(j-kind<0) j = i+kind-j;\r
++ else if(j+kind>nx-1) j = i+nx-1-j-kind;\r
++ else j=i;\r
++ for(long k=-kind;k<=kind;k++) b[i] += a[j+k]/mreal(2*kind+1);\r
++ }\r
++ else\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<t->n;i+=mglNumThr)\r
++ {\r
++ long j = i%nx;\r
++ if(j>1 && j<nx-2) b[i] = (mreal(12)*a[i-2] - mreal(3)*a[i-1] + mreal(17)*a[i] - mreal(3)*a[i+1] + mreal(12)*a[i+2])/mreal(35);\r
++ else if(j==1 || j==nx-2) b[i] = (a[i-1] + a[i] + a[i+1])/mreal(3);\r
++ else b[i] = a[i];\r
++ }\r
++ return 0;\r
++}\r
++MGL_NO_EXPORT void *mgl_csmth_y(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0],ny=t->p[1], kind=t->p[2];\r
++ dual *b=t->a;\r
++ const dual *a=t->b;\r
++ if(kind>0)\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<t->n;i+=mglNumThr)\r
++ {\r
++ long j = (i/nx)%ny;\r
++ if(j-kind<0) j = i+(kind-j)*nx;\r
++ else if(j+kind>ny-1) j = i+(ny-1-j-kind)*nx;\r
++ else j=i;\r
++ for(long k=-kind;k<=kind;k++) b[i] += a[j+k*nx]/mreal(2*kind+1);\r
++ }\r
++ else\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<t->n;i+=mglNumThr)\r
++ {\r
++ long j = (i/nx)%ny;\r
++ if(j>1 && j<ny-2) b[i] = (mreal(12)*a[i-2*nx] - mreal(3)*a[i-nx] + mreal(17)*a[i] - mreal(3)*a[i+nx] + mreal(12)*a[i+2*nx])/mreal(35);\r
++ else if(j==1 || j==ny-2) b[i] = (a[i-nx] + a[i] + a[i+nx])/mreal(3);\r
++ else b[i] = a[i];\r
++ }\r
++ return 0;\r
++}\r
++MGL_NO_EXPORT void *mgl_csmth_z(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nn=t->p[0]*t->p[1], nz=t->n/nn, kind=t->p[2];\r
++ dual *b=t->a;\r
++ const dual *a=t->b;\r
++ if(kind>0)\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<t->n;i+=mglNumThr)\r
++ {\r
++ long j = i/nn;\r
++ if(j-kind<0) j = i+(kind-j)*nn;\r
++ else if(j+kind>nz-1) j = i+(nz-1-j-kind)*nn;\r
++ else j=i;\r
++ for(long k=-kind;k<=kind;k++) b[i] += a[j+k*nn]/mreal(2*kind+1);\r
++ }\r
++ else\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<t->n;i+=mglNumThr)\r
++ {\r
++ long j = i/nn;\r
++ if(j>1 && j<nz-2) b[i] = (mreal(12)*a[i-2*nn] - mreal(3)*a[i-nn] + mreal(17)*a[i] - mreal(3)*a[i+nn] + mreal(12)*a[i+2*nn])/mreal(35);\r
++ else if(j==1 || j==nz-2) b[i] = (a[i-nn] + a[i] + a[i+nn])/mreal(3);\r
++ else b[i] = a[i];\r
++ }\r
++ return 0;\r
++}\r
++void MGL_EXPORT mgl_datac_smooth(HADT d, const char *dirs, mreal )\r
++{\r
++ long Type = -1;\r
++ if(!dirs || *dirs==0) dirs = "xyz";\r
++ if(strchr(dirs,'0')) return;\r
++ if(strchr(dirs,'d'))\r
++ {\r
++ if(strchr(dirs,'1')) Type = 1;\r
++ if(strchr(dirs,'2')) Type = 2;\r
++ if(strchr(dirs,'3')) Type = 3;\r
++ if(strchr(dirs,'4')) Type = 4;\r
++ if(strchr(dirs,'5')) Type = 5;\r
++ if(strchr(dirs,'6')) Type = 6;\r
++ if(strchr(dirs,'7')) Type = 7;\r
++ if(strchr(dirs,'8')) Type = 8;\r
++ if(strchr(dirs,'9')) Type = 9;\r
++ }\r
++ else\r
++ {\r
++ if(strchr(dirs,'1')) return;\r
++ if(strchr(dirs,'3')) Type = 1;\r
++ if(strchr(dirs,'5')) Type = 2;\r
++ }\r
++ long nx=d->nx,ny=d->ny,nz=d->nz;\r
++// if(Type == SMOOTH_NONE) return;\r
++ long p[3]={nx,ny,Type};\r
++ dual *b = new dual[nx*ny*nz];\r
++ // ����������� �� x\r
++ memset(b,0,nx*ny*nz*sizeof(dual));\r
++ if(nx>4 && strchr(dirs,'x'))\r
++ {\r
++ mglStartThreadC(mgl_csmth_x,0,nx*ny*nz,b,d->a,0,p);\r
++ memcpy(d->a,b,nx*ny*nz*sizeof(dual));\r
++ memset(b,0,nx*ny*nz*sizeof(dual));\r
++ }\r
++ if(ny>4 && strchr(dirs,'y'))\r
++ {\r
++ mglStartThreadC(mgl_csmth_y,0,nx*ny*nz,b,d->a,0,p);\r
++ memcpy(d->a,b,nx*ny*nz*sizeof(dual));\r
++ memset(b,0,nx*ny*nz*sizeof(dual));\r
++ }\r
++ if(nz>4 && strchr(dirs,'z'))\r
++ {\r
++ mglStartThreadC(mgl_csmth_z,0,nx*ny*nz,b,d->a,0,p);\r
++ memcpy(d->a,b,nx*ny*nz*sizeof(dual));\r
++ }\r
++ delete []b;\r
++}\r
++void MGL_EXPORT mgl_datac_smooth_(uintptr_t *d, const char *dir, mreal *delta,int l)\r
++{ char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0;\r
++ mgl_datac_smooth(_DC_,s,*delta); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_ccsum_z(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nz=t->p[2], nn=t->n;\r
++ dual *b=t->a;\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ {\r
++ b[i] = a[i];\r
++ for(long j=1;j<nz;j++) b[i+j*nn] = b[i+j*nn-nn] + a[i+j*nn];\r
++ }\r
++ return 0;\r
++}\r
++MGL_NO_EXPORT void *mgl_ccsum_y(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0], ny=t->p[1], nn=t->n;\r
++ dual *b=t->a;\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ {\r
++ long k = (i%nx)+nx*ny*(i/nx); b[k] = a[k];\r
++ for(long j=1;j<ny;j++) b[k+j*nx] = b[k+j*nx-nx] + a[k+nx*j];\r
++ }\r
++ return 0;\r
++}\r
++MGL_NO_EXPORT void *mgl_ccsum_x(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0], nn=t->n;\r
++ dual *b=t->a;\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ {\r
++ long k = i*nx; b[k] = a[k];\r
++ for(long j=1;j<nx;j++) b[j+k] = b[j+k-1] + a[j+k];\r
++ }\r
++ return 0;\r
++}\r
++void MGL_EXPORT mgl_datac_cumsum(HADT d, const char *dir)\r
++{\r
++ if(!dir || *dir==0) return;\r
++ long nx=d->nx,ny=d->ny,nz=d->nz,nn=nx*ny*nz;\r
++ long p[3]={nx,ny,nz};\r
++ dual *b = new dual[nn];\r
++ memcpy(b,d->a,nn*sizeof(dual));\r
++ if(strchr(dir,'z') && nz>1)\r
++ {\r
++ mglStartThreadC(mgl_ccsum_z,0,nx*ny,b,d->a,0,p);\r
++ memcpy(d->a,b,nn*sizeof(dual));\r
++ }\r
++ if(strchr(dir,'y') && ny>1)\r
++ {\r
++ mglStartThreadC(mgl_ccsum_y,0,nx*nz,b,d->a,0,p);\r
++ memcpy(d->a,b,nn*sizeof(dual));\r
++ }\r
++ if(strchr(dir,'x') && nx>1)\r
++ {\r
++ mglStartThreadC(mgl_ccsum_x,0,nz*ny,b,d->a,0,p);\r
++ memcpy(d->a,b,nn*sizeof(dual));\r
++ }\r
++ delete []b;\r
++}\r
++void MGL_EXPORT mgl_datac_cumsum_(uintptr_t *d, const char *dir,int l)\r
++{ char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0;\r
++ mgl_datac_cumsum(_DC_,s); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_cint_z(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nz=t->p[2], nn=t->n;\r
++ dual *b=t->a, dd=0.5/nz;\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ {\r
++ b[i] = 0;\r
++ for(long j=1;j<nz;j++) b[i+j*nn] = b[i+j*nn-nn] + (a[i+nn*j]+a[i+j*nn-nn])*dd;\r
++ }\r
++ return 0;\r
++}\r
++MGL_NO_EXPORT void *mgl_cint_y(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0], ny=t->p[1], nn=t->n;\r
++ dual *b=t->a, dd=0.5/ny;\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ {\r
++ long k = (i%nx)+nx*ny*(i/nx); b[k] = 0;\r
++ for(long j=1;j<ny;j++) b[k+j*nx] = b[k+j*nx-nx] + (a[k+j*nx]+a[k+j*nx-nx])*dd;\r
++ }\r
++ return 0;\r
++}\r
++MGL_NO_EXPORT void *mgl_cint_x(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0], nn=t->n;\r
++ dual *b=t->a, dd=0.5/nx;\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ {\r
++ long k = i*nx; b[k] = 0;\r
++ for(long j=1;j<nx;j++) b[j+k] = b[j+k-1] + (a[j+k]+a[j+k-1])*dd;\r
++ }\r
++ return 0;\r
++}\r
++void MGL_EXPORT mgl_datac_integral(HADT d, const char *dir)\r
++{\r
++ if(!dir || *dir==0) return;\r
++ long nx=d->nx,ny=d->ny,nz=d->nz,nn=nx*ny*nz;\r
++ long p[3]={nx,ny,nz};\r
++ dual *b = new dual[nn];\r
++ memcpy(b,d->a,nn*sizeof(dual));\r
++ if(strchr(dir,'z') && nz>1)\r
++ {\r
++ mglStartThreadC(mgl_cint_z,0,nx*ny,b,d->a,0,p);\r
++ memcpy(d->a,b,nn*sizeof(dual));\r
++ }\r
++ if(strchr(dir,'y') && ny>1)\r
++ {\r
++ mglStartThreadC(mgl_cint_y,0,nx*nz,b,d->a,0,p);\r
++ memcpy(d->a,b,nn*sizeof(dual));\r
++ }\r
++ if(strchr(dir,'x') && nx>1)\r
++ {\r
++ mglStartThreadC(mgl_cint_x,0,nz*ny,b,d->a,0,p);\r
++ memcpy(d->a,b,nn*sizeof(dual));\r
++ }\r
++ delete []b;\r
++}\r
++void MGL_EXPORT mgl_datac_integral_(uintptr_t *d, const char *dir,int l)\r
++{ char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0;\r
++ mgl_datac_integral(_DC_,s); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_cdif_z(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nz=t->p[2], nn=t->n;\r
++ dual *b=t->a, dd=0.5*nz;\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ {\r
++ b[i] = -(mgl3*a[i]-mgl4*a[i+nn]+a[i+2*nn])*dd;\r
++ b[i+(nz-1)*nn] = (mgl3*a[i+(nz-1)*nn]-mgl4*a[i+(nz-2)*nn]+a[i+(nz-3)*nn])*dd;\r
++ for(long j=1;j<nz-1;j++) b[i+j*nn] = (a[i+j*nn+nn]-a[i+j*nn-nn])*dd;\r
++ }\r
++ return 0;\r
++}\r
++MGL_NO_EXPORT void *mgl_cdif_y(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0], ny=t->p[1], nn=t->n;\r
++ dual *b=t->a, dd=0.5*ny;\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ {\r
++ long k = (i%nx)+nx*ny*(i/nx);\r
++ b[k] = -(mgl3*a[k]-mgl4*a[k+nx]+a[k+2*nx])*dd;\r
++ b[k+(ny-1)*nx] = (mgl3*a[k+(ny-1)*nx]-mgl4*a[k+(ny-2)*nx]+a[k+(ny-3)*nx])*dd;\r
++ for(long j=1;j<ny-1;j++) b[k+j*nx] = (a[k+j*nx+nx]-a[k+j*nx-nx])*dd;\r
++ }\r
++ return 0;\r
++}\r
++MGL_NO_EXPORT void *mgl_cdif_x(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0], nn=t->n;\r
++ dual *b=t->a, dd=0.5*nx;\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ {\r
++ long k = i*nx;\r
++ b[k] = -(mgl3*a[k]-mgl4*a[k+1]+a[k+2])*dd;\r
++ b[k+nx-1] = (mgl3*a[k+nx-1]-mgl4*a[k+nx-2]+a[k+nx-3])*dd;\r
++ for(long j=1;j<nx-1;j++) b[j+k] = (a[j+k+1]-a[j+k-1])*dd;\r
++ }\r
++ return 0;\r
++}\r
++void MGL_EXPORT mgl_datac_diff(HADT d, const char *dir)\r
++{\r
++ if(!dir || *dir==0) return;\r
++ long nx=d->nx,ny=d->ny,nz=d->nz,nn=nx*ny*nz;\r
++ long p[3]={nx,ny,nz};\r
++ dual *b = new dual[nn];\r
++ if(strchr(dir,'z') && nz>1)\r
++ {\r
++ mglStartThreadC(mgl_cdif_z,0,nx*ny,b,d->a,0,p);\r
++ memcpy(d->a,b,nn*sizeof(dual));\r
++ }\r
++ if(strchr(dir,'y') && ny>1)\r
++ {\r
++ mglStartThreadC(mgl_cdif_y,0,nx*nz,b,d->a,0,p);\r
++ memcpy(d->a,b,nn*sizeof(dual));\r
++ }\r
++ if(strchr(dir,'x') && nx>1)\r
++ {\r
++ mglStartThreadC(mgl_cdif_x,0,nz*ny,b,d->a,0,p);\r
++ memcpy(d->a,b,nn*sizeof(dual));\r
++ }\r
++ delete []b;\r
++}\r
++void MGL_EXPORT mgl_datac_diff_(uintptr_t *d, const char *dir,int l)\r
++{ char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0;\r
++ mgl_datac_diff(_DC_,s); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_cdif2_z(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nz=t->p[2], nn=t->n;\r
++ dual *b=t->a, dd=0.5*nz*nz;\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ {\r
++ b[i] = b[i+(nz-1)*nn] = 0;\r
++ for(long j=1;j<nz-1;j++) b[i+j*nn] = (a[i+j*nn+nn]+a[i+j*nn-nn]-mgl2*a[i+j*nn])*dd;\r
++ }\r
++ return 0;\r
++}\r
++MGL_NO_EXPORT void *mgl_cdif2_y(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0], ny=t->p[1], nn=t->n;\r
++ dual *b=t->a, dd=0.5*ny*ny;\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ {\r
++ long k = (i%nx)+nx*ny*(i/nx); b[k] = b[k+(ny-1)*nx] = 0;\r
++ for(long j=1;j<ny-1;j++) b[k+j*nx] = (a[k+j*nx+nx]+a[k+j*nx-nx]-mgl2*a[k+j*nx])*dd;\r
++ }\r
++ return 0;\r
++}\r
++MGL_NO_EXPORT void *mgl_cdif2_x(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0], nn=t->n;\r
++ dual *b=t->a, dd=0.5*nx*nx;\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ {\r
++ long k = i*nx; b[k] = b[k+nx-1] = 0;\r
++ for(long j=1;j<nx-1;j++) b[j+k] = (a[j+k+1]+a[j+k-1]-mgl2*a[j+k])*dd;\r
++ }\r
++ return 0;\r
++}\r
++void MGL_EXPORT mgl_datac_diff2(HADT d, const char *dir)\r
++{\r
++ if(!dir || *dir==0) return;\r
++ long nx=d->nx,ny=d->ny,nz=d->nz,nn=nx*ny*nz;\r
++ long p[3]={nx,ny,nz};\r
++ dual *b = new dual[nn];\r
++ if(strchr(dir,'z') && nz>1)\r
++ {\r
++ mglStartThreadC(mgl_cdif2_z,0,nx*ny,b,d->a,0,p);\r
++ memcpy(d->a,b,nn*sizeof(dual));\r
++ }\r
++ if(strchr(dir,'y') && ny>1)\r
++ {\r
++ mglStartThreadC(mgl_cdif2_y,0,nx*nz,b,d->a,0,p);\r
++ memcpy(d->a,b,nn*sizeof(dual));\r
++ }\r
++ if(strchr(dir,'x') && nx>1)\r
++ {\r
++ mglStartThreadC(mgl_cdif2_x,0,nz*ny,b,d->a,0,p);\r
++ memcpy(d->a,b,nn*sizeof(dual));\r
++ }\r
++ delete []b;\r
++}\r
++void MGL_EXPORT mgl_datac_diff2_(uintptr_t *d, const char *dir,int l)\r
++{ char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0;\r
++ mgl_datac_diff2(_DC_,s); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_swap(HADT d, const char *dir)\r
++{\r
++ if(!dir || *dir==0) return;\r
++ if(strchr(dir,'z') && d->nz>1) mgl_datac_roll(d,'z',d->nz/2);\r
++ if(strchr(dir,'y') && d->ny>1) mgl_datac_roll(d,'y',d->ny/2);\r
++ if(strchr(dir,'x') && d->nx>1) mgl_datac_roll(d,'x',d->nx/2);\r
++}\r
++void MGL_EXPORT mgl_datac_swap_(uintptr_t *d, const char *dir,int l)\r
++{ char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0;\r
++ mgl_datac_swap(_DC_,s); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_roll(HADT dd, char dir, long num)\r
++{\r
++ long nx=dd->nx,ny=dd->ny,nz=dd->nz, d;\r
++ dual *b,*a=dd->a;\r
++ if(dir=='z' && nz>1)\r
++ {\r
++ d = num>0 ? num%nz : (num+nz*(1-num/nz))%nz;\r
++ if(d==0) return; // nothing to do\r
++ b = new dual[nx*ny*nz];\r
++ memcpy(b,a+nx*ny*d,nx*ny*(nz-d)*sizeof(dual));\r
++ memcpy(b+nx*ny*(nz-d),a,nx*ny*d*sizeof(dual));\r
++ memcpy(a,b,nx*ny*nz*sizeof(dual)); delete []b;\r
++ }\r
++ if(dir=='y' && ny>1)\r
++ {\r
++ d = num>0 ? num%ny : (num+ny*(1-num/ny))%ny;\r
++ if(d==0) return; // nothing to do\r
++ b = new dual[nx*ny*nz];\r
++ memcpy(b,a+nx*d,(nx*ny*nz-nx*d)*sizeof(dual));\r
++#pragma omp parallel for\r
++ for(long i=0;i<nz;i++)\r
++ memcpy(b+nx*(ny-d)+nx*ny*i,a+nx*ny*i,nx*d*sizeof(dual));\r
++ memcpy(a,b,nx*ny*nz*sizeof(dual)); delete []b;\r
++ }\r
++ if(dir=='x' && nx>1)\r
++ {\r
++ d = num>0 ? num%nx : (num+nx*(1-num/nx))%nx;\r
++ if(d==0) return; // nothing to do\r
++ b = new dual[nx*ny*nz];\r
++ memcpy(b,a+d,(nx*ny*nz-d)*sizeof(dual));\r
++#pragma omp parallel for\r
++ for(long i=0;i<nz*ny;i++)\r
++ memcpy(b+nx-d+nx*i,a+nx*i,d*sizeof(dual));\r
++ memcpy(a,b,nx*ny*nz*sizeof(dual)); delete []b;\r
++ }\r
++}\r
++void MGL_EXPORT mgl_datac_roll_(uintptr_t *d, const char *dir, int *num, int)\r
++{ mgl_datac_roll(_DC_,*dir,*num); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_mirror(HADT d, const char *dir)\r
++{\r
++ if(!dir || *dir==0) return;\r
++ long nx=d->nx,ny=d->ny,nz=d->nz;\r
++ dual *a=d->a;\r
++ if(strchr(dir,'z') && nz>1)\r
++ {\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<nz/2;j++) for(long i=0;i<nx*ny;i++)\r
++ {\r
++ long i0 = i+j*nx*ny, j0 = i+(nz-1-j)*nx*ny;\r
++ dual b = a[i0]; a[i0] = a[j0]; a[j0] = b;\r
++ }\r
++ }\r
++ if(strchr(dir,'y') && ny>1)\r
++ {\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny/2;j++) for(long i=0;i<nx*nz;i++)\r
++ {\r
++ long j0 = (i%nx)+nx*(ny*(i/nx)+j), i0 = j0+(ny-1-2*j)*nx;\r
++ dual b = a[j0]; a[j0] = a[i0]; a[i0] = b;\r
++ }\r
++ }\r
++ if(strchr(dir,'x') && nx>1)\r
++ {\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny*nz;j++) for(long i=0;i<nx/2;i++)\r
++ {\r
++ long i0 = nx-1-i+j*nx, j0 = i+j*nx;\r
++ dual b = a[j0]; a[j0] = a[i0]; a[i0] = b;\r
++ }\r
++ }\r
++}\r
++void MGL_EXPORT mgl_datac_mirror_(uintptr_t *d, const char *dir,int l)\r
++{ char *s=new char[l+1]; memcpy(s,dir,l); s[l]=0;\r
++ mgl_datac_mirror(_DC_,s); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++dual MGL_EXPORT mglSpline3Cs(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z)\r
++{ return mglSpline3st<dual>(a,nx,ny,nz,x,y,z); }\r
++//-----------------------------------------------------------------------------\r
++dual MGL_EXPORT mglSpline3C(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z,dual *dx, dual *dy, dual *dz)\r
++{ return mglSpline3t<dual>(a,nx,ny,nz,x,y,z,dx,dy,dz); }\r
++//-----------------------------------------------------------------------------\r
++dual MGL_EXPORT mglLinearC(const dual *a, long nx, long ny, long nz, mreal x, mreal y, mreal z)\r
++{ return mglLineart<dual>(a,nx,ny,nz,x,y,z); }\r
++//-----------------------------------------------------------------------------\r
++mdual MGL_EXPORT mgl_datac_spline(HCDT d, mreal x,mreal y,mreal z)\r
++{\r
++ const mglDataC *dd=dynamic_cast<const mglDataC *>(d);\r
++ dual r = dd ? mglSpline3st<dual>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z) : d->value(x,y,z);\r
++ return r.real()+r.imag()*mgl_I;\r
++}\r
++//-----------------------------------------------------------------------------\r
++mdual MGL_EXPORT mgl_datac_spline_ext(HCDT d, mreal x,mreal y,mreal z, dual *dx,dual *dy,dual *dz)\r
++{\r
++ const mglDataC *dd=dynamic_cast<const mglDataC *>(d);\r
++ if(!dd)\r
++ {\r
++ mreal rx=0,ry=0,rz=0,res;\r
++ res=d->valueD(x,y,z,&rx,&ry,&rz);\r
++ if(dx) *dx=rx;\r
++ if(dy) *dy=ry;\r
++ if(dz) *dz=rz;\r
++ return res;\r
++ }\r
++ dual r = mglSpline3t<dual>(dd->a,dd->nx,dd->ny,dd->nz,x,y,z,dx,dy,dz);\r
++ return r.real()+r.imag()*mgl_I;\r
++}\r
++//-----------------------------------------------------------------------------\r
++mdual MGL_EXPORT mgl_datac_spline_(uintptr_t *d, mreal *x,mreal *y,mreal *z)\r
++{ return mgl_datac_spline(_DA_(d),*x,*y,*z); }\r
++mdual MGL_EXPORT mgl_datac_spline_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, dual *dx,dual *dy,dual *dz)\r
++{ return mgl_datac_spline_ext(_DA_(d),*x,*y,*z,dx,dy,dz); }\r
++//-----------------------------------------------------------------------------\r
++mdual MGL_EXPORT mgl_datac_linear_ext(HCDT d, mreal x,mreal y,mreal z, dual *dx,dual *dy,dual *dz)\r
++{\r
++ long kx=long(x), ky=long(y), kz=long(z);\r
++ dual b0,b1;\r
++ const mglDataC *dd=dynamic_cast<const mglDataC *>(d);\r
++ if(!dd)\r
++ {\r
++ mreal rx=0,ry=0,rz=0,res;\r
++ res=mgl_data_linear_ext(d,x,y,z,&rx,&ry,&rz);\r
++ if(dx) *dx=rx;\r
++ if(dy) *dy=ry;\r
++ if(dz) *dz=rz;\r
++ return res;\r
++ }\r
++\r
++ long nx=dd->nx, ny=dd->ny, nz=dd->nz, dn=ny>1?nx:0;\r
++ kx = kx>=0 ? kx:0; kx = kx<nx-1 ? kx:nx-2;\r
++ ky = ky>=0 ? ky:0; ky = ky<ny-1 ? ky:ny-2;\r
++ kz = kz>=0 ? kz:0; kz = kz<nz-1 ? kz:nz-2;\r
++ x -= kx; y -= ky; z -= kz;\r
++ const dual *aa = dd->a, *bb;\r
++ if(kz>=0)\r
++ {\r
++ aa=dd->a+kx+nx*(ky+ny*kz); bb = aa+nx*ny;\r
++ b0 = aa[0]*(1-x-y+x*y) + x*(1-y)*aa[1] + y*(1-x)*aa[dn] + x*y*aa[1+dn];\r
++ b1 = bb[0]*(1-x-y+x*y) + x*(1-y)*bb[1] + y*(1-x)*bb[dn] + x*y*bb[1+dn];\r
++ }\r
++ else\r
++ {\r
++ z=0;\r
++ if(ky>=0)\r
++ {\r
++ aa=dd->a+kx+nx*ky;\r
++ b0 = b1 = aa[0]*(1-x-y+x*y) + x*(1-y)*aa[1] + y*(1-x)*aa[dn] + x*y*aa[1+dn];\r
++ }\r
++ else if(kx>=0)\r
++ {\r
++ aa=dd->a+kx; b0 = b1 = aa[0]*(1-x) + x*aa[1];\r
++ }\r
++ else b0 = b1 = dd->a[0];\r
++ }\r
++ if(dx) *dx = kx>=0?aa[1]-aa[0]:0;\r
++ if(dy) *dy = ky>=0?aa[dn]-aa[0]:0;\r
++ if(dz) *dz = b1-b0;\r
++ dual r = b0 + z*(b1-b0);\r
++ return r.real()+r.imag()*mgl_I;\r
++}\r
++mdual MGL_EXPORT mgl_datac_linear(HCDT d, mreal x,mreal y,mreal z)\r
++{ return mgl_datac_linear_ext(d, x,y,z, 0,0,0); }\r
++//-----------------------------------------------------------------------------\r
++mdual MGL_EXPORT mgl_datac_linear_(uintptr_t *d, mreal *x,mreal *y,mreal *z)\r
++{ return mgl_datac_linear(_DA_(d),*x,*y,*z); }\r
++mdual MGL_EXPORT mgl_datac_linear_ext_(uintptr_t *d, mreal *x,mreal *y,mreal *z, dual *dx,dual *dy,dual *dz)\r
++{ return mgl_datac_linear_ext(_DA_(d),*x,*y,*z,dx,dy,dz); }\r
++//-----------------------------------------------------------------------------\r
++long MGL_NO_EXPORT mgl_powers(long N, const char *how);\r
++void MGL_EXPORT mgl_datac_crop_opt(HADT d, const char *how)\r
++{\r
++ const char *h = "235";\r
++ if(mglchr(how,'2') || mglchr(how,'3') || mglchr(how,'5')) h = how;\r
++ if(mglchr(how,'x')) mgl_datac_crop(d, 0, mgl_powers(d->nx, h), 'x');\r
++ if(mglchr(how,'y')) mgl_datac_crop(d, 0, mgl_powers(d->ny, h), 'y');\r
++ if(mglchr(how,'z')) mgl_datac_crop(d, 0, mgl_powers(d->nz, h), 'z');\r
++}\r
++void MGL_EXPORT mgl_datac_crop_opt_(uintptr_t *d, const char *how, int l)\r
++{ char *s=new char[l+1]; memcpy(s,how,l); s[l]=0;\r
++ mgl_datac_crop_opt(_DC_,s); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_crop(HADT d, long n1, long n2, char dir)\r
++{\r
++ long nx=d->nx,ny=d->ny,nz=d->nz, nn;\r
++ dual *b;\r
++ if(n1<0) n1=0;\r
++ switch(dir)\r
++ {\r
++ case 'x':\r
++ if(n1>=nx) break;\r
++ n2 = n2>0 ? n2 : nx+n2;\r
++ if(n2<0 || n2>=nx || n2<n1) n2 = nx;\r
++ nn = n2-n1; b = new dual[nn*ny*nz];\r
++#pragma omp parallel for\r
++ for(long i=0;i<ny*nz;i++)\r
++ memcpy(b+nn*i,d->a+nx*i+n1,nn*sizeof(dual));\r
++ d->nx = nn; if(!d->link) delete []d->a;\r
++ d->a = b; d->link=false; d->NewId();\r
++ break;\r
++ case 'y':\r
++ if(n1>=ny) break;\r
++ n2 = n2>0 ? n2 : ny+n2;\r
++ if(n2<0 || n2>=ny || n2<n1) n2 = ny;\r
++ nn = n2-n1; b = new dual[nn*nx*nz];\r
++#pragma omp parallel for\r
++ for(long j=0;j<nz;j++) for(long i=0;i<nn;i++)\r
++ memcpy(b+nx*(i+nn*j),d->a+nx*(n1+i+ny*j),nx*sizeof(dual));\r
++ d->ny = nn; if(!d->link) delete []d->a;\r
++ d->a = b; d->link=false;\r
++ break;\r
++ case 'z':\r
++ if(n1>=nz) break;\r
++ n2 = n2>0 ? n2 : nz+n2;\r
++ if(n2<0 || n2>=nz || n2<n1) n2 = nz;\r
++ nn = n2-n1; b = new dual[nn*nx*ny];\r
++ memcpy(b,d->a+nx*ny*n1,nn*nx*ny*sizeof(dual));\r
++ d->nz = nn; if(!d->link) delete []d->a;\r
++ d->a = b; d->link=false;\r
++ break;\r
++ }\r
++}\r
++void MGL_EXPORT mgl_datac_crop_(uintptr_t *d, int *n1, int *n2, const char *dir,int)\r
++{ mgl_datac_crop(_DC_,*n1,*n2,*dir); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_insert(HADT d, char dir, long at, long num)\r
++{\r
++ if(num<1) return;\r
++ at = at<0 ? 0:at;\r
++ long nx=d->nx, ny=d->ny, nz=d->nz, nn;\r
++ mglDataC b;\r
++ if(dir=='x')\r
++ {\r
++ if(at>nx) at=nx;\r
++ nn=nx+num; b.Create(nn,ny,nz);\r
++#pragma omp parallel for\r
++ for(long k=0;k<ny*nz;k++)\r
++ {\r
++ if(at>0) memcpy(b.a+nn*k, d->a+nx*k,at*sizeof(dual));\r
++ if(at<nx) memcpy(b.a+at+num+nn*k, d->a+at+nx*k,(nx-at)*sizeof(dual));\r
++ for(long i=0;i<num;i++) b.a[nn*k+at+i]=d->a[nx*k+at]; // copy values\r
++ }\r
++ d->Set(b); nx+=num;\r
++ }\r
++ if(dir=='y')\r
++ {\r
++ if(at>ny) at=ny;\r
++ nn=num+ny; b.Create(nx,nn,nz);\r
++#pragma omp parallel for\r
++ for(long k=0;k<nz;k++)\r
++ {\r
++ if(at>0) memcpy(b.a+nx*nn*k, d->a+nx*ny*k,at*nx*sizeof(dual));\r
++ if(at<ny) memcpy(b.a+nx*(at+num+nn*k), d->a+nx*(at+ny*k),(ny-at)*nx*sizeof(dual));\r
++ for(long i=0;i<num;i++) memcpy(b.a+nx*(nn*k+at+i),d->a+nx*(ny*k+at),nx*sizeof(dual));\r
++ }\r
++ d->Set(b); ny+=num;\r
++ }\r
++ if(dir=='z')\r
++ {\r
++ if(at>nz) at=nz;\r
++ b.Create(nx,ny,nz+num);\r
++ if(at>0) memcpy(b.a, d->a,at*nx*ny*sizeof(dual));\r
++ if(at<nz) memcpy(b.a+nx*ny*(at+num), d->a+nx*ny*at,(nz-at)*nx*ny*sizeof(dual));\r
++#pragma omp parallel for\r
++ for(long i=0;i<num;i++) memcpy(b.a+nx*ny*(at+i),d->a+nx*ny*at,nx*ny*sizeof(dual));\r
++ d->Set(b);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_delete(HADT d, char dir, long at, long num)\r
++{\r
++ if(num<1 || at<0) return;\r
++ mglDataC b;\r
++ long nx=d->nx, ny=d->ny, nz=d->nz, nn;\r
++ if(dir=='x')\r
++ {\r
++ if(at+num>=nx) return;\r
++ nn=nx-num; b.Create(nn,ny,nz);\r
++#pragma omp parallel for\r
++ for(long k=0;k<ny*nz;k++)\r
++ {\r
++ if(at>0) memcpy(b.a+nn*k, d->a+nx*k,at*sizeof(dual));\r
++ memcpy(b.a+at+nn*k, d->a+at+num+nx*k,(nx-at-num)*sizeof(dual));\r
++ }\r
++ d->Set(b); nx-=num;\r
++ }\r
++ if(dir=='y')\r
++ {\r
++ if(at+num>=ny) return;\r
++ nn=ny-num; b.Create(nx,nn,nz);\r
++#pragma omp parallel for\r
++ for(long k=0;k<nz;k++)\r
++ {\r
++ if(at>0) memcpy(b.a+nx*nn*k, d->a+nx*ny*k,at*nx*sizeof(dual));\r
++ memcpy(b.a+nx*(at+nn*k), d->a+nx*(at+num+ny*k),(ny-at-num)*nx*sizeof(dual));\r
++ }\r
++ d->Set(b); ny-=num;\r
++ }\r
++ if(dir=='z')\r
++ {\r
++ if(at+num>=nz) return;\r
++ b.Create(nx,ny,nz-num);\r
++ if(at>0) memcpy(b.a, d->a,at*nx*ny*sizeof(dual));\r
++ memcpy(b.a+nx*ny*at, d->a+nx*ny*(at+num),(nz-at-num)*nx*ny*sizeof(dual));\r
++ d->Set(b);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_insert_(uintptr_t *d, const char *dir, int *at, int *num, int)\r
++{ mgl_datac_insert(_DC_,*dir,*at,*num); }\r
++void MGL_EXPORT mgl_datac_delete_(uintptr_t *d, const char *dir, int *at, int *num, int)\r
++{ mgl_datac_delete(_DC_,*dir,*at,*num); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_set_value(HADT dat, dual v, long i, long j, long k)\r
++{\r
++ if(i>=0 && i<dat->nx && j>=0 && j<dat->ny && k>=0 && k<dat->nz)\r
++ dat->a[i+dat->nx*(j+dat->ny*k)]=v;\r
++}\r
++void MGL_EXPORT mgl_datac_set_value_(uintptr_t *d, dual *v, int *i, int *j, int *k)\r
++{ mgl_datac_set_value(_DC_,*v,*i,*j,*k); }\r
++//-----------------------------------------------------------------------------\r
++mdual MGL_EXPORT mgl_datac_get_value(HCDT dat, long i, long j, long k)\r
++{\r
++ long nx=dat->GetNx(), ny=dat->GetNy(), i0=i+nx*(j+ny*k);\r
++ if(i<0 || i>=nx || j<0 || j>=ny || k<0 || k>=dat->GetNz())\r
++ return NAN;\r
++ const mglDataC *d = dynamic_cast<const mglDataC*>(dat);\r
++ dual r = d ? d->a[i0] : dual(dat->vthr(i0),0);\r
++ return r.real()+r.imag()*mgl_I;\r
++}\r
++mdual MGL_EXPORT mgl_datac_get_value_(uintptr_t *d, int *i, int *j, int *k)\r
++{ return mgl_datac_get_value(_DA_(d),*i,*j,*k); }\r
++//-----------------------------------------------------------------------------\r
++MGL_EXPORT dual *mgl_datac_data(HADT dat) { return dat->a; }\r
++//-----------------------------------------------------------------------------\r
++MGL_EXPORT dual *mgl_datac_value(HADT dat, long i,long j,long k)\r
++{ long ii=i*dat->nx*(j+dat->ny*k);\r
++ return ii>=0 && ii<dat->GetNN() ? dat->a+ii : 0; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_join(HADT d, HCDT v)\r
++{\r
++ long nx=d->nx, ny=d->ny, nz=d->nz, k=nx*ny*nz;\r
++ const mglDataC *mv = dynamic_cast<const mglDataC *>(v);\r
++ long vx=v->GetNx(), vy=v->GetNy(), vz=v->GetNz(), m = vx*vy*vz;\r
++\r
++ if(nx==vx && ny==vy && ny>1) d->nz += vz;\r
++ else\r
++ {\r
++ ny *= nz; vy *= vz;\r
++ if(nx==vx && nx>1)\r
++ { d->nz = 1; d->ny = ny+vy; }\r
++ else\r
++ { d->ny = d->nz = 1; d->nx = k+m; }\r
++ }\r
++ dual *b = new dual[k+m];\r
++ memcpy(b,d->a,k*sizeof(dual));\r
++ if(mv) memcpy(b+k,mv->a,m*sizeof(dual));\r
++ else\r
++#pragma omp parallel for\r
++ for(long i=0;i<m;i++) b[k+i] = v->vthr(i);\r
++ if(!d->link) delete []d->a;\r
++ d->a = b; d->link=false; d->NewId();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_join_(uintptr_t *d, uintptr_t *val)\r
++{ mgl_datac_join(_DC_,_DA_(val)); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_put_val(HADT d, dual val, long xx, long yy, long zz)\r
++{\r
++ long nx=d->nx, ny=d->ny, nz=d->nz;\r
++ if(xx>=nx || yy>=ny || zz>=nz) return;\r
++ dual *a=d->a;\r
++ if(xx>=0 && yy>=0 && zz>=0) a[xx+nx*(yy+zz*ny)] = val;\r
++ else if(xx<0 && yy<0 && zz<0)\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx*ny*nz;i++) a[i] = val;\r
++ else if(xx<0 && yy<0)\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx*ny;i++) a[i+zz*nx*ny] = val;\r
++ else if(yy<0 && zz<0)\r
++#pragma omp parallel for\r
++ for(long i=0;i<nz*ny;i++) a[xx+i*nx] = val;\r
++ else if(xx<0 && zz<0)\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<nz;j++) for(long i=0;i<nx;i++) a[i+nx*(yy+j*ny)] = val;\r
++ else if(xx<0)\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx;i++) a[i+nx*(yy+zz*ny)] = val;\r
++ else if(yy<0)\r
++#pragma omp parallel for\r
++ for(long i=0;i<ny;i++) a[xx+nx*(i+zz*ny)] = val;\r
++ else //if(zz<0)\r
++#pragma omp parallel for\r
++ for(long i=0;i<nz;i++) a[xx+nx*(yy+i*ny)] = val;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_put_dat(HADT d, HCDT v, long xx, long yy, long zz)\r
++{\r
++ long nx=d->nx, ny=d->ny, nz=d->nz;\r
++ if(xx>=nx || yy>=ny || zz>=nz) return;\r
++ const mglDataC *mv = dynamic_cast<const mglDataC *>(v);\r
++ dual *a=d->a, vv=v->v(0);\r
++ const dual *b = mv?mv->a:0;\r
++ long vx=v->GetNx(), vy=v->GetNy(), vz=v->GetNz();\r
++ if(xx<0 && yy<0 && zz<0) // whole array\r
++ {\r
++ if(vx>=nx && vy>=ny && vz>=nz)\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<nx*ny*nz;ii++)\r
++ { long i=ii%nx, j=(ii/nx)%ny, k=ii/(nx*ny);\r
++ a[ii] = b?b[i+vx*(j+k*vy)]:v->v(i,j,k); }\r
++ else if(vx>=nx && vy>=ny)\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<nx*ny*nz;ii++)\r
++ { long i=ii%nx, j=(ii/nx)%ny;\r
++ a[ii] = b?b[i+vx*j]:v->v(i,j); }\r
++ else if(vx>=nx)\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<nx*ny*nz;ii++)\r
++ { long i=ii%nx; a[ii] = b?b[i]:v->v(i); }\r
++ else\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<nx*ny*nz;ii++) a[ii] = vv;\r
++ }\r
++ else if(xx<0 && yy<0) // 2d\r
++ {\r
++ zz*=nx*ny;\r
++ if(vx>=nx && vy>=ny)\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<nx*ny;ii++)\r
++ { long i=ii%nx, j=ii/nx;\r
++ a[ii+zz] = b?b[i+vx*j]:v->v(i,j); }\r
++ else if(vx>=nx)\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<nx*ny;ii++)\r
++ { long i=ii%nx; a[ii+zz] = b?b[i]:v->v(i); }\r
++ else\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<nx*ny;ii++) a[ii+zz] = vv;\r
++ }\r
++ else if(yy<0 && zz<0) // 2d\r
++ {\r
++ if(vx>=ny && vy>=nz)\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<ny*nz;ii++)\r
++ { long i=ii%ny, j=ii/ny;\r
++ a[ii*nx+xx] = b?b[i+vx*j]:v->v(i,j); }\r
++ else if(vx>=ny)\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<ny*nz;ii++)\r
++ { long i=ii%ny; a[ii*nx+xx] = b?b[i]:v->v(i); }\r
++ else\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<ny*nz;ii++) a[ii*nx+xx] = vv;\r
++ }\r
++ else if(xx<0 && zz<0) // 2d\r
++ {\r
++ yy *= nx; zz = nx*ny;\r
++ if(vx>=nx && vy>=nz)\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<nx*nz;ii++)\r
++ { long i=ii%nx, j=ii/nx;\r
++ a[i+yy+j*zz] = b?b[i+vx*j]:v->v(i,j); }\r
++ else if(vx>=nx)\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<nx*nz;ii++)\r
++ { long i=ii%nx, j=ii/nx;\r
++ a[i+yy+j*zz] = b?b[i]:v->v(i); }\r
++ else\r
++#pragma omp parallel for\r
++ for(long ii=0;ii<nx*nz;ii++)\r
++ { long i=ii%nx, j=ii/nx;\r
++ a[i+yy+j*zz] = vv; }\r
++ }\r
++ else if(xx<0)\r
++ {\r
++ xx = nx*(yy+zz*ny);\r
++ if(vx>=nx)\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx;i++) a[i+xx] = b?b[i]:v->v(i);\r
++ else\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx;i++) a[i+xx] = vv;\r
++ }\r
++ else if(yy<0)\r
++ {\r
++ xx += zz*nx*ny;\r
++ if(vx>=ny)\r
++#pragma omp parallel for\r
++ for(long i=0;i<ny;i++) a[xx+nx*i] = b?b[i]:v->v(i);\r
++ else\r
++#pragma omp parallel for\r
++ for(long i=0;i<ny;i++) a[xx+nx*i] = vv;\r
++ }\r
++ else if(zz<0)\r
++ {\r
++ xx += nx*yy; yy = nx*ny;\r
++ if(vx>=nz)\r
++#pragma omp parallel for\r
++ for(long i=0;i<nz;i++) a[xx+yy*i] = b?b[i]:v->v(i);\r
++ else\r
++#pragma omp parallel for\r
++ for(long i=0;i<nz;i++) a[xx+yy*i] = vv;\r
++ }\r
++ else a[xx+nx*(yy+ny*zz)] = vv;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_put_val_(uintptr_t *d, dual *val, int *i, int *j, int *k)\r
++{ mgl_datac_put_val(_DC_,*val, *i,*j,*k); }\r
++void MGL_EXPORT mgl_datac_put_dat_(uintptr_t *d, uintptr_t *val, int *i, int *j, int *k)\r
++{ mgl_datac_put_dat(_DC_,_DA_(val), *i,*j,*k); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_difr_grid(dual *a,int n,int step,dual q,int Border,dual *tmp,int kk);\r
++void MGL_EXPORT mgl_difr_axial(dual *a,int n,int step,dual q,int Border,dual *tmp,int kk, double di);\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_difr(void *par)\r
++{\r
++#if !defined(_MSC_VER) // MSVC produce internal compiler error on this code\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long n=t->p[0], st=t->p[1], bord=t->p[3], nn=t->n;\r
++ dual *b=t->a, q = *(t->b);\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel\r
++#endif\r
++ {\r
++ dual *tmp = new dual[2*n];\r
++ if(t->p[2])\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ mgl_difr_axial(b + ((i%st)+n*(i/st)), n,st, q, bord,tmp,3,0);\r
++ else\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp for\r
++#endif\r
++ for(long i=t->id;i<nn;i+=mglNumThr)\r
++ mgl_difr_grid(b + ((i%st)+n*(i/st)), n,st, q, bord,tmp,3);\r
++ delete []tmp;\r
++ }\r
++#endif\r
++ return 0;\r
++}\r
++void MGL_EXPORT mgl_datac_diffr(HADT d, const char *how, mreal q)\r
++{\r
++ if(!how || *how==0) return;\r
++<<<<<<< HEAD\r
++ long nx=d->nx,ny=d->ny,nz=d->nz,ll=strlen(how);\r
++ long p[4]={0,0,0,0};\r
++ dual qq=q;\r
++ for(long i=0;i<ll;i++) if(how[i]>='0' && how[i]<='9') p[3] = how[i]-'0';\r
++ bool axial = mglchr(how,'r')||mglchr(how,'r');\r
++ if(mglchr(how,'z') && nz>1)\r
++ {\r
++ p[0]=nz; p[1]=nx*ny; p[2]=0;\r
++ mglStartThreadC(mgl_difr,0,nx*ny,0,&qq,0,p);\r
++=======\r
++ long nx=d->nx,ny=d->ny,nz=d->nz;\r
++ long p[4]={0,0,0,0};\r
++ dual qq=q;\r
++ if(mglchr(how,'e')) p[3]=-1;\r
++ if(mglchr(how,'g')) p[3]=-2;\r
++ if(mglchr(how,'1')) p[3]=1;\r
++ if(mglchr(how,'2')) p[3]=2;\r
++ if(mglchr(how,'3')) p[3]=3;\r
++ bool axial = mglchr(how,'r')||mglchr(how,'a');\r
++ if(mglchr(how,'z') && nz>1)\r
++ {\r
++ p[0]=nz; p[1]=nx*ny; p[2]=0;\r
++ mglStartThreadC(mgl_difr,0,nx*ny,d->a,&qq,0,p);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ }\r
++ if(mglchr(how,'y') && ny>1 && !axial)\r
++ {\r
++ p[0]=ny; p[1]=nx; p[2]=0;\r
++<<<<<<< HEAD\r
++ mglStartThreadC(mgl_difr,0,nx*nz,0,&qq,0,p);\r
++=======\r
++ mglStartThreadC(mgl_difr,0,nx*nz,d->a,&qq,0,p);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ }\r
++ if(mglchr(how,'x') && nx>1 && !axial)\r
++ {\r
++ p[0]=nx; p[1]=1; p[2]=0;\r
++<<<<<<< HEAD\r
++ mglStartThreadC(mgl_difr,0,ny*nz,0,&qq,0,p);\r
++=======\r
++ mglStartThreadC(mgl_difr,0,ny*nz,d->a,&qq,0,p);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ }\r
++ if(axial && nx>1)\r
++ {\r
++ p[0]=nx; p[1]=1; p[2]=1;\r
++ mglStartThreadC(mgl_difr,0,ny*nz,0,&qq,0,p);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_diffr_(uintptr_t *d, const char *how, double q,int l)\r
++{ char *s=new char[l+1]; memcpy(s,how,l); s[l]=0;\r
++ mgl_datac_diffr(_DC_,s,q); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++HADT MGL_EXPORT mgl_gsplinec_init(HCDT x, HCDT v)\r
++{\r
++ long n = v->GetNx();\r
++ if(!x || x->GetNx()!=n) return 0;\r
++ mglDataC *res = new mglDataC(5*(n-1));\r
++ mreal *xx=0;\r
++ dual *vv=0;\r
++ const mglData *dx = dynamic_cast<const mglData *>(x);\r
++ if(!dx)\r
++ {\r
++ xx = new mreal[n];\r
++ for(long i=0;i<n;i++) xx[i] = x->v(i);\r
++ }\r
++ const mglDataC *dv = dynamic_cast<const mglDataC *>(v);\r
++ if(!dv)\r
++ {\r
++ vv = new dual[n];\r
++ for(long i=0;i<n;i++) vv[i] = v->v(i);\r
++ }\r
++ mgl_gspline_init(n,dx?dx->a:xx,dv?dv->a:vv,res->a);\r
++ if(xx) delete []xx;\r
++ if(vv) delete []vv;\r
++ return res;\r
++}\r
++uintptr_t MGL_EXPORT mgl_gsplinec_init_(uintptr_t *x, uintptr_t *v)\r
++{ return uintptr_t(mgl_gspline_init(_DA_(x),_DA_(v))); }\r
++//-----------------------------------------------------------------------------\r
++mdual MGL_EXPORT mgl_gsplinec(HCDT c, mreal dx, dual *d1, dual *d2)\r
++{\r
++ long i=0, n = c->GetNx();\r
++ if(n%5) return NAN; // not the table of coefficients\r
++ while(dx>c->v(5*i) && i<n-1) { dx-=c->v(5*i); i++; }\r
++ dual res;\r
++ const mglDataC *d = dynamic_cast<const mglDataC *>(c);\r
++ if(d)\r
++ {\r
++ const dual *a = d->a+5*i;\r
++ if(d1) *d1 = a[2]+dx*(mreal(2)*a[3]+(3*dx)*a[4]);\r
++ if(d2) *d2 = mreal(2)*a[3]+(6*dx)*a[4];\r
++ res = a[1]+dx*(a[2]+dx*(a[3]+dx*a[4]));\r
++ }\r
++ else\r
++ {\r
++ if(d1) *d1 = c->v(5*i+2)+dx*(2*c->v(5*i+3)+3*dx*c->v(5*i+4));\r
++ if(d2) *d2 = 2*c->v(5*i+3)+6*dx*c->v(5*i+4);\r
++ res = c->v(5*i+1)+dx*(c->v(5*i+2)+dx*(c->v(5*i+3)+dx*c->v(5*i+4)));\r
++ }\r
++ return res.real()+res.imag()*mgl_I;\r
++}\r
++mdual MGL_EXPORT mgl_gsplinec_(uintptr_t *c, mreal *dx, dual *d1, dual *d2)\r
++{ return mgl_gsplinec(_DA_(c),*dx,d1,d2); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_refill_gs(HADT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl)\r
++{\r
++ HADT coef = mgl_gsplinec_init(xdat, vdat);\r
++ if(!coef) return; // incompatible dimensions\r
++ const long nx = dat->nx, nn=dat->ny*dat->nz;\r
++ mreal x0 = x1-xdat->v(0), dx = (x2-x1)/(nx-1);\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx;i++)\r
++ {\r
++ dual d = mgl_gsplinec(coef,x0+dx*i,0,0);\r
++ if(sl<0) for(long j=0;j<nn;j++) dat->a[i+j*nx] = d;\r
++ else dat->a[i+sl*nx] = d;\r
++ }\r
++ mgl_delete_datac(coef);\r
++}\r
++//-----------------------------------------------------------------------------\r
++mreal MGL_NO_EXPORT mgl_index_1(mreal v, HCDT dat);\r
++void MGL_EXPORT mgl_datac_refill_x(HADT dat, HCDT xdat, HCDT vdat, mreal x1, mreal x2, long sl)\r
++{\r
++ long nx=dat->nx,mx=vdat->GetNx(),nn=dat->ny*dat->nz;\r
++ if(mx!=xdat->GetNx()) return; // incompatible dimensions\r
++ mreal dx = (x2-x1)/(nx-1);\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx;i++)\r
++ {\r
++<<<<<<< HEAD\r
++ register mreal u = mgl_index_1(x1+dx*i,xdat);\r
++=======\r
++ mreal u = mgl_index_1(x1+dx*i,xdat);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ dual d = mgl_datac_spline(vdat,u,0,0);\r
++ if(sl<0) for(long j=0;j<nn;j++) dat->a[i+j*nx] = d;\r
++ else dat->a[i+sl*nx] = d;\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_refill_xy(HADT dat, HCDT xdat, HCDT ydat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, long sl)\r
++{\r
++ long nx=dat->nx,ny=dat->ny,nz=dat->nz,mx=vdat->GetNx(),my=vdat->GetNy(),nn=nx*ny;\r
++ bool both=(xdat->GetNN()==vdat->GetNN() && ydat->GetNN()==vdat->GetNN());\r
++ if(!both && (xdat->GetNx()!=mx || ydat->GetNx()!=my)) return; // incompatible dimensions\r
++ mreal dx = (x2-x1)/(nx-1), dy = (y2-y1)/(ny-1);\r
++ if(both)\r
++ {\r
++#pragma omp parallel for\r
++ for(long i=0;i<nn*nz;i++) dat->a[i]=NAN;\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<my-1;j++) for(long i=0;i<mx-1;i++)\r
++ {\r
++ long i0 = i+mx*j;\r
++ mreal vx0 = (xdat->vthr(i0)-x1)/dx, vy0 = (ydat->vthr(i0)-y1)/dy;\r
++ mreal vx1 = (xdat->vthr(i0+1)-x1)/dx, vy1 = (ydat->vthr(i0+1)-y1)/dy;\r
++ mreal vx2 = (xdat->vthr(i0+mx)-x1)/dx, vy2 = (ydat->vthr(i0+mx)-y1)/dy;\r
++ mreal vx3 = (xdat->vthr(i0+mx+1)-x1)/dx, vy3 = (ydat->vthr(i0+mx+1)-y1)/dy;\r
++ long xx1 = long(mgl_min( mgl_min(vx0,vx1), mgl_min(vx2,vx3) )); // bounding box\r
++ long yy1 = long(mgl_min( mgl_min(vy0,vy1), mgl_min(vy2,vy3) ));\r
++ long xx2 = long(mgl_max( mgl_max(vx0,vx1), mgl_max(vx2,vx3) ));\r
++ long yy2 = long(mgl_max( mgl_max(vy0,vy1), mgl_max(vy2,vy3) ));\r
++ xx1=mgl_max(xx1,0); xx2=mgl_min(xx2,nx-1);\r
++ yy1=mgl_max(yy1,0); yy2=mgl_min(yy2,ny-1);\r
++ if(xx1>xx2 || yy1>yy2) continue;\r
++\r
++ mreal d1x = vx1-vx0, d1y = vy1-vy0;\r
++ mreal d2x = vx2-vx0, d2y = vy2-vy0;\r
++ mreal d3x = vx3+vx0-vx1-vx2, d3y = vy3+vy0-vy1-vy2;\r
++ mreal dd = d1x*d2y-d1y*d2x;\r
++ mreal dsx =-4*(d2y*d3x - d2x*d3y)*d1y;\r
++ mreal dsy = 4*(d2y*d3x - d2x*d3y)*d1x;\r
++\r
++ for(long jj=yy1;jj<=yy2;jj++) for(long ii=xx1;ii<=xx2;ii++)\r
++ {\r
++ mreal xx = (ii-vx0), yy = (jj-vy0);\r
++ mreal s = dsx*xx + dsy*yy + (dd+d3y*xx-d3x*yy)*(dd+d3y*xx-d3x*yy);\r
++ if(s>=0)\r
++ {\r
++ s = sqrt(s);\r
++ mreal qu = d3x*yy - d3y*xx + dd + s;\r
++ mreal qv = d3y*xx - d3x*yy + dd + s;\r
++ mreal u = 2.f*(d2y*xx - d2x*yy)/qu;\r
++ mreal v = 2.f*(d1x*yy - d1y*xx)/qv;\r
++ if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) // first root bad\r
++ {\r
++ qu = d3x*yy - d3y*xx + dd - s;\r
++ qv = d3y*xx - d3x*yy + dd - s;\r
++ u = 2.f*(d2y*xx - d2x*yy)/qu;\r
++ v = 2.f*(d1x*yy - d1y*xx)/qv;\r
++ if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) continue; // second root bad\r
++ }\r
++ i0 = ii+nx*jj; s = vdat->value(i+u,j+v,0);\r
++ if(sl<0) for(long k=0;k<nz;k++) dat->a[i0+k*nn] = s;\r
++ else dat->a[i0+sl*nn] = s;\r
++ }\r
++ }\r
++ }\r
++ }\r
++ else\r
++ {\r
++ mglData u(nx), v(ny);\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx;i++) u.a[i] = mgl_index_1(x1+dx*i,xdat);\r
++#pragma omp parallel for\r
++ for(long i=0;i<ny;i++) v.a[i] = mgl_index_1(y1+dy*i,ydat);\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ dual d = mgl_datac_spline(vdat,u.a[i],v.a[j],0);\r
++<<<<<<< HEAD\r
++ register long i0=i+nx*j;\r
++=======\r
++ long i0=i+nx*j;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ if(sl<0) for(long k=0;k<nz;k++) dat->a[i0+k*nn] = d;\r
++ else dat->a[i0+sl*nn] = d;\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_datac_refill_xyz(HADT dat, HCDT xdat, HCDT ydat, HCDT zdat, HCDT vdat, mreal x1, mreal x2, mreal y1, mreal y2, mreal z1, mreal z2)\r
++{\r
++ if(!dat || !xdat || !ydat || !zdat || !vdat) return;\r
++ long nx=dat->nx,ny=dat->ny,nz=dat->nz,mx=vdat->GetNx(),my=vdat->GetNy(),mz=vdat->GetNz();\r
++ bool both=(xdat->GetNN()==vdat->GetNN() && ydat->GetNN()==vdat->GetNN() && zdat->GetNN()==vdat->GetNN());\r
++ if(!both && (xdat->GetNx()!=mx || ydat->GetNx()!=my || zdat->GetNx()!=mz)) return; // incompatible dimensions\r
++ const mreal acx=1e-6*fabs(x2-x1), acy=1e-6*fabs(y2-y1), acz=1e-6*fabs(z2-z1);\r
++ if(both)\r
++#pragma omp parallel for collapse(3)\r
++ for(long k=0;k<nz;k++) for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ mreal xx = x1+(x2-x1)*i/(nx-1.),dxx,dxy,dxz,vx,dx=0,dd;\r
++ mreal yy = y1+(y2-y1)*j/(ny-1.),dyx,dyy,dyz,vy,dy=0;\r
++ mreal zz = z1+(z2-z1)*k/(nz-1.),dzx,dzy,dzz,vz,dz=0;\r
++ vx = xdat->valueD(dx,dy,dz,&dxx,&dxy,&dxz);\r
++ vy = ydat->valueD(dx,dy,dz,&dyx,&dyy,&dyz);\r
++ vz = zdat->valueD(dx,dy,dz,&dzx,&dzy,&dzz);\r
++ long count=0;\r
++ do // use Newton method to find root\r
++ {\r
++ if(count>50) { dx=NAN; break; } count++;\r
++ dd = -dxx*dyy*dzz+dxy*dyx*dzz+dxx*dyz*dzy-dxz*dyx*dzy-dxy*dyz*dzx+dxz*dyy*dzx;\r
++ dx += ((dyz*dzy-dyy*dzz)*(xx-vx)+(dxy*dzz-dxz*dzy)*(yy-vy)+(dxz*dyy-dxy*dyz)*(zz-vz))/dd;\r
++ dy += ((dyx*dzz-dyz*dzx)*(xx-vx)+(dxz*dzx-dxx*dzz)*(yy-vy)+(dxx*dyz-dxz*dyx)*(zz-vz))/dd;\r
++ dz += ((dyy*dzx-dyx*dzy)*(xx-vx)+(dxx*dzy-dxy*dzx)*(yy-vy)+(dxy*dyx-dxx*dyy)*(zz-vz))/dd;\r
++ vx = xdat->valueD(dx,dy,dz,&dxx,&dxy,&dxz);\r
++ vy = ydat->valueD(dx,dy,dz,&dyx,&dyy,&dyz);\r
++ vz = zdat->valueD(dx,dy,dz,&dzx,&dzy,&dzz);\r
++ } while(fabs(xx-vx)>acx && fabs(yy-vy)>acy && fabs(zz-vz)>acz); // this valid for linear interpolation\r
++ dat->a[i+nx*(j+ny*k)] = mgl_isnan(dx)?NAN:vdat->value(dx,dy,dz);\r
++ }\r
++ else\r
++ {\r
++ mglData u(nx), v(ny), w(nz);\r
++ mreal dx = (x2-x1)/(nx-1), dy = (y2-y1)/(ny-1), dz = (z2-z1)/(nz-1);\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx;i++) u.a[i] = mgl_index_1(x1+dx*i,xdat);\r
++#pragma omp parallel for\r
++ for(long i=0;i<ny;i++) v.a[i] = mgl_index_1(y1+dy*i,ydat);\r
++#pragma omp parallel for\r
++ for(long i=0;i<nz;i++) w.a[i] = mgl_index_1(z1+dz*i,zdat);\r
++#pragma omp parallel for collapse(3)\r
++ for(long k=0;k<nz;k++) for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ dat->a[i+nx*(j+ny*k)] = mgl_datac_spline(vdat,u.a[i],v.a[j],w.a[k]);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_diffc_3(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0], ny=t->p[1], nz=t->p[2], nn=t->n, n2=nx*ny;\r
++ dual *b=t->a,au,av,aw;\r
++ HCDT x=(HCDT)(t->c),y=(HCDT)(t->d),z=(HCDT)(t->e);\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for private(au,av,aw)\r
++#endif\r
++ for(long i0=t->id;i0<nn;i0+=mglNumThr)\r
++ {\r
++ long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);\r
++ mreal xu,xv,xw,yu,yv,yw,zu,zv,zw;\r
++ if(i==0)\r
++ {\r
++ au = mreal(3)*a[i0]-mreal(4)*a[i0+1]+a[i0+2];\r
++ xu = 3*x->vthr(i0)-4*x->vthr(i0+1)+x->vthr(i0+2);\r
++ yu = 3*y->vthr(i0)-4*y->vthr(i0+1)+y->vthr(i0+2);\r
++ zu = 3*z->vthr(i0)-4*z->vthr(i0+1)+z->vthr(i0+2);\r
++ }\r
++ else if(i==nx-1)\r
++ {\r
++ au = mreal(3)*a[i0]-mreal(4)*a[i0-1]+a[i0-2];\r
++ xu = 3*x->vthr(i0)-4*x->vthr(i0-1)+x->vthr(i0-2);\r
++ yu = 3*y->vthr(i0)-4*y->vthr(i0-1)+y->vthr(i0-2);\r
++ zu = 3*z->vthr(i0)-4*z->vthr(i0-1)+z->vthr(i0-2);\r
++ }\r
++ else\r
++ {\r
++ au = a[i0+1]-a[i0-1];\r
++ xu = x->vthr(i0+1)-x->vthr(i0-1);\r
++ yu = y->vthr(i0+1)-y->vthr(i0-1);\r
++ zu = z->vthr(i0+1)-z->vthr(i0-1);\r
++ }\r
++ if(j==0)\r
++ {\r
++ av = mreal(3)*a[i0]-mreal(4)*a[i0+nx]+a[i0+2*nx];\r
++ xv = 3*x->vthr(i0)-4*x->vthr(i0+nx)+x->vthr(i0+2*nx);\r
++ yv = 3*y->vthr(i0)-4*y->vthr(i0+nx)+y->vthr(i0+2*nx);\r
++ zv = 3*z->vthr(i0)-4*z->vthr(i0+nx)+z->vthr(i0+2*nx);\r
++ }\r
++ else if(j==ny-1)\r
++ {\r
++ av = mreal(3)*a[i0]-mreal(4)*a[i0-nx]+a[i0+(ny-3)*nx];\r
++ xv = 3*x->vthr(i0)-4*x->vthr(i0-nx)+x->vthr(i0-2*nx);\r
++ yv = 3*y->vthr(i0)-4*y->vthr(i0-nx)+y->vthr(i0-2*nx);\r
++ zv = 3*z->vthr(i0)-4*z->vthr(i0-nx)+z->vthr(i0-2*nx);\r
++ }\r
++ else\r
++ {\r
++ av = a[i0+nx]-a[i0-nx];\r
++ xv = x->vthr(i0+nx)-x->vthr(i0-nx);\r
++ yv = y->vthr(i0+nx)-y->vthr(i0-nx);\r
++ zv = z->vthr(i0+nx)-z->vthr(i0-nx);\r
++ }\r
++ if(k==0)\r
++ {\r
++ aw = mreal(3)*a[i0]-mreal(4)*a[i0+n2]+a[i0+2*n2];\r
++ xw = 3*x->vthr(i0)-4*x->vthr(i0+n2)+x->vthr(i0+2*n2);\r
++ yw = 3*y->vthr(i0)-4*y->vthr(i0+n2)+y->vthr(i0+2*n2);\r
++ zw = 3*z->vthr(i0)-4*z->vthr(i0+n2)+z->vthr(i0+2*n2);\r
++ }\r
++ else if(k==nz-1)\r
++ {\r
++ aw = mreal(3)*a[i0]-mreal(4)*a[i0-n2]+a[i0-2*n2];\r
++ xw = 3*x->vthr(i0)-4*x->vthr(i0-n2)+x->vthr(i0-2*n2);\r
++ yw = 3*y->vthr(i0)-4*y->vthr(i0-n2)+y->vthr(i0-2*n2);\r
++ zw = 3*z->vthr(i0)-4*z->vthr(i0-n2)+z->vthr(i0-2*n2);\r
++ }\r
++ else\r
++ {\r
++ aw = a[i0+n2]-a[i0-n2];\r
++ xw = x->vthr(i0+n2)-x->vthr(i0-n2);\r
++ yw = y->vthr(i0+n2)-y->vthr(i0-n2);\r
++ zw = z->vthr(i0+n2)-z->vthr(i0-n2);\r
++ }\r
++ b[i0] = (au*yv*zw-av*yu*zw-au*yw*zv+aw*yu*zv+av*yw*zu-aw*yv*zu) / (xu*yv*zw-xv*yu*zw-xu*yw*zv+xw*yu*zv+xv*yw*zu-xw*yv*zu);\r
++ }\r
++ return 0;\r
++}\r
++MGL_NO_EXPORT void *mgl_diffc_2(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0], ny=t->p[1], nn=t->n, same=t->p[2];\r
++ dual *b=t->a,au,av;\r
++ HCDT x=(HCDT)(t->c),y=(HCDT)(t->d);\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for private(au,av)\r
++#endif\r
++ for(long i0=t->id;i0<nn;i0+=mglNumThr)\r
++ {\r
++ long i=i0%nx, j=((i0/nx)%ny), i1 = same ? i0 : i0%(nx*ny);\r
++ mreal xu,xv,yu,yv;\r
++ if(i==0)\r
++ {\r
++ au = mreal(3)*a[i0]-mreal(4)*a[i0+1]+a[i0+2];\r
++ xu = 3*x->vthr(i1)-4*x->vthr(i1+1)+x->vthr(i1+2);\r
++ yu = 3*y->vthr(i1)-4*y->vthr(i1+1)+y->vthr(i1+2);\r
++ }\r
++ else if(i==nx-1)\r
++ {\r
++ au = mreal(3)*a[i0]-mreal(4)*a[i0-1]+a[i0-2];\r
++ xu = 3*x->vthr(i1)-4*x->vthr(i1-1)+x->vthr(i1-2);\r
++ yu = 3*y->vthr(i1)-4*y->vthr(i1-1)+y->vthr(i1-2);\r
++ }\r
++ else\r
++ {\r
++ au = a[i0+1]-a[i0-1];\r
++ xu = x->vthr(i1+1)-x->vthr(i1-1);\r
++ yu = y->vthr(i1+1)-y->vthr(i1-1);\r
++ }\r
++ if(j==0)\r
++ {\r
++ av = mreal(3)*a[i0]-mreal(4)*a[i0+nx]+a[i0+2*nx];\r
++ xv = 3*x->vthr(i1)-4*x->vthr(i1+nx)+x->vthr(i1+2*nx);\r
++ yv = 3*y->vthr(i1)-4*y->vthr(i1+nx)+y->vthr(i1+2*nx);\r
++ }\r
++ else if(j==ny-1)\r
++ {\r
++ av = mreal(3)*a[i0]-mreal(4)*a[i0-nx]+a[i0-2*nx];\r
++ xv = 3*x->vthr(i1)-4*x->vthr(i1-nx)+x->vthr(i1-2*nx);\r
++ yv = 3*y->vthr(i1)-4*y->vthr(i1-nx)+y->vthr(i1-2*nx);\r
++ }\r
++ else\r
++ {\r
++ av = a[i0+nx]-a[i0-nx];\r
++ xv = x->vthr(i1+nx)-x->vthr(i1-nx);\r
++ yv = y->vthr(i1+nx)-y->vthr(i1-nx);\r
++ }\r
++ b[i0] = (av*yu-au*yv)/(xv*yu-xu*yv);\r
++ }\r
++ return 0;\r
++}\r
++MGL_NO_EXPORT void *mgl_diffc_1(void *par)\r
++{\r
++ mglThreadC *t=(mglThreadC *)par;\r
++ long nx=t->p[0], nn=t->n, same=t->p[1];\r
++ dual *b=t->a,au;\r
++ HCDT x=(HCDT)(t->c);\r
++ const dual *a=t->b;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for private(au)\r
++#endif\r
++ for(long i0=t->id;i0<nn;i0+=mglNumThr)\r
++ {\r
++ long i=i0%nx, i1 = same ? i0 : i;\r
++ mreal xu;\r
++ if(i==0)\r
++ {\r
++ au = mreal(3)*a[i0]-mreal(4)*a[i0+1]+a[i0+2];\r
++ xu = 3*x->vthr(i1)-4*x->vthr(i1+1)+x->vthr(i1+2);\r
++ }\r
++ else if(i==nx-1)\r
++ {\r
++ au = mreal(3)*a[i0]-mreal(4)*a[i0-1]+a[i0-2];\r
++ xu = 3*x->vthr(i1)-4*x->vthr(i1-1)+x->vthr(i1-2);\r
++ }\r
++ else\r
++ {\r
++ au = a[i0+1]-a[i0-1];\r
++ xu = x->vthr(i1+1)-x->vthr(i1-1);\r
++ }\r
++ b[i0] = au/xu;\r
++ }\r
++ return 0;\r
++}\r
++void MGL_EXPORT mgl_datac_diff_par(HADT d, HCDT x, HCDT y, HCDT z)\r
++{\r
++ long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(), nn=nx*ny*nz;\r
++ if(nx<2 || ny<2) return;\r
++ dual *b = new dual[nn]; memset(b,0,nn*sizeof(dual));\r
++ long p[3]={nx,ny,nz};\r
++\r
++ if(x&&y&&z && x->GetNN()==nn && y->GetNN()==nn && z->GetNN()==nn)\r
++ mglStartThreadC(mgl_diffc_3,0,nn,b,d->a,(const dual *)x,p,0,(const dual *)y,(const dual *)z);\r
++ else if(x&&y && x->GetNx()*x->GetNy()==nx*ny && y->GetNx()*y->GetNy()==nx*ny)\r
++ {\r
++ p[2]=(x->GetNz()==nz && y->GetNz()==nz);\r
++ mglStartThreadC(mgl_diffc_2,0,nn,b,d->a,(const dual *)x,p,0,(const dual *)y);\r
++ }\r
++ else if(x && x->GetNx()==nx)\r
++ {\r
++ p[1]=(x->GetNy()*x->GetNz()==ny*nz);\r
++ mglStartThreadC(mgl_diffc_1,0,nn,b,d->a,(const dual *)x,p,0,0);\r
++ }\r
++ memcpy(d->a,b,nn*sizeof(dual)); delete []b;\r
++}\r
++void MGL_EXPORT mgl_datac_diff_par_(uintptr_t *d, uintptr_t *v1, uintptr_t *v2, uintptr_t *v3)\r
++{ mgl_datac_diff_par(_DC_,_DA_(v1),_DA_(v2),_DA_(v3)); }\r
++//-----------------------------------------------------------------------------\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * crust.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include <float.h>\r
++#include <math.h>\r
++#include <list>\r
++#include <limits>\r
++#include "mgl2/other.h"\r
++#include "mgl2/data.h"\r
++#include "mgl2/thread.h"\r
++#include "mgl2/base.h"\r
++//-----------------------------------------------------------------------------\r
++//\r
++// TriPlot series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_triplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
++{\r
++ long n = x->GetNN(), m = nums->GetNy();\r
++ if(mgl_check_trig(gr,nums,x,y,z,a,"TriPlot")) return;\r
++\r
++ long ss=gr->AddTexture(sch);\r
++ gr->SaveState(opt); gr->SetPenPal("-");\r
++ static int cgid=1; gr->StartGroup("TriPlot",cgid++);\r
++\r
++ bool wire = mglchr(sch,'#');\r
++ long nc = a->GetNN();\r
++ if(nc!=n && nc>=m) // colors per triangle\r
++ {\r
++ mglPoint p1,p2,p3,q;\r
++ gr->Reserve(m*3);\r
++ for(long i=0;i<m;i++) if(nums->v(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0)\r
++ {\r
++ long k1 = long(nums->v(0,i)+0.5);\r
++ p1.Set(x->v(k1), y->v(k1), z->v(k1));\r
++ long k2 = long(nums->v(1,i)+0.5);\r
++ p2.Set(x->v(k2), y->v(k2), z->v(k2));\r
++ long k3 = long(nums->v(2,i)+0.5);\r
++ p3.Set(x->v(k3), y->v(k3), z->v(k3));\r
++ q = wire ? mglPoint(NAN,NAN) : (p2-p1) ^ (p3-p1);\r
++ k1 = gr->AddPnt(p1,gr->GetC(ss,a->v(k1)),q);\r
++ k2 = gr->AddPnt(p2,gr->GetC(ss,a->v(k2)),q);\r
++ k3 = gr->AddPnt(p3,gr->GetC(ss,a->v(k3)),q);\r
++ gr->trig_plot(k1,k2,k3);\r
++ }\r
++ }\r
++ else if(nc>=n) // colors per point\r
++ {\r
++ gr->Reserve(n);\r
++ long *kk = new long[n];\r
++ mglPoint *pp = new mglPoint[n];\r
++ for(long i=0;i<m;i++) if(nums->v(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0) // add averaged normales\r
++ {\r
++ long k1 = long(nums->v(0,i)+0.5);\r
++ long k2 = long(nums->v(1,i)+0.5);\r
++ long k3 = long(nums->v(2,i)+0.5);\r
++ if(!wire)\r
++ {\r
++ mglPoint q(mglPoint(x->v(k2)-x->v(k1), y->v(k2)-y->v(k1), z->v(k2)-z->v(k1)) ^\r
++ mglPoint(x->v(k3)-x->v(k1), y->v(k3)-y->v(k1), z->v(k3)-z->v(k1)));\r
++ q.Normalize();\r
++ // try be sure that in the same direction ...\r
++ if(q.z<0) q *= -1;\r
++ pp[k1] += q; pp[k2] += q; pp[k3] += q;\r
++ }\r
++ else pp[k1]=pp[k2]=pp[k3]=mglPoint(NAN,NAN);\r
++ }\r
++ for(long i=0;i<n;i++) // add points\r
++ kk[i] = gr->AddPnt(mglPoint(x->v(i), y->v(i), z->v(i)), gr->GetC(ss,a->v(i)), pp[i]);\r
++ for(long i=0;i<m;i++) if(nums->v(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0) // draw triangles\r
++ {\r
++ long k1 = long(nums->v(0,i)+0.5);\r
++ long k2 = long(nums->v(1,i)+0.5);\r
++ long k3 = long(nums->v(2,i)+0.5);\r
++ if(wire)\r
++ {\r
++ gr->line_plot(kk[k1],kk[k2]); gr->line_plot(kk[k1],kk[k3]);\r
++ gr->line_plot(kk[k3],kk[k2]);\r
++ }\r
++ else gr->trig_plot(kk[k1],kk[k2],kk[k3]);\r
++ }\r
++ delete []kk; delete []pp;\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_triplot_xyz(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
++{ mgl_triplot_xyzc(gr,nums,x,y,z,z,sch,opt); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_triplot_xy(HMGL gr, HCDT nums, HCDT x, HCDT y, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglData z(x->GetNN());\r
++ mreal zm = gr->AdjustZMin(); z.Fill(zm,zm);\r
++ mgl_triplot_xyzc(gr,nums,x,y,&z,&z,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_triplot_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_triplot_xyzc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_triplot_xyz_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_triplot_xyz(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_triplot_xy_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_triplot_xy(_GR_, _DA_(nums), _DA_(x), _DA_(y), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// QuadPlot series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_quadplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
++{\r
++ long n = x->GetNN(), m = nums->GetNy();\r
++ if(mgl_check_trig(gr,nums,x,y,z,a,"QuadPlot",4)) return;\r
++\r
++ long ss=gr->AddTexture(sch);\r
++ gr->SaveState(opt); gr->SetPenPal("-");\r
++ static int cgid=1; gr->StartGroup("QuadPlot",cgid++);\r
++ mglPoint p1,p2,p3,p4;\r
++\r
++ long nc = a->GetNN();\r
++ bool wire = mglchr(sch,'#');\r
++ if(nc!=n && nc>=m) // colors per triangle\r
++ {\r
++ gr->Reserve(m*4);\r
++ for(long i=0;i<m;i++) if(nums->v(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0 && nums->v(3,i)>=0)\r
++ {\r
++ long k1 = long(nums->v(0,i)+0.5);\r
++ p1.Set(x->v(k1), y->v(k1), z->v(k1));\r
++ long k2 = long(nums->v(1,i)+0.5);\r
++ p2.Set(x->v(k2), y->v(k2), z->v(k2));\r
++ long k3 = long(nums->v(2,i)+0.5);\r
++ p3.Set(x->v(k3), y->v(k3), z->v(k3));\r
++ long k4 = long(nums->v(3,i)+0.5);\r
++ p4.Set(x->v(k4), y->v(k4), z->v(k4));\r
++ mglPoint q = wire ? mglPoint(NAN,NAN):(p2-p1) ^ (p3-p1);\r
++ k1 = gr->AddPnt(p1,gr->GetC(ss,a->v(k1)),q);\r
++ k2 = gr->AddPnt(p2,gr->GetC(ss,a->v(k2)),q);\r
++ k3 = gr->AddPnt(p3,gr->GetC(ss,a->v(k3)),q);\r
++ k4 = gr->AddPnt(p4,gr->GetC(ss,a->v(k4)),q);\r
++ gr->quad_plot(k1,k2,k3,k4);\r
++ }\r
++ }\r
++ else if(nc>=n) // colors per point\r
++ {\r
++ gr->Reserve(n);\r
++ long *kk = new long[n];\r
++ mglPoint *pp = new mglPoint[n];\r
++ for(long i=0;i<m;i++) if(nums->v(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0 && nums->v(3,i)>=0)\r
++ { // add averaged normales\r
++ long k1 = long(nums->v(0,i)+0.5);\r
++ p1.Set(x->v(k1), y->v(k1), z->v(k1));\r
++ long k2 = long(nums->v(1,i)+0.5);\r
++ p2.Set(x->v(k2), y->v(k2), z->v(k2));\r
++ long k3 = long(nums->v(2,i)+0.5);\r
++ p3.Set(x->v(k3), y->v(k3), z->v(k3));\r
++ long k4 = long(nums->v(3,i)+0.5);\r
++ p4.Set(x->v(k4), y->v(k4), z->v(k4));\r
++\r
++ if(wire) pp[k1]=pp[k2]=pp[k3]=pp[k4]=mglPoint(NAN,NAN);\r
++ else\r
++ {\r
++ mglPoint q1 = (p2-p1) ^ (p3-p1); if(q1.z<0) q1*=-1;\r
++ mglPoint q2 = (p2-p4) ^ (p3-p4); if(q2.z<0) q2*=-1;\r
++ mglPoint q3 = (p1-p2) ^ (p4-p2); if(q3.z<0) q3*=-1;\r
++ mglPoint q4 = (p1-p4) ^ (p4-p3); if(q4.z<0) q4*=-1;\r
++ pp[k1] += q1; pp[k2] += q2; pp[k3] += q3; pp[k4] += q4;\r
++ }\r
++ }\r
++ for(long i=0;i<n;i++) // add points\r
++ kk[i] = gr->AddPnt(mglPoint(x->v(i), y->v(i), z->v(i)),gr->GetC(ss,a->v(i)), pp[i]);\r
++ for(long i=0;i<m;i++) if(nums->v(0,i)>=0 && nums->v(1,i)>=0 && nums->v(2,i)>=0 && nums->v(3,i)>=0)\r
++ { // draw quads\r
++ long k1 = long(nums->v(0,i)+0.5);\r
++ long k2 = long(nums->v(1,i)+0.5);\r
++ long k3 = long(nums->v(2,i)+0.5);\r
++ long k4 = long(nums->v(3,i)+0.5);\r
++ if(wire)\r
++ {\r
++ gr->line_plot(kk[k1],kk[k2]); gr->line_plot(kk[k1],kk[k3]);\r
++ gr->line_plot(kk[k4],kk[k2]); gr->line_plot(kk[k4],kk[k3]);\r
++ }\r
++ else gr->quad_plot(kk[k1],kk[k2],kk[k3],kk[k4]);\r
++ }\r
++ delete []kk; delete []pp;\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_quadplot_xyz(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
++{ mgl_quadplot_xyzc(gr,nums,x,y,z,z,sch,opt); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_quadplot_xy(HMGL gr, HCDT nums, HCDT x, HCDT y, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglData z(x->GetNN()); z.Fill(gr->Min.z,gr->Min.z);\r
++ mgl_quadplot_xyzc(gr,nums,x,y,&z,&z,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_quadplot_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_quadplot_xyzc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o);\r
++ delete []o; delete []s;}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_quadplot_xyz_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_quadplot_xyzc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(z), s, o);\r
++ delete []o; delete []s;}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_quadplot_xy_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_quadplot_xy(_GR_, _DA_(nums), _DA_(x), _DA_(y), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// TriCont series\r
++//\r
++//-----------------------------------------------------------------------------\r
++#include "cont.hpp"\r
++//-----------------------------------------------------------------------------\r
++std::vector<mglSegment> MGL_NO_EXPORT mgl_tri_lines(mreal val, HCDT nums, HCDT a, HCDT x, HCDT y, HCDT z)\r
++{\r
++ long n = x->GetNN(), m = nums->GetNy();\r
++ std::vector<mglSegment> lines;\r
++ for(long i=0;i<m;i++)\r
++ {\r
++ long k1 = long(nums->v(0,i)+0.5), k2 = long(nums->v(1,i)+0.5), k3 = long(nums->v(2,i)+0.5);\r
++ if(k1<0 || k1>=n || k2<0 || k2>=n || k3<0 || k3>=n) continue;\r
++ mreal v1 = a->v(k1), v2 = a->v(k2), v3 = a->v(k3);\r
++ mreal d1 = mgl_d(val,v1,v2), d2 = mgl_d(val,v1,v3), d3 = mgl_d(val,v2,v3);\r
++ mglSegment line;\r
++ if(d1>=0 && d1<=1 && d2>=0 && d2<=1)\r
++ {\r
++ line.p1.Set(x->v(k1)*(1-d1)+x->v(k2)*d1, y->v(k1)*(1-d1)+y->v(k2)*d1, z->v(k1)*(1-d1)+z->v(k2)*d1);\r
++ line.p2.Set(x->v(k1)*(1-d2)+x->v(k3)*d2, y->v(k1)*(1-d2)+y->v(k3)*d2, z->v(k1)*(1-d2)+z->v(k3)*d2);\r
++ }\r
++ else if(d1>=0 && d1<=1 && d3>=0 && d3<=1)\r
++ {\r
++ line.p1.Set(x->v(k1)*(1-d1)+x->v(k2)*d1, y->v(k1)*(1-d1)+y->v(k2)*d1, z->v(k1)*(1-d1)+z->v(k2)*d1);\r
++ line.p2.Set(x->v(k2)*(1-d3)+x->v(k3)*d3, y->v(k2)*(1-d3)+y->v(k3)*d3, z->v(k2)*(1-d3)+z->v(k3)*d3);\r
++ }\r
++ else if(d3>=0 && d3<=1 && d2>=0 && d2<=1)\r
++ {\r
++ line.p1.Set(x->v(k1)*(1-d2)+x->v(k3)*d2, y->v(k1)*(1-d2)+y->v(k3)*d2, z->v(k1)*(1-d2)+z->v(k3)*d2);\r
++ line.p2.Set(x->v(k2)*(1-d3)+x->v(k3)*d3, y->v(k2)*(1-d3)+y->v(k3)*d3, z->v(k2)*(1-d3)+z->v(k3)*d3);\r
++ }\r
++ if(line.p1!=line.p2) lines.push_back(line);\r
++ }\r
++ return lines;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricont_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
++{\r
++ mglDataV zz(x->GetNN());\r
++ if(!z) z = &zz;\r
++ if(mgl_check_trig(gr,nums,x,y,z,a,"TriCont")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("TriCont",cgid++);\r
++ int text=0;\r
++ if(mglchr(sch,'t')) text=1;\r
++ if(mglchr(sch,'T')) text=2;\r
++ bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z);\r
++ long s=gr->AddTexture(sch);\r
++ gr->SetPenPal(sch);\r
++\r
++ for(long k=0;k<v->GetNx();k++)\r
++ {\r
++ mreal v0 = v->v(k); zz.Fill(fixed ? gr->Min.z : v0);\r
++ mgl_draw_curvs(gr,v0,gr->GetC(s,v0),text,mgl_get_curvs(gr,mgl_tri_lines(v0,nums,a,x,y,fixed?&zz:z)));\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricont_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long n = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5);\r
++ mglData v(n);\r
++ for(long i=0;i<n;i++) v.a[i] = gr->Min.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(n+1);\r
++ mgl_tricont_xyzcv(gr,&v,nums,x,y,z,a,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricont_xyc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
++{ mgl_tricont_xyzc(gr,nums,x,y,0,z,sch,opt); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricont_xycv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
++{ mgl_tricont_xyzcv(gr,v,nums,x,y,0,z,sch,opt); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricont_xyzcv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tricont_xyzcv(_GR_, _DA_(v), _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricont_xycv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tricont_xycv(_GR_, _DA_(v), _DA_(nums), _DA_(x), _DA_(y), _DA_(z), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricont_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tricont_xyzc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricont_xyc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tricont_xyc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// TriContV series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricontv_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
++{\r
++ mglDataV zz(x->GetNN());\r
++ if(!z) z = &zz;\r
++ if(mgl_check_trig(gr,nums,x,y,z,a,"TriContV")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("TriContV",cgid++);\r
++ bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z);\r
++ long s=gr->AddTexture(sch);\r
++ gr->SetPenPal(sch);\r
++\r
++ for(long k=0;k<v->GetNx();k++)\r
++ {\r
++ mreal v0 = v->v(k); zz.Fill(fixed ? gr->Min.z : v0);\r
++ mreal dv = (gr->Max.c-gr->Min.c)/8, c = gr->GetC(s,v0);\r
++ if(k>0) dv = v->v(k-1)-v->v(k);\r
++ else if(k<v->GetNx()-1) dv = v->v(k)-v->v(k+1);\r
++ if(fixed) dv=-dv;\r
++\r
++ const std::vector<mglSegment> curvs = mgl_get_curvs(gr,mgl_tri_lines(v0,nums,a,x,y,fixed?&zz:z));\r
++ for(size_t i=0;i<curvs.size();i++)\r
++ {\r
++ const std::list<mglPoint> &pp=curvs[i].pp;\r
++ long f2=-1,g2=-1;\r
++ for(std::list<mglPoint>::const_iterator it=pp.begin(); it != pp.end(); ++it)\r
++ {\r
++ mglPoint p=*it,q(p.y,-p.x);\r
++ long f1 = f2; f2 = gr->AddPnt(p,c,q); p.z+=dv;\r
++ long g1 = g2; g2 = gr->AddPnt(p,c,q);\r
++ gr->quad_plot(f1,g1,f2,g2);\r
++ }\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricontv_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long n = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5);\r
++ mglData v(n);\r
++ for(long i=0;i<n;i++) v.a[i] = gr->Min.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(n+1);\r
++ mgl_tricontv_xyzcv(gr,&v,nums,x,y,z,a,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricontv_xyc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
++{ mgl_tricontv_xyzc(gr,nums,x,y,0,z,sch,opt); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricontv_xycv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
++{ mgl_tricontv_xyzcv(gr,v,nums,x,y,0,z,sch,opt); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricontv_xyzcv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tricontv_xyzcv(_GR_, _DA_(v), _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricontv_xycv_(uintptr_t *gr, uintptr_t *v, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tricontv_xycv(_GR_, _DA_(v), _DA_(nums), _DA_(x), _DA_(y), _DA_(z), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricontv_xyzc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *sch, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tricontv_xyzc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), _DA_(c), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tricontv_xyc_(uintptr_t *gr, uintptr_t *nums, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tricontv_xyc(_GR_, _DA_(nums), _DA_(x), _DA_(y), _DA_(z), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Dots series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_dots_ca(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, HCDT a, const char *sch, const char *opt)\r
++{\r
++ long n = x->GetNN(), d, k=1;\r
++ if(x->GetNz()>1) k=3; else if(x->GetNy()>1) k=2;\r
++\r
++ if(y->GetNN()!=n || z->GetNN()!=n || c->GetNN()!=n || (a && a->GetNN()!=n))\r
++ { gr->SetWarn(mglWarnDim,"Dots"); return; }\r
++ gr->SaveState(opt);\r
++\r
++ d = gr->MeshNum>0 ? mgl_ipow(gr->MeshNum+1,k) : n;\r
++ d = n>d ? n/d:1;\r
++\r
++ static int cgid=1; gr->StartGroup("Dots",cgid++);\r
++ char mk=gr->SetPenPal(sch);\r
++ long ss=gr->AddTexture(sch);\r
++ if(mk==0) mk='.';\r
++ gr->Reserve(n);\r
++\r
++ for(long i=0;i<n;i+=d)\r
++ {\r
++ mglPoint p(x->vthr(i),y->vthr(i),z->vthr(i));\r
++ long pp = gr->AddPnt(p,gr->GetC(ss,c->vthr(i)),mglPoint(NAN),a?gr->GetA(a->vthr(i)):-1);\r
++ gr->mark_plot(pp, mk);\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_dots_a(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
++{ mgl_dots_ca(gr, x, y, z, z, a, sch, opt); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_dots(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
++{ mgl_dots_ca(gr, x, y, z, z, NULL, sch, opt); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_dots_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_dots(_GR_, _DA_(x),_DA_(y),_DA_(z),s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_dots_a_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_dots_a(_GR_, _DA_(x),_DA_(y),_DA_(z),_DA_(a),s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_dots_ca_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, uintptr_t *a, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_dots_ca(_GR_, _DA_(x),_DA_(y),_DA_(z),_DA_(c),_DA_(a),s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// mglTriangulation\r
++//\r
++//-----------------------------------------------------------------------------\r
++long MGL_NO_EXPORT mgl_crust(long n,mglPoint *pp,long **nn,mreal ff);\r
++HMDT MGL_EXPORT mgl_triangulation_3d(HCDT x, HCDT y, HCDT z)\r
++{\r
++ mglData *nums=0;\r
++ long n = x->GetNN(), m;\r
++ if(y->GetNN()!=n || z->GetNN()!=n) return nums;\r
++ mglPoint *pp = new mglPoint[n];\r
++ long *nn=0;\r
++ for(long i=0;i<n;i++) pp[i].Set(x->v(i), y->v(i), z->v(i));\r
++ m = mgl_crust(n,pp,&nn,0);\r
++\r
++ if(m>0)\r
++ {\r
++ nums=new mglData(3,m);\r
++ for(long i=0;i<3*m;i++) nums->a[i]=nn[i];\r
++ }\r
++ delete []pp; free(nn); return nums;\r
++}\r
++//-----------------------------------------------------------------------------\r
++#include "s_hull/s_hull_pro.h"\r
++HMDT MGL_EXPORT mgl_triangulation_2d(HCDT x, HCDT y)\r
++{\r
++ mglData *nums=0;\r
++ long n = x->GetNN();\r
++ if(y->GetNN()!=n) return nums;\r
++ // use s-hull here\r
++ std::vector<Shx> pts;\r
++ Shx pt;\r
++\r
++ double x1=mglInf, x2=-mglInf, y1=mglInf, y2=-mglInf;\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mreal xx=x->vthr(i), yy = y->vthr(i);\r
++ if(xx<x1) x1=xx;\r
++ if(xx>x2) x2=xx;\r
++ if(yy<y1) y1=yy;\r
++ if(yy>y2) y2=yy;\r
++ }\r
++ const double dx=x2-x1, dy=y2-y1;\r
++ if(dx==0 || dy==0) return nums;\r
++ for(long i=0;i<n;i++) // Filter NaNs and Infs\r
++ {\r
++ pt.r = (x->vthr(i)-x1)/dx; pt.c = (y->vthr(i)-y1)/dy;\r
++ if(mgl_isbad(pt.r) || mgl_isbad(pt.c)) continue;\r
++ pt.id = i; pts.push_back(pt);\r
++ }\r
++\r
++ std::vector<Triad> triads;\r
++ static const double float_eps = std::numeric_limits<float>::epsilon();\r
++ Dupex grid_step(float_eps, float_eps);\r
++ const size_t original_size = pts.size();\r
++\r
++ if(pts.size() >= 3u && 0. < grid_step.r && 0. < grid_step.c) {\r
++ std::vector<long> out;\r
++ de_duplicate(pts, out, grid_step);\r
++\r
++ if (pts.size() >= 3u && s_hull_pro(pts, triads) < 0) {\r
++ // Error occured. It may be caused by degenerated dataset. Well, let's try to increment rounding grid step.\r
++ // Why 4? Why not. There are no particular reasons for this.\r
++ grid_step.r *= 4.;\r
++ grid_step.c *= 4.;\r
++\r
++ out.clear();\r
++ triads.clear();\r
++\r
++ de_duplicate(pts, out, grid_step);\r
++\r
++ if (pts.size() >= 3u && s_hull_pro(pts, triads) < 0) {\r
++ // Last try. Let's assume uniform points distribution and use range / sqrt(pts.size()) * 2 as epsilon.\r
++ // It removes a 3/4 of points in optimal case but in the worst case it merges all points to the one.\r
++ const double density = 1. + floor(0.5 + std::sqrt(static_cast<double>(pts.size())));\r
++ grid_step.r = grid_step.c = 2/density;\r
++\r
++ out.clear();\r
++ de_duplicate(pts, out, grid_step);\r
++\r
++ triads.clear();\r
++ s_hull_pro(pts, triads);\r
++ }\r
++ }\r
++ }\r
++\r
++ if (triads.empty()) {\r
++ mgl_set_global_warn(_("Cannot triangulate this set!"));\r
++ } else if(original_size > pts.size()) {\r
++ mgl_set_global_warn(_("There are duplicated or indistinguishably adjacent points for triangulation."));\r
++ }\r
++\r
++ long m = triads.size();\r
++ nums=new mglData(3,m);\r
++ for(long i=0;i<m;i++)\r
++ {\r
++ nums->a[3*i] = triads[i].a;\r
++ nums->a[3*i+1] = triads[i].b;\r
++ nums->a[3*i+2] = triads[i].c;\r
++ }\r
++ return nums;\r
++}\r
++//-----------------------------------------------------------------------------\r
++uintptr_t MGL_EXPORT mgl_triangulation_3d_(uintptr_t *x, uintptr_t *y, uintptr_t *z)\r
++{ return uintptr_t(mgl_triangulation_3d(_DA_(x),_DA_(y),_DA_(z))); }\r
++uintptr_t MGL_EXPORT mgl_triangulation_2d_(uintptr_t *x, uintptr_t *y)\r
++{ return uintptr_t(mgl_triangulation_2d(_DA_(x),_DA_(y))); }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// DataGrid\r
++//\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_grid_t(void *par)\r
++{\r
++ mglThreadD *t=(mglThreadD *)par;\r
++ long nx=t->p[0],ny=t->p[1];\r
++ mreal *b=t->a;\r
++ const mreal *x=t->b, *y=t->c, *d=t->d;\r
++ HCDT zdat = (HCDT) t->v;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i0=t->id;i0<t->n;i0+=mglNumThr) if(d[3*i0]>=0 && d[3*i0+1]>=0 && d[3*i0+2]>=0)\r
++ {\r
++ long k1 = long(d[3*i0]+0.5), k2 = long(d[3*i0+1]+0.5), k3 = long(d[3*i0+2]+0.5);\r
++ mreal dxu,dxv,dyu,dyv;\r
++ mreal z1=zdat->vthr(k1), z2=zdat->vthr(k2), z3=zdat->vthr(k3);\r
++ mglPoint d1(x[k2]-x[k1],y[k2]-y[k1],z2-z1), d2(x[k3]-x[k1],y[k3]-y[k1],z3-z1), p;\r
++\r
++ dxu = d2.x*d1.y - d1.x*d2.y;\r
++ if(fabs(dxu)<1e-5) continue; // points lies on the same line\r
++ dyv =-d1.x/dxu; dxv = d1.y/dxu;\r
++ dyu = d2.x/dxu; dxu =-d2.y/dxu;\r
++\r
++ long x1,y1,x2,y2;\r
++ x1 = long(mgl_min(mgl_min(x[k1],x[k2]),x[k3])); // bounding box\r
++ y1 = long(mgl_min(mgl_min(y[k1],y[k2]),y[k3]));\r
++ x2 = long(mgl_max(mgl_max(x[k1],x[k2]),x[k3]));\r
++ y2 = long(mgl_max(mgl_max(y[k1],y[k2]),y[k3]));\r
++ x1 = x1>0 ? x1:0; x2 = x2<nx ? x2:nx-1;\r
++ y1 = y1>0 ? y1:0; y2 = y2<ny ? y2:ny-1;\r
++ if((x1>x2) | (y1>y2)) continue;\r
++\r
++ mreal x0 = x[k1], y0 = y[k1];\r
++ for(long i=x1;i<=x2;i++) for(long j=y1;j<=y2;j++)\r
++ {\r
++ mreal xx = (i-x0), yy = (j-y0);\r
++ mreal u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy;\r
++ if((u<0) | (v<0) | (u+v>1)) continue;\r
++ b[i+nx*j] = z1 + d1.z*u + d2.z*v;\r
++ }\r
++ }\r
++ return 0;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_grid_xy(HMDT d, HCDT xdat, HCDT ydat, HCDT zdat, mreal x1, mreal x2, mreal y1, mreal y2)\r
++{ // NOTE: only for mglData\r
++ const mglData *x = dynamic_cast<const mglData *>(xdat);\r
++ const mglData *y = dynamic_cast<const mglData *>(ydat);\r
++ long n=xdat->GetNN();\r
++ if((n<3) || (ydat->GetNN()!=n) || (zdat->GetNN()!=n)) return;\r
++\r
++ mglData *nums = mgl_triangulation_2d(xdat,ydat);\r
++ if(nums->nx<3) { delete nums; return; }\r
++ long nn = nums->ny, par[3]={d->nx,d->ny,d->nz};\r
++ mreal xx[4]={x1,(d->nx-1)/(x2-x1), y1,(d->ny-1)/(y2-y1)};\r
++\r
++ mreal *xc=new mreal[n], *yc=new mreal[n];\r
++ if(x && y)\r
++#pragma omp parallel for\r
++ for(long i=0;i<n;i++)\r
++ { xc[i]=xx[1]*(x->a[i]-xx[0]); yc[i]=xx[3]*(y->a[i]-xx[2]); }\r
++ else\r
++#pragma omp parallel for\r
++ for(long i=0;i<n;i++)\r
++ { xc[i]=xx[1]*(xdat->vthr(i)-xx[0]); yc[i]=xx[3]*(ydat->vthr(i)-xx[2]); }\r
++ long tmp = d->nx*d->ny*d->nz;\r
++#pragma omp parallel for\r
++ for(long i=0;i<tmp;i++) d->a[i] = NAN;\r
++\r
++ mglStartThread(mgl_grid_t,0,nn,d->a,xc,yc,par,zdat,nums->a);\r
++ delete nums; delete []xc; delete []yc;\r
++}\r
++void MGL_EXPORT mgl_data_grid_xy_(uintptr_t *d, uintptr_t *x, uintptr_t *y, uintptr_t *z, mreal *x1, mreal *x2, mreal *y1, mreal *y2)\r
++{ mgl_data_grid_xy(_DT_,_DA_(x),_DA_(y),_DA_(z),*x1,*x2,*y1,*y2); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_grid(HMGL gr, HMDT d, HCDT xdat, HCDT ydat, HCDT zdat, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mgl_data_grid_xy(d,xdat,ydat,zdat,gr->Min.x,gr->Max.x,gr->Min.y,gr->Max.y);\r
++ gr->LoadState();\r
++}\r
++void MGL_EXPORT mgl_data_grid_(uintptr_t *gr, uintptr_t *d, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *opt,int lo)\r
++{ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_data_grid(_GR_,_DT_,_DA_(x),_DA_(y),_DA_(z),o); delete []o; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Crust series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_crust(HMGL gr, HCDT x, HCDT y, HCDT z, const char *sch, const char *opt)\r
++{\r
++ if(y->GetNN()!=x->GetNN() || z->GetNN()!=x->GetNN())\r
++ { gr->SetWarn(mglWarnDim,"Crust"); return; }\r
++ HMDT nums = mgl_triangulation_3d(x, y, z);\r
++ mgl_triplot_xyzc(gr,nums,x,y,z,z,sch,opt);\r
++ mgl_delete_data(nums);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_crust_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_crust(_GR_, _DA_(x),_DA_(y),_DA_(z),s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++long MGL_NO_EXPORT mgl_insert_trig(long i1,long i2,long i3,long **n)\r
++{\r
++ static long Cur=0,Max=0;\r
++ if(i1<0 || i2<0 || i3<0) return Cur;\r
++ if(*n==0)\r
++ {\r
++ Max = 1024; Cur = 0;\r
++ *n = (long *)malloc(Max*3*sizeof(long));\r
++ memset(*n,0,Max*3*sizeof(long));\r
++ }\r
++ if(Cur>=Max)\r
++ {\r
++ Max += 1024;\r
++ *n = (long *)realloc(*n,Max*3*sizeof(long));\r
++ memset(*n+3*(Max-1024),0,3*1024*sizeof(long));\r
++ }\r
++ long *nn;\r
++ if(i1>i3) { long k1=i1; i1=i3; i3=k1; } // simple sorting\r
++ if(i1>i2) { long k1=i1; i1=i2; i2=k1; }\r
++ if(i2>i3) { long k1=i2; i2=i3; i3=k1; }\r
++ for(long i=0;i<Cur;i++) // check if it is unique\r
++ {\r
++ nn = *n + 3*i;\r
++ if(nn[0]==i1 && nn[1]==i2 && nn[2]==i3) return Cur;\r
++ }\r
++ nn = *n + 3*Cur;\r
++ nn[0]=i1; nn[1]=i2; nn[2]=i3;\r
++ Cur++; return Cur;\r
++}\r
++//-----------------------------------------------------------------------------\r
++long MGL_NO_EXPORT mgl_get_next(long k1,long n,long *,long *set,mglPoint *qq)\r
++{\r
++ long i,j=-1;\r
++ mreal r,rm=FLT_MAX;\r
++ for(i=0;i<n;i++)\r
++ {\r
++ if(i==k1 || set[i]>0) continue;\r
++ r = mgl_anorm(qq[i]-qq[k1]);\r
++ if(r<rm) { rm=r; j=i; }\r
++ }\r
++ return j;\r
++}\r
++//-----------------------------------------------------------------------------\r
++long MGL_NO_EXPORT mgl_crust(long n,mglPoint *pp,long **nn,mreal ff)\r
++{ // TODO: update to normal algorithm\r
++ mreal rs=0;\r
++ if(ff<=0) ff=2;\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mreal rm = FLT_MAX;\r
++ for(long j=0;j<n;j++)\r
++ {\r
++ if(i==j) continue;\r
++ mreal r = mgl_anorm(pp[i]-pp[j]);\r
++ if(rm>r) rm = r;\r
++ }\r
++ rs += sqrt(rm);\r
++ }\r
++ rs *= ff/n; rs = rs*rs; // "average" distance\r
++ const int nnum=100;\r
++<<<<<<< HEAD\r
++ long *ind, *set, ii; // indexes of "close" points, flag that it was added and its number\r
++=======\r
++ long *ind, *set; // indexes of "close" points, flag that it was added and its number\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ mglPoint *qq; // normalized point coordinates\r
++ ind = new long[nnum]; set = new long[nnum]; qq = new mglPoint[nnum];\r
++ long k1,k2,k3,m=0;\r
++ for(long i=0;i<n;i++) // now the triangles will be found\r
++ {\r
++ memset(set,0,nnum*sizeof(long));\r
++<<<<<<< HEAD\r
++ for(ii=0,j=0;j<n;j++) // find close vertexes\r
++=======\r
++ long ii=0;\r
++ for(long j=0;j<n;j++) // find close vertexes\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ {\r
++ mreal r = mgl_anorm(pp[i]-pp[j]);\r
++ if(r<=rs && j!=i) { ind[ii] = j; ii++; if(ii==99) break;}\r
++ }\r
++ if(ii<3) continue; // nothing to do\r
++ for(long j=0;j<ii;j++)\r
++ {\r
++ k1 = j; k2 = ind[j]; k3 = i;\r
++ qq[k1] = pp[k2] - pp[k3];\r
++ qq[k1] /= qq[k1].norm();\r
++ }\r
++ k1 = 0;\r
++ while((k2=mgl_get_next(k1,ii,ind,set,qq))>0)\r
++ {\r
++ set[k1]=1;\r
++ mgl_insert_trig(i,ind[k1],ind[k2],nn);\r
++ k1 = k2;\r
++ }\r
++ m = mgl_insert_trig(i,ind[k1],ind[0],nn);\r
++ }\r
++ delete []set; delete []ind; delete []qq; return m;\r
++}\r
++//-----------------------------------------------------------------------------\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * data_io.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include <ctype.h>\r
++\r
++#ifndef WIN32\r
++#include <glob.h>\r
++#endif\r
++\r
++#include "mgl2/data.h"\r
++#include "mgl2/datac.h"\r
++#include "mgl2/eval.h"\r
++#include "mgl2/thread.h"\r
++\r
++#if MGL_HAVE_HDF5\r
++//#define H5_NO_DEPRECATED_SYMBOLS\r
++#define H5_USE_16_API\r
++#include <hdf5.h>\r
++#endif\r
++#if MGL_HAVE_HDF4\r
++#define intf hdf4_intf\r
++#include <hdf/mfhdf.h>\r
++#undef intf\r
++#endif\r
++\r
++inline bool isn(char ch) {return ch=='\n';}\r
++HMDT MGL_NO_EXPORT mglFormulaCalc(const char *str, const std::vector<mglDataA*> &head);\r
++//-----------------------------------------------------------------------------\r
++HMDT MGL_EXPORT mgl_create_data() { return new mglData; }\r
++HMDT MGL_EXPORT mgl_create_data_size(long nx, long ny, long nz){ return new mglData(nx,ny,nz); }\r
++HMDT MGL_EXPORT mgl_create_data_file(const char *fname) { return new mglData(fname); }\r
++void MGL_EXPORT mgl_delete_data(HMDT d) { if(d) delete d; }\r
++//-----------------------------------------------------------------------------\r
++uintptr_t MGL_EXPORT mgl_create_data_()\r
++{ return uintptr_t(new mglData()); }\r
++uintptr_t MGL_EXPORT mgl_create_data_size_(int *nx, int *ny, int *nz)\r
++{ return uintptr_t(new mglData(*nx,*ny,*nz)); }\r
++uintptr_t MGL_EXPORT mgl_create_data_file_(const char *fname,int l)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ uintptr_t r = uintptr_t(new mglData(s)); delete []s; return r; }\r
++void MGL_EXPORT mgl_delete_data_(uintptr_t *d)\r
++{ if(_DT_) delete _DT_; }\r
++//-----------------------------------------------------------------------------\r
++void mglFromStr(HMDT d,char *buf,long NX,long NY,long NZ)\r
++{\r
++ if(NX<1 || NY <1 || NZ<1) return;\r
++ mgl_data_create(d, NX,NY,NZ);\r
++ const std::string loc = setlocale(LC_NUMERIC, "C");\r
++ std::vector<char *> lines;\r
++ std::vector<std::vector<mreal> > numbs;\r
++ lines.push_back(buf);\r
++ for(char *s=buf; *s; s++) if(isn(*s))\r
++ { lines.push_back(s+1); *s = 0; s++; }\r
++ numbs.resize(lines.size());\r
++ long nl = long(lines.size());\r
++#pragma omp parallel for\r
++ for(long k=0;k<nl;k++)\r
++ {\r
++ char *b = lines[k];\r
++ long nb = strlen(b);\r
++ for(long j=0;j<nb;j++)\r
++ {\r
++ while(j<nb && b[j]<=' ') j++; // skip first spaces\r
++ if(j>=nb) break;\r
++ if(b[j]=='#')\r
++ {\r
++ if(j<nb-1 && b[j+1]=='#') for(long i=j+2;i<nb;i++)\r
++ if(b[i]>='a' && b[i]<='z') d->id.push_back(b[i]);\r
++ break;\r
++ }\r
++ const char *s=b+j;\r
++ while(j<nb && b[j]>' ' && b[j]!=',' && b[j]!=';') j++;\r
++ b[j]=0;\r
++ numbs[k].push_back(strstr(s,"NAN")?NAN:atof(s));\r
++ }\r
++ }\r
++ long i=0, n=NX*NY*NZ;\r
++ for(long k=0;k<nl && i<n;k++)\r
++ {\r
++ const std::vector<mreal> &vals = numbs[k];\r
++ long c = vals.size();\r
++ if(c>n-i) c = n-i;\r
++ memcpy(d->a+i,&(vals[0]),c*sizeof(mreal));\r
++ i += c;\r
++ }\r
++ setlocale(LC_NUMERIC, loc.c_str());\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set(HMDT d, HCDT a)\r
++{\r
++ if(!a) return;\r
++// d->temp = a->temp; d->s = a->s; d->func = a->func; d->o = a->o;\r
++\r
++ mgl_data_create(d, a->GetNx(), a->GetNy(), a->GetNz());\r
++ const mglData *dd = dynamic_cast<const mglData *>(a); // faster for mglData\r
++ if(dd) // this one should be much faster\r
++ memcpy(d->a, dd->a, d->nx*d->ny*d->nz*sizeof(mreal));\r
++ else // very inefficient!!!\r
++#pragma omp parallel for collapse(3)\r
++ for(long k=0;k<d->nz;k++) for(long j=0;j<d->ny;j++) for(long i=0;i<d->nx;i++)\r
++ d->a[i+d->nx*(j+d->ny*k)] = a->v(i,j,k);\r
++}\r
++void MGL_EXPORT mgl_data_set_(uintptr_t *d, uintptr_t *a) { mgl_data_set(_DT_,_DA_(a)); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set_values(HMDT d, const char *v,long NX,long NY,long NZ)\r
++{\r
++ if(NX<1 || NY <1 || NZ<1) return;\r
++ long n=strlen(v)+1;\r
++ char *buf = new char[n];\r
++ memcpy(buf,v,n);\r
++ mglFromStr(d,buf,NX,NY,NZ);\r
++ delete []buf;\r
++}\r
++void MGL_EXPORT mgl_data_set_values_(uintptr_t *d, const char *val, int *nx, int *ny, int *nz, int l)\r
++{ char *s=new char[l+1]; memcpy(s,val,l); s[l]=0;\r
++ mgl_data_set_values(_DT_,s,*nx,*ny,*nz); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set_vector(HMDT d, gsl_vector *v)\r
++{\r
++#if MGL_HAVE_GSL\r
++ if(!v || v->size<1) return;\r
++ mgl_data_create(d, v->size,1,1);\r
++#pragma omp parallel for\r
++ for(long i=0;i<d->nx;i++) d->a[i] = v->data[i*v->stride];\r
++#endif\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set_matrix(HMDT d, gsl_matrix *m)\r
++{\r
++#if MGL_HAVE_GSL\r
++ if(!m || m->size1<1 || m->size2<1) return;\r
++ mgl_data_create(d, m->size1,m->size2,1);\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<d->ny;j++) for(long i=0;i<d->nx;i++)\r
++ d->a[i+j*d->nx] = m->data[i * m->tda + j];\r
++#endif\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set_float(HMDT d, const float *A,long NX,long NY,long NZ)\r
++{\r
++ if(NX<=0 || NY<=0 || NZ<=0) return;\r
++ mgl_data_create(d, NX,NY,NZ); if(!A) return;\r
++#if MGL_USE_DOUBLE\r
++#pragma omp parallel for\r
++ for(long i=0;i<NX*NY*NZ;i++) d->a[i] = A[i];\r
++#else\r
++ memcpy(d->a,A,NX*NY*NZ*sizeof(float));\r
++#endif\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set_double(HMDT d, const double *A,long NX,long NY,long NZ)\r
++{\r
++ if(NX<=0 || NY<=0 || NZ<=0) return;\r
++ mgl_data_create(d, NX,NY,NZ); if(!A) return;\r
++#if MGL_USE_DOUBLE\r
++ memcpy(d->a,A,NX*NY*NZ*sizeof(double));\r
++#else\r
++#pragma omp parallel for\r
++ for(long i=0;i<NX*NY*NZ;i++) d->a[i] = A[i];\r
++#endif\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set_float2(HMDT d, float const * const *A,long N1,long N2)\r
++{\r
++ if(N1<=0 || N2<=0) return;\r
++ mgl_data_create(d, N2,N1,1); if(!A) return;\r
++#if MGL_USE_DOUBLE\r
++#pragma omp parallel for collapse(2)\r
++ for(long i=0;i<N1;i++) for(long j=0;j<N2;j++) d->a[j+i*N2] = A[i][j];\r
++#else\r
++#pragma omp parallel for\r
++ for(long i=0;i<N1;i++) memcpy(d->a+i*N2,A[i],N2*sizeof(float));\r
++#endif\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set_double2(HMDT d, double const *const *A,long N1,long N2)\r
++{\r
++ if(N1<=0 || N2<=0) return;\r
++ mgl_data_create(d, N2,N1,1); if(!A) return;\r
++#if MGL_USE_DOUBLE\r
++#pragma omp parallel for\r
++ for(long i=0;i<N1;i++) memcpy(d->a+i*N2,A[i],N2*sizeof(double));\r
++#else\r
++#pragma omp parallel for collapse(2)\r
++ for(long i=0;i<N1;i++) for(long j=0;j<N2;j++) d->a[j+i*N2] = A[i][j];\r
++#endif\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set_float3(HMDT d, float const * const * const *A,long N1,long N2,long N3)\r
++{\r
++ if(N1<=0 || N2<=0 || N3<=0) return;\r
++ mgl_data_create(d, N3,N2,N1); if(!A) return;\r
++#if MGL_USE_DOUBLE\r
++#pragma omp parallel for collapse(3)\r
++ for(long i=0;i<N1;i++) for(long j=0;j<N2;j++) for(long k=0;k<N3;k++)\r
++ d->a[k+N3*(j+i*N2)] = A[i][j][k];\r
++#else\r
++#pragma omp parallel for collapse(2)\r
++ for(long i=0;i<N1;i++) for(long j=0;j<N2;j++)\r
++ memcpy(d->a+N3*(j+i*N2),A[i][j],N3*sizeof(float));\r
++#endif\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set_double3(HMDT d, double const * const * const *A,long N1,long N2,long N3)\r
++{\r
++ if(N1<=0 || N2<=0 || N3<=0) return;\r
++ mgl_data_create(d, N3,N2,N1); if(!A) return;\r
++#if MGL_USE_DOUBLE\r
++#pragma omp parallel for collapse(2)\r
++ for(long i=0;i<N1;i++) for(long j=0;j<N2;j++)\r
++ memcpy(d->a+N3*(j+i*N2),A[i][j],N3*sizeof(double));\r
++#else\r
++#pragma omp parallel for collapse(3)\r
++ for(long i=0;i<N1;i++) for(long j=0;j<N2;j++) for(long k=0;k<N3;k++)\r
++ d->a[k+N3*(j+i*N2)] = A[i][j][k];\r
++#endif\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set_float1_(uintptr_t *d, const float *A,int *NX)\r
++{ mgl_data_set_float(_DT_,A,*NX,1,1); }\r
++void MGL_EXPORT mgl_data_set_double1_(uintptr_t *d, const double *A,int *NX)\r
++{ mgl_data_set_double(_DT_,A,*NX,1,1); }\r
++void MGL_EXPORT mgl_data_set_float_(uintptr_t *d, const float *A,int *NX,int *NY,int *NZ)\r
++{ mgl_data_set_float(_DT_,A,*NX,*NY,*NZ); }\r
++void MGL_EXPORT mgl_data_set_double_(uintptr_t *d, const double *A,int *NX,int *NY,int *NZ)\r
++{ mgl_data_set_double(_DT_,A,*NX,*NY,*NZ); }\r
++void MGL_EXPORT mgl_data_set_float2_(uintptr_t *d, const float *A,int *N1,int *N2)\r
++{ mgl_data_set_float(_DT_,A,*N1,*N2,1); }\r
++void MGL_EXPORT mgl_data_set_double2_(uintptr_t *d, const double *A,int *N1,int *N2)\r
++{ mgl_data_set_double(_DT_,A,*N1,*N2,1); }\r
++void MGL_EXPORT mgl_data_set_float3_(uintptr_t *d, const float *A,int *N1,int *N2,int *N3)\r
++{ mgl_data_set_float(_DT_,A,*N1,*N2,*N3); }\r
++void MGL_EXPORT mgl_data_set_double3_(uintptr_t *d, const double *A,int *N1,int *N2,int *N3)\r
++{ mgl_data_set_double(_DT_,A,*N1,*N2,*N3); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_rearrange(HMDT d, long mx,long my,long mz)\r
++{\r
++ if(mx<1) return; // wrong mx\r
++ if(my<1) { my = d->nx*d->ny*d->nz/mx; mz = 1; }\r
++ else if(mz<1) mz = (d->nx*d->ny*d->nz)/(mx*my);\r
++ long m = mx*my*mz;\r
++ if(m==0 || m>d->nx*d->ny*d->nz) return; // too high desired dimensions\r
++ d->nx = mx; d->ny = my; d->nz = mz; d->NewId();\r
++}\r
++void MGL_EXPORT mgl_data_rearrange_(uintptr_t *d, int *mx, int *my, int *mz)\r
++{ mgl_data_rearrange(_DT_,*mx,*my,*mz); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set_id(HMDT d, const char *ids) { d->id = ids; }\r
++void MGL_EXPORT mgl_data_set_id_(uintptr_t *d, const char *eq,int l)\r
++{ char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0;\r
++ mgl_data_set_id(_DT_, s); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_set_name_w(mglDataA *dat, const wchar_t *name)\r
++{ dat->s = name; }\r
++void MGL_EXPORT mgl_data_set_name(mglDataA *dat, const char *name)\r
++{ MGL_TO_WCS(name,dat->s = wcs); }\r
++void MGL_EXPORT mgl_data_set_name_(uintptr_t *d, const char *name,int l)\r
++{ char *s=new char[l+1]; memcpy(s,name,l); s[l]=0;\r
++ mgl_data_set_name(_DT_,s); delete []s; }\r
++void MGL_EXPORT mgl_data_set_func(mglDataA *dat, void (*func)(void *), void *par)\r
++{ dat->func = func; dat->o = par; }\r
++//-----------------------------------------------------------------------------\r
++/// Get section separated by symbol ch. This is analog of QString::section().\r
++std::vector<std::string> MGL_EXPORT mgl_str_args(const std::string &str, char ch)\r
++{\r
++ std::vector<size_t> pos; pos.push_back(0);\r
++ for(size_t p=0; p != std::string::npos;)\r
++ { p=str.find(ch,p+1); pos.push_back(p?p+1:0); }\r
++ std::vector<std::string> res;\r
++ for(size_t i=0;i<pos.size()-1;i++)\r
++ res.push_back(str.substr(pos[i],pos[i+1]-pos[i]-1));\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++/// Get section separated by symbol ch. This is analog of QString::section().\r
++std::string MGL_EXPORT mgl_str_arg(const std::string &str, char ch, int n1, int n2)\r
++{\r
++ std::vector<size_t> pos; pos.push_back(0);\r
++ for(size_t p=0; p != std::string::npos;)\r
++ { p=str.find(ch,p+1); pos.push_back(p?p+1:0); }\r
++ std::string res;\r
++ if(n2<0) n2=n1;\r
++ if(n1<0 || n1>=pos.size()-1 || n2<n1) return res;\r
++ if(n2>=pos.size()) n2=pos.size()-1;\r
++ res = str.substr(pos[n1],pos[n2+1]-pos[n1]-1);\r
++ if(res.size()==1 && res[0]==ch) res.clear();\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++/// Get string from number.\r
++std::string MGL_EXPORT mgl_str_num(double val)\r
++{ char buf[32]; snprintf(buf,32,"%g",val); return std::string(buf); }\r
++std::string MGL_EXPORT mgl_str_num(dual val)\r
++{\r
++ char buf[64];\r
++ double re = real(val), im = imag(val);\r
++ if(re==0 && im>0) snprintf(buf,64,"i%g",im);\r
++ else if(re && im<0) snprintf(buf,64,"-i%g",-im);\r
++ else if(im>0) snprintf(buf,64,"%g+i%g",re,im);\r
++ else if(im<0) snprintf(buf,64,"%g-i%g",re,-im);\r
++ else snprintf(buf,64,"%g",re);\r
++ return std::string(buf);\r
++}\r
++//-----------------------------------------------------------------------------\r
++std::string MGL_EXPORT mgl_data_to_string(HCDT d, long ns)\r
++{\r
++ long nx=d->GetNx(), ny=d->GetNy(), nz=d->GetNz();\r
++ const std::string loc = setlocale(LC_NUMERIC, "C");\r
++ std::string out;\r
++ if(ns<0 || (ns>=nz && nz>1)) for(long k=0;k<nz;k++)\r
++ { // save whole data\r
++ const mglData *dr = dynamic_cast<const mglData *>(d);\r
++ if(dr && !dr->id.empty()) out += "## "+dr->id+'\n';\r
++ for(long i=0;i<ny;i++)\r
++ {\r
++ for(long j=0;j<nx-1;j++) out += mgl_str_num(d->v(j,i,k))+'\t';\r
++ out += mgl_str_num(d->v(nx-1,i,k))+'\n';\r
++ }\r
++ out += "\n";\r
++ }\r
++ else\r
++ { // save selected slice\r
++ if(nz>1) for(long i=0;i<ny;i++)\r
++ {\r
++ for(long j=0;j<nx-1;j++) out += mgl_str_num(d->v(j,i,ns))+'\t';\r
++ out += mgl_str_num(d->v(nx-1,i,ns))+'\n';\r
++ }\r
++ else if(ns<ny) for(long j=0;j<nx;j++) out += mgl_str_num(d->v(j,ns))+'\t';\r
++ }\r
++ setlocale(LC_NUMERIC, loc.c_str());\r
++ return out;\r
++}\r
++void MGL_EXPORT mgl_data_save(HCDT d, const char *fname,long ns)\r
++{\r
++ FILE *fp = fopen(fname,"w");\r
++ if(fp) { fprintf(fp,"%s",mgl_data_to_string(d,ns).c_str()); fclose(fp); }\r
++}\r
++void MGL_EXPORT mgl_data_save_(uintptr_t *d, const char *fname,int *ns,int l)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ mgl_data_save(_DT_,s,*ns); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT char *mgl_read_gz(gzFile fp)\r
++{\r
++ long size=1024,n=0,m;\r
++ char *buf=(char*)malloc(size);\r
++ while((m=gzread(fp,buf+size*n,size))>0)\r
++ {\r
++ if(m<size) { buf[size*n+m]=0; break; }\r
++ n++; buf=(char*)realloc(buf,size*(n+1));\r
++ memset(buf+size*n,0,size);\r
++ }\r
++ return buf;\r
++}\r
++//-----------------------------------------------------------------------------\r
++int MGL_EXPORT mgl_data_read(HMDT d, const char *fname)\r
++{\r
++ long l=1,m=1,k=1,i;\r
++ gzFile fp = gzopen(fname,"r");\r
++ if(!fp)\r
++ {\r
++ if(!d->a) mgl_data_create(d, 1,1,1);\r
++ return 0;\r
++ }\r
++ char *buf = mgl_read_gz(fp);\r
++ long nb = strlen(buf); gzclose(fp);\r
++\r
++ bool first=false;\r
++ for(i=nb-1;i>=0;i--) if(buf[i]>' ') break;\r
++ buf[i+1]=0; nb = i+1; // remove tailing spaces\r
++ for(i=0;i<nb-1 && !isn(buf[i]);i++) // determine nx\r
++ {\r
++ while(buf[i]=='#') { while(!isn(buf[i]) && i<nb) i++; }\r
++ char ch = buf[i];\r
++ if(ch>' ' && !first) first=true;\r
++ if(first && (ch==' ' || ch=='\t' || ch==',' || ch==';') && buf[i+1]>' ') k++;\r
++ }\r
++ first = false;\r
++ for(i=0;i<nb-1;i++) // determine ny\r
++ {\r
++ char ch = buf[i];\r
++ if(ch=='#') while(!isn(buf[i]) && i<nb) i++;\r
++ if(isn(ch))\r
++ {\r
++ while(buf[i+1]==' ' || buf[i+1]=='\t') i++;\r
++ if(isn(buf[i+1])) {first=true; break; }\r
++ m++;\r
++ }\r
++ if(ch=='\f') break;\r
++ }\r
++ if(first) for(i=0;i<nb-1;i++) // determine nz\r
++ {\r
++ char ch = buf[i];\r
++ if(ch=='#') while(!isn(buf[i]) && i<nb) i++;\r
++ if(isn(ch))\r
++ {\r
++ while(buf[i+1]==' ' || buf[i+1]=='\t') i++;\r
++ if(isn(buf[i+1])) l++;\r
++ }\r
++ }\r
++ else for(i=0;i<nb-1;i++) if(buf[i]=='\f') l++;\r
++ mglFromStr(d,buf,k,m,l);\r
++ free(buf); return 1;\r
++}\r
++int MGL_EXPORT mgl_data_read_(uintptr_t *d, const char *fname,int l)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ int r = mgl_data_read(_DT_, s); delete []s; return r; }\r
++//-----------------------------------------------------------------------------\r
++int MGL_EXPORT mgl_data_scan_file(HMDT d,const char *fname, const char *templ)\r
++{\r
++ // first scan for all "%g"\r
++ char *buf=new char[strlen(templ)+1],*s=buf;\r
++ strcpy(buf,templ);\r
++ std::vector<std::string> strs;\r
++ for(size_t i=0;buf[i];i++)\r
++ {\r
++ if(buf[i]=='%' && buf[i+1]=='%') i++;\r
++ else if(buf[i]=='%' && buf[i+1]=='g')\r
++ { buf[i]=0; strs.push_back(s); s = buf+i+2; }\r
++ }\r
++ delete []buf;\r
++ if(strs.size()<1) return 0;\r
++ // read proper lines from file\r
++ std::vector<const char *> bufs;\r
++ gzFile fp = gzopen(fname,"r");\r
++ if(!fp)\r
++ {\r
++ if(!d->a) mgl_data_create(d, 1,1,1);\r
++ return 0;\r
++ }\r
++ s = mgl_read_gz(fp); gzclose(fp);\r
++ size_t len = strs[0].length();\r
++ const char *s0 = strs[0].c_str();\r
++ if(!strncmp(s, s0, len)) bufs.push_back(s);\r
++ for(long i=0;s[i];i++) if(s[i]=='\n')\r
++ {\r
++ while(s[i+1]=='\n') i++;\r
++ s[i]=0; i++;\r
++ if(!strncmp(s+i, s0, len)) bufs.push_back(s+i);\r
++ if(!s[i]) break;\r
++ }\r
++ // parse lines and collect data\r
++ size_t nx=strs.size(), ny=bufs.size();\r
++ if(ny<1)\r
++ {\r
++ if(!d->a) mgl_data_create(d, 1,1,1);\r
++ return 0;\r
++ }\r
++ d->Create(nx,ny);\r
++ for(size_t j=0;j<ny;j++)\r
++ {\r
++ const char *c = bufs[j];\r
++ for(size_t i=0;i<nx;i++)\r
++ {\r
++ const char *p = strstr(c,strs[i].c_str());\r
++ if(!p) break;\r
++ p += strs[i].length(); c=p;\r
++ d->a[i+nx*j] = atof(p);\r
++ }\r
++ }\r
++ free(s); return 1;\r
++}\r
++int MGL_EXPORT mgl_data_scan_file_(uintptr_t *d,const char *fname, const char *templ,int l,int m)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ char *t=new char[m+1]; memcpy(t,templ,m); t[m]=0;\r
++ int r = mgl_data_scan_file(_DT_, s,t); delete []s; delete []t; return r; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_create(HMDT d,long mx,long my,long mz)\r
++{\r
++ d->nx = mx>0 ? mx:1; d->ny = my>0 ? my:1; d->nz = mz>0 ? mz:1;\r
++ if(d->a && !d->link) delete [](d->a);\r
++ d->a = new mreal[d->nx*d->ny*d->nz];\r
++ d->id.clear(); d->link=false;\r
++ memset(d->a,0,d->nx*d->ny*d->nz*sizeof(mreal));\r
++}\r
++void MGL_EXPORT mgl_data_create_(uintptr_t *d, int *nx,int *ny,int *nz)\r
++{ mgl_data_create(_DT_,*nx,*ny,*nz); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_link(HMDT d, mreal *A, long mx,long my,long mz)\r
++{\r
++ if(!A) return;\r
++ if(!d->link && d->a) delete [](d->a);\r
++ d->nx = mx>0 ? mx:1; d->ny = my>0 ? my:1; d->nz = mz>0 ? mz:1;\r
++ d->link=true; d->a=A; d->NewId();\r
++}\r
++void MGL_EXPORT mgl_data_link_(uintptr_t *d, mreal *A, int *nx,int *ny,int *nz)\r
++{ mgl_data_link(_DT_,A,*nx,*ny,*nz); }\r
++//-----------------------------------------------------------------------------\r
++int MGL_EXPORT mgl_data_read_dim(HMDT d, const char *fname,long mx,long my,long mz)\r
++{\r
++ if(mx<=0 || my<=0 || mz<=0) return 0;\r
++ gzFile fp = gzopen(fname,"r");\r
++ if(!fp) return 0;\r
++ char *buf = mgl_read_gz(fp);\r
++ gzclose(fp);\r
++ mglFromStr(d,buf,mx,my,mz);\r
++ free(buf); return 1;\r
++}\r
++int MGL_EXPORT mgl_data_read_dim_(uintptr_t *d, const char *fname,int *mx,int *my,int *mz,int l)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ int r = mgl_data_read_dim(_DT_,s,*mx,*my,*mz); delete []s; return r; }\r
++//-----------------------------------------------------------------------------\r
++int MGL_EXPORT mgl_data_read_mat(HMDT d, const char *fname, long dim)\r
++{\r
++ if(dim<=0 || dim>3) return 0;\r
++ gzFile fp = gzopen(fname,"r");\r
++ if(!fp) return 0;\r
++ long nx=1, ny=1, nz=1;\r
++ char *buf = mgl_read_gz(fp);\r
++ long nb = strlen(buf); gzclose(fp);\r
++\r
++ long j=0;\r
++ if(buf[j]=='#') while(!isn(buf[j])) j++; // skip comment\r
++ while(j<nb && buf[j]<=' ') j++;\r
++ if(dim==1)\r
++ {\r
++ sscanf(buf+j,"%ld",&nx);\r
++ while(j<nb && buf[j]!='\n') j++;\r
++ j++;\r
++// while(buf[j]>' ') j++;\r
++ }\r
++ else if(dim==2)\r
++ {\r
++ sscanf(buf+j,"%ld%ld",&nx,&ny);\r
++ while(j<nb && buf[j]!='\n') j++;\r
++ j++;\r
++ char *b=buf+j;\r
++ long l=0;\r
++ for(long i=0;b[i];i++)\r
++ {\r
++ while(b[i]=='#') { while(!isn(b[i]) && b[i]) i++; }\r
++ if(b[i]=='\n') l++;\r
++ }\r
++ if(l==nx*ny || l==nx*ny+1) // try to read 3d data (i.e. columns of matrix nx*ny)\r
++ {\r
++ nz=ny; ny=nx; nx=1; l=0;\r
++ bool first = false;\r
++ for(long i=0;b[i] && !isn(b[i]);i++) // determine nx\r
++ {\r
++ while(b[i]=='#') { while(!isn(b[i]) && b[i]) i++; }\r
++ char ch = b[i];\r
++ if(ch>' ' && !first) first=true;\r
++ if(first && (ch==' ' || ch=='\t' || ch==',' || ch==';') && b[i+1]>' ') nx++;\r
++ }\r
++ }\r
++ }\r
++ else if(dim==3)\r
++ {\r
++ sscanf(buf+j,"%ld%ld%ld",&nx,&ny,&nz);\r
++ while(j<nb && buf[j]!='\n') j++;\r
++ j++;\r
++/* while(buf[j]>' ' && j<nb) j++;\r
++ while(buf[j]<=' ' && j<nb) j++;\r
++ while(buf[j]>' ' && j<nb) j++;\r
++ while(buf[j]<=' ' && j<nb) j++;\r
++ while(buf[j]>' ' && j<nb) j++;*/\r
++ }\r
++ mglFromStr(d,buf+j,nx,ny,nz);\r
++ free(buf); return 1;\r
++}\r
++int MGL_EXPORT mgl_data_read_mat_(uintptr_t *d, const char *fname,int *dim,int l)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ int r = mgl_data_read_mat(_DT_,s,*dim); delete []s; return r; }\r
++//-----------------------------------------------------------------------------\r
++mreal MGL_EXPORT mgl_data_max(HCDT d)\r
++{\r
++ mreal m1=-INFINITY;\r
++ long nn=d->GetNN();\r
++#pragma omp parallel\r
++ {\r
++ mreal m=-INFINITY;\r
++#pragma omp for nowait\r
++ for(long i=0;i<nn;i++)\r
++ { mreal v = d->vthr(i); m = m<v ? v:m; }\r
++#pragma omp critical(max_dat)\r
++ { m1 = m1>m ? m1:m; }\r
++ }\r
++ return m1;\r
++}\r
++mreal MGL_EXPORT mgl_data_max_(uintptr_t *d) { return mgl_data_max(_DT_); }\r
++//-----------------------------------------------------------------------------\r
++mreal MGL_EXPORT mgl_data_min(HCDT d)\r
++{\r
++ mreal m1=INFINITY;\r
++ long nn=d->GetNN();\r
++#pragma omp parallel\r
++ {\r
++ mreal m=INFINITY;\r
++#pragma omp for nowait\r
++ for(long i=0;i<nn;i++)\r
++ { mreal v = d->vthr(i); m = m>v ? v:m; }\r
++#pragma omp critical(min_dat)\r
++ { m1 = m1<m ? m1:m; }\r
++ }\r
++ return m1;\r
++}\r
++mreal MGL_EXPORT mgl_data_min_(uintptr_t *d) { return mgl_data_min(_DT_); }\r
++//-----------------------------------------------------------------------------\r
++mreal MGL_EXPORT mgl_data_neg_max(HCDT d)\r
++{\r
++ mreal m1=0;\r
++ long nn=d->GetNN();\r
++#pragma omp parallel\r
++ {\r
++ mreal m=0;\r
++#pragma omp for nowait\r
++ for(long i=0;i<nn;i++)\r
++ { mreal v = d->vthr(i); m = m<v && v<0 ? v:m; }\r
++#pragma omp critical(nmax_dat)\r
++ { m1 = m1>m ? m1:m; }\r
++ }\r
++ return m1;\r
++}\r
++mreal MGL_EXPORT mgl_data_neg_max_(uintptr_t *d) { return mgl_data_neg_max(_DT_); }\r
++//-----------------------------------------------------------------------------\r
++mreal MGL_EXPORT mgl_data_pos_min(HCDT d)\r
++{\r
++ mreal m1=INFINITY;\r
++ long nn=d->GetNN();\r
++#pragma omp parallel\r
++ {\r
++ mreal m=INFINITY;\r
++#pragma omp for nowait\r
++ for(long i=0;i<nn;i++)\r
++ { mreal v = d->vthr(i); m = m>v && v>0 ? v:m; }\r
++#pragma omp critical(pmin_dat)\r
++ { m1 = m1<m ? m1:m; }\r
++ }\r
++ return m1;\r
++}\r
++mreal MGL_EXPORT mgl_data_pos_min_(uintptr_t *d) { return mgl_data_pos_min(_DT_); }\r
++//-----------------------------------------------------------------------------\r
++mreal MGL_EXPORT mgl_data_max_int(HCDT d, long *i, long *j, long *k)\r
++{\r
++ mreal m1=-INFINITY;\r
++ long nx=d->GetNx(), ny=d->GetNy(), nn=d->GetNN();\r
++#pragma omp parallel\r
++ {\r
++ mreal m=-INFINITY;\r
++ long im=-1,jm=-1,km=-1;\r
++#pragma omp for nowait\r
++ for(long ii=0;ii<nn;ii++)\r
++ {\r
++ mreal v = d->vthr(ii);\r
++ if(m < v)\r
++ { m=v; im=ii%nx; jm=(ii/nx)%ny; km=ii/(nx*ny); }\r
++ }\r
++#pragma omp critical(max_int)\r
++ if(m1 < m) { m1=m; *i=im; *j=jm; *k=km; }\r
++ }\r
++ return m1;\r
++}\r
++mreal MGL_EXPORT mgl_data_max_int_(uintptr_t *d, int *i, int *j, int *k)\r
++{ long ii,jj,kk; mreal res=mgl_data_max_int(_DT_,&ii,&jj,&kk);\r
++ *i=ii; *j=jj; *k=kk; return res; }\r
++//-----------------------------------------------------------------------------\r
++mreal MGL_EXPORT mgl_data_min_int(HCDT d, long *i, long *j, long *k)\r
++{\r
++ mreal m1=INFINITY;\r
++ long nx=d->GetNx(), ny=d->GetNy(), nn=d->GetNN();\r
++#pragma omp parallel\r
++ {\r
++ mreal m=INFINITY;\r
++ long im=-1,jm=-1,km=-1;\r
++#pragma omp for nowait\r
++ for(long ii=0;ii<nn;ii++)\r
++ {\r
++ mreal v = d->vthr(ii);\r
++ if(m > v)\r
++ { m=v; im=ii%nx; jm=(ii/nx)%ny; km=ii/(nx*ny); }\r
++ }\r
++#pragma omp critical(min_int)\r
++ if(m1 > m) { m1=m; *i=im; *j=jm; *k=km; }\r
++ }\r
++ return m1;\r
++}\r
++mreal MGL_EXPORT mgl_data_min_int_(uintptr_t *d, int *i, int *j, int *k)\r
++{ long ii,jj,kk; mreal res=mgl_data_min_int(_DT_,&ii,&jj,&kk);\r
++ *i=ii; *j=jj; *k=kk; return res; }\r
++//-----------------------------------------------------------------------------\r
++long MGL_EXPORT mgl_data_max_first(HCDT d, char dir, long from, long *p1, long *p2)\r
++{\r
++ long n=d->GetNx(), n1=d->GetNy(), n2=d->GetNz(), d1=n, d2=n*n1, dd=1;\r
++ if(dir=='y') { n=n1; n1=dd=d1; d1=1; }\r
++ if(dir=='z') { n=n2; n2=n1; n1=d1; d1=1; dd=d2; d2=n2; }\r
++ bool find=false;\r
++ if(from>=0)\r
++ {\r
++ for(long i=from+1;i<n-1;i++)\r
++ {\r
++#pragma omp parallel for collapse(2)\r
++ for(long i1=0;i1<n1;i1++) for(long i2=0;i2<n2;i2++)\r
++ {\r
++ long ii=i*dd+i1*d1+i2*d2;\r
++ if(d->vthr(ii)>=d->vthr(ii+dd) && d->vthr(ii)>=d->vthr(ii-dd))\r
++ { find=true; if(p1) *p1=i1; if(p2) *p2=i2; }\r
++ }\r
++ if(find) return i;\r
++ }\r
++ }\r
++ else\r
++ {\r
++ for(long i=n+from-1;i>0;i--)\r
++ {\r
++ for(long i1=0;i1<n1;i1++) for(long i2=0;i2<n2;i2++)\r
++ {\r
++ long ii=i*dd+i1*d1+i2*d2;\r
++ if(d->vthr(ii)>=d->vthr(ii+dd) && d->vthr(ii)>=d->vthr(ii-dd))\r
++ { find=true; if(p1) *p1=i1; if(p2) *p2=i2; }\r
++ }\r
++ if(find) return i;\r
++ }\r
++ }\r
++ return -1;\r
++}\r
++long MGL_EXPORT mgl_data_max_first_(uintptr_t *d, const char *dir, long *from, long *p1, long *p2,int)\r
++{ return mgl_data_max_first(_DT_,*dir,*from,p1,p2); }\r
++//-----------------------------------------------------------------------------\r
++mreal MGL_EXPORT mgl_data_max_real(HCDT d, mreal *x, mreal *y, mreal *z)\r
++{\r
++ long im=-1,jm=-1,km=-1;\r
++ long nx=d->GetNx(), ny=d->GetNy(), nz=d->GetNz();\r
++ mreal m=mgl_data_max_int(d,&im,&jm,&km), v, v1, v2;\r
++ *x=im; *y=jm; *z=km;\r
++\r
++ v = d->v(im,jm,km);\r
++ if(nx>2)\r
++ {\r
++ if(im==0) im=1;\r
++ if(im==nx-1)im=nx-2;\r
++ v1 = d->v(im+1,jm,km); v2 = d->v(im-1,jm,km);\r
++ *x = (v1+v2-2*v)==0 ? im : im+(v1-v2)/(v1+v2-2*v)/2;\r
++ }\r
++ if(ny>2)\r
++ {\r
++ if(jm==0) jm=1;\r
++ if(jm==ny-1)jm=ny-2;\r
++ v1 = d->v(im,jm+1,km); v2 = d->v(im,jm-1,km);\r
++ *y = (v1+v2-2*v)==0 ? jm : jm+(v1-v2)/(v1+v2-2*v)/2;\r
++ }\r
++ if(nz>2)\r
++ {\r
++ if(km==0) km=1;\r
++ if(km==nz-1)km=nz-2;\r
++ v1 = d->v(im,jm,km+1); v2 = d->v(im,jm,km-1);\r
++ *z = (v1+v2-2*v)==0 ? km : km+(v1-v2)/(v1+v2-2*v)/2;\r
++ }\r
++ return m;\r
++}\r
++mreal MGL_EXPORT mgl_data_max_real_(uintptr_t *d, mreal *x, mreal *y, mreal *z)\r
++{ return mgl_data_max_real(_DT_,x,y,z); }\r
++//-----------------------------------------------------------------------------\r
++mreal MGL_EXPORT mgl_data_min_real(HCDT d, mreal *x, mreal *y, mreal *z)\r
++{\r
++ long im=-1,jm=-1,km=-1;\r
++ long nx=d->GetNx(), ny=d->GetNy(), nz=d->GetNz();\r
++ mreal m=mgl_data_min_int(d,&im,&jm,&km), v, v1, v2;\r
++ *x=im; *y=jm; *z=km;\r
++\r
++ v = d->v(im,jm,km);\r
++ if(nx>2)\r
++ {\r
++ if(im==0) im=1;\r
++ if(im==nx-1)im=nx-2;\r
++ v1 = d->v(im+1,jm,km); v2 = d->v(im-1,jm,km);\r
++ *x = (v1+v2-2*v)==0 ? im : im+(v1-v2)/(v1+v2-2*v)/2;\r
++ }\r
++ if(ny>2)\r
++ {\r
++ if(jm==0) jm=1;\r
++ if(jm==ny-1)jm=ny-2;\r
++ v1 = d->v(im,jm+1,km); v2 = d->v(im,jm-1,km);\r
++ *y = (v1+v2-2*v)==0 ? jm : jm+(v1-v2)/(v1+v2-2*v)/2;\r
++ }\r
++ if(nz>2)\r
++ {\r
++ if(km==0) km=1;\r
++ if(km==nz-1)km=nz-2;\r
++ v1 = d->v(im,jm,km+1); v2 = d->v(im,jm,km-1);\r
++ *z = (v1+v2-2*v)==0 ? km : km+(v1-v2)/(v1+v2-2*v)/2;\r
++ }\r
++ return m;\r
++}\r
++mreal MGL_EXPORT mgl_data_min_real_(uintptr_t *d, mreal *x, mreal *y, mreal *z)\r
++{ return mgl_data_min_real(_DT_,x,y,z); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_fill(HMDT d, mreal x1,mreal x2,char dir)\r
++{\r
++ if(mgl_isnan(x2)) x2=x1;\r
++ if(dir<'x' || dir>'z') dir='x';\r
++ long nx=d->nx,ny=d->ny,nz=d->nz;\r
++ if(dir=='x')\r
++ {\r
++ mreal dx = d->nx>1 ? (x2-x1)/(d->nx-1):0;\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny*nz;j++) for(long i=1;i<nx;i++) d->a[i+nx*j] = x1+dx*i;\r
++#pragma omp parallel for\r
++ for(long j=0;j<ny*nz;j++) d->a[nx*j] = x1;\r
++ }\r
++ if(dir=='y')\r
++ {\r
++ mreal dx = d->ny>1 ? (x2-x1)/(d->ny-1):0;\r
++#pragma omp parallel for collapse(3)\r
++ for(long k=0;k<nz;k++) for(long j=1;j<ny;j++) for(long i=0;i<nx;i++) d->a[i+nx*(j+ny*k)] = x1+dx*j;\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<nz;j++) for(long i=0;i<nx;i++) d->a[i+nx*ny*j] = x1;\r
++ }\r
++ if(dir=='z')\r
++ {\r
++ mreal dx = d->nz>1 ? (x2-x1)/(d->nz-1):0;\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=1;j<nz;j++) for(long i=0;i<nx*ny;i++) d->a[i+nx*ny*j] = x1+dx*j;\r
++#pragma omp parallel for\r
++ for(long j=0;j<nx*ny;j++) d->a[j] = x1;\r
++ }\r
++}\r
++void MGL_EXPORT mgl_data_fill_(uintptr_t *d, mreal *x1,mreal *x2,const char *dir,int)\r
++{ mgl_data_fill(_DT_,*x1,*x2,*dir); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_norm(HMDT d, mreal v1,mreal v2,int sym,long dim)\r
++{\r
++ long s,nn=d->nx*d->ny*d->nz;\r
++ mreal a1=INFINITY,a2=-INFINITY,v,*a=d->a;\r
++ s = dim*d->ny*(d->nz>1 ? d->nx : 1);\r
++ for(long i=s;i<nn;i++) // determines borders of existing data\r
++ { a1 = a1>a[i] ? a[i]:a1; a2 = a2<a[i] ? a[i]:a2; }\r
++ if(a1==a2) { if(a1!=0) a1=0.; else a2=1; }\r
++ if(v1>v2) { v=v1; v1=v2; v2=v; } // swap if uncorrect\r
++ if(sym) // use symmetric\r
++ {\r
++ v2 = -v1>v2 ? -v1:v2; v1 = -v2;\r
++ a2 = -a1>a2 ? -a1:a2; a1 = -a2;\r
++ }\r
++ v2 = (v2-v1)/(a2-a1); v1 = v1-a1*v2;\r
++#pragma omp parallel for\r
++ for(long i=s;i<nn;i++) a[i] = v1 + v2*a[i];\r
++}\r
++void MGL_EXPORT mgl_data_norm_(uintptr_t *d, mreal *v1,mreal *v2,int *sym,int *dim)\r
++{ mgl_data_norm(_DT_,*v1,*v2,*sym,*dim); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_squeeze(HMDT d, long rx,long ry,long rz,long smooth)\r
++{\r
++ long kx,ky,kz, nx=d->nx, ny=d->ny, nz=d->nz;\r
++ mreal *b;\r
++\r
++ // simple checking\r
++ if(rx>=nx) rx=nx-1;\r
++ if(rx<1) rx=1;\r
++ if(ry>=ny) ry=ny-1;\r
++ if(ry<1) ry=1;\r
++ if(rz>=nz) rz=nz-1;\r
++ if(rz<1) rz=1;\r
++ // new sizes\r
++ kx = 1+(nx-1)/rx; ky = 1+(ny-1)/ry; kz = 1+(nz-1)/rz;\r
++ b = new mreal[kx*ky*kz];\r
++ if(!smooth)\r
++#pragma omp parallel for collapse(3)\r
++ for(long k=0;k<kz;k++) for(long j=0;j<ky;j++) for(long i=0;i<kx;i++)\r
++ b[i+kx*(j+ky*k)] = d->a[i*rx+nx*(j*ry+ny*rz*k)];\r
++ else\r
++#pragma omp parallel for collapse(3)\r
++ for(long k=0;k<kz;k++) for(long j=0;j<ky;j++) for(long i=0;i<kx;i++)\r
++ {\r
++ long dx,dy,dz,i1,j1,k1;\r
++ dx = (i+1)*rx<=nx ? rx : nx-i*rx;\r
++ dy = (j+1)*ry<=ny ? ry : ny-j*ry;\r
++ dz = (k+1)*rz<=nz ? rz : nz-k*rz;\r
++ mreal s = 0;\r
++ for(k1=k*rz;k1<k*rz+dz;k1++) for(j1=j*ry;j1<j*ry+dz;j1++) for(i1=i*rx;i1<i*rx+dx;i1++)\r
++ s += d->a[i1+nx*(j1+ny*k1)];\r
++ b[i+kx*(j+ky*k)] = s/(dx*dy*dz);\r
++ }\r
++ if(!d->link) delete [](d->a);\r
++ d->a=b; d->nx = kx; d->ny = ky; d->nz = kz; d->NewId(); d->link=false;\r
++}\r
++void MGL_EXPORT mgl_data_squeeze_(uintptr_t *d, int *rx,int *ry,int *rz,int *smooth)\r
++{ mgl_data_squeeze(_DT_,*rx,*ry,*rz,*smooth); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_extend(HMDT d, long n1, long n2)\r
++{\r
++ long nx=d->nx, ny=d->ny, nz=d->nz;\r
++ if(nz>2 || n1==0) return;\r
++ long mx, my, mz;\r
++ mreal *b=0;\r
++ if(n1>0) // extend to higher dimension(s)\r
++ {\r
++ n2 = n2>0 ? n2:1;\r
++ mx = nx; my = ny>1?ny:n1; mz = ny>1 ? n1 : n2;\r
++ b = new mreal[mx*my*mz];\r
++ if(ny>1)\r
++#pragma omp parallel for\r
++ for(long i=0;i<n1;i++) memcpy(b+i*nx*ny, d->a, nx*ny*sizeof(mreal));\r
++ else\r
++#pragma omp parallel for\r
++ for(long i=0;i<n1*n2;i++) memcpy(b+i*nx, d->a, nx*sizeof(mreal));\r
++ }\r
++ else\r
++ {\r
++ mx = -n1; my = n2<0 ? -n2 : nx; mz = n2<0 ? nx : ny;\r
++ if(n2>0 && ny==1) mz = n2;\r
++ b = new mreal[mx*my*mz];\r
++ if(n2<0)\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<nx;j++) for(long i=0;i<mx*my;i++)\r
++ b[i+mx*my*j] = d->a[j];\r
++ else\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<nx*ny;j++) for(long i=0;i<mx;i++)\r
++ b[i+mx*j] = d->a[j];\r
++ if(n2>0 && ny==1)\r
++#pragma omp parallel for\r
++ for(long i=0;i<n2;i++)\r
++ memcpy(b+i*mx*my, d->a, mx*my*sizeof(mreal));\r
++ }\r
++ if(!d->link) delete [](d->a);\r
++ d->a=b; d->nx=mx; d->ny=my; d->nz=mz;\r
++ d->NewId(); d->link=false;\r
++}\r
++void MGL_EXPORT mgl_data_extend_(uintptr_t *d, int *n1, int *n2)\r
++{ mgl_data_extend(_DT_,*n1,*n2); }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_transpose(HMDT d, const char *dim)\r
++{\r
++ long nx=d->nx, ny=d->ny, nz=d->nz, n;\r
++ mreal *b=new mreal[nx*ny*nz], *a=d->a;\r
++ if(!strcmp(dim,"xzy") || !strcmp(dim,"zy"))\r
++ {\r
++#pragma omp parallel for collapse(3)\r
++ for(long j=0;j<ny;j++) for(long k=0;k<nz;k++) for(long i=0;i<nx;i++)\r
++ b[i+nx*(k+nz*j)] = a[i+nx*(j+ny*k)];\r
++ n=nz; nz=ny; ny=n;\r
++ }\r
++ else if(!strcmp(dim,"yxz") || !strcmp(dim,"yx"))\r
++ {\r
++#pragma omp parallel for collapse(3)\r
++ for(long k=0;k<nz;k++) for(long i=0;i<nx;i++) for(long j=0;j<ny;j++)\r
++ b[j+ny*(i+nx*k)] = a[i+nx*(j+ny*k)];\r
++ n=nx; nx=ny; ny=n;\r
++ }\r
++ else if(!strcmp(dim,"yzx"))\r
++ {\r
++#pragma omp parallel for collapse(3)\r
++ for(long k=0;k<nz;k++) for(long i=0;i<nx;i++) for(long j=0;j<ny;j++)\r
++ b[j+ny*(k+nz*i)] = a[i+nx*(j+ny*k)];\r
++ n=nx; nx=ny; ny=nz; nz=n;\r
++ }\r
++ else if(!strcmp(dim,"zxy"))\r
++ {\r
++#pragma omp parallel for collapse(3)\r
++ for(long i=0;i<nx;i++) for(long j=0;j<ny;j++) for(long k=0;k<nz;k++)\r
++ b[k+nz*(i+nx*j)] = a[i+nx*(j+ny*k)];\r
++ n=nx; nx=nz; nz=ny; ny=n;\r
++ }\r
++ else if(!strcmp(dim,"zyx") || !strcmp(dim,"zx"))\r
++ {\r
++#pragma omp parallel for collapse(3)\r
++ for(long i=0;i<nx;i++) for(long j=0;j<ny;j++) for(long k=0;k<nz;k++)\r
++ b[k+nz*(j+ny*i)] = a[i+nx*(j+ny*k)];\r
++ n=nz; nz=nx; nx=n;\r
++ }\r
++ else memcpy(b,a,nx*ny*nz*sizeof(mreal));\r
++ memcpy(a,b,nx*ny*nz*sizeof(mreal)); delete []b;\r
++ n=d->nx; d->nx=nx; d->ny=ny; d->nz=nz;\r
++ if(nx!=n) d->NewId();\r
++}\r
++void MGL_EXPORT mgl_data_transpose_(uintptr_t *d, const char *dim,int l)\r
++{ char *s=new char[l+1]; memcpy(s,dim,l); s[l]=0;\r
++ mgl_data_transpose(_DT_,s); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_modify(void *par)\r
++{\r
++ mglThreadD *t=(mglThreadD *)par;\r
++ const mglFormula *f = (const mglFormula *)(t->v);\r
++ long nx=t->p[0],ny=t->p[1],nz=t->p[2];\r
++ mreal *b=t->a, dx,dy,dz;\r
++ const mreal *v=t->b, *w=t->c;\r
++ dx=nx>1?1/(nx-1.):0; dy=ny>1?1/(ny-1.):0; dz=nz>1?1/(nz-1.):0;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i0=t->id;i0<t->n;i0+=mglNumThr)\r
++ {\r
++ long i=i0%nx, j=((i0/nx)%ny), k=i0/(nx*ny);\r
++ b[i0] = f->Calc(i*dx, j*dy, k*dz, b[i0], v?v[i0]:0, w?w[i0]:0);\r
++ }\r
++ return 0;\r
++}\r
++void MGL_EXPORT mgl_data_modify(HMDT d, const char *eq,long dim)\r
++{\r
++ long nx=d->nx, ny=d->ny, nz=d->nz, par[3]={nx,ny,nz};\r
++ if(dim<=0) mgl_data_modify_vw(d,eq,0,0); // fastes variant for whole array\r
++ else if(nz>1) // 3D array\r
++ {\r
++ mglFormula f(eq);\r
++ par[2] -= dim; if(par[2]<0) par[2]=0;\r
++ mglStartThread(mgl_modify,0,nx*ny*par[2],d->a+nx*ny*dim,0,0,par,&f);\r
++ }\r
++ else // 2D or 1D array\r
++ {\r
++ mglFormula f(eq);\r
++ par[1] -= dim; if(par[1]<0) par[1]=0;\r
++ mglStartThread(mgl_modify,0,nx*par[1],d->a+nx*dim,0,0,par,&f);\r
++ }\r
++}\r
++void MGL_EXPORT mgl_data_modify_(uintptr_t *d, const char *eq,int *dim,int l)\r
++{ char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0;\r
++ mgl_data_modify(_DT_,s,*dim); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_modify_vw(HMDT d, const char *eq,HCDT vdat,HCDT wdat)\r
++{\r
++ std::wstring s = d->s; d->s = L"u";\r
++ mglDataV x(d->nx,d->ny,d->nz, 0,1,'x'); x.s=L"x";\r
++ mglDataV y(d->nx,d->ny,d->nz, 0,1,'y'); y.s=L"y";\r
++ mglDataV z(d->nx,d->ny,d->nz, 0,1,'z'); z.s=L"z";\r
++ mglDataV i(d->nx,d->ny,d->nz, 0,d->nx-1,'x'); i.s=L"i";\r
++ mglDataV j(d->nx,d->ny,d->nz, 0,d->ny-1,'y'); j.s=L"j";\r
++ mglDataV k(d->nx,d->ny,d->nz, 0,d->nz-1,'z'); k.s=L"k";\r
++ mglDataV r(d->nx,d->ny,d->nz); r.s=L"#$mgl";\r
++ mglData v(vdat), w(wdat); v.s = L"v"; w.s = L"w";\r
++ std::vector<mglDataA*> list;\r
++ list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(d);\r
++ list.push_back(&v); list.push_back(&w); list.push_back(&r);\r
++ list.push_back(&i); list.push_back(&j); list.push_back(&k);\r
++ d->Move(mglFormulaCalc(eq,list)); d->s = s;\r
++}\r
++void MGL_EXPORT mgl_data_modify_vw_(uintptr_t *d, const char *eq, uintptr_t *v, uintptr_t *w,int l)\r
++{ char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0;\r
++ mgl_data_modify_vw(_DT_,s,_DA_(v),_DA_(w)); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++#if MGL_HAVE_HDF4\r
++int MGL_EXPORT mgl_data_read_hdf4(HMDT d,const char *fname,const char *data)\r
++{\r
++ int32 sd = SDstart(fname,DFACC_READ), nn, i;\r
++ if(sd==-1) return 0; // is not a HDF4 file\r
++ char name[64];\r
++ SDfileinfo(sd,&nn,&i);\r
++ for(i=0;i<nn;i++)\r
++ {\r
++ int32 sds, rank, dims[32], type, attr, in[2]={0,0};\r
++ sds = SDselect(sd,i);\r
++ SDgetinfo(sds,name,&rank,dims,&type,&attr);\r
++ if(!strcmp(name,data)) // as I understand there are possible many datas with the same name\r
++ {\r
++ if(rank==1) { dims[2]=dims[0]; dims[0]=dims[1]=1; }\r
++ else if(rank==2) { dims[2]=dims[1]; dims[1]=dims[0]; dims[0]=1; }\r
++// else if(rank>3) continue;\r
++ long mm=dims[0]*dims[1]*dims[2];\r
++ if(type==DFNT_FLOAT32)\r
++ {\r
++ float *b = new float[mm];\r
++ SDreaddata(sds,in,0,dims,b);\r
++ mgl_data_set_float(d,b,dims[2],dims[1],dims[0]);\r
++ delete []b;\r
++ }\r
++ if(type==DFNT_FLOAT64)\r
++ {\r
++ double *b = new double[mm];\r
++ SDreaddata(sds,in,0,dims,b);\r
++ mgl_data_set_double(d,b,dims[2],dims[1],dims[0]);\r
++ delete []b;\r
++ }\r
++ }\r
++ SDendaccess(sds);\r
++ }\r
++ SDend(sd);\r
++ return 1;\r
++}\r
++#else\r
++int MGL_EXPORT mgl_data_read_hdf4(HMDT ,const char *,const char *)\r
++{ mgl_set_global_warn(_("HDF4 support was disabled. Please, enable it and rebuild MathGL.")); return 0; }\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++#if MGL_HAVE_HDF5\r
++void MGL_EXPORT mgl_data_save_hdf(HCDT dat,const char *fname,const char *data,int rewrite)\r
++{\r
++ const mglData *d = dynamic_cast<const mglData *>(dat); // NOTE: slow for non-mglData\r
++ if(!d) { mglData d(dat); mgl_data_save_hdf(&d,fname,data,rewrite); return; }\r
++ hid_t hf,hd,hs;\r
++ hsize_t dims[3];\r
++ long rank = 3, res;\r
++ H5Eset_auto(0,0);\r
++ res=H5Fis_hdf5(fname);\r
++ if(res>0 && !rewrite) hf = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT);\r
++ else hf = H5Fcreate(fname, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);\r
++ if(hf<0) return;\r
++ if(d->nz==1 && d->ny == 1) { rank=1; dims[0]=d->nx; }\r
++ else if(d->nz==1) { rank=2; dims[0]=d->ny; dims[1]=d->nx; }\r
++ else { rank=3; dims[0]=d->nz; dims[1]=d->ny; dims[2]=d->nx; }\r
++ hs = H5Screate_simple(rank, dims, 0);\r
++#if MGL_USE_DOUBLE\r
++ hid_t mem_type_id = H5T_NATIVE_DOUBLE;\r
++#else\r
++ hid_t mem_type_id = H5T_NATIVE_FLOAT;\r
++#endif\r
++ hd = H5Dcreate(hf, data, mem_type_id, hs, H5P_DEFAULT);\r
++ H5Dwrite(hd, mem_type_id, hs, hs, H5P_DEFAULT, d->a);\r
++ H5Dclose(hd); H5Sclose(hs); H5Fclose(hf);\r
++}\r
++//-----------------------------------------------------------------------------\r
++int MGL_EXPORT mgl_data_read_hdf(HMDT d,const char *fname,const char *data)\r
++{\r
++ hid_t hf,hd,hs;\r
++ long rank, res = H5Fis_hdf5(fname);\r
++ if(res<=0) return mgl_data_read_hdf4(d,fname,data);\r
++ hf = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT);\r
++ if(hf<0) return 0;\r
++ hd = H5Dopen(hf,data);\r
++ if(hd<0) return 0;\r
++ hs = H5Dget_space(hd);\r
++ rank = H5Sget_simple_extent_ndims(hs);\r
++ if(rank>0 && rank<=3)\r
++ {\r
++ hsize_t dims[3];\r
++ H5Sget_simple_extent_dims(hs,dims,0);\r
++ if(rank==1) { dims[2]=dims[0]; dims[0]=dims[1]=1; }\r
++ else if(rank==2) { dims[2]=dims[1]; dims[1]=dims[0]; dims[0]=1; }\r
++// else if(rank>3) continue;\r
++ mgl_data_create(d,dims[2],dims[1],dims[0]);\r
++#if MGL_USE_DOUBLE\r
++ H5Dread(hd, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a);\r
++#else\r
++ H5Dread(hd, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, d->a);\r
++#endif\r
++ }\r
++ H5Sclose(hs); H5Dclose(hd); H5Fclose(hf); return 1;\r
++}\r
++//-----------------------------------------------------------------------------\r
++MGL_EXPORT const char * const * mgl_datas_hdf_str(const char *fname)\r
++{\r
++ static std::vector<std::string> names;\r
++ static const char **res=0;\r
++ hid_t hf,hg,hd,ht;\r
++ hf = H5Fopen(fname, H5F_ACC_RDONLY, H5P_DEFAULT); names.clear();\r
++ if(!hf) return 0;\r
++ hg = H5Gopen(hf,"/");\r
++ hsize_t num;\r
++ char name[256];\r
++ H5Gget_num_objs(hg, &num); // replace by H5G_info_t t; H5Gget_info(hg,&t); num=t.nlinks;\r
++ for(hsize_t i=0;i<num;i++)\r
++ {\r
++ if(H5Gget_objtype_by_idx(hg, i)!=H5G_DATASET) continue;\r
++ H5Gget_objname_by_idx(hg, i, name, 256); // replace by H5Lget_name_by_idx(hg,".",i,0,0,name,256,0) ?!\r
++ hd = H5Dopen(hf,name);\r
++ ht = H5Dget_type(hd);\r
++ if(H5Tget_class(ht)==H5T_FLOAT || H5Tget_class(ht)==H5T_INTEGER) names.push_back(name);\r
++ H5Dclose(hd); H5Tclose(ht);\r
++ }\r
++ H5Gclose(hg); H5Fclose(hf); names.push_back("");\r
++ if(res) delete []res;\r
++ size_t nn = names.size();\r
++ res = new const char*[nn+1];\r
++ for(size_t i=0;i<nn;i++) res[i]=names[i].c_str();\r
++ res[nn]=NULL; return res;\r
++}\r
++\r
++long MGL_EXPORT mgl_datas_hdf(const char *fname, char *buf, long size)\r
++{\r
++ const char * const *res = mgl_datas_hdf_str(fname);\r
++ if(!res) return 0;\r
++ long n=0, len=1;\r
++ while(res[n][0]) { len += strlen(res[n])+1; n++; }\r
++ if(len>size) return -long(len);\r
++ strcpy(buf,res[0]);\r
++ for(long i=1;i<n;i++) { strcat(buf,"\t"); strcat(buf,res[i]); }\r
++ return n;\r
++}\r
++#else\r
++void MGL_EXPORT mgl_data_save_hdf(HCDT ,const char *,const char *,int )\r
++{ mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); }\r
++MGL_EXPORT const char * const * mgl_datas_hdf_str(const char *fname)\r
++{ mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); return 0;}\r
++long MGL_EXPORT mgl_datas_hdf(const char *, char *, long )\r
++{ mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); return 0;}\r
++int MGL_EXPORT mgl_data_read_hdf(HMDT ,const char *,const char *)\r
++{ mgl_set_global_warn(_("HDF5 support was disabled. Please, enable it and rebuild MathGL.")); return 0;}\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++int MGL_EXPORT mgl_data_read_hdf_(uintptr_t *d, const char *fname, const char *data,int l,int n)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ char *t=new char[n+1]; memcpy(t,data,n); t[n]=0;\r
++ int r = mgl_data_read_hdf(_DT_,s,t); delete []s; delete []t; return r; }\r
++void MGL_EXPORT mgl_data_save_hdf_(uintptr_t *d, const char *fname, const char *data, int *rewrite,int l,int n)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ char *t=new char[n+1]; memcpy(t,data,n); t[n]=0;\r
++ mgl_data_save_hdf(_DT_,s,t,*rewrite); delete []s; delete []t; }\r
++long MGL_EXPORT mgl_datas_hdf_(const char *fname, char *buf, int l, int size)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ int r = mgl_datas_hdf(s,buf,size); delete []s; return r; }\r
++//-----------------------------------------------------------------------------\r
++bool MGL_EXPORT mgl_add_file(long &kx,long &ky, long &kz, mreal *&b, mglData *d,bool as_slice)\r
++{\r
++ if(as_slice && d->nz==1)\r
++ {\r
++ if(kx==d->nx && d->ny==1)\r
++ {\r
++ b = (mreal *)realloc(b,kx*(ky+1)*sizeof(mreal));\r
++ memcpy(b+kx*ky,d->a,kx*sizeof(mreal)); ky++;\r
++ }\r
++ else if(kx==d->nx && ky==d->ny)\r
++ {\r
++ b = (mreal *)realloc(b,kx*ky*(kz+1)*sizeof(mreal));\r
++ memcpy(b+kx*ky*kz,d->a,kx*ky*sizeof(mreal)); kz++;\r
++ }\r
++ else return false;\r
++ }\r
++ else\r
++ {\r
++ if(d->ny*d->nz==1 && ky*kz==1)\r
++ {\r
++ b = (mreal *)realloc(b,(kx+d->nx)*sizeof(mreal));\r
++ memcpy(b+kx,d->a,d->nx*sizeof(mreal)); kx+=d->nx;\r
++ }\r
++ else if(kx==d->nx && kz==1 && d->nz==1)\r
++ {\r
++ b = (mreal *)realloc(b,kx*(ky+d->ny)*sizeof(mreal));\r
++ memcpy(b+kx*ky,d->a,kx*d->ny*sizeof(mreal)); ky+=d->ny;\r
++ }\r
++ else if(kx==d->nx && ky==d->ny)\r
++ {\r
++ b = (mreal *)realloc(b,kx*kx*(kz+d->nz)*sizeof(mreal));\r
++ memcpy(b+kx*ky*kz,d->a,kx*ky*d->nz*sizeof(mreal)); kz+=d->nz;\r
++ }\r
++ else return false;\r
++ }\r
++ return true;\r
++}\r
++//-----------------------------------------------------------------------------\r
++int MGL_EXPORT mgl_data_read_range(HMDT dat, const char *templ, double from, double to, double step, int as_slice)\r
++{\r
++ mglData d;\r
++ mreal t = from, *b;\r
++ long kx,ky,kz,n=strlen(templ)+20;\r
++ char *fname = new char[n];\r
++\r
++ //read first file\r
++ do{ snprintf(fname,n,templ,t); fname[n-1]=0; t+= step; } while(!mgl_data_read(&d,fname) && t<=to);\r
++\r
++ if(t>to) { delete []fname; return 0; }\r
++ kx = d.nx; ky = d.ny; kz = d.nz;\r
++ b = (mreal *)malloc(kx*ky*kz*sizeof(mreal));\r
++ memcpy(b,d.a,kx*ky*kz*sizeof(mreal));\r
++\r
++ // read other files\r
++ for(;t<=to;t+=step)\r
++ {\r
++ snprintf(fname,n,templ,t); fname[n-1]=0;\r
++ if(mgl_data_read(&d,fname))\r
++ if(!mgl_add_file(kx,ky,kz,b,&d,as_slice))\r
++ { delete []fname; free(b); return 0; }\r
++ }\r
++ dat->Set(b,kx,ky,kz);\r
++ delete []fname; free(b);\r
++ return 1;\r
++}\r
++int MGL_EXPORT mgl_data_read_range_(uintptr_t *d, const char *fname, mreal *from, mreal *to, mreal *step, int *as_slice,int l)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ int r = mgl_data_read_range(_DT_,s,*from,*to,*step,*as_slice); delete []s; return r; }\r
++//-----------------------------------------------------------------------------\r
++int MGL_EXPORT mgl_data_read_all(HMDT dat, const char *templ, int as_slice)\r
++{\r
++#ifndef WIN32\r
++ mglData d;\r
++ glob_t res;\r
++ size_t i;\r
++ mreal *b;\r
++ long kx,ky,kz;\r
++ glob (templ, GLOB_TILDE, NULL, &res);\r
++\r
++ //read first file\r
++ for(i=0;i<res.gl_pathc;i++)\r
++ if(mgl_data_read(&d,res.gl_pathv[i])) break;\r
++\r
++ if(i>=res.gl_pathc)\r
++ { globfree (&res); return 0; }\r
++ kx = d.nx; ky = d.ny; kz = d.nz;\r
++ b = (mreal *)malloc(kx*ky*kz*sizeof(mreal));\r
++ memcpy(b,d.a,kx*ky*kz*sizeof(mreal));\r
++\r
++ for(;i<res.gl_pathc;i++)\r
++ {\r
++ if(mgl_data_read(&d,res.gl_pathv[i]))\r
++ if(!mgl_add_file(kx,ky,kz,b,&d,as_slice))\r
++ { globfree (&res); free(b); return 0; }\r
++ }\r
++ dat->Set(b,kx,ky,kz);\r
++\r
++ globfree (&res); free(b);\r
++ return 1;\r
++#else\r
++ return 0;\r
++#endif\r
++}\r
++int MGL_EXPORT mgl_data_read_all_(uintptr_t *d, const char *fname, int *as_slice,int l)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ int r = mgl_data_read_all(_DT_,s,*as_slice); delete []s; return r; }\r
++//-----------------------------------------------------------------------------\r
++HMDT MGL_EXPORT mgl_data_column(HCDT dat, const char *eq)\r
++{\r
++ const mglData *dd=dynamic_cast<const mglData *>(dat);\r
++ std::vector<mglDataA*> list;\r
++ if(dd && dd->id.length()>0) for(size_t i=0;i<dd->id.length();i++)\r
++ {\r
++ mglDataT *col = new mglDataT(*dat);\r
++ col->SetInd(i,dd->id[i]);\r
++ list.push_back(col);\r
++ }\r
++ const mglDataC *dc=dynamic_cast<const mglDataC *>(dat);\r
++ if(dc && dc->id.length()>0) for(size_t i=0;i<dc->id.length();i++)\r
++ {\r
++ mglDataT *col = new mglDataT(*dat);\r
++ col->SetInd(i,dc->id[i]);\r
++ list.push_back(col);\r
++ }\r
++ if(list.size()==0) return 0; // no named columns\r
++ mglDataV *t = new mglDataV(dat->GetNy(),dat->GetNz());\r
++ t->s=L"#$mgl"; list.push_back(t);\r
++ HMDT r = mglFormulaCalc(eq,list);\r
++ for(size_t i=0;i<list.size();i++) delete list[i];\r
++ return r;\r
++}\r
++uintptr_t MGL_EXPORT mgl_data_column_(uintptr_t *d, const char *eq,int l)\r
++{ char *s=new char[l+1]; memcpy(s,eq,l); s[l]=0;\r
++ uintptr_t r = uintptr_t(mgl_data_column(_DT_,s));\r
++ delete []s; return r; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_data_limit(HMDT d, mreal v)\r
++{\r
++ long n = d->GetNN();\r
++ mreal *a = d->a;\r
++ #pragma omp parallel for\r
++ for(long i=0;i<n;i++)\r
++ { mreal b = fabs(a[i]); if(b>v) a[i] *= v/b; }\r
++}\r
++void MGL_EXPORT mgl_data_limit_(uintptr_t *d, mreal *v)\r
++{ mgl_data_limit(_DT_, *v); }\r
++//-----------------------------------------------------------------------------\r
++<<<<<<< HEAD\r
++=======\r
++/// Read binary data and swap big-endian to little-endian if swap=true\r
++size_t MGL_EXPORT mgl_fread(FILE *fp, void *vals, size_t size, size_t num, int swap)\r
++{\r
++ char *ptr = (char*)vals;\r
++ size_t r = fread(ptr,size,num,fp);\r
++ if(r && swap)\r
++ {\r
++ char buf[8], ch;\r
++ if(size==4) for(size_t i=0;i<r;i++)\r
++ {\r
++ memcpy(buf,ptr+i*size,size);\r
++ ch=buf[0]; buf[0]=buf[3]; buf[3]=ch;\r
++ ch=buf[1]; buf[1]=buf[2]; buf[2]=ch;\r
++ }\r
++ else if(size==2) for(size_t i=0;i<r;i++)\r
++ {\r
++ memcpy(buf,ptr+i*size,size);\r
++ ch=buf[0]; buf[0]=buf[1]; buf[1]=ch;\r
++ }\r
++ else if(size==8) for(size_t i=0;i<r;i++)\r
++ {\r
++ memcpy(buf,ptr+i*size,size);\r
++ ch=buf[0]; buf[0]=buf[7]; buf[7]=ch;\r
++ ch=buf[1]; buf[1]=buf[6]; buf[6]=ch;\r
++ ch=buf[2]; buf[2]=buf[5]; buf[5]=ch;\r
++ ch=buf[3]; buf[3]=buf[4]; buf[4]=ch;\r
++ }\r
++ }\r
++ return r;\r
++}\r
++//-----------------------------------------------------------------------------\r
++/// Read data array from Tektronix WFM file\r
++/** Parse Tektronix TDS5000/B, TDS6000/B/C, TDS/CSA7000/B, MSO70000/C, DSA70000/B/C DPO70000/B/C DPO7000/ MSO/DPO5000. */\r
++int MGL_EXPORT mgl_data_read_wfm(HMDT d,const char *fname, long num, long step/*=1*/, long start/*=0*/)\r
++{\r
++/* if(step<1) step=1;\r
++ if(start<0) start=0;\r
++ FILE *fp = fopen(fname,"rb");\r
++ if(!fp) return 0; // couldn't open file\r
++ unsigned short byte_order;\r
++ fread(&byte_order,2,1,fp);\r
++ bool byteorder; // TODO\r
++*/ return 0; \r
++}\r
++int MGL_EXPORT mgl_data_read_wfm_(uintptr_t *d, const char *fname, long *num, long *step, long *start,int l)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ int r = mgl_data_read_wfm(_DT_,s,*num,*step,*start);\r
++ delete []s; return r; }\r
++/// Read data array from Matlab MAT file (parse versions 4 and 5)\r
++int MGL_EXPORT mgl_data_read_matlab(HMDT d,const char *fname,const char *data)\r
++{\r
++ // TODO\r
++/**/return 0;\r
++}\r
++int MGL_EXPORT mgl_data_read_matlab_(uintptr_t *d, const char *fname, const char *data,int l,int n)\r
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;\r
++ char *t=new char[n+1]; memcpy(t,data,n); t[n]=0;\r
++ int r = mgl_data_read_matlab(_DT_,s,t); delete []s; delete []t; return r; }\r
++//-----------------------------------------------------------------------------\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * evalc.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include <time.h>\r
++#include "mgl2/datac_cf.h"\r
++#include "mgl2/evalc.h"\r
++#if MGL_HAVE_GSL\r
++#include <gsl/gsl_sf.h>\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++// constants for expression parsing\r
++enum{\r
++EQ_NUM=0, // a variable substitution\r
++EQ_RND, // random number\r
++EQ_A, // numeric constant\r
++// normal functions of 2 arguments\r
++EQ_LT, // comparison x<y !!! MUST BE FIRST 2-PLACE FUNCTION\r
++EQ_GT, // comparison x>y\r
++EQ_EQ, // comparison x=y\r
++EQ_ADD, // addition x+y\r
++EQ_SUB, // substraction x-y\r
++EQ_MUL, // multiplication x*y\r
++EQ_DIV, // division x/y\r
++EQ_IPOW, // power x^n for integer n\r
++EQ_POW, // power x^y\r
++EQ_LOG, // logarithm of x on base a, log_a(x) = ln(x)/ln(a)\r
++EQ_CMPLX, // return a+i*b\r
++EQ_HYPOT, // return sqrt(a*a+b*b)\r
++// normal functions of 1 argument\r
++EQ_SIN, // sine function \sin(x). !!! MUST BE FIRST 1-PLACE FUNCTION\r
++EQ_COS, // cosine function \cos(x).\r
++EQ_TAN, // tangent function \tan(x).\r
++EQ_ASIN, // inverse sine function \asin(x).\r
++EQ_ACOS, // inverse cosine function \acos(x).\r
++EQ_ATAN, // inverse tangent function \atan(x).\r
++EQ_SINH, // hyperbolic sine function \sinh(x).\r
++EQ_COSH, // hyperbolic cosine function \cosh(x).\r
++EQ_TANH, // hyperbolic tangent function \tanh(x).\r
++EQ_ASINH, // inverse hyperbolic sine function \asinh(x).\r
++EQ_ACOSH, // inverse hyperbolic cosine function \acosh(x).\r
++EQ_ATANH, // inverse hyperbolic tangent function \atanh(x).\r
++EQ_SQRT, // square root function \sqrt(x)\r
++EQ_EXP, // exponential function \exp(x)\r
++EQ_EXPI, // exponential function \exp(i*x)\r
++EQ_LN, // logarithm of x, ln(x)\r
++EQ_LG, // decimal logarithm of x, lg(x) = ln(x)/ln(10)\r
++EQ_ABS, // absolute value\r
++EQ_ARG, // argument (or phase) of complex number\r
++EQ_CONJ, // complex conjugate\r
++EQ_REAL, // real part\r
++EQ_IMAG, // imaginary part\r
++EQ_NORM, // square of absolute value |u|^2\r
++EQ_LAST // id of last entry\r
++};\r
++//-----------------------------------------------------------------------------\r
++int mglFormulaC::Error=0;\r
++bool MGL_LOCAL_PURE mglCheck(char *str,int n);\r
++int MGL_LOCAL_PURE mglFindInText(const char *str, const char *lst);\r
++//-----------------------------------------------------------------------------\r
++mglFormulaC::~mglFormulaC()\r
++{\r
++ if(Left) delete Left;\r
++ if(Right) delete Right;\r
++}\r
++//-----------------------------------------------------------------------------\r
++// Formula constructor (automatically parse and "compile" formula)\r
++mglFormulaC::mglFormulaC(const char *string)\r
++{\r
++ Error=0;\r
++ Left=Right=0;\r
++ Res=0; Kod=0;\r
++ if(!string) { Kod = EQ_NUM; Res = 0; return; }\r
++ char *str = new char[strlen(string)+1];\r
++ strcpy(str,string);\r
++ long n,len;\r
++ mgl_strtrim(str);\r
++ mgl_strlwr(str);\r
++ len=strlen(str);\r
++ if(str[0]==0) { delete []str; return; }\r
++ if(str[0]=='(' && mglCheck(&(str[1]),len-2)) // remove braces\r
++ {\r
++ memmove(str,str+1,len);\r
++ len-=2; str[len]=0;\r
++ }\r
++ len=strlen(str);\r
++ n=mglFindInText(str,"<>="); // low priority -- conditions\r
++ if(n>=0)\r
++ {\r
++ if(str[n]=='<') Kod=EQ_LT;\r
++ else if(str[n]=='>') Kod=EQ_GT;\r
++ else Kod=EQ_EQ;\r
++ str[n]=0;\r
++ Left=new mglFormulaC(str);\r
++ Right=new mglFormulaC(str+n+1);\r
++ delete []str; return;\r
++ }\r
++ n=mglFindInText(str,"+-"); // normal priority -- additions\r
++ if(n>=0 && (n<2 || str[n-1]!='e' || (str[n-2]!='.' && !isdigit(str[n-2]))))\r
++ {\r
++ if(str[n]=='+') Kod=EQ_ADD; else Kod=EQ_SUB;\r
++ str[n]=0;\r
++ Left=new mglFormulaC(str);\r
++ Right=new mglFormulaC(str+n+1);\r
++ delete []str; return;\r
++ }\r
++ n=mglFindInText(str,"*/"); // high priority -- multiplications\r
++ if(n>=0)\r
++ {\r
++ if(str[n]=='*') Kod=EQ_MUL; else Kod=EQ_DIV;\r
++ str[n]=0;\r
++ Left=new mglFormulaC(str);\r
++ Right=new mglFormulaC(str+n+1);\r
++ delete []str; return;\r
++ }\r
++ n=mglFindInText(str,"^"); // highest priority -- power\r
++ if(n>=0)\r
++ {\r
++ Kod=EQ_IPOW; str[n]=0;\r
++ Left=new mglFormulaC(str);\r
++ Right=new mglFormulaC(str+n+1);\r
++ delete []str; return;\r
++ }\r
++\r
++ for(n=0;n<len;n++) if(str[n]=='(') break;\r
++ if(n>=len) // this is number or variable\r
++ {\r
++ Kod = EQ_NUM;\r
++// Left = Right = 0;\r
++ if(str[1]==0 && str[0]>='a' && str[0]<='z') // available variables\r
++ { Kod=EQ_A; Res = str[0]-'a'; }\r
++ else if(!strcmp(str,"rnd")) Kod=EQ_RND;\r
++ else if(!strcmp(str,"pi")) Res=M_PI;\r
++ else if(!strcmp(str,"inf")) Res=INFINITY;\r
++ else if(str[0]=='i') Res = dual(0,str[1]>' '?atof(str+1):1);\r
++ else Res=atof(str); // this is number\r
++ }\r
++ else\r
++ {\r
++ char name[128];\r
++ mgl_strncpy(name,str,128); name[127]=name[n]=0;\r
++ memmove(str,str+n+1,len-n);\r
++ len=strlen(str); str[--len]=0;\r
++ if(!strcmp(name,"sin")) Kod=EQ_SIN;\r
++ else if(!strcmp(name,"cos")) Kod=EQ_COS;\r
++ else if(!strcmp(name,"tg")) Kod=EQ_TAN;\r
++ else if(!strcmp(name,"tan")) Kod=EQ_TAN;\r
++ else if(!strcmp(name,"asin")) Kod=EQ_ASIN;\r
++ else if(!strcmp(name,"acos")) Kod=EQ_ACOS;\r
++ else if(!strcmp(name,"atan")) Kod=EQ_ATAN;\r
++ else if(!strcmp(name,"sinh")) Kod=EQ_SINH;\r
++ else if(!strcmp(name,"cosh")) Kod=EQ_COSH;\r
++ else if(!strcmp(name,"tanh")) Kod=EQ_TANH;\r
++ else if(!strcmp(name,"sh")) Kod=EQ_SINH;\r
++ else if(!strcmp(name,"ch")) Kod=EQ_COSH;\r
++ else if(!strcmp(name,"th")) Kod=EQ_TANH;\r
++ else if(!strcmp(name,"sqrt")) Kod=EQ_SQRT;\r
++ else if(!strcmp(name,"log")) Kod=EQ_LOG;\r
++ else if(!strcmp(name,"pow")) Kod=EQ_POW;\r
++ else if(!strcmp(name,"exp")) Kod=EQ_EXP;\r
++ else if(!strcmp(name,"lg")) Kod=EQ_LG;\r
++ else if(!strcmp(name,"ln")) Kod=EQ_LN;\r
++ else if(!strcmp(name,"abs")) Kod=EQ_ABS;\r
++ else if(!strcmp(name,"arg")) Kod=EQ_ARG;\r
++ else if(!strcmp(name,"conj")) Kod=EQ_CONJ;\r
++ else if(!strcmp(name,"real")) Kod=EQ_REAL;\r
++ else if(!strcmp(name,"imag")) Kod=EQ_IMAG;\r
++ else if(!strcmp(name,"norm")) Kod=EQ_NORM;\r
++<<<<<<< HEAD\r
++=======\r
++ else if(!strcmp(name,"cmplx")) Kod=EQ_CMPLX;\r
++ else if(!strcmp(name,"hypot")) Kod=EQ_HYPOT;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ else { delete []str; return; } // unknown function\r
++ n=mglFindInText(str,",");\r
++ if(n>=0)\r
++ {\r
++ str[n]=0;\r
++ Left=new mglFormulaC(str);\r
++ Right=new mglFormulaC(str+n+1);\r
++ }\r
++ else\r
++ Left=new mglFormulaC(str);\r
++ }\r
++ delete []str;\r
++}\r
++//-----------------------------------------------------------------------------\r
++// evaluate formula for 'x'='r', 'y'='n'='v', 't'='z', 'u'='a' variables\r
++dual mglFormulaC::Calc(dual x,dual y,dual t,dual u) const\r
++{\r
++ Error=0;\r
++ dual a1[MGL_VS]; memset(a1,0,MGL_VS*sizeof(dual));\r
++ a1['a'-'a'] = a1['u'-'a'] = u;\r
++ a1['x'-'a'] = a1['r'-'a'] = x;\r
++ a1['y'-'a'] = a1['n'-'a'] = a1['v'-'a'] = y;\r
++ a1['z'-'a'] = a1['t'-'a'] = t;\r
++ a1['i'-'a'] = dual(0,1);\r
++ return CalcIn(a1);\r
++}\r
++//-----------------------------------------------------------------------------\r
++// evaluate formula for 'x'='r', 'y'='n', 't'='z', 'u'='a', 'v'='b', 'w'='c' variables\r
++dual mglFormulaC::Calc(dual x,dual y,dual t,dual u,dual v,dual w) const\r
++{\r
++ Error=0;\r
++ dual a1[MGL_VS]; memset(a1,0,MGL_VS*sizeof(dual));\r
++ a1['c'-'a'] = a1['w'-'a'] = w;\r
++ a1['b'-'a'] = a1['v'-'a'] = v;\r
++ a1['a'-'a'] = a1['u'-'a'] = u;\r
++ a1['x'-'a'] = a1['r'-'a'] = x;\r
++ a1['y'-'a'] = a1['n'-'a'] = y;\r
++ a1['z'-'a'] = a1['t'-'a'] = t;\r
++ a1['i'-'a'] = dual(0,1);\r
++ return CalcIn(a1);\r
++}\r
++//-----------------------------------------------------------------------------\r
++// evaluate formula for arbitrary set of variables\r
++dual mglFormulaC::Calc(const dual var[MGL_VS]) const\r
++{\r
++ Error=0;\r
++ return CalcIn(var);\r
++}\r
++//-----------------------------------------------------------------------------\r
++dual MGL_LOCAL_CONST ceqc(dual a,dual b) {return a==b?1:0;}\r
++dual MGL_LOCAL_CONST cltc(dual a,dual b) {return real(a-b)<0?1:0;}\r
++dual MGL_LOCAL_CONST cgtc(dual a,dual b) {return real(a-b)>0?1:0;}\r
++dual MGL_LOCAL_CONST addc(dual a,dual b) {return a+b;}\r
++dual MGL_LOCAL_CONST subc(dual a,dual b) {return a-b;}\r
++dual MGL_LOCAL_CONST mulc(dual a,dual b) {return a*b;}\r
++dual MGL_LOCAL_CONST divc(dual a,dual b) {return a/b;}\r
++dual MGL_LOCAL_CONST ipwc(dual a,dual b) {return mgl_ipowc(a,int(b.real()));}\r
++dual MGL_LOCAL_CONST powc(dual a,dual b) {return exp(b*log(a)); }\r
++dual MGL_LOCAL_CONST llgc(dual a,dual b) {return log(a)/log(b); }\r
++dual MGL_LOCAL_CONST cmplxc(dual a,dual b) {return a+dual(0,1)*b; }\r
++dual MGL_LOCAL_CONST expi(dual a) { return exp(dual(0,1)*a); }\r
++dual MGL_LOCAL_CONST expi(double a) { return dual(cos(a),sin(a)); }\r
++//-----------------------------------------------------------------------------\r
++dual MGL_NO_EXPORT ic = dual(0,1);\r
++dual MGL_LOCAL_CONST hypotc(dual x, dual y) { return sqrt(x*x+y*y); }\r
++dual MGL_LOCAL_CONST asinhc(dual x) { return log(x+sqrt(x*x+mreal(1))); }\r
++dual MGL_LOCAL_CONST acoshc(dual x) { return log(x+sqrt(x*x-mreal(1))); }\r
++dual MGL_LOCAL_CONST atanhc(dual x) { return log((mreal(1)+x)/(mreal(1)-x))/mreal(2); }\r
++dual MGL_LOCAL_CONST conjc(dual x) { return dual(real(x),-imag(x)); }\r
++dual MGL_LOCAL_CONST sinc(dual x) { return sin(x); }\r
++dual MGL_LOCAL_CONST cosc(dual x) { return cos(x); }\r
++dual MGL_LOCAL_CONST tanc(dual x) { return tan(x); }\r
++dual MGL_LOCAL_CONST sinhc(dual x) { return sinh(x); }\r
++dual MGL_LOCAL_CONST coshc(dual x) { return cosh(x); }\r
++dual MGL_LOCAL_CONST tanhc(dual x) { return tanh(x); }\r
++dual MGL_LOCAL_CONST asinc(dual x) { return log(ic*x+sqrt(mreal(1)-x*x))/ic; }\r
++dual MGL_LOCAL_CONST acosc(dual x) { return log(x+sqrt(x*x-mreal(1)))/ic; }\r
++dual MGL_LOCAL_CONST atanc(dual x) { return log((ic-x)/(ic+x))/(mreal(2)*ic); }\r
++dual MGL_LOCAL_CONST expc(dual x) { return exp(x); }\r
++dual MGL_LOCAL_CONST sqrtc(dual x) { return sqrt(x); }\r
++dual MGL_LOCAL_CONST logc(dual x) { return log(x); }\r
++dual MGL_LOCAL_CONST absc(dual x) { return abs(x); }\r
++dual MGL_LOCAL_CONST argc(dual x) { return arg(x); }\r
++dual MGL_LOCAL_CONST lgc(dual x) { return log10(x);}\r
++dual MGL_LOCAL_CONST realc(dual x) { return real(x); }\r
++dual MGL_LOCAL_CONST imagc(dual x) { return imag(x); }\r
++dual MGL_LOCAL_CONST normc(dual x) { return norm(x); }\r
++//-----------------------------------------------------------------------------\r
++typedef dual (*func_1)(dual);\r
++typedef dual (*func_2)(dual, dual);\r
++static const func_2 f2[EQ_SIN-EQ_LT] = {cltc,cgtc,ceqc,addc,subc,mulc,divc,ipwc,powc,llgc,cmplxc,hypotc};\r
++static const func_1 f1[EQ_LAST-EQ_SIN] = {sinc,cosc,tanc,asinc,acosc,atanc,sinhc,coshc,tanhc,\r
++ asinhc,acoshc,atanhc,sqrtc,expc,expi,logc,lgc,absc,argc,conjc,realc,imagc,normc};\r
++// evaluation of embedded (included) expressions\r
++dual mglFormulaC::CalcIn(const dual *a1) const\r
++{\r
++// if(Error) return 0;\r
++ if(Kod==EQ_A) return a1[(int)Res.real()];\r
++ if(Kod==EQ_RND) return mgl_rnd();\r
++ if(Kod==EQ_NUM) return Res;\r
++\r
++ dual a = Left->CalcIn(a1);\r
++ if(mgl_isfin(a))\r
++ {\r
++ if(Kod<EQ_SIN)\r
++ {\r
++ dual b = Right->CalcIn(a1);\r
++ b = mgl_isfin(b)?f2[Kod-EQ_LT](a,b):NAN;\r
++ return mgl_isfin(b)?b:NAN;\r
++ }\r
++ else\r
++ { a = f1[Kod-EQ_SIN](a); return mgl_isfin(a)?a:NAN; }\r
++ }\r
++ return NAN;\r
++}\r
++//-----------------------------------------------------------------------------\r
++mdual MGL_EXPORT_CONST mgl_ipowc(dual x,int n)\r
++{\r
++ dual t;\r
++ if(n==2) t = x*x;\r
++ else if(n==1) t = x;\r
++ else if(n<0) t = mreal(1)/mgl_ipowc(x,-n);\r
++ else if(n==0) t = mreal(1);\r
++ else\r
++ {\r
++ t = mgl_ipowc(x,n/2); t = t*t;\r
++ if(n%2==1) t *= x;\r
++ }\r
++ return t.real()+t.imag()*mgl_I;\r
++}\r
++mdual MGL_EXPORT mgl_ipowc_(dual *x,int *n) { return mgl_ipowc(*x,*n); }\r
++//-----------------------------------------------------------------------------\r
++HAEX MGL_EXPORT mgl_create_cexpr(const char *expr) { return new mglFormulaC(expr); }\r
++uintptr_t MGL_EXPORT mgl_create_cexpr_(const char *expr, int l)\r
++{ char *s=new char[l+1]; memcpy(s,expr,l); s[l]=0;\r
++ uintptr_t res = uintptr_t(mgl_create_cexpr(s));\r
++ delete []s; return res; }\r
++void MGL_EXPORT mgl_delete_cexpr(HAEX ex) { if(ex) delete ex; }\r
++void MGL_EXPORT mgl_delete_cexpr_(uintptr_t *ex) { mgl_delete_cexpr((HAEX)ex); }\r
++mdual MGL_EXPORT mgl_cexpr_eval(HAEX ex, dual x, dual y,dual z)\r
++{ dual r = ex->Calc(x,y,z); return r.real()+r.imag()*mgl_I; }\r
++mdual MGL_EXPORT mgl_cexpr_eval_(uintptr_t *ex, dual *x, dual *y, dual *z)\r
++{ return mgl_cexpr_eval((HAEX) ex, *x,*y,*z); }\r
++mdual MGL_EXPORT mgl_cexpr_eval_v(HAEX ex, dual *var)\r
++{ dual r = ex->Calc(var); return r.real()+r.imag()*mgl_I; }\r
++//-----------------------------------------------------------------------------\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * font.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include <locale.h>\r
++#include <ctype.h>\r
++#include <wctype.h>\r
++#include <unistd.h>\r
++\r
++#if !defined(__BORLANDC__) || (__CODEGEARC__ >= 0x0630)\r
++#include <algorithm>\r
++#else\r
++#include <algorithm.h>\r
++#endif\r
++\r
++#include "mgl2/base.h"\r
++#include "mgl2/font.h"\r
++#include "def_font.cc"\r
++#include "tex_table.cc"\r
++//-----------------------------------------------------------------------------\r
++//mglFont mglDefFont("nofont");\r
++mglFont mglDefFont;\r
++//-----------------------------------------------------------------------------\r
++size_t MGL_EXPORT mgl_wcslen(const wchar_t *str)\r
++{\r
++ long i=0;\r
++ if(str) while(str[i]) i++;\r
++ return i;\r
++}\r
++//-----------------------------------------------------------------------------\r
++long MGL_EXPORT_PURE mgl_internal_code(unsigned s, const std::vector<mglGlyphDescr> &glyphs)\r
++{\r
++ long i1=0,i2=glyphs.size()-1;\r
++ wchar_t j = wchar_t(s & MGL_FONT_MASK);\r
++ // let suppose that id[i]<id[i+1]\r
++ while(i1<i2)\r
++ {\r
++ long i = (i1+i2)/2;\r
++ if(j<glyphs[i].id) i2 = i;\r
++ else if(j>glyphs[i].id) i1=i+1;\r
++ else return i;\r
++ }\r
++ return j==glyphs[i2].id ? i2 : -1;\r
++}\r
++//-----------------------------------------------------------------------------\r
++bool MGL_EXPORT mglGetStyle(const char *how, int *font, int *align)\r
++{\r
++ bool col=false;\r
++ if(align) *align = 1; // centering text by default\r
++ if(!how || *how==0) return col;\r
++ // NOTE: no brightness for text color\r
++ for(;*how && *how!=':';how++)\r
++ {\r
++ if(strchr(MGL_COLORS,*how)) col = true;\r
++ if(*how=='{' && how[1]=='x') col = true;\r
++ }\r
++ if(align)\r
++ {\r
++ *align = 1;\r
++ if(strchr(how,'R')) *align = 2;\r
++// if(strchr(how,'C')) *align = 1;\r
++ if(strchr(how,'L')) *align = 0;\r
++ if(strchr(how,'D')) *align+= 4;\r
++ }\r
++ if(font)\r
++ {\r
++ *font = 0;\r
++ if(strchr(how,'b')) *font = *font|MGL_FONT_BOLD;\r
++ if(strchr(how,'i')) *font = *font|MGL_FONT_ITAL;\r
++ if(strchr(how,'w')) *font = *font|MGL_FONT_WIRE;\r
++ if(strchr(how,'o')) *font = *font|MGL_FONT_OLINE;\r
++ if(strchr(how,'u')) *font = *font|MGL_FONT_ULINE;\r
++ }\r
++ return col;\r
++}\r
++//-----------------------------------------------------------------------------\r
++float mglFont::Puts(const char *str,const char *how,float c1,float c2) const\r
++{\r
++ int font=0, align=1; float w=0;\r
++ mglGetStyle(how,&font,&align);\r
++ MGL_TO_WCS(str,w = Puts(wcs,font,align,c1,c2));\r
++ return w;\r
++}\r
++//-----------------------------------------------------------------------------\r
++float mglFont::Width(const char *str,const char *how) const\r
++{\r
++ int font=0; float w=0;\r
++ mglGetStyle(how,&font);\r
++ MGL_TO_WCS(str,w = Width(wcs,font));\r
++ return w;\r
++}\r
++//-----------------------------------------------------------------------------\r
++float mglFont::Puts(const wchar_t *str,const char *how,float c1,float c2) const\r
++{\r
++ int font=0, align=1;\r
++ mglGetStyle(how,&font,&align);\r
++ return Puts(str, font, align,c1,c2);\r
++}\r
++//-----------------------------------------------------------------------------\r
++float mglFont::Width(const wchar_t *str,const char *how) const\r
++{\r
++ int font=0;\r
++ mglGetStyle(how,&font);\r
++ return Width(str, font);\r
++}\r
++//-----------------------------------------------------------------------------\r
++float mglFont::Puts(const wchar_t *str,int font,int align, float c1,float c2) const\r
++{\r
++ if(GetNumGlyph()==0 || !str || *str==0) return 0;\r
++ float ww=0,w=0,h = (align&4) ? 500./fact[0] : 0;\r
++ size_t size = mgl_wcslen(str)+1,num=0;\r
++ if(parse)\r
++ {\r
++ unsigned *wcs = new unsigned[size], *buf=wcs;\r
++ memcpy(wcs,str,size*sizeof(wchar_t));\r
++ Convert(str, wcs);\r
++ for(size_t i=0;wcs[i];i++)\r
++ {\r
++ if(wcs[i]=='\n') // parse '\n' symbol\r
++ {\r
++ wcs[i]=0; w = Puts(buf,0,0,1.f,0x10|font,c1,c2); // find width\r
++ Puts(buf,-w*(align&3)/2.f,-h - 660*num/fact[0],1.f,font,c1,c2); // draw it really\r
++ buf=wcs+i+1; num++; if(w>ww) ww=w;\r
++ }\r
++// if(wcs[i]=='\\' && wcs[i+1]=='n' && (wcs[i+2]>' ' || wcschr(L"{}[]()!@#$%^&*/-?.,_=+\\\"", wcs[i+2]))) // parse '\n' symbol\r
++// {\r
++// wcs[i]=0; w = Puts(buf,0,0,1.f,0x10|font,c1,c2); // find width\r
++// Puts(buf,-w*(align&3)/2.f,-h - 720.*num/fact[0],1.f,font,c1,c2); // draw it really\r
++// buf=wcs+i+2; num++; if(w>ww) ww=w;\r
++// }\r
++ }\r
++ // draw string itself\r
++ w = Puts(buf,0,0,1.f,0x10|font,c1,c2); // find width\r
++ Puts(buf,-w*(align&3)/2.f,-h - 660*num/fact[0],1.f,font,c1,c2); // draw it really\r
++ if(w>ww) ww=w;\r
++ delete []wcs;\r
++ }\r
++ else\r
++ {\r
++ int s = (font/MGL_FONT_BOLD)&3;\r
++ h *= fact[0]/fact[s];\r
++ for(size_t i=0;i<size;i++) // find width\r
++ {\r
++ long j = str[i]!=' ' ? Internal(str[i]) : Internal('!');\r
++ if(j==-1) continue;\r
++ w+= GetWidth(s,j)/fact[s];\r
++ }\r
++ ww = w; w *= -(align&3)/2.f;\r
++ if(gr) for(size_t i=0;i<size;i++) // draw it\r
++ {\r
++ long j=0; //Internal('!');\r
++ if(str[i]!=' ')\r
++ {\r
++ j = Internal(str[i]);\r
++ if(j==-1) continue;\r
++ gr->Glyph(w, -h, 1, (s+(font&MGL_FONT_WIRE))?4:0, j, c1+i*(c2-c1)/(size-1));\r
++ }\r
++ w+= GetWidth(s,j)/fact[s];\r
++ }\r
++ }\r
++ return ww;\r
++}\r
++//-----------------------------------------------------------------------------\r
++float mglFont::Width(const wchar_t *str,int font) const\r
++{\r
++ if(GetNumGlyph()==0 || !str || *str==0) return 0;\r
++ float ww=0,w=0;\r
++ size_t size = mgl_wcslen(str)+1;\r
++ if(parse)\r
++ {\r
++ unsigned *wcs = new unsigned[size], *buf=wcs;\r
++ memcpy(wcs,str,size*sizeof(wchar_t));\r
++ Convert(str, wcs);\r
++ for(size_t i=0;wcs[i];i++) if(wcs[i]=='\n') // parse '\n' symbol\r
++ {\r
++ wcs[i]=0; w = Puts(buf,0,0,1.,0x10|font,'k','k'); // find width\r
++ buf=wcs+i+1; if(w>ww) ww=w;\r
++ }\r
++ w = Puts(buf,0,0,1.,0x10|font,'k','k');\r
++ if(w<ww) w=ww;\r
++ delete []wcs;\r
++ }\r
++ else\r
++ {\r
++ int s = (font/MGL_FONT_BOLD)&3;\r
++ for(size_t i=0;i<size;i++)\r
++ {\r
++ long j = str[i]!=' ' ? Internal(str[i]) : Internal('!');\r
++ if(j==-1) continue;\r
++ w+= GetWidth(s,j)/fact[s];\r
++ }\r
++ }\r
++ return w;\r
++}\r
++//-----------------------------------------------------------------------------\r
++float mglFont::Height(int font) const\r
++{\r
++ if(GetNumGlyph()==0) return 0;\r
++ int s = (font/MGL_FONT_BOLD)&3;\r
++ return 660/fact[s];\r
++}\r
++//-----------------------------------------------------------------------------\r
++float mglFont::Height(const char *how) const\r
++{\r
++ if(GetNumGlyph()==0) return 0;\r
++ int s=0;\r
++ if(how)\r
++ {\r
++ if(strchr(how,'b')) s = s|1;\r
++ if(strchr(how,'i')) s = s|2;\r
++ }\r
++ return 660/fact[s];\r
++}\r
++//-----------------------------------------------------------------------------\r
++/// Table of acents and its UTF8 codes\r
++MGL_NO_EXPORT mglTeXsymb mgl_act_symb[] = {\r
++ {0x02c6, L"hat"}, {0x02dc, L"tilde"}, {0x02d9, L"dot"}, {0x00a8, L"ddot"}, {0x20db, L"dddot"}, {0x20dc, L"ddddot"}, {0x02ca, L"acute"}, {0x02c7, L"check"}, {0x02cb, L"grave"}, {0x20d7, L"vec"}, {0x02c9, L"bar"}, {0x02d8, L"breve"},\r
++ /*end*/{0, L"\0"}};\r
++//-----------------------------------------------------------------------------\r
++int MGL_LOCAL_PURE mgl_tex_symb_cmp(const void *a, const void *b)\r
++{\r
++ const mglTeXsymb *aa = (const mglTeXsymb *)a;\r
++ const mglTeXsymb *bb = (const mglTeXsymb *)b;\r
++ return wcscmp(aa->tex, bb->tex);\r
++}\r
++//-----------------------------------------------------------------------------\r
++// parse LaTeX commands (mostly symbols and acents, and some font-style commands)\r
++unsigned mglFont::Parse(const wchar_t *s) const\r
++{\r
++ unsigned res = unsigned(-2); // Default is no symbol\r
++ if(!s || !s[0]) return res;\r
++ mglTeXsymb tst, *rts;\r
++ tst.tex = s;\r
++ rts = (mglTeXsymb *) bsearch(&tst, mgl_tex_symb, mgl_tex_num, sizeof(mglTeXsymb), mgl_tex_symb_cmp);\r
++ if(rts) return rts->kod;\r
++\r
++ for(long k=0;mgl_act_symb[k].kod;k++) // acents\r
++ if(!wcscmp(s,mgl_act_symb[k].tex))\r
++ return mgl_act_symb[k].kod | MGL_FONT_ZEROW;\r
++ // arbitrary UTF symbol\r
++ if(s[0]=='u' && s[1]=='t' && s[2]=='f')\r
++ { long k = wcstoul(s+3,NULL,16); return wchar_t(k); }\r
++ // font/style changes for next symbol\r
++ if(!wcscmp(s,L"big")) res = unsigned(-5);\r
++ else if(!wcscmp(s,L"frac")) res = unsigned(-6);\r
++ else if(!wcscmp(s,L"stack")) res = unsigned(-7);\r
++ else if(!wcscmp(s,L"overset")) res = unsigned(-8);\r
++ else if(!wcscmp(s,L"underset")) res = unsigned(-9);\r
++ else if(!wcscmp(s,L"stackr")) res = unsigned(-10);\r
++ else if(!wcscmp(s,L"stackl")) res = unsigned(-11);\r
++ else if(!wcscmp(s,L"sub")) res = unsigned(-12);\r
++ else if(!wcscmp(s,L"sup")) res = unsigned(-13);\r
++ else if(!wcscmp(s,L"textsc")) res = unsigned(-14); // new\r
++ else if(!wcscmp(s,L"dfrac")) res = unsigned(-15);\r
++ else if(!wcscmp(s,L"b")) res = MGL_FONT_BOLD;\r
++ else if(!wcscmp(s,L"i")) res = MGL_FONT_ITAL;\r
++ else if(!wcscmp(s,L"bi")) res = MGL_FONT_BOLD|MGL_FONT_ITAL;\r
++ else if(!wcscmp(s,L"r")) res = unsigned(-1);\r
++ else if(!wcscmp(s,L"a")) res = MGL_FONT_OLINE;\r
++ else if(!wcscmp(s,L"u")) res = MGL_FONT_ULINE;\r
++ else if(!wcscmp(s,L"n")) res = '\n';\r
++ else if(!wcscmp(s,L"overline")) res = MGL_FONT_OLINE;\r
++ else if(!wcscmp(s,L"underline"))res = MGL_FONT_ULINE;\r
++ else if(!wcscmp(s,L"textbf")) res = MGL_FONT_BOLD;\r
++ else if(!wcscmp(s,L"textit")) res = MGL_FONT_ITAL;\r
++ else if(!wcscmp(s,L"textrm")) res = unsigned(-1);\r
++ else if(!wcscmp(s,L"T2A")) res = unsigned(-1);\r
++ else if(!wcscmp(s,L"w")) res = MGL_FONT_WIRE;\r
++ else if(!wcscmp(s,L"wire")) res = MGL_FONT_WIRE;\r
++ else if(!wcsncmp(s,L"color",5)) res = MGL_COLOR_MASK + (0xff & s[5]);\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglFont::Convert(const wchar_t *str, unsigned *res) const\r
++{\r
++ size_t j=0;\r
++ wchar_t s[128]=L""; // TeX command and current char\r
++ for(size_t i=0;str[i];i++)\r
++ {\r
++ wchar_t ch = str[i];\r
++ if(ch=='\\') // It can be TeX command\r
++ {\r
++ if(wcschr(L"{}_^\\@# ",str[i+1])) // No, it is usual symbol\r
++ res[j++] = str[++i];\r
++ else // Yes, it is TeX command\r
++ {\r
++ size_t i0=i+1, k;\r
++ for(k=0;isalnum(str[++i]) && k<127;k++) s[k] = str[i];\r
++ s[k] = 0;\r
++ size_t r = Parse(s);\r
++ if(r==unsigned(-2)) // command not found, so use next symbol itself\r
++ { res[j++] = str[i0]; i = i0; }\r
++ else if(r)\r
++ {\r
++ res[j++] = r;\r
++ if(str[i]>' ') i--;\r
++ if(str[i]==0) break;\r
++ }\r
++ }\r
++ }\r
++ else if(ch=='-' && str[i+1]=='-') { res[j++] = 0x2212; i++; }\r
++ else if(ch=='\b'){}\r
++ else if(ch<=' ' && ch!='\n') res[j++] = ' '; // no \t at this moment :(\r
++ else if(ch=='_') res[j++] = MGL_FONT_LOWER;\r
++ else if(ch=='^') res[j++] = MGL_FONT_UPPER;\r
++ else if(ch=='@') res[j++] = MGL_FONT_UPPER|MGL_FONT_LOWER;\r
++ else if(ch=='{') res[j++] = unsigned(-3);\r
++ else if(ch=='}') res[j++] = unsigned(-4);\r
++ else if(ch=='#' && str[i+1]>' ')\r
++ res[j++] = MGL_COLOR_MASK + (0xff & str[++i]); // TODO inline colors -- stack of RGBA colors + index\r
++ else res[j++] = ch; // It is just symbol\r
++ }\r
++ res[j] = 0;\r
++}\r
++//-----------------------------------------------------------------------------\r
++float mglFont::get_ptr(long &i,unsigned *str, unsigned **b1, unsigned **b2,float &w1,float &w2, float f1, float f2, int st) const\r
++{\r
++ static unsigned s1[2]={0,0}, s2[2]={0,0};\r
++ i++;\r
++ if(str[i]==unsigned(-3))\r
++ {\r
++ i++; *b1 = str+i;\r
++ for(long k=1;k>0 && str[i];i++)\r
++ {\r
++ if(str[i]==unsigned(-4)) k--;\r
++ if(str[i]==unsigned(-3)) k++;\r
++ }\r
++ str[i-1]=0;\r
++ }\r
++ else { s1[0] = str[i]; *b1 = s1; i++; }\r
++ if(str[i]==unsigned(-3))\r
++ {\r
++ i++; *b2 = str+i;\r
++ for(long k=1;k>0 && str[i];i++)\r
++ {\r
++ if(str[i]==unsigned(-4)) k--;\r
++ if(str[i]==unsigned(-3)) k++;\r
++ }\r
++ str[i-1]=0;\r
++ }\r
++ else { s2[0] = str[i]; *b2 = s2; i++; }\r
++ i--;\r
++ w1 = Puts(*b1, 0, 0, f1, 0x10|st,'k','k');\r
++ w2 = Puts(*b2, 0, 0, f2, 0x10|st,'k','k');\r
++ return w1>w2 ? w1 : w2;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglFont::draw_ouline(int st, float x, float y, float f, float g, float ww, float ccol) const\r
++{\r
++ if(st&MGL_FONT_OLINE)\r
++ gr->Glyph(x,y+499*f/g, ww*g, (st&MGL_FONT_WIRE)?12:8, 0, ccol);\r
++ if(st&MGL_FONT_ULINE)\r
++ gr->Glyph(x,y-200*f/g, ww*g, (st&MGL_FONT_WIRE)?12:8, 0, ccol);\r
++}\r
++//-----------------------------------------------------------------------------\r
++#define MGL_CLEAR_STYLE {st = style; yy = y; ff = f; ccol=c1+dc*i; a = (st/MGL_FONT_BOLD)&3;}\r
++float mglFont::Puts(const unsigned *text, float x,float y,float f,int style,float c1,float c2) const\r
++{\r
++ if(GetNumGlyph()==0) return 0;\r
++ float w=0; // string width\r
++ int st = style; // current style\r
++ unsigned *b1, *b2; // pointer to substring\r
++ unsigned *str; // string itself\r
++ float yy=y, ff=f, ww, w1, w2;\r
++ int a = (st/MGL_FONT_BOLD)&3;\r
++ long i;\r
++ for(i=0;text[i];i++);\r
++ float dc=i>1?(c2-c1)/(i-1):0;\r
++ str = new unsigned[i+1];\r
++ memcpy(str,text,(i+1)*sizeof(unsigned));\r
++\r
++ float ccol = 0;\r
++ for(long i=0;str[i];i++)\r
++ {\r
++ ccol = ccol<0?ccol:c1+dc*i;\r
++ unsigned s = str[i]; ww = 0;\r
++ if(s==unsigned(-3)) // recursion call here\r
++ {\r
++ i++; b1 = str+i;\r
++ for(long k=1;k>0 && str[i];i++)\r
++ {\r
++ if(str[i]==unsigned(-4)) k--;\r
++ if(str[i]==unsigned(-3)) k++;\r
++ }\r
++ str[i-1]=0; i--;\r
++ ww = Puts(b1, x, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ if(gr && !(style&0x10)) // add under-/over- line now\r
++ draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
++ MGL_CLEAR_STYLE\r
++ }\r
++ else if(s=='\n') // newline\r
++ {\r
++ ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff, st);\r
++ Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ Puts(b2, x+(ww-w2)/2, yy-660*ff/fact[a], ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ MGL_CLEAR_STYLE\r
++ }\r
++ else if(s==unsigned(-9)) // underset\r
++ {\r
++ ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff/4, st);\r
++ Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ Puts(b2, x+(ww-w2)/2, yy-150*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ if(gr && !(style&0x10)) // add under-/over- line now\r
++ draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
++ MGL_CLEAR_STYLE\r
++ }\r
++ else if(s==unsigned(-8)) // overset\r
++ {\r
++ ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff/4, st);\r
++ Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ Puts(b2, x+(ww-w2)/2, yy+375*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ if(gr && !(style&0x10)) // add under-/over- line now\r
++ draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
++ MGL_CLEAR_STYLE\r
++ }\r
++ else if(s==unsigned(-12)) // sub\r
++ {\r
++ ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff/4, st);\r
++ Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ Puts(b2, x+(ww-w2)/2, yy-250*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ if(gr && !(style&0x10)) // add under-/over- line now\r
++ draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
++ MGL_CLEAR_STYLE\r
++ }\r
++ else if(s==unsigned(-13)) // sup\r
++ {\r
++ ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff/4, st);\r
++ Puts(b1, x+(ww-w1)/2, yy, ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ Puts(b2, x+(ww-w2)/2, yy+450*ff/fact[a], ff/4, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ if(gr && !(style&0x10)) // add under-/over- line now\r
++ draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
++ MGL_CLEAR_STYLE\r
++ }\r
++ else if(s==unsigned(-11)) // stackl\r
++ {\r
++ ww = get_ptr(i, str, &b1, &b2, w1, w2, ff*0.45, ff*0.45, st);\r
++ Puts(b1, x, yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ Puts(b2, x, yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ if(gr && !(style&0x10)) // add under-/over- line now\r
++ draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
++ MGL_CLEAR_STYLE\r
++ }\r
++ else if(s==unsigned(-10)) // stacr\r
++ {\r
++ ww = get_ptr(i, str, &b1, &b2, w1, w2, ff*0.45, ff*0.45, st);\r
++ Puts(b1, x+(ww-w1), yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ Puts(b2, x+(ww-w2), yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ if(gr && !(style&0x10)) // add under-/over- line now\r
++ draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
++ MGL_CLEAR_STYLE\r
++ }\r
++ else if(s==unsigned(-7)) // stack\r
++ {\r
++ ww = get_ptr(i, str, &b1, &b2, w1, w2, ff*0.45, ff*0.45, st);\r
++ Puts(b1, x+(ww-w1)/2, yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ Puts(b2, x+(ww-w2)/2, yy-110*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ if(gr && !(style&0x10)) // add under-/over- line now\r
++ draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
++ MGL_CLEAR_STYLE\r
++ }\r
++ else if(s==unsigned(-6)) // frac\r
++ {\r
++ ww = get_ptr(i, str, &b1, &b2, w1, w2, ff*0.45, ff*0.45, st);\r
++ Puts(b1, x+(ww-w1)/2, yy+250*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ Puts(b2, x+(ww-w2)/2, yy-60*ff/fact[a], ff*0.45, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ if(gr && !(style&0x10)) // add under-/over- line now\r
++ {\r
++ draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
++ gr->Glyph(x,y+150*f/fact[a], ww*fact[a], (st&MGL_FONT_WIRE)?12:8, 0, ccol);\r
++ }\r
++ MGL_CLEAR_STYLE\r
++ }\r
++ else if(s==unsigned(-15)) // dfrac\r
++ {\r
++ ww = get_ptr(i, str, &b1, &b2, w1, w2, ff, ff, st);\r
++ Puts(b1, x+(ww-w1)/2, yy+315*ff/fact[a], ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ Puts(b2, x+(ww-w2)/2, yy-405*ff/fact[a], ff, (st&(~MGL_FONT_OLINE)&(~MGL_FONT_ULINE)), ccol,ccol);\r
++ if(gr && !(style&0x10)) // add under-/over- line now\r
++ {\r
++ draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
++ gr->Glyph(x,y+150*f/fact[a], ww*fact[a], (st&MGL_FONT_WIRE)?12:8, 0, ccol);\r
++ }\r
++ MGL_CLEAR_STYLE\r
++ }\r
++ else if(s==unsigned(-4)) MGL_CLEAR_STYLE // should be never here but if I miss sth ...\r
++ else if(s==unsigned(-14)) // script symbols\r
++ {\r
++ long k=1;\r
++ if(str[i+1]==unsigned(-3)) for(long j=i+2;k>0 && str[j];j++)\r
++ {\r
++ if(str[j]==unsigned(-3)) k++;\r
++ if(str[j]==unsigned(-4)) k--;\r
++ if(iswlower(str[j]))\r
++ str[j] = MGL_FONT_UPPER|MGL_FONT_LOWER|towupper(str[j]);\r
++ }\r
++ }\r
++ else if(s==unsigned(-5)) // large symbol\r
++ ff *= 1.5;\r
++ else if(s==unsigned(-1)) // set normal font\r
++ st = style & MGL_FONT_ROMAN;\r
++ else if((s&MGL_COLOR_MASK)==MGL_COLOR_MASK) // color specification\r
++ ccol = -float(s & 0xff); // TODO inline colors -- make textures\r
++ else\r
++ {\r
++ unsigned ss = s&MGL_FONT_MASK;\r
++ if(ss) // draw symbol (glyph)\r
++ {\r
++ long j = Internal('!');\r
++ float dx=0;\r
++ if(ss>' ')\r
++ {\r
++ j = Internal(ss);\r
++ if(j==-1) continue;\r
++ if(s & MGL_FONT_ZEROW)\r
++ {\r
++ long j=1;\r
++ yy += 100*ff/fact[a];\r
++ while(str[i+j]>=unsigned(-15)) j++;\r
++ unsigned sn = str[i+j];\r
++ if(sn<unsigned(-15) && (sn&MGL_FONT_MASK)>' ') // specially center\r
++ {\r
++ long jj = Internal(sn&MGL_FONT_MASK);\r
++ dx = jj<0?0:0.75*ff*(GetWidth(a,jj)-GetWidth(a,j))/fact[a];\r
++ if(dx<0) dx=0;\r
++ }\r
++ }\r
++ if(gr && !(style&0x10))\r
++ {\r
++ if(st & MGL_FONT_WIRE) gr->Glyph(x+dx,yy,ff,a+4,j,ccol);\r
++ else gr->Glyph(x+dx,yy,ff,a,j,ccol);\r
++ }\r
++ }\r
++ ww = j>=0?ff*GetWidth(a,j)/fact[a]:0;\r
++ if(gr && !(style&0x10)) // add under-/over- line now\r
++ draw_ouline(st,x,y,f,fact[a],ww,ccol);\r
++ if(s & MGL_FONT_ZEROW) ww = 0;\r
++ MGL_CLEAR_STYLE\r
++ }\r
++ // apply new styles\r
++ if(s/MGL_FONT_BOLD) st = st | (s & MGL_FONT_STYLE);\r
++ a = (st/MGL_FONT_BOLD)&3;\r
++ ss = (s/MGL_FONT_UPPER)%4;\r
++ if(ss)\r
++ {\r
++ if(ss==1) { ff *=0.6; yy += 200*ff/fact[a]; } // = 500*0.4\r
++ else if(ss==2) { ff *=0.6; yy -= 80*ff/fact[a]; } // = -500*0.16\r
++ else if(ss==3) { ff *=0.8; yy += 0*60*ff/fact[a]; } // = 500*0.12\r
++ }\r
++ }\r
++ x += ww; w += ww;\r
++ }\r
++ delete []str;\r
++ return w;\r
++}\r
++//-----------------------------------------------------------------------------\r
++// copy normal style as default for other styles\r
++void mglFont::main_copy()\r
++{\r
++#pragma omp parallel for\r
++ for(long i=0;i<long(glyphs.size());i++)\r
++ {\r
++ mglGlyphDescr &g = glyphs[i];\r
++ g.numl[1] = g.numl[2] = g.numl[3] = g.numl[0];\r
++ g.numt[1] = g.numt[2] = g.numt[3] = g.numt[0];\r
++ g.ln[1] = g.ln[2] = g.ln[3] = g.ln[0];\r
++ g.tr[1] = g.tr[2] = g.tr[3] = g.tr[0];\r
++ g.width[1] = g.width[2] = g.width[3] = g.width[0];\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++bool mglFont::read_def()\r
++{\r
++ // copy default factor for other font styles;\r
++ fact[1] = fact[2] = fact[3] = fact[0] = mgl_fact*mgl_fgen;\r
++ Buf = new short[mgl_cur]; // prealocate buffer\r
++ memset(Buf,0,mgl_cur*sizeof(short));\r
++ // now allocate memory for all fonts\r
++ mem_alloc(mgl_numg);\r
++ // and load symbols itself\r
++#ifndef WIN32 // win32 don't initialized threads before main()\r
++#pragma omp parallel for\r
++#endif\r
++ for(size_t i=0;i<mgl_numg;i++)\r
++ {\r
++ mglGlyphDescr &g = glyphs[i];\r
++ g.id = mgl_gen_fnt[i][0];\r
++ g.width[0] = g.width[1] = g.width[2] = g.width[3] = mgl_gen_fnt[i][1];\r
++ g.numl[0] = g.numl[1] = g.numl[2] = g.numl[3] = mgl_gen_fnt[i][2];\r
++ g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = mgl_gen_fnt[i][3];\r
++ g.numt[0] = g.numt[1] = g.numt[2] = g.numt[3] = mgl_gen_fnt[i][4];\r
++ g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = mgl_gen_fnt[i][5];\r
++ }\r
++ memcpy(Buf, mgl_buf_fnt, mgl_cur*sizeof(short));\r
++ numb = mgl_cur;\r
++ return true;\r
++}\r
++//-----------------------------------------------------------------------------\r
++bool mglFont::read_data(const char *fname, int s, std::vector<short> &buf, std::vector<mglGlyphDescr> &extra)\r
++{\r
++ gzFile fp;\r
++ char str[256];\r
++ int n, tmpw, tmpnl, tmpnt, retVal;\r
++ unsigned ss, tmpi, tmppl, tmppt;\r
++ fp = gzopen(fname,"r"); if(!fp) return false; // false if no file\r
++ // first string is comment (not used), second string have information\r
++ if(!gzgets(fp,str,256) || strncmp(str,"# font",6) || !gzgets(fp,str,256))\r
++ { gzclose(fp); return false; }\r
++ retVal = sscanf(str, "%d%f%u", &n, fact+s, &ss);\r
++ //Check sscanf read all data (3 items)\r
++ if(retVal != 3) { gzclose(fp); return false; }\r
++\r
++ for(int i=0;i<n;i++)\r
++ {\r
++ gzgets(fp,str,256);\r
++ retVal = sscanf(str,"%u%d%d%u%d%u", &tmpi, &tmpw, &tmpnl, &tmppl, &tmpnt, &tmppt);\r
++ if(retVal != 6) { gzclose(fp); buf.clear(); return false; }\r
++ long j=Internal(unsigned(tmpi));\r
++ if(j>=0) // known symbol\r
++ {\r
++ mglGlyphDescr &g = glyphs[j]; g.width[s] = tmpw;\r
++ g.ln[s] = -1-tmppl; g.tr[s] = -1-tmppt;\r
++ g.numl[s] = tmpnl; g.numt[s] = tmpnt;\r
++ }\r
++ else\r
++ {\r
++ mglGlyphDescr g; g.id = tmpi;\r
++ g.width[0] = g.width[1] = g.width[2] = g.width[3] = tmpw;\r
++ g.numl[0] = g.numl[1] = g.numl[2] = g.numl[3] = tmpnl;\r
++ g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = -1-tmppl;\r
++ g.numt[0] = g.numt[1] = g.numt[2] = g.numt[3] = tmpnt;\r
++ g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = -1-tmppt;\r
++#pragma omp critical\r
++ extra.push_back(g);\r
++ }\r
++ }\r
++ for(unsigned i=0;i<ss;i++)\r
++ {\r
++ for(int j=0;j<256;j++) if((str[j] = gzgetc(fp))<=' ') break;\r
++ buf.push_back(atoi(str));\r
++ }\r
++ gzclose(fp); // finish wire normal font\r
++ return true;\r
++}\r
++//-----------------------------------------------------------------------------\r
++bool mglFont::read_main(const char *fname, std::vector<short> &buf)\r
++{\r
++ gzFile fp;\r
++ int tmpi, tmpw, tmpnl, tmpnt;\r
++ unsigned s, tmppl, tmppt,numg;\r
++ char str[256];\r
++\r
++ fp = gzopen(fname,"r"); if(!fp) return false; // this font must be in any case\r
++ // first string is comment (not used), second string have information\r
++ if(!gzgets(fp,str,256) || strncmp(str,"# font",6) || !gzgets(fp,str,256))\r
++ { gzclose(fp); return false; }\r
++ sscanf(str, "%u%f%u", &numg, fact, &s);\r
++ fact[1] = fact[2] = fact[3] = fact[0]; // copy default factor for other font styles;\r
++ // now allocate memory for all fonts\r
++ mem_alloc(numg);\r
++ // and load symbols itself\r
++ for(size_t i=0;i<numg;i++)\r
++ {\r
++ gzgets(fp,str,256);\r
++ sscanf(str,"%d%d%d%u%d%u", &tmpi, &tmpw, &tmpnl, &tmppl, &tmpnt, &tmppt);\r
++ mglGlyphDescr &g = glyphs[i]; g.id = tmpi;\r
++ g.width[0] = g.width[1] = g.width[2] = g.width[3] = tmpw;\r
++ g.numl[0] = g.numl[1] = g.numl[2] = g.numl[3] = tmpnl;\r
++ g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = tmppl;\r
++ g.numt[0] = g.numt[1] = g.numt[2] = g.numt[3] = tmpnt;\r
++ g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = tmppt;\r
++ }\r
++ for(unsigned i=0;i<s;i++)\r
++ {\r
++ for(int j=0;j<256;j++) if((str[j] = gzgetc(fp))<=' ') break;\r
++ buf.push_back(atoi(str));\r
++ }\r
++ gzclose(fp); // finish wire normal font\r
++ return true;\r
++}\r
++//-----------------------------------------------------------------------------\r
++size_t mglFont::SaveBin(const char *fname)\r
++{\r
++ FILE *fp = fopen(fname,"wb");\r
++ if(!fp) return 0;\r
++ size_t sum=0;\r
++ fwrite(&numb,sizeof(size_t),1,fp); sum += sizeof(size_t);\r
++ fwrite(fact,sizeof(float),4,fp); sum += sizeof(float)*4;\r
++ fwrite(Buf,sizeof(short),numb,fp); sum += sizeof(short)*numb;\r
++ size_t len = glyphs.size();\r
++ fwrite(&len,sizeof(size_t),1,fp); sum += sizeof(long);\r
++ fwrite(&(glyphs[0]),sizeof(mglGlyphDescr),len,fp); sum += sizeof(mglGlyphDescr)*len;\r
++ fclose(fp); return sum;\r
++}\r
++//-----------------------------------------------------------------------------\r
++bool mglFont::LoadBin(const char *base, const char *path)\r
++{\r
++ Clear(); // first clear old\r
++ if(!path) path = MGL_FONT_PATH;\r
++ char str[256], sep='/';\r
++ snprintf(str,256,"%s%c%s.vfmb",path,sep,base?base:""); str[255]=0;\r
++ FILE *fp = fopen(str,"rb"); if(!fp) return false;\r
++ size_t s, len;\r
++ bool res = true;\r
++ s = fread(&numb,sizeof(size_t),1,fp);\r
++ if(s<1) res = false;\r
++ s = fread(fact,sizeof(float),4,fp);\r
++ if(s<4) res = false;\r
++ Buf = new short[numb];\r
++ s = fread(Buf,sizeof(short),numb,fp);\r
++ if(s<numb) res = false;\r
++ s = fread(&len,sizeof(size_t),1,fp);\r
++ if(s<1) res = false;\r
++ if(res)\r
++ {\r
++ glyphs.clear(); glyphs.resize(len);\r
++ s = fread(&(glyphs[0]),sizeof(mglGlyphDescr),len,fp);\r
++ if(s<len) res = false;\r
++ }\r
++// if(!res) Clear();\r
++ fclose(fp); return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++bool mglFont::Load(const char *base, const char *path)\r
++{\r
++// base = 0;\r
++ char *buf=0,sep='/';\r
++#ifdef WIN32\r
++ sep='\\';\r
++#endif\r
++ char str[256];\r
++ std::string loc = setlocale(LC_NUMERIC,"C");\r
++ if(!path) path = MGL_FONT_PATH;\r
++ if(base && *base)\r
++ {\r
++ buf = new char[strlen(base)+1];\r
++ strcpy(buf,base);\r
++ if(strchr(buf,sep))\r
++ {\r
++ int i;\r
++ for(i=strlen(buf);i>=0 && buf[i]!=sep;i--);\r
++ path = buf; buf[i]=0; base = buf+i+1;\r
++ }\r
++ if(LoadBin(base,path))\r
++ { delete []buf; return true; }\r
++ }\r
++ Clear(); // first clear old\r
++\r
++ snprintf(str,256,"%s%c%s.vfm",path,sep,base?base:""); str[255]=0;\r
++ std::vector<short> norm, bold, ital, both;\r
++ if(!(base && *base) || !read_main(str,norm))\r
++ {\r
++ read_def(); setlocale(LC_NUMERIC,loc.c_str());\r
++ if(buf) delete []buf;\r
++ return true;\r
++ }\r
++ fact[1] = fact[2] = fact[3] = fact[0];\r
++\r
++ std::vector<mglGlyphDescr> ex_b,ex_i,ex_bi;\r
++#pragma omp parallel sections\r
++ {\r
++ //================== bold ===========================================\r
++#pragma omp section\r
++ { char str[256]; snprintf(str,256,"%s%c%s_b.vfm",path,sep,base); // this file may absent\r
++ str[255]=0; read_data(str, 1, bold, ex_b); }\r
++\r
++ //================== italic =========================================\r
++#pragma omp section\r
++ { char str[256]; snprintf(str,256,"%s%c%s_i.vfm",path,sep,base);\r
++ str[255]=0; read_data(str, 2, ital, ex_i); }\r
++\r
++ //================== bold-italic ====================================\r
++#pragma omp section\r
++ { char str[256]; snprintf(str,256,"%s%c%s_bi.vfm",path,sep,base);\r
++ str[255]=0; read_data(str, 3, both, ex_bi); }\r
++ }\r
++\r
++ // now collect data\r
++ numb = norm.size()+bold.size()+ital.size()+both.size();\r
++ Buf = new short[numb];\r
++ memcpy(Buf,&norm[0],norm.size()*sizeof(short));\r
++ long cur = norm.size(), len = long(bold.size());\r
++ if(bold.size()>0)\r
++ memcpy(Buf+cur,&bold[0],bold.size()*sizeof(short));\r
++#pragma omp parallel for\r
++ for(long i=0;i<long(GetNumGlyph());i++) if(glyphs[i].ln[1]<0)\r
++ { glyphs[i].ln[1] = cur-1-glyphs[i].ln[1]; glyphs[i].tr[1] = cur-1-glyphs[i].tr[1]; }\r
++#pragma omp parallel for\r
++ for(long i=0;i<long(ex_b.size());i++) if(ex_b[i].ln[1]<0)\r
++ {\r
++ mglGlyphDescr &g = ex_b[i];\r
++ g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = cur-1-g.ln[1];\r
++ g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = cur-1-g.tr[1];\r
++ }\r
++ cur += len; len = long(ital.size());\r
++ if(ital.size()>0)\r
++ memcpy(Buf+cur,&ital[0],ital.size()*sizeof(short));\r
++#pragma omp parallel for\r
++ for(long i=0;i<long(GetNumGlyph());i++) if(glyphs[i].ln[2]<0)\r
++ { glyphs[i].ln[2] = cur-1-glyphs[i].ln[2]; glyphs[i].tr[2] = cur-1-glyphs[i].tr[2]; }\r
++#pragma omp parallel for\r
++ for(long i=0;i<long(ex_i.size());i++) if(ex_i[i].ln[2]<0)\r
++ {\r
++ mglGlyphDescr &g = ex_i[i];\r
++ g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = cur-1-g.ln[2];\r
++ g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = cur-1-g.tr[2];\r
++ }\r
++ cur += len;\r
++ if(both.size()>0)\r
++ memcpy(Buf+cur,&both[0],both.size()*sizeof(short));\r
++#pragma omp parallel for\r
++ for(long i=0;i<long(GetNumGlyph());i++) if(glyphs[i].ln[3]<0)\r
++ { glyphs[i].ln[3] = cur-1-glyphs[i].ln[3]; glyphs[i].tr[3] = cur-1-glyphs[i].tr[3]; }\r
++#pragma omp parallel for\r
++ for(long i=0;i<long(ex_bi.size());i++) if(ex_bi[i].ln[3]<0)\r
++ {\r
++ mglGlyphDescr &g = ex_bi[i];\r
++ g.ln[0] = g.ln[1] = g.ln[2] = g.ln[3] = cur-1-g.ln[3];\r
++ g.tr[0] = g.tr[1] = g.tr[2] = g.tr[3] = cur-1-g.tr[3];\r
++ }\r
++ // now add missing symbols\r
++ if(ex_b.size()==0) ex_b = ex_i;\r
++ else\r
++ {\r
++ for(size_t i=0;i<ex_i.size();i++) // add from ex_i\r
++ {\r
++ long j = mgl_internal_code(ex_i[i].id, ex_b);\r
++ if(j>=0) // known symbol\r
++ {\r
++ mglGlyphDescr &g = ex_b[j], &f = ex_i[i];\r
++ g.width[2] = f.width[2];\r
++ g.ln[2] = f.ln[2]; g.tr[2] = f.tr[2];\r
++ g.numl[2] = f.numl[2]; g.numt[2] = f.numt[2];\r
++ }\r
++ else ex_b.push_back(ex_i[i]);\r
++ }\r
++ std::sort(ex_b.begin(),ex_b.end());\r
++ }\r
++ if(ex_b.size()==0) ex_b = ex_bi;\r
++ else\r
++ {\r
++ for(size_t i=0;i<ex_bi.size();i++) // add from ex_bi\r
++ {\r
++ long j = mgl_internal_code(ex_bi[i].id, ex_b);\r
++ if(j>=0) // known symbol\r
++ {\r
++ mglGlyphDescr &g = ex_b[j], &f = ex_bi[i];\r
++ g.width[2] = f.width[3];\r
++ g.ln[2] = f.ln[3]; g.tr[2] = f.tr[3];\r
++ g.numl[2] = f.numl[3]; g.numt[2] = f.numt[3];\r
++ }\r
++ else ex_b.push_back(ex_bi[i]);\r
++ }\r
++ std::sort(ex_b.begin(),ex_b.end());\r
++ }\r
++ if(ex_b.size()>0)\r
++ {\r
++ glyphs.reserve(ex_b.size()); // preallocate memory\r
++ glyphs.insert(glyphs.end(), ex_b.begin(), ex_b.end());\r
++ std::sort(glyphs.begin(),glyphs.end());\r
++ }\r
++\r
++ // Finally normalize all factors\r
++ fact[0] *= mgl_fgen; fact[1] *= mgl_fgen;\r
++ fact[2] *= mgl_fgen; fact[3] *= mgl_fgen;\r
++ setlocale(LC_NUMERIC,loc.c_str());\r
++ if(buf) delete []buf;\r
++ return true;\r
++}\r
++//-----------------------------------------------------------------------------\r
++#if MGL_HAVE_PTHREAD\r
++pthread_mutex_t mutexRnd;\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++float mgl_cos[360];\r
++void MGL_NO_EXPORT mgl_init()\r
++{\r
++ mgl_textdomain(NULL,"");\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_init(&mutexRnd,0);\r
++#endif\r
++#ifndef WIN32 // win32 don't initialized threads before main()\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=0;i<360;i++) mgl_cos[i] = cos(i*M_PI/180.);\r
++}\r
++//-----------------------------------------------------------------------------\r
++mglFont::mglFont(const char *name, const char *path)\r
++{\r
++ parse = true; gr=0; Buf=0;\r
++// if(this==&mglDefFont) Load(name, path); else Copy(&mglDefFont);\r
++ if(name && *name) Load(name, path);\r
++ else if(this!=&mglDefFont) Copy(&mglDefFont);\r
++ else\r
++ {\r
++ mgl_init(); // NOTE: this call init function for the library.\r
++ Load(MGL_DEF_FONT_NAME,0);\r
++ }\r
++}\r
++mglFont::~mglFont() { if(Buf) delete []Buf; }\r
++void mglFont::Restore() { Copy(&mglDefFont); }\r
++//-----------------------------------------------------------------------------\r
++void mglFont::Clear()\r
++{\r
++//#pragma omp critical(font)\r
++ { if(Buf) delete []Buf; Buf=0; glyphs.clear(); }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglFont::Copy(mglFont *f)\r
++{\r
++ if(!f || f==this) return;\r
++#pragma omp critical(font)\r
++ { if(Buf) delete []Buf; Buf=0; }\r
++ // copy scale factors\r
++ memcpy(fact,f->fact,4*sizeof(float));\r
++ // copy symbols descriptions\r
++ numb = f->numb; Buf = new short[numb]; memcpy(Buf, f->Buf, numb*sizeof(short));\r
++ // copy symbol parameters\r
++ glyphs.resize(f->glyphs.size());\r
++ memcpy(&glyphs[0],&(f->glyphs)[0],glyphs.size()*sizeof(mglGlyphDescr));\r
++}\r
++//-----------------------------------------------------------------------------\r
++long MGL_EXPORT mgl_check_tex_table()\r
++{\r
++ size_t i=0; while(mgl_tex_symb[i].tex[0]) i++;\r
++ long res = 0;\r
++ if(mgl_tex_num!=i)\r
++ { printf("real=%zu, set=%zu\n",i,mgl_tex_num); res = -1; }\r
++ for(i=0;mgl_tex_symb[i].tex[0];i++)\r
++ {\r
++ mglTeXsymb tst, *rts; tst.tex = mgl_tex_symb[i].tex;\r
++ rts = (mglTeXsymb *) bsearch(&tst, mgl_tex_symb, mgl_tex_num, sizeof(mglTeXsymb), mgl_tex_symb_cmp);\r
++ if(!rts)\r
++<<<<<<< HEAD\r
++ { printf("Bad '%ls' at %zu\n",mgl_tex_symb[i].tex,i); res = 1+i; }\r
++ }\r
++ return res;\r
++}\r
++=======\r
++ { printf(_("Bad '%ls' at %zu\n"),mgl_tex_symb[i].tex,i); res = 1+i; }\r
++ }\r
++ return res;\r
++}\r
++//---------------------------------------------------------------------------\r
++bool MGL_NO_EXPORT test_transl(const char *p)\r
++{\r
++ if(!p) return false;\r
++#if MGL_USE_GETTEXT\r
++ std::string f = std::string(p) + "/ru/LC_MESSAGES/mathgl.mo";\r
++ FILE *fp = fopen(f.c_str(),"r");\r
++ if(fp)\r
++ {\r
++ bindtextdomain("mathgl", p);\r
++ textdomain("mathgl");\r
++ fclose(fp); return true;\r
++ }\r
++#endif\r
++ return false;\r
++}\r
++void MGL_EXPORT mgl_textdomain(const char *argv0, const char *loc)\r
++{\r
++ static const char *argv=NULL;\r
++ if(!argv0) argv0=argv; else argv=argv0;\r
++ setlocale(LC_ALL, loc); setlocale(LC_NUMERIC, "C");\r
++#if MGL_USE_GETTEXT\r
++ if(!test_transl(MGL_INSTALL_DIR"/share/locale/"))\r
++ if(!test_transl("/usr/share/locale/"))\r
++ if(!test_transl("/usr/local/share/locale/"))\r
++ if(!test_transl(getcwd(NULL,0)))\r
++ {\r
++ const char *f = argv0?strrchr(argv0,'/'):NULL;\r
++#ifdef WIN32\r
++ if(!f) f = argv0?strrchr(argv0,'\\'):NULL;\r
++#endif\r
++ if(f)\r
++ {\r
++ std::string p(argv0,f-argv0);\r
++ if(!test_transl(p.c_str()))\r
++ return;\r
++ }\r
++ else return;\r
++ }\r
++#endif\r
++}\r
++void MGL_EXPORT mgl_textdomain_(const char *locale, int l)\r
++{ char *s=new char[l+1]; memcpy(s,locale,l); s[l]=0;\r
++ mgl_textdomain(NULL,s); delete []s; }\r
++//---------------------------------------------------------------------------\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * other.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include "mgl2/other.h"\r
++#include "mgl2/surf.h"\r
++#include "mgl2/cont.h"\r
++#include "mgl2/eval.h"\r
++#include "mgl2/data.h"\r
++#include "mgl2/base.h"\r
++//-----------------------------------------------------------------------------\r
++<<<<<<< HEAD\r
++=======\r
++void MGL_NO_EXPORT mgl_surf_gen(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, HCDT a, const char *sch);\r
++//-----------------------------------------------------------------------------\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++HCDT MGL_NO_EXPORT fill_slice_x(HMGL gr, double sv, HCDT a, mglDataV &xx, mglDataV &yy, mglDataV &zz, mglData &aa)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
++ if(l>1)\r
++ {\r
++ aa.Create(m,l); xx.Create(m,l); yy.Create(m,l); zz.Create(m,l);\r
++ mreal d = (n-1)*(sv - gr->Min.x)/(gr->Max.x - gr->Min.x);\r
++ long k = long(d); d = d - k;\r
++ if(k>n-2) { k=n-2; d=1; }\r
++ if(k<0) { k=0; d=0; }\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<l;j++) for(long i=0;i<m;i++)\r
++ aa.a[i+m*j] = a->v(k,i,j)*(1-d) + d*a->v(k+1,i,j);\r
++ a = &aa;\r
++ }\r
++ else\r
++ { xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); }\r
++ xx.Fill(sv, sv);\r
++ yy.Fill(gr->Min.y, gr->Max.y,'x');\r
++ zz.Fill(gr->Min.z, gr->Max.z,'y');\r
++ return a;\r
++}\r
++//-----------------------------------------------------------------------------\r
++HCDT MGL_NO_EXPORT fill_slice_y(HMGL gr, double sv, HCDT a, mglDataV &xx, mglDataV &yy, mglDataV &zz, mglData &aa)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
++ if(l>1)\r
++ {\r
++ aa.Create(n,l); xx.Create(n,l); yy.Create(n,l); zz.Create(n,l);\r
++ mreal d = (m-1)*(sv - gr->Min.y)/(gr->Max.y - gr->Min.y);\r
++ long k = long(d); d = d - k;\r
++ if(k>m-2) { k=m-2; d=1; }\r
++ if(k<0) { k=0; d=0; }\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<l;j++) for(long i=0;i<n;i++)\r
++ aa.a[i+n*j] = a->v(i,k,j)*(1-d) + d*a->v(i,k+1,j);\r
++ a = &aa;\r
++ }\r
++ else\r
++ { xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); }\r
++ yy.Fill(sv, sv);\r
++ xx.Fill(gr->Min.x, gr->Max.x,'x');\r
++ zz.Fill(gr->Min.z, gr->Max.z,'y');\r
++ return a;\r
++}\r
++//-----------------------------------------------------------------------------\r
++HCDT MGL_NO_EXPORT fill_slice_z(HMGL gr, double sv, HCDT a, mglDataV &xx, mglDataV &yy, mglDataV &zz, mglData &aa)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
++ xx.Create(n,m); yy.Create(n,m); zz.Create(n,m);\r
++ if(l>1)\r
++ {\r
++ aa.Create(n,m);\r
++ mreal d = (l-1)*(sv - gr->Min.z)/(gr->Max.z - gr->Min.z);\r
++ long k = long(d); d = d - k;\r
++ if(k>l-2) { k=l-2; d=1; }\r
++ if(k<0) { k=0; d=0; }\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<m;j++) for(long i=0;i<n;i++)\r
++ aa.a[i+n*j] = a->v(i,j,k)*(1-d) + d*a->v(i,j,k+1);\r
++ a = &aa;\r
++ }\r
++ zz.Fill(sv, sv);\r
++ yy.Fill(gr->Min.y, gr->Max.y,'y');\r
++ xx.Fill(gr->Min.x, gr->Max.x,'x');\r
++ return a;\r
++}\r
++//-----------------------------------------------------------------------------\r
++//\r
++// DensX, DensY, DensZ series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_dens_x(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy();\r
++ if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"DensX"); return; }\r
++ gr->SaveState(opt);\r
++ if(mgl_isnan(sv)) sv = gr->GetOrgX('x');\r
++ if(sv<gr->Min.x || sv>gr->Max.x) { gr->SetWarn(mglWarnSlc,"DensX"); gr->LoadState(); return; }\r
++ mglDataV xx,yy,zz; mglData aa;\r
++ a = fill_slice_x(gr,sv,a,xx,yy,zz,aa);\r
++ mgl_surf_gen(gr, &xx,&yy,&zz,a, 0, sch);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_dens_y(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy();\r
++ if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"DensY"); return; }\r
++ gr->SaveState(opt);\r
++ if(mgl_isnan(sv)) sv = gr->GetOrgY('y');\r
++ if(sv<gr->Min.y || sv>gr->Max.y) { gr->SetWarn(mglWarnSlc,"DensY"); gr->LoadState(); return; }\r
++ mglDataV xx,yy,zz; mglData aa;\r
++ a = fill_slice_y(gr,sv,a,xx,yy,zz,aa);\r
++ mgl_surf_gen(gr, &xx,&yy,&zz,a, 0, sch);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_dens_z(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy();\r
++ if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"DensZ"); return; }\r
++ gr->SaveState(opt);\r
++ if(mgl_isnan(sv)) sv = gr->GetOrgZ('z');\r
++ if(sv<gr->Min.z || sv>gr->Max.z) { gr->SetWarn(mglWarnSlc,"DensZ"); gr->LoadState(); return; }\r
++ mglDataV xx,yy,zz; mglData aa;\r
++ a = fill_slice_z(gr,sv,a,xx,yy,zz,aa);\r
++ mgl_surf_gen(gr, &xx,&yy,&zz,a, 0, sch);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_dens_x_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_dens_x(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_dens_y_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{\r
++ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_dens_y(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_dens_z_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{\r
++ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_dens_z(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// ContX, ContY, ContZ series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cont_gen(HMGL gr, mreal val, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, int text,long ak);\r
++void MGL_EXPORT mgl_cont_x_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy();\r
++ if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContX"); return; }\r
++ gr->SaveState(opt);\r
++ if(mgl_isnan(sv)) sv = gr->GetOrgX('x');\r
++ if(sv<gr->Min.x || sv>gr->Max.x) { gr->SetWarn(mglWarnSlc,"ContX"); gr->LoadState(); return; }\r
++ static int cgid=1; gr->StartGroup("ContX",cgid++);\r
++ mglDataV xx,yy,zz; mglData aa;\r
++\r
++ int text=0;\r
++ if(mglchr(sch,'t')) text=1;\r
++ if(mglchr(sch,'T')) text=2;\r
++ long ss=gr->AddTexture(sch);\r
++ gr->SetPenPal(sch);\r
++\r
++ a = fill_slice_x(gr,sv,a,xx,yy,zz,aa);\r
++#pragma omp parallel for\r
++ for(long i=0;i<v->GetNx();i++)\r
++ {\r
++ mreal v0 = v->v(i);\r
++ mgl_cont_gen(gr,v0,a,&xx,&yy,&zz,gr->GetC(ss,v0),text,0);\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cont_y_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy();\r
++ if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContY"); return; }\r
++ gr->SaveState(opt);\r
++ if(mgl_isnan(sv)) sv = gr->GetOrgY('y');\r
++ if(sv<gr->Min.y || sv>gr->Max.y) { gr->SetWarn(mglWarnSlc,"ContY"); gr->LoadState(); return; }\r
++ static int cgid=1; gr->StartGroup("ContY",cgid++);\r
++ mglDataV xx,yy,zz; mglData aa;\r
++\r
++ int text=0;\r
++ if(mglchr(sch,'t')) text=1;\r
++ if(mglchr(sch,'T')) text=2;\r
++ long ss=gr->AddTexture(sch);\r
++ gr->SetPenPal(sch);\r
++\r
++ a = fill_slice_y(gr,sv,a,xx,yy,zz,aa);\r
++#pragma omp parallel for\r
++ for(long i=0;i<v->GetNx();i++)\r
++ {\r
++ mreal v0 = v->v(i);\r
++ mgl_cont_gen(gr,v0,a,&xx,&yy,&zz,gr->GetC(ss,v0),text,0);\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cont_z_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy();\r
++ if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContZ"); return; }\r
++ gr->SaveState(opt);\r
++ if(mgl_isnan(sv)) sv = gr->GetOrgZ('z');\r
++ if(sv<gr->Min.z || sv>gr->Max.z) { gr->SetWarn(mglWarnSlc,"ContZ"); gr->LoadState(); return; }\r
++ static int cgid=1; gr->StartGroup("ContZ",cgid++);\r
++ mglDataV xx,yy,zz; mglData aa;\r
++\r
++ int text=0;\r
++ if(mglchr(sch,'t')) text=1;\r
++ if(mglchr(sch,'T')) text=2;\r
++ long ss=gr->AddTexture(sch);\r
++ gr->SetPenPal(sch);\r
++\r
++ a = fill_slice_z(gr,sv,a,xx,yy,zz,aa);\r
++#pragma omp parallel for\r
++ for(long i=0;i<v->GetNx();i++)\r
++ {\r
++ mreal v0 = v->v(i);\r
++ mgl_cont_gen(gr,v0,a,&xx,&yy,&zz,gr->GetC(ss,v0),text,0);\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cont_x(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5);\r
++ mglData v(Num);\r
++ for(long i=0;i<Num;i++) v.a[i] = gr->Min.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1);\r
++ mgl_cont_x_val(gr,&v,a,sch,sv,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cont_y(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5);\r
++ mglData v(Num);\r
++ for(long i=0;i<Num;i++) v.a[i] = gr->Min.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1);\r
++ mgl_cont_y_val(gr,&v,a,sch,sv,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cont_z(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5);\r
++ mglData v(Num);\r
++ for(long i=0;i<Num;i++) v.a[i] = gr->Min.c + (gr->Max.c-gr->Min.c)*mreal(i+1)/(Num+1);\r
++ mgl_cont_z_val(gr,&v,a,sch,sv,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cont_x_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_cont_x(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cont_y_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_cont_y(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cont_z_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_cont_z(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cont_x_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_cont_x_val(_GR_, _DA_(v), _DA_(a), s, *sv, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cont_y_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_cont_y_val(_GR_, _DA_(v), _DA_(a), s, *sv, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cont_z_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_cont_z_val(_GR_, _DA_(v), _DA_(a), s, *sv, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// ContFX, ContFY, ContFZ series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_contf_gen(HMGL gr, mreal v1, mreal v2, HCDT a, HCDT x, HCDT y, HCDT z, mreal c, long ak);\r
++void MGL_EXPORT mgl_contf_x_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy();\r
++ if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContFX"); return; }\r
++ gr->SaveState(opt);\r
++ if(mgl_isnan(sv)) sv = gr->GetOrgX('x');\r
++ if(sv<gr->Min.x || sv>gr->Max.x) { gr->SetWarn(mglWarnSlc,"ContFX"); gr->LoadState(); return; }\r
++ static int cgid=1; gr->StartGroup("ContFX",cgid++);\r
++ mglDataV xx,yy,zz; mglData aa;\r
++ long ss=gr->AddTexture(sch);\r
++\r
++ a = fill_slice_x(gr,sv,a,xx,yy,zz,aa);\r
++#pragma omp parallel for\r
++ for(long i=0;i<v->GetNx()-1;i++)\r
++ {\r
++ mreal v0 = v->v(i);\r
++ mgl_contf_gen(gr,v0,v->v(i+1),a,&xx,&yy,&zz,gr->GetC(ss,v0),0);\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_contf_y_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy();\r
++ if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContFY"); return; }\r
++ gr->SaveState(opt);\r
++ if(mgl_isnan(sv)) sv = gr->GetOrgY('y');\r
++ if(sv<gr->Min.y || sv>gr->Max.y) { gr->SetWarn(mglWarnSlc,"ContFY"); gr->LoadState(); return; }\r
++ static int cgid=1; gr->StartGroup("ContFY",cgid++);\r
++ mglDataV xx,yy,zz; mglData aa;\r
++ long ss=gr->AddTexture(sch);\r
++\r
++ a = fill_slice_y(gr,sv,a,xx,yy,zz,aa);\r
++#pragma omp parallel for\r
++ for(long i=0;i<v->GetNx()-1;i++)\r
++ {\r
++ mreal v0 = v->v(i);\r
++ mgl_contf_gen(gr,v0,v->v(i+1),a,&xx,&yy,&zz,gr->GetC(ss,v0),0);\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_contf_z_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy();\r
++ if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContFZ"); return; }\r
++ gr->SaveState(opt);\r
++ if(mgl_isnan(sv)) sv = gr->GetOrgZ('z');\r
++ if(sv<gr->Min.z || sv>gr->Max.z) { gr->SetWarn(mglWarnSlc,"ContFZ"); gr->LoadState(); return; }\r
++ static int cgid=1; gr->StartGroup("ContFZ",cgid++);\r
++ mglDataV xx,yy,zz; mglData aa;\r
++ long ss=gr->AddTexture(sch);\r
++\r
++ a = fill_slice_z(gr,sv,a,xx,yy,zz,aa);\r
++#pragma omp parallel for\r
++ for(long i=0;i<v->GetNx()-1;i++)\r
++ {\r
++ mreal v0 = v->v(i);\r
++ mgl_contf_gen(gr,v0,v->v(i+1),a,&xx,&yy,&zz,gr->GetC(ss,v0),0);\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_contf_x(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5);\r
++ mglData v(Num); v.Fill(gr->Min.c, gr->Max.c);\r
++ mgl_contf_x_val(gr,&v,a,sch,sv,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_contf_y(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5);\r
++ mglData v(Num); v.Fill(gr->Min.c, gr->Max.c);\r
++ mgl_contf_y_val(gr,&v,a,sch,sv,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_contf_z(HMGL gr, HCDT a, const char *sch, double sv, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long Num = (mgl_isnan(r) || r<=0) ? 7:long(r+0.5);\r
++ mglData v(Num); v.Fill(gr->Min.c, gr->Max.c);\r
++ mgl_contf_z_val(gr,&v,a,sch,sv,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_contf_x_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_contf_x(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; }\r
++/// Draw several contour plots for data a at y = *sv\r
++void MGL_EXPORT mgl_contf_y_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_contf_y(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; }\r
++/// Draw several contour plots for data a at z = *sv\r
++void MGL_EXPORT mgl_contf_z_(uintptr_t *gr, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_contf_z(_GR_, _DA_(a), s, *sv, o); delete []o; delete []s; }\r
++/// Draw contour plots for data a at x = *sv\r
++void MGL_EXPORT mgl_contf_x_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_contf_x_val(_GR_, _DA_(v), _DA_(a), s, *sv, o); delete []o; delete []s;}\r
++/// Draw contour plots for data a at y = *sv\r
++void MGL_EXPORT mgl_contf_y_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_contf_y_val(_GR_, _DA_(v), _DA_(a), s, *sv, o); delete []o; delete []s;}\r
++/// Draw contour plots for data a at z = *sv\r
++void MGL_EXPORT mgl_contf_z_val_(uintptr_t *gr, uintptr_t *v, uintptr_t *a, const char *sch, mreal *sv, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_contf_z_val(_GR_, _DA_(v), _DA_(a), s, *sv, o); delete []o; delete []s;}\r
++//-----------------------------------------------------------------------------\r
--- /dev/null
--- /dev/null
++/***************************************************************************
++ * parse.cpp is part of Math Graphic Library
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU Library General Public License as *
++ * published by the Free Software Foundation; either version 3 of the *
++ * License, or (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU Library General Public *
++ * License along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
++ ***************************************************************************/
++#include <ctype.h>
++#include "mgl2/parser.h"
++#include "mgl2/canvas_cf.h"
++#include "mgl2/base.h"
++//-----------------------------------------------------------------------------
++int MGL_LOCAL_PURE mgl_cmd_cmp(const void *a, const void *b)
++{
++ const mglCommand *aa = (const mglCommand *)a;
++ const mglCommand *bb = (const mglCommand *)b;
++ return strcmp(aa->name, bb->name);
++}
++//-----------------------------------------------------------------------------
++mglCommand *mglParser::BaseCmd=NULL; ///< Base table of MGL commands. It MUST be sorted by 'name'!!!
++void mglParser::FillBaseCmd()
++{
++ if(BaseCmd) return;
++ size_t na=0, nd=0, ng=0, np=0, ns=0, nsum=0;
++ while(mgls_prg_cmd[na].name[0]) na++;
++ while(mgls_dat_cmd[nd].name[0]) nd++;
++ while(mgls_grf_cmd[ng].name[0]) ng++;
++ while(mgls_prm_cmd[np].name[0]) np++;
++ while(mgls_set_cmd[ns].name[0]) ns++;
++ BaseCmd = new mglCommand[na+nd+ng+np+ns+1];
++ memcpy(BaseCmd, mgls_prg_cmd, na*sizeof(mglCommand)); nsum+=na;
++ memcpy(BaseCmd+nsum,mgls_dat_cmd, nd*sizeof(mglCommand)); nsum+=nd;
++ memcpy(BaseCmd+nsum,mgls_grf_cmd, ng*sizeof(mglCommand)); nsum+=ng;
++ memcpy(BaseCmd+nsum,mgls_prm_cmd, np*sizeof(mglCommand)); nsum+=np;
++ memcpy(BaseCmd+nsum,mgls_set_cmd, (ns+1)*sizeof(mglCommand)); nsum+=ns;
++ qsort(BaseCmd, nsum, sizeof(mglCommand), mgl_cmd_cmp);
++#if DEBUG
++ long stat[17]; memset(stat,0,17*sizeof(long));
++ const char *name[17] = { _("0 - special plot"), _("1 - other plot"), _("2 - setup"), _("3 - data handle"), _("4 - data create"), _("5 - subplot"), _("6 - program flow"), _("7 - 1d plot"), _("8 - 2d plot"), _("9 - 3d plot"), _("10 - dd plot"), _("11 - vector plot"), _("12 - axis"), _("13 - primitives"), _("14 - axis setup"), _("15 - text/legend"), _("16 - data transform") };
++ for(size_t i=0;BaseCmd[i].name[0];i++) stat[BaseCmd[i].type]+=1;
++ for(size_t i=0;i<17;i++) printf("%s: %ld\n",name[i],stat[i]);
++ printf("\n"); fflush(stdout);
++#endif
++}
++//-----------------------------------------------------------------------------
++HMDT MGL_NO_EXPORT mglFormulaCalc(std::wstring string, mglParser *arg, const std::vector<mglDataA*> &head);
++HADT MGL_NO_EXPORT mglFormulaCalcC(std::wstring string, mglParser *arg, const std::vector<mglDataA*> &head);
++//-----------------------------------------------------------------------------
++MGL_EXPORT void (*mgl_ask_func)(const wchar_t *, wchar_t *)=0;
++void MGL_EXPORT mgl_ask_gets(const wchar_t *quest, wchar_t *res)
++{ printf("%ls\n",quest); if(!fgetws(res,1024,stdin)) *res=0; }
++//-----------------------------------------------------------------------------
++mglFunc::mglFunc(long p, const wchar_t *f)
++{
++ pos = p; func = f;
++ size_t i;
++ for(i=0;(isalnum(f[i]) || f[i]=='_');i++);
++ narg = wcstol(f+i+1,0,0); func = func.substr(0,i);
++ if(narg<0 || narg>9) narg=0;
++}
++//-----------------------------------------------------------------------------
++long mglParser::IsFunc(const std::wstring &name, int *na)
++{
++ for(size_t i=0;i<func.size();i++)
++ {
++ const mglFunc &f = func[i];
++ if(f.func==name)
++ { if(na) *na=f.narg; return f.pos+1; }
++ }
++ return 0;
++}
++//-----------------------------------------------------------------------------
++void mglParser::ScanFunc(const wchar_t *line)
++{
++ static long num=0;
++ if(!line)
++ { func.clear(); num=0; return; }
++ num++;
++ while(*line<=' ' && *line!=0) line++;
++ if(wcsncmp(line,L"func",4) || line[4]>' ') return;
++ long i;
++ for(i=4;line[i]<=' ' || line[i]=='\'';i++);
++ func.push_back(mglFunc(num-1, line+i));
++}
++//-----------------------------------------------------------------------------
++MGL_NO_EXPORT wchar_t *mgl_str_copy(const char *s)
++{
++ size_t i,l=strlen(s);
++ wchar_t *str = new wchar_t[l+1];
++ for(i=0;i<l;i++) str[i] = s[i];
++ str[i] = 0; return str;
++}
++//-----------------------------------------------------------------------------
++bool mglParser::CheckForName(const std::wstring &s)
++{
++ return !isalpha(s[0]) || s.find_first_of(L"!@#$%%^&*()-+|,.<>:")!=std::wstring::npos || s==L"rnd" || FindNum(s.c_str());
++// return !isalpha(s[0])||s.find_first_of(L".:()")!=std::wstring::npos;
++}
++//-----------------------------------------------------------------------------
++const mglCommand *mglParser::FindCommand(const char *com) const
++{
++ if(!AllowFileIO && ( !strncmp(com,"read",4) || !strncmp(com,"save",4) || !strcmp(com,"fgets") || !strcmp(com,"import") || !strcmp(com,"export") ))
++ return 0;
++ mglCommand tst, *rts, *cmd = Cmd;
++ long i;
++ for(i=0;cmd[i].name[0];i++); // determine the number of symbols
++ tst.name = com;
++ rts = (mglCommand *) bsearch(&tst, cmd, i, sizeof(mglCommand), mgl_cmd_cmp);
++ return rts;
++}
++//-----------------------------------------------------------------------------
++const mglCommand *mglParser::FindCommand(const wchar_t *com) const
++{
++ size_t s = 15<mgl_wcslen(com)?15:mgl_wcslen(com);
++ char cmd[16]; wcstombs(cmd,com,s+1); cmd[s]=0;
++ return FindCommand(cmd);
++}
++//-----------------------------------------------------------------------------
++// return values : 0 -- OK, 1 -- wrong arguments, 2 -- wrong command, 3 -- unclosed string
++int mglParser::Exec(mglGraph *gr, const wchar_t *com, long n, mglArg *a, const std::wstring &/*var*/, const wchar_t *opt)
++{
++ const char *id="dsn";
++ std::string k;
++ for(long i=0;i<n;i++)
++ {
++ k += id[a[i].type];
++ size_t len = wcstombs(NULL,a[i].w.c_str(),0)+1;
++ char *buf = new char[len]; memset(buf,0,len);
++ wcstombs(buf,a[i].w.c_str(),len);
++ a[i].s = buf; delete []buf;
++ }
++ const mglCommand *rts=FindCommand(com);
++ if(!rts || !rts->exec) return 2;
++/* if(rts->type == 4)
++ {
++ if(n<1 || CheckForName(var)) return 2;
++ a[0].type = 0; a[0].d = AddVar(var.c_str());
++ a[0].w = var; k[0] = 'd';
++ }*/
++ std::string vopt;
++ if(opt && *opt) // TODO: parse arguments of options
++ {
++ size_t len = mgl_wcslen(opt);
++ std::vector<std::wstring> ss;
++ std::wstring s, o;
++ bool st = true, name = true;
++ for(size_t i=0;i<len+1;i++)
++ {
++ if(st && opt[i]<=' ') continue; // skip spaces at beginning
++ st = false;
++ if(i<len && opt[i]!=';')
++ {
++ if(name && opt[i]<=' ') { name = false; o = s; }
++ s.push_back(opt[i]);
++ }
++ else
++ {
++ size_t j = o.size(),k;
++ wchar_t buf[64];
++ if(o==L"xrange" || o==L"yrange" || o==L"zrange" || o==L"crange") // 2 arguments
++ {
++ bool alph=false;
++ for(k=j;k<s.length();k++)
++ {
++ if(s[k]>' ') alph=true;
++ if(alph && s[k]<=' ') break;
++ }
++ HMDT d1 = mglFormulaCalc(s.substr(j+1,k-j),this, DataList);
++ HMDT d2 = mglFormulaCalc(s.substr(k+1),this, DataList);
++ mglprintf(buf,64,L" %g %g",d1->a[0],d2->a[0]);
++ s = o+buf; delete d1; delete d2;
++ }
++ else if(o!=L"legend") // 1 argument
++ {
++ HMDT dd = mglFormulaCalc(s.substr(j+1),this, DataList);
++ mglprintf(buf,64,L" %g",dd->a[0]);
++ s = o+buf; delete dd;
++ }
++ st = name = true; ss.push_back(s);
++ o.clear(); s.clear();
++ }
++ }
++ for(size_t i=0;i<ss.size();i++)
++ {
++ for(size_t j=0;j<ss[i].length();j++) vopt += ss[i][j];
++ vopt += ';';
++ }
++ }
++ int res=rts->exec(gr, n, a, k.c_str(), vopt.c_str());
++ return res;
++}
++//-----------------------------------------------------------------------------
++mglParser::mglParser(bool setsize)
++{
++ InUse = 1; curGr = 0; Variant = 0;
++<<<<<<< HEAD
++ Skip=Stop=for_br=false;
++=======
++ Skip=Stop=for_br=false; StarObhID = 0;
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ memset(for_stack,0,40*sizeof(int));
++ memset(if_stack,0,40*sizeof(int));
++ memset(if_for,0,40*sizeof(int));
++ if_pos=for_addr=0;
++ for(long i=0;i<40;i++) par[i]=L"";
++
++ FillBaseCmd(); Cmd = BaseCmd;
++ AllowSetSize=setsize; AllowFileIO=true; AllowDllCall=true;
++ Once = true;
++ fval = new mglData[40];
++ mglNum *v;
++ v = new mglNum(0); v->s = L"off"; NumList.push_back(v);
++ v = new mglNum(1); v->s = L"on"; NumList.push_back(v);
++ v = new mglNum(-1); v->s = L"all"; NumList.push_back(v);
++ v = new mglNum(NAN); v->s = L"nan"; NumList.push_back(v);
++ v = new mglNum(M_PI); v->s = L"pi"; NumList.push_back(v);
++ v = new mglNum(INFINITY); v->s = L"inf"; NumList.push_back(v);
++#if MGL_HAVE_LTDL
++ lt_dlinit();
++#endif
++}
++//-----------------------------------------------------------------------------
++mglParser::~mglParser()
++{
++ DeleteAll(); delete []fval;
++ for(size_t i=0;i<NumList.size();i++) // force delete built-in variables
++ if(NumList[i]) delete NumList[i];
++ NumList.clear();
++#if MGL_HAVE_LTDL
++ lt_dlexit();
++#endif
++}
++//-----------------------------------------------------------------------------
++void mglParser::DeleteAll()
++{
++ for(size_t i=0;i<DataList.size();i++)
++ if(DataList[i]) delete DataList[i];
++ DataList.clear();
++ for(size_t i=0;i<NumList.size();i++)
++ if(NumList[i]) delete NumList[i];
++ NumList.clear();
++ mglNum *v;
++ v = new mglNum(0); v->s = L"off"; NumList.push_back(v);
++ v = new mglNum(1); v->s = L"on"; NumList.push_back(v);
++ v = new mglNum(-1); v->s = L"all"; NumList.push_back(v);
++ v = new mglNum(NAN); v->s = L"nan"; NumList.push_back(v);
++ v = new mglNum(M_PI); v->s = L"pi"; NumList.push_back(v);
++ v = new mglNum(INFINITY); v->s = L"inf"; NumList.push_back(v);
++ if(Cmd && Cmd!=BaseCmd) { delete []Cmd; Cmd = BaseCmd; }
++#if MGL_HAVE_LTDL
++ for(size_t i=0;i<DllOpened.size();i++)
++ lt_dlclose(DllOpened[i]);
++ DllOpened.clear();
++#endif
++}
++//-----------------------------------------------------------------------------
++void mglParser::AddParam(int n, const char *str)
++{
++ MGL_TO_WCS(str,AddParam(n,wcs));
++}
++//-----------------------------------------------------------------------------
++int mglParser::Parse(mglGraph *gr, const char *str, long pos)
++{
++ int r=0;
++ MGL_TO_WCS(str,r = Parse(gr,wcs,pos));
++ return r;
++}
++//-----------------------------------------------------------------------------
++mglDataA *mglParser::AddVar(const char *str)
++{
++ mglDataA *v=0;
++ MGL_TO_WCS(str,v = AddVar(wcs));
++ return v;
++}
++//-----------------------------------------------------------------------------
++mglDataA *mglParser::FindVar(const char *str)
++{
++ mglDataA *v=0;
++ MGL_TO_WCS(str,v = FindVar(wcs));
++ return v;
++}
++//-----------------------------------------------------------------------------
++mglNum *mglParser::AddNum(const char *str)
++{
++ mglNum *v=0;
++ MGL_TO_WCS(str,v = AddNum(wcs));
++ return v;
++}
++//-----------------------------------------------------------------------------
++mglNum *mglParser::FindNum(const char *str)
++{
++ mglNum *v=0;
++ MGL_TO_WCS(str,v = FindNum(wcs));
++ return v;
++}
++//-----------------------------------------------------------------------------
++void mglParser::AddParam(int n, const wchar_t *str)
++{
++// if(str && n>=0 && n<40 && !wcschr(str,'$')) par[n] = str;
++ if(str && n>=0 && n<40) par[n] = str;
++}
++//-----------------------------------------------------------------------------
++mglDataA *mglParser::FindVar(const wchar_t *name)
++{
++ if(name[0]=='!') name = name+1; // ignore complex prefix
++ for(size_t i=0;i<DataList.size();i++)
++ if(DataList[i] && DataList[i]->s==name) return DataList[i];
++ return 0;
++}
++//-----------------------------------------------------------------------------
++mglDataA *mglParser::AddVar(const wchar_t *name)
++{ // TODO add list of forbidden names (like function names)
++ mglDataA *d=FindVar(name);
++ if(name[0]=='!' && dynamic_cast<mglDataC*>(d)==0)
++ { d = new mglDataC; d->s=(name+1); DataList.push_back(d); }
++ else if(!d)
++ { d = new mglData; d->s = name; DataList.push_back(d); }
++ return d;
++}
++//-----------------------------------------------------------------------------
++mglNum *mglParser::FindNum(const wchar_t *name)
++{
++ for(size_t i=0;i<NumList.size();i++)
++ if(NumList[i] && NumList[i]->s==name) return NumList[i];
++ return 0;
++}
++//-----------------------------------------------------------------------------
++mglNum *mglParser::AddNum(const wchar_t *name)
++{
++ mglNum *v = FindNum(name);
++ if(!v) { v=new mglNum; v->s = name; NumList.push_back(v); }
++ return v;
++}
++//-----------------------------------------------------------------------------
++int MGL_LOCAL_PURE mglFindArg(const std::wstring &str)
++{
++<<<<<<< HEAD
++ register long l=0,k=0;
++=======
++ long l=0,k=0;
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ const size_t s=str.length();
++ for(size_t i=0;i<s;i++)
++ {
++ if(str[i]=='\'') l++;
++ if(str[i]=='{') k++;
++ if(str[i]=='}') k--;
++ if(l%2==0 && k==0)
++ {
++ if(str[i]=='#' || str[i]==';') return -long(i);
++ if(str[i]<=' ') return long(i);
++ }
++ }
++ return 0;
++}
++//-----------------------------------------------------------------------------
++// convert substrings to arguments
++void mglParser::FillArg(mglGraph *gr, int k, std::wstring *arg, mglArg *a)
++{
++ for(long n=1;n<k;n++)
++ {
++ mglDataA *v; mglNum *f;
++ a[n-1].type = -1;
++ std::wstring str = arg[n];
++ size_t i1=0, i2=str.length(), j=0;
++ bool s=true;
++ for(size_t i=0;i<i2;i++)
++ {
++ if(str[i]=='\'') s = !s;
++ if(s && str[i]=='?')
++ {
++ if(j<Variant) i1=i+1;
++ else i2=i;
++ j++;
++ }
++ }
++ str = str.substr(i1,i2-i1);
++
++ if(str.empty()) a[n-1].type = -2;
++ else if(str[0]=='|') a[n-1].type = -1;
++ else if(str[0]=='\'') // this is string (simplest case)
++ {
++ a[n-1].type = 1;
++<<<<<<< HEAD
++ std::wstring &w=str,f;
++ wchar_t buf[32];
++ long i,i1,ll=w.length();
++ for(i=1;i<ll;i++)
++=======
++ long na=1, ns=0, np=0, ll=str.length(), ii=1, op=0;
++ std::vector<std::wstring> s;
++ std::vector<int> id; // 0 - string, 1 - cval, 2 - rval, 3 - plus, 4 - index
++ for(long i=1;i<ll;i++)
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ {
++ if(str[i]=='\'')
++ {
++ if(na%2==1)
++ { id.push_back(0); s.push_back(str.substr(ii,i-ii)); }
++ else if(op && i>ii)
++ { id.push_back(op); s.push_back(str.substr(ii,i-ii)); }
++ na++; ii=i+1; op=0;
++ }
++ else if(na%2==0 && ns==0 && np==0)
++ {
++ if(str[i]=='+' && str[i-1]=='\'')
++ { op=3; ii=i+1; }
++ else if(str[i]==',' && str[i+1]=='!')
++ {
++ if(op && i>ii)
++ { id.push_back(op); s.push_back(str.substr(ii,i-ii)); }
++ op=1; ii=i+2;
++ }
++ else if(str[i]==',')
++ {
++ if(op && i>ii)
++ { id.push_back(op); s.push_back(str.substr(ii,i-ii)); }
++ op=2; ii=i+1;
++ }
++ else if(str[i]=='[' && str[i-1]=='\'')
++ { ii=i+1; ns++; }
++ else if(str[i]=='(') np++;
++ }
++ else if(na%2==0 && np==0 && str[i]==']' && ns==1)
++ {
++ id.push_back(4); s.push_back(str.substr(ii,i-ii));
++ op=0; ii=i+1; ns--;
++ }
++ else if(na%2==0 && np==1 && str[i]==')' && ns==0) np--;
++ }
++ if(op && ll>ii)
++ { id.push_back(op); s.push_back(str.substr(ii,ll-ii)); }
++ wchar_t buf[32];
++ for(size_t i=0;i<id.size();i++)
++ {
++ if(id[i]==0) a[n-1].w += s[i];
++ else if(id[i]==1)
++ {
++ HADT d = mglFormulaCalcC(s[i], this, DataList);
++ mreal di = imag(d->a[0]), dr = real(d->a[0]);
++ if(di>0) mglprintf(buf,32,L"%g+%gi",dr,di);
++ else if(di<0) mglprintf(buf,32,L"%g-%gi",dr,-di); // TODO use \u2212 ???
++ else mglprintf(buf,32,L"%g",dr);
++ a[n-1].w += buf; delete d;
++ }
++ else if(id[i]==2)
++ {
++ HMDT d = mglFormulaCalc(s[i], this, DataList);
++ mglprintf(buf,32,L"%g",d->a[0]); a[n-1].w += buf; delete d;
++ }
++ else if(id[i]==3)
++ {
++ HMDT d = mglFormulaCalc(s[i], this, DataList);
++ a[n-1].w[a[n-1].w.size()-1] += d->a[0]; delete d;
++ }
++ else if(id[i]==4)
++ {
++ HMDT d = mglFormulaCalc(s[i], this, DataList);
++ long v = long(d->a[0]+0.5); delete d;
++ if(v>=0 && v<long(a[n-1].w.size())) a[n-1].w = a[n-1].w[v];
++ else a[n-1].w = L"";
++ }
++ }
++ }
++ else if(str[0]=='{')
++ { // this is temp data
++ mglData *u=new mglData;
++ std::wstring s = str.substr(1,str.length()-2);
++ a[n-1].w = u->s = L"/*"+s+L"*/";
++ a[n-1].type = 0;
++ ParseDat(gr, s, *u); a[n-1].d = u;
++ u->temp=true; DataList.push_back(u);
++ }
++ else if((v = FindVar(str.c_str()))!=0) // try to find normal variables (for data creation)
++ { a[n-1].type=0; a[n-1].d=v; a[n-1].w=v->s; }
++ else if((f = FindNum(str.c_str()))!=0) // try to find normal number (for data creation)
++ { a[n-1].type=2; a[n-1].d=0; a[n-1].v=f->d; a[n-1].c=f->c; a[n-1].w = f->s; }
++ else if(str[0]=='!') // complex array is asked
++ { // parse all numbers and formulas by unified way
++ HADT d = mglFormulaCalcC(str.substr(1), this, DataList);
++ if(d->GetNN()==1)
++ {
++ if(CheckForName(str.substr(1)))
++ { a[n-1].type = 2; a[n-1].v = d->v(0); a[n-1].c = d->a[0]; }
++ else
++ { a[n-1].type = 0; a[n-1].d = AddVar(str.c_str()); }
++ delete d;
++ }
++ else
++ {
++ a[n-1].w = L"/*"+str+L"*/";
++ d->temp=true; DataList.push_back(d);
++ a[n-1].type = 0; a[n-1].d = d;
++ }
++ }
++ else
++ { // parse all numbers and formulas by unified way
++ HMDT d = mglFormulaCalc(str, this, DataList);
++ if(d->GetNN()==1)
++ {
++ if(CheckForName(str))
++ { a[n-1].type = 2; a[n-1].c = a[n-1].v = d->v(0); }
++ else
++ { a[n-1].type = 0; a[n-1].d = AddVar(str.c_str()); }
++ delete d;
++ }
++ else
++ {
++ a[n-1].w = L"/*"+str+L"*/";
++ d->temp=true; DataList.push_back(d);
++ a[n-1].type = 0; a[n-1].d = d;
++ }
++ }
++ }
++}
++//-----------------------------------------------------------------------------
++// return values: 0 - not found, 1 - OK, 2 - wrong arguments, 3 - wrong command, 4 - string too long
++int mglParser::PreExec(mglGraph *, long k, std::wstring *arg, mglArg *a)
++{
++ long n=0;
++ if(!arg[0].compare(L"list")) // parse command "list"
++ {
++ if(k<3 || CheckForName(arg[1])) return 2;
++ long nx=0, ny=1,j=0,i,t=0;
++ for(i=2;i<k;i++)
++ {
++ char ch = arg[i][0];
++ if(a[i-1].type==1) return 2;
++ if(a[i-1].type==0)
++ {
++ if(t==1) return 2;
++ t=2; nx++;
++ }
++ if(a[i-1].type==2)
++ {
++ if(t==2) return 2;
++ j++; t=1;
++ }
++ if(ch=='|' && t==1) { nx = j>nx ? j:nx; j=0; ny++; }
++ }
++ mglDataA *vv = AddVar(arg[1].c_str());
++ mglData *v = dynamic_cast<mglData*>(vv);
++ mglDataC *vc = dynamic_cast<mglDataC*>(vv);
++ if(v)
++ {
++ if(t==1) nx = j>nx ? j:nx;
++ if(t==1) // list of numeric values
++ {
++ v->Create(nx,ny);
++ j=t=0;
++ for(i=2;i<k;i++)
++ {
++ if(arg[i][0]=='|') { t++; j=0; }
++ else
++ { v->a[j+nx*t] = a[i-1].v; j++; }
++ }
++ }
++ if(t==2) // list of data
++ {
++ v->Set(a[1].d);
++ for(long i=2;i<k;i++) v->Join(*(a[i].d));
++ }
++ n=1;
++ }
++ if(vc)
++ {
++ if(t==1) nx = j>nx ? j:nx;
++ if(t==1) // list of numeric values
++ {
++ vc->Create(nx,ny);
++ j=t=0;
++ for(i=2;i<k;i++)
++ {
++ if(arg[i][0]=='|') { t++; j=0; }
++ else
++ { vc->a[j+nx*t] = a[i-1].c; j++; }
++ }
++ }
++ if(t==2) // list of data
++ {
++ vc->Set(a[1].d);
++ for(long i=2;i<k;i++) vc->Join(*(a[i].d));
++ }
++ n=1;
++ }
++ }
++ return n;
++}
++//-----------------------------------------------------------------------------
++void mglParser::PutArg(std::wstring &str, bool def)
++{
++ size_t pos = str.find('$',def?10:0);
++ while(pos<str.length())
++ {
++ wchar_t ch = str[pos+1];
++ if(ch>='0' && ch<='9') str.replace(pos,2,par[ch-'0']);
++ else if(ch>='a' && ch<='z') str.replace(pos,2,par[ch-'a'+10]);
++ else if(ch=='$') str.replace(pos,2,L"\uffff");
++ else str.replace(pos,1,L"\uffff");
++ pos = str.find('$',def?10:0);
++ }
++ while((pos = str.find(L'\uffff'))<str.length()) str[pos]='$';
++}
++//-----------------------------------------------------------------------------
++std::wstring mgl_trim_ws(const std::wstring &str)
++{
++ size_t n=str.length(), k, i;
++ for(k=0;k<n;k++) if(str[k]>' ') break;
++ for(i=n;i>k;i--) if(str[i-1]>' ') break;
++ return str.substr(k,i-k);
++}
++//-----------------------------------------------------------------------------
++int mglParser::ParseDef(std::wstring &str)
++{
++ if(!skip() && !str.compare(0,3,L"def") && (str[6]==' ' || str[6]=='\t'))
++ {
++ int res = 1; mreal d;
++ PutArg(str,true);
++ size_t end; bool ss=false;
++ for(end=7;str[end] && (str[end]!='#' || ss);end++)
++ { if(str[end]=='\'') ss=!ss; }
++ const std::wstring s = mgl_trim_ws(str.substr(7,end-7));
++ if(!str.compare(3,3,L"ine"))
++ {
++ int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1);
++ if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10)
++ {
++ AddParam(nn, mgl_trim_ws(s.substr(2)).c_str()); return 1;
++ }
++ }
++ if(!str.compare(3,3,L"num"))
++ {
++ int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1);
++ if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10)
++ {
++ res = 0;
++ HMDT dd = mglFormulaCalc(mgl_trim_ws(s.substr(2)), this, DataList);
++ d = dd->a[0]; delete dd;
++ AddParam(nn, mgl_str_num(d).c_str());
++ }
++ return res+1;
++ }
++ if(!str.compare(3,3,L"chr"))
++ {
++ int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1);
++ if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10)
++ {
++ res = 0;
++ HMDT dd = mglFormulaCalc(mgl_trim_ws(s.substr(2)), this, DataList);
++ d=dd->a[0]; delete dd;
++ wchar_t buf[2]={0,0}; buf[0] = wchar_t(d); AddParam(nn, buf);
++ }
++ return res+1;
++ }
++ }
++ if(!skip() && !str.compare(0,3,L"ask") && (str[3]==' ' || str[3]=='\t'))
++ {
++ PutArg(str,true);
++ std::wstring s = mgl_trim_ws(str.substr(4));
++ int nn = s[1]<='9' ? s[1]-'0' : (s[1]>='a' ? s[1]-'a'+10:-1);
++ if(s[0]=='$' && nn>=0 && nn<='z'-'a'+10)
++ {
++ s = mgl_trim_ws(s.substr(2));
++ if(s[0]=='\'') s=s.substr(1,s.length()-2);
++ if(mgl_ask_func)
++ {
++ static wchar_t res[1024];
++ mgl_ask_func(s.c_str(),res);
++ if(*res) AddParam(nn, res);
++ }
++ return mgl_ask_func?1:2;
++ }
++ else return 2;
++ }
++ if(!skip() && !str.compare(0,3,L"for") && (str[3]==' ' || str[3]=='\t'))
++ {
++ size_t i; for(i=4;str[i]<=' ';i++);
++ // if command have format 'for $N ...' then change it to 'for N ...'
++ if(str[i]=='$' && str[i+1]>='0' && str[i+1]<='9') str[i] = ' ';
++ if(str[i]=='$' && str[i+1]>='a' && str[i+1]<='z') str[i] = ' ';
++ }
++ return 0;
++}
++//-----------------------------------------------------------------------------
++// return values: 0 - OK, 1 - wrong arguments, 2 - wrong command, 3 - string too long, 4 -- unclosed string
++int mglParser::Parse(mglGraph *gr, std::wstring str, long pos)
++{
++ if(Stop || gr->NeedStop()) return 0;
++<<<<<<< HEAD
++ curGr = gr->Self();
++=======
++ curGr = gr->Self(); gr->pr = this;
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ str=mgl_trim_ws(str);
++ long n,k=0,m=0,mm=0,res;
++ // try parse ':' -- several commands in line
++ for(n=0;n<long(str.length());n++)
++ {
++ if(str[n]=='\'' && (n==0 || str[n-1]!='\\')) k++;
++ if(k%2) continue;
++ if(str[n]=='(') m++;
++ if(str[n]==')') m--;
++ if(str[n]=='{') mm++;
++ if(str[n]=='}') mm--;
++ if(str[n]=='#') break;
++ if((str[n]==':' || str[n]=='\n') && k%2==0 && m==0 && mm==0)
++ {
++ res=Parse(gr,str.substr(0,n),pos);
++ if(!res) res=Parse(gr,str.substr(n+1),pos);
++ return res;
++ }
++ }
++ if(k%2 || m || mm) return 4; // strings is not closed
++ // define parameters or start cycle
++ res = ParseDef(str); if(res) return res-1;
++ // parse arguments (parameters $1, ..., $9)
++ PutArg(str,false); str=mgl_trim_ws(str);
++
++ std::wstring opt;
++ std::vector<std::wstring> arg;
++ while(!str.empty()) // parse string to substrings (by spaces)
++ {
++ n = mglFindArg(str);
++ if(n<1) // this is option
++ {
++ if(str[-n]==';') opt = str.substr(-n+1);
++ if(n<0) str = str.substr(0,-n);
++ break;
++ }
++ arg.push_back(str.substr(0,n));
++ str = mgl_trim_ws(str.substr(n+1));
++ }
++ // try to find last argument
++ if(str[0]!=0 && str[0]!='#' && str[0]!=';') arg.push_back(str);
++ k = arg.size();
++ if(k<1) n = 0;
++ else
++ {
++ // fill arguments by its values
++ mglArg *a = new mglArg[k];
++ FillArg(gr, k, &(arg[0]), a);
++ // execute first special (program-flow-control) commands
++ if(!skip() && !arg[0].compare(L"stop"))
++ { Stop = true; delete []a; return 0; }
++ if(!arg[0].compare(L"func"))
++ { Stop = true; delete []a; return 0; }
++ n = FlowExec(gr, arg[0].c_str(),k-1,a);
++ if(n) { delete []a; return n-1; }
++ if(skip()) { delete []a; return 0; }
++ if(!arg[0].compare(L"define"))
++ {
++ if(k==3)
++ {
++ DeleteVar(arg[1].c_str()); // force to delete variable with the same name
++ mglNum *v=AddNum(arg[1].c_str());
++ if(arg[2][0]=='!') // complex number is added
++ { HADT dd = mglFormulaCalcC(arg[2].substr(1),this, DataList);
++ v->d=NAN; v->c = dd->a[0]; delete dd; }
++ else
++ { HMDT dd = mglFormulaCalc(arg[2],this, DataList);
++ v->c = v->d = dd->a[0]; delete dd; }
++ }
++ delete []a; return k==3?0:1;
++ }
++<<<<<<< HEAD
++ if(!arg[0].compare(L"rkstep"))
++ {
++ int res=1;
++ if(k>2 && a[0].type==1 && a[1].type==1)
++ {
++ std::wstring a1 = arg[1], a2=arg[2]; res = 0;
++ if(a1[0]=='\'') a1 = a1.substr(1,a1.length()-2);
++ if(a2[0]=='\'') a2 = a2.substr(1,a2.length()-2);
++ mgl_rk_step_w(this, a1.c_str(), a2.c_str(), (k>3 && a[2].type==2)?a[2].v:1);
++ }
++ delete []a; return res;
++ }
++ if(!arg[0].compare(L"variant"))
++ {
++ int res=1;
++ if(k==2 && a[0].type==2) { SetVariant(a[0].v); res=0; }
++ delete []a; return res;
++ }
++=======
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ if(!arg[0].compare(L"call"))
++ {
++ n = 1;
++ if(a[0].type==1)
++ {
++ int na=0;
++ a[0].s.assign(a[0].w.begin(),a[0].w.end());
++ n=-IsFunc(a[0].w.c_str(),&na);
++ if(n && k!=na+2)
++ {
++ char buf[64];
++ snprintf(buf,64,_("Bad arguments for %ls: %ld instead of %d\n"), a[0].w.c_str(),k-2,na);
++ buf[63]=0; gr->SetWarn(-1,buf); n = 1;
++ }
++ else if(n)
++ {
++ mglFnStack fn; fn.pos = pos;
++ for(int i=0;i<10;i++) { fn.par[i] = par[i]; par[i]=L""; }
++ for(int i=1;i<k-1;i++) AddParam(i,arg[i+1].c_str());
++ fn_stack.push_back(fn); n--;
++ }
++ else if(AllowFileIO) // disable external scripts if AllowFileIO=false
++ {
++ FILE *fp = fopen(a[0].s.c_str(),"rt");
++ if(fp)
++ {
++ mglParser *prs = new mglParser(AllowSetSize);
++ prs->DataList.swap(DataList); prs->NumList.swap(NumList); prs->Cmd=Cmd;
++ for(int i=10;i<30;i++) prs->AddParam(i,par[i].c_str());
++ prs->Execute(gr,fp);
++ for(int i=10;i<30;i++) AddParam(i,prs->par[i].c_str());
++ DataList.swap(prs->DataList); NumList.swap(prs->NumList);
++ prs->Cmd=0; delete prs; fclose(fp);
++ }
++ else n=1;
++ }
++ }
++ delete []a; return n;
++ }
++ if(!arg[0].compare(L"for"))
++ {
++ if(k<2) { delete []a; return 1; }
++ n = 1;
++ char ch = arg[1][0];
++ int r = ch-'0';
++ if(ch>='a' && ch<='z') r = 10+ch-'a';
++// int r = int(a[0].v);
++ if(arg[1][1]==0 && (r>=0 && r<40))
++ {
++ if(a[1].type==0)
++ {
++ n=0; fval[r] = *(a[1].d);
++ fval[r].nx *= fval[r].ny*fval[r].nz;
++ }
++ else if(a[1].type==2 && a[2].type==2 && a[2].v>a[1].v)
++ {
++ mreal step = a[3].type==2?a[3].v:1;
++ mm = int(step>0 ? (a[2].v-a[1].v)/step : 0);
++ if(mm>0)
++ {
++ n=0; fval[r].Create(mm+1);
++ for(int ii=0;ii<mm+1;ii++)
++ fval[r].a[ii] = a[1].v + step*ii;
++ }
++ }
++ if(n==0)
++ {
++ for(int i=39;i>0;i--)
++ { for_stack[i]=for_stack[i-1]; if_for[i]=if_for[i-1]; }
++ for_stack[0] = r+1; fval[r].nz = pos; if_for[0]=if_pos;
++ wchar_t buf[32]; mglprintf(buf,32,L"%g",fval[r].a[0]);
++ AddParam(r, buf); fval[r].ny = 1;
++ }
++ }
++ delete []a; return n;
++ }
++ // alocate new arrays and execute the command itself
++ n = PreExec(gr, k, &(arg[0]), a);
++ if(n>0) n--;
++ else if(!arg[0].compare(L"setsize") && !AllowSetSize) n = 2;
++ else n = Exec(gr, arg[0].c_str(),k-1,a, k>1?arg[1]:L"", opt.c_str());
++ delete []a;
++ }
++ // delete temporary data arrays
++ for(size_t i=0;i<DataList.size();i++) if(DataList[i] && DataList[i]->temp)
++ { mglDataA *u=DataList[i]; DataList[i]=0; delete u; }
++ return n;
++}
++//-----------------------------------------------------------------------------
++// return values: 0 - OK, 1 - wrong arguments, 2 - wrong command, 3 - string too long, 4 -- unclosed string
++int mglParser::ParseDat(mglGraph *gr, std::wstring str, mglData &res)
++{
++ std::wstring arg[32];
++ str = mgl_trim_ws(str);
++ long n,k=0;
++ for(k=0;k<32;k++) // parse string to substrings (by spaces)
++ {
++ n = mglFindArg(str);
++ if(n<1) { if(n<0) str=str.substr(0,-n); break; }
++ arg[k] = str.substr(0,n);// k++;
++ str = str.substr(n+1); str = mgl_trim_ws(str);
++ }
++ // try to find last argument
++ if(!str.empty() && k<32) { arg[k] = str; k++; }
++ if(k<1) n = 0;
++ else
++ { // fill arguments by its values
++ mglArg *a = new mglArg[k+1];
++ FillArg(gr, k, arg, a+1); a[0].type=0; a[0].d=&res;
++ // alocate new arrays and execute the command itself
++ int i;
++ std::string kk;
++ const char *id="dsn";
++ for(i=0;i<k;i++)
++ {
++ kk += id[a[i].type];
++ a[i].s.assign(a[i].w.begin(),a[i].w.end());
++ }
++ const mglCommand *rts=FindCommand(arg[0].c_str());
++ if(!rts || rts->type!=4) n = 2;
++ else n = rts->exec(gr, k, a, kk.c_str(), 0);
++ delete []a;
++ }
++ return n;
++}
++//-----------------------------------------------------------------------------
++int mglParser::FlowExec(mglGraph *, const std::wstring &com, long m, mglArg *a)
++{
++ int n=-1;
++ if(!ifskip() && !com.compare(L"once"))
++ {
++ if(a[0].type==2)
++ {
++ n = 0;
++ if(a[0].v) Skip = !Once;
++ else Skip = Once = false;
++ }
++ else n = 1;
++ }
++ else if(!Skip && !com.compare(L"if"))
++ {
++ int cond;
++ if(a[0].type==2)
++ { n = 0; cond = (a[0].v!=0)?3:0; }
++ else if(a[0].type==0)
++ {
++ n = 0; a[1].s.assign(a[1].w.begin(),a[1].w.end());
++ cond = a[0].d->FindAny((m>1 && a[1].type==1) ? a[1].s.c_str():"u")?3:0;
++ }
++ else n = 1;
++ if(n==0)
++ { if_stack[if_pos] = cond; if_pos = if_pos<39 ? if_pos+1 : 39; }
++ }
++ else if(!Skip && !com.compare(L"endif"))
++ { if_pos = if_pos>0 ? if_pos-1 : 0; n = 0; }
++ else if(!Skip && !com.compare(L"else"))
++ {
++ if(if_pos>0)
++ { n=0; if_stack[if_pos-1] = (if_stack[if_pos-1]&2)?2:3; }
++ else n = 1;
++ }
++ else if(!Skip && !com.compare(L"elseif"))
++ {
++ int cond;
++ if(if_pos<1 || m<1) n = 1;
++ else if(if_stack[if_pos-1]&2) { n = 0; cond = 2; }
++ else if(a[0].type==2)
++ { n = 0; cond = (a[0].v!=0)?3:0; }
++ else if(a[0].type==0)
++ {
++ n = 0; a[1].s.assign(a[1].w.begin(),a[1].w.end());
++ cond = a[0].d->FindAny((m>1 && a[1].type==1) ? a[1].s.c_str():"u")?3:0;
++ }
++ else n = 1;
++ if(n==0) if_stack[if_pos-1] = cond;
++ }
++ else if(!ifskip() && !Skip && !com.compare(L"break"))
++ {
++ if(if_pos==if_for[0]) if_pos = if_pos>0 ? if_pos-1 : 0;
++ n = for_stack[0] ? 0:1; for_br = true;
++ }
++ else if(!skip() && !com.compare(L"return"))
++ {
++ if(fn_stack.size()<1) return 2;
++ const mglFnStack &fn=fn_stack.back();
++ for(int i=0;i<10;i++) par[i]=fn.par[i];
++ n = -fn.pos-1; fn_stack.pop_back();
++ }
++ else if(!ifskip() && !Skip && !com.compare(L"next"))
++ {
++ if(if_pos==if_for[0]) if_pos = if_pos>0 ? if_pos-1 : 0;
++ int r = for_stack[0]-1;
++ n = for_stack[0] ? 0:1;
++ if(for_stack[0])
++ {
++ if(fval[r].ny<fval[r].nx && !for_br)
++ {
++ wchar_t buf[32]; mglprintf(buf,32,L"%g",fval[r].a[fval[r].ny]);
++ AddParam(r, buf); fval[r].ny += 1;
++ n = -fval[r].nz-1;
++ }
++ else
++ {
++ for(int i=0;i<39;i++)
++ { for_stack[i]=for_stack[i+1]; if_for[i]=if_for[i+1]; }
++ for_stack[39] = 0; for_br=false;
++ }
++ }
++ }
++ else if(!ifskip() && !Skip && !com.compare(L"continue"))
++ {
++ if(if_pos==if_for[0]) if_pos = if_pos>0 ? if_pos-1 : 0;
++ int r = for_stack[0]-1;
++ n = for_stack[0] ? 0:1;
++ if(for_stack[0])
++ {
++ if(fval[r].ny<fval[r].nx)
++ {
++ wchar_t buf[32]; mglprintf(buf,32,L"%g",fval[r].a[fval[r].ny]);
++ AddParam(r, buf); fval[r].ny += 1;
++ n = -fval[r].nz-1;
++ }
++ else for_br = true;
++ }
++ }
++ return n+1;
++}
++//-----------------------------------------------------------------------------
++void mglParser::Execute(mglGraph *gr, FILE *fp, bool print)
++{
++ if(gr==0 || fp==0) return;
++ std::wstring str;
++ wchar_t ch;
++ while(!feof(fp) && size_t(ch=fgetwc(fp))!=WEOF) str.push_back(ch);
++ Execute(gr,str.c_str());
++ if(print) printf("%s\n",gr->Message());
++}
++//-----------------------------------------------------------------------------
++void mglParser::Execute(mglGraph *gr, int n, const wchar_t **text)
++{
++ if(n<1 || text==0) return;
++ long res=0;
++ char buf[64];
++ for_br=Skip=false; if_pos=0; ScanFunc(0); fn_stack.clear();
++ for(long i=0;i<n;i++) ScanFunc(text[i]);
++ for(long i=0;i<n;i++)
++ {
++ gr->SetWarn(-1, "");
++ gr->SetObjId(i+1+StarObhID);
++ long r = Parse(gr,text[i],i+1);
++ if(r<0) { i = -r-2; continue; }
++ if(r==1) snprintf(buf,64,_("\nWrong argument(s) in line %ld"), i+1);
++ else if(r==2) snprintf(buf,64,_("\nWrong command in line %ld"), i+1);
++ else if(r==3) snprintf(buf,64,_("\nString too long in line %ld"), i+1);
++ else if(r==4) snprintf(buf,64,_("\nUnbalanced ' in line %ld"), i+1);
++ else if(r==5) snprintf(buf,64,_("\nChange temporary data in line %ld"), i+1);
++ else if(gr->GetWarn()>0) snprintf(buf,64,_("in line %ld"), i+1);
++ else *buf=0;
++ buf[63] = 0;
++ if(*buf) gr->SetWarn(-2,buf);
++ if(r>0 && r<5) res=r;
++ }
++ int code[]={mglScrArg, mglScrCmd, mglScrLong, mglScrStr, mglScrTemp};
++ if(res>0) gr->SetWarn(code[res-1],_("MGL Parser"));
++}
++//-----------------------------------------------------------------------------
++void mglParser::Execute(mglGraph *gr, const wchar_t *text)
++{
++ size_t s = mgl_wcslen(text)+1, n=1;
++ wchar_t *wcs = new wchar_t[s];
++ const wchar_t **str;
++ for(size_t i=0;i<s;i++) if(text[i]=='\n') n++;
++ str = (const wchar_t **)malloc(n*sizeof(wchar_t *));
++ memcpy(wcs, text, s*sizeof(wchar_t));
++ str[0] = wcs; n=1;
++ long next=0;
++ Stop = false;
++ for(size_t i=0;i<s;i++)
++ {
++ if(text[i]=='\\') next = i;
++ else if(text[i]>' ')next = 0;
++ if(text[i]=='\n')
++ { // if string need to be continued then I but ' ' instead of 0x0 and
++ // pointer next string to 0x0. Last one for keeping number of strings.
++ if(next)
++ { for(size_t ii=next;ii<=i;ii++) wcs[ii]='\b'; str[n] = wcs+s-1; next=0; }
++ else
++ { wcs[i]=0; str[n] = wcs+i+1; }
++ n++;
++ }
++ }
++ Execute(gr, n, str);
++ delete []wcs; free(str);
++}
++//-----------------------------------------------------------------------------
++void mglParser::Execute(mglGraph *gr, const char *text)
++{
++ MGL_TO_WCS(text, Execute(gr, wcs));
++}
++//-----------------------------------------------------------------------------
++void mglParser::DeleteVar(const char *name)
++{
++ MGL_TO_WCS(name,DeleteVar(wcs));
++}
++//-----------------------------------------------------------------------------
++void mglParser::DeleteVar(const wchar_t *name)
++{
++ for(size_t i=0;i<DataList.size();i++) if(DataList[i] && DataList[i]->s==name)
++ { mglDataA *u=DataList[i]; DataList[i]=0; delete u; }
++}
++//-----------------------------------------------------------------------------
++void mglParser::AddCommand(const mglCommand *cmd)
++{
++ // determine the number of symbols
++ size_t mp=0; while(Cmd[mp].name[0]) mp++;
++ size_t mc=0; while(cmd[mc].name[0]) mc++;
++ // copy all together
++ mglCommand *buf = new mglCommand[mp+mc+1];
++ memcpy(buf, cmd, mc*sizeof(mglCommand));
++ memcpy(buf+mc, Cmd, (mp+1)*sizeof(mglCommand));
++ qsort(buf, mp+mc, sizeof(mglCommand), mgl_cmd_cmp); // sort it
++#pragma omp critical(cmd_parser)
++ { if(Cmd!=BaseCmd) delete []Cmd; Cmd = buf; }
++}
++//-----------------------------------------------------------------------------
++HMPR MGL_EXPORT mgl_create_parser() { return new mglParser; }
++void MGL_EXPORT mgl_delete_parser(HMPR p) { delete p; }
++void MGL_EXPORT mgl_parser_add_param(HMPR p, int id, const char *str) { p->AddParam(id,str); }
++void MGL_EXPORT mgl_parser_add_paramw(HMPR p, int id, const wchar_t *str) { p->AddParam(id,str); }
++MGL_EXPORT mglDataA *mgl_parser_add_var(HMPR p, const char *name) { return p->AddVar(name); }
++MGL_EXPORT mglDataA *mgl_parser_find_var(HMPR p, const char *name) { return p->FindVar(name);}
++void MGL_EXPORT mgl_parser_del_var(HMPR p, const char *name) { p->DeleteVar(name); }
++MGL_EXPORT mglDataA *mgl_parser_add_varw(HMPR p, const wchar_t *name) { return p->AddVar(name); }
++MGL_EXPORT mglDataA *mgl_parser_find_varw(HMPR p, const wchar_t *name) { return p->FindVar(name);}
++void MGL_EXPORT mgl_parser_del_varw(HMPR p, const wchar_t *name) { p->DeleteVar(name); }
++int MGL_EXPORT mgl_parse_line(HMGL gr, HMPR p, const char *str, int pos)
++{ return p->Parse(gr, str, pos); }
++int MGL_EXPORT mgl_parse_linew(HMGL gr, HMPR p, const wchar_t *str, int pos)
++{ return p->Parse(gr, str, pos); }
++void MGL_EXPORT mgl_parse_text(HMGL gr, HMPR p, const char *str)
++{ p->Execute(gr, str); }
++void MGL_EXPORT mgl_parse_textw(HMGL gr, HMPR p, const wchar_t *str)
++{ p->Execute(gr, str); }
++void MGL_EXPORT mgl_parse_file(HMGL gr, HMPR p, FILE *fp, int print)
++{ p->Execute(gr,fp,print); }
++void MGL_EXPORT mgl_parser_restore_once(HMPR p) { p->RestoreOnce(); }
++void MGL_EXPORT mgl_parser_stop(HMPR p) { p->Stop = true; }
++void MGL_EXPORT mgl_parser_allow_setsize(HMPR p, int a) { p->AllowSetSize= a; }
++void MGL_EXPORT mgl_parser_allow_file_io(HMPR p, int a) { p->AllowFileIO = a; }
++void MGL_EXPORT mgl_parser_allow_dll_call(HMPR p, int a){ p->AllowDllCall = a; }
++//-----------------------------------------------------------------------------
++#define _PR_ ((mglParser *)(*p))
++uintptr_t MGL_EXPORT mgl_create_parser_() { return uintptr_t(new mglParser); }
++void MGL_EXPORT mgl_delete_parser_(uintptr_t* p) { delete _PR_; }
++void MGL_EXPORT mgl_parser_add_param_(uintptr_t* p, int *id, const char *str, int l)
++{ char *s=new char[l+1]; memcpy(s,str,l); s[l]=0;
++ _PR_->AddParam(*id, s); delete []s; }
++/*===!!! NOTE !!! You must not delete obtained data arrays !!!===============*/
++uintptr_t MGL_EXPORT mgl_parser_add_var_(uintptr_t* p, const char *name, int l)
++{ char *s=new char[l+1]; memcpy(s,name,l); s[l]=0;
++ mglDataA *v=_PR_->AddVar(s); delete []s; return uintptr_t(v); }
++/*===!!! NOTE !!! You must not delete obtained data arrays !!!===============*/
++uintptr_t MGL_EXPORT mgl_parser_find_var_(uintptr_t* p, const char *name, int l)
++{ char *s=new char[l+1]; memcpy(s,name,l); s[l]=0;
++ mglDataA *v=_PR_->FindVar(s); delete []s; return uintptr_t(v); }
++void MGL_EXPORT mgl_parser_del_var_(uintptr_t* p, const char *name, int l)
++{ char *s=new char[l+1]; memcpy(s,name,l); s[l]=0;
++ _PR_->DeleteVar(s); delete []s; }
++int MGL_EXPORT mgl_parse_line_(uintptr_t* gr, uintptr_t* p, const char *str, int *pos, int l)
++{ char *s=new char[l+1]; memcpy(s,str,l); s[l]=0;
++ int r = _PR_->Parse(_GR_, s, *pos); delete []s; return r; }
++void MGL_EXPORT mgl_parse_text_(uintptr_t* gr, uintptr_t* p, const char *str, int l)
++{ char *s=new char[l+1]; memcpy(s,str,l); s[l]=0;
++ _PR_->Execute(_GR_, s); delete []s; }
++void MGL_EXPORT mgl_parser_restore_once_(uintptr_t* p) { _PR_->RestoreOnce(); }
++void MGL_EXPORT mgl_parser_allow_setsize_(uintptr_t* p, int *a) { _PR_->AllowSetSize= *a; }
++void MGL_EXPORT mgl_parser_allow_file_io_(uintptr_t* p, int *a) { _PR_->AllowFileIO = *a; }
++void MGL_EXPORT mgl_parser_allow_dll_call_(uintptr_t* p, int *a){ _PR_->AllowDllCall= *a; }
++void MGL_EXPORT mgl_parser_stop_(uintptr_t* p) { _PR_->Stop = true; }
++//-----------------------------------------------------------------------------
++long MGL_EXPORT mgl_use_parser(HMPR pr, int inc)
++{ pr->InUse+=inc; return pr->InUse; }
++long MGL_EXPORT mgl_use_parser_(uintptr_t *p, int *inc)
++{ _PR_->InUse+=*inc; return _PR_->InUse; }
++//---------------------------------------------------------------------------
++MGL_EXPORT mglDataA *mgl_parser_get_var(HMPR p, unsigned long id)
++{ return id<p->DataList.size()?p->DataList[id]:0; }
++uintptr_t MGL_EXPORT mgl_parser_get_var_(uintptr_t* p, unsigned long *id)
++{ return uintptr_t(mgl_parser_get_var(_PR_,*id)); }
++long MGL_EXPORT mgl_parser_num_var(HMPR p)
++{ return p->DataList.size(); }
++long MGL_EXPORT mgl_parser_num_var_(uintptr_t* p)
++{ return mgl_parser_num_var(_PR_); }
++long MGL_EXPORT mgl_parser_num_const(HMPR p)
++{ return p->NumList.size(); }
++long MGL_EXPORT mgl_parser_num_const_(uintptr_t* p)
++{ return mgl_parser_num_const(_PR_); }
++MGL_EXPORT mglNum *mgl_parser_get_const(HMPR p, unsigned long id)
++{ return id<p->NumList.size()?p->NumList[id]:0; }
++uintptr_t MGL_EXPORT mgl_parser_get_const_(uintptr_t* p, unsigned long *id)
++{ return uintptr_t(mgl_parser_get_const(_PR_,*id)); }
++//---------------------------------------------------------------------------
++int MGL_EXPORT mgl_parser_cmd_type(HMPR pr, const char *name)
++{
++ const mglCommand *cmd = pr->FindCommand(name);
++ return cmd ? cmd->type + 1 : 0;
++}
++int MGL_EXPORT mgl_parser_cmd_type_(uintptr_t* p, const char *str, int l)
++{ char *s=new char[l+1]; memcpy(s,str,l); s[l]=0;
++ l = mgl_parser_cmd_type(_PR_, s); delete []s; return l; }
++//---------------------------------------------------------------------------
++MGL_EXPORT const char *mgl_parser_cmd_desc(HMPR pr, const char *name)
++{
++ const mglCommand *cmd = pr->FindCommand(name);
++ return cmd ? cmd->desc : 0;
++}
++MGL_EXPORT const char *mgl_parser_cmd_frmt(HMPR pr, const char *name)
++{
++ const mglCommand *cmd = pr->FindCommand(name);
++ return cmd ? cmd->form : 0;
++}
++//---------------------------------------------------------------------------
++MGL_EXPORT const char *mgl_parser_cmd_name(HMPR pr, long id)
++{ return (id<mgl_parser_cmd_num(pr) && id>=0) ? pr->Cmd[id].name:""; }
++long MGL_EXPORT mgl_parser_cmd_num(HMPR pr)
++{ long i=0; while(pr->Cmd[i].name[0]) i++; return i; }
++//---------------------------------------------------------------------------
++HMDT MGL_EXPORT mgl_parser_calc(HMPR pr, const char *formula)
++{ HMDT d=0; MGL_TO_WCS(formula,d = mgl_parser_calcw(pr,wcs)); return d; }
++HMDT MGL_EXPORT mgl_parser_calcw(HMPR pr, const wchar_t *formula)
++{ return mglFormulaCalc(formula,pr, pr->DataList); }
++uintptr_t MGL_EXPORT mgl_parser_calc_(uintptr_t *p, const char *str,int l)
++{ char *s=new char[l+1]; memcpy(s,str,l); s[l]=0;
++ uintptr_t d = (uintptr_t)mgl_parser_calc(_PR_, s); delete []s; return d; }
++//---------------------------------------------------------------------------
++HADT MGL_EXPORT mgl_parser_calc_complex(HMPR pr, const char *formula)
++{ HADT d=0; MGL_TO_WCS(formula,d = mgl_parser_calc_complexw(pr,wcs)); return d; }
++HADT MGL_EXPORT mgl_parser_calc_complexw(HMPR pr, const wchar_t *formula)
++{ return mglFormulaCalcC(formula,pr, pr->DataList); }
++uintptr_t MGL_EXPORT mgl_parser_calc_complex_(uintptr_t *p, const char *str,int l)
++{ char *s=new char[l+1]; memcpy(s,str,l); s[l]=0;
++ uintptr_t d = (uintptr_t)mgl_parser_calc_complex(_PR_, s); delete []s; return d; }
++//---------------------------------------------------------------------------
++void MGL_EXPORT mgl_parser_del_all(HMPR p) { p->DeleteAll(); }
++void MGL_EXPORT mgl_parser_del_all_(uintptr_t *p) { _PR_->DeleteAll(); }
++//---------------------------------------------------------------------------
++void MGL_EXPORT mgl_parser_load(HMPR pr, const char *so_name)
++{
++ if(!pr->AllowDllCall) return;
++#if MGL_HAVE_LTDL
++ lt_dlhandle so = lt_dlopen(so_name);
++ if(!so) return;
++ const mglCommand *cmd = (const mglCommand *)lt_dlsym(so,"mgl_cmd_extra");
++ bool exist = true;
++ if(cmd) for(size_t i=0;cmd[i].name[0];i++)
++ if(!pr->FindCommand(cmd[i].name)) exist=false;
++ if(exist) { lt_dlclose(so); return; } // all commands already presents
++ else pr->DllOpened.push_back(so);
++ pr->AddCommand(cmd);
++#endif
++}
++void MGL_EXPORT mgl_parser_load_(uintptr_t *p, const char *dll_name,int l)
++{ char *s=new char[l+1]; memcpy(s,dll_name,l); s[l]=0;
++ mgl_parser_load(_PR_, s); delete []s; }
++//---------------------------------------------------------------------------
++struct mglRKdat
++{
++ mglDataA *v;
++ std::wstring e;
++ bool cmplx;
++ mglDataC cin,c1,c2,c3,c4, *cc;
++ mglData din,d1,d2,d3,d4, *dd;
++ mglRKdat(mglDataA *var, std::wstring &eq):v(var), e(eq)
++ { cmplx = dynamic_cast<mglDataC*>(var); cc=0; dd=0; }
++ void allocate()
++ {
++ if(cmplx)
++ { cc = dynamic_cast<mglDataC*>(v); cin.Set(v); }
++ else
++ { dd = dynamic_cast<mglData*>(v); din.Set(v); }
++ }
++};
++void MGL_EXPORT mgl_rk_step_w(HMPR pr, const wchar_t *Eqs, const wchar_t *Vars, mreal dt)
++{
++ const std::wstring eqs(Eqs);
++ const std::wstring vars(Vars);
++ std::vector<mglRKdat> rkv;
++ size_t iv=0,jv=0,ie=0,je=0;
++ while(1)
++ {
++ iv = vars.find(';',jv); ie = eqs.find(';',je);
++ mglDataA *vv=mgl_parser_find_varw(pr,vars.substr(jv,iv-jv).c_str());
++ std::wstring eq = eqs.substr(je,ie-je).c_str();
++ if(vv) rkv.push_back(mglRKdat(vv, eq ));
++ jv = iv+1; je = ie+1;
++ if(iv==std::wstring::npos || ie==std::wstring::npos) break;
++ }
++ for(size_t i=0;i<rkv.size();i++) rkv[i].allocate();
++ mreal hh = dt/2;
++ for(size_t i=0;i<rkv.size();i++)
++ {
++ mglRKdat &rk = rkv[i];
++ if(rk.cmplx) rk.c1.Move(mglFormulaCalcC(rk.e, pr, pr->DataList));
++ else rk.d1.Move(mglFormulaCalc(rk.e, pr, pr->DataList));
++ }
++ for(size_t i=0;i<rkv.size();i++)
++ {
++ mglRKdat &rk = rkv[i];
++ if(rk.cc)
++ {
++ long n = rk.cc->GetNN(); dual a = hh*rk.c1.a[0];
++ if(rk.c1.GetNN()==n)
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + hh*rk.c1.a[j];
++ else
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + a;
++ }
++ if(rk.dd)
++ {
++ long n = rk.dd->GetNN(); mreal a = hh*rk.d1.a[0];
++ if(rk.d1.GetNN()==n)
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + hh*rk.d1.a[j];
++ else
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + a;
++ }
++ }
++
++ for(size_t i=0;i<rkv.size();i++)
++ {
++ mglRKdat &rk = rkv[i];
++ if(rk.cmplx) rk.c2.Move(mglFormulaCalcC(rk.e, pr, pr->DataList));
++ else rk.d2.Move(mglFormulaCalc(rk.e, pr, pr->DataList));
++ }
++ for(size_t i=0;i<rkv.size();i++)
++ {
++ mglRKdat &rk = rkv[i];
++ if(rk.cc)
++ {
++ long n = rk.cc->GetNN(); dual a = hh*rk.c2.a[0];
++ if(rk.c2.GetNN()==n)
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + hh*rk.c2.a[j];
++ else
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + a;
++ }
++ if(rk.dd)
++ {
++ long n = rk.dd->GetNN(); mreal a = hh*rk.d2.a[0];
++ if(rk.d2.GetNN()==n)
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + hh*rk.d2.a[j];
++ else
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + a;
++ }
++ }
++
++ for(size_t i=0;i<rkv.size();i++)
++ {
++ mglRKdat &rk = rkv[i];
++ if(rk.cmplx) rk.c3.Move(mglFormulaCalcC(rk.e, pr, pr->DataList));
++ else rk.d3.Move(mglFormulaCalc(rk.e, pr, pr->DataList));
++ }
++ for(size_t i=0;i<rkv.size();i++)
++ {
++ mglRKdat &rk = rkv[i];
++ if(rk.cc)
++ {
++ long n = rk.cc->GetNN(); dual a = dt*rk.c3.a[0];
++ if(rk.c3.GetNN()==n)
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + dt*rk.c3.a[j];
++ else
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + a;
++ }
++ if(rk.dd)
++ {
++ long n = rk.dd->GetNN(); mreal a = dt*rk.d3.a[0];
++ if(rk.d3.GetNN()==n)
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + dt*rk.d3.a[j];
++ else
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + a;
++ }
++ }
++
++ for(size_t i=0;i<rkv.size();i++)
++ {
++ mglRKdat &rk = rkv[i];
++ if(rk.cmplx) rk.c4.Move(mglFormulaCalcC(rk.e, pr, pr->DataList));
++ else rk.d4.Move(mglFormulaCalc(rk.e, pr, pr->DataList));
++ }
++ for(size_t i=0;i<rkv.size();i++)
++ {
++ mglRKdat &rk = rkv[i];
++ if(rk.cc)
++ {
++ long n = rk.cc->GetNN();
++ dual a = (rk.c1.a[0]+rk.c2.a[0]+mreal(2)*(rk.c3.a[0]+rk.c4.a[0]))*(dt/6);
++ if(rk.c1.GetNN()==n)
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + (rk.c1.a[j]+rk.c2.a[j]+mreal(2)*(rk.c3.a[j]+rk.c4.a[j]))*(dt/6);
++ else
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.cc->a[j] = rk.cin.a[j] + a;
++ }
++ if(rk.dd)
++ {
++ long n = rk.dd->GetNN();
++ mreal a = (rk.d1.a[0]+rk.d2.a[0]+2*(rk.d3.a[0]+rk.d4.a[0]))*(dt/6);
++ if(rk.d1.GetNN()==n)
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + (rk.d1.a[j]+rk.d2.a[j]+2*(rk.d3.a[j]+rk.d4.a[j]))*(dt/6);
++ else
++#pragma omp parallel for
++ for(long j=0;j<n;j++) rk.dd->a[j] = rk.din.a[j] + a;
++ }
++ }
++}
++void MGL_EXPORT mgl_rk_step(HMPR pr, const char *Eqs, const char *Vars, mreal dt)
++{
++ if(Eqs && *Eqs && Vars && *Vars)
++ {
++ size_t s=mbstowcs(0,Eqs,0), w=mbstowcs(0,Vars,0);
++ wchar_t *eqs=new wchar_t[s+1]; mbstowcs(eqs,Eqs ,s); eqs[s]=0;
++ wchar_t *wcs=new wchar_t[s+1]; mbstowcs(wcs,Vars,s); wcs[w]=0;
++ mgl_rk_step_w(pr,eqs,wcs,dt); delete []wcs; delete []eqs;
++ }
++}
++void MGL_EXPORT mgl_rk_step_(uintptr_t *p, const char *eqs, const char *vars, double *dt,int l,int m)
++{ char *e=new char[l+1]; memcpy(e,eqs,l); e[l]=0;
++ char *s=new char[m+1]; memcpy(s,vars,m); s[m]=0;
++ mgl_rk_step(_PR_,e,s,*dt); delete []e; delete []s; }
++//---------------------------------------------------------------------------
++void MGL_EXPORT mgl_parser_variant(HMPR p, int var) { p->SetVariant(var); }
++void MGL_EXPORT mgl_parser_variant_(uintptr_t *p, int *var) { mgl_parser_variant(_PR_,*var); }
++//---------------------------------------------------------------------------
++<<<<<<< HEAD
++=======
++void MGL_EXPORT mgl_parser_openhdf(HMPR p, const char *fname)
++{
++ const char * const *res = mgl_datas_hdf_str(fname);
++ if(!res) return;
++ for(size_t n=0;res[n][0];n++)
++ {
++ mglDataA *d = p->AddVar(res[n]);
++ mglData *dr = dynamic_cast<mglData*>(d);
++ mglDataC *dc = dynamic_cast<mglDataC*>(d);
++ if(dr) dr->ReadHDF(fname,res[n]);
++ if(dc) dc->ReadHDF(fname,res[n]);
++ }
++}
++void MGL_EXPORT mgl_parser_openhdf_(uintptr_t *p, const char *fname,int l)
++{ char *s=new char[l+1]; memcpy(s,fname,l); s[l]=0;
++ mgl_parser_openhdf(_PR_,s); delete []s; }
++//---------------------------------------------------------------------------
++void MGL_EXPORT mgl_parser_start_id(HMPR pr, int id)
++{ pr->StarObhID = id; }
++void MGL_EXPORT mgl_parser_start_id_(uintptr_t* p, int *id)
++{ mgl_parser_start_id(_PR_, *id); }
++
++//---------------------------------------------------------------------------
++mglCommand mgls_prg_cmd[] = {
++ {"ask",_("Define parameter from user input"),"ask $N 'question'", 0, 6},
++ {"break",_("Break for-loop"),"break", 0, 6},
++ {"call",_("Execute script in external file"),"call 'name' [args]", 0, 6},
++ {"continue",_("Skip commands and iterate for-loop again"),"continue", 0, 6},
++ {"defchr",_("Define parameter as character"),"defchr $N val", 0, 6},
++ {"define",_("Define constant or parameter"),"define $N sth | Var val", 0, 6},
++ {"defnum",_("Define parameter as numerical value"),"defnum $N val", 0, 6},
++// {"defpal",_("Define parameter as palette color"),"defpal $N val", 0, 6},
++ {"else",_("Execute if condition is false"),"else", 0, 6},
++ {"elseif",_("Conditional operator"),"elseif val|Dat ['cond']", 0, 6},
++ {"endif",_("Finish if/else block"),"endif", 0, 6},
++ {"for",_("For loop"),"for $N v1 v2 [dv] | $N Dat", 0, 6},
++ {"func",_("Start function definition and stop execution of main script"),"func 'name' [narg]", 0, 6},
++ {"if",_("Conditional operator"),"if val|Dat ['cond']", 0, 6},
++ {"list",_("Creates new variable from list of numbers or data"),"list Var v1 ...|Var D1 ...", 0, 4},
++ {"next",_("Start next for-loop iteration"),"next", 0, 6},
++ {"once",_("Start/close commands which should executed only once"),"once val", 0, 6},
++ {"return",_("Return from function"),"return", 0, 6},
++ {"stop",_("Stop execution"),"stop", 0, 6},
++{"","","",NULL,0}};
++//-----------------------------------------------------------------------------
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * pde.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include "mgl2/data.h"\r
++#include "mgl2/datac.h"\r
++#include "mgl2/eval.h"\r
++#include "mgl2/thread.h"\r
++#include "mgl2/base.h"\r
++const double GAMMA=0.1; ///< value for damping\r
++HADT MGL_NO_EXPORT mglFormulaCalcC(const char *str, const std::vector<mglDataA*> &head);\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Advanced PDE series in 2D case\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_NO_EXPORT mgl_operator_exp(long n, dual *h, dual *a, dual *f)\r
++{\r
++ memset(f,0,2*n*sizeof(dual));\r
++ const long i1=n/2, i2=3*n/2-1;\r
++#pragma omp parallel for\r
++ for(long j=0;j<n;j++)\r
++ {\r
++ long jp = (j+1)%n;\r
++<<<<<<< HEAD\r
++ mreal h1=real(h[n*j]), h2=real(h[n-1+n*j]);\r
++ mreal g1=(h1+real(h[n*jp]))/2, g2=(h2+real(h[n-1+n*jp]))/2;\r
++ mreal k1=M_PI*2*j/n, k2 = M_PI*(2*j+1)/n;\r
++ for(long i=0;i<i1;i++)\r
++ {\r
++ f[2*j] += a[i]*exp(dual(0,h1+i*k1));\r
++ f[2*j+1] += a[i]*exp(dual(0,g1+i*k2));\r
++ }\r
++ for(long i=i1;i<i2;i++)\r
++ {\r
++ mreal hh = real(h[i-i1+n*j]);\r
++ f[2*j] += a[i]*exp(dual(0,hh+i*k1));\r
++ f[2*j+1] += a[i]*exp(dual(0,(hh+real(h[i-i1+n*jp]))/2+i*k2));\r
++ }\r
++ for(long i=i2;i<2*n;i++)\r
++ {\r
++ f[2*j] += a[i]*exp(dual(0,h2+i*k1));\r
++ f[2*j+1] += a[i]*exp(dual(0,g2+i*k2));\r
++=======\r
++ dual h1=h[n*j]*dual(0,1), g1=(h1+h[n*jp]*dual(0,1))/mreal(2);\r
++ dual h2=h[n-1+n*j]*dual(0,1), g2=(h2+h[n-1+n*jp]*dual(0,1))/mreal(2);\r
++ mreal k1=M_PI*2*j/n, k2 = M_PI*(2*j+1)/n;\r
++ for(long i=0;i<i1;i++)\r
++ {\r
++ f[2*j] += a[i]*exp(h1+dual(0,i*k1));\r
++ f[2*j+1] += a[i]*exp(g1+dual(0,i*k2));\r
++ }\r
++ for(long i=i1;i<i2;i++)\r
++ {\r
++ dual hh = h[i-i1+n*j];\r
++ f[2*j] += a[i]*exp(hh*dual(0,1)+dual(0,i*k1));\r
++ f[2*j+1] += a[i]*exp((hh+h[i-i1+n*jp])*dual(0,0.5)+dual(0,i*k2));\r
++ }\r
++ for(long i=i2;i<2*n;i++)\r
++ {\r
++ f[2*j] += a[i]*exp(h2+dual(0,i*k1));\r
++ f[2*j+1] += a[i]*exp(g2+dual(0,i*k2));\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ }\r
++ }\r
++ memset(a,0,2*n*sizeof(dual));\r
++#pragma omp parallel for\r
++ for(long i=0;i<2*n;i++)\r
++ {\r
++<<<<<<< HEAD\r
++ register long ii=i-i1;\r
++ if(ii<0) ii=0; if(ii>n-1) ii=n-1;\r
++ double kk=M_PI*2*i/n;\r
++ for(long j=0;j<n;j++)\r
++ {\r
++ mreal h1 = real(h[ii+n*j]), g1 = (h1+real(h[ii+n*((j+1)%n)]))/2;\r
++ a[i] += f[2*j]*exp(dual(0,h1-kk*j));\r
++ a[i] += f[2*j+1]*exp(dual(0,g1-kk*(j+0.5)));\r
++=======\r
++ long ii=i-i1;\r
++ if(ii<0) ii=0;\r
++ if(ii>n-1) ii=n-1;\r
++ double kk=M_PI*2*i/n;\r
++ for(long j=0;j<n;j++)\r
++ {\r
++ dual h1 = h[ii+n*j], g1 = (h1+h[ii+n*((j+1)%n)])*dual(0,0.5);\r
++ a[i] += f[2*j]*exp(h1*dual(0,1)-dual(0,kk*j));\r
++ a[i] += f[2*j+1]*exp(g1-dual(0,kk*(j+0.5)));\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++<<<<<<< HEAD\r
++void MGL_NO_EXPORT mgl_operator_hrm(long n, dual *h, dual *a, dual *f, dual *g, dual *o)\r
++=======\r
++void MGL_NO_EXPORT mgl_operator_lin(long n, mreal *h, dual *a, dual *f, dual *g, dual *o)\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++{\r
++ memset(f,0,2*n*sizeof(dual));\r
++ memset(g,0,2*n*sizeof(dual));\r
++ const long i1=n/2, i2=3*n/2-1;\r
++<<<<<<< HEAD\r
++ #pragma omp parallel for\r
++ for(long j=0;j<n;j++)\r
++ {\r
++ long jp = (j+1)%n;\r
++ mreal h1=real(h[n*j]), h2=real(h[n-1+n*j]);\r
++ mreal g1=h1+real(h[n*jp])/2., g2=h2+real(h[n-1+n*jp])/2.;\r
++=======\r
++#pragma omp parallel for\r
++ for(long j=0;j<n;j++)\r
++ {\r
++ long jp = (j+1)%n;\r
++ mreal h1=tanh(h[n*j]), g1=(h1+tanh(h[n*jp]))/2;\r
++ mreal h2=tanh(h[n-1+n*j]), g2=(h2+tanh(h[n-1+n*jp]))/2;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ mreal k1=M_PI*2*j/n, k2 = M_PI*(2*j+1)/n;\r
++ for(long i=0;i<i1;i++)\r
++ {\r
++ dual e1=exp(dual(0,i*k1)), e2=exp(dual(0,i*k2));\r
++ f[2*j] += a[i]*h1*e1; f[2*j+1] += a[i]*g1*e2;\r
++ g[2*j] += a[i]*e1; g[2*j+1] += a[i]*e2;\r
++ }\r
++ for(long i=i1;i<i2;i++)\r
++ {\r
++<<<<<<< HEAD\r
++ mreal hh = real(h[i-i1+n*j]);\r
++ mreal gg = hh+real(h[i-i1+n*jp])/2.;\r
++=======\r
++ mreal hh = tanh(h[i-i1+n*j]);\r
++ mreal gg = (hh+tanh(h[i-i1+n*jp]))/2;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ dual e1=exp(dual(0,i*k1)), e2=exp(dual(0,i*k2));\r
++ f[2*j] += a[i]*hh*e1; f[2*j+1] += a[i]*gg*e2;\r
++ g[2*j] += a[i]*e1; g[2*j+1] += a[i]*e2;\r
++ }\r
++ for(long i=i2;i<2*n;i++)\r
++ {\r
++ dual e1=exp(dual(0,i*k1)), e2=exp(dual(0,i*k2));\r
++ f[2*j] += a[i]*h2*e1; f[2*j+1] += a[i]*g2*e2;\r
++ g[2*j] += a[i]*e1; g[2*j+1] += a[i]*e2;\r
++ }\r
++ }\r
++ memset(o,0,2*n*sizeof(dual));\r
++<<<<<<< HEAD\r
++ #pragma omp parallel for\r
++ for(long i=0;i<2*n;i++)\r
++ {\r
++ register long ii=i-i1;\r
++ if(ii<0) ii=0; if(ii>n-1) ii=n-1;\r
++ double kk=M_PI*2*i/n;\r
++ for(long j=0;j<n;j++)\r
++ {\r
++ mreal h1 = real(h[ii+n*j]);\r
++ mreal g1 = h1+real(h[ii+n*((j+1)%n)])/2.;\r
++=======\r
++#pragma omp parallel for\r
++ for(long i=0;i<2*n;i++)\r
++ {\r
++ long ii=i-i1;\r
++ if(ii<0) ii=0;\r
++ if(ii>n-1) ii=n-1;\r
++ double kk=M_PI*2*i/n;\r
++ for(long j=0;j<n;j++)\r
++ {\r
++ mreal h1 = tanh(h[ii+n*j]);\r
++ mreal g1 = (h1+tanh(h[ii+n*((j+1)%n)]))/2;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ dual e1=exp(dual(0,-j*kk)), e2=exp(dual(0,-kk*(j+0.5)));\r
++ o[i] += f[2*j]*e1 + f[2*j+1]*e2;\r
++ o[i] += g[2*j]*h1*e1 + g[2*j+1]*g1*e2;\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++<<<<<<< HEAD\r
++inline dual isqrt(dual a)\r
++{ mreal b=imag(a); return b>=0?dual(sqrt(b),0):dual(0,sqrt(-b)); }\r
++void MGL_NO_EXPORT mgl_operator_lin(long n, dual *h, dual *a, dual *f, dual *g, dual *o)\r
++{\r
++ memset(f,0,2*n*sizeof(dual));\r
++ memset(g,0,2*n*sizeof(dual));\r
++ const long i1=n/2, i2=3*n/2-1;\r
++#pragma omp parallel for\r
++ for(long j=0;j<n;j++)\r
++ {\r
++ long jp = (j+1)%n;\r
++ dual h1=tanh(isqrt(h[n*j])), h2=tanh(isqrt(h[n-1+n*j]));\r
++ dual g1=tanh(h1+isqrt(h[n*jp]))/2., g2=tanh(h2+isqrt(h[n-1+n*jp]))/2.;\r
++ mreal k1=M_PI*2*j/n, k2 = M_PI*(2*j+1)/n;\r
++ for(long i=0;i<i1;i++)\r
++ {\r
++ dual e1=exp(dual(0,i*k1)), e2=exp(dual(0,i*k2));\r
++ f[2*j] += a[i]*h1*e1; f[2*j+1] += a[i]*g1*e2;\r
++ g[2*j] += a[i]*e1; g[2*j+1] += a[i]*e2;\r
++ }\r
++ for(long i=i1;i<i2;i++)\r
++ {\r
++ dual hh = tanh(isqrt(h[i-i1+n*j]));\r
++ dual gg = tanh(hh+isqrt(h[i-i1+n*jp]))/2.;\r
++ dual e1=exp(dual(0,i*k1)), e2=exp(dual(0,i*k2));\r
++ f[2*j] += a[i]*hh*e1; f[2*j+1] += a[i]*gg*e2;\r
++ g[2*j] += a[i]*e1; g[2*j+1] += a[i]*e2;\r
++ }\r
++ for(long i=i2;i<2*n;i++)\r
++ {\r
++ dual e1=exp(dual(0,i*k1)), e2=exp(dual(0,i*k2));\r
++ f[2*j] += a[i]*h2*e1; f[2*j+1] += a[i]*g2*e2;\r
++ g[2*j] += a[i]*e1; g[2*j+1] += a[i]*e2;\r
++ }\r
++ }\r
++ memset(o,0,2*n*sizeof(dual));\r
++#pragma omp parallel for\r
++ for(long i=0;i<2*n;i++)\r
++ {\r
++ register long ii=i-i1;\r
++ if(ii<0) ii=0; if(ii>n-1) ii=n-1;\r
++ double kk=M_PI*2*i/n;\r
++ for(long j=0;j<n;j++)\r
++ {\r
++ dual h1 = tanh(isqrt(h[ii+n*j]));\r
++ dual g1 = tanh(h1+isqrt(h[ii+n*((j+1)%n)]))/2.;\r
++ dual e1=exp(dual(0,-j*kk)), e2=exp(dual(0,-kk*(j+0.5)));\r
++ o[i] += f[2*j]*e1 + f[2*j+1]*e2;\r
++ o[i] += g[2*j]*h1*e1 + g[2*j+1]*g1*e2;\r
++ }\r
++ }\r
++=======\r
++HADT MGL_NO_EXPORT mgl_apde_calc_ham(HMDT hs, bool old, const char *func, std::vector<mglDataA*> list, const mreal dd)\r
++{\r
++ HADT ham = mglFormulaCalcC(func, list); mgl_datac_mul_num(ham,dd);\r
++ const long nx = ham->nx;\r
++ if(old)\r
++ {\r
++ mreal hh = ham->Imag().Minimal();\r
++ if(hh>0) hh=0;\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx*nx;i++)\r
++ {\r
++ hs->a[i] = sqrt(imag(ham->a[i])-hh); // non-additive term\r
++ ham->a[i] = dual(real(ham->a[i]),hh); // additive terms\r
++ }\r
++ }\r
++ else\r
++ {\r
++ mglData xIm(nx), pIm(nx);\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx;i++) // first find minimal values along x and p\r
++ {\r
++ dual *ax=ham->a+i, *ay=ham->a+i*nx;\r
++ mreal mx=imag(ax[0]), my=imag(ay[0]);\r
++ for(long j=1;j<nx;j++) my = (my<imag(ay[j]))?my:imag(ay[j]);\r
++ for(long j=1;j<nx;j++) mx = (mx<imag(ax[j*nx]))?mx:imag(ax[j*nx]);\r
++ xIm.a[i] = mx; pIm.a[i]=my;\r
++ }\r
++ mreal mIm=xIm.a[0]; mreal *aa=xIm.a; // global minimum\r
++ for(long j=1;j<nx;j++) mIm = (mIm<aa[j])?mIm:aa[j];\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<nx;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ mreal hh = xIm.a[i]+pIm.a[j]-mIm;\r
++ long i0=i+nx*j;\r
++ hs->a[i0] = sqrt(fabs(imag(ham->a[i0])-hh)); // non-additive term. NOTE: fabs() guarantee absence of negative values due to rounding error\r
++ ham->a[i0] = dual(real(ham->a[i0]),hh); // additive terms\r
++ }\r
++ }\r
++ return ham;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++}\r
++//-----------------------------------------------------------------------------\r
++// Solve equation dx/dy = func(p,x,y,|u|)[u] where p=d/dx. There are no assumptions about form of func().\r
++HADT MGL_EXPORT mgl_pde_adv_c(HMGL gr, const char *func, HCDT ini_re, HCDT ini_im, mreal dt, mreal k0, const char *opt)\r
++{\r
++ mreal gamma = gr->SaveState(opt); if(mgl_isnan(gamma)) gamma = 20;\r
++ const mglPoint &Min=gr->Min, &Max=gr->Max;\r
++ const long nx=ini_re->GetNx(), nt = long((Max.y-Min.y)/dt)+1;\r
++ if(nx<2 || nt<2 || Max.x==Min.x){ gr->SetWarn(mglWarnLow,"PDE"); return 0; } // Too small data\r
++ if(ini_im->GetNx() != nx) { gr->SetWarn(mglWarnDim,"PDE"); return 0; } // Wrong dimensions\r
++\r
++ mglDataC *res=new mglDataC(nx, nt);\r
++ mglData hIm(nx,nx); // for advanced damping calculation\r
++ mglDataC u(nx); u.s = L"u";\r
++ mglDataV x(nx,nx), y(nx,nx), r(nx,nx);\r
++ mglDataW p(nx,nx); p.s = L"p";\r
++ bool old = func[0]==';'; if(old) func=func+1;\r
++ x.s = L"x"; y.s = L"y"; r.s=L"#$mgl";\r
++ const mreal dp = 2*M_PI/(Max.x-Min.x), dd = k0*dt/2;\r
++ x.Fill(Min.x,Max.x,'x'); p.Freq(dp/k0,'y');\r
++ std::vector<mglDataA*> list;\r
++ list.push_back(&x); list.push_back(&y); list.push_back(&p); list.push_back(&r); list.push_back(&u);\r
++\r
++ dual *a = new dual[2*nx]; memset(a,0,2*nx*sizeof(dual)); // Add "damping" area\r
++ dual *f = new dual[6*nx], *g=f+2*nx, *s=f+4*nx;\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx;i++) // Initial conditions\r
++ a[i+nx/2] = dual(ini_re->v(i), ini_im->v(i));\r
++ double *dmp = new double[2*nx]; memset(dmp,0,2*nx*sizeof(double));\r
++#pragma omp parallel for\r
++ for(long i=0;i<2*nx;i++) // dumping\r
++ {\r
++ if(i<nx/2) dmp[i] += gamma*mgl_ipow((nx/2-i)/mreal(nx/2),2);\r
++ if(i>3*nx/2) dmp[i] += gamma*mgl_ipow((i-3*nx/2-1)/mreal(nx/2),2);\r
++ }\r
++ bool have_y = mglchr(func,'y');\r
++ HADT ham;\r
++<<<<<<< HEAD\r
++ if(!have_y)\r
++ { ham = mglFormulaCalcC(func, list); mgl_datac_mul_num(ham,dd); }\r
++=======\r
++ if(!have_y) ham = mgl_apde_calc_ham(&hIm, old, func, list, dd);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ for(long k=0;k<nt;k++)\r
++ {\r
++ memcpy(u.a,a+nx/2,nx*sizeof(dual));\r
++ memcpy(res->a+k*nx,a+nx/2,nx*sizeof(dual));\r
++ if(have_y)\r
++<<<<<<< HEAD\r
++ { y.Fill(k*dt); ham = mglFormulaCalcC(func, list); mgl_datac_mul_num(ham,dd); }\r
++ mgl_operator_exp(nx,ham->a,a,f);\r
++ mgl_operator_lin(nx,ham->a,a,f,g,s);\r
++ mgl_operator_lin(nx,ham->a,s,f,g,s);\r
++#pragma omp parallel for\r
++ for(long i=0;i<2*nx;i++)\r
++ a[i] = (a[i]-s[i]/mreal(8*nx*nx))*exp(-dmp[i]*dt)/mreal(2*nx);\r
++=======\r
++ { y.Fill(k*dt); ham = mgl_apde_calc_ham(&hIm, old, func, list, dd); }\r
++ mgl_operator_exp(nx,ham->a,a,f);\r
++ mgl_operator_lin(nx,hIm.a,a,f,g,s);\r
++ mgl_operator_lin(nx,hIm.a,s,f,g,s);\r
++#pragma omp parallel for\r
++ for(long i=0;i<2*nx;i++)\r
++ a[i] = (a[i]-s[i]/mreal(8*nx*nx))*mreal(exp(-dmp[i]*dt)/2/nx);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ if(have_y) delete ham;\r
++ }\r
++ delete []a; delete []f; delete []dmp;\r
++ if(!have_y) delete ham;\r
++ gr->LoadState(); return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++HMDT MGL_EXPORT mgl_pde_adv(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0, const char *opt)\r
++{\r
++ HADT res = mgl_pde_adv_c(gr,ham,ini_re,ini_im,dz,k0,opt);\r
++ HMDT out = mgl_datac_abs(res); delete res; return out;\r
++}\r
++//-----------------------------------------------------------------------------\r
++uintptr_t MGL_EXPORT mgl_pde_adv_c_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo)\r
++{ char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ uintptr_t res = uintptr_t(mgl_pde_adv_c(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o));\r
++ delete []o; delete []s; return res; }\r
++//-----------------------------------------------------------------------------\r
++uintptr_t MGL_EXPORT mgl_pde_adv_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo)\r
++{ char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ uintptr_t res = uintptr_t(mgl_pde_adv(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o));\r
++ delete []o; delete []s; return res; }\r
++//-----------------------------------------------------------------------------\r
++/*HADT MGL_EXPORT mgl_pde_adv_3d_c(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0, const char *opt)\r
++{\r
++ mreal gamma = gr->SaveState(opt); if(mgl_isnan(gamma)) gamma = GAMMA;\r
++ mglPoint Min=gr->Min, Max=gr->Max;\r
++ long nx=ini_re->GetNx(), ny=ini_re->GetNy(), nz = long((Max.z-Min.z)/dz)+1;\r
++ if(nx<2 || nz<2 || Max.x==Min.x) // Too small data\r
++ { gr->SetWarn(mglWarnLow,"PDE"); return 0; }\r
++ if(ini_im->GetNx()*ini_im->GetNy() != nx*ny)// Wrong dimensions\r
++ { gr->SetWarn(mglWarnDim,"PDE"); return 0; }\r
++ mglDataC *res=new mglDataC(nz, nx, ny);\r
++\r
++ mglDataV x(nx,ny), y(nx,ny), z, r(nx,ny);\r
++ mglDataW p(nx,ny), q(nx,ny);\r
++ x.s = L"x"; y.s = L"y"; p.s = L"p"; q.s = L"q"; z.s = L"z"; r.s=L"#$mgl";\r
++ //z.Fill(f->zz);\r
++ mreal dx = (Max.x-Min.x)/(nx-1), dy = ny>1?(Max.y-Min.y)/(ny-1):0;\r
++ mreal dp = M_PI/(Max.x-Min.x), dq = M_PI/(Max.y-Min.y);\r
++ double dd = k0*dz;\r
++ x.Fill(Min.x,Max.x,'x'); p.Freq(dp/k0,'x');\r
++ y.Fill(Min.y,Max.y,'y'); q.Freq(dq/k0,'y');\r
++\r
++ ddual *a = new ddual[4*nx*ny]; // Add "damping" area\r
++ ddual *f = new ddual[4*nx*ny]; // Effective "spectrum"\r
++ memset(a,0,4*nx*ny*sizeof(ddual));\r
++ memset(f,0,4*nx*ny*sizeof(ddual));\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++) // Initial conditions\r
++ {\r
++ long i0 = i+nx/2+2*nx*(j+ny/2);\r
++ a[i0] = dual(ini_re->v(i,j), ini_im->v(i,j));\r
++ res->a[nz*(i+nx*j)] = a[i0];\r
++ }\r
++ double *dmp = new double[4*nx*ny];\r
++ memset(dmp,0,4*nx*ny*sizeof(double));\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<2*ny;j++) for(long i=0;i<2*nx;i++) // step 1\r
++ {\r
++ long i0 = i+2*nx*j;\r
++ if(i<nx/2) dmp[i0] += gamma*mgl_ipow((nx/2-i)/(nx/2.),2);\r
++ if(i>3*nx/2) dmp[i0] += gamma*mgl_ipow((i-3*nx/2-1)/(nx/2.),2);\r
++ if(j<ny/2) dmp[i0] += gamma*mgl_ipow((ny/2-j)/(ny/2.),2);\r
++ if(j>3*ny/2) dmp[i0] += gamma*mgl_ipow((j-3*ny/2-1)/(ny/2.),2);\r
++ }\r
++ ddual *Hdat = new ddual[nx*nx*ny*ny];\r
++ for(long k=1;k<nz;k++)\r
++ {\r
++ }\r
++}*/\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Simplified PDE series\r
++//\r
++//-----------------------------------------------------------------------------\r
++struct mgl_pde_ham\r
++{\r
++ ddual *a,*hxy,*hxv,*huv,*huy;\r
++ const char *eqs;\r
++ long nx,ny;\r
++ double xx,yy,xs,ys,dx,dy,dq,dp,zz;\r
++ double dd;\r
++};\r
++void MGL_NO_EXPORT mgl_pde_hprep(const mgl_pde_ham *f)\r
++{\r
++ const long nx = f->nx, ny = f->ny;\r
++ mglDataV x(nx,ny), y(nx,ny), z, r(nx,ny);\r
++ mglDataW p(nx,ny), q(nx,ny);\r
++ x.s = L"x"; y.s = L"y"; p.s = L"p"; q.s = L"q"; r.s=L"#$mgl";\r
++ z.s = L"z"; z.Fill(f->zz);\r
++ dual dd(0,f->dd);\r
++ mglData u(nx,ny); u.s = L"u";\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx*ny;i++) u.a[i] = abs(f->a[i]);\r
++ std::vector<mglDataA*> list;\r
++ list.push_back(&x); list.push_back(&y); list.push_back(&z);\r
++ list.push_back(&p); list.push_back(&q); list.push_back(&u);\r
++\r
++ x.Fill(f->xx,f->xx+f->dx*(nx-1),'x'); p.Freq(0,'x');\r
++ y.Fill(f->yy,f->yy+f->dy*(ny-1),'y'); q.Freq(0,'y');\r
++ HADT res = mglFormulaCalcC(f->eqs, list);\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx*ny;i++) f->hxy[i] = res->a[i]*dd;\r
++ delete res;\r
++ if(ny>2)\r
++ {\r
++ x.Fill(f->xs); p.Freq(f->dp,'x');\r
++ res = mglFormulaCalcC(f->eqs, list);\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx*ny;i++) f->huy[i] = res->a[i]*dd;\r
++ delete res;\r
++ }\r
++ x.Fill(f->xs); p.Freq(f->dp,'x');\r
++ y.Fill(f->ys); q.Freq(f->dq,'y');\r
++ res = mglFormulaCalcC(f->eqs, list);\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx*ny;i++) f->huv[i] = res->a[i]*dd;\r
++ delete res;\r
++ if(ny>2)\r
++ {\r
++ x.Fill(f->xx,f->xx+f->dx*(nx-1),'x'); p.Freq(0,'x');\r
++ res = mglFormulaCalcC(f->eqs, list);\r
++#pragma omp parallel for\r
++ for(long i=0;i<nx*ny;i++) f->hxv[i] = res->a[i]*dd;\r
++ delete res;\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++// Solve equation dx/dz = func(p,q,x,y,z,|u|)[u] where p=d/dx, q=d/dy. At this moment simplified form of ham is supported: ham = f(p,q,z) + g(x,y,z,'u'), where variable 'u'=|u| (for allowing solve nonlinear problems). You may specify imaginary part like ham = p^2 + 1i*x*(x>0).\r
++HADT MGL_EXPORT mgl_pde_solve_c(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0, const char *opt)\r
++{\r
++ mreal gamma = gr->SaveState(opt); if(mgl_isnan(gamma)) gamma = GAMMA;\r
++ mglPoint Min=gr->Min, Max=gr->Max;\r
++ long nx=ini_re->GetNx(), ny=ini_re->GetNy(), nz = long((Max.z-Min.z)/dz)+1;\r
++ if(nx<2 || nz<2 || Max.x==Min.x) // Too small data\r
++ { gr->SetWarn(mglWarnLow,"PDE"); return 0; }\r
++ if(ini_im->GetNx()*ini_im->GetNy() != nx*ny)// Wrong dimensions\r
++ { gr->SetWarn(mglWarnDim,"PDE"); return 0; }\r
++ mglDataC *res=new mglDataC(nz, nx, ny);\r
++\r
++ ddual *a = new ddual[4*nx*ny], hh0; // Add "damping" area\r
++ ddual *hxy = new ddual[4*nx*ny], *hxv = new ddual[4*nx*ny];\r
++ ddual *huy = new ddual[4*nx*ny], *huv = new ddual[4*nx*ny];\r
++ ddual *hx = new ddual[2*nx], *hv = new ddual[2*ny];\r
++ ddual *hy = new ddual[2*ny], *hu = new ddual[2*nx];\r
++ double *dmp = new double[4*nx*ny];\r
++ memset(a,0,4*nx*ny*sizeof(ddual));\r
++ memset(dmp,0,4*nx*ny*sizeof(double));\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++) // Initial conditions\r
++ {\r
++ long i0 = i+nx/2+2*nx*(j+ny/2);\r
++ a[i0] = dual(ini_re->v(i,j), ini_im->v(i,j));\r
++ res->a[nz*(i+nx*j)] = a[i0];\r
++ }\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<2*ny;j++) for(long i=0;i<2*nx;i++) // step 1\r
++ {\r
++ long i0 = i+2*nx*j;\r
++ if(i<nx/2) dmp[i0] += gamma*mgl_ipow((nx/2-i)/(nx/2.),2);\r
++ if(i>3*nx/2) dmp[i0] += gamma*mgl_ipow((i-3*nx/2-1)/(nx/2.),2);\r
++ if(j<ny/2) dmp[i0] += gamma*mgl_ipow((ny/2-j)/(ny/2.),2);\r
++ if(j>3*ny/2) dmp[i0] += gamma*mgl_ipow((j-3*ny/2-1)/(ny/2.),2);\r
++ }\r
++ mreal dx = (Max.x-Min.x)/(nx-1), dy = ny>1?(Max.y-Min.y)/(ny-1):0;\r
++ mreal dp = M_PI/(Max.x-Min.x)/k0, dq = M_PI/(Max.y-Min.y)/k0;\r
++ mreal xs=(Min.x+Max.x)/2, ys=(Min.y+Max.y)/2;\r
++ double dd = k0*dz;\r
++\r
++ mgl_pde_ham tmp;tmp.eqs = ham;\r
++ tmp.nx = 2*nx; tmp.ny = 2*ny; tmp.dd = dd; tmp.a=a;\r
++ tmp.hxy=hxy; tmp.hxv=hxv; tmp.huy=huy; tmp.huv=huv;\r
++ tmp.xx = Min.x-dx*(nx/2); tmp.xs = xs; tmp.dx = dx; tmp.dp = dp;\r
++ tmp.yy = Min.y-dy*(ny/2); tmp.ys = ys; tmp.dy = dy; tmp.dq = dq;\r
++\r
++ // prepare fft. NOTE: slow procedures due to unknown nx, ny.\r
++ void *wtx = mgl_fft_alloc(2*nx,0,0);\r
++ void *wty = mgl_fft_alloc(2*ny,0,0);\r
++ for(long k=1;k<nz;k++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ tmp.zz = Min.z+dz*k;\r
++ memset(hxy,0,4*nx*ny*sizeof(dual)); memset(hxv,0,4*nx*ny*sizeof(dual));\r
++ memset(huv,0,4*nx*ny*sizeof(dual)); memset(huy,0,4*nx*ny*sizeof(dual));\r
++ mgl_pde_hprep(&tmp);\r
++ for(long i=0;i<2*nx;i++) { hx[i] = hxv[i]; hu[i] = huv[i]; }\r
++ for(long j=0;j<2*ny;j++) { hy[j] = huy[2*nx*j]; hv[j] = huv[2*nx*j];}\r
++ // rearrange arrays\r
++ hh0=hu[0];\r
++ if(ny>1)\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<2*ny;j++) for(long i=0;i<2*nx;i++)\r
++ {\r
++ long i0 = i+2*nx*j; huv[i0] -= hh0;\r
++ hxv[i0] -= hx[i]+hv[j]-hh0;\r
++ huy[i0] -= hu[i]+hy[j]-hh0;\r
++ }\r
++ else\r
++#pragma omp parallel for\r
++ for(long i=0;i<4*nx*ny;i++) huv[i] -= hh0;\r
++ // solve equation\r
++ if(ny>1)\r
++#pragma omp parallel\r
++ {\r
++ void *wsx = mgl_fft_alloc_thr(2*nx), *wsy = mgl_fft_alloc_thr(2*ny);\r
++#pragma omp for\r
++ for(long i=0;i<4*nx*ny;i++) a[i] *= exp(hxy[i])*exp(-double(dmp[i]*dz));\r
++#pragma omp for\r
++ for(long i=0;i<2*ny;i++) mgl_fft((double *)(a+i*2*nx), 1, 2*nx, wtx, wsx, false);\r
++#pragma omp for\r
++ for(long i=0;i<4*nx*ny;i++) a[i] *= exp(huy[i]);\r
++#pragma omp for\r
++ for(long i=0;i<2*nx;i++) mgl_fft((double *)(a+i), 2*nx, 2*ny, wty, wsy, false);\r
++#pragma omp for\r
++ for(long i=0;i<4*nx*ny;i++) a[i] *= exp(huv[i]);\r
++#pragma omp for\r
++ for(long i=0;i<2*ny;i++) mgl_fft((double *)(a+2*i*nx), 1, 2*nx, wtx, wsx, true);\r
++#pragma omp for\r
++ for(long i=0;i<4*nx*ny;i++) a[i] *= exp(hxv[i]);\r
++#pragma omp for\r
++ for(long i=0;i<2*nx;i++) mgl_fft((double *)(a+i), 2*nx, 2*ny, wty, wsy, true);\r
++ mgl_fft_free_thr(wsx); mgl_fft_free_thr(wsy);\r
++ }\r
++ else\r
++#pragma omp parallel\r
++ {\r
++ void *wsx = mgl_fft_alloc_thr(2*nx);\r
++#pragma omp for\r
++ for(long i=0;i<4*nx*ny;i++) a[i] *= exp(hxy[i])*exp(-double(dmp[i]*dz));\r
++#pragma omp for\r
++ for(long i=0;i<2*ny;i++) mgl_fft((double *)(a+i*2*nx), 1, 2*nx, wtx, wsx, false);\r
++#pragma omp for\r
++ for(long i=0;i<4*nx*ny;i++) a[i] *= exp(huv[i]);\r
++#pragma omp for\r
++ for(long i=0;i<2*ny;i++) mgl_fft((double *)(a+2*i*nx), 1, 2*nx, wtx, wsx, true);\r
++ mgl_fft_free_thr(wsx);\r
++ }\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++) // save result\r
++ res->a[k+nz*(i+nx*j)] = a[i+nx/2+2*nx*(j+ny/2)];\r
++ }\r
++ mgl_fft_free(wtx,0,0); mgl_fft_free(wty,0,0);\r
++ delete []a; delete []dmp;\r
++ delete []hxy; delete []hxv; delete []huy; delete []huv;\r
++ delete []hx; delete []hy; delete []hu; delete []hv;\r
++ gr->LoadState();\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++HMDT MGL_EXPORT mgl_pde_solve(HMGL gr, const char *ham, HCDT ini_re, HCDT ini_im, mreal dz, mreal k0, const char *opt)\r
++{\r
++ HADT res = mgl_pde_solve_c(gr,ham,ini_re,ini_im,dz,k0,opt);\r
++ HMDT out = mgl_datac_abs(res); delete res; return out;\r
++}\r
++//-----------------------------------------------------------------------------\r
++uintptr_t MGL_EXPORT mgl_pde_solve_c_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo)\r
++{ char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ uintptr_t res = uintptr_t(mgl_pde_solve_c(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o));\r
++ delete []o; delete []s; return res; }\r
++//-----------------------------------------------------------------------------\r
++uintptr_t MGL_EXPORT mgl_pde_solve_(uintptr_t* gr, const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, mreal *dz, mreal *k0, const char *opt, int l, int lo)\r
++{ char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ uintptr_t res = uintptr_t(mgl_pde_solve(_GR_, s, _DA_(ini_re), _DA_(ini_im), *dz, *k0, o));\r
++ delete []o; delete []s; return res; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// ODE series\r
++//\r
++//-----------------------------------------------------------------------------\r
++struct mglOdeTxt { long n; HMEX *eq; const char *var; };\r
++void MGL_NO_EXPORT mgl_txt_func(const mreal *x, mreal *dx, void *par)\r
++{\r
++ mglOdeTxt *p=(mglOdeTxt *)par;\r
++ mreal vars[MGL_VS];\r
++ for(long i=0;i<p->n;i++)\r
++ { char ch = p->var[i]; if(ch>='a' && ch<='z') vars[ch-'a']=x[i]; }\r
++#pragma omp parallel for\r
++ for(long i=0;i<p->n;i++)\r
++ dx[i] = mgl_expr_eval_v(p->eq[i], vars);\r
++}\r
++HMDT MGL_EXPORT mgl_ode_solve_str(const char *func, const char *var, HCDT x0, mreal dt, mreal tmax)\r
++{\r
++ if(!var || !(*var) || !func) return 0;\r
++ long len = strlen(func);\r
++ mglOdeTxt par; par.var=var;\r
++ par.n = strlen(var);\r
++ par.eq = new HMEX[par.n];\r
++ char *buf = new char[len+1], *f=buf, *g=f; memcpy(buf,func,len+1);\r
++ mreal *xx = new mreal[par.n];\r
++ for(long i=0;i<par.n;i++)\r
++ {\r
++ xx[i] = x0?x0->vthr(i):0;\r
++ for(long k=0;f[k];k++) if(f[k]==';')\r
++ { g = f+k+1; f[k]=0; break; }\r
++ if(f==g) g = f+strlen(f);\r
++ par.eq[i] = mgl_create_expr(f);\r
++ f = g;\r
++ }\r
++ HMDT res = mgl_ode_solve_ex(mgl_txt_func,par.n,xx,dt,tmax,&par,NULL);\r
++ for(long i=0;i<par.n;i++) mgl_delete_expr(par.eq[i]);\r
++ delete []par.eq; delete []buf; delete []xx;\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++struct mglOdeTxtC { long n; HAEX *eq; const char *var; };\r
++void MGL_NO_EXPORT mgl_txt_funcC(const mreal *x, mreal *dx, void *par)\r
++{\r
++ mglOdeTxtC *p=(mglOdeTxtC *)par;\r
++ dual vars[MGL_VS];\r
++ for(long i=0;i<p->n;i++)\r
++ { char ch = p->var[i]; if(ch>='a' && ch<='z') vars[ch-'a']=dual(x[2*i],x[2*i+1]); }\r
++#pragma omp parallel for\r
++ for(long i=0;i<p->n;i++)\r
++ {\r
++ dual r = mgl_cexpr_eval_v(p->eq[i], vars);\r
++ dx[2*i] = real(r); dx[2*i+1] = imag(r);\r
++ }\r
++}\r
++HADT MGL_EXPORT mgl_ode_solve_str_c(const char *func, const char *var, HCDT x0, mreal dt, mreal tmax)\r
++{\r
++ if(!var || !(*var) || !func) return 0;\r
++ long len = strlen(func);\r
++ mglOdeTxtC par; par.var=var;\r
++ par.n = strlen(var);\r
++ par.eq = new HAEX[par.n];\r
++ char *buf = new char[len+1], *f=buf, *g=f; memcpy(buf,func,len+1);\r
++ mreal *xx = new mreal[2*par.n];\r
++ const mglDataC *c = dynamic_cast<const mglDataC *>(x0);\r
++ for(long i=0;i<par.n;i++)\r
++ {\r
++ if(c) { xx[2*i]=real(c->a[i]); xx[2*i+1]=imag(c->a[i]); }\r
++ else { xx[2*i] = x0?x0->vthr(i):0; xx[2*i+1]=0; }\r
++ for(long k=0;f[k];k++) if(f[k]==';')\r
++ { g = f+k+1; f[k]=0; break; }\r
++ if(f==g) g = f+strlen(f);\r
++ par.eq[i] = mgl_create_cexpr(f);\r
++ f = g;\r
++ }\r
++ HMDT res = mgl_ode_solve_ex(mgl_txt_funcC,2*par.n,xx,dt,tmax,&par,NULL);\r
++ for(long i=0;i<par.n;i++) mgl_delete_cexpr(par.eq[i]);\r
++ delete []par.eq; delete []buf; delete []xx;\r
++ const long nn=par.n,nt=res->ny;\r
++ mglDataC *out = new mglDataC(nn, nt);\r
++#pragma omp parallel for\r
++ for(long i=0;i<nt*nn;i++) out->a[i] = dual(res->a[2*i],res->a[2*i+1]);\r
++ delete res; return out;\r
++}\r
++//-----------------------------------------------------------------------------\r
++HMDT MGL_EXPORT mgl_ode_solve(void (*func)(const mreal *x, mreal *dx, void *par), int n, const mreal *x0, mreal dt, mreal tmax, void *par)\r
++{ return mgl_ode_solve_ex(func,n,x0,dt,tmax,par,0); }\r
++HMDT MGL_EXPORT mgl_ode_solve_ex(void (*func)(const mreal *x, mreal *dx, void *par), int n, const mreal *x0, mreal dt, mreal tmax, void *par, void (*bord)(mreal *x, const mreal *xp, void *par))\r
++{\r
++ if(tmax<dt) return 0; // nothing to do\r
++ const long nt = int(tmax/dt+0.5)+1;\r
++ mglData *res=new mglData(n,nt);\r
++ mreal *x=new mreal[n], *k1=new mreal[n], *k2=new mreal[n], *k3=new mreal[n], *v=new mreal[n], hh=dt/2;\r
++ // initial conditions\r
++ for(long i=0;i<n;i++) x[i] = res->a[i] = x0[i];\r
++ // Runge Kutta scheme of 4th order\r
++ for(long k=1;k<nt;k++)\r
++ {\r
++ func(x,k1,par);\r
++ for(long i=0;i<n;i++) v[i] = x[i]+k1[i]*hh;\r
++ func(v,k2,par);\r
++ for(long i=0;i<n;i++) v[i] = x[i]+k2[i]*hh;\r
++ func(v,k3,par);\r
++ for(long i=0;i<n;i++) { v[i] = x[i]+k3[i]*dt; k3[i] += k2[i]; }\r
++ func(v,k2,par);\r
++ for(long i=0;i<n;i++) x[i] += (k1[i]+k2[i]+2*k3[i])*dt/6;\r
++ if(bord) bord(x,res->a+n*(k-1),par);\r
++ for(long i=0;i<n;i++) res->a[i+n*k] = x[i];\r
++ }\r
++ delete []x; delete []k1; delete []k2; delete []k3; delete []v;\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Common functions for quasioptical calculations\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_NO_EXPORT mgl_ray3d(const mreal *in, mreal *out, void *par)\r
++{\r
++ mglFormula *eqs = (mglFormula *)par;\r
++ const char *v="xyzpqvt";\r
++ mreal var[MGL_VS]; memset(var,0,MGL_VS*sizeof(mreal));\r
++ for(int i=0;i<7;i++) var[v[i]-'a'] = in[i];\r
++ out[0] = eqs->CalcD(var,'p'); out[3] = -eqs->CalcD(var,'x');\r
++ out[1] = eqs->CalcD(var,'q'); out[4] = -eqs->CalcD(var,'y');\r
++ out[2] = eqs->CalcD(var,'v'); out[5] = -eqs->CalcD(var,'z');\r
++ out[7] = eqs->CalcD(var,'i'); out[6] = 1;\r
++}\r
++// Solve GO ray equation like dr/dt = d ham/dp, dp/dt = -d ham/dr where ham = ham(x,y,z,p,q,v,t) and px=p, py=q, pz=v. The starting point (at t=0) is r0, p0. Result is array of {x,y,z,p,q,v,t}\r
++HMDT MGL_EXPORT mgl_ray_trace(const char *ham, mreal x0, mreal y0, mreal z0, mreal px, mreal py, mreal pz, mreal dt, mreal tmax)\r
++{\r
++ mglFormula eqs(ham);\r
++ mreal in[8]={x0,y0,z0,px,py,pz,0,0};\r
++ HMDT res = mgl_ode_solve(mgl_ray3d,8,in,dt,tmax,&eqs);\r
++ mgl_data_set_id(res,"xyzpqvti");\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++uintptr_t MGL_EXPORT mgl_ray_trace_(const char *ham, mreal *x0, mreal *y0, mreal *z0, mreal *px, mreal *py, mreal *pz, mreal *dt, mreal *tmax,int l)\r
++{ char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0;\r
++ uintptr_t res = uintptr_t(mgl_ray_trace(s, *x0,*y0,*z0, *px,*py,*pz, *dt,*tmax));\r
++ delete []s; return res; }\r
++//-----------------------------------------------------------------------------\r
++struct mgl_ap\r
++{\r
++ double x0,y0,z0,x1,y1,z1,x2,y2,z2; // vectors {l, g1, g2}\r
++ double t1,t2,ch,q1,q2,pt,dt,d1,d2; // theta_{1,2}, chi, q_{1,2}, p_t, dtau, dq_{1,2}\r
++ mgl_ap() { memset(this,0,sizeof(mgl_ap)); }\r
++};\r
++//-----------------------------------------------------------------------------\r
++void MGL_NO_EXPORT mgl_init_ra(long n, int n7, const mreal *r, mgl_ap *ra) // prepare some intermediate data for QO (3d case)\r
++{\r
++ double tt = hypot(r[n7]-r[0], r[n7+1]-r[1]);\r
++ if(tt)\r
++ {\r
++ ra[0].x1 = (r[n7+1]-r[1])/tt;\r
++ ra[0].y1 = (r[0]-r[n7])/tt;\r
++ ra[0].z1 = 0;\r
++ }\r
++ else { ra[0].x1 = ra[0].y1 = 0; ra[0].z1 = 1; }\r
++ ra[0].x0 = r[n7] - r[0]; ra[0].y0 = r[n7+1] - r[1]; ra[0].z0 = r[n7+2] - r[2];\r
++ tt = sqrt(ra[0].x0*ra[0].x0 + ra[0].y0*ra[0].y0 + ra[0].z0*ra[0].z0);\r
++ ra[0].x0 /= tt; ra[0].y0 /= tt; ra[0].z0 /= tt;\r
++ ra[0].x2 = ra[0].y1*ra[0].z0 - ra[0].y0*ra[0].z1; // vector g_2\r
++ ra[0].y2 = ra[0].z1*ra[0].x0 - ra[0].z0*ra[0].x1;\r
++ ra[0].z2 = ra[0].x1*ra[0].y0 - ra[0].x0*ra[0].y1;\r
++ for(long i=1;i<n;i++) // NOTE: no parallel due to dependence on prev point!\r
++ {\r
++ mgl_ap *ri=ra+i, *rp=ra+i-1;\r
++ const mreal *rr = r+n7*i;\r
++ ri->dt = rr[6] - rr[6-n7];\r
++ ri->x0 = rr[0] - rr[-n7]; // NOTE: very rough formulas\r
++ ri->y0 = rr[1] - rr[1-n7]; // for corresponding with dt one\r
++ ri->z0 = rr[2] - rr[2-n7]; // for corresponding with dt one\r
++ double ch = sqrt(ri->x0*ri->x0 + ri->y0*ri->y0 + ri->z0*ri->z0);\r
++ ri->x0 /= ch; ri->y0 /= ch; ri->z0 /= ch;\r
++ ri->ch = ch/ri->dt;\r
++ ri->pt = rr[3]*ri->x0 + rr[4]*ri->y0 + rr[5]*ri->z0;\r
++ ri->q1 = rr[3]*ri->x1 + rr[4]*ri->y1 + rr[5]*ri->z1;\r
++ ri->q2 = rr[3]*ri->x2 + rr[4]*ri->y2 + rr[5]*ri->z2;\r
++ // NOTE previous point is used here!\r
++ tt = ri->x0*rp->x1 + ri->y0*rp->y1 + ri->z0*rp->z1;\r
++ ri->x1 = rp->x1 - tt*ri->x0; // vector g_1\r
++ ri->y1 = rp->y1 - tt*ri->y0;\r
++ ri->z1 = rp->z1 - tt*ri->z0;\r
++ ri->t1 = tt/ch;\r
++ tt = sqrt(ri->x1*ri->x1 + ri->y1*ri->y1 + ri->z1*ri->z1);\r
++ ri->x1 /= tt; ri->y1 /= tt; ri->z1 /= tt; // norm for reducing numeric error\r
++ ri->x2 = ri->y1*ri->z0 - ri->y0*ri->z1; // vector g_2\r
++ ri->y2 = ri->z1*ri->x0 - ri->z0*ri->x1;\r
++ ri->z2 = ri->x1*ri->y0 - ri->x0*ri->y1;\r
++ tt = ri->x0*rp->x2 + ri->y0*rp->y2 + ri->z0*rp->z2;\r
++ ri->t2 = tt/ch;\r
++ ri->d1 = (ri->q1-rp->q1)/ch;\r
++ ri->d2 = (ri->q2-rp->q2)/ch;\r
++ }\r
++ memcpy(ra,ra+1,sizeof(mgl_ap)); // setup zero point\r
++ ra[0].pt = r[3]*ra[0].x0 + r[4]*ra[0].y0 + r[5]*ra[0].z0;\r
++ ra[0].q1 = r[3]*ra[0].x1 + r[4]*ra[0].y1 + r[5]*ra[0].z1;\r
++ ra[0].q2 = r[3]*ra[0].x2 + r[4]*ra[0].y2 + r[5]*ra[0].z2;\r
++}\r
++//-----------------------------------------------------------------------------\r
++//\r
++// QO2d series\r
++//\r
++//-----------------------------------------------------------------------------\r
++struct mgl_qo2d_ham\r
++{\r
++ ddual *hx, *hu, *a, h0;\r
++ double *dmp, dr, dk;\r
++ mreal *r;\r
++ mgl_ap *ra;\r
++ ddual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par);\r
++ void *par;\r
++};\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_qo2d_hprep(void *par)\r
++{\r
++ mglThreadD *t=(mglThreadD *)par;\r
++ mgl_qo2d_ham *f = (mgl_qo2d_ham *)t->v;\r
++ mgl_ap *ra = f->ra;\r
++\r
++ const mreal *r = f->r;\r
++ const long nx=t->n;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=t->id;i<nx;i+=mglNumThr)\r
++ {\r
++ // x terms\r
++ mreal x1 = (2*i-nx+1)*f->dr, hh = 1 - ra->t1*x1;\r
++ hh = sqrt(sqrt(0.041+hh*hh*hh*hh));\r
++ mreal tt = (ra->pt + ra->d1*x1)/hh - ra->pt;\r
++ f->hx[i] = f->ham(abs(f->a[i]), r[0]+ra->x1*x1, r[1]+ra->y1*x1, r[3]+ra->x0*tt, r[4]+ra->y0*tt, f->par) - f->h0/2.;\r
++ // u-y terms\r
++ x1 = f->dk/2*(i<nx/2 ? i:i-nx);\r
++ f->hu[i] = f->ham(0, r[0], r[1], r[3]+ra->x1*x1, r[4]+ra->y1*x1, f->par) - f->h0/2.;\r
++\r
++ if(imag(f->hx[i])>0) f->hx[i] = f->hx[i].real();\r
++ if(imag(f->hu[i])>0) f->hu[i] = f->hu[i].real();\r
++ // add boundary conditions for x-direction\r
++ f->hx[i] -= dual(0,f->dmp[i]);\r
++ }\r
++ return 0;\r
++}\r
++//-----------------------------------------------------------------------------\r
++HADT MGL_EXPORT mgl_qo2d_func_c(ddual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy)\r
++{\r
++ const mglData *ray=dynamic_cast<const mglData *>(ray_dat); // NOTE: Ray must be mglData!\r
++ if(!ray) return 0;\r
++ const long nx=ini_re->GetNx(), nt=ray->ny, n7=ray->nx;\r
++ if(nx<2 || ini_im->GetNx()!=nx || nt<2) return 0;\r
++ mglDataC *res=new mglDataC(nx,nt,1);\r
++\r
++ ddual *a=new ddual[2*nx], *hu=new ddual[2*nx], *hx=new ddual[2*nx];\r
++ double *dmp=new double[2*nx];\r
++ mgl_ap *ra = new mgl_ap[nt]; mgl_init_ra(nt, n7, ray->a, ra); // ray\r
++\r
++ mreal dr = r/(nx-1), dk = M_PI*(nx-1)/(k0*r*nx);\r
++ memset(dmp,0,2*nx*sizeof(double));\r
++ for(long i=0;i<nx/2;i++) // prepare damping\r
++ {\r
++ mreal x1 = (nx/2-i)/(nx/2.);\r
++ dmp[2*nx-1-i] = dmp[i] = 30*GAMMA*x1*x1/k0;\r
++ }\r
++ for(long i=0;i<nx;i++) a[i+nx/2] = dual(ini_re->v(i),ini_im->v(i)); // init\r
++ void *wsx, *wtx = mgl_fft_alloc(2*nx,&wsx,1);\r
++ if(xx && yy) { xx->Create(nx,nt); yy->Create(nx,nt); }\r
++\r
++ mgl_qo2d_ham tmp; // parameters for Hamiltonian calculation\r
++ tmp.hx=hx; tmp.hu=hu; tmp.dmp=dmp; tmp.par=par;\r
++ tmp.dr=dr; tmp.dk=dk; tmp.ham=ham; tmp.a=a;\r
++ // start calculation\r
++ for(long k=0;k<nt;k++)\r
++ {\r
++ for(long i=0;i<nx;i++) // "save"\r
++ res->a[i+k*nx]=a[i+nx/2]*sqrt(ra[0].ch/ra[k].ch);\r
++ if(xx && yy) for(long i=0;i<nx;i++) // prepare xx, yy\r
++ {\r
++ mreal x1 = (2*i-nx+1)*dr;\r
++ xx->a[i+k*nx] = ray->a[n7*k] + ra[k].x1*x1; // new coordinates\r
++ yy->a[i+k*nx] = ray->a[n7*k+1] + ra[k].y1*x1;\r
++ }\r
++ tmp.r=ray->a+n7*k; tmp.ra=ra+k;\r
++ mreal hh = ra[k].pt*(1/sqrt(sqrt(1.041))-1); // 0.041=0.45^4 -- minimal value of h\r
++ tmp.h0 = ham(0, tmp.r[0], tmp.r[1], tmp.r[3]+ra[k].x0*hh, tmp.r[4]+ra[k].x0*hh, par);\r
++ mglStartThread(mgl_qo2d_hprep,0,2*nx,0,0,0,0,&tmp);\r
++ // Step for field\r
++ ddual dt = ddual(0, -ra[k].dt*k0);\r
++ for(long i=0;i<2*nx;i++) a[i] *= exp(hx[i]*dt);\r
++ mgl_fft((double *)a, 1, 2*nx, wtx, wsx, false);\r
++ for(long i=0;i<2*nx;i++) a[i] *= exp(hu[i]*dt);\r
++ mgl_fft((double *)a, 1, 2*nx, wtx, wsx, true);\r
++\r
++/* // Calculate B1 // TODO make more general scheme later!!!\r
++ hh = ra[k].pt*(1/sqrt(sqrt(1.041))-1);\r
++ var['x'-'a'] = ray->a[n7*k]; // new coordiantes\r
++ var['y'-'a'] = ray->a[n7*k+1];\r
++ var['p'-'a'] = ray->a[n7*k+3] + ra[k].x0*hh; // new momentums\r
++ var['q'-'a'] = ray->a[n7*k+4] + ra[k].y0*hh;\r
++ tt = h.CalcD(var,'p')*ra[k].x1 + h.CalcD(var,'q')*ra[k].y1;\r
++ var['x'-'a'] = ray->a[n7*k] + ra[k].x1*dr; // new coordiantes\r
++ var['y'-'a'] = ray->a[n7*k+1] + ra[k].y1*dr;\r
++ hh = 1 - ra[k].t1*dr; hh = sqrt(sqrt(0.041+hh*hh*hh*hh));\r
++ hh = (ra[k].ch*ra[k].pt + ra[k].d1*dr)/(hh*ra[k].ch) - ra[k].pt;\r
++ var['p'-'a'] = ray->a[n7*k+3] + ra[k].x0*hh; // new momentums\r
++ var['q'-'a'] = ray->a[n7*k+4] + ra[k].y0*hh;\r
++ B1 = h.CalcD(var,'p')*ra[k].x1 + h.CalcD(var,'q')*ra[k].y1;\r
++ B1 = (B1-tt)/dr;\r
++ double a1=0, a2=0;\r
++ for(i=0;i<2*nx;i++) a1 += norm(a[i]);\r
++ hx[0] = hx[2*nx-1] = 0.;\r
++ for(i=1;i<2*nx-1;i++) hx[i] = (B1*ra[k].dt*(i-nx))*(a[i+1]-a[i-1]);\r
++ for(i=0;i<2*nx;i++) { a[i] += hx[i]; a2 += norm(a[i]); }\r
++ a1 = sqrt(a1/a2);\r
++ for(i=0;i<2*nx;i++) a[i] *= a1;*/\r
++ }\r
++ mgl_fft_free(wtx,&wsx,1);\r
++ delete []a; delete []hu; delete []hx; delete []ra; delete []dmp;\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++HMDT MGL_EXPORT mgl_qo2d_func(ddual (*ham)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy)\r
++{\r
++ HADT res = mgl_qo2d_func_c(ham,par,ini_re,ini_im,ray_dat,r,k0,xx,yy);\r
++ HMDT out = mgl_datac_abs(res); delete res; return out;\r
++}\r
++//-----------------------------------------------------------------------------\r
++ddual MGL_NO_EXPORT mgl_ham2d(mreal u, mreal x, mreal y, mreal px, mreal py, void *par)\r
++{\r
++ mglFormula *h = (mglFormula *)par;\r
++ mreal var[MGL_VS]; memset(var,0,MGL_VS*sizeof(mreal));\r
++ var['x'-'a'] = x; var['y'-'a'] = y; var['u'-'a'] = u;\r
++ var['p'-'a'] = px; var['q'-'a'] = py;\r
++ return ddual(h->Calc(var), -h->CalcD(var,'i'));\r
++}\r
++//-----------------------------------------------------------------------------\r
++HADT MGL_EXPORT mgl_qo2d_solve_c(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy)\r
++{\r
++ mglFormula h(ham);\r
++ return mgl_qo2d_func_c(mgl_ham2d, &h, ini_re, ini_im, ray_dat, r, k0, xx, yy);\r
++}\r
++//-----------------------------------------------------------------------------\r
++HMDT MGL_EXPORT mgl_qo2d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy)\r
++{\r
++ HADT res = mgl_qo2d_solve_c(ham,ini_re,ini_im,ray_dat,r,k0,xx,yy);\r
++ HMDT out = mgl_datac_abs(res); delete res; return out;\r
++}\r
++//-----------------------------------------------------------------------------\r
++uintptr_t MGL_EXPORT mgl_qo2d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, int l)\r
++{ char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0;\r
++ uintptr_t res = uintptr_t(mgl_qo2d_solve(s, _DA_(ini_re), _DA_(ini_im), _DA_(ray), *r, *k0, _DM_(xx), _DM_(yy)));\r
++ delete []s; return res; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// QO3d series\r
++//\r
++//-----------------------------------------------------------------------------\r
++struct mgl_qo3d_ham\r
++{\r
++ ddual *hxy, *huv, *hxv, *huy, *a;\r
++ ddual *hx, *hy, *hu, *hv, h0;\r
++ double *dmp, dr, dk;\r
++ mreal *r;\r
++ mgl_ap *ra;\r
++ ddual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par);\r
++ void *par;\r
++};\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_qo3d_hprep(void *par)\r
++{\r
++ mglThreadD *t=(mglThreadD *)par;\r
++ mgl_qo3d_ham *f = (mgl_qo3d_ham *)t->v;\r
++ mgl_ap *ra = f->ra;\r
++ const mreal *r = f->r;\r
++ const long nx=t->n;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long ii=t->id;ii<nx*nx;ii+=mglNumThr)\r
++ {\r
++ long i = ii%nx, j = ii/nx;\r
++ // x-y terms\r
++ mreal x1 = (2*i-nx+1)*f->dr, x2 = (2*j-nx+1)*f->dr, hh = 1-ra->t1*x1-ra->t2*x2;\r
++ hh = sqrt(sqrt(0.041+hh*hh*hh*hh));\r
++ mreal tt = (ra->pt + ra->d1*x1 + ra->d2*x2)/hh - ra->pt;\r
++ f->hxy[ii] = f->ham(abs(f->a[i]), r[0]+ra->x1*x1+ra->x2*x2, r[1]+ra->y1*x1+ra->y2*x2, r[2]+ra->z1*x1+ra->z2*x2, r[3]+ra->x0*tt, r[4]+ra->y0*tt, r[5]+ra->z0*tt, f->par);\r
++ // x-v terms\r
++ x1 = (2*i-nx+1)*f->dr; x2 = f->dk/2*(j<nx/2 ? j:j-nx); hh = 1-ra->t1*x1;\r
++ hh = sqrt(sqrt(0.041+hh*hh*hh*hh));\r
++ tt = (ra->pt + ra->d1*x1)/hh - ra->pt;\r
++ f->hxv[ii] = f->ham(0, r[0]+ra->x1*x1, r[1]+ra->y1*x1, r[2]+ra->z1*x1, r[3]+ra->x0*tt+ra->x2*x2, r[4]+ra->y0*tt+ra->y2*x2, r[5]+ra->z0*tt+ra->z2*x2, f->par);\r
++ // u-y terms\r
++ x1 = f->dk/2*(i<nx/2 ? i:i-nx); x2 = (2*j-nx+1)*f->dr; hh = 1-ra->t2*x2;\r
++ hh = sqrt(sqrt(0.041+hh*hh*hh*hh));\r
++ tt = (ra->pt + ra->d2*x2)/hh - ra->pt;\r
++ f->huy[ii] = f->ham(0, r[0]+ra->x2*x2, r[1]+ra->y2*x2, r[2]+ra->z2*x2, r[3]+ra->x1*x1+ra->x0*tt, r[4]+ra->y1*x1+ra->y0*tt, r[5]+ra->z1*x1+ra->z0*tt, f->par);\r
++ // u-y terms\r
++ x1 = f->dk/2*(i<nx/2 ? i:i-nx); x2 = f->dk/2*(j<nx/2 ? j:j-nx);\r
++ f->huv[ii] = f->ham(0, r[0], r[1], r[2], r[3]+ra->x1*x1+ra->x2*x2, r[4]+ra->y1*x1+ra->y2*x2, r[5]+ra->z1*x1+ra->z2*x2, f->par);\r
++ }\r
++ return 0;\r
++}\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_qo3d_post(void *par)\r
++{\r
++ mglThreadD *t=(mglThreadD *)par;\r
++ mgl_qo3d_ham *f = (mgl_qo3d_ham *)t->v;\r
++ const long nx=t->n;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long ii=t->id;ii<nx*nx;ii+=mglNumThr)\r
++ {\r
++ long i = ii%nx, j = ii/nx;\r
++ f->hxy[ii] -= (f->hx[i]+f->hy[j]-f->h0/2.)/2.;\r
++ if(imag(f->hxy[ii])>0) f->hxy[ii] = f->hxy[ii].real();\r
++ f->hxv[ii] -= (f->hx[i]+f->hv[j]-f->h0/2.)/2.;\r
++ if(imag(f->hxv[ii])>0) f->hxv[ii] = f->hxv[ii].real();\r
++ f->huy[ii] -= (f->hu[i]+f->hy[j]-f->h0/2.)/2.;\r
++ if(imag(f->huy[ii])>0) f->huy[ii] = f->huy[ii].real();\r
++ f->huv[ii] -= (f->hu[i]+f->hv[j]-f->h0/2.)/2.;\r
++ if(imag(f->huv[ii])>0) f->huv[ii] = f->huv[ii].real();\r
++ // add boundary conditions for x-direction\r
++ f->hxy[ii] -= dual(0,f->dmp[ii]);\r
++ }\r
++ return 0;\r
++}\r
++//-----------------------------------------------------------------------------\r
++HADT MGL_EXPORT mgl_qo3d_func_c(ddual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz)\r
++{\r
++ const mglData *ray=dynamic_cast<const mglData *>(ray_dat); // NOTE: Ray must be mglData!\r
++ if(!ray) return 0;\r
++ const long nx=ini_re->GetNx(), nt=ray->ny, n7=ray->nx; // NOTE: only square grids are supported now (for simplicity)\r
++ if(nx<2 || ini_re->GetNx()!=nx || ini_im->GetNx()*ini_im->GetNy()!=nx*nx || nt<2) return 0;\r
++ mglDataC *res=new mglDataC(nx,nx,nt);\r
++\r
++ ddual *a=new ddual[4*nx*nx], *huv=new ddual[4*nx*nx], *hxy=new ddual[4*nx*nx], *huy=new ddual[4*nx*nx], *hxv=new ddual[4*nx*nx];\r
++ ddual *hu=new ddual[2*nx], *hx=new ddual[2*nx], *hy=new ddual[2*nx], *hv=new ddual[2*nx];\r
++ double *dmp=new double[4*nx*nx];\r
++ mgl_ap *ra = new mgl_ap[nt];\r
++ mgl_init_ra(nt, n7, ray->a, ra); // prepare ray\r
++\r
++ double dr = r/(nx-1), dk = M_PI*(nx-1)/(k0*r*nx);\r
++ memset(dmp,0,4*nx*nx*sizeof(double));\r
++#pragma omp parallel for collapse(2)\r
++ for(long i=0;i<nx/2;i++) for(long j=0;j<nx/2;j++) // prepare damping\r
++ {\r
++ double x1 = (nx/2-i)/(nx/2.), x2 = (nx/2-j)/(nx/2.);\r
++ dmp[2*nx-1-i] = dmp[i] = 30*GAMMA*x1*x1/k0;\r
++ dmp[(2*nx-1-j)*2*nx] += 30*GAMMA*x2*x2/k0;\r
++ dmp[j*2*nx] += 30*GAMMA*x2*x2/k0;\r
++ }\r
++#pragma omp parallel for collapse(2)\r
++ for(long i=0;i<nx;i++) for(long j=0;j<nx;j++) // init\r
++ a[i+nx/2+2*nx*(j+nx/2)] = dual(ini_re->v(i,j),ini_im->v(i,j));\r
++ void *wtx = mgl_fft_alloc(2*nx,0,0);\r
++ if(xx && yy && zz) { xx->Create(nx,nx,nt); yy->Create(nx,nx,nt); zz->Create(nx,nx,nt); }\r
++\r
++ mgl_qo3d_ham tmp; // parameters for Hamiltonian calculation\r
++ tmp.hxy=hxy; tmp.hx=hx; tmp.huv=huv; tmp.hu=hu;\r
++ tmp.huy=huy; tmp.hy=hy; tmp.hxv=hxv; tmp.hv=hv;\r
++ tmp.dmp=dmp; tmp.par=par;\r
++ tmp.dr=dr; tmp.dk=dk; tmp.ham=ham; tmp.a=a;\r
++ // start calculation\r
++ for(long k=0;k<nt;k++)\r
++ {\r
++#pragma omp parallel for collapse(2)\r
++ for(long i=0;i<nx;i++) for(long j=0;j<nx;j++) // "save"\r
++ res->a[i+nx*(j+k*nx)]=a[i+nx/2+2*nx*(j+nx/2)]*sqrt(ra[0].ch/ra[k].ch);\r
++ if(xx && yy && zz)\r
++#pragma omp parallel for collapse(2)\r
++ for(long i=0;i<nx;i++) for(long j=0;j<nx;j++) // prepare xx, yy, zz\r
++ {\r
++ mreal x1 = (2*i-nx+1)*dr, x2 = (2*j-nx+1)*dr;\r
++ xx->a[i+nx*(j+k*nx)] = ray->a[n7*k] + ra[k].x1*x1 + ra[k].x2*x2; // new coordinates\r
++ yy->a[i+nx*(j+k*nx)] = ray->a[n7*k+1] + ra[k].y1*x1 + ra[k].y2*x2;\r
++ zz->a[i+nx*(j+k*nx)] = ray->a[n7*k+2] + ra[k].z1*x1 + ra[k].z2*x2;\r
++ }\r
++ tmp.r=ray->a+n7*k; tmp.ra=ra+k;\r
++ mglStartThread(mgl_qo3d_hprep,0,2*nx,0,0,0,0,&tmp); tmp.h0 = huv[0];\r
++ for(long i=0;i<2*nx;i++) // fill intermediate arrays\r
++ {\r
++ tmp.hx[i] = hxv[i]; tmp.hy[i] = huy[i*2*nx];\r
++ tmp.hv[i] = huv[i]; tmp.hu[i] = huv[i*2*nx];\r
++ }\r
++ mglStartThread(mgl_qo3d_post,0,2*nx,0,0,0,0,&tmp);\r
++ // Step for field\r
++ ddual dt = ddual(0, -ra[k].dt*k0);\r
++#pragma omp parallel\r
++ {\r
++ void *wsx = mgl_fft_alloc_thr(2*nx);\r
++#pragma omp for\r
++ for(long i=0;i<4*nx*nx;i++) a[i] *= exp(hxy[i]*dt); // x-y\r
++#pragma omp for\r
++ for(long i=0;i<2*nx;i++) // x->u\r
++ mgl_fft((double *)(a+i*2*nx), 1, 2*nx, wtx, wsx, false);\r
++#pragma omp for\r
++ for(long i=0;i<4*nx*nx;i++) a[i] *= exp(huy[i]*dt); // u-y\r
++#pragma omp for\r
++ for(long i=0;i<2*nx;i++) // y->v\r
++ mgl_fft((double *)(a+i), 2*nx, 2*nx, wtx, wsx, false);\r
++#pragma omp for\r
++ for(long i=0;i<4*nx*nx;i++) a[i] *= exp(huv[i]*dt); // u-v\r
++#pragma omp for\r
++ for(long i=0;i<2*nx;i++) // u->x\r
++ mgl_fft((double *)(a+i*2*nx), 1, 2*nx, wtx, wsx, true);\r
++#pragma omp for\r
++ for(long i=0;i<4*nx*nx;i++) a[i] *= exp(hxv[i]*dt); // x-v\r
++#pragma omp for\r
++ for(long i=0;i<2*nx;i++) // v->y\r
++ mgl_fft((double *)(a+i), 2*nx, 2*nx, wtx, wsx, true);\r
++ mgl_fft_free_thr(wsx);\r
++ }\r
++\r
++/* // Calculate B1 // TODO make more general scheme later!!!\r
++ hh = ra[k].pt*(1/sqrt(sqrt(1.041))-1);\r
++ var['x'-'a'] = ray->a[n7*k]; // new coordiantes\r
++ var['y'-'a'] = ray->a[n7*k+1];\r
++ var['p'-'a'] = ray->a[n7*k+3] + ra[k].x0*hh; // new momentums\r
++ var['q'-'a'] = ray->a[n7*k+4] + ra[k].y0*hh;\r
++ tt = h.CalcD(var,'p')*ra[k].x1 + h.CalcD(var,'q')*ra[k].y1;\r
++ var['x'-'a'] = ray->a[n7*k] + ra[k].x1*dr; // new coordiantes\r
++ var['y'-'a'] = ray->a[n7*k+1] + ra[k].y1*dr;\r
++ hh = 1 - ra[k].t1*dr; hh = sqrt(sqrt(0.041+hh*hh*hh*hh));\r
++ hh = (ra[k].ch*ra[k].pt + ra[k].d1*dr)/(hh*ra[k].ch) - ra[k].pt;\r
++ var['p'-'a'] = ray->a[n7*k+3] + ra[k].x0*hh; // new momentums\r
++ var['q'-'a'] = ray->a[n7*k+4] + ra[k].y0*hh;\r
++ B1 = h.CalcD(var,'p')*ra[k].x1 + h.CalcD(var,'q')*ra[k].y1;\r
++ B1 = (B1-tt)/dr;\r
++ double a1=0, a2=0;\r
++ for(i=0;i<2*nx;i++) a1 += norm(a[i]);\r
++ hx[0] = hx[2*nx-1] = 0.;\r
++ for(i=1;i<2*nx-1;i++) hx[i] = (B1*ra[k].dt*(i-nx))*(a[i+1]-a[i-1]);\r
++ for(i=0;i<2*nx;i++) { a[i] += hx[i]; a2 += norm(a[i]); }\r
++ a1 = sqrt(a1/a2);\r
++ for(i=0;i<2*nx;i++) a[i] *= a1;*/\r
++ }\r
++ mgl_fft_free(wtx,0,0);\r
++ delete []a; delete []ra; delete []dmp;\r
++ delete []huv; delete []hxy; delete []hxv; delete []huy;\r
++ delete []hu; delete []hx; delete []hv; delete []hy;\r
++ return res;\r
++}\r
++//-----------------------------------------------------------------------------\r
++HMDT MGL_EXPORT mgl_qo3d_func(ddual (*ham)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par), void *par, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz)\r
++{\r
++ HADT res = mgl_qo3d_func_c(ham,par,ini_re,ini_im,ray_dat,r,k0,xx,yy,zz);\r
++ HMDT out = mgl_datac_abs(res); delete res; return out;\r
++}\r
++//-----------------------------------------------------------------------------\r
++ddual MGL_NO_EXPORT mgl_ham3d(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par)\r
++{\r
++ mglFormula *h = (mglFormula *)par;\r
++ mreal var[MGL_VS]; memset(var,0,MGL_VS*sizeof(mreal));\r
++ var['x'-'a'] = x; var['y'-'a'] = y; var['z'-'a'] = z; var['u'-'a'] = u;\r
++ var['p'-'a'] = px; var['q'-'a'] = py; var['v'-'a'] = pz;\r
++ return ddual(h->Calc(var), -h->CalcD(var,'i'));\r
++}\r
++//-----------------------------------------------------------------------------\r
++HADT MGL_EXPORT mgl_qo3d_solve_c(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz)\r
++{\r
++ mglFormula h(ham);\r
++ return mgl_qo3d_func_c(mgl_ham3d, &h, ini_re, ini_im, ray_dat, r, k0, xx, yy, zz);\r
++}\r
++//-----------------------------------------------------------------------------\r
++HMDT MGL_EXPORT mgl_qo3d_solve(const char *ham, HCDT ini_re, HCDT ini_im, HCDT ray_dat, mreal r, mreal k0, HMDT xx, HMDT yy, HMDT zz)\r
++{\r
++ HADT res = mgl_qo3d_solve_c(ham,ini_re,ini_im,ray_dat,r,k0,xx,yy,zz);\r
++ HMDT out = mgl_datac_abs(res); delete res; return out;\r
++}\r
++//-----------------------------------------------------------------------------\r
++uintptr_t MGL_EXPORT mgl_qo3d_solve_(const char *ham, uintptr_t* ini_re, uintptr_t* ini_im, uintptr_t* ray, mreal *r, mreal *k0, uintptr_t* xx, uintptr_t* yy, uintptr_t* zz, int l)\r
++{ char *s=new char[l+1]; memcpy(s,ham,l); s[l]=0;\r
++ uintptr_t res = uintptr_t(mgl_qo3d_solve(s, _DA_(ini_re), _DA_(ini_im), _DA_(ray), *r, *k0, _DM_(xx), _DM_(yy), _DM_(zz)));\r
++ delete []s; return res; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// mglJacobian series\r
++//\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_jacob2(void *par)\r
++{\r
++ mglThreadD *t=(mglThreadD *)par;\r
++ const long nx=t->p[0], ny=t->p[1];\r
++ mreal *r=t->a;\r
++ const mreal *x=t->b, *y=t->c;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i0=t->id;i0<t->n;i0+=mglNumThr)\r
++ {\r
++ long i=i0%nx, j=i0/nx;\r
++ long ip = i<nx-1 ? 1:0, jp = j<ny-1 ? nx:0;\r
++ long im = i>0 ? -1:0, jm = j>0 ? -nx:0;\r
++ r[i0] = (x[i0+ip]-x[i0+im])*(y[i0+jp]-y[i0+jm]) -\r
++ (y[i0+ip]-y[i0+im])*(x[i0+jp]-x[i0+jm]);\r
++ r[i0] *= mreal((nx-1)*(ny-1)) / mreal((ip-im)*(jp-jm));\r
++ }\r
++ return 0;\r
++}\r
++HMDT MGL_EXPORT mgl_jacobian_2d(HCDT x, HCDT y)\r
++{\r
++ const long nx = x->GetNx(), ny=x->GetNy();\r
++ if(nx!=y->GetNx() || ny!=y->GetNy() || nx<2 || ny<2) return 0;\r
++ mglData *r=new mglData(nx,ny,1);\r
++ const mglData *xx=dynamic_cast<const mglData *>(x);\r
++ const mglData *yy=dynamic_cast<const mglData *>(y);\r
++ if(xx && yy)\r
++ {\r
++ long p[2]={nx,ny};\r
++ mglStartThread(mgl_jacob2,0,nx*ny,r->a,xx->a,yy->a,p);\r
++ }\r
++ else // slow variant\r
++ {\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ long im = i>0 ? i-1:i, ip = i<nx-1 ? i+1:i;\r
++ long jm = j>0 ? j-1:j, jp = j<ny-1 ? j+1:j;\r
++ r->a[i+nx*j] = (x->v(ip,j)-x->v(im,j))*(y->v(i,jp)-y->v(i,jm)) -\r
++ (y->v(ip,j)-y->v(im,j))*(x->v(i,jp)-x->v(i,jm));\r
++ r->a[i+nx*j] *= mreal((nx-1)*(ny-1)) / mreal((ip-im)*(jp-jm));\r
++ }\r
++ }\r
++ return r;\r
++}\r
++//-----------------------------------------------------------------------------\r
++MGL_NO_EXPORT void *mgl_jacob3(void *par)\r
++{\r
++ mglThreadD *t=(mglThreadD *)par;\r
++ const long nx=t->p[0], ny=t->p[1], nz=t->p[2];\r
++ mreal *r=t->a;\r
++ const mreal *x=t->b, *y=t->c, *z=t->d;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i0=t->id;i0<t->n;i0+=mglNumThr)\r
++ {\r
++ long i=i0%nx, j=(i0/nx)%ny, k=i0/(nx*ny);\r
++ long ip = i<nx-1 ? 1:0, jp = j<ny-1 ? nx:0, kp = k<nz-1 ? nx*ny:0;\r
++ long im = i>0 ? -1:0, jm = j>0 ? -nx:0, km = k>0 ? -nx*ny:0;\r
++ r[i0] = (x[i0+ip]-x[i0+im])*(y[i0+jp]-y[i0+jm])*(z[i0+kp]-z[i0+km]) -\r
++ (x[i0+ip]-x[i0+im])*(y[i0+kp]-y[i0+km])*(z[i0+jp]-z[i0+jm]) -\r
++ (x[i0+jp]-x[i0+jm])*(y[i0+ip]-y[i0+im])*(z[i0+kp]-z[i0+km]) +\r
++ (x[i0+jp]-x[i0+jm])*(y[i0+kp]-y[i0+km])*(z[i0+ip]-z[i0+im]) +\r
++ (x[i0+kp]-x[i0+km])*(y[i0+ip]-y[i0+im])*(z[i0+jp]-z[i0+jm]) -\r
++ (x[i0+kp]-x[i0+km])*(y[i0+jp]-y[i0+jm])*(z[i0+ip]-z[i0+im]);\r
++ r[i0] *= mreal((nx-1)*(ny-1)*(nz-1)) / mreal((ip-im)*(jp-jm)*(kp-km));\r
++ }\r
++ return 0;\r
++}\r
++HMDT MGL_EXPORT mgl_jacobian_3d(HCDT x, HCDT y, HCDT z)\r
++{\r
++ const long nx = x->GetNx(), ny=x->GetNy(), nz=x->GetNz(), nn = nx*ny*nz;\r
++ if(nx<2 || ny<2 || nz<2) return 0;\r
++ if(nn!=y->GetNN() || nn!=z->GetNN()) return 0;\r
++ mglData *r=new mglData(nx,ny,nz);\r
++ const mglData *xx=dynamic_cast<const mglData *>(x);\r
++ const mglData *yy=dynamic_cast<const mglData *>(y);\r
++ const mglData *zz=dynamic_cast<const mglData *>(z);\r
++ if(xx && yy && zz)\r
++ {\r
++ long p[3]={nx,ny,nz};\r
++ mglStartThread(mgl_jacob3,0,nx*ny*nz,r->a,xx->a,yy->a,p,0,zz->a);\r
++ }\r
++ else // slow variant\r
++ {\r
++#pragma omp parallel for collapse(3)\r
++ for(long k=0;k<nz;k++) for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ long im = i>0 ? i-1:i, ip = i<nx-1 ? i+1:i;\r
++ long jm = j>0 ? j-1:j, jp = j<ny-1 ? j+1:j;\r
++ long km = k>0 ? k-1:k, kp = k<nz-1 ? k+1:k;\r
++ long i0 = i+nx*(j+ny*k);\r
++ r->a[i0] = (x->v(ip,j,k)-x->v(im,j,k))*(y->v(i,jp,k)-y->v(i,jm,k))*(z->v(i,j,kp)-z->v(i,j,km)) -\r
++ (x->v(ip,j,k)-x->v(im,j,k))*(y->v(i,j,kp)-y->v(i,j,km))*(z->v(i,jp,k)-z->v(i,jm,k)) -\r
++ (x->v(i,jp,k)-x->v(i,jm,k))*(y->v(ip,j,k)-y->v(im,j,k))*(z->v(i,j,kp)-z->v(i,j,km)) +\r
++ (x->v(i,jp,k)-x->v(i,jm,k))*(y->v(i,j,kp)-y->v(i,j,km))*(z->v(ip,j,k)-z->v(im,j,k)) +\r
++ (x->v(i,j,kp)-x->v(i,j,km))*(y->v(ip,j,k)-y->v(im,j,k))*(z->v(i,jp,k)-z->v(i,jm,k)) -\r
++ (x->v(i,j,kp)-x->v(i,j,km))*(y->v(i,jp,k)-y->v(i,jm,k))*(z->v(ip,j,k)-z->v(im,j,k));\r
++ r->a[i0] *= mreal((nx-1)*(ny-1)*(nz-1)) / mreal((ip-im)*(jp-jm)*(kp-km));\r
++ }\r
++\r
++ }\r
++ return r;\r
++}\r
++//-----------------------------------------------------------------------------\r
++uintptr_t MGL_EXPORT mgl_jacobian_2d_(uintptr_t* x, uintptr_t* y)\r
++{ return uintptr_t(mgl_jacobian_2d(_DA_(x), _DA_(y))); }\r
++uintptr_t MGL_EXPORT mgl_jacobian_3d_(uintptr_t* x, uintptr_t* y, uintptr_t* z)\r
++{ return uintptr_t(mgl_jacobian_3d(_DA_(x), _DA_(y), _DA_(z))); }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Progonka\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_NO_EXPORT mgl_progonka_sr(HCDT A, HCDT B, HCDT C, HCDT D, mreal *dat, long n, long id, long i0, long di, bool difr)\r
++{\r
++ mreal *aa=dat, *bb=dat+n, *uu=dat+2*n;\r
++ mreal b0=B->vthr(i0), c0=C->vthr(i0), d0=D->vthr(id);\r
++ if(difr) d0 = (2.-b0)*d0-c0*D->vthr(id+di);\r
++ aa[0] = -c0/b0; bb[0] = d0/b0;\r
++ for(long i=1;i<n;i++)\r
++ {\r
++<<<<<<< HEAD\r
++ register long ii=i0+di*i, dd=id+di*i, tt = id+di*((i+1)%n);\r
++=======\r
++ long ii=i0+di*i, dd=id+di*i, tt = id+di*((i+1)%n);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ mreal a=A->vthr(ii), b=B->vthr(ii), c=C->vthr(ii);\r
++ mreal d=difr?-a*D->vthr(dd-di)+(2.-b)*D->vthr(dd)-c*D->vthr(tt):D->vthr(dd);\r
++ aa[i] = -c/(b+a*aa[i-1]);\r
++ bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]);\r
++ }\r
++ uu[n-1] = bb[n-1];\r
++ for(long i=n-2;i>=0;i--) uu[i] = bb[i]+aa[i]*uu[i+1];\r
++}\r
++void MGL_NO_EXPORT mgl_progonka_pr(HCDT A, HCDT B, HCDT C, HCDT D, mreal *dat, long n, long id, long i0, long di, bool difr)\r
++{\r
++ mreal *aa=dat, *bb=dat+n, *gg=dat+2*n, *uu=dat+3*n;\r
++ mreal a0=A->vthr(i0), b0=B->vthr(i0), c0=C->vthr(i0), d0=D->vthr(id);\r
++ if(difr) d0 = -a0*D->vthr(id+di*(n-1))+(2.-b0)*d0-c0*D->vthr(id+di);\r
++ aa[0] =-c0/b0; bb[0] = d0/b0; gg[0] =-a0/b0;\r
++ for(long i=1;i<n;i++)\r
++ {\r
++<<<<<<< HEAD\r
++ register long ii=i0+di*i, il=id+di*((i+1)%n), dd=id+di*i;\r
++=======\r
++ long ii=i0+di*i, il=id+di*((i+1)%n), dd=id+di*i;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ mreal a=A->vthr(ii), b=B->vthr(ii), c=C->vthr(ii);\r
++ mreal d=difr?-a*D->vthr(dd-di)+(2.-b)*D->vthr(dd)-c*D->vthr(il):D->vthr(dd);\r
++ aa[i] = -c/(b+a*aa[i-1]);\r
++ bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]);\r
++ gg[i] = -a*gg[i-1]/(b+a*aa[i-1]);\r
++ }\r
++ mreal P=bb[n-1]/(1.-gg[n-1]), Q=aa[n-1]/(1.-gg[n-1]);\r
++ aa[n-1] = Q; bb[n-1] = P;\r
++ for(long i=n-2;i>=0;i--)\r
++ {\r
++ bb[i] += aa[i]*bb[i+1]+gg[i]*P;\r
++ aa[i] = aa[i]*aa[i+1]+gg[i]*Q;\r
++ }\r
++ mreal u0 = bb[0]/(1.-aa[0]);\r
++ for(long i=0;i<n;i++) uu[i]=bb[i]+aa[i]*u0;\r
++}\r
++void MGL_NO_EXPORT mgl_progonka_hr(HCDT A, HCDT B, HCDT C, HCDT D, mreal *dat, long n, long id, long i0, bool difr)\r
++{\r
++ mreal *aa=dat, *bb=dat+n, *uu=dat+n*n;\r
++ mreal b0=B->vthr(i0), c0=C->vthr(i0), d0=D->vthr(id);\r
++ uu[0] = d0/b0*(difr?(2.-b0):1.);\r
++ b0=B->vthr(i0+n*n-1); d0=D->vthr(id+n*n-1);\r
++ uu[n*n-1] = d0/b0*(difr?(2.-b0):1.);\r
++ long di = n-1, i1 = i0+n*(n-1), d1 = id+n*(n-1);\r
++ // suppose the square grid!\r
++ for(long j=1;j<n;j++)\r
++ {\r
++ // first bottom-left triangle\r
++ b0=B->vthr(i0+j); c0=C->vthr(i0+j); d0=D->vthr(id+j);\r
++ if(difr) d0 = (2.-b0)*d0-c0*D->vthr(id+j+di);\r
++ aa[0] = -c0/b0; bb[0] = d0/b0;\r
++ for(long i=1;i<=j;i++)\r
++ {\r
++<<<<<<< HEAD\r
++ register long ii=i0+j+di*i, dd=id+j+di*i;\r
++=======\r
++ long ii=i0+j+di*i, dd=id+j+di*i;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ mreal a=A->vthr(ii),b=B->vthr(ii),c=C->vthr(ii);\r
++ mreal d=difr?-a*D->vthr(dd-di)+(2.-b)*D->vthr(dd)-c*D->vthr(dd+di):D->vthr(dd);\r
++ aa[i] = -c/(b+a*aa[i-1]);\r
++ bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]);\r
++ }\r
++ uu[j+di*(j-1)] = bb[j];\r
++ for(long i=j-1;i>=0;i--)\r
++ uu[j+di*i] = bb[i]+aa[i]*uu[j+di*i+di];\r
++ // next top-right triangle\r
++ long j1=n-1-j;\r
++ b0=B->vthr(i1+j1); c0=C->vthr(i1+j1); d0=D->vthr(d1+j1);\r
++ if(difr) d0 = (2.-b0)*d0-c0*D->vthr(d1+j1-di);\r
++ aa[0] = -c0/b0; bb[0] = d0/b0;\r
++ for(long i=1;i<=j;i++)\r
++ {\r
++<<<<<<< HEAD\r
++ register long ii=i1+j1-di*i, dd=d1+j1-di*i;\r
++=======\r
++ long ii=i1+j1-di*i, dd=d1+j1-di*i;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ mreal a=A->vthr(ii),b=B->vthr(ii),c=C->vthr(ii);\r
++ mreal d=difr?-a*D->vthr(dd+di)+(2.-b)*D->vthr(dd)-c*D->vthr(dd-di):D->vthr(dd);\r
++ aa[i] = -c/(b+a*aa[i-1]);\r
++ bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]);\r
++ }\r
++ uu[j1+n*(n-1)-di*(j-1)] = bb[j];\r
++ for(long i=j-1;i>=0;i--)\r
++ uu[j1+n*(n-1)-di*i] = bb[i]+aa[i]*uu[j1+n*(n-1)-di*i-di];\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++HMDT MGL_EXPORT mgl_data_tridmat(HCDT A, HCDT B, HCDT C, HCDT D, const char *how)\r
++{\r
++ const long nx=D->GetNx(),ny=D->GetNy(),nz=D->GetNz();\r
++ const long nn=nx*ny*nz, np=nx*ny, na=A->GetNN();\r
++ if(B->GetNN()!=na || C->GetNN()!=na) return 0;\r
++ mglData *r = new mglData(nx,ny,nz);\r
++ bool per = mglchr(how,'c');\r
++ bool difr = mglchr(how,'d');\r
++ if(mglchr(how,'x') && (na==nn || na==np || na==nx))\r
++#pragma omp parallel\r
++ {\r
++ mglData T(nx,4); mreal *uu=T.a+(per?3:2)*nx;\r
++#pragma omp for collapse(2)\r
++ for(long k=0;k<nz;k++) for(long j=0;j<ny;j++)\r
++ {\r
++ long i0=0, i1=nx*(j+ny*k);\r
++ if(na==nn) i0=nx*(j+ny*k); else if(na==np) i0=nx*j;\r
++ if(per) mgl_progonka_pr(A,B,C,D,T.a,nx,i1,i0,1,difr);\r
++ else mgl_progonka_sr(A,B,C,D,T.a,nx,i1,i0,1,difr);\r
++ i0 = nx*(j+ny*k);\r
++ for(long i=0;i<nx;i++) r->a[i+i0] = uu[i];\r
++ }\r
++ }\r
++ else if(mglchr(how,'y') && (na==nn || na==np || na==ny))\r
++#pragma omp parallel\r
++ {\r
++ mglData T(ny,4); mreal *uu=T.a+(per?3:2)*ny;\r
++#pragma omp for collapse(2)\r
++ for(long k=0;k<nz;k++) for(long i=0;i<nx;i++)\r
++ {\r
++ long i0=0, i1 = i+np*k;\r
++ if(na==nn) i0=i+np*k; else if(na==np) i0=i;\r
++ if(per) mgl_progonka_pr(A,B,C,D,T.a,ny,i1,i0,nx,difr);\r
++ else mgl_progonka_sr(A,B,C,D,T.a,ny,i1,i0,nx,difr);\r
++ i0 = i+np*k;\r
++ for(long j=0;j<ny;j++) r->a[j*nx+i0] = uu[j];\r
++ }\r
++ }\r
++ else if(mglchr(how,'z') && (na==nn || na==nz))\r
++#pragma omp parallel\r
++ {\r
++ mglData T(nz,4); mreal *uu=T.a+(per?3:2)*nz;\r
++#pragma omp for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ long i0 = na==nn?i+nx*j:0, i1 = i+nx*j;\r
++ if(per) mgl_progonka_pr(A,B,C,D,T.a,nz,i1,i0,np,difr);\r
++ else mgl_progonka_sr(A,B,C,D,T.a,nz,i1,i0,np,difr);\r
++ i0 = i+nx*j;\r
++ for(long k=0;k<nz;k++) r->a[k*np+i0] = uu[k];\r
++ }\r
++ }\r
++ else if(mglchr(how,'h') && ny==nx && (na==nn || na==np) && nx>1)\r
++#pragma omp parallel\r
++ {\r
++ mglData T(np,2);\r
++#pragma omp for\r
++ for(long k=0;k<nz;k++)\r
++ {\r
++ mgl_progonka_hr(A,B,C,D,T.a,nx,k*np,na==nn ? k*np:0,difr);\r
++ memcpy(r->a+k*np, T.a+np, np*sizeof(mreal));\r
++ }\r
++ }\r
++ else { delete r; r=0; }\r
++ return r;\r
++}\r
++//-----------------------------------------------------------------------------\r
++uintptr_t MGL_EXPORT mgl_data_tridmat_(uintptr_t *A, uintptr_t *B, uintptr_t *C, uintptr_t *D, const char *how, int l)\r
++{ char *s=new char[l+1]; memcpy(s,how,l); s[l]=0;\r
++ uintptr_t r = uintptr_t(mgl_data_tridmat(_DA_(A),_DA_(B),_DA_(C),_DA_(D),s));\r
++ delete []s; return r;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_NO_EXPORT mgl_progonka_sc(HCDT A, HCDT B, HCDT C, HCDT D, dual *dat, long n, long id, long i0, long di, bool difr)\r
++{\r
++ dual *aa=dat, *bb=dat+n, *uu=dat+2*n;\r
++ dual b0=B->vcthr(i0), c0=C->vcthr(i0), d0=D->vcthr(id);\r
++<<<<<<< HEAD\r
++ if(difr) d0 = (2.-b0)*d0-c0*D->vcthr(id+di);\r
++ aa[0] = -c0/b0; bb[0] = d0/b0;\r
++ for(long i=1;i<n;i++)\r
++ {\r
++ register long ii=i0+di*i, dd=id+di*i, tt = id+di*((i+1)%n);\r
++ dual a=A->vcthr(ii), b=B->vcthr(ii), c=C->vcthr(ii);\r
++ dual d=difr?-a*D->vcthr(dd-di)+(2.-b)*D->vcthr(dd)-c*D->vcthr(tt):D->vcthr(dd);\r
++=======\r
++ if(difr) d0 = (mreal(2)-b0)*d0-c0*D->vcthr(id+di);\r
++ aa[0] = -c0/b0; bb[0] = d0/b0;\r
++ for(long i=1;i<n;i++)\r
++ {\r
++ long ii=i0+di*i, dd=id+di*i, tt = id+di*((i+1)%n);\r
++ dual a=A->vcthr(ii), b=B->vcthr(ii), c=C->vcthr(ii);\r
++ dual d=difr?-a*D->vcthr(dd-di)+(mreal(2)-b)*D->vcthr(dd)-c*D->vcthr(tt):D->vcthr(dd);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ aa[i] = -c/(b+a*aa[i-1]);\r
++ bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]);\r
++ }\r
++ uu[n-1] = bb[n-1];\r
++ for(long i=n-2;i>=0;i--) uu[i] = bb[i]+aa[i]*uu[i+1];\r
++}\r
++void MGL_NO_EXPORT mgl_progonka_pc(HCDT A, HCDT B, HCDT C, HCDT D, dual *dat, long n, long id, long i0, long di, bool difr)\r
++{\r
++ dual *aa=dat, *bb=dat+n, *gg=dat+2*n, *uu=dat+3*n;\r
++ dual a0=A->vcthr(i0), b0=B->vcthr(i0), c0=C->vcthr(i0), d0=D->vcthr(id);\r
++<<<<<<< HEAD\r
++ if(difr) d0 = -a0*D->vcthr(id+di*(n-1))+(2.-b0)*d0-c0*D->vcthr(id+di);\r
++ aa[0] =-c0/b0; bb[0] = d0/b0; gg[0] =-a0/b0;\r
++ for(long i=1;i<n;i++)\r
++ {\r
++ register long ii=i0+di*i, il=id+di*((i+1)%n), dd=id+di*i;\r
++ dual a=A->vcthr(ii), b=B->vcthr(ii), c=C->vcthr(ii);\r
++ dual d=difr?-a*D->vcthr(dd-di)+(2.-b)*D->vcthr(dd)-c*D->vcthr(il):D->vcthr(dd);\r
++=======\r
++ if(difr) d0 = -a0*D->vcthr(id+di*(n-1))+(mreal(2)-b0)*d0-c0*D->vcthr(id+di);\r
++ aa[0] =-c0/b0; bb[0] = d0/b0; gg[0] =-a0/b0;\r
++ for(long i=1;i<n;i++)\r
++ {\r
++ long ii=i0+di*i, il=id+di*((i+1)%n), dd=id+di*i;\r
++ dual a=A->vcthr(ii), b=B->vcthr(ii), c=C->vcthr(ii);\r
++ dual d=difr?-a*D->vcthr(dd-di)+(mreal(2)-b)*D->vcthr(dd)-c*D->vcthr(il):D->vcthr(dd);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ aa[i] = -c/(b+a*aa[i-1]);\r
++ bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]);\r
++ gg[i] = -a*gg[i-1]/(b+a*aa[i-1]);\r
++ }\r
++<<<<<<< HEAD\r
++ dual P=bb[n-1]/(1.-gg[n-1]), Q=aa[n-1]/(1.-gg[n-1]);\r
++=======\r
++ dual P=bb[n-1]/(mreal(1)-gg[n-1]), Q=aa[n-1]/(mreal(1)-gg[n-1]);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ aa[n-1] = Q; bb[n-1] = P;\r
++ for(long i=n-2;i>=0;i--)\r
++ {\r
++ bb[i] += aa[i]*bb[i+1]+gg[i]*P;\r
++ aa[i] = aa[i]*aa[i+1]+gg[i]*Q;\r
++ }\r
++<<<<<<< HEAD\r
++ dual u0 = bb[0]/(1.-aa[0]);\r
++=======\r
++ dual u0 = bb[0]/(mreal(1)-aa[0]);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ for(long i=0;i<n;i++) uu[i]=bb[i]+aa[i]*u0;\r
++}\r
++void MGL_NO_EXPORT mgl_progonka_hc(HCDT A, HCDT B, HCDT C, HCDT D, dual *dat, long n, long id, long i0, bool difr)\r
++{\r
++ dual *aa=dat, *bb=dat+n, *uu=dat+n*n;\r
++ dual b0=B->vcthr(i0), c0=C->vcthr(i0), d0=D->vcthr(id);\r
++<<<<<<< HEAD\r
++ uu[0] = d0/b0*(difr?(2.-b0):1.);\r
++ b0=B->vcthr(i0+n*n-1); d0=D->vcthr(id+n*n-1);\r
++ uu[n*n-1] = d0/b0*(difr?(2.-b0):1.);\r
++=======\r
++ uu[0] = d0/b0*(difr?(mreal(2)-b0):mreal(1));\r
++ b0=B->vcthr(i0+n*n-1); d0=D->vcthr(id+n*n-1);\r
++ uu[n*n-1] = d0/b0*(difr?(mreal(2)-b0):mreal(1));\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ long di = n-1, i1 = i0+n*(n-1), d1 = id+n*(n-1);\r
++ // suppose the square grid!\r
++ for(long j=1;j<n;j++)\r
++ {\r
++ // first bottom-left triangle\r
++ b0=B->vcthr(i0+j); c0=C->vcthr(i0+j); d0=D->vcthr(id+j);\r
++<<<<<<< HEAD\r
++ if(difr) d0 = (2.-b0)*d0-c0*D->vcthr(id+j+di);\r
++ aa[0] = -c0/b0; bb[0] = d0/b0;\r
++ for(long i=1;i<=j;i++)\r
++ {\r
++ register long ii=i0+j+di*i, dd=id+j+di*i;\r
++ dual a=A->vcthr(ii),b=B->vcthr(ii),c=C->vcthr(ii);\r
++ dual d=difr?-a*D->vcthr(dd-di)+(2.-b)*D->vcthr(dd)-c*D->vcthr(dd+di):D->vcthr(dd);\r
++=======\r
++ if(difr) d0 = (mreal(2)-b0)*d0-c0*D->vcthr(id+j+di);\r
++ aa[0] = -c0/b0; bb[0] = d0/b0;\r
++ for(long i=1;i<=j;i++)\r
++ {\r
++ long ii=i0+j+di*i, dd=id+j+di*i;\r
++ dual a=A->vcthr(ii),b=B->vcthr(ii),c=C->vcthr(ii);\r
++ dual d=difr?-a*D->vcthr(dd-di)+(mreal(2)-b)*D->vcthr(dd)-c*D->vcthr(dd+di):D->vcthr(dd);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ aa[i] = -c/(b+a*aa[i-1]);\r
++ bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]);\r
++ }\r
++ uu[j+di*(j-1)] = bb[j];\r
++ for(long i=j-1;i>=0;i--)\r
++ uu[j+di*i] = bb[i]+aa[i]*uu[j+di*i+di];\r
++ // next top-right triangle\r
++ long j1=n-1-j;\r
++ b0=B->vcthr(i1+j1); c0=C->vcthr(i1+j1); d0=D->vcthr(d1+j1);\r
++<<<<<<< HEAD\r
++ if(difr) d0 = (2.-b0)*d0-c0*D->vcthr(d1+j1-di);\r
++ aa[0] = -c0/b0; bb[0] = d0/b0;\r
++ for(long i=1;i<=j;i++)\r
++ {\r
++ register long ii=i1+j1-di*i, dd=d1+j1-di*i;\r
++ dual a=A->vcthr(ii),b=B->vcthr(ii),c=C->vcthr(ii);\r
++ dual d=difr?-a*D->vcthr(dd+di)+(2.-b)*D->vcthr(dd)-c*D->vcthr(dd-di):D->vcthr(dd);\r
++=======\r
++ if(difr) d0 = (mreal(2)-b0)*d0-c0*D->vcthr(d1+j1-di);\r
++ aa[0] = -c0/b0; bb[0] = d0/b0;\r
++ for(long i=1;i<=j;i++)\r
++ {\r
++ long ii=i1+j1-di*i, dd=d1+j1-di*i;\r
++ dual a=A->vcthr(ii),b=B->vcthr(ii),c=C->vcthr(ii);\r
++ dual d=difr?-a*D->vcthr(dd+di)+(mreal(2)-b)*D->vcthr(dd)-c*D->vcthr(dd-di):D->vcthr(dd);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ aa[i] = -c/(b+a*aa[i-1]);\r
++ bb[i] = (d-a*bb[i-1])/(b+a*aa[i-1]);\r
++ }\r
++ uu[j1+n*(n-1)-di*(j-1)] = bb[j];\r
++ for(long i=j-1;i>=0;i--)\r
++ uu[j1+n*(n-1)-di*i] = bb[i]+aa[i]*uu[j1+n*(n-1)-di*i-di];\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++HADT MGL_EXPORT mgl_datac_tridmat(HCDT A, HCDT B, HCDT C, HCDT D, const char *how)\r
++{\r
++ const long nx=D->GetNx(),ny=D->GetNy(),nz=D->GetNz();\r
++ const long nn=nx*ny*nz, np=nx*ny, na=A->GetNN();\r
++ if(B->GetNN()!=na || C->GetNN()!=na) return 0;\r
++ mglDataC *r = new mglDataC(nx,ny,nz);\r
++ bool per = mglchr(how,'c');\r
++ bool difr = mglchr(how,'d');\r
++ if(mglchr(how,'x') && (na==nn || na==np || na==nx))\r
++#pragma omp parallel\r
++ {\r
++ mglDataC T(nx,4); dual *uu=T.a+(per?3:2)*nx;\r
++#pragma omp for collapse(2)\r
++ for(long k=0;k<nz;k++) for(long j=0;j<ny;j++)\r
++ {\r
++ long i0=0, i1=nx*(j+ny*k);\r
++ if(na==nn) i0=i1; else if(na==np) i0=nx*j;\r
++ if(per) mgl_progonka_pc(A,B,C,D,T.a,nx,i1,i0,1,difr);\r
++ else mgl_progonka_sc(A,B,C,D,T.a,nx,i1,i0,1,difr);\r
++ for(long i=0;i<nx;i++) r->a[i+i1] = uu[i];\r
++ }\r
++ }\r
++ else if(mglchr(how,'y') && (na==nn || na==np || na==ny))\r
++#pragma omp parallel\r
++ {\r
++ mglDataC T(ny,4); dual *uu=T.a+(per?3:2)*ny;\r
++#pragma omp for collapse(2)\r
++ for(long k=0;k<nz;k++) for(long i=0;i<nx;i++)\r
++ {\r
++ long i0=0, i1 = i+np*k;\r
++ if(na==nn) i0=i1; else if(na==np) i0=i;\r
++ if(per) mgl_progonka_pc(A,B,C,D,T.a,ny,i1,i0,nx,difr);\r
++ else mgl_progonka_sc(A,B,C,D,T.a,ny,i1,i0,nx,difr);\r
++ i0 = i+np*k;\r
++ for(long j=0;j<ny;j++) r->a[j*nx+i0] = uu[j];\r
++ }\r
++ }\r
++ else if(mglchr(how,'z') && (na==nn || na==nz))\r
++#pragma omp parallel\r
++ {\r
++ mglDataC T(nz,4); dual *uu=T.a+(per?3:2)*nz;\r
++#pragma omp for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ long i0 = na==nn?i+nx*j:0, i1 = i+nx*j;\r
++ if(per) mgl_progonka_pc(A,B,C,D,T.a,nz,i1,i0,np,difr);\r
++ else mgl_progonka_sc(A,B,C,D,T.a,nz,i1,i0,np,difr);\r
++ for(long k=0;k<nz;k++) r->a[k*np+i1] = uu[k];\r
++ }\r
++ }\r
++ else if(mglchr(how,'h') && ny==nx && (na==nn || na==np) && nx>1)\r
++#pragma omp parallel\r
++ {\r
++ mglDataC T(np,2);\r
++#pragma omp for\r
++ for(long k=0;k<nz;k++)\r
++ {\r
++ mgl_progonka_hc(A,B,C,D,T.a,nx,k*np, na==nn ? k*np:0,difr);\r
++ memcpy(r->a+k*np, T.a+np, np*sizeof(dual));\r
++ }\r
++ }\r
++ else { delete r; r=0; }\r
++ return r;\r
++}\r
++//-----------------------------------------------------------------------------\r
++uintptr_t MGL_EXPORT mgl_datac_tridmat_(uintptr_t *A, uintptr_t *B, uintptr_t *C, uintptr_t *D, const char *how, int l)\r
++{ char *s=new char[l+1]; memcpy(s,how,l); s[l]=0;\r
++ uintptr_t r = uintptr_t(mgl_datac_tridmat(_DA_(A),_DA_(B),_DA_(C),_DA_(D),s));\r
++ delete []s; return r;\r
++}\r
++//-----------------------------------------------------------------------------\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * pixel.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include <algorithm>\r
++#include "mgl2/canvas.h"\r
++#include "mgl2/thread.h"\r
++#if MGL_HAVE_OMP\r
++#include <omp.h>\r
++<<<<<<< HEAD\r
++#endif\r
++\r
++inline mreal get_persp(float pf, float z, float Depth)\r
++//{ return (1-pf)/(1-pf*z/Depth); }\r
++{ return (1-pf/1.37)/(1-pf*z/Depth); }\r
++inline mreal get_pfact(float pf, float Depth)\r
++//{ return pf/(1-pf)/Depth; }\r
++{ return pf/(1-pf/1.37)/Depth; }\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::SetSize(int w,int h,bool clf)\r
++{\r
++ if(w<=0 || h<=0) { SetWarn(mglWarnSize,"SetSize"); return; }\r
++ if(Width==w && Height==h)\r
++ {\r
++ InPlot(0,1,0,1,false);\r
++ if(clf || (Quality&4)) Clf();\r
++ return;\r
++ }\r
++\r
++ const double dx = double(w)/Width;\r
++ const double dy = double(h)/Height;\r
++ const double dz = sqrt(double(w*h))/Depth;\r
++ Width = w; Height = h; Depth = long(sqrt(double(w*h)));\r
++ const long s = long(w)*long(h);\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_lock(&mutexClf);\r
++#elif MGL_HAVE_OMP\r
++ omp_set_lock((omp_lock_t*)lockClf);\r
++#endif\r
++ if(G) { delete []G; delete []C; delete []Z; delete []G4;delete []GB;delete []OI; G=0; }\r
++ G = new unsigned char[s*3];\r
++ G4= new unsigned char[s*4];\r
++ GB= new unsigned char[s*4];\r
++ C = new unsigned char[s*12];\r
++ Z = new float[s*3]; // only 3 planes\r
++ OI= new int[s];\r
++#pragma omp parallel for\r
++ for(long i=0;i<s;i++) memcpy(GB+4*i,BDef,4);\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_unlock(&mutexClf);\r
++#elif MGL_HAVE_OMP\r
++ omp_unset_lock((omp_lock_t*)lockClf);\r
++#endif\r
++\r
++ InPlot(0,1,0,1,false);\r
++ if(clf || (Quality&4)) Clf();\r
++ else // No clearing. So, need to scale\r
++ {\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_lock(&mutexPnt);\r
++ pthread_mutex_lock(&mutexClf);\r
++#elif MGL_HAVE_OMP\r
++ omp_set_lock((omp_lock_t*)lockClf);\r
++#endif\r
++ const long m = long(Prm.size());\r
++ double dd = dx>dy?dy:dx;\r
++#pragma omp parallel for // Scale text\r
++ for(long i=0;i<m;i++) if(Prm[i].type==4)\r
++ {\r
++ mglPnt &q = Pnt[Prm[i].n1];\r
++ Prm[i].p *=dd;\r
++ q.u *= dd; q.v *= dd;\r
++ }\r
++ const long n = long(Pnt.size());\r
++#pragma omp parallel for // Scale coordinates\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mglPnt &q = Pnt[i];\r
++ q.x*=dx; q.y*=dy; q.z*=dz;\r
++ q.xx*=dx; q.yy*=dy; q.zz*=dz;\r
++ if(mgl_isnum(q.w))\r
++ { q.u*=dx; q.v*=dy; q.w*=dz; }\r
++ }\r
++ for(size_t i=0;i<Sub.size();i++)\r
++ { mglBlock &q = Sub[i]; q.n1*=dx; q.n2*=dx; q.n3*=dy; q.n4*=dy; }\r
++ for(size_t k=0;k<DrwDat.size();k++) // scale frames too\r
++ {\r
++ mglStack<mglPnt> &pnt = DrwDat[k].Pnt;\r
++ const long n = long(pnt.size());\r
++#pragma omp parallel for\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mglPnt &q = pnt[i];\r
++ q.x*=dx; q.y*=dy; q.z*=dz;\r
++ q.xx*=dx; q.yy*=dy; q.zz*=dz;\r
++ if(mgl_isnum(q.w))\r
++ { q.u*=dx; q.v*=dy; q.w*=dz; }\r
++ }\r
++ std::vector<mglBlock> &sub = DrwDat[k].Sub;\r
++ for(size_t i=0;i<sub.size();i++)\r
++ { mglBlock &q = sub[i]; q.n1*=dx; q.n2*=dx; q.n3*=dy; q.n4*=dy; }\r
++ }\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_unlock(&mutexClf);\r
++ pthread_mutex_unlock(&mutexPnt);\r
++#elif MGL_HAVE_OMP\r
++ omp_unset_lock((omp_lock_t*)lockClf);\r
++=======\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++#endif\r
++\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::pxl_combine(long id, long n, const void *)\r
++{\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=id;i<n;i+=mglNumThr)\r
++ {\r
++ unsigned char *cc = C+12*i, c[4];\r
++ memcpy(c,GB+4*i,4); // memcpy(c,BDef,4);\r
++ combine(c,cc+8); combine(c,cc+4);\r
++ combine(c,cc); memcpy(G4+4*i,c,4);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::pxl_memcpy(long id, long n, const void *)\r
++{\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=id;i<n;i+=mglNumThr) memcpy(G4+4*i,C+12*i,4);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::pxl_backgr(long id, long n, const void *)\r
++{\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=id;i<n;i+=mglNumThr)\r
++ { unsigned char c[4]; memcpy(c,GB+4*i,4); combine(c,G4+4*i); memcpy(G+3*i,c,3); }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::pxl_transform(long id, long n, const void *)\r
++{\r
++ const mreal *b = Bp.b;\r
++ const mreal dx = -Bp.x*Width/2, dy = -Bp.y*Height/2, dz = Depth/2.;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=id;i<n;i+=mglNumThr)\r
++ {\r
++ mglPnt &p=Pnt[i];\r
++ if(p.sub>=0)\r
++ {\r
++ float x = p.xx-Width/2., y = p.yy-Height/2., z = p.zz-Depth/2.;\r
++ p.x = b[0]*x + b[1]*y + b[2]*z + dx;\r
++ p.y = b[3]*x + b[4]*y + b[5]*z + dy;\r
++ p.z = b[6]*x + b[7]*y + b[8]*z + dz;\r
++ float d = get_persp(Bp.pf,p.z,Depth);\r
++ p.x = Width/2. + d*p.x; p.y = Height/2. + d*p.y;\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::pxl_setz_adv(long id, long n, const void *)\r
++{\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=id;i<n;i+=mglNumThr)\r
++ {\r
++ mglPrim &q=Prm[i]; q.z = Pnt[q.n1].z;\r
++ if(q.type==3) q.z = (q.z + Pnt[q.n2].z + Pnt[q.n3].z + Pnt[q.n4].z)/4;\r
++ else if(q.type==2) q.z = (q.z + Pnt[q.n2].z + Pnt[q.n3].z)/3;\r
++ else if(q.type==1) q.z = (q.z + Pnt[q.n2].z)/2;\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::pxl_pntcol(long id, long n, const void *)\r
++{\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=id;i<n;i+=mglNumThr)\r
++ { mglRGBA c; col2int(Pnt[i],c.r,HighId-1); pnt_col[i]=c.c; }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::pxl_setz(long id, long n, const void *)\r
++{\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=id;i<n;i+=mglNumThr)\r
++ { mglPrim &q=Prm[i]; q.z = Pnt[q.n1].z; }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::pxl_primdr(long id, long , const void *)\r
++{\r
++#define Q 4 // should be >= sqrt(2*num_thr) ???\r
++ const int nx=Q,ny=Q; // TODO find dependence on Q for 1, 2, 4, 8 threads. Try to select optimal\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=id;i<nx*ny;i+=mglNumThr)\r
++ {\r
++ mglDrawReg d; d.set(this,nx,ny,i);\r
++ if(Quality&MGL_DRAW_NORM) for(size_t k=0;k<Prm.size();k++)\r
++ {\r
++ if(Stop) break;\r
++ const mglPrim &p=GetPrm(k); d.copy(p);\r
++ long n1=p.n1, n2=p.n2, n3=p.n3, n4=p.n4;\r
++ switch(p.type)\r
++ {\r
++ case 3: quad_draw(Pnt[n1],Pnt[n2],Pnt[n3],Pnt[n4],&d); break;\r
++ case 1: line_draw(Pnt[n1],Pnt[n2],&d); break;\r
++ case 4: glyph_draw(p,&d); break;\r
++ case 0: mark_draw(Pnt[n1],n4,p.s,&d); break;\r
++ case 2: trig_draw(Pnt[n1],Pnt[n2],Pnt[n3],true,&d); break;\r
++ }\r
++ }\r
++ else if(Quality&MGL_DRAW_FAST) for(size_t k=0;k<Prm.size();k++)\r
++ {\r
++ if(Stop) break;\r
++ const mglPrim &p=GetPrm(k); d.copy(p);\r
++ long n1=p.n1, n2=p.n2, n3=p.n3, n4=p.n4;\r
++ switch(p.type)\r
++ {\r
++ case 3: trig_draw(Pnt[n1],Pnt[n2],Pnt[n4],true,&d);\r
++ trig_draw(Pnt[n1],Pnt[n3],Pnt[n4],true,&d); break;\r
++ case 1: line_draw(Pnt[n1],Pnt[n2],&d); break;\r
++ case 4: glyph_draw(p,&d); break;\r
++ case 0: mark_draw(Pnt[n1],n4,p.s,&d); break;\r
++ case 2: trig_draw(Pnt[n1],Pnt[n2],Pnt[n3],true,&d); break;\r
++ }\r
++ }\r
++ else for(size_t k=0;k<Prm.size();k++)\r
++ {\r
++ if(Stop) break;\r
++ const mglPrim &p=GetPrm(k); d.copy(p);\r
++ long n1=p.n1, n2=p.n2, n3=p.n3, n4=p.n4;\r
++ switch(p.type)\r
++ {\r
++ case 3: fast_draw(Pnt[n1],Pnt[n4],&d); fast_draw(Pnt[n2],Pnt[n3],&d); break;\r
++ case 1: fast_draw(Pnt[n1],Pnt[n2],&d); break;\r
++ case 4: glyph_draw(p,&d); break;\r
++ case 0: mark_draw(Pnt[n1],n4,p.s,&d); break;\r
++ case 2: fast_draw(Pnt[n1],Pnt[n2],&d); fast_draw(Pnt[n1],Pnt[n3],&d);\r
++ fast_draw(Pnt[n2],Pnt[n3],&d); break;\r
++ }\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::pxl_dotsdr(long id, long n, const void *)\r
++{\r
++ const mreal *b = Bp.b;\r
++ const mreal dx = -Bp.x*Width/2, dy = -Bp.y*Height/2, dz = Depth/2.;\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long i=id;i<n;i+=mglNumThr)\r
++ {\r
++ unsigned char r[4]={0,0,0,255};\r
++ const mglPnt &p=Pnt[i];\r
++ if(p.sub<0) continue;\r
++ float x = p.xx-Width/2., y = p.yy-Height/2., z = p.zz-Depth/2.,xx,yy,zz;\r
++ xx = b[0]*x + b[1]*y + b[2]*z + dx;\r
++ yy = b[3]*x + b[4]*y + b[5]*z + dy;\r
++ zz = b[6]*x + b[7]*y + b[8]*z + dz;\r
++ float d = get_persp(Bp.pf,zz,Depth);\r
++ xx = Width/2. + d*xx; yy = Height/2. + d*yy;\r
++\r
++ r[0] = (unsigned char)(255*p.r);\r
++ r[1] = (unsigned char)(255*p.g);\r
++ r[2] = (unsigned char)(255*p.b);\r
++ long i0=long(xx)+Width*(Height-1-long(yy));\r
++ if(i0>=0 && i0<Width*Height && zz>Z[3*i0])\r
++ { Z[3*i0]=z; memcpy(C+12*i0,r,4); OI[i0]=-1; }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++<<<<<<< HEAD\r
++void mglCanvas::Finish()\r
++{\r
++ static mglMatrix bp;\r
++ if(Quality==MGL_DRAW_NONE) return;\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_lock(&mutexPrm);\r
++ pthread_mutex_lock(&mutexPnt);\r
++ pthread_mutex_lock(&mutexClf);\r
++#elif MGL_HAVE_OMP\r
++ omp_set_lock((omp_lock_t*)lockClf);\r
++#endif\r
++ if(Quality==MGL_DRAW_DOTS)\r
++ {\r
++ mglStartThread(&mglCanvas::pxl_dotsdr,this,Pnt.size());\r
++ mglStartThread(&mglCanvas::pxl_memcpy,this,Width*Height);\r
++ mglStartThread(&mglCanvas::pxl_backgr,this,Width*Height);\r
++ }\r
++ else\r
++ {\r
++ if((Quality&MGL_DRAW_LMEM) || (memcmp(&Bp,&bp,sizeof(mglMatrix)) && !(Quality&MGL_DRAW_LMEM) && Prm.size()>0))\r
++ clr(MGL_FINISHED);\r
++ if(!get(MGL_FINISHED))\r
++ {\r
++ if(!(Quality&MGL_DRAW_LMEM) && Prm.size()>0)\r
++ {\r
++ PreparePrim(0); bp=Bp;\r
++ clr(MGL_FINISHED);\r
++ mglStartThread(&mglCanvas::pxl_primdr,this,Prm.size());\r
++ }\r
++ size_t n=Width*Height;\r
++ BDef[3] = (Flag&3)!=2 ? 0:255;\r
++ if(Quality&MGL_DRAW_NORM) mglStartThread(&mglCanvas::pxl_combine,this,n);\r
++ else mglStartThread(&mglCanvas::pxl_memcpy,this,n);\r
++ BDef[3] = 255;\r
++ mglStartThread(&mglCanvas::pxl_backgr,this,n);\r
++ set(MGL_FINISHED);\r
++ }\r
++ }\r
++#if MGL_HAVE_PTHREAD\r
++ pthread_mutex_unlock(&mutexClf);\r
++ pthread_mutex_unlock(&mutexPnt);\r
++ pthread_mutex_unlock(&mutexPrm);\r
++#elif MGL_HAVE_OMP\r
++ omp_unset_lock((omp_lock_t*)lockClf);\r
++#endif\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::ClfZB(bool force)\r
++{\r
++ if(!force && (Quality&MGL_DRAW_LMEM)) return;\r
++ register long n=Width*Height;\r
++ memset(C,0,12*n); memset(OI,0,n*sizeof(int));\r
++#pragma omp parallel for\r
++ for(long i=0;i<3*n;i++) Z[i] = -1e20f;\r
++ clr(MGL_FINISHED);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Clf(mglColor Back)\r
++{\r
++ Fog(0); PDef = 0xffff; pPos = 0;\r
++ ClearFrame();\r
++ if((Flag&3)==2) Back.Set(0,0,0,0);\r
++ if(Back!=NC) FillBackground(Back);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Clf(const char *col)\r
++{\r
++ Fog(0); PDef = 0xffff; pPos = 0;\r
++ ClearFrame();\r
++ mglTexture txt(col,0,0);\r
++ FillBackground(txt.col[1]);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::Rasterize()\r
++{\r
++ Finish();\r
++ memcpy(GB,G4,4*Width*Height);\r
++}\r
++//-----------------------------------------------------------------------------\r
++bool MGL_NO_EXPORT mgl_read_image(unsigned char **g, int &w, int &h, const char *fname);\r
++void mglCanvas::LoadBackground(const char *fname, double alpha)\r
++{\r
++ mgl_read_image(&GB,Width,Height,fname);\r
++ if(alpha<1 && alpha>0)\r
++#pragma omp parallel for\r
++ for(long i=0;i<Width*Height;i++) GB[4*i+3] = (unsigned char)(GB[4*i+3]*alpha);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::FillBackground(const mglColor &cc)\r
++{\r
++ BDef[0] = (unsigned char)(255*cc.r); BDef[1] = (unsigned char)(255*cc.g);\r
++ BDef[2] = (unsigned char)(255*cc.b); BDef[3] = (unsigned char)(255*cc.a);\r
++#pragma omp parallel for\r
++ for(long i=0;i<Width*Height;i++) memcpy(GB+4*i,BDef,4);\r
++}\r
++//-----------------------------------------------------------------------------\r
++=======\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++void mglCanvas::pxl_other(long id, long n, const void *p)\r
++{\r
++ const mglCanvas *gr = (const mglCanvas *)p;\r
++ if(Quality&MGL_DRAW_NORM)\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long k=id;k<n;k+=mglNumThr)\r
++ {\r
++ long i = k%Width, j = Height-1-(k/Width);\r
++ pnt_plot(i,j,gr->Z[3*k+2],gr->C+12*k+8,gr->OI[k]);\r
++ pnt_plot(i,j,gr->Z[3*k+1],gr->C+12*k+4,gr->OI[k]);\r
++ pnt_plot(i,j,gr->Z[3*k],gr->C+12*k,gr->OI[k]);\r
++ }\r
++ else\r
++#if !MGL_HAVE_PTHREAD\r
++#pragma omp parallel for\r
++#endif\r
++ for(long k=id;k<n;k+=mglNumThr)\r
++ {\r
++ long i = k%Width, j = Height-1-(k/Width);\r
++ pnt_plot(i,j,gr->Z[3*k],gr->C+12*k,gr->OI[k]);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::pnt_plot(long x,long y,mreal z,const unsigned char ci[4], int obj_id)\r
++{\r
++ if(ci[3])\r
++ {\r
++ long i0=x+Width*(Height-1-y);\r
++ unsigned char *cc = C+12*i0, c[4];\r
++ memcpy(c,ci,4);\r
++ float *zz = Z+3*i0, zf = FogDist*(z/Depth-0.5-FogDz);\r
++ // try to remove double transparency near vertexes\r
++ if(fabs(z-zz[0])<1 && OI[i0]==obj_id && abs(cc[0]-ci[0])+abs(cc[1]-ci[1])+abs(cc[2]-ci[2])<5)\r
++ { if(cc[3]<ci[3]) memcpy(cc,c,4); return; }\r
++ if(zf<0) // add fog\r
++ {\r
++ int d = int(255.f-255.f*exp(5.f*zf));\r
++ unsigned char cb[4] = {BDef[0], BDef[1], BDef[2], (unsigned char)d};\r
++ if(d==255) return;\r
++ combine(c,cb);\r
++ }\r
++ if(Quality&MGL_DRAW_NORM)\r
++ {\r
++ if(z>=zz[1]) // shift point on slice down and paste new point\r
++ {\r
++ zz[2] = zz[1]; combine(cc+8,cc+4);\r
++ if(z>=zz[0])\r
++ { zz[1] = zz[0]; zz[0] = z; OI[i0]=obj_id;\r
++ memcpy(cc+4,cc,4); memcpy(cc,c,4); }\r
++ else { zz[1] = z; memcpy(cc+4,c,4); }\r
++ }\r
++ else\r
++ {\r
++ if(z>=zz[2]) // shift point on slice down and paste new point\r
++ { zz[2] = z; combine(cc+8,c); }\r
++ else // point below the background\r
++ { combine(c,cc+8); memcpy(cc+8,c,4); }\r
++ }\r
++ }\r
++ if(Quality&MGL_DRAW_FAST)\r
++ {\r
++ if(z>=zz[0]) // point upper the background\r
++ { zz[0]=z; combine(cc,c); OI[i0]=obj_id; }\r
++ }\r
++ else\r
++ {\r
++ if(z>=zz[0]) // point upper the background\r
++ { zz[0]=z; memcpy(cc,c,4); OI[i0]=obj_id; }\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++unsigned char* mglCanvas::col2int(const mglPnt &p,unsigned char *r, int obj_id) const\r
++{\r
++// if(!r) return r; // NOTE r must be provided!\r
++ if(p.a<=0) { memset(r,0,4); return r; }\r
++ float b0=0,b1=0,b2=0, ar,ag,ab,dif;\r
++ const size_t nl = p.sub>=0?p.sub:1-p.sub;\r
++ const bool glob = !get(MGL_LOCAL_LIGHT);\r
++ ar = ag = ab = glob?AmbBr:Sub[nl].AmbBr;\r
++ dif = glob?DifBr:Sub[nl].DifBr;\r
++\r
++ if(mgl_isnum(p.u+p.v+p.w))\r
++ {\r
++ float d0,d1,d2,nn;\r
++ for(long i=0;i<10;i++)\r
++ {\r
++ const mglLight &ll=glob?light[i]:Sub[nl].light[i];\r
++ if(!ll.n) continue;\r
++ if(mgl_isnan(ll.q.x)) // source at infinity\r
++ {\r
++ nn = 2*(p.u*ll.p.x+p.v*ll.p.y+p.w*ll.p.z) / (p.u*p.u+p.v*p.v+p.w*p.w+1e-6);\r
++ d0 = ll.p.x - p.u*nn;\r
++ d1 = ll.p.y - p.v*nn;\r
++ d2 = ll.p.z - p.w*nn;\r
++ nn = 1 + d2/sqrt(d0*d0+d1*d1+d2*d2+1e-6);\r
++\r
++ nn = exp(-ll.a*nn)*ll.b*2;\r
++ b0 += nn*ll.c.r;\r
++ b1 += nn*ll.c.g;\r
++ b2 += nn*ll.c.b;\r
++ }\r
++ else // diffuse and specular light\r
++ {\r
++ d0 = ll.q.x-p.x; // direction to light source\r
++ d1 = ll.q.y-p.y;\r
++ d2 = ll.q.z-p.z;\r
++ nn = 1+(d0*ll.p.x+d1*ll.p.y+d2*ll.p.z)/sqrt(d0*d0+d1*d1+d2*d2+1e-6);\r
++ float bb = exp(-3*ll.a*nn); nn = bb*dif*2;\r
++ ar += nn*ll.c.r;\r
++ ag += nn*ll.c.g;\r
++ ab += nn*ll.c.b;\r
++\r
++ nn = 2*(p.u*d0+p.v*d1+p.w*d2) / (p.u*p.u+p.v*p.v+p.w*p.w+1e-6);\r
++ d0 -= p.u*nn; d1 -= p.v*nn; d2 -= p.w*nn;\r
++ nn = 1 + d2/sqrt(d0*d0+d1*d1+d2*d2+1e-6);\r
++\r
++ nn = exp(-ll.a*nn)*bb*ll.b*2;\r
++ b0 += nn*ll.c.r;\r
++ b1 += nn*ll.c.g;\r
++ b2 += nn*ll.c.b;\r
++ }\r
++ }\r
++ b0 += (ar>1 ? 1:ar)*p.r; // diffuse light\r
++ b1 += (ag>1 ? 1:ag)*p.g;\r
++ b2 += (ab>1 ? 1:ab)*p.b;\r
++ b0 = b0<1 ? b0 : 1; // normalize components\r
++ b1 = b1<1 ? b1 : 1;\r
++ b2 = b2<1 ? b2 : 1;\r
++ }\r
++ else\r
++ { b0=p.r; b1=p.g; b2=p.b; }\r
++ // try to highlight faces\r
++ if(obj_id==HighId) { b0*=0.7; b1*=0.7; b2*=0.7; }\r
++ r[0] = (unsigned char)(255*b0);\r
++ r[1] = (unsigned char)(255*b1);\r
++ r[2] = (unsigned char)(255*b2);\r
++// r[3] = get(MGL_ENABLE_ALPHA) ? (unsigned char)(255*p.a) : 255;\r
++ r[3] = (unsigned char)((Quality&MGL_DRAW_NORM)?255*p.a:255);\r
++ return r;\r
++}\r
++//-----------------------------------------------------------------------------\r
++/// color mixing: color c1 is under color c2 !!!\r
++void mglCanvas::combine(unsigned char *c1, const unsigned char *c2) const\r
++{\r
++ if(c2[3])\r
++ {\r
++<<<<<<< HEAD\r
++ const register unsigned a1=c1[3], a2=c2[3];\r
++=======\r
++ const unsigned a1=c1[3], a2=c2[3];\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ if((Flag&3)==0)\r
++ {\r
++ unsigned b1=255-a2;\r
++ c1[0] = (c1[0]*b1 + c2[0]*a2)/256;\r
++ c1[1] = (c1[1]*b1 + c2[1]*a2)/256;\r
++ c1[2] = (c1[2]*b1 + c2[2]*a2)/256;\r
++ c1[3] = (unsigned char)(a2+a1*b1/255);\r
++ }\r
++ else if((Flag&3)==1)\r
++ {\r
++ c1[0] = (unsigned char)((255-a1*(255-c1[0])/256)*(255-a2*(255-c2[0])/256)/256);\r
++ c1[1] = (unsigned char)((255-a1*(255-c1[1])/256)*(255-a2*(255-c2[1])/256)/256);\r
++ c1[2] = (unsigned char)((255-a1*(255-c1[2])/256)*(255-a2*(255-c2[2])/256)/256);\r
++ c1[3] = 255;\r
++ }\r
++ else if((Flag&3)==2)\r
++ {\r
++<<<<<<< HEAD\r
++ register unsigned b1,b2,b3;\r
++=======\r
++ unsigned b1,b2,b3;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ b1 = (c1[0]*a1 + c2[0]*a2)/255; c1[0] = b1<255 ? b1 : 255;\r
++ b2 = (c1[1]*a1 + c2[1]*a2)/255; c1[1] = b2<255 ? b2 : 255;\r
++ b3 = (c1[2]*a1 + c2[2]*a2)/255; c1[2] = b3<255 ? b3 : 255;\r
++ c1[3] = 255;\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++bool inline visible(long i, long j, const unsigned char m[8], mreal pw, int a) // Check if pixel visible\r
++{\r
++ float c = mgl_cos[(a+360)%360], s = mgl_cos[(a+450)%360];\r
++// int ii = int(0.5+(i*c+j*s)/pw)%8, jj = int(0.5+(j*c-i*s)/pw)%8;\r
++// if(ii<0) ii+=8; if(jj<0) jj+=8;\r
++ int ii = int(0.5+(i*c+j*s)/pw)&7, jj = int(0.5+(j*c-i*s)/pw)&7;\r
++ return m[jj] & (1L<<ii);\r
++}\r
++//-----------------------------------------------------------------------------\r
++/* Bilinear interpolation r(u,v) = r0 + (r1-r0)*u + (r2-r0)*v + (r3+r0-r1-r2)*u*v\r
++ is used (where r is one of {x,y,z,R,G,B,A}. Variables u,v are determined\r
++ for each point (x,y) and selected one pair which 0<u<1 and 0<v<1.*/\r
++void mglCanvas::quad_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4, const mglDrawReg *d)\r
++{\r
++ if(Quality&MGL_DRAW_LMEM)\r
++ {\r
++ if(!(Quality&3))\r
++ { fast_draw(p1,p4,d); fast_draw(p2,p3,d); return; }\r
++ if(!(Quality&MGL_DRAW_NORM))\r
++ { trig_draw(p1,p2,p4,true,d); trig_draw(p1,p3,p4,true,d); return; }\r
++ }\r
++ unsigned char r[4];\r
++ long y1,x1,y2,x2;\r
++ mglPnt d1(p2-p1), d2(p3-p1), d3(p4+p1-p2-p3);\r
++\r
++ if(d1.x==0 && d1.y==0) { trig_draw(p1,p3,p4,true,d); return; }\r
++ if(d2.x==0 && d2.y==0) { trig_draw(p1,p2,p4,true,d); return; }\r
++\r
++ x1 = long(mgl_min(mgl_min(p1.x,p2.x), mgl_min(p3.x,p4.x))); // bounding box\r
++ y1 = long(mgl_min(mgl_min(p1.y,p2.y), mgl_min(p3.y,p4.y)));\r
++ x2 = long(mgl_max(mgl_max(p1.x,p2.x), mgl_max(p3.x,p4.x)));\r
++ y2 = long(mgl_max(mgl_max(p1.y,p2.y), mgl_max(p3.y,p4.y)));\r
++ x1=mgl_max(x1,d->x1); x2=mgl_min(x2,d->x2);\r
++ y1=mgl_max(y1,d->y1); y2=mgl_min(y2,d->y2);\r
++// if(x1>x2 || y1>y2) return;\r
++\r
++ const float dd = d1.x*d2.y-d1.y*d2.x;\r
++ const float dsx =-4*(d2.y*d3.x - d2.x*d3.y)*d1.y;\r
++ const float dsy = 4*(d2.y*d3.x - d2.x*d3.y)*d1.x;\r
++\r
++ mglPoint n1(mglPoint(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z)^mglPoint(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z));\r
++ mglPoint n2(mglPoint(p2.x-p4.x,p2.y-p4.y,p2.z-p4.z)^mglPoint(p3.x-p4.x,p3.y-p4.y,p3.z-p4.z));\r
++ mglPoint nr((n1.x+n2.x)*0.5,(n1.y+n2.y)*0.5,(n1.z+n2.z)*0.5);\r
++\r
++ const float x0 = p1.x, y0 = p1.y;\r
++ const int oi = d->ObjId, ang=d->angle;\r
++ const mreal pw = d->PenWidth;\r
++ const uint64_t pd = d->PDef;\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ if(pd==MGL_SOLID_MASK || visible(i,j,d->m, pw,ang))\r
++ {\r
++ float xx = (i-x0), yy = (j-y0), s;\r
++ s = dsx*xx + dsy*yy + (dd+d3.y*xx-d3.x*yy)*(dd+d3.y*xx-d3.x*yy);\r
++ if(s>=0)\r
++ {\r
++ s = sqrt(s);\r
++ float qu = d3.x*yy - d3.y*xx + dd + s;\r
++ float qv = d3.y*xx - d3.x*yy + dd + s;\r
++ float u = 2.f*(d2.y*xx - d2.x*yy)/qu;\r
++ float v = 2.f*(d1.x*yy - d1.y*xx)/qv;\r
++ if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) // first root bad\r
++ {\r
++ qu = d3.x*yy - d3.y*xx + dd - s;\r
++ qv = d3.y*xx - d3.x*yy + dd - s;\r
++// u = v = -1.f;\r
++ u = 2.f*(d2.y*xx - d2.x*yy)/qu; v = 2.f*(d1.x*yy - d1.y*xx)/qv;\r
++ if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) continue; // second root bad\r
++ }\r
++ mglPnt p(p1+d1*u+d2*v+d3*(u*v));\r
++ if(mgl_isnan(p.u) && mgl_isnum(p.v))\r
++ { p.u = nr.x; p.v = nr.y; p.w = nr.z; }\r
++ pnt_plot(i,j,p.z,col2int(p,r,oi),oi);\r
++ }\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++/* Linear interpolation r(u,v) = r0 + (r1-r0)*u + (r2-r0)*v is used, where r is\r
++ one of {x,y,z,R,G,B,A}. Variables u,v are determined for each point (x,y).\r
++ Point plotted is u>0 and v>0 and u+v<1.*/\r
++void mglCanvas::trig_draw(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, bool anorm, const mglDrawReg *d)\r
++{\r
++ if(!(Quality&3) && anorm)\r
++ { fast_draw(p1,p2,d); fast_draw(p1,p3,d); fast_draw(p2,p3,d); return; }\r
++ unsigned char r[4];\r
++ long y1,x1,y2,x2;\r
++ const mglPnt d1(p2-p1), d2(p3-p1);\r
++\r
++ const float tmp = d2.x*d1.y - d1.x*d2.y;\r
++ if(fabs(tmp)<1e-5) return; // points lies on the same line\r
++ const float dyv =-d1.x/tmp, dxv = d1.y/tmp;\r
++ const float dyu = d2.x/tmp, dxu =-d2.y/tmp;\r
++\r
++ x1 = long(mgl_min(p1.x<p2.x?p1.x:p2.x, p3.x)); // bounding box\r
++ y1 = long(mgl_min(p1.y<p2.y?p1.y:p2.y, p3.y));\r
++ x2 = long(mgl_max(p1.x>p2.x?p1.x:p2.x, p3.x));\r
++ y2 = long(mgl_max(p1.y>p2.y?p1.y:p2.y, p3.y));\r
++ x1=x1>d->x1?x1:d->x1; x2=x2<d->x2?x2:d->x2;\r
++ y1=y1>d->y1?y1:d->y1; y2=y2<d->y2?y2:d->y2;\r
++// if(x1>x2 || y1>y2) return;\r
++ // default normale\r
++ const mglPoint nr(mglPoint(p2.x-p1.x,p2.y-p1.y,p2.z-p1.z)^mglPoint(p3.x-p1.x,p3.y-p1.y,p3.z-p1.z));\r
++ const float x0 = p1.x, y0 = p1.y;\r
++ // provide additional height to be well visible on the surfaces\r
++ const float dz = anorm? 0 : (Width>2 ? 1 : 1e-5*Width);\r
++ const int oi = d->ObjId, ang=d->angle;\r
++ const mreal pw = d->PenWidth;\r
++ const uint64_t pd = d->PDef;\r
++ if(Quality&MGL_DRAW_NORM) for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ if(pd==MGL_SOLID_MASK || visible(i,j,d->m, pw,ang))\r
++ {\r
++ float xx = (i-x0), yy = (j-y0);\r
++ float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy;\r
++ if(u<0 || v<0 || u+v>1) continue;\r
++ mglPnt p(p1+d1*u+d2*v);\r
++ if(mgl_isnan(p.u) && mgl_isnum(p.v) && anorm)\r
++ { p.u = nr.x; p.v = nr.y; p.w = nr.z; }\r
++ pnt_plot(i,j,p.z+dz,col2int(p,r,oi),oi);\r
++ }\r
++ }\r
++ else\r
++ {\r
++ col2int(p1,r,oi);\r
++ float zz = p1.z+dz;\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ if(pd==MGL_SOLID_MASK || visible(i,j,d->m, pw,ang))\r
++ {\r
++ float xx = (i-x0), yy = (j-y0);\r
++ float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy;\r
++ if(u<0 || v<0 || u+v>1) continue;\r
++ pnt_plot(i,j,zz,r,oi);\r
++ }\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++inline unsigned char mgl_sline(unsigned char c,float x)\r
++{ x*=x/2; return (unsigned char)(c/(1+x+x*x/5)); }\r
++void mglCanvas::line_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *dr)\r
++{\r
++ if((Quality&3)==MGL_DRAW_WIRE) { fast_draw(p1,p2,dr); return; } // previously was <2. This may slightly slow down for Quality=1\r
++ unsigned char r[4];\r
++ long y1,x1,y2,x2;\r
++\r
++ const float dz = Width>2 ? 1 : 1e-5*Width; // provide additional height to be well visible on the surfaces\r
++ const int oi = dr->ObjId;\r
++ const float pw=dr->PenWidth*(oi==HighId?2:1), dpw=pen_delta*(oi==HighId?2:3);\r
++ const mglPnt d(p2-p1);\r
++ bool hor = fabs(d.x)>fabs(d.y);\r
++\r
++ x1 = long(p1.x<p2.x?p1.x:p2.x); y1 = long(p1.y<p2.y?p1.y:p2.y); // bounding box\r
++ x2 = long(p1.x>p2.x?p1.x:p2.x); y2 = long(p1.y>p2.y?p1.y:p2.y);\r
++ x1 -= pw+10/dpw; x2 += pw+10/dpw;\r
++ y1 -= pw+10/dpw; y2 += pw+10/dpw;\r
++ x1=x1>dr->x1?x1:dr->x1; x2=x2<dr->x2?x2:dr->x2;\r
++ y1=y1>dr->y1?y1:dr->y1; y2=y2<dr->y2?y2:dr->y2;\r
++ const float dd = hypot(d.x, d.y);\r
++// if(x1>x2 || y1>y2 || dd<1e-5) return;\r
++ if(dd<1e-5) return;\r
++\r
++ const float dxv = d.y/dd, dyv =-d.x/dd;\r
++ const float dxu = d.x/dd, dyu = d.y/dd;\r
++\r
++ const uint64_t pd = dr->PDef;\r
++ const mreal pp = dr->pPos;\r
++ if(hor) for(long i=x1;i<=x2;i++)\r
++ {\r
++ y1 = int(p1.y+d.y*(i-p1.x)/d.x - pw - 10/dpw);\r
++ y2 = int(p1.y+d.y*(i-p1.x)/d.x + pw + 10/dpw);\r
++ y1=y1>dr->y1?y1:dr->y1; y2=y2<dr->y2?y2:dr->y2;\r
++ if(y1>y2) continue;\r
++ for(long j=y1;j<=y2;j++)\r
++ {\r
++ float xx = (i-p1.x), yy = (j-p1.y);\r
++ float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy; v = v*v;\r
++ if(u<0) v += u*u;\r
++ else if(u>dd) v += (u-dd)*(u-dd);\r
++// if(v>pw*pw) continue;\r
++<<<<<<< HEAD\r
++ if(!(pd & ((uint64_t)1<<long(fmod(pp+u/pw/1.5, 16)) ) )) continue;\r
++=======\r
++ if(!(pd & ((uint64_t)1<<long(fmod(pp+u/pw, 16)) ) )) continue;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ mglPnt p(p1+d*(u/dd)); col2int(p,r,oi);\r
++ r[3] = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
++ pnt_plot(i,j,p.z+dz,r,oi);\r
++ }\r
++ }\r
++ else for(long j=y1;j<=y2;j++)\r
++ {\r
++ x1 = int(p1.x+d.x*(j-p1.y)/d.y - pw - 10/dpw);\r
++ x2 = int(p1.x+d.x*(j-p1.y)/d.y + pw + 10/dpw);\r
++ x1=x1>dr->x1?x1:dr->x1; x2=x2<dr->x2?x2:dr->x2;\r
++ if(x1>x2) continue;\r
++\r
++ for(long i=x1;i<=x2;i++)\r
++ {\r
++ float xx = (i-p1.x), yy = (j-p1.y);\r
++ float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy; v = v*v;\r
++ if(u<0) v += u*u;\r
++ else if(u>dd) v += (u-dd)*(u-dd);\r
++// if(v>pw*pw) continue;\r
++<<<<<<< HEAD\r
++ if(!(pd & ((uint64_t)1<<long(fmod(pp+u/pw/1.5, 16))))) continue;\r
++=======\r
++ if(!(pd & ((uint64_t)1<<long(fmod(pp+u/pw, 16))))) continue;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ mglPnt p(p1+d*(u/dd)); col2int(p,r,oi);\r
++ r[3] = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
++ pnt_plot(i,j,p.z+dz,r,oi);\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::pnt_fast(long x,long y,mreal z,const unsigned char ci[4], int obj_id)\r
++{\r
++ long i0=x+Width*(Height-1-y);\r
++ if(ci[3]!=0 && z>Z[3*i0]) // point upper the background\r
++ { Z[3*i0]=z; memcpy(C+12*i0,ci,4); OI[i0]=obj_id; }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::fast_draw(const mglPnt &p1, const mglPnt &p2, const mglDrawReg *dr)\r
++{\r
++ if(p1.x==p2.x && p1.y==p2.y) return;\r
++ const mglPnt d(p2-p1);\r
++ const int oi = dr->ObjId;\r
++ unsigned char r[4]; col2int(p1,r,oi);\r
++ long y1,x1,y2,x2;\r
++\r
++ const bool hor = fabs(d.x)>fabs(d.y);\r
++\r
++ x1 = long(p1.x<p2.x?p1.x:p2.x); y1 = long(p1.y<p2.y?p1.y:p2.y); // bounding box\r
++ x2 = long(p1.x>p2.x?p1.x:p2.x); y2 = long(p1.y>p2.y?p1.y:p2.y);\r
++ x1=x1>dr->x1?x1:dr->x1; x2=x2<dr->x2?x2:dr->x2;\r
++ y1=y1>dr->y1?y1:dr->y1; y2=y2<dr->y2?y2:dr->y2;\r
++ if(x1>x2 || y1>y2) return;\r
++ const float dz = Width>2 ? 1 : 1e-5*Width; // provide additional height to be well visible on the surfaces\r
++\r
++ if(hor) for(long i=x1;i<=x2;i++)\r
++ {\r
++ long c = long(p1.y+d.y*(i-p1.x)/d.x);\r
++ if(c>=y1 && c<=y2)\r
++ pnt_fast(i, c, p1.z+d.z*(i-p1.x)/d.x+dz, r,oi);\r
++ }\r
++ else for(long i=y1;i<=y2;i++)\r
++ {\r
++ long c = long(p1.x+d.x*(i-p1.y)/d.y);\r
++ if(c>=x1 && c<=x2)\r
++ pnt_fast(c, i, p1.z+d.z*(i-p1.y)/d.y+dz, r,oi);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++<<<<<<< HEAD\r
++void mglCanvas::line_pix(long i, long j, const mglPnt &p1, const mglPnt &p2, const mglDrawReg *dr)\r
++{\r
++ register float xx = (i-p1.x), yy = (j-p1.y);\r
++ mglPnt d(p2-p1);\r
++ register float dd = hypot(d.x, d.y);\r
++ register float dxv = d.y/dd, dyv =-d.x/dd, dxu = d.x/dd, dyu = d.y/dd;\r
++ register float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy; v = v*v;\r
++ if(u<0) v += u*u;\r
++ else if(u>dd) v += (u-dd)*(u-dd);\r
++ register float pw=dr->PenWidth, dpw=3*pen_delta;\r
++ if(dr->ObjId==HighId) { pw *= 2; dpw=2*pen_delta; }\r
++ if(v>pw*pw || !(dr->PDef & ( (uint64_t)1<<long(fmod(dr->pPos+u/pw/1.5, 16)) ) )) return;\r
++ mglPnt p(p1+d*(u/dd));\r
++ unsigned char r[4];\r
++ col2int(p,r,dr->ObjId);\r
++ r[3] = v<(pw-1)*(pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-pw)/2));\r
++ register float dz = Width>2 ? 1 : 1e-5*Width; // provide additional height to be well visible on the surfaces\r
++ pnt_plot(i,j,p.z+dz,r,dr->ObjId);\r
++}\r
++//-----------------------------------------------------------------------------\r
++=======\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++void mglCanvas::pnt_draw(const mglPnt &p, const mglDrawReg *dr)\r
++{\r
++// if(k<0 || !dr) return;\r
++ const int oi = dr->ObjId;\r
++ const float pw=(oi==HighId?6:3)*dr->PenWidth,dpw=(oi==HighId?2:3)*pen_delta;\r
++ unsigned char cs[4], cc;\r
++ col2int(p,cs,oi); cc = cs[3];\r
++ if(cc==0) return;\r
++ const long s = long(pw+10/dpw+fabs(pw));\r
++ const long i1=mgl_max(-s,dr->x1-p.x),i2=mgl_min(s,dr->x2-p.x);\r
++ const long j1=mgl_max(-s,dr->y1-p.y),j2=mgl_min(s,dr->y2-p.y);\r
++ if(!(Quality&3)) for(long j=j1;j<=j2;j++) for(long i=i1;i<=i2;i++) // fast draw\r
++ {\r
++ float v = i*i+j*j;\r
++ if(v>1+(pw-1)*(pw-1)/4) continue;\r
++ pnt_plot(p.x+i,p.y+j,p.z,cs,oi);\r
++ }\r
++ else for(long j=j1;j<=j2;j++) for(long i=i1;i<=i2;i++)\r
++ {\r
++ float v = i*i+j*j;\r
++ cs[3] = v<(pw-1)*(pw-1)/4 ? cc : mgl_sline(cc,dpw*(sqrt(v)+(1-pw)/2));\r
++ pnt_plot(p.x+i,p.y+j,p.z,cs,oi);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::mark_draw(const mglPnt &q, char type, mreal size, mglDrawReg *dr)\r
++{\r
++ const int oi = dr->ObjId;\r
++ unsigned char cs[4]; col2int(q,cs,oi);\r
++ const unsigned char ca = cs[3];// = size>0 ? 255 : 255*q.t;\r
++ const mreal ss=(strchr("xsSoO",type)?1:1.1)*fabs(size), dpw=(oi==HighId?2:3)*pen_delta;\r
++ mreal PW=1;\r
++\r
++ if(type=='.' || ss==0)\r
++ {\r
++ PW = 3*(ss?ss:sqrt(font_factor/400));\r
++ if(oi==HighId) PW *= 2;\r
++ const mreal pw = PW;\r
++ mreal dd = pw+10/dpw;\r
++ long x1 = long(q.x-dd), y1 = long(q.y-dd); // bounding box\r
++ long x2 = long(q.x+dd), y2 = long(q.y+dd);\r
++ x1=x1>dr->x1?x1:dr->x1; x2=x2<dr->x2?x2:dr->x2;\r
++ y1=y1>dr->y1?y1:dr->y1; y2=y2<dr->y2?y2:dr->y2;\r
++ if(x1>x2 || y1>y2) return;\r
++ const float V=(pw-1)*(pw-1)/4,S=(1-pw)/2;\r
++\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v=dx*dx+dy*dy;\r
++ int sum = v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ }\r
++ else\r
++ {\r
++ dr->PDef = MGL_SOLID_MASK; dr->angle = 0;\r
++ PW = dr->PenWidth*sqrt(fabs(50*size));\r
++ if(PW<1) PW=1;\r
++ if(oi==HighId) PW *= 2;\r
++ const mreal pw = PW;\r
++\r
++ mreal dd = ss+pw+10/dpw;\r
++ long x1 = long(q.x-dd), y1 = long(q.y-dd); // bounding box\r
++ long x2 = long(q.x+dd), y2 = long(q.y+dd);\r
++ x1=x1>dr->x1?x1:dr->x1; x2=x2<dr->x2?x2:dr->x2;\r
++ y1=y1>dr->y1?y1:dr->y1; y2=y2<dr->y2?y2:dr->y2;\r
++ if(x1>x2 || y1>y2) return;\r
++ const float V=(pw-1)*(pw-1)/4,S=(1-pw)/2;\r
++\r
++ switch(type)\r
++ {\r
++ case 'P':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ int sum=0;\r
++ u = fabs(dy)-ss; v = (dx-ss)*(dx-ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dy)-ss; v = (dx+ss)*(dx+ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dy)-ss; v = dx*dx+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx)-ss; v = (dy-ss)*(dy-ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx)-ss; v = (dy+ss)*(dy+ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx)-ss; v = dy*dy+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case '+':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ int sum=0;\r
++ u = fabs(dy)-ss; v = dx*dx+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx)-ss; v = dy*dy+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'X':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ int sum=0;\r
++ u = fabs(dy)-ss; v = (dx-ss)*(dx-ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dy)-ss; v = (dx+ss)*(dx+ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx)-ss; v = (dy-ss)*(dy-ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx)-ss; v = (dy+ss)*(dy+ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++\r
++ u = fabs(dx+dy)-2*ss; v = dx-dy; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx-dy)-2*ss; v = dx+dy; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'x':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ int sum=0;\r
++ u = fabs(dx+dy)-2*ss; v = dx-dy; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx-dy)-2*ss; v = dx+dy; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'S':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ u = fabs(dy)-ss; if(u<0) u=0;\r
++ v = fabs(dx)-ss; if(v<0) v=0; v = u*u+v*v;\r
++ int sum = v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 's':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ int sum=0;\r
++ u = fabs(dy)-ss; v = (dx-ss)*(dx-ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dy)-ss; v = (dx+ss)*(dx+ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx)-ss; v = (dy-ss)*(dy-ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx)-ss; v = (dy+ss)*(dy+ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'D':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ u = fabs(dx-dy)-ss; if(u<0) u=0;\r
++ v = fabs(dx+dy)-ss; if(v<0) v=0; v = u*u+v*v;\r
++ int sum = v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'd':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ int sum=0;\r
++ u = fabs(dx+dy)-ss; v = (dx-dy-ss)*(dx-dy-ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx+dy)-ss; v = (dx-dy+ss)*(dx-dy+ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx-dy)-ss; v = (dx+dy-ss)*(dx+dy-ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(dx-dy)-ss; v = (dx+dy+ss)*(dx+dy+ss)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'Y':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ int sum=0;\r
++ u = fabs(dy+ss/2)-ss/2; v = dx*dx+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.87*dx+0.5*dy-ss/2)-ss/2; v = (0.5*dx-0.87*dy)*(0.5*dx-0.87*dy)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(-0.87*dx+0.5*dy-ss/2)-ss/2; v = (0.5*dx+0.87*dy)*(0.5*dx+0.87*dy)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case '*':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ int sum=0;\r
++ u = fabs(dy)-ss; v = dx*dx+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.87*dx+0.5*dy)-ss; v = (0.5*dx-0.87*dy)*(0.5*dx-0.87*dy)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(-0.87*dx+0.5*dy)-ss; v = (0.5*dx+0.87*dy)*(0.5*dx+0.87*dy)+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'T':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ u=dy/1.5+ss/3; v=(dx+ss-u)/2;\r
++ if(u>0 && v>0 && u+v<ss) cs[3]=ca;\r
++ else\r
++ {\r
++ int sum=0;\r
++ u = fabs(dx)-ss; v = dy+ss/2; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dx+0.83*dy)-0.9*ss; v = 0.83*dx-0.55*dy+0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dx-0.83*dy)-0.9*ss; v = 0.83*dx+0.55*dy-0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ }\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case '^':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ int sum=0;\r
++ u = fabs(dx)-ss; v = dy+ss/2; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dx+0.83*dy)-0.9*ss; v = 0.83*dx-0.55*dy+0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dx-0.83*dy)-0.9*ss; v = 0.83*dx+0.55*dy-0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'V':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ u=-dy/1.5+ss/3; v=(dx+ss-u)/2;\r
++ if(u>0 && v>0 && u+v<ss) cs[3]=ca;\r
++ else\r
++ {\r
++ int sum=0;\r
++ u = fabs(dx)-ss; v = dy-ss/2; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dx+0.83*dy)-0.9*ss; v = 0.83*dx-0.55*dy-0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dx-0.83*dy)-0.9*ss; v = 0.83*dx+0.55*dy+0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ }\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'v':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ int sum=0;\r
++ u = fabs(dx)-ss; v = dy-ss/2; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dx+0.83*dy)-0.9*ss; v = 0.83*dx-0.55*dy-0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dx-0.83*dy)-0.9*ss; v = 0.83*dx+0.55*dy+0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'L':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ u=-dx/1.5+ss/3; v=(dy+ss-u)/2;\r
++ if(u>0 && v>0 && u+v<ss) cs[3]=ca;\r
++ else\r
++ {\r
++ int sum=0;\r
++ u = fabs(dy)-ss; v = dx-ss/2; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dy+0.83*dx)-0.9*ss; v = 0.83*dy-0.55*dx-0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dy-0.83*dx)-0.9*ss; v = 0.83*dy+0.55*dx+0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ }\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case '<':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ int sum=0;\r
++ u = fabs(dy)-ss; v = dx-ss/2; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dy+0.83*dx)-0.9*ss; v = 0.83*dy-0.55*dx-0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dy-0.83*dx)-0.9*ss; v = 0.83*dy+0.55*dx+0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'R':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ u=dx/1.5+ss/3; v=(dy+ss-u)/2;\r
++ if(u>0 && v>0 && u+v<ss) cs[3]=ca;\r
++ else\r
++ {\r
++ int sum=0;\r
++ u = fabs(dy)-ss; v = dx+ss/2; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dy+0.83*dx)-0.9*ss; v = 0.83*dy-0.55*dx+0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dy-0.83*dx)-0.9*ss; v = 0.83*dy+0.55*dx-0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ }\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case '>':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v,u;\r
++ int sum=0;\r
++ u = fabs(dy)-ss; v = dx+ss/2; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dy+0.83*dx)-0.9*ss; v = 0.83*dy-0.55*dx+0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ u = fabs(0.55*dy-0.83*dx)-0.9*ss; v = 0.83*dy+0.55*dx-0.55*ss; v = v*v+(u<0?0:u*u);\r
++ sum += v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'O':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v;\r
++ v = hypot(dx,dy)-ss; v=v<0?0:v*v;\r
++ int sum = v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'o':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v;\r
++ v = hypot(dx,dy)-ss; v=v*v;\r
++ int sum = v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ case 'C':\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float dx=i-q.x, dy=j-q.y, v;\r
++ v = hypot(dx,dy)-ss; v=v*v;\r
++ int sum = v<V ? 255 : mgl_sline(255,dpw*(sqrt(v)+S));\r
++ v = dx*dx+dy*dy;\r
++ sum += v<(2*pw-1)*(2*pw-1)/4 ? 255 : mgl_sline(255,dpw*(sqrt(v)+(1-2*pw)/2));\r
++ sum = sum>255?255:sum; cs[3] = ca*sum/255;\r
++ pnt_plot(i,j,q.z+1,cs,oi);\r
++ }\r
++ break;\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++// scale direction for new view/zoom\r
++float mglCanvas::GetGlyphPhi(const mglPnt &q, float phi)\r
++{\r
++ float x,y,z,ll;\r
++ if(q.sub<0)\r
++ { x = q.u; y = q.v; z = q.w; }\r
++ else\r
++ {\r
++ x = Bp.b[0]*q.u + Bp.b[1]*q.v + Bp.b[2]*q.w;\r
++ y = Bp.b[3]*q.u + Bp.b[4]*q.v + Bp.b[5]*q.w;\r
++ z = Bp.b[6]*q.u + Bp.b[7]*q.v + Bp.b[8]*q.w;\r
++\r
++ float dv= get_persp(Bp.pf,q.z,Depth);\r
++ float c = get_pfact(Bp.pf,Depth);\r
++ x += (q.x-Width/2)*z*c*dv;\r
++ y += (q.y-Height/2)*z*c*dv;\r
++ }\r
++ ll = x*x+y*y;\r
++ if(ll < 1e-10) return NAN;\r
++ if(ll==ll && phi<1e4)\r
++ {\r
++ phi = -atan2(y,x)*180/M_PI;\r
++// if(fabs(phi)>90) phi+=180; // NOTE this is 2nd part of rotation changes (see also text_plot())\r
++ }\r
++ else phi=0;\r
++ return phi;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::glyph_draw(const mglPrim &P, mglDrawReg *d)\r
++{\r
++ float phi = GetGlyphPhi(Pnt[P.n2],P.w);\r
++ if(mgl_isnan(phi)) return;\r
++ if(d) { d->PDef = MGL_SOLID_MASK; d->angle = 0; d->PenWidth=(P.n3&4)?1.2:0.8; }\r
++\r
++ mglPnt p=Pnt[P.n1]; p.a=1;\r
++ mreal fact = get_persp(Bp.pf,p.z,Depth);\r
++ mreal pf=p.sub<0?1:sqrt((Bp.b[0]*Bp.b[0]+Bp.b[1]*Bp.b[1]+Bp.b[3]*Bp.b[3]+Bp.b[4]*Bp.b[4])/2)*fact;\r
++ mreal size=P.s, f = P.p*pf*P.s;\r
++ p.u *= pf*size; p.v *= pf*size;\r
++\r
++ const mglGlyph &g = Glf[P.n4];\r
++ if(P.n3&8)\r
++ {\r
++ if(!(P.n3&4)) glyph_line(phi,p,f,true, d);\r
++ glyph_line(phi,p,f,false, d);\r
++ }\r
++ else\r
++ {\r
++ if(!(P.n3&4)) glyph_fill(phi,p,f,g, d);\r
++ glyph_wire(phi,p,f,g, d);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_NO_EXPORT mgl_addpnts(mreal x1,mreal y1,mreal x2,mreal y2, std::vector<mreal> *b)\r
++{\r
++// if(x1>x2) { mreal t=x1; x1=x2; x2=t; t=y1; y1=y2; y2=t; }\r
++ if(y1<y2) for(int i=long(y1);i<=long(y2)+1;i++)\r
++ {\r
++ mreal d = (i-y1)/(y2-y1);\r
++ if(d>=0 && d<=1) b[i].push_back(x1+d*(x2-x1));\r
++ }\r
++ else for(int i=long(y2);i<=long(y1)+1;i++)\r
++ {\r
++// mreal xx1 = x1+(x2-x1)*(i-y1)/(y2-y1);\r
++// mreal xx2 = x1+(x2-x1)*(i+1-y1)/(y2-y1);\r
++// if(xx1>xx2) { mreal t=xx1; xx1=xx2; xx2=t; }\r
++// if(xx1<x1) xx1=x1;\r
++// if(xx2>x2) xx2=x2;\r
++// if(i>y1 && i<y2)\r
++// {\r
++// b[i].push_back(xx1);\r
++// if(xx2>=xx1+1) { b[i].push_back(xx2); b[i].push_back(xx2); }\r
++// }\r
++ mreal d = (i-y1)/(y2-y1);\r
++ if(d>=0 && d<=1) b[i].push_back(x1+d*(x2-x1));\r
++ }\r
++}\r
++void mglCanvas::glyph_fill(mreal phi, const mglPnt &pp, mreal f, const mglGlyph &g, const mglDrawReg *d)\r
++{\r
++ if(g.trig && g.nt>0) // slow but look very nice :(\r
++ {\r
++ const mreal co=cos(phi*M_PI/180), si=sin(phi*M_PI/180);\r
++ mglPnt q0=pp, q1=pp, q2=pp;\r
++ q0.u=q0.v=q1.u=q1.v=q2.u=q2.v=NAN;\r
++ for(long ik=0;ik<g.nt;ik++)\r
++ {\r
++ long ii = 6*ik; mreal x, y;\r
++ x = pp.u+g.trig[ii]*f; y = pp.v+g.trig[ii+1]*f;\r
++ q0.x = pp.x+(x*co+y*si)/2; q0.y = pp.y+(y*co-x*si)/2; ii+=2;\r
++ x = pp.u+g.trig[ii]*f; y = pp.v+g.trig[ii+1]*f;\r
++ q1.x = pp.x+(x*co+y*si)/2; q1.y = pp.y+(y*co-x*si)/2; ii+=2;\r
++ x = pp.u+g.trig[ii]*f; y = pp.v+g.trig[ii+1]*f;\r
++ q2.x = pp.x+(x*co+y*si)/2; q2.y = pp.y+(y*co-x*si)/2;\r
++ trig_draw(q0,q1,q2,false,d);\r
++ }\r
++ return;\r
++ }\r
++ if(!g.line || g.nl<=0) return;\r
++ const mreal co=cos(phi*M_PI/180), si=sin(phi*M_PI/180);\r
++\r
++ mreal x1 = 1e10, x2=-1e10, y1=1e10, y2=-1e10;\r
++ for(long i=0;i<g.nl;i++) // find sizes of glyph\r
++ {\r
++ long ii=2*i;\r
++ if(g.line[ii]==0x3fff && g.line[ii+1]==0x3fff) continue;\r
++ mreal x = pp.u + g.line[ii]*f, y = pp.v + g.line[ii+1]*f;\r
++ mreal xx = pp.x+(x*co+y*si)/2, yy = pp.y+(y*co-x*si)/2;\r
++ if(xx<x1) x1=xx;\r
++ if(xx>x2) x2=xx;\r
++ if(yy<y1) y1=yy;\r
++ if(yy>y2) y2=yy;\r
++ }\r
++ x1-=2; x2+=2; y1-=2; y2+=2;\r
++ long w = long(x2-x1+1), h = long(y2-y1+1), il=0;\r
++ long x0=long(x1), y0=long(y1),i1=1,i2=w-2,j1=1,j2=h-2;\r
++ if(d) // apply mglDrawReg\r
++ {\r
++ if(x0+i1<d->x1) i1 = d->x1-x0;\r
++ if(x0+i2>d->x2) i2 = d->x2-x0;\r
++ if(y0+j1<d->y1) j1 = d->y1-y0;\r
++ if(y0+j2>d->y2) j2 = d->y2-y0;\r
++ }\r
++ else\r
++ {\r
++ if(x0+i1<0) i1 = -x0;\r
++ if(x0+i2>Width) i2 = Width-x0;\r
++ if(y0+j1<0) j1 = -y0;\r
++ if(y0+j2>Height)j2 = Height-y0;\r
++ }\r
++ if(i1>=i2 || j1>=j2) return;\r
++\r
++ std::vector<mreal> *b = new std::vector<mreal>[h];\r
++ const float dz = Width>2 ? 1 : 1e-5*Width; // provide additional height to be well visible on the surfaces\r
++ const int oi = d?d->ObjId:-1;\r
++ unsigned char r[4]; col2int(pp,r,oi);\r
++ for(long i=0;i<g.nl;i++) // add bounding points\r
++ {\r
++ long ii=2*i;\r
++ mreal x = pp.u + g.line[ii]*f, y = pp.v + g.line[ii+1]*f;\r
++ mreal xx1 = pp.x+(x*co+y*si)/2-x1, yy1 = pp.y+(y*co-x*si)/2-y1, xx2, yy2;\r
++ if(g.line[ii]==0x3fff && g.line[ii+1]==0x3fff) // line breakthrough\r
++ { il = i+1; continue; }\r
++ else if(i==g.nl-1 || (g.line[ii+2]==0x3fff && g.line[ii+3]==0x3fff)) // enclose the circle\r
++ {\r
++ ii=2*il; x = pp.u + g.line[ii]*f; y = pp.v + g.line[ii+1]*f;\r
++ xx2 = pp.x+(x*co+y*si)/2-x1; yy2 = pp.y+(y*co-x*si)/2-y1;\r
++ }\r
++ else // ordinary line\r
++ {\r
++ ii+=2; x = pp.u + g.line[ii]*f; y = pp.v + g.line[ii+1]*f;\r
++ xx2 = pp.x+(x*co+y*si)/2-x1; yy2 = pp.y+(y*co-x*si)/2-y1;\r
++ }\r
++ mgl_addpnts(xx1,yy1,xx2,yy2,b);\r
++ // draw boundary lines in any case ???\r
++ if(fabs(xx2-xx1)>fabs(yy2-yy1)) // horizontal line\r
++ {\r
++ mreal d = (yy2-yy1)/(xx2-xx1), a = yy1-d*xx1+0.5;\r
++ if(xx1>xx2) { mreal t=xx1; xx1=xx2; xx2=t; }\r
++ for(long k=xx1;k<=xx2;k++)\r
++ {\r
++ long ii = long(k), jj = long(a+d*k);\r
++ if(ii>=i1 && ii<=i2 && jj>=j1 && jj<=j2) pnt_plot(x0+ii,y0+jj,pp.z+dz,r,oi);\r
++ }\r
++ }\r
++ else // vertical line\r
++ {\r
++ mreal d = (xx2-xx1)/(yy2-yy1), a = xx1-d*yy1+0.5;\r
++ if(yy1>yy2) { mreal t=yy1; yy1=yy2; yy2=t; }\r
++ for(long k=yy1;k<=yy2;k++)\r
++ {\r
++ long jj = long(k), ii = long(a+d*k);\r
++ if(ii>=i1 && ii<=i2 && jj>=j1 && jj<=j2) pnt_plot(x0+ii,y0+jj,pp.z+dz,r,oi);\r
++ }\r
++ }\r
++ }\r
++ // TODO add smoothing -- if 3 neighbors >0 => set 1; if 3 neighbors=0 => set 0 ???\r
++ for(long j=j1;j<=j2;j++) // draw glyph\r
++ {\r
++ if(b[j].size()<2) continue;\r
++ std::sort(b[j].begin(),b[j].end());\r
++ for(size_t k=0;k<b[j].size();k+=2)\r
++ {\r
++ long ii1 = long(b[j][k]+0.5), ii2=long(b[j][k+1]+0.5);\r
++// if(ii1==ii2 && b[j].size()%2==1) { k++; ii2=long(b[j][k+1]+0.5); }\r
++ if(ii1<i1) ii1=i1;\r
++ if(ii2>i2) ii2=i2;\r
++ for(long i=ii1;i<=ii2;i++) pnt_plot(x0+i,y0+j,pp.z+dz,r,oi);\r
++ }\r
++ }\r
++ delete []b;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::glyph_wire(mreal phi, const mglPnt &pp, mreal f, const mglGlyph &g, const mglDrawReg *d)\r
++{\r
++ if(!g.line || g.nl<=0) return;\r
++ long il=0;\r
++ const mreal co=cos(phi*M_PI/180), si=sin(phi*M_PI/180);\r
++ mglPnt q0=pp, q1=pp; q0.u=q0.v=q1.u=q1.v=NAN;\r
++ mglPoint p1,p2;\r
++ for(long ik=0;ik<g.nl;ik++)\r
++ {\r
++ long ii = 2*ik;\r
++ if(g.line[ii]==0x3fff && g.line[ii+1]==0x3fff) // line breakthrough\r
++ { il = ik+1; continue; }\r
++ else if(ik==g.nl-1 || (g.line[ii+2]==0x3fff && g.line[ii+3]==0x3fff))\r
++ { // enclose the circle\r
++ mreal x,y;\r
++ x = pp.u+g.line[ii]*f; y = pp.v+g.line[ii+1]*f;\r
++ q0.x = pp.x+(x*co+y*si)/2; q0.y = pp.y+(y*co-x*si)/2; ii=2*il;\r
++ x = pp.u+g.line[ii]*f; y = pp.v+g.line[ii+1]*f;\r
++ q1.x = pp.x+(x*co+y*si)/2; q1.y = pp.y+(y*co-x*si)/2;\r
++ line_draw(q0,q1,d);\r
++ }\r
++ else\r
++ { // normal line\r
++ mreal x,y;\r
++ x = pp.u+g.line[ii]*f; y = pp.v+g.line[ii+1]*f;\r
++ q0.x = pp.x+(x*co+y*si)/2; q0.y = pp.y+(y*co-x*si)/2; ii+=2;\r
++ x = pp.u+g.line[ii]*f; y = pp.v+g.line[ii+1]*f;\r
++ q1.x = pp.x+(x*co+y*si)/2; q1.y = pp.y+(y*co-x*si)/2;\r
++ line_draw(q0,q1,d);\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::glyph_line(mreal phi, const mglPnt &pp, mreal f, bool solid, const mglDrawReg *d)\r
++{\r
++ const mreal co=cos(phi*M_PI/180), si=sin(phi*M_PI/180);\r
++ mglPnt q0=pp,q1=pp,q2=pp,q3=pp;\r
++ q0.u=q0.v=q1.u=q1.v=q2.u=q2.v=q3.u=q3.v=NAN;\r
++\r
++ mreal dy = 0.004,x,y;\r
++ x=pp.u; y=pp.v-dy; q0.x=pp.x+(x*co+y*si)/2; q0.y=pp.y+(y*co-x*si)/2;\r
++ x=pp.u+f; y=pp.v-dy; q1.x=pp.x+(x*co+y*si)/2; q1.y=pp.y+(y*co-x*si)/2;\r
++ x=pp.u; y=pp.v+dy; q2.x=pp.x+(x*co+y*si)/2; q2.y=pp.y+(y*co-x*si)/2;\r
++ x=pp.u+f; y=pp.v+dy; q3.x=pp.x+(x*co+y*si)/2; q3.y=pp.y+(y*co-x*si)/2;\r
++\r
++ if(solid) quad_draw(q0,q1,q3,q2,d);\r
++ else\r
++ {\r
++ line_draw(q0,q1,d); line_draw(q2,q1,d);\r
++ line_draw(q0,q3,d); line_draw(q2,q3,d);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++long mglCanvas::setPp(mglPnt &q, const mglPoint &p)\r
++{\r
++ q.xx=q.x=p.x; q.yy=q.y=p.y; q.zz=q.z=p.z;\r
++ long k;\r
++#pragma omp critical(pnt)\r
++ {k=Pnt.size(); MGL_PUSH(Pnt,q,mutexPnt);}\r
++ return k;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::arrow_draw(long n1, long n2, char st, float ll)\r
++{\r
++ const mglPnt &p1=Pnt[n1], &p2=Pnt[n2];\r
++ mglPnt q=p1; //q.u=q.v=q.w=0;\r
++\r
++ mglPoint kl(p1.x-p2.x,p1.y-p2.y,p1.z-p2.z), kt, p0(p1.x,p1.y,p1.z), p;\r
++ mreal d = hypot(kl.x,kl.y);\r
++ if(d==0) return;\r
++ kl /= d; kt = !kl;\r
++ kl *= ll; kt *= ll;\r
++\r
++ Reserve(8);\r
++ long k1,k2,k3,k4;\r
++\r
++ switch(st) // S,D -- cube, T -- sq.pyramid, I -- square, O -- sphere???, A,K,V -- cone???\r
++ {\r
++ case 'I':\r
++ k1=setPp(q,p0+kt); k2=setPp(q,p0-kt); line_plot(k1,k2); break;\r
++ case 'D':\r
++ k1=setPp(q,p0+kl); k2=setPp(q,p0-kl); k3=setPp(q,p0+kt); k4=setPp(q,p0-kt);\r
++ trig_plot(k1,k2,k3); trig_plot(k1,k2,k4); break;\r
++ case 'S':\r
++ k1=setPp(q,p0+kl+kt); k2=setPp(q,p0+kl-kt);\r
++ k3=setPp(q,p0-kl-kt); k4=setPp(q,p0-kl+kt);\r
++ quad_plot(k1,k2,k4,k3); break;\r
++ case 'X':\r
++ k1=setPp(q,p0+kl+kt); k2=setPp(q,p0+kl-kt);\r
++ k3=setPp(q,p0-kl-kt); k4=setPp(q,p0-kl+kt);\r
++ line_plot(k1,k3); line_plot(k2,k4); break;\r
++ case 'T':\r
++ k1=setPp(q,p0-kl+kt); k2=setPp(q,p0-kl-kt); k3=setPp(q,p0+kl);\r
++ trig_plot(k1,k2,k3); break;\r
++ case 'K':\r
++ k1=setPp(q,p0+kt); k2=setPp(q,p0-kt); line_plot(k1,k2);\r
++ case 'A':\r
++ k1=setPp(q,p0-2.*kl+kt); k2=setPp(q,p0-2.*kl-kt); k3=setPp(q,p0-1.5*kl);\r
++ trig_plot(n1,k3,k1); trig_plot(n1,k3,k2); break;\r
++ case 'V':\r
++ k1=setPp(q,p0+2.*kl+kt); k2=setPp(q,p0+2.*kl-kt); k3=setPp(q,p0+1.5*kl);\r
++ trig_plot(n1,k3,k1); trig_plot(n1,k3,k2); break;\r
++ case 'O': // let draw icosahedron\r
++ {\r
++ const int n = 12; k1=setPp(q,p0+kl);\r
++ for(int i=1;i<=n;i++)\r
++ {\r
++ mreal u = 2*i*M_PI/n;\r
++ k2 = k1; k1 = setPp(q,p0+kl*cos(u)+kt*sin(u));\r
++ trig_plot(n1,k1,k2);\r
++ }\r
++ break;\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvas::arrow_plot_3d(long n1, long n2, char st, float ll)\r
++{\r
++ const mglPnt &p1=Pnt[n1], &p2=Pnt[n2];\r
++ mglPnt q=p1; //q.u=q.v=q.w=0;\r
++\r
++ mglPoint kl(p1.x-p2.x,p1.y-p2.y,p1.z-p2.z), kt, kz, p0(p1.x,p1.y,p1.z), p;\r
++ if(kl.norm()==0) return;\r
++ kl.Normalize(); kt = !kl; kz = kl^kt;\r
++ kl *= ll; kt *= ll; kz *= ll;\r
++\r
++ Reserve(8);\r
++ long k1,k2,k3,k4,k5, k6,k7,k8;\r
++\r
++ switch(st) // S,D -- cube, T -- sq.pyramid, I -- square, O -- sphere???, A,K,V -- cone???\r
++ {\r
++ case 'I':\r
++ k1=setPp(q,p0+kt); k2=setPp(q,p0+kz);\r
++ k3=setPp(q,p0-kt); k4=setPp(q,p0-kz);\r
++ quad_plot(k1,k2,k4,k3); break;\r
++ case 'D':\r
++ k1=setPp(q,p0+kl); k2=setPp(q,p0-kl); k5=k3=setPp(q,p0+kt);\r
++ k4=setPp(q,p0+kz); trig_plot(k1,k3,k4); trig_plot(k2,k3,k4); k3=k4;\r
++ k4=setPp(q,p0-kt); trig_plot(k1,k3,k4); trig_plot(k2,k3,k4); k3=k4;\r
++ k4=setPp(q,p0-kz); trig_plot(k1,k3,k4); trig_plot(k2,k3,k4); k3=k4;\r
++ trig_plot(k1,k3,k5); trig_plot(k2,k3,k5); break;\r
++ case 'S':\r
++ k1=setPp(q,p0+kl+kt); k2=setPp(q,p0+kl+kz); k3=setPp(q,p0+kl-kt); k4=setPp(q,p0+kl-kz);\r
++ k5=setPp(q,p0-kl+kt); k6=setPp(q,p0-kl+kz); k7=setPp(q,p0-kl-kt); k8=setPp(q,p0-kl-kz);\r
++ quad_plot(k1,k2,k4,k3); quad_plot(k1,k2,k5,k6); quad_plot(k3,k2,k7,k6);\r
++ quad_plot(k1,k4,k5,k8); quad_plot(k3,k4,k7,k8); quad_plot(k5,k6,k8,k7); break;\r
++ case 'X':\r
++ k1=setPp(q,p0+kl+kt); k2=setPp(q,p0+kl+kz); k3=setPp(q,p0+kl-kt); k4=setPp(q,p0+kl-kz);\r
++ k5=setPp(q,p0-kl+kt); k6=setPp(q,p0-kl+kz); k7=setPp(q,p0-kl-kt); k8=setPp(q,p0-kl-kz);\r
++ line_plot(k1,k7); line_plot(k2,k8); line_plot(k3,k5); line_plot(k4,k6); break;\r
++ case 'T':\r
++ k1=setPp(q,p0-kl+kt); k2=setPp(q,p0-kl+kz); k3=setPp(q,p0-kl-kt);\r
++ k4=setPp(q,p0-kl-kz); k5=setPp(q,p0+kl);\r
++ trig_plot(k1,k2,k5); trig_plot(k2,k3,k5);\r
++ trig_plot(k3,k4,k5); trig_plot(k1,k4,k5); break;\r
++ case 'K':\r
++ k1=setPp(q,p0+kt); k2=setPp(q,p0+kz);\r
++ k3=setPp(q,p0-kt); k4=setPp(q,p0-kz); quad_plot(k1,k2,k4,k3);\r
++ case 'A':\r
++ k1=setPp(q,p0-2.*kl+kt); k2=setPp(q,p0-2.*kl+kz); k3=setPp(q,p0-2.*kl-kt);\r
++ k4=setPp(q,p0-2.*kl-kz); k5=setPp(q,p0-1.5*kl);\r
++ trig_plot(n1,k5,k1); trig_plot(n1,k5,k2);\r
++ trig_plot(n1,k5,k3); trig_plot(n1,k5,k4); break;\r
++ case 'V':\r
++ k1=setPp(q,p0+2.*kl+kt); k2=setPp(q,p0+2.*kl+kz); k3=setPp(q,p0+2.*kl-kt);\r
++ k4=setPp(q,p0+2.*kl-kz); k5=setPp(q,p0+1.5*kl);\r
++ trig_plot(n1,k5,k1); trig_plot(n1,k5,k2);\r
++ trig_plot(n1,k5,k3); trig_plot(n1,k5,k4); break;\r
++ case 'O': // let draw icosahedron\r
++ {\r
++ const int n = 12, m = n/2; Reserve(n*m);\r
++ long *nn=new long[2*n], n1=setPp(q,p0+kl), n2=setPp(q,p0-kl);\r
++ mreal u,v,rr;\r
++ for(long i=0;i<m;i++) for(long j=0;j<n;j++)\r
++ {\r
++ if(i>0 && i<m-1)\r
++ {\r
++ u = i*M_PI/(m-1.); v = 2*M_PI*j/(n-1.)-1; rr = sin(u);\r
++ nn[j+n]=nn[j]; nn[j]=setPp(q,p0+kl*cos(u)+kt*rr*cos(v)+kz*rr*sin(v));\r
++ }\r
++ else if(i==0) nn[j] = n1;\r
++ else if(i==m-1) { nn[j+n]=nn[j]; nn[j]=n2; }\r
++ if(i*j>0) quad_plot(nn[j-1], nn[j], nn[j+n-1], nn[j+n]);\r
++ }\r
++ delete []nn; break;\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++bool mglCanvas::quad_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3, const mglPnt &p4) const\r
++{\r
++ unsigned char r[4];\r
++ long y1,x1,y2,x2;\r
++ mglPnt d1(p2-p1), d2(p3-p1), d3(p4+p1-p2-p3);\r
++\r
++ if(d1.x==0 && d1.y==0) return trig_vis(p1,p3,p4);\r
++ if(d2.x==0 && d2.y==0) return trig_vis(p1,p2,p4);\r
++\r
++ x1 = long(mgl_min(mgl_min(p1.x,p2.x), mgl_min(p3.x,p4.x))); // bounding box\r
++ y1 = long(mgl_min(mgl_min(p1.y,p2.y), mgl_min(p3.y,p4.y)));\r
++ x2 = long(mgl_max(mgl_max(p1.x,p2.x), mgl_max(p3.x,p4.x)));\r
++ y2 = long(mgl_max(mgl_max(p1.y,p2.y), mgl_max(p3.y,p4.y)));\r
++ x1=mgl_max(x1,0); x2=mgl_min(x2,Width);\r
++ y1=mgl_max(y1,0); y2=mgl_min(y2,Height);\r
++// if(x1>x2 || y1>y2) return;\r
++\r
++ const float dd = d1.x*d2.y-d1.y*d2.x;\r
++ const float dsx =-4*(d2.y*d3.x - d2.x*d3.y)*d1.y;\r
++ const float dsy = 4*(d2.y*d3.x - d2.x*d3.y)*d1.x;\r
++\r
++ const float x0 = p1.x, y0 = p1.y;\r
++ bool vis = false;\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float xx = (i-x0), yy = (j-y0), s;\r
++ s = dsx*xx + dsy*yy + (dd+d3.y*xx-d3.x*yy)*(dd+d3.y*xx-d3.x*yy);\r
++ if(s>=0)\r
++ {\r
++ s = sqrt(s);\r
++ float qu = d3.x*yy - d3.y*xx + dd + s;\r
++ float qv = d3.y*xx - d3.x*yy + dd + s;\r
++ float u = 2.f*(d2.y*xx - d2.x*yy)/qu;\r
++ float v = 2.f*(d1.x*yy - d1.y*xx)/qv;\r
++ if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) // first root bad\r
++ {\r
++ qu = d3.x*yy - d3.y*xx + dd - s;\r
++ qv = d3.y*xx - d3.x*yy + dd - s;\r
++// u = v = -1.f;\r
++ u = 2.f*(d2.y*xx - d2.x*yy)/qu; v = 2.f*(d1.x*yy - d1.y*xx)/qv;\r
++ if(u*(1.f-u)<0.f || v*(1.f-v)<0.f) continue; // second root bad\r
++ }\r
++ float zz = p1.z+d1.z*u+d2.z*v+d3.z*(u*v);\r
++ if(zz>=Z[3*(i+Width*(Height-1-j))]-2) vis=true;\r
++ }\r
++ }\r
++ return vis;\r
++}\r
++//-----------------------------------------------------------------------------\r
++bool mglCanvas::trig_vis(const mglPnt &p1, const mglPnt &p2, const mglPnt &p3) const\r
++{\r
++ unsigned char r[4];\r
++ long y1,x1,y2,x2;\r
++ const mglPnt d1(p2-p1), d2(p3-p1);\r
++\r
++ const float tmp = d2.x*d1.y - d1.x*d2.y;\r
++ if(fabs(tmp)<1e-5) return false; // points lies on the same line\r
++ const float dyv =-d1.x/tmp, dxv = d1.y/tmp;\r
++ const float dyu = d2.x/tmp, dxu =-d2.y/tmp;\r
++\r
++ x1 = long(mgl_min(p1.x<p2.x?p1.x:p2.x, p3.x)); // bounding box\r
++ y1 = long(mgl_min(p1.y<p2.y?p1.y:p2.y, p3.y));\r
++ x2 = long(mgl_max(p1.x>p2.x?p1.x:p2.x, p3.x));\r
++ y2 = long(mgl_max(p1.y>p2.y?p1.y:p2.y, p3.y));\r
++ x1=x1>0?x1:0; x2=x2<Width?x2:Width;\r
++ y1=y1>0?y1:0; y2=y2<Height?y2:Height;\r
++// if(x1>x2 || y1>y2) return;\r
++ // default normale\r
++ const float x0 = p1.x, y0 = p1.y;\r
++ bool vis=false;\r
++ // provide additional height to be well visible on the surfaces\r
++ for(long j=y1;j<=y2;j++) for(long i=x1;i<=x2;i++)\r
++ {\r
++ float xx = (i-x0), yy = (j-y0);\r
++ float u = dxu*xx+dyu*yy, v = dxv*xx+dyv*yy;\r
++ if(u<0 || v<0 || u+v>1) continue;\r
++ float zz = p1.z+d1.z*u+d2.z*v;\r
++ if(zz>=Z[3*(i+Width*(Height-1-j))]-2) vis=true;\r
++ }\r
++ return vis;\r
++}\r
++//-----------------------------------------------------------------------------\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * plot.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include <algorithm>\r
++#include "mgl2/plot.h"\r
++#include "mgl2/eval.h"\r
++#include "mgl2/data.h"\r
++#include "mgl2/base.h"\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Plot by formulas series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_fplot(HMGL gr, const char *eqY, const char *pen, const char *opt)\r
++{\r
++ if(eqY==0 || eqY[0]==0) return; // nothing to plot\r
++ mreal r = gr->SaveState(opt);\r
++ long n = (mgl_isnan(r) || r<=0) ? 100:long(r+0.5);\r
++ long nm = gr->FaceNum?gr->FaceNum*n:10000, nd = gr->FaceNum?gr->FaceNum*10:1000;\r
++\r
++ mglDataS x, y;\r
++ x.dat.reserve(nm); y.dat.reserve(nm);\r
++\r
++ mglFormula *eq = new mglFormula(eqY);\r
++ // initial data filling\r
++ x.clear(); y.clear();\r
++ if(gr->Min.x>0 && gr->Max.x>100*gr->Min.x)\r
++ {\r
++ mreal d = log(2*gr->Max.x/gr->Min.x)/(n-1);\r
++ for(long i=0;i<n;i++)\r
++ { mreal xx = 2*gr->Max.x*exp(d*i)/(2*gr->Max.x/gr->Min.x+exp(d*i));\r
++ x.dat.push_back(xx); y.dat.push_back(eq->Calc(xx)); }\r
++ }\r
++ else if(gr->Max.x<0 && gr->Min.x<100*gr->Max.x)\r
++ {\r
++ mreal d = log(2*gr->Min.x/gr->Max.x)/(n-1);\r
++ for(long i=0;i<n;i++)\r
++ { mreal xx = 2*gr->Min.x*exp(d*i)/(2*gr->Min.x/gr->Max.x+exp(d*i));\r
++ x.dat.push_back(xx); y.dat.push_back(eq->Calc(xx)); }\r
++ }\r
++ else\r
++ {\r
++ mreal d = (gr->Max.x - gr->Min.x)/(n-1.);\r
++ for(long i=0;i<n;i++)\r
++ { mreal xx = gr->Min.x + i*d;\r
++ x.dat.push_back(xx); y.dat.push_back(eq->Calc(xx)); }\r
++ }\r
++\r
++ bool check=true;\r
++ mreal ym=fabs(gr->Max.y - gr->Min.y)/nd;\r
++ while(check && long(x.dat.size())<nm)\r
++ {\r
++ if(gr->NeedStop()) { delete eq; return; }\r
++ check = false;\r
++ for(long i=1;i<long(x.size());i++)\r
++ {\r
++ mreal xs=(x[i]+x[i-1])/2;\r
++ mreal ys=(y[i]+y[i-1])/2, yr=eq->Calc(xs);\r
++ if(fabs(yr-ys)>ym) // bad approximation here\r
++ {\r
++ x.dat.insert(x.dat.begin()+i,xs);\r
++ y.dat.insert(y.dat.begin()+i,yr);\r
++ check = true; i++;\r
++ }\r
++ }\r
++ }\r
++ delete eq; mgl_plot_xy(gr,&x,&y,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_fplot_xyz(HMGL gr, const char *eqX, const char *eqY, const char *eqZ, const char *pen, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long n = (mgl_isnan(r) || r<=0) ? 100:long(r+0.5);\r
++ long nm = gr->FaceNum?gr->FaceNum*n:10000, nd = gr->FaceNum?gr->FaceNum*10:1000;\r
++\r
++ mglDataS x, y, z, t;\r
++ x.dat.reserve(nm); y.dat.reserve(nm);\r
++ z.dat.reserve(nm); t.dat.reserve(nm);\r
++ mglFormula *ex, *ey, *ez;\r
++ ex = new mglFormula(eqX ? eqX : "0");\r
++ ey = new mglFormula(eqY ? eqY : "0");\r
++ ez = new mglFormula(eqZ ? eqZ : "0");\r
++ t.clear(); x.clear(); y.clear(); z.clear();\r
++ for(long i=0;i<n;i++) // initial data filling\r
++ {\r
++ mreal tt = i/(n-1.); t.push_back(tt);\r
++ x.push_back(ex->Calc(0,0,t[i]));\r
++ y.push_back(ey->Calc(0,0,t[i]));\r
++ z.push_back(ez->Calc(0,0,t[i]));\r
++ }\r
++\r
++ bool check=true;\r
++ mreal xm=fabs(gr->Max.x-gr->Min.x)/nd, ym=fabs(gr->Max.y-gr->Min.y)/nd, zm=fabs(gr->Max.z-gr->Min.z)/nd;\r
++ while(check && long(x.dat.size())<nm)\r
++ {\r
++ if(gr->NeedStop()) { delete ex; delete ey; delete ez; return; }\r
++ check = false;\r
++ for(long i=1;i<long(t.size());i++)\r
++ {\r
++ mreal ts=(t[i]+t[i-1])/2;\r
++ mreal xs=(x[i]+x[i-1])/2, xr=ex->Calc(0,0,ts);\r
++ mreal ys=(y[i]+y[i-1])/2, yr=ey->Calc(0,0,ts);\r
++ mreal zs=(z[i]+z[i-1])/2, zr=ez->Calc(0,0,ts);\r
++ if(fabs(xr-xs)>xm || fabs(yr-ys)>ym || fabs(zr-zs)>zm) // bad approximation here\r
++ {\r
++ t.dat.insert(t.dat.begin()+i,ts);\r
++ x.dat.insert(x.dat.begin()+i,xr);\r
++ y.dat.insert(y.dat.begin()+i,yr);\r
++ z.dat.insert(z.dat.begin()+i,zr);\r
++ check = true; i++;\r
++ }\r
++ }\r
++ }\r
++ delete ex; delete ey; delete ez;\r
++ mgl_plot_xyz(gr,&x,&y,&z,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_fplot_(uintptr_t *gr, const char *fy, const char *stl, const char *opt, int ly, int ls, int lo)\r
++{ char *s=new char[ly+1]; memcpy(s,fy,ly); s[ly]=0;\r
++ char *p=new char[ls+1]; memcpy(p,stl,ls); p[ls]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_fplot(_GR_, s, p, o);\r
++ delete []s; delete []p; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_fplot_xyz_(uintptr_t *gr, const char *fx, const char *fy, const char *fz, const char *stl, const char *opt, int lx, int ly, int lz, int ls, int lo)\r
++{ char *sx=new char[lx+1]; memcpy(sx,fx,lx); sx[lx]=0;\r
++ char *sy=new char[ly+1]; memcpy(sy,fy,ly); sy[ly]=0;\r
++ char *sz=new char[lz+1]; memcpy(sz,fz,lz); sz[lz]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ char *p=new char[ls+1]; memcpy(p,stl,ls); p[ls]=0;\r
++ mgl_fplot_xyz(_GR_, sx, sy, sz, p, o);\r
++ delete []sx; delete []sy; delete []sz; delete []p; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Radar series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_radar(HMGL gr, HCDT a, const char *pen, const char *opt)\r
++{\r
++ long n = a->GetNx(), ny=a->GetNy();\r
++ if(n<2) { gr->SetWarn(mglWarnLow,"Radar"); return; }\r
++ mglData x(n+1,ny), y(n+1,ny);\r
++ mreal m=a->Minimal(), r=gr->SaveState(opt);\r
++ if(mgl_isnan(r) || r<0) r = m<0 ? -m:0;\r
++ mreal *co=new mreal[2*n];\r
++ for(long i=0;i<n;i++) { co[i]=cos(2*i*M_PI/n); co[i+n]=sin(2*i*M_PI/n); }\r
++ for(long j=0;j<ny;j++)\r
++ {\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mreal v = a->v(i,j);\r
++ x.a[i+(n+1)*j] = (r+v)*co[i];\r
++ y.a[i+(n+1)*j] = (r+v)*co[i+n];\r
++ }\r
++ x.a[n+(n+1)*j] = r+a->v(0,j); y.a[n+(n+1)*j] = 0;\r
++ }\r
++ mgl_plot_xy(gr,&x,&y,pen,0);\r
++ if(mglchr(pen,'#')) // draw "grid"\r
++ {\r
++ m = 1.1*(a->Maximal()+r);\r
++ x.Create(2); y.Create(2);\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ x.a[1]=m*co[i]; y.a[1]=m*co[i+n];\r
++ mgl_plot_xy(gr,&x,&y,"k",0);\r
++ }\r
++ if(r>0)\r
++ {\r
++ x.Create(101); y.Create(101);\r
++ for(long i=0;i<91;i++)\r
++ { x.a[i]=r*mgl_cos[(4*i)%360]; y.a[i]=r*mgl_cos[(270+4*i)%360]; }\r
++ mgl_plot_xy(gr,&x,&y,"k",0);\r
++ }\r
++ }\r
++ delete []co;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_radar_(uintptr_t *gr, uintptr_t *a, const char *pen, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_radar(_GR_, _DA_(a),s,o); delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Candle series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_candle_xyv(HMGL gr, HCDT x, HCDT v1, HCDT v2, HCDT y1, HCDT y2, const char *pen, const char *opt)\r
++{\r
++ long n=v1->GetNx(),pal,nx=x->GetNx();\r
++ if(n<2) { gr->SetWarn(mglWarnLow,"Candle"); return; }\r
++ if(nx<n || v2->GetNx()!=n) { gr->SetWarn(mglWarnDim,"Candle"); return; }\r
++ bool d1=false,d2=false;\r
++ if(!y1) { y1 = new mglData(n); d1=true; ((mglData *)y1)->Fill(NAN,NAN); }\r
++ if(!y2) { y2 = new mglData(n); d2=true; ((mglData *)y2)->Fill(NAN,NAN); }\r
++ if(y1->GetNx()!=n || y2->GetNx()!=n)\r
++ { if(d1) delete y1; if(d2) delete y2;\r
++ gr->SetWarn(mglWarnDim,"Candle"); return; }\r
++ static int cgid=1; gr->StartGroup("Candle",cgid++);\r
++ gr->SaveState(opt); gr->SetPenPal(pen,&pal); gr->Reserve(8*n);\r
++ bool sh = mglchr(pen,'!');\r
++ bool wire = mglchr(pen,'#');\r
++\r
++ mreal dv=nx>n?1:0;\r
++ if(mglchr(pen,'<')) dv = 1;\r
++ if(mglchr(pen,'^')) dv = 0;\r
++ if(mglchr(pen,'>')) dv =-1;\r
++ mreal zm = gr->AdjustZMin();\r
++ mreal c1,c2; c2=c1=gr->NextColor(pal);\r
++ bool col2 = (gr->GetNumPal(pal)==2 && !sh);\r
++ if(col2) c2 = gr->NextColor(pal);\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mreal m1=v1->v(i), m2 = v2->v(i), xx = x->v(i);\r
++ mreal d = i<nx-1 ? x->v(i+1)-xx : xx-x->v(i-1), c;\r
++ mreal x1 = xx + d/2*(dv-gr->BarWidth);\r
++ mreal x2 = x1 + gr->BarWidth*d; xx = (x1+x2)/2;\r
++ if(sh) c = gr->NextColor(pal,i);\r
++ else if(wire) c = (i>0 && m2>v2->v(i-1))?c2:c1;\r
++ else c = (m1>m2)?c1:c2;\r
++ long n1 = gr->AddPnt(mglPoint(xx,y1->v(i),zm),c);\r
++ long n2 = gr->AddPnt(mglPoint(xx,m1,zm),c);\r
++ gr->line_plot(n1,n2);\r
++ long n3 = gr->AddPnt(mglPoint(xx,y2->v(i),zm),c);\r
++ long n4 = gr->AddPnt(mglPoint(xx,m2,zm),c);\r
++ gr->line_plot(n3,n4);\r
++\r
++ n1 = gr->AddPnt(mglPoint(x1,m1,zm),c);\r
++ n2 = gr->AddPnt(mglPoint(x2,m1,zm),c);\r
++ n3 = gr->AddPnt(mglPoint(x1,m2,zm),c);\r
++ n4 = gr->AddPnt(mglPoint(x2,m2,zm),c);\r
++ gr->line_plot(n1,n2); gr->line_plot(n1,n3);\r
++ gr->line_plot(n4,n2); gr->line_plot(n4,n3);\r
++ if(m1>m2 || (col2 && !wire)) gr->quad_plot(n1,n2,n3,n4);\r
++ }\r
++ if(d1) delete y1;\r
++ if(d2) delete y2;\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_candle_yv(HMGL gr, HCDT v1, HCDT v2, HCDT y1, HCDT y2, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(v1->GetNx()+1);\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ mgl_candle_xyv(gr,&x,v1,v2,y1,y2,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_candle(HMGL gr, HCDT v1, HCDT y1, HCDT y2, const char *pen, const char *opt)\r
++{\r
++ mglData v2(v1);\r
++ v2.Roll('x',1); v2.a[0]=NAN;\r
++ mgl_candle_yv(gr,v1,&v2,y1,y2,pen,opt);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_candle_xyv_(uintptr_t *gr, uintptr_t *x, uintptr_t *v1, uintptr_t *v2, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_candle_xyv(_GR_,_DA_(x),_DA_(v1),_DA_(v2),_DA_(y1),_DA_(y2),s,o); delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_candle_yv_(uintptr_t *gr, uintptr_t *v1, uintptr_t *v2, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_candle_yv(_GR_,_DA_(v1),_DA_(v2),_DA_(y1),_DA_(y2),s,o); delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_candle_(uintptr_t *gr, uintptr_t *y, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_candle(_GR_,_DA_(y),_DA_(y1),_DA_(y2),s,o);\r
++ delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Plot series\r
++//\r
++//-----------------------------------------------------------------------------\r
++struct mglPointA { mglPoint p; bool orig; mglPointA(const mglPoint &pp, bool o) : p(pp), orig(o) {} };\r
++std::vector<mglPointA> MGL_NO_EXPORT mgl_pnt_prepare(const mglPoint &p1, const mglPoint &p2, HCDT xx, HCDT yy, HCDT zz, HCDT cc)\r
++{\r
++ std::vector<mglPointA> out;\r
++ long n = xx->GetNx();\r
++ mglPoint p(xx->v(0),yy->v(0),zz->v(0),cc?cc->v(0):0);\r
++ if(p>p1 && p<p2) out.push_back(mglPointA(p,true));\r
++ else out.push_back(mglPointA(mglPoint(NAN),true));\r
++ for(long i=1;i<n;i++)\r
++ {\r
++ mglPoint q(xx->v(i),yy->v(i),zz->v(i),cc?cc->v(i):0);\r
++ mreal x1,x2,y1,y2,z1,z2,t;\r
++ x1=mgl_d(p1.x, p.x, q.x); x2=mgl_d(p2.x, p.x, q.x); if(x2<x1) { t=x1; x1=x2; x2=t; }\r
++ y1=mgl_d(p1.y, p.y, q.y); y2=mgl_d(p2.y, p.y, q.y); if(y2<y1) { t=y1; y1=y2; y2=t; }\r
++ z1=mgl_d(p1.z, p.z, q.z); z2=mgl_d(p2.z, p.z, q.z); if(z2<z1) { t=z1; z1=z2; z2=t; }\r
++ mreal d1 = mgl_isnum(x1)?x1:0, d2 = mgl_isnum(x2)?x2:1;\r
++ if(y1>d1) d1=y1;\r
++ if(y2<d2) d2=y2;\r
++ if(z1>d1) d1=z1;\r
++ if(z2<d2) d2=z2;\r
++ if(d1>0 && d1<1) out.push_back(mglPointA(p+d1*(q-p),false));\r
++ if(d2>0 && d2<1) out.push_back(mglPointA(p+d2*(q-p),false));\r
++ if(d1<1 && d2>=1) out.push_back(mglPointA(q,true));\r
++ else if(i==n-1) out.push_back(mglPointA(mglPoint(NAN),true));\r
++ p = q;\r
++ }\r
++ return out;\r
++}\r
++std::vector<mglPointA> MGL_NO_EXPORT mgl_pnt_copy(HCDT xx, HCDT yy, HCDT zz, HCDT cc)\r
++{\r
++ std::vector<mglPointA> out;\r
++ long n = xx->GetNx();\r
++ for(long i=0;i<n;i++)\r
++ out.push_back(mglPointA(mglPoint(xx->v(i),yy->v(i),zz->v(i),cc?cc->v(i):0),true));\r
++ return out;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_mark(HMGL gr, double x, double y, double z,const char *mark);\r
++void MGL_EXPORT mgl_plot_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
++{\r
++ static int cgid=1;\r
++ long n=y->GetNx(),pal;\r
++ if(n<2 && !mgl_check_dim0(gr,x,y,z,0,"Plot"))\r
++ {\r
++ gr->StartGroup("Plot",cgid++);\r
++ gr->SaveState(opt);\r
++\r
++ char mk = gr->SetPenPal(pen);\r
++ if(mk)\r
++ {\r
++ long k = gr->AddPnt(mglPoint(x->v(0),y->v(0),z->v(0)),gr->CDef,mglPoint(NAN),-1,3);\r
++ gr->mark_plot(k,mk,gr->GetPenWidth()); gr->AddActive(k);\r
++ }\r
++ gr->EndGroup(); return;\r
++ }\r
++ if(mgl_check_dim1(gr,x,y,z,0,"Plot")) return;\r
++\r
++ gr->StartGroup("Plot",cgid++);\r
++ gr->SaveState(opt);\r
++ long m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m;\r
++ char mk=gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m);\r
++ bool sh = mglchr(pen,'!'), orig = !mglchr(pen,'a'), appr = mglchr(pen,'~');\r
++\r
++ int d = gr->MeshNum>0 ? gr->MeshNum+1 : n, dx = n>d?n/d:1;\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
++ gr->NextColor(pal);\r
++ mglDataR xx(x,mx), yy(y,my), zz(z,mz);\r
++ const std::vector<mglPointA> &pp = orig ? mgl_pnt_copy(&xx, &yy, &zz, 0) :\r
++ mgl_pnt_prepare(gr->Min, gr->Max, &xx, &yy, &zz, 0);\r
++ size_t num = pp.size();\r
++ long *nn = new long[num];\r
++ for(size_t i=0;i<num;i++)\r
++ { mreal c = sh ? gr->NextColor(pal,i):gr->CDef; nn[i] = gr->AddPnt(pp[i].p, c); }\r
++ \r
++ if(mk) for(size_t i=0;i<num;i+=dx)\r
++ if(nn[i]>=0 && pp[i].orig) gr->mark_plot(nn[i], mk);\r
++ if(num>1)\r
++ {\r
++ if(nn[0]>=0 && nn[1]>=0)\r
++ gr->arrow_plot(nn[0],nn[1],gr->Arrow1);\r
++ if(nn[num-1]>=0 && nn[num-2]>=0)\r
++ gr->arrow_plot(nn[num-1],nn[num-2],gr->Arrow2);\r
++ }\r
++ for(size_t i=0;i+1<num;i++)\r
++ {\r
++ if(nn[i]<0 || nn[i+1]<0) continue;\r
++ if(!appr) gr->line_plot(nn[i+1],nn[i]);\r
++ else\r
++ {\r
++ size_t k=i+2;\r
++ while(k<num)\r
++ {\r
++ const mglPoint p1(gr->GetPntP(i)), p2(gr->GetPntP(k));\r
++ mreal dy=p2.x-p1.x, dx=p1.y-p2.y, dd=2*(dx*dx+dy*dy);\r
++ bool ops=false;\r
++ for(size_t ii=i+1;ii<k;ii++)\r
++ {\r
++ const mglPoint p(gr->GetPntP(ii));\r
++ mreal d = dx*p.x+dy*p.y;\r
++ if(d*d>dd) ops = true;\r
++ }\r
++ if(ops) break;\r
++ k++;\r
++ }\r
++ k--; gr->line_plot(nn[k],nn[i]); i = k-1;\r
++ }\r
++ }\r
++ delete []nn;\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_plot_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
++ mgl_plot_xyz(gr,x,y,&z,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_plot(HMGL gr, HCDT y, const char *pen, const char *opt)\r
++{\r
++ long n=y->GetNx();\r
++ if(n<2) { gr->SetWarn(mglWarnLow,"Plot"); return; }\r
++ gr->SaveState(opt);\r
++ mglDataV x(n), z(n);\r
++ x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin());\r
++ mgl_plot_xyz(gr,&x,y,&z,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_plot_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_plot_xyz(_GR_, _DA_(x),_DA_(y),_DA_(z),s,o); delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_plot_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_plot_xy(_GR_, _DA_(x),_DA_(y),s,o); delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_plot_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_plot(_GR_, _DA_(y),s,o); delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Tens series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tens_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT c, const char *pen, const char *opt)\r
++{\r
++ long m,n=y->GetNx(), pal;\r
++ if(mgl_check_dim1(gr,x,y,z,0,"Tens")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Tens",cgid++);\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m;\r
++ char mk=gr->SetPenPal(pen, &pal); gr->Reserve(2*n*m);\r
++ long ss=gr->AddTexture(pen);\r
++ bool orig = !mglchr(pen,'a'), appr = mglchr(pen,'~');\r
++\r
++ int d = gr->MeshNum>0 ? gr->MeshNum+1 : n, dx = n>d?n/d:1;\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
++ long mz = j<z->GetNy() ? j:0, mc = j<c->GetNy() ? j:0;\r
++ mglDataR xx(x,mx), yy(y,my), zz(z,mz), cc(c,mc);\r
++ const std::vector<mglPointA> &pp = orig ? mgl_pnt_copy(&xx, &yy, &zz, &cc) :\r
++ mgl_pnt_prepare(gr->Min, gr->Max, &xx, &yy, &zz, &cc);\r
++\r
++ size_t num = pp.size();\r
++ long *nn = new long[num];\r
++ for(size_t i=0;i<num;i++) nn[i] = gr->AddPnt(pp[i].p, gr->GetC(ss,pp[i].p.c));\r
++ \r
++ if(mk) for(size_t i=0;i<num;i+=dx)\r
++ if(nn[i]>=0 && pp[i].orig) gr->mark_plot(nn[i], mk);\r
++ if(num>1)\r
++ {\r
++ if(nn[0]>=0 && nn[1]>=0)\r
++ gr->arrow_plot(nn[0],nn[1],gr->Arrow1);\r
++ if(nn[num-1]>=0 && nn[num-2]>=0)\r
++ gr->arrow_plot(nn[num-1],nn[num-2],gr->Arrow2);\r
++ }\r
++ for(size_t i=0;i+1<num;i++)\r
++ {\r
++ if(nn[i]<0 || nn[i+1]<0) continue;\r
++ if(!appr) gr->line_plot(nn[i+1],nn[i]);\r
++ else\r
++ {\r
++ size_t k=i+2;\r
++ while(k<num)\r
++ {\r
++ const mglPoint p1(gr->GetPntP(i)), p2(gr->GetPntP(k));\r
++ mreal dy=p2.x-p1.x, dx=p1.y-p2.y, dd=2*(dx*dx+dy*dy);\r
++ bool ops=false;\r
++ for(size_t ii=i+1;ii<k;ii++)\r
++ {\r
++ const mglPoint p(gr->GetPntP(ii));\r
++ mreal d = dx*p.x+dy*p.y;\r
++ if(d*d>dd) ops = true;\r
++ }\r
++ if(ops) break;\r
++ k++;\r
++ }\r
++ k--; gr->line_plot(nn[k],nn[i]); i = k-1;\r
++ }\r
++ }\r
++ delete []nn;\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tens_xy(HMGL gr, HCDT x, HCDT y, HCDT c, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
++ mgl_tens_xyz(gr,x,y,&z,c,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tens(HMGL gr, HCDT y, HCDT c, const char *pen, const char *opt)\r
++{\r
++ long n=y->GetNx();\r
++ if(n<2) { gr->SetWarn(mglWarnLow,"Tens"); return; }\r
++ gr->SaveState(opt);\r
++ mglDataV x(n), z(n);\r
++ x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin());\r
++ mgl_tens_xyz(gr,&x,y,&z,c,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tens_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *c, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tens_xyz(_GR_, _DA_(x),_DA_(y),_DA_(z),_DA_(c),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tens_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *c, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tens_xy(_GR_, _DA_(x),_DA_(y),_DA_(c),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tens_(uintptr_t *gr, uintptr_t *y, uintptr_t *c, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tens(_GR_, _DA_(y),_DA_(c),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Area series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_area_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
++{\r
++ long n=y->GetNx(),m,pal;\r
++ if(mgl_check_dim1(gr,x,y,z,0,"Area")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Area3",cgid++);\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m;\r
++ bool sh = mglchr(pen,'!'), wire = mglchr(pen,'#'), orig = !mglchr(pen,'a');\r
++\r
++ mreal z0=gr->GetOrgZ('x');\r
++ gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m);\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ mreal c1=gr->NextColor(pal), c2=c1;\r
++ if(gr->GetNumPal(pal)==2*m && !sh) c2 = gr->NextColor(pal);\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
++\r
++ mglDataR xx(x,mx), yy(y,my), zz(z,mz);\r
++ std::vector<mglPointA> pp = orig ? mgl_pnt_copy(&xx, &yy, &zz, 0) :\r
++ mgl_pnt_prepare(gr->Min, gr->Max, &xx, &yy, &zz, 0);\r
++ size_t np = pp.size();\r
++ long n1=-1, n2=-1;\r
++ mglPoint nn(pp[0].p.y-pp[1].p.y, pp[1].p.x-pp[0].p.x);\r
++ for(size_t i=0;i<np;i++)\r
++ {\r
++ long n3=n1, n4=n2;\r
++ if(sh) c2=c1=gr->NextColor(pal,i);\r
++ if(i>0 && i<np-1) { nn.x=(pp[i-1].p.y-pp[i+1].p.y)/2; nn.y=(pp[i+1].p.x-pp[i-1].p.x)/2; }\r
++ else if(i==np-1) { nn.x=pp[np-2].p.y-pp[np-1].p.y; nn.y=pp[np-1].p.x-pp[np-2].p.x; }\r
++ n1 = gr->AddPnt(pp[i].p, c1,nn,-1,27); pp[i].p.z = z0;\r
++ n2 = gr->AddPnt(pp[i].p, c2,nn,-1,27);\r
++ if(gr->SamePnt(n1,n3) || gr->SamePnt(n2,n4)) continue;\r
++ if(wire)\r
++ {\r
++ gr->line_plot(n1,n2); gr->line_plot(n3,n4);\r
++ gr->line_plot(n1,n3); gr->line_plot(n4,n2);\r
++ }\r
++ else gr->quad_plot(n1,n2,n3,n4);\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_area_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
++{\r
++ long n=y->GetNx(),m=y->GetNy(),pal;\r
++ if(mgl_check_dim1(gr,x,y,0,0,"Area")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Curve",cgid++);\r
++ mreal zm = gr->AdjustZMin();\r
++ mreal y0=gr->GetOrgY('x');\r
++ mglPoint nn(0,0,1);\r
++ bool sh = mglchr(pen,'!'), wire = mglchr(pen,'#'), orig = !mglchr(pen,'a');\r
++\r
++ gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m);\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ mreal c1=gr->NextColor(pal), c2=c1;\r
++ if(gr->GetNumPal(pal)==2*m && !sh) c2=gr->NextColor(pal);\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
++ mreal z0 = zm + (m-1-j)*(gr->Max.z-zm)/m;\r
++\r
++ mglDataR xx(x,mx), yy(y,my); mglDataV zz(n,1,1,z0);\r
++ std::vector<mglPointA> pp = orig ? mgl_pnt_copy(&xx, &yy, &zz, 0) :\r
++ mgl_pnt_prepare(gr->Min, gr->Max, &xx, &yy, &zz, 0);\r
++ size_t np = pp.size();\r
++ long n1=-1, n2=-1;\r
++ for(size_t i=0;i<np;i++)\r
++ {\r
++ long n3=n1, n4=n2;\r
++ if(sh) c2=c1=gr->NextColor(pal,i);\r
++ n1 = gr->AddPnt(pp[i].p, c1,nn,-1,27); pp[i].p.y = y0;\r
++ n2 = gr->AddPnt(pp[i].p, c2,nn,-1,27);\r
++ if(n1<0 || n2<0) { n1=n2=-1; continue; }\r
++ if(gr->SamePnt(n1,n3) || gr->SamePnt(n2,n4)) continue;\r
++ if(wire)\r
++ {\r
++ gr->line_plot(n1,n2); gr->line_plot(n3,n4);\r
++ gr->line_plot(n1,n3); gr->line_plot(n4,n2);\r
++ }\r
++ else gr->quad_plot(n1,n2,n3,n4);\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_area(HMGL gr, HCDT y, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(y->GetNx()); x.Fill(gr->Min.x,gr->Max.x);\r
++ mgl_area_xy(gr,&x,y,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_area_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_area_xyz(_GR_, _DA_(x),_DA_(y),_DA_(z),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_area_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_area_xy(_GR_, _DA_(x),_DA_(y),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_area_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_area(_GR_, _DA_(y),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Region series\r
++//\r
++//-----------------------------------------------------------------------------\r
++struct mglPointB { mglPoint p1, p2; bool orig;\r
++ mglPointB(const mglPoint &pp1, const mglPoint &pp2, bool o) : p1(pp1), p2(pp2), orig(o) {} };\r
++std::vector<mglPointB> MGL_NO_EXPORT mgl_pnt_prepare(const mglPoint &a1, const mglPoint &a2, HCDT xx1, HCDT yy1, HCDT zz1, HCDT xx2, HCDT yy2, HCDT zz2)\r
++{\r
++ std::vector<mglPointB> out;\r
++ long n = xx1->GetNx();\r
++ mglPoint p1(xx1->v(0),yy1->v(0),zz1->v(0)), p2(xx2->v(0),yy2->v(0),zz2->v(0));\r
++ if(p1>a1 && p1<a2 && p2>a1 && p2<a2) out.push_back(mglPointB(p1,p2,true));\r
++ else out.push_back(mglPointB(mglPoint(NAN),mglPoint(NAN),true));\r
++ for(long i=1;i<n;i++)\r
++ {\r
++ mglPoint q1(xx1->v(i),yy1->v(i),zz1->v(i)), q2(xx2->v(i),yy2->v(i),zz2->v(i));\r
++ mreal x1,x2,y1,y2,z1,z2,t;\r
++ x1=mgl_d(a1.x, p1.x, q1.x); x2=mgl_d(a2.x, p1.x, q1.x); if(x2<x1) { t=x1; x1=x2; x2=t; }\r
++ y1=mgl_d(a1.y, p1.y, q1.y); y2=mgl_d(a2.y, p1.y, q1.y); if(y2<y1) { t=y1; y1=y2; y2=t; }\r
++ z1=mgl_d(a1.z, p1.z, q1.z); z2=mgl_d(a2.z, p1.z, q1.z); if(z2<z1) { t=z1; z1=z2; z2=t; }\r
++ mreal d11 = mgl_isnum(x1)?x1:0, d12 = mgl_isnum(x2)?x2:1;\r
++ if(y1>d11) d11=y1;\r
++ if(y2<d12) d12=y2;\r
++ if(z1>d11) d11=z1;\r
++ if(z2<d12) d12=z2;\r
++ x1=mgl_d(a1.x, p2.x, q2.x); x2=mgl_d(a2.x, p2.x, q2.x); if(x2<x1) { t=x1; x1=x2; x2=t; }\r
++ y1=mgl_d(a1.y, p2.y, q2.y); y2=mgl_d(a2.y, p2.y, q2.y); if(y2<y1) { t=y1; y1=y2; y2=t; }\r
++ z1=mgl_d(a1.z, p2.z, q2.z); z2=mgl_d(a2.z, p2.z, q2.z); if(z2<z1) { t=z1; z1=z2; z2=t; }\r
++ mreal d21 = mgl_isnum(x1)?x1:0, d22 = mgl_isnum(x2)?x2:1;\r
++ if(y1>d21) d21=y1;\r
++ if(y2<d22) d22=y2;\r
++ if(z1>d21) d21=z1;\r
++ if(z2<d22) d22=z2;\r
++ \r
++ std::vector<mreal> dd;\r
++ if(d11>0 && d11<1) dd.push_back(d11);\r
++ if(d21>0 && d21<1) dd.push_back(d21);\r
++ if(d12>0 && d12<1) dd.push_back(d12);\r
++ if(d22>0 && d22<1) dd.push_back(d22);\r
++ // now add all intersections to be sure\r
++ x1=mgl_d(0, p2.x-p1.x, q2.x-q1.x); if(x1>0 && x1<1) dd.push_back(x1);\r
++ y1=mgl_d(0, p2.y-p1.y, q2.y-q1.y); if(y1>0 && y1<1) dd.push_back(y1);\r
++ z1=mgl_d(0, p2.z-p1.z, q2.z-q1.z); if(z1>0 && z1<1) dd.push_back(z1);\r
++ std::sort(dd.begin(),dd.end());\r
++ for(size_t j=0;j<dd.size();j++)\r
++ out.push_back(mglPointB(p1+dd[j]*(q1-p1), p2+dd[j]*(q2-p2), false));\r
++ if((d11<1 && d12>=1) || (d21<1 && d22>=1)) out.push_back(mglPointB(q1,q2,true));\r
++ else if(i==n-1) out.push_back(mglPointB(mglPoint(NAN),mglPoint(NAN),true));\r
++ p1 = q1; p2 = q2;\r
++ }\r
++ return out;\r
++}\r
++std::vector<mglPointB> MGL_NO_EXPORT mgl_pnt_copy(HCDT xx1, HCDT yy1, HCDT zz1, HCDT xx2, HCDT yy2, HCDT zz2)\r
++{\r
++ std::vector<mglPointB> out;\r
++ long n = xx1->GetNx();\r
++ for(long i=0;i<n;i++)\r
++ out.push_back(mglPointB(mglPoint(xx1->v(i),yy1->v(i),zz1->v(i)), mglPoint(xx2->v(i),yy2->v(i),zz2->v(i)), true));\r
++ return out;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_region_3d(HMGL gr, HCDT x1, HCDT y1, HCDT z1, HCDT x2, HCDT y2, HCDT z2, const char *pen, const char *opt)\r
++{\r
++ long n=y1->GetNx(), m, pal;\r
++ if(mgl_check_dim1(gr,x1,y1,z1,0,"Region")) return;\r
++ if(mgl_check_dim1(gr,x1,x2,y2,z2,"Region")) return;\r
++ m = x1->GetNy() > y1->GetNy() ? x1->GetNy() : y1->GetNy();\r
++ m = (z1 && z1->GetNy() > m) ? z1->GetNy() : m;\r
++ bool zhave = z1 && z2;\r
++ if(x1->GetNy()!=x2->GetNy() || y1->GetNy()!=y2->GetNy())\r
++ { gr->SetWarn(mglWarnDim,"Region"); return; }\r
++ if(zhave && z1->GetNy()!=z2->GetNy())\r
++ { gr->SetWarn(mglWarnDim,"Region"); return; }\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Region",cgid++);\r
++ mreal c1,c2;\r
++ mglPoint nn(0,0,1);\r
++ mreal zm = gr->AdjustZMin();\r
++// bool inside = (mglchr(pen,'i')); // NOTE: check if 'i' is free (used here for inside flag)\r
++ bool sh = mglchr(pen,'!'), wire = mglchr(pen,'#'), orig = !mglchr(pen,'a');\r
++\r
++ gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m);\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ c2=c1=gr->NextColor(pal);\r
++ if(gr->GetNumPal(pal)==2*m && !sh) c2=gr->NextColor(pal);\r
++ long mx = j<x1->GetNy() ? j:0, my = j<y1->GetNy() ? j:0;\r
++ long mz = (zhave && j<z1->GetNy()) ? j:0;\r
++ mreal z0 = zm + (m-1-j)*(gr->Max.z-zm)/m;\r
++\r
++ mglDataR xx1(x1,mx), yy1(y1,my), xx2(x2,mx), yy2(y2,my);\r
++ mglDataV zz0(n,1,1,z0);\r
++ std::vector<mglPointB> pp;\r
++ if(zhave)\r
++ {\r
++ mglDataR zz1(z1,mz), zz2(z2,mz);\r
++ pp = orig ? mgl_pnt_copy(&xx1, &yy1, &zz1, &xx2, &yy2, &zz2) :\r
++ mgl_pnt_prepare(gr->Min, gr->Max, &xx1, &yy1, &zz1, &xx2, &yy2, &zz2);\r
++ }\r
++ else\r
++ {\r
++ pp = orig ? mgl_pnt_copy(&xx1, &yy1, &zz0, &xx2, &yy2, &zz0) :\r
++ mgl_pnt_prepare(gr->Min, gr->Max, &xx1, &yy1, &zz0, &xx2, &yy2, &zz0);\r
++ }\r
++\r
++ long n1=-1, n2=-1;\r
++ size_t np = pp.size();\r
++ for(size_t i=0;i<np;i++)\r
++ {\r
++ long n3=n1, n4=n2;\r
++ if(sh) c2=c1=gr->NextColor(pal,i);\r
++ n1 = gr->AddPnt(pp[i].p1, c1,nn,-1,27);\r
++ n2 = gr->AddPnt(pp[i].p2, c2,nn,-1,27);\r
++ if(n1<0 || n2<0) { n1=n2=-1; continue; }\r
++ if(gr->SamePnt(n1,n3) || gr->SamePnt(n2,n4)) continue;\r
++ if(wire)\r
++ {\r
++ gr->line_plot(n1,n2); gr->line_plot(n3,n4);\r
++ gr->line_plot(n1,n3); gr->line_plot(n4,n2);\r
++ }\r
++ else gr->quad_plot(n1,n2,n3,n4);\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_region_xy(HMGL gr, HCDT x, HCDT y1, HCDT y2, const char *pen, const char *opt)\r
++{\r
++ long n=y1->GetNx(), m=y1->GetNy(), pal;\r
++ if(mgl_check_dim1(gr,x,y1,y2,0,"Region")) return;\r
++ if(y2->GetNy()!=m) { gr->SetWarn(mglWarnDim,"Region"); return; }\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Region",cgid++);\r
++ mreal c1,c2;\r
++ mglPoint nn(0,0,1);\r
++ mreal zm = gr->AdjustZMin();\r
++ bool inside = mglchr(pen,'i'); // NOTE: check if 'i' is free (used here for inside flag)\r
++ bool sh = mglchr(pen,'!'), wire = mglchr(pen,'#'), orig = !mglchr(pen,'a');\r
++\r
++ gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m);\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ c2=c1=gr->NextColor(pal);\r
++ if(gr->GetNumPal(pal)==2*m && !sh) c2=gr->NextColor(pal);\r
++ long mx = j<x->GetNy() ? j:0;\r
++ mreal z0 = zm + (m-1-j)*(gr->Max.z-zm)/m;\r
++\r
++ mglDataR xx(x,mx), yy1(y1,j), yy2(y2,j);\r
++ mglDataV zz0(n,1,1,z0);\r
++ std::vector<mglPointB> pp = orig ? mgl_pnt_copy(&xx, &yy1, &zz0, &xx, &yy2, &zz0) :\r
++ mgl_pnt_prepare(gr->Min, gr->Max, &xx, &yy1, &zz0, &xx, &yy2, &zz0);\r
++\r
++ mreal f1=0, f2=0;\r
++ long n1=-1, n2=-1;\r
++ size_t np = pp.size();\r
++ for(size_t i=0;i<np;i++)\r
++ {\r
++ long n3=n1, n4=n2;\r
++ mreal f3=f1, f4=f2;\r
++ f1 = pp[i].p1.y; f2 = pp[i].p2.y;\r
++ if(sh) c2=c1=gr->NextColor(pal,i);\r
++ n1 = gr->AddPnt(pp[i].p1, c1,nn,-1,27);\r
++ n2 = gr->AddPnt(pp[i].p2, c2,nn,-1,27);\r
++ if(n1<0 || n2<0) { n1=n2=-1; continue; }\r
++ if(inside && (f2<f1 || f4<f3)) continue;\r
++ if(gr->SamePnt(n1,n3) || gr->SamePnt(n2,n4)) continue;\r
++ if(wire)\r
++ {\r
++ gr->line_plot(n1,n2); gr->line_plot(n3,n4);\r
++ gr->line_plot(n1,n3); gr->line_plot(n4,n2);\r
++ }\r
++ else gr->quad_plot(n1,n2,n3,n4);\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_region(HMGL gr, HCDT y1, HCDT y2, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(y1->GetNx()); x.Fill(gr->Min.x, gr->Max.x);\r
++ mgl_region_xy(gr,&x,y1,y2,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_region_3d_(uintptr_t *gr, uintptr_t *x1, uintptr_t *y1, uintptr_t *z1, uintptr_t *x2, uintptr_t *y2, uintptr_t *z2, const char *pen, const char *opt, int l, int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_region_3d(_GR_, _DA_(x1),_DA_(y1),_DA_(z1),_DA_(x2),_DA_(y2),_DA_(z2),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_region_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt, int l, int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_region_xy(_GR_, _DA_(x),_DA_(y1),_DA_(y2),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_region_(uintptr_t *gr, uintptr_t *y1, uintptr_t *y2, const char *pen, const char *opt, int l, int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_region(_GR_, _DA_(y1),_DA_(y2),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Step series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_step_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
++{\r
++ long m,n=y->GetNx(), pal;\r
++ if(mgl_check_dim1(gr,x,y,z,0,"Step")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Step3",cgid++);\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m;\r
++ bool sh = mglchr(pen,'!');\r
++\r
++ char mk=gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m);\r
++ int d = gr->MeshNum>0 ? gr->MeshNum+1 : n, dx = n>d?n/d:1;\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
++ gr->NextColor(pal);\r
++ long n1 = gr->AddPnt(mglPoint(x->v(0,mx), y->v(0,my), z->v(0,mz)));\r
++ if(mk) gr->mark_plot(n1,mk);\r
++ for(long i=1;i<n;i++)\r
++ {\r
++ long n2 = n1; // horizontal\r
++ mglPoint p(x->v(i,mx), y->v(i,my), z->v(i-1,mz));\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ n1 = gr->AddPnt(p,c); gr->line_plot(n1,n2);\r
++ if(i==1) gr->arrow_plot(n2,n1,gr->Arrow1);\r
++\r
++ n2 = n1; // vertical\r
++ p.z = z->v(i,mz); n1 = gr->AddPnt(p,c);\r
++ if(mk && i%dx==0) gr->mark_plot(n1,mk);\r
++ gr->line_plot(n1,n2);\r
++ if(i==n-1) gr->arrow_plot(n1,n2,gr->Arrow2);\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_step_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
++{\r
++ long m,n=y->GetNx(), pal;\r
++ if(mgl_check_dim1(gr,x,y,0,0,"Step",true)) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Step",cgid++);\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();\r
++ bool sh = mglchr(pen,'!');\r
++ bool same = x->GetNx()==n;\r
++\r
++ mreal zVal =gr->AdjustZMin();\r
++ char mk=gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m);\r
++ int d = gr->MeshNum>0 ? gr->MeshNum+1 : n, dx = n>d?n/d:1;\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
++ gr->NextColor(pal);\r
++ mreal xx = x->v(0,mx);\r
++ long n1 = gr->AddPnt(mglPoint(same?xx:(xx+x->v(1,mx))/2, y->v(0,my), zVal));\r
++ if(mk) gr->mark_plot(n1,mk);\r
++ if(!same) n1 = gr->AddPnt(mglPoint(xx, y->v(0,my), zVal));\r
++ for(long i=1;i<n;i++)\r
++ {\r
++ long n2 = n1; // horizontal\r
++ xx = x->v(i,mx);\r
++<<<<<<< HEAD\r
++ p.Set(xx, y->v(i-1,my), zVal);\r
++=======\r
++ mglPoint p(xx, y->v(i-1,my), zVal);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ n1 = gr->AddPnt(p,c); gr->line_plot(n1,n2);\r
++ if(i==1) gr->arrow_plot(n2,n1,gr->Arrow1);\r
++\r
++ n2 = n1; // vertical\r
++ p.y = y->v(i,my); n1 = gr->AddPnt(p,c);\r
++ gr->line_plot(n1,n2);\r
++ if(same && i==n-1) gr->arrow_plot(n1,n2,gr->Arrow2);\r
++ long nn = n1;\r
++ if(!same) nn = gr->AddPnt(mglPoint((xx+x->v(i+1,mx))/2, y->v(i,my), zVal));\r
++<<<<<<< HEAD\r
++ if(mk) gr->mark_plot(nn,mk);\r
++ }\r
++ if(!same)\r
++ {\r
++ p.Set(x->v(n,mx), y->v(n-1,my), zVal);\r
++=======\r
++ if(mk && i%dx==0) gr->mark_plot(nn,mk);\r
++ }\r
++ if(!same)\r
++ {\r
++ mglPoint p(x->v(n,mx), y->v(n-1,my), zVal);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ mreal c = sh ? gr->NextColor(pal,n-1):gr->CDef;\r
++ long n2 = gr->AddPnt(p,c); gr->line_plot(n1,n2);\r
++ gr->arrow_plot(n2,n1,gr->Arrow2);\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_step(HMGL gr, HCDT y, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(y->GetNx()); x.Fill(gr->Min.x,gr->Max.x);\r
++ mgl_step_xy(gr,&x,y,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_step_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_step_xyz(_GR_, _DA_(x),_DA_(y),_DA_(z),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_step_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_step_xy(_GR_, _DA_(x),_DA_(y),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_step_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_step(_GR_, _DA_(y),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Stem series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_stem_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
++{\r
++ long m,n=y->GetNx(), pal;\r
++ if(mgl_check_dim0(gr,x,y,z,0,"Stem")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Stem3",cgid++);\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m;\r
++ bool sh = mglchr(pen,'!');\r
++\r
++ mreal z0=gr->GetOrgZ('x');\r
++ char mk=gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m);\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
++ gr->NextColor(pal);\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ long n1 = gr->AddPnt(mglPoint(x->v(i,mx), y->v(i,my), z->v(i,mz)),c);\r
++ if(mk) gr->mark_plot(n1,mk);\r
++ long n2 = gr->AddPnt(mglPoint(x->v(i,mx), y->v(i,my), z0),c);\r
++ gr->line_plot(n1,n2);\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_stem_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
++{\r
++ long m,n=y->GetNx(), pal;\r
++ if(mgl_check_dim0(gr,x,y,0,0,"Stem")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Stem",cgid++);\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();\r
++ bool sh = mglchr(pen,'!');\r
++\r
++ mreal zVal = gr->AdjustZMin(), y0=gr->GetOrgY('x');\r
++ char mk=gr->SetPenPal(pen,&pal); gr->Reserve(2*n*m);\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
++ gr->NextColor(pal);\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mreal vv = x->v(i,mx);\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ long n1 = gr->AddPnt(mglPoint(vv, y->v(i,my), zVal),c);\r
++ if(mk) gr->mark_plot(n1,mk);\r
++ long n2 = gr->AddPnt(mglPoint(vv, y0, zVal),c);\r
++ gr->line_plot(n1,n2);\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_stem(HMGL gr, HCDT y, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(y->GetNx()); x.Fill(gr->Min.x,gr->Max.x);\r
++ mgl_stem_xy(gr,&x,y,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_stem_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_stem_xyz(_GR_,_DA_(x),_DA_(y),_DA_(z),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_stem_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_stem_xy(_GR_,_DA_(x),_DA_(y),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_stem_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_stem(_GR_,_DA_(y),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Bars series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_bars_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
++{\r
++ long m,n=z->GetNx(), pal,nx=x->GetNx(),ny=y->GetNx();\r
++ if(mgl_check_dim1(gr,x,z,y,0,"Bars",true)) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Bars3",cgid++);\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();\r
++ m = z->GetNy() > m ? z->GetNy() : m;\r
++ bool sh = mglchr(pen,'!');\r
++\r
++ bool wire = mglchr(pen,'#'), fixed = mglchr(pen,'F');\r
++ bool above = mglchr(pen,'a'), fall = mglchr(pen,'f');\r
++ if(above) fall = false;\r
++ mreal c1,c2;\r
++ mreal *dd=new mreal[n], z0,zp,dv=nx>n?1:0;\r
++ if(mglchr(pen,'<')) dv = 1;\r
++ if(mglchr(pen,'^')) dv = 0;\r
++ if(mglchr(pen,'>')) dv = -1;\r
++ memset(dd,0,n*sizeof(mreal));\r
++\r
++ mreal dc=INFINITY;\r
++ if(fixed) for(long j=0;j<m;j++)\r
++ {\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
++ for(long i=0;i<n-1;i++)\r
++ {\r
++ mreal cx = hypot(x->v(i+1,mx)-x->v(i,mx), y->v(i+1,my)-y->v(i,my));\r
++ if(cx<dc) dc=cx;\r
++ }\r
++ }\r
++ if(dc==0) fixed=false; // NOTE: disable fixed width if it is zero\r
++\r
++ gr->SetPenPal(pen,&pal);\r
++ gr->Reserve(4*n*m);\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ c2=c1=gr->NextColor(pal);\r
++ if(gr->GetNumPal(pal)==2*m && !sh) c2 = gr->NextColor(pal);\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
++ zp = z0 = gr->GetOrgZ('x');\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ if(sh) c2=c1=gr->NextColor(pal,i);\r
++ mreal vv = x->v(i,mx), dx = i<nx-1 ? x->v(i+1,mx)-vv : vv-x->v(i-1,mx), dy, zz;\r
++ vv = y->v(i,my); dy = i<ny-1 ? y->v(i+1,my)-vv : vv-y->v(i-1,my);\r
++ if(fixed)\r
++ { mreal ff = dc/hypot(dx,dy); dx *= ff; dy *= ff; }\r
++ mreal x1 = vv + dx/2*(dv-gr->BarWidth), x2 = x1 + gr->BarWidth*dx;\r
++ mreal y1 = vv + dy/2*(dv-gr->BarWidth), y2 = y1 + gr->BarWidth*dy;\r
++ vv = zz = z->v(i,mz);\r
++ if(!above)\r
++ {\r
++ x2 = (x2-x1)/m; x1 += j*x2; x2 += x1;\r
++ y2 = (y2-y1)/m; y1 += j*y2; y2 += y1;\r
++ }\r
++ else\r
++ { z0 = gr->GetOrgZ('x') + dd[i]; dd[i] += zz; zz += z0; }\r
++ if(fall) { z0 = zp; zz += z0; zp = zz; }\r
++\r
++ mreal c = vv<0 ? c1 : c2;\r
++ mglPoint nn(-y->dvx(i,my),x->dvx(i,mx));\r
++ long n1 = gr->AddPnt(mglPoint(x1,y1,zz),c,nn);\r
++ long n2 = gr->AddPnt(mglPoint(x1,y1,z0),c,nn);\r
++ long n3 = gr->AddPnt(mglPoint(x2,y2,z0),c,nn);\r
++ long n4 = gr->AddPnt(mglPoint(x2,y2,zz),c,nn);\r
++ if(wire)\r
++ {\r
++ gr->line_plot(n1,n2); gr->line_plot(n1,n4);\r
++ gr->line_plot(n3,n2); gr->line_plot(n3,n4);\r
++ }\r
++ else gr->quad_plot(n1,n2,n4,n3);\r
++ }\r
++ }\r
++ gr->EndGroup(); delete []dd;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_bars_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
++{\r
++ long m,n=y->GetNx(),nx=x->GetNx(),pal;\r
++ if(mgl_check_dim1(gr,x,y,0,0,"Bars",true)) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Bars",cgid++);\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();\r
++ bool sh = mglchr(pen,'!');\r
++\r
++ bool wire = mglchr(pen,'#'), fixed = mglchr(pen,'F');\r
++ bool above = mglchr(pen,'a'), fall = mglchr(pen,'f');\r
++ if(above) fall = false;\r
++ mreal c1,c2;\r
++ mreal *dd=new mreal[n], y0,yp,dv=nx>n?1:0;\r
++ if(mglchr(pen,'<')) dv = 1;\r
++ if(mglchr(pen,'^')) dv = 0;\r
++ if(mglchr(pen,'>')) dv = -1;\r
++ mreal zm = gr->AdjustZMin();\r
++ memset(dd,0,n*sizeof(mreal));\r
++\r
++ mreal dx=INFINITY;\r
++ if(fixed)\r
++ {\r
++ long nn=x->GetNy();\r
++ for(long j=0;j<nn;j++) for(long i=0;i<n-1;i++)\r
++ {\r
++ mreal cx = fabs(x->v(i+1,j)-x->v(i,j));\r
++ if(cx<dx) dx=cx;\r
++ }\r
++ }\r
++ if(dx==0) fixed=false; // NOTE: disable fixed width if it is zero\r
++\r
++ gr->SetPenPal(pen,&pal);\r
++ gr->Reserve(4*n*m);\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ c2=c1=gr->NextColor(pal);\r
++ if(gr->GetNumPal(pal)==2*m && !sh) c2 = gr->NextColor(pal);\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
++ yp = y0 = gr->GetOrgY('x');\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ if(sh) c2=c1=gr->NextColor(pal,i);\r
++ mreal vv = x->v(i,mx), d = i<nx-1 ? x->v(i+1,mx)-vv : vv-x->v(i-1,mx), yy;\r
++ if(fixed) d = dx;\r
++ mreal x1 = vv + d/2*(dv-gr->BarWidth), x2 = x1 + gr->BarWidth*d;\r
++ vv = yy = y->v(i,my);\r
++ if(!above)\r
++ { x2 = (x2-x1)/m; x1 += j*x2; x2 += x1; }\r
++ else\r
++ { y0 = gr->GetOrgY('x') + dd[i]; dd[i] += yy; yy += y0; }\r
++ if(fall) { y0 = yp; yy += y0; yp = yy; }\r
++\r
++ mreal c = vv<0 ? c1 : c2;\r
++ long n1 = gr->AddPnt(mglPoint(x1,yy,zm),c);\r
++ long n2 = gr->AddPnt(mglPoint(x1,y0,zm),c);\r
++ long n3 = gr->AddPnt(mglPoint(x2,y0,zm),c);\r
++ long n4 = gr->AddPnt(mglPoint(x2,yy,zm),c);\r
++ if(wire)\r
++ {\r
++ gr->line_plot(n1,n2); gr->line_plot(n1,n4);\r
++ gr->line_plot(n3,n2); gr->line_plot(n3,n4);\r
++ }\r
++ else gr->quad_plot(n1,n2,n4,n3);\r
++ }\r
++ }\r
++ gr->EndGroup(); delete []dd;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_bars(HMGL gr, HCDT y, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(y->GetNx()+1); x.Fill(gr->Min.x,gr->Max.x);\r
++ mgl_bars_xy(gr,&x,y,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_bars_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_bars_xyz(_GR_,_DA_(x),_DA_(y),_DA_(z),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_bars_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_bars_xy(_GR_,_DA_(x),_DA_(y),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_bars_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_bars(_GR_,_DA_(y),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Barh series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_barh_yx(HMGL gr, HCDT y, HCDT v, const char *pen, const char *opt)\r
++{\r
++ long m,n=v->GetNx(),ny=y->GetNx(),pal;\r
++ if(mgl_check_dim1(gr,y,v,0,0,"Barh",true)) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Barh",cgid++);\r
++ m = y->GetNy() > v->GetNy() ? y->GetNy() : v->GetNy();\r
++ bool sh = mglchr(pen,'!');\r
++\r
++ bool wire = mglchr(pen,'#'), fixed = mglchr(pen,'F');\r
++ bool above = mglchr(pen,'a'), fall = mglchr(pen,'f');\r
++ if(above) fall = false;\r
++ mreal *dd=new mreal[n], x0,xp,dv=ny>n?1:0;\r
++ if(mglchr(pen,'<')) dv = 1;\r
++ if(mglchr(pen,'^')) dv = 0;\r
++ if(mglchr(pen,'>')) dv = -1;\r
++ mreal zm = gr->AdjustZMin();\r
++ memset(dd,0,n*sizeof(mreal));\r
++\r
++ mreal dy=INFINITY;\r
++ if(fixed)\r
++ {\r
++ long nn=y->GetNy();\r
++ for(long j=0;j<nn;j++) for(long i=0;i<n-1;i++)\r
++ {\r
++ mreal cx = fabs(y->v(i+1,j)-y->v(i,j));\r
++ if(cx<dy) dy=cx;\r
++ }\r
++ }\r
++ if(dy==0) fixed=false; // NOTE: disable fixed width if it is zero\r
++\r
++ gr->SetPenPal(pen,&pal);\r
++ gr->Reserve(4*n*m);\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ mreal c1,c2; c2=c1=gr->NextColor(pal);\r
++ if(gr->GetNumPal(pal)==2*m && !sh) c2 = gr->NextColor(pal);\r
++ long mx = j<v->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
++ xp = x0 = gr->GetOrgX('y');\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ if(sh) c2=c1=gr->NextColor(pal,i);\r
++ mreal vv = y->v(i,my), d = i<ny-1 ? y->v(i+1,my)-vv : vv-y->v(i-1,my), xx;\r
++ if(fixed) d = dy;\r
++ mreal y1 = vv + d/2*(dv-gr->BarWidth), y2 = y1 + gr->BarWidth*d;\r
++ vv = xx = v->v(i,mx);\r
++ if(!above)\r
++ { y2 = (y2-y1)/m; y1 += j*y2; y2 += y1; }\r
++ else\r
++ { x0 = gr->GetOrgX('y') + dd[i]; dd[i] += xx; xx += x0; }\r
++ if(fall) { x0 = xp; xx += x0; xp = xx; }\r
++\r
++ mreal c = vv<0 ? c1 : c2;\r
++ long n1 = gr->AddPnt(mglPoint(xx,y1,zm),c);\r
++ long n2 = gr->AddPnt(mglPoint(xx,y2,zm),c);\r
++ long n3 = gr->AddPnt(mglPoint(x0,y2,zm),c);\r
++ long n4 = gr->AddPnt(mglPoint(x0,y1,zm),c);\r
++ if(wire)\r
++ {\r
++ gr->line_plot(n1,n2); gr->line_plot(n1,n4);\r
++ gr->line_plot(n3,n2); gr->line_plot(n3,n4);\r
++ }\r
++ else gr->quad_plot(n1,n2,n4,n3);\r
++ }\r
++ }\r
++ gr->EndGroup(); delete []dd;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_barh(HMGL gr, HCDT v, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV y(v->GetNx()+1); y.Fill(gr->Min.y,gr->Max.y);\r
++ mgl_barh_yx(gr,&y,v,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_barh_yx_(uintptr_t *gr, uintptr_t *y, uintptr_t *v, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_barh_yx(_GR_,_DA_(y),_DA_(v),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_barh_(uintptr_t *gr, uintptr_t *v, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_barh(_GR_,_DA_(v),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// OHLC series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_ohlc_x(HMGL gr, HCDT x, HCDT open, HCDT high, HCDT low, HCDT close, const char *pen, const char *opt)\r
++{\r
++ long n=open->GetNx(), nx=x->GetNx(), m=open->GetNy(), mx;\r
++ if(nx<n || n*m!=high->GetNx()*high->GetNy() || n*m!=low->GetNx()*low->GetNy() || n*m!=close->GetNx()*close->GetNy())\r
++ { gr->SetWarn(mglWarnDim,"OHLC"); return; }\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("OHLC",cgid++);\r
++ mreal dv=nx>n?1:0;\r
++ if(mglchr(pen,'<')) dv = 1;\r
++ if(mglchr(pen,'^')) dv = 0;\r
++ if(mglchr(pen,'>')) dv = -1;\r
++ mreal zVal = gr->AdjustZMin();\r
++ bool sh = mglchr(pen,'!');\r
++\r
++ long pal;\r
++ gr->SetPenPal(pen,&pal); gr->Reserve(6*n*m);\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ mreal c1,c2; c2=c1=gr->NextColor(pal);\r
++ if(gr->GetNumPal(pal)==2*m && !sh) c2 = gr->NextColor(pal);\r
++ mx = j<x->GetNy() ? j:0;\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mreal dd,vv,x1,x2;\r
++ vv = x->v(i,mx); dd = i<nx-1 ? x->v(i+1)-vv : vv-x->v(i-1);\r
++ x1 = vv + dd/2*(dv-gr->BarWidth); x2 = x1 + gr->BarWidth*dd;\r
++ x2 = (x2-x1)/m; x1 += j*x2; x2 += x1; vv = (x2+x1)/2;\r
++ if(sh) c1=c2=gr->NextColor(pal,i);\r
++ long n1,n2;\r
++\r
++ dd = close->v(i,j);\r
++ mreal c = (i==0 || dd>=close->v(i-1,j)) ? c1:c2;\r
++ n1=gr->AddPnt(mglPoint(vv,dd,zVal),c);\r
++ n2=gr->AddPnt(mglPoint(x2,dd,zVal),c);\r
++ gr->line_plot(n1,n2);\r
++ dd = open->v(i,j);\r
++ n1=gr->AddPnt(mglPoint(x1,dd,zVal),c);\r
++ n2=gr->AddPnt(mglPoint(vv,dd,zVal),c);\r
++ gr->line_plot(n1,n2);\r
++ n1=gr->AddPnt(mglPoint(vv,low->v(i,j),zVal),c);\r
++ n2=gr->AddPnt(mglPoint(vv,high->v(i,j),zVal),c);\r
++ gr->line_plot(n1,n2);\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_ohlc(HMGL gr, HCDT open, HCDT high, HCDT low, HCDT close, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(open->GetNx()+1); x.Fill(gr->Min.x,gr->Max.x);\r
++ mgl_ohlc_x(gr,&x,open,high,low,close,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_ohlc_x_(uintptr_t *gr, uintptr_t *x, uintptr_t *open, uintptr_t *high, uintptr_t *low, uintptr_t *close, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_ohlc_x(_GR_,_DA_(x),_DA_(open),_DA_(high),_DA_(low),_DA_(close),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_ohlc_(uintptr_t *gr, uintptr_t *open, uintptr_t *high, uintptr_t *low, uintptr_t *close, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_ohlc(_GR_,_DA_(open),_DA_(high),_DA_(low),_DA_(close),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// BoxPlot series\r
++//\r
++//-----------------------------------------------------------------------------\r
++double sgn(double a);\r
++int MGL_NO_EXPORT mgl_cmp_flt(const void *a, const void *b)\r
++{\r
++ const mreal *aa = (const mreal *)a;\r
++ const mreal *bb = (const mreal *)b;\r
++ return int(sgn(*aa-*bb));\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_boxplot_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
++{\r
++ long n=y->GetNx(), m=y->GetNy(), nx=x->GetNx();\r
++ if(nx<n || nx<2 || m<2) { gr->SetWarn(mglWarnDim,"BoxPlot"); return; }\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("BoxPlot",cgid++);\r
++ mreal *b = new mreal[5*n], x1, x2, dd, dv=nx>n?1:0;\r
++ if(mglchr(pen,'<')) dv = 1;\r
++ if(mglchr(pen,'^')) dv = 0;\r
++ if(mglchr(pen,'>')) dv = -1;\r
++ mreal zVal = gr->AdjustZMin(), vv;\r
++ bool sh = mglchr(pen,'!');\r
++ mreal *d = new mreal[m];\r
++ for(long i=0;i<n;i++) // find quartiles by itself\r
++ {\r
++ long mm=0,k;\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ mreal vv = y->v(i,j);\r
++ if(mgl_isnum(vv)) { d[mm]=vv; mm++; }\r
++ }\r
++// if(m==0) { b[i]=NAN; break; }\r
++ qsort(d, mm, sizeof(mreal), mgl_cmp_flt);\r
++ b[i] = d[0]; b[i+4*n] = d[mm-1]; k = mm/4;\r
++ b[i+n] = (mm%4) ? d[k] : (d[k]+d[k-1])/2.;\r
++ b[i+2*n] = (mm%2) ? d[mm/2] : (d[mm/2]+d[mm/2-1])/2.;\r
++ b[i+3*n] = (mm%4) ? d[mm-k-1] : (d[mm-k-1]+d[mm-k])/2.;\r
++ }\r
++ delete []d;\r
++\r
++ long pal;\r
++ gr->SetPenPal(pen,&pal); gr->NextColor(pal); gr->Reserve(18*n);\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ vv = x->v(i);\r
++ dd = i<nx-1 ? x->v(i+1)-vv : vv-x->v(i-1);\r
++ x1 = vv + dd/2*(dv-gr->BarWidth);\r
++ x2 = x1 + gr->BarWidth*dd;\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ long n1,n2;\r
++\r
++ n1=gr->AddPnt(mglPoint(x1,b[i],zVal),c); // horizontal lines\r
++ n2=gr->AddPnt(mglPoint(x2,b[i],zVal),c);\r
++ gr->line_plot(n1,n2);\r
++ n1=gr->AddPnt(mglPoint(x1,b[i+n],zVal),c);\r
++ n2=gr->AddPnt(mglPoint(x2,b[i+n],zVal),c);\r
++ gr->line_plot(n1,n2);\r
++ n1=gr->AddPnt(mglPoint(x1,b[i+2*n],zVal),c);\r
++ n2=gr->AddPnt(mglPoint(x2,b[i+2*n],zVal),c);\r
++ gr->line_plot(n1,n2);\r
++ n1=gr->AddPnt(mglPoint(x1,b[i+3*n],zVal),c);\r
++ n2=gr->AddPnt(mglPoint(x2,b[i+3*n],zVal),c);\r
++ gr->line_plot(n1,n2);\r
++ n1=gr->AddPnt(mglPoint(x1,b[i+4*n],zVal),c);\r
++ n2=gr->AddPnt(mglPoint(x2,b[i+4*n],zVal),c);\r
++ gr->line_plot(n1,n2);\r
++\r
++ //vertical lines\r
++ n1=gr->AddPnt(mglPoint(x1,b[i+n],zVal),c);\r
++ n2=gr->AddPnt(mglPoint(x1,b[i+3*n],zVal),c);\r
++ gr->line_plot(n1,n2);\r
++ n1=gr->AddPnt(mglPoint(x2,b[i+n],zVal),c);\r
++ n2=gr->AddPnt(mglPoint(x2,b[i+3*n],zVal),c);\r
++ gr->line_plot(n1,n2);\r
++ n1=gr->AddPnt(mglPoint((x1+x2)/2,b[i],zVal),c);\r
++ n2=gr->AddPnt(mglPoint((x1+x2)/2,b[i+n],zVal),c);\r
++ gr->line_plot(n1,n2);\r
++ n1=gr->AddPnt(mglPoint((x1+x2)/2,b[i+3*n],zVal),c);\r
++ n2=gr->AddPnt(mglPoint((x1+x2)/2,b[i+4*n],zVal),c);\r
++ gr->line_plot(n1,n2);\r
++ }\r
++ delete []b; gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_boxplot(HMGL gr, HCDT y, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(y->GetNx()+1); x.Fill(gr->Min.x,gr->Max.x);\r
++ mgl_boxplot_xy(gr,&x,y,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_boxplot_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_boxplot_xy(_GR_,_DA_(x),_DA_(y),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_boxplot_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_boxplot(_GR_,_DA_(y),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Error series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_error_exy(HMGL gr, HCDT x, HCDT y, HCDT ex, HCDT ey, const char *pen, const char *opt)\r
++{\r
++ long m,n=ey->GetNx(),pal;\r
++ if(mgl_check_dim0(gr,x,y,ey,ex,"Error")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Error",cgid++);\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();\r
++ m = ex->GetNy() > m ? ex->GetNy() : m;\r
++ m = ey->GetNy() > m ? ey->GetNy() : m;\r
++ bool sh = mglchr(pen,'!');\r
++\r
++ bool ma = mglchr(pen,'@');\r
++ char mk = gr->SetPenPal(pen,&pal);\r
++ mreal zVal=gr->AdjustZMin();\r
++ gr->Reserve(5*n*m);\r
++ if(ma && (mk==0 || !strchr("PXsSdD+xoOC",mk) )) mk = 'S';\r
++ gr->ResetMask();\r
++ mglPoint q(NAN,NAN);\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
++ long m1 = j<ex->GetNy() ? j:0,m2 = j<ey->GetNy() ? j:0;\r
++ gr->NextColor(pal);\r
++ if(ma)\r
++ {\r
++ if(strchr("PXsS",mk)) for(long i=0;i<n;i++) // boundary of square\r
++ {\r
++ mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ long n1 = gr->AddPnt(mglPoint(vx-ve, vy+vf, zVal),c,q,-1,27);\r
++ long n2 = gr->AddPnt(mglPoint(vx-ve, vy-vf, zVal),c,q,-1,27);\r
++ long n3 = gr->AddPnt(mglPoint(vx+ve, vy+vf, zVal),c,q,-1,27);\r
++ long n4 = gr->AddPnt(mglPoint(vx+ve, vy-vf, zVal),c,q,-1,27);\r
++ gr->line_plot(n1,n2); gr->line_plot(n1,n3);\r
++ gr->line_plot(n4,n2); gr->line_plot(n4,n3);\r
++ }\r
++ if(strchr("dD",mk)) for(long i=0;i<n;i++) // boundary of rhomb\r
++ {\r
++ mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,27);\r
++ long n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),c,q,-1,27);\r
++ long n3 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,27);\r
++ long n4 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),c,q,-1,27);\r
++ gr->line_plot(n1,n2); gr->line_plot(n2,n3);\r
++ gr->line_plot(n3,n4); gr->line_plot(n4,n1);\r
++ }\r
++ if(strchr("oOC",mk)) for(long i=0;i<n;i++) // circle\r
++ {\r
++ mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ long n1,n2,k;\r
++ for(k=0,n2=-1;k<=40;k++)\r
++ {\r
++ n1 = n2;\r
++ n2 = gr->AddPnt(mglPoint(vx+ve*mgl_cos[(18*k)%360],\r
++ vy+vf*mgl_cos[(270+18*k)%360], zVal),c,q,-1,27);\r
++ if(k>0) gr->line_plot(n1,n2);\r
++ }\r
++ }\r
++ switch(mk)\r
++ {\r
++ case 'P': case '+':\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,27);\r
++ long n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),c,q,-1,27);\r
++ long n3 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,27);\r
++ long n4 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),c,q,-1,27);\r
++ gr->line_plot(n1,n3); gr->line_plot(n2,n4);\r
++ } break;\r
++ case 'X': case 'x':\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ long n1 = gr->AddPnt(mglPoint(vx-ve, vy+vf, zVal),c,q,-1,27);\r
++ long n2 = gr->AddPnt(mglPoint(vx-ve, vy-vf, zVal),c,q,-1,27);\r
++ long n3 = gr->AddPnt(mglPoint(vx+ve, vy+vf, zVal),c,q,-1,27);\r
++ long n4 = gr->AddPnt(mglPoint(vx+ve, vy-vf, zVal),c,q,-1,27);\r
++ gr->line_plot(n1,n4); gr->line_plot(n2,n3);\r
++ } break;\r
++ case 'S':\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ long n1 = gr->AddPnt(mglPoint(vx-ve, vy+vf, zVal),c,q,-1,27);\r
++ long n2 = gr->AddPnt(mglPoint(vx-ve, vy-vf, zVal),c,q,-1,27);\r
++ long n3 = gr->AddPnt(mglPoint(vx+ve, vy+vf, zVal),c,q,-1,27);\r
++ long n4 = gr->AddPnt(mglPoint(vx+ve, vy-vf, zVal),c,q,-1,27);\r
++ gr->quad_plot(n1,n2,n3,n4);\r
++ } break;\r
++ case 'D':\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,27);\r
++ long n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),c,q,-1,27);\r
++ long n3 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,27);\r
++ long n4 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),c,q,-1,27);\r
++ gr->quad_plot(n1,n4,n2,n3);\r
++ } break;\r
++ case 'O':\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ long n1, n2, n3 = gr->AddPnt(mglPoint(vx,vy,zVal),c),k;\r
++ for(k=0,n2=-1;k<=40;k++)\r
++ {\r
++ n1 = n2;\r
++ n2 = gr->AddPnt(mglPoint(vx+ve*mgl_cos[(18*k)%360],\r
++ vy+vf*mgl_cos[(270+18*k)%360], zVal),c,q,-1,27);\r
++ if(k>0) gr->trig_plot(n1,n2,n3);\r
++ }\r
++ } break;\r
++ case 'C':\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ gr->mark_plot(gr->AddPnt(mglPoint(x->v(i,mx),y->v(i,my),zVal),-1,q,-1,3), '.');\r
++ if(sh) gr->NextColor(pal);\r
++ }\r
++ }\r
++ }\r
++ else for(long i=0;i<n;i++)\r
++ {\r
++ mreal vx=x->v(i,mx), ve=ex->v(i,m1), vy=y->v(i,my), vf=ey->v(i,m2);\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ if(mk) gr->mark_plot(gr->AddPnt(mglPoint(vx,vy,zVal),c), mk);\r
++\r
++ long n1 = gr->AddPnt(mglPoint(vx, vy+vf, zVal),c,q,-1,27);\r
++ long n2 = gr->AddPnt(mglPoint(vx, vy-vf, zVal),c,q,-1,27);\r
++ gr->line_plot(n1,n2); gr->arrow_plot(n1,n2,'I'); gr->arrow_plot(n2,n1,'I');\r
++\r
++ n1 = gr->AddPnt(mglPoint(vx+ve, vy, zVal),-1,q,c,27);\r
++ n2 = gr->AddPnt(mglPoint(vx-ve, vy, zVal),-1,q,c,27);\r
++ gr->line_plot(n1,n2); gr->arrow_plot(n1,n2,'I'); gr->arrow_plot(n2,n1,'I');\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_error_xy(HMGL gr, HCDT x, HCDT y, HCDT ey, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV ex(y->GetNx()); ex.Fill(NAN);\r
++ mgl_error_exy(gr,x,y,&ex,ey,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_error(HMGL gr, HCDT y, HCDT ey, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(y->GetNx()), ex(y->GetNx());\r
++ x.Fill(gr->Min.x,gr->Max.x); ex.Fill(NAN);\r
++ mgl_error_exy(gr,&x,y,&ex,ey,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_error_(uintptr_t *gr, uintptr_t *y, uintptr_t *ey, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_error(_GR_,_DA_(y),_DA_(ey),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_error_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ey, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_error_xy(_GR_,_DA_(x),_DA_(y),_DA_(ey),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_error_exy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ex, uintptr_t *ey, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_error_exy(_GR_,_DA_(x),_DA_(y),_DA_(ex),_DA_(ey),s,o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Chart series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void face_plot(mglBase *gr, mglPoint o, mglPoint d1, mglPoint d2, mreal c, bool wire)\r
++{\r
++ const int num=10;\r
++ mglPoint nn=d1^d2;\r
++ d1 = d1/num; d2 = d2/num;\r
++ long n=num+1, *id=new long[n*n];\r
++ gr->Reserve(n*n);\r
++ for(long j=0;j<n;j++) for(long i=0;i<n;i++)\r
++ id[i+n*j] = gr->AddPnt(o+d1*i+d2*j,c,nn);\r
++ for(long j=0;j<num;j++) for(long i=0;i<num;i++)\r
++ {\r
++ long *ii = id+i+n*j;\r
++ gr->quad_plot(ii[0],ii[1],ii[n],ii[n+1]);\r
++ }\r
++ if(wire)\r
++ {\r
++ gr->Reserve(4*n); gr->SetPenPal("k-");\r
++ long *jj=id+n+1;\r
++ jj[0] = jj[1] = gr->CopyNtoC(id[0],gr->CDef);\r
++ jj[2] = jj[3] = gr->CopyNtoC(id[n*n-1],gr->CDef);\r
++ for(long i=1;i<n;i++)\r
++ {\r
++ memcpy(jj+4,jj,4*sizeof(long));\r
++ jj[0] = gr->CopyNtoC(id[i],gr->CDef);\r
++ jj[1] = gr->CopyNtoC(id[n*i],gr->CDef);\r
++ jj[2] = gr->CopyNtoC(id[n*n-1-i],gr->CDef);\r
++ jj[3] = gr->CopyNtoC(id[n*n-1-n*i],gr->CDef);\r
++ gr->line_plot(jj[4],jj[0]);\r
++ gr->line_plot(jj[5],jj[1]);\r
++ gr->line_plot(jj[6],jj[2]);\r
++ gr->line_plot(jj[7],jj[3]);\r
++ }\r
++ }\r
++ delete []id;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_chart(HMGL gr, HCDT a, const char *cols, const char *opt)\r
++{\r
++ if(a->Minimal()<0) { gr->SetWarn(mglWarnNeg,"Chart"); return; }\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Chart",cgid++);\r
++ bool wire = mglchr(cols,'#'); // draw edges\r
++ long n=a->GetNx(),i,j=0,len=cols?long(strlen(cols)):0;\r
++ if(cols) for(i=0;i<len;i++)\r
++ if(strchr(MGL_COLORS,cols[i]) || cols[i]==' ') j++;\r
++ if(j==0) { cols = MGL_DEF_PAL; len=long(strlen(cols)); }\r
++ mreal *c = new mreal[len+1],cc;\r
++ long nc=0; // number of colors\r
++ for(i=0;i<len;i++)\r
++ if(strchr(MGL_COLORS,cols[i]) || cols[i]==' ')\r
++ { c[nc]=gr->AddTexture(cols[i]); nc++; }\r
++ // NOTE: nc>0 since j>0 or MGL_DEF_PAL is not empty\r
++\r
++ mreal dy = (gr->Max.y-gr->Min.y)/a->GetNy(), dx, ss, cs, x1, y1, dz=gr->Max.z-gr->Min.z, vv;\r
++ mglPoint d1,d2,o;\r
++\r
++ for(j=0;j<a->GetNy();j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ y1 = gr->Min.y + dy*j;\r
++ for(i=0,ss=0;i<n;i++) ss += a->v(i,j);\r
++ if(ss==0) continue;\r
++ for(cs=0,i=0;i<n;i++)\r
++ {\r
++ vv = a->v(i,j); dx = vv/ss; cc = c[i%nc];\r
++ if(dx==0) continue;\r
++ x1 = gr->Min.x + (gr->Max.x-gr->Min.x)*cs/ss; dx *= (gr->Max.x-gr->Min.x);\r
++ if(cc>=0)\r
++ {\r
++ face_plot(gr,mglPoint(x1,y1,gr->Min.z),mglPoint(dx,0,0),mglPoint(0,0,dz),cc,wire);\r
++ face_plot(gr,mglPoint(x1,y1,gr->Min.z),mglPoint(dx,0,0),mglPoint(0,dy,0),cc,wire);\r
++ face_plot(gr,mglPoint(x1,y1,gr->Min.z),mglPoint(0,dy,0),mglPoint(0,0,dz),cc,wire);\r
++\r
++ face_plot(gr,mglPoint(x1+dx,y1+dy,gr->Max.z),mglPoint(-dx,0,0),mglPoint(0,0,-dz),cc,wire);\r
++ face_plot(gr,mglPoint(x1+dx,y1+dy,gr->Max.z),mglPoint(-dx,0,0),mglPoint(0,-dy,0),cc,wire);\r
++ face_plot(gr,mglPoint(x1+dx,y1+dy,gr->Max.z),mglPoint(0,-dy,0),mglPoint(0,0,-dz),cc,wire);\r
++ }\r
++ cs += vv;\r
++ }\r
++ }\r
++ gr->EndGroup(); delete []c;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_chart_(uintptr_t *gr, uintptr_t *a, const char *col, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,col,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_chart(_GR_, _DA_(a), s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Mark series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_mark_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt)\r
++{\r
++ long m,n=y->GetNx(),pal;\r
++ if(mgl_check_dim0(gr,x,y,z,r,"Mark")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Mark",cgid++);\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();\r
++ m = z->GetNy() > m ? z->GetNy() : m;\r
++ char mk=gr->SetPenPal(pen,&pal); gr->Reserve(n*m);\r
++ if(mk==0) mk='.';\r
++ bool sh = mglchr(pen,'!');\r
++\r
++ int d = gr->MeshNum>0 ? gr->MeshNum+1 : n, dx = n>d?n/d:1;\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ gr->NextColor(pal);\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
++ long mz = j<z->GetNy() ? j:0, mr = j<r->GetNy() ? j:0;\r
++ for(long i=0;i<n;i+=dx)\r
++ {\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ gr->mark_plot(gr->AddPnt(mglPoint(x->v(i,mx),y->v(i,my),z->v(i,mz)),c), mk, fabs(r->v(i,mr)));\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_mark_xy(HMGL gr, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
++ mgl_mark_xyz(gr,x,y,&z,r,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_mark_y(HMGL gr, HCDT y, HCDT r, const char *pen, const char *opt)\r
++{\r
++ long n=y->GetNx();\r
++ gr->SaveState(opt);\r
++ mglDataV x(n), z(n);\r
++ x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin());\r
++ mgl_mark_xyz(gr,&x,y,&z,r,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_mark_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_mark_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(r),s,o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_mark_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_mark_xy(_GR_, _DA_(x), _DA_(y), _DA_(r),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_mark_y_(uintptr_t *gr, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_mark_y(_GR_,_DA_(y),_DA_(r),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Tube series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tube_xyzr(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt)\r
++{\r
++ long m,n=y->GetNx(),pal;\r
++ if(mgl_check_dim1(gr,x,y,z,r,"Tube")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Tube",cgid++);\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();\r
++ m = z->GetNy() > m ? z->GetNy() : m;\r
++ m = r->GetNy() > m ? r->GetNy() : m;\r
++ bool sh = mglchr(pen,'!');\r
++ bool wire = mglchr(pen,'#');\r
++\r
++ int num=!(gr->GetQuality()&3)?13:25;\r
++ gr->SetPenPal(pen,&pal);\r
++ gr->Reserve(n*m*num);\r
++ mglPoint p,l,t,u,q,d;\r
++ long *nn=new long[2*num];\r
++ memset(nn,-1,2*num*sizeof(long));\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ gr->NextColor(pal);\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
++ long mz = j<z->GetNy() ? j:0, mr = j<r->GetNy() ? j:0;\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ l.Set(x->dvx(i,mx),y->dvx(i,my),z->dvx(i,mz));\r
++ t = !l; t.Normalize(); u = t^l; u.Normalize();\r
++ q.Set(x->v(i,mx),y->v(i,my),z->v(i,mz));\r
++ mreal rr=r->v(i,mr), dr=r->dvx(i,mr);\r
++ mreal c = sh ? gr->NextColor(pal,i):gr->CDef;\r
++ for(long k=0;k<num;k++)\r
++ {\r
++ int kk = k*360/(num-1);\r
++ float co = mgl_cos[(kk)%360], si = mgl_cos[(270+kk)%360];\r
++ p = q + t*(rr*co) + u*(rr*si);\r
++ d = (t*si - u*co)^(l + t*(dr*co) + u*(dr*si));\r
++ nn[k+num]=nn[k]; nn[k] = gr->AddPnt(p,c,wire?mglPoint(NAN,NAN):d,-1,3);\r
++ if(i*k>0 && !wire) gr->quad_plot(nn[k],nn[k-1],nn[k+num],nn[k+num-1]);\r
++ if(i*k>0 && wire && k%4==0) gr->line_plot(nn[k],nn[k+num]);\r
++ if(k>0 && wire) gr->line_plot(nn[k],nn[k-1]);\r
++ }\r
++ }\r
++ }\r
++ delete []nn; gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tube_xyr(HMGL gr, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
++ mgl_tube_xyzr(gr,x,y,&z,r,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tube_r(HMGL gr, HCDT y, HCDT r, const char *pen, const char *opt)\r
++{\r
++ long n=y->GetNx();\r
++ if(n<2) { gr->SetWarn(mglWarnLow,"Tube"); return; }\r
++ gr->SaveState(opt);\r
++ mglDataV x(n), z(n);\r
++ x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin());\r
++ mgl_tube_xyzr(gr,&x,y,&z,r,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tube(HMGL gr, HCDT y, double rr, const char *pen, const char *opt)\r
++{\r
++ long n=y->GetNx();\r
++ if(n<2) { gr->SetWarn(mglWarnLow,"Tube"); return; }\r
++ gr->SaveState(opt);\r
++ mglDataV x(n), r(n), z(n);\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ r.Fill(rr); z.Fill(gr->AdjustZMin());\r
++ mgl_tube_xyzr(gr,&x,y,&z,&r,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tube_xy(HMGL gr, HCDT x, HCDT y, double rr, const char *pen, const char *opt)\r
++{\r
++ long n=y->GetNx();\r
++ if(n<2) { gr->SetWarn(mglWarnLow,"Tube"); return; }\r
++ gr->SaveState(opt);\r
++ mglDataV r(n), z(n);\r
++ r.Fill(rr); z.Fill(gr->AdjustZMin());\r
++ mgl_tube_xyzr(gr,x,y,&z,&r,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tube_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, double rr, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV r(y->GetNx()); r.Fill(rr);\r
++ mgl_tube_xyzr(gr,x,y,z,&r,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tube_xyzr_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tube_xyzr(_GR_,_DA_(x),_DA_(y),_DA_(z), _DA_(r),s,o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tube_xyr_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tube_xyr(_GR_,_DA_(x),_DA_(y),_DA_(r),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tube_r_(uintptr_t *gr, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tube_r(_GR_,_DA_(y),_DA_(r),s,o); delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tube_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, mreal *r, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tube_xyz(_GR_,_DA_(x),_DA_(y),_DA_(z),*r,s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tube_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, mreal *r, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tube_xy(_GR_,_DA_(x),_DA_(y),*r,s,o); delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tube_(uintptr_t *gr, uintptr_t *y, mreal *r, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tube(_GR_,_DA_(y),*r,s,o);\r
++ delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Tape series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tape_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, const char *pen, const char *opt)\r
++{\r
++ long m,n=y->GetNx(),pal;\r
++ if(mgl_check_dim1(gr,x,y,z,0,"Tape")) return;\r
++\r
++ static int cgid=1; gr->StartGroup("Tape",cgid++);\r
++ mreal ll, rr = gr->SaveState(opt);\r
++ if(rr==0 || mgl_isnan(rr)) rr = mgl_norm(gr->Max-gr->Min)*gr->BarWidth/25;\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy(); m = z->GetNy() > m ? z->GetNy() : m;\r
++ gr->SetPenPal(pen,&pal); gr->Reserve(4*n*m);\r
++ mglPoint p1,p2,q1,q2,l,nn,qn(NAN,NAN);\r
++ long n1=-1,n2=-1,n3=-1,n4=-1, m1=-1,m2=-1,m3=-1,m4=-1;\r
++ bool sh = mglchr(pen,'!'), xo = mglchr(pen,'x'), zo = mglchr(pen,'z'), wire = mglchr(pen,'#');\r
++ if(!xo && !zo) xo = zo = true;\r
++ mreal c1,c2;\r
++\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ c2=c1=gr->NextColor(pal);\r
++ if(gr->GetNumPal(pal)==2*m && !sh) c2 = gr->NextColor(pal);\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0, mz = j<z->GetNy() ? j:0;\r
++ // initial values for normales\r
++ p2.Set(x->v(0,mx), y->v(0,my), z->v(0,mz));\r
++ l.Set(x->v(1,mx)-p2.x, y->v(1,my)-p2.y, z->v(1,mz)-p2.z); l /= mgl_norm(l);\r
++ q1.Set(-l.y,l.x,0); ll = mgl_norm(q1);\r
++ if(ll) q1 /= ll; else q1.Set(0,1,0);\r
++ q2 = (q1^l);\r
++ if(p2>gr->Min && p2<gr->Max)\r
++ {\r
++ if(xo) { n1 = gr->AddPnt(p2,c1,q2,-1,3); n2 = gr->AddPnt(p2+rr*q1,c1,q2,-1,3); }\r
++ if(zo) { n3 = gr->AddPnt(p2,c2,q1,-1,3); n4 = gr->AddPnt(p2+rr*q2,c2,q1,-1,3); }\r
++ }\r
++ else { n1=n2=n3=n4=-1; }\r
++ for(long i=1;i<n;i++)\r
++ {\r
++ p1 = p2; p2.Set(x->v(i,mx), y->v(i,my), z->v(i,mz));\r
++ l = p2-p1; l /= mgl_norm(l);\r
++ q1 -= l*(l*q1); q1/= mgl_norm(q1); q2 = (q1^l);\r
++ m1 = n1; m2 = n2; m3 = n3; m4 = n4;\r
++ if(sh) c2=c1=gr->NextColor(pal,i);\r
++ if(p2>gr->Min && p2<gr->Max)\r
++ {\r
++ if(xo)\r
++ {\r
++ n1 = gr->AddPnt(p2,c1,wire?qn:q2,-1,3);\r
++ n2 = gr->AddPnt(p2+rr*q1,c1,wire?qn:q2,-1,3);\r
++ if(wire) gr->line_plot(m2,n2);\r
++ else gr->quad_plot(n1,n2,m1,m2);\r
++ }\r
++ if(zo)\r
++ {\r
++ n3 = gr->AddPnt(p2,c2,wire?qn:q1,-1,3);\r
++ n4 = gr->AddPnt(p2+rr*q2,c2,wire?qn:q1,-1,3);\r
++ if(wire) gr->line_plot(m4,n4);\r
++ else gr->quad_plot(n3,n4,m3,m4);\r
++ }\r
++ }\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tape_xy(HMGL gr, HCDT x, HCDT y, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
++ mgl_tape_xyz(gr,x,y,&z,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tape(HMGL gr, HCDT y, const char *pen, const char *opt)\r
++{\r
++ long n=y->GetNx();\r
++ if(n<2) { gr->SetWarn(mglWarnLow,"Plot"); return; }\r
++ gr->SaveState(opt);\r
++ mglDataV x(n), z(n);\r
++ x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin());\r
++ mgl_tape_xyz(gr,&x,y,&z,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tape_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tape_xyz(_GR_, _DA_(x),_DA_(y),_DA_(z),s,o); delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tape_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tape_xy(_GR_, _DA_(x),_DA_(y),s,o); delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_tape_(uintptr_t *gr, uintptr_t *y, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_tape(_GR_, _DA_(y),s,o); delete []s; delete []o; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Pmap series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_pmap_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT r, const char *pen, const char *opt)\r
++{\r
++ long m,n=y->GetNx(),pal;\r
++ if(mgl_check_dim0(gr,x,y,z,r,"Mark")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Mark",cgid++);\r
++ m = x->GetNy() > y->GetNy() ? x->GetNy() : y->GetNy();\r
++ m = z->GetNy() > m ? z->GetNy() : m;\r
++ char mk=gr->SetPenPal(pen,&pal); gr->Reserve(n*m);\r
++ if(mk==0) mk='.';\r
++\r
++ for(long j=0;j<m;j++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ gr->NextColor(pal);\r
++ long mx = j<x->GetNy() ? j:0, my = j<y->GetNy() ? j:0;\r
++ long mz = j<z->GetNy() ? j:0, mr = j<r->GetNy() ? j:0;\r
++ for(long i=0;i<n-1;i++)\r
++ {\r
++ mreal r1=r->v(i,mr), r2 = r->v(i+1,mr);\r
++ if(r1==0) gr->mark_plot(gr->AddPnt(mglPoint(x->v(i,mx),y->v(i,my),z->v(i,mz))), mk);\r
++ if(r1*r2<0)\r
++ {\r
++ mreal d = r1/(r1-r2);\r
++ mglPoint p(x->v(i,mx)*(1-d)+x->v(i+1,mx)*d, y->v(i,my)*(1-d)+y->v(i+1,my)*d, z->v(i,mz)*(1-d)+d*z->v(i+1,mz));\r
++ gr->mark_plot(gr->AddPnt(p), mk);\r
++ }\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_pmap_xy(HMGL gr, HCDT x, HCDT y, HCDT r, const char *pen, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV z(y->GetNx()); z.Fill(gr->AdjustZMin());\r
++ mgl_pmap_xyz(gr,x,y,&z,r,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_pmap(HMGL gr, HCDT y, HCDT r, const char *pen, const char *opt)\r
++{\r
++ long n=y->GetNx();\r
++ gr->SaveState(opt);\r
++ mglDataV x(n), z(n);\r
++ x.Fill(gr->Min.x,gr->Max.x); z.Fill(gr->AdjustZMin());\r
++ mgl_pmap_xyz(gr,&x,y,&z,r,pen,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_pmap_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *r, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_pmap_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(r),s,o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_pmap_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_pmap_xy(_GR_, _DA_(x), _DA_(y), _DA_(r),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_pmap_(uintptr_t *gr, uintptr_t *y, uintptr_t *r, const char *pen, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,pen,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_pmap(_GR_,_DA_(y),_DA_(r),s,o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * vect.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include "mgl2/vect.h"\r
++#include "mgl2/eval.h"\r
++#include "mgl2/data.h"\r
++#include "mgl2/base.h"\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Traj series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_traj_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt)\r
++{\r
++ long n=ax->GetNx(),pal;\r
++ if(mgl_check_dim1(gr,x,z,y,ax,"Traj")) return;\r
++ if(mgl_check_dim1(gr,ax,az,ay,0,"Traj")) return;\r
++\r
++ mreal len=gr->SaveState(opt); if(mgl_isnan(len)) len = 0;\r
++ static int cgid=1; gr->StartGroup("Traj",cgid++);\r
++\r
++ // find maximum\r
++ long m = x->GetNy()>y->GetNy() ? x->GetNy():y->GetNy();\r
++ long i = ax->GetNy()>ay->GetNy() ? ax->GetNy():ay->GetNy();\r
++ long j = z->GetNy()>az->GetNy() ? z->GetNy():az->GetNy();\r
++ if(i>m) m=i;\r
++ if(j>m) m=j;\r
++ gr->SetPenPal(sch,&pal); gr->Reserve(4*n*m);\r
++\r
++ mglPoint p1,p2;\r
++/* for(j=0;j<m;j++) for(i=0;i<n;i++) // find maximal amplitude of vector field\r
++ {\r
++ mx = j<ax->GetNy() ? j:0; my = j<ay->GetNy() ? j:0; mz = j<az->GetNy() ? j:0;\r
++ da = sqrt(ax->v(i,mx)*ax->v(i,mx)+ay->v(i,my)*ay->v(i,my)+az->v(i,mz)*az->v(i,mz));\r
++ xm = xm>da ? xm : da;\r
++ }\r
++ xm = 1./(xm ? sqrt(xm):1);*/\r
++ for(long j=0;j<m;j++) // start prepare arrows\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ gr->NextColor(pal);\r
++ long nx = j<x->GetNy() ? j:0, ny = j<y->GetNy() ? j:0, nz = j<z->GetNy() ? j:0;\r
++ long mx = j<ax->GetNy() ? j:0,my = j<ay->GetNy() ? j:0,mz = j<az->GetNy() ? j:0;\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ p1.Set(x->v(i,nx), y->v(i,ny), z->v(i,nz));\r
++ p2.Set(ax->v(i,mx),ay->v(i,my),az->v(i,mz));\r
++ mreal dd = p2.norm();\r
++ if(len==0)\r
++ {\r
++ mreal dx,dy,dz;\r
++ if(i<n-1)\r
++ { dx=x->v(i+1,nx)-p1.x; dy=y->v(i+1,ny)-p1.y; dz=z->v(i+1,nz)-p1.z; }\r
++ else\r
++ { dx=p1.x-x->v(i-1,nx); dy=p1.y-y->v(i-1,ny); dz=p1.z-z->v(i-1,nz); }\r
++ dd = dd ? sqrt(dx*dx+dy*dy+dz*dz)/dd : 0;\r
++ }\r
++ else dd = len;\r
++ gr->vect_plot(gr->AddPnt(p1), gr->AddPnt(p1+dd*p2,-1,mglPoint(NAN),-1,2),gr->GetArrowSize());\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_traj_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV z(x->GetNx()), az(x->GetNx()); z.Fill(gr->AdjustZMin());\r
++ mgl_traj_xyz(gr,x,y,&z,ax,ay,&az,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_traj_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_traj_xy(_GR_, _DA_(x), _DA_(y), _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_traj_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_traj_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Vect series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_vect_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
++{\r
++ long n=ax->GetNx(),m=ax->GetNy(),l=ax->GetNz();\r
++ if(mgl_check_dim2(gr,x,y,ax,ay,"Vect")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Vect",cgid++);\r
++ bool dot = sch && mglchr(sch,'.');\r
++ bool fix = mglchr(sch,'f');\r
++ bool end = mglchr(sch,'>');\r
++ bool beg = mglchr(sch,'<');\r
++ bool grd = mglchr(sch,'=');\r
++\r
++ long ss = gr->AddTexture(sch);\r
++ gr->Reserve(4*n*m);\r
++ mreal zVal = gr->Min.z;\r
++\r
++ long tx=1,ty=1;\r
++ if(gr->MeshNum>1) { tx=(n-1)/(gr->MeshNum-1); ty=(m-1)/(gr->MeshNum-1); }\r
++ if(tx<1) tx=1;\r
++ if(ty<1) ty=1;\r
++\r
++ mreal xm=0,cm=0,ca=0;\r
++ mreal dm=(fabs(gr->Max.c)+fabs(gr->Min.c))*1e-5;\r
++ // use whole array for determining maximal vectors length\r
++ mglPoint p1,p2,v,d;\r
++\r
++#pragma omp parallel private(p1,p2,v,d)\r
++ {\r
++ mreal xm1=0,cm1=0,xx,c1,c2;\r
++#pragma omp for nowait collapse(3) reduction(+:ca)\r
++ for(long k=0;k<l;k++) for(long j=0;j<m;j+=ty) for(long i=0;i<n;i+=tx)\r
++ {\r
++ d.Set(GetX(x,i,j,k).x, GetY(y,i,j,k).x);\r
++ v.Set(ax->v(i,j,k),ay->v(i,j,k));\r
++ c1 = v.norm(); xm1 = xm1<c1 ? c1:xm1; // handle NAN values\r
++ p1 = i<n-1 ? mglPoint(GetX(x,i+tx,j,k).x, GetY(y,i+tx,j,k).x)-d : d-mglPoint(GetX(x,i-tx,j,k).x, GetY(y,i-tx,j,k).x);\r
++ c1 = fabs(v*p1); xx = p1.norm(); c1 *= xx?1/(xx*xx):0;\r
++ p1 = j<m-1 ? mglPoint(GetX(x,i,j+ty,k).x, GetY(y,i,j+ty,k).x)-d : d-mglPoint(GetX(x,i,j-ty,k).x, GetY(y,i,j-ty,k).x);\r
++ c2 = fabs(v*p1); xx = p1.norm(); c2 *= xx?1/(xx*xx):0;\r
++ c1 = c1<c2 ? c2:c1; ca+=c1; cm1 = cm1<c1 ? c1:cm1;\r
++ }\r
++#pragma omp critical(max_vec)\r
++ {cm = cm<cm1 ? cm1:cm; xm = xm<xm1 ? xm1:xm;}\r
++ }\r
++ ca /= (n*m*l)/(tx*ty);\r
++ xm = xm?1./xm:0; cm = cm?1./cm:0;\r
++\r
++ for(long k=0;k<l;k++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ if(ax->GetNz()>1) zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(ax->GetNz()-1);\r
++ for(long j=0;j<m;j+=ty) for(long i=0;i<n;i+=tx)\r
++ {\r
++ d.Set(GetX(x,i,j,k).x, GetY(y,i,j,k).x, zVal);\r
++ v.Set(ax->v(i,j,k),ay->v(i,j,k));\r
++ mreal dd = v.norm(), c1, c2;\r
++ v *= cm*(fix?(dd>dm ? 1./dd : 0) : xm);\r
++\r
++ if(end) { p1 = d-v; p2 = d; }\r
++ else if(beg) { p1 = d; p2 = d+v; }\r
++ else { p1=d-v/2.; p2=d+v/2.; }\r
++ if(grd) { c1=gr->GetC(ss,dd*xm-0.5,false); c2=gr->GetC(ss,dd*xm,false);}\r
++ else c1 = c2 = gr->GetC(ss,dd*xm,false);\r
++ long n1=gr->AddPnt(p1,c1), n2=gr->AddPnt(p2,c2);\r
++ // allow vectors outside bounding box\r
++ if(n1<0 && n2>=0) n1=gr->AddPnt(p1,c1,mglPoint(NAN),-1,2);\r
++ if(n2<0 && n1>=0) n2=gr->AddPnt(p2,c2,mglPoint(NAN),-1,2);\r
++ if(dot) { gr->line_plot(n1,n2); gr->mark_plot(n1,'.'); }\r
++ else gr->vect_plot(n1,n2,gr->GetArrowSize());\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_vect_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(ax->GetNx()), y(ax->GetNy());\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ mgl_vect_xy(gr,&x,&y,ax,ay,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_vect_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_vect_xy(_GR_, _DA_(x), _DA_(y), _DA_(ax), _DA_(ay), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_vect_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_vect_2d(_GR_, _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Vect3 series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_vect_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt)\r
++{\r
++ long n=ax->GetNx(),m=ax->GetNy(),l=ax->GetNz();\r
++ if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"Vect_3d")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Vect_3d",cgid++);\r
++ bool dot = mglchr(sch,'.');\r
++ bool fix = mglchr(sch,'f');\r
++ bool end = mglchr(sch,'>');\r
++ bool beg = mglchr(sch,'<');\r
++ bool grd = mglchr(sch,'=');\r
++\r
++ long ss = gr->AddTexture(sch);\r
++ gr->Reserve(2*n*m*l);\r
++ long tx=1,ty=1,tz=1;\r
++ if(gr->MeshNum>1)\r
++ { tx=(n-1)/(gr->MeshNum-1); ty=(m-1)/(gr->MeshNum-1); tz=(l-1)/(gr->MeshNum-1);}\r
++ if(tx<1) tx=1;\r
++ if(ty<1) ty=1;\r
++ if(tz<1) tz=1;\r
++\r
++ mreal xm=0,cm=0,ca=0;\r
++ mreal dm=(fabs(gr->Max.c)+fabs(gr->Min.c))*1e-5;\r
++ // use whole array for determining maximal vectors length\r
++ mglPoint p1,p2, v, d;\r
++\r
++#pragma omp parallel private(p1,p2,v,d)\r
++ {\r
++ mreal c1,c2,c3, xm1=0,cm1=0,xx;\r
++#pragma omp for nowait collapse(3) reduction(+:ca)\r
++ for(long k=0;k<l;k+=tz) for(long i=0;i<n;i+=tx) for(long j=0;j<m;j+=ty)\r
++ {\r
++ d.Set(GetX(x,i,j,k).x, GetY(y,i,j,k).x, GetZ(z,i,j,k).x);\r
++ v.Set(ax->v(i,j,k),ay->v(i,j,k),az->v(i,j,k));\r
++ c1 = v.norm(); xm1 = xm1<c1 ? c1:xm1; // handle NAN values\r
++ p1 = i<n-1 ? mglPoint(GetX(x,i+tx,j,k).x, GetY(y,i+tx,j,k).x, GetZ(z,i+tx,j,k).x)-d : d-mglPoint(GetX(x,i-tx,j,k).x, GetY(y,i-tx,j,k).x, GetZ(z,i-tx,j,k).x);\r
++ c1 = fabs(v*p1); xx = p1.norm(); c1 *= xx?1/(xx*xx):0;\r
++ p1 = j<m-1 ? mglPoint(GetX(x,i,j+ty,k).x, GetY(y,i,j+ty,k).x, GetZ(z,i,j+ty,k).x)-d : d-mglPoint(GetX(x,i,j-ty,k).x, GetY(y,i,j-ty,k).x, GetZ(z,i,j-ty,k).x);\r
++ c2 = fabs(v*p1); xx = p1.norm(); c2 *= xx?1/(xx*xx):0;\r
++ p1 = k<l-1 ? mglPoint(GetX(x,i,j,k+tz).x, GetY(y,i,j,k+tz).x, GetZ(z,i,j,k+tz).x)-d : d-mglPoint(GetX(x,i,j,k-tz).x, GetY(y,i,j,k-tz).x, GetZ(z,i,j,k-tz).x);\r
++ c3 = fabs(v*p1); xx = p1.norm(); c3 *= xx?1/(xx*xx):0;\r
++ c1 = c1<c2 ? c2:c1; c1 = c1<c3 ? c3:c1;\r
++ ca+=c1; cm1 = cm1<c1 ? c1:cm1;\r
++ }\r
++#pragma omp critical(max_vec)\r
++ {cm = cm<cm1 ? cm1:cm; xm = xm<xm1 ? xm1:xm;}\r
++ }\r
++ ca /= mreal(n*m*l)/mreal(tx*ty*tz);\r
++ xm = xm?1./xm:0; cm = cm?1./cm:0;\r
++\r
++ for(long k=0;k<l;k+=tz)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ for(long i=0;i<n;i+=tx) for(long j=0;j<m;j+=ty)\r
++ {\r
++ d.Set(GetX(x,i,j,k).x, GetY(y,i,j,k).x, GetZ(z,i,j,k).x);\r
++ v.Set(ax->v(i,j,k),ay->v(i,j,k),az->v(i,j,k));\r
++ mreal dd = v.norm(),c1,c2;\r
++ v *= cm*(fix?(dd>dm ? 1./dd : 0) : xm);\r
++\r
++ if(end) { p1 = d-v; p2 = d; }\r
++ else if(beg) { p1 = d; p2 = d+v; }\r
++ else { p1=d-v/2.; p2=d+v/2.; }\r
++ if(grd) { c1=gr->GetC(ss,dd*xm-0.5,false); c2=gr->GetC(ss,dd*xm,false); }\r
++ else c1 = c2 = gr->GetC(ss,dd*xm,false);\r
++ long n1=gr->AddPnt(p1,c1), n2=gr->AddPnt(p2,c2);\r
++ // allow vectors outside bounding box\r
++ if(n1<0 && n2>=0) n1=gr->AddPnt(p1,c1,mglPoint(NAN),-1,2);\r
++ if(n2<0 && n1>=0) n2=gr->AddPnt(p2,c2,mglPoint(NAN),-1,2);\r
++ if(dot) { gr->line_plot(n1,n2); gr->mark_plot(n1,'.'); }\r
++ else gr->vect_plot(n1,n2,gr->GetArrowSize());\r
++ }\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_vect_3d(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz());\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_vect_xyz(gr,&x,&y,&z,ax,ay,az,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_vect_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_vect_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_vect_3d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_vect_3d(_GR_, _DA_(ax), _DA_(ay), _DA_(az), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Vect3 series\r
++//\r
++//-----------------------------------------------------------------------------\r
++struct _mgl_vec_slice { mglData x,y,z,ax,ay,az; };\r
++//-----------------------------------------------------------------------------\r
++void MGL_NO_EXPORT mgl_get_slice(_mgl_vec_slice &s, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, char dir, mreal d, bool both)\r
++{\r
++ long n=ax->GetNx(),m=ax->GetNy(),l=ax->GetNz(), nx=1,ny=1,p;\r
++\r
++ if(dir=='x') { nx = m; ny = l; if(d<0) d = n/2.; }\r
++ if(dir=='y') { nx = n; ny = l; if(d<0) d = m/2.; }\r
++ if(dir=='z') { nx = n; ny = m; if(d<0) d = l/2.; }\r
++ s.x.Create(nx,ny); s.y.Create(nx,ny); s.z.Create(nx,ny);\r
++ s.ax.Create(nx,ny); s.ay.Create(nx,ny); s.az.Create(nx,ny);\r
++ p = long(d); d -= p;\r
++ if(dir=='x' && p>=n-1) { d+=p-n+2; p=n-2; }\r
++ if(dir=='y' && p>=m-1) { d+=p-m+2.; p=m-2; }\r
++ if(dir=='z' && p>=l-1) { d+=p-l+2; p=l-2; }\r
++\r
++ if(both)\r
++ {\r
++ if(dir=='x')\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ long i0 = i+nx*j;\r
++ s.x.a[i0] = x->v(p,i,j)*(1-d) + x->v(p+1,i,j)*d;\r
++ s.y.a[i0] = y->v(p,i,j)*(1-d) + y->v(p+1,i,j)*d;\r
++ s.z.a[i0] = z->v(p,i,j)*(1-d) + z->v(p+1,i,j)*d;\r
++ s.ax.a[i0] = ax->v(p,i,j)*(1-d) + ax->v(p+1,i,j)*d;\r
++ s.ay.a[i0] = ay->v(p,i,j)*(1-d) + ay->v(p+1,i,j)*d;\r
++ s.az.a[i0] = az->v(p,i,j)*(1-d) + az->v(p+1,i,j)*d;\r
++ }\r
++ if(dir=='y')\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ long i0 = i+nx*j;\r
++ s.x.a[i0] = x->v(i,p,j)*(1-d) + x->v(i,p+1,j)*d;\r
++ s.y.a[i0] = y->v(i,p,j)*(1-d) + y->v(i,p+1,j)*d;\r
++ s.z.a[i0] = z->v(i,p,j)*(1-d) + z->v(i,p+1,j)*d;\r
++ s.ax.a[i0] = ax->v(i,p,j)*(1-d) + ax->v(i,p+1,j)*d;\r
++ s.ay.a[i0] = ay->v(i,p,j)*(1-d) + ay->v(i,p+1,j)*d;\r
++ s.az.a[i0] = az->v(i,p,j)*(1-d) + az->v(i,p+1,j)*d;\r
++ }\r
++ if(dir=='z')\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ long i0 = i+nx*j;\r
++ s.x.a[i0] = x->v(i,j,p)*(1-d) + x->v(i,j,p+1)*d;\r
++ s.y.a[i0] = y->v(i,j,p)*(1-d) + y->v(i,j,p+1)*d;\r
++ s.z.a[i0] = z->v(i,j,p)*(1-d) + z->v(i,j,p+1)*d;\r
++ s.ax.a[i0] = ax->v(i,j,p)*(1-d) + ax->v(i,j,p+1)*d;\r
++ s.ay.a[i0] = ay->v(i,j,p)*(1-d) + ay->v(i,j,p+1)*d;\r
++ s.az.a[i0] = az->v(i,j,p)*(1-d) + az->v(i,j,p+1)*d;\r
++ }\r
++ }\r
++ else // x, y, z -- vectors\r
++ {\r
++ if(dir=='x')\r
++ {\r
++ mreal v = x->v(p)*(1-d)+x->v(p+1)*d;\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ long i0 = i+nx*j; s.x.a[i0] = v;\r
++ s.y.a[i0] = y->v(i); s.z.a[i0] = z->v(j);\r
++ s.ax.a[i0] = ax->v(p,i,j)*(1-d) + ax->v(p+1,i,j)*d;\r
++ s.ay.a[i0] = ay->v(p,i,j)*(1-d) + ay->v(p+1,i,j)*d;\r
++ s.az.a[i0] = az->v(p,i,j)*(1-d) + az->v(p+1,i,j)*d;\r
++ }\r
++ }\r
++ if(dir=='y')\r
++ {\r
++ mreal v = y->v(p)*(1-d)+y->v(p+1)*d;\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ long i0 = i+nx*j; s.y.a[i0] = v;\r
++ s.x.a[i0] = x->v(i); s.z.a[i0] = z->v(j);\r
++ s.ax.a[i0] = ax->v(i,p,j)*(1-d) + ax->v(i,p+1,j)*d;\r
++ s.ay.a[i0] = ay->v(i,p,j)*(1-d) + ay->v(i,p+1,j)*d;\r
++ s.az.a[i0] = az->v(i,p,j)*(1-d) + az->v(i,p+1,j)*d;\r
++ }\r
++ }\r
++ if(dir=='z')\r
++ {\r
++ mreal v = z->v(p)*(1-d)+z->v(p+1)*d;\r
++#pragma omp parallel for collapse(2)\r
++ for(long j=0;j<ny;j++) for(long i=0;i<nx;i++)\r
++ {\r
++ long i0 = i+nx*j; s.z.a[i0] = v;\r
++ s.x.a[i0] = x->v(i); s.y.a[i0] = y->v(j);\r
++ s.ax.a[i0] = ax->v(i,j,p)*(1-d) + ax->v(i,j,p+1)*d;\r
++ s.ay.a[i0] = ay->v(i,j,p)*(1-d) + ay->v(i,j,p+1)*d;\r
++ s.az.a[i0] = az->v(i,j,p)*(1-d) + az->v(i,j,p+1)*d;\r
++ }\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_vect3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, double sVal, const char *opt)\r
++{\r
++ bool both = mgl_isboth(x,y,z,ax);\r
++ if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"Vect3")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Vect3",cgid++);\r
++ char dir='y';\r
++ if(mglchr(sch,'x')) dir='x';\r
++ if(mglchr(sch,'z')) dir='z';\r
++\r
++ bool dot = mglchr(sch,'.');\r
++ bool fix = mglchr(sch,'f');\r
++ bool end = mglchr(sch,'>');\r
++ bool beg = mglchr(sch,'<');\r
++ bool grd = mglchr(sch,'=');\r
++ long ss = gr->AddTexture(sch);\r
++\r
++ _mgl_vec_slice s;\r
++ mgl_get_slice(s,x,y,z,ax,ay,az,dir,sVal,both);\r
++\r
++ long n=s.ax.nx,m=s.ax.ny, tx=1,ty=1;\r
++ if(gr->MeshNum>1) { tx=(n-1)/(gr->MeshNum-1); ty=(m-1)/(gr->MeshNum-1); }\r
++ if(tx<1) tx=1;\r
++ if(ty<1) ty=1;\r
++ mreal xm=0,cm=0,ca=0;\r
++ mreal dm=(fabs(gr->Max.c)+fabs(gr->Min.c))*1e-5;\r
++ // use whole array for determining maximal vectors length\r
++ mglPoint p1,p2, v, d=(gr->Max-gr->Min)/mglPoint(1./ax->GetNx(),1./ax->GetNy(),1./ax->GetNz());\r
++\r
++ long tn=ty*n;\r
++#pragma omp parallel private(p1,p2,v)\r
++ {\r
++ mreal xm1=0,cm1=0, xx,yy,zz, c1,c2;\r
++#pragma omp for nowait collapse(2) reduction(+:ca)\r
++ for(long i=0;i<n;i+=tx) for(long j=0;j<m;j+=ty)\r
++ {\r
++ long i0 = i+n*j;\r
++ xx = s.x.a[i0]; yy = s.y.a[i0]; zz = s.z.a[i0];\r
++ p1 = i<n-1 ? mglPoint(s.x.a[i0+tx]-xx, s.y.a[i0+tx]-yy, s.z.a[i0+tx]-zz) : mglPoint(xx-s.x.a[i0-tx], yy-s.y.a[i0-tx], zz-s.z.a[i0-tx]);\r
++ p2 = j<m-1 ? mglPoint(s.x.a[i0+tn]-xx, s.y.a[i0+tn]-yy, s.z.a[i0+tn]-zz) : mglPoint(xx-s.x.a[i0-tn], yy-s.y.a[i0-tn], zz-s.z.a[i0-tn]);\r
++ v.Set(s.ax.a[i0], s.ay.a[i0], s.az.a[i0]);\r
++ c1 = v.norm(); xm1 = xm1<c1 ? c1:xm1; // handle NAN values\r
++ yy = fabs(v*d); xx = d.norm(); yy *= xx?1/(xx*xx):0;\r
++ c1 = fabs(v*p1); xx = p1.norm(); c1 *= xx?1/(xx*xx):0;\r
++ c2 = fabs(v*p2); xx = p2.norm(); c2 *= xx?1/(xx*xx):0;\r
++ c1 = c1<c2 ? c2:c1; c1 = c1<yy ? yy:c1;\r
++ ca+=c1; cm1 = cm1<c1 ? c1:cm1;\r
++ }\r
++#pragma omp critical(max_vec)\r
++ {cm = cm<cm1 ? cm1:cm; xm = xm<xm1 ? xm1:xm;}\r
++ }\r
++ ca /= mreal(n*m)/mreal(tx*ty);\r
++ xm = xm?1./xm:0; cm = cm?1./cm:0;\r
++\r
++ for(long i=0;i<n;i+=tx) for(long j=0;j<m;j+=ty)\r
++ {\r
++ long i0 = i+n*j;\r
++ d.Set(s.x.a[i0], s.y.a[i0], s.z.a[i0]);\r
++ v.Set(s.ax.a[i0], s.ay.a[i0], s.az.a[i0]);\r
++ mreal dd = v.norm(),c1,c2;\r
++ v *= cm*(fix?(dd>dm ? 1./dd : 0) : xm);\r
++\r
++ if(end) { p1 = d-v; p2 = d; }\r
++ else if(beg) { p1 = d; p2 = d+v; }\r
++ else { p1=d-v/2.; p2=d+v/2.; }\r
++ if(grd) { c1=gr->GetC(ss,dd*xm-0.5,false); c2=gr->GetC(ss,dd*xm,false);}\r
++ else c1 = c2 = gr->GetC(ss,dd*xm,false);\r
++ long n1=gr->AddPnt(p1,c1), n2=gr->AddPnt(p2,c2);\r
++ // allow vectors outside bounding box\r
++ if(n1<0 && n2>=0) n1=gr->AddPnt(p1,c1,mglPoint(NAN),-1,2);\r
++ if(n2<0 && n1>=0) n2=gr->AddPnt(p2,c2,mglPoint(NAN),-1,2);\r
++ if(dot) { gr->line_plot(n1,n2); gr->mark_plot(n1,'.'); }\r
++ else gr->vect_plot(n1,n2,gr->GetArrowSize());\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_vect3(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, double sVal, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(ax->GetNx()), y(ax->GetNy()),z(ax->GetNz()); // NOTE mglDataV here is useless\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_vect3_xyz(gr,&x,&y,&z,ax,ay,az,sch,sVal,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_vect3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, mreal *sVal, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_vect3_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, *sVal, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_vect3_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, mreal *sVal, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_vect3(_GR_, _DA_(ax), _DA_(ay), _DA_(az), s, *sVal, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Flow 2d series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_NO_EXPORT flow(mglBase *gr, double zVal, double u, double v, HCDT x, HCDT y, HCDT ax, HCDT ay, long ss, bool vv)\r
++{\r
++ long n=100*(ax->GetNx()+ax->GetNy());\r
++ bool nboth = x->GetNx()*x->GetNy()!=ax->GetNx()*ax->GetNy() || y->GetNx()*y->GetNy()!=ax->GetNx()*ax->GetNy();\r
++\r
++ mglPoint *pp = new mglPoint[n], dp;\r
++ mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z));\r
++ mglPoint nx(ax->GetNx(),ax->GetNy());\r
++\r
++ mreal dt = 0.5/(ax->GetNx() > ax->GetNy() ? ax->GetNx() : ax->GetNy());\r
++ mreal e,f,g,ff[4],gg[4],h,s=2,acc=dt/20;\r
++ if(u<0 || v<0) { dt = -dt; u = -u; v = -v; s *= -1;}\r
++ long k=0;\r
++ bool end = false;\r
++ if(nboth) do{\r
++ mglPoint dif;\r
++ pp[k].x = x->Spline1(dif,u,0,0); f = ax->Spline1(u,v,0)/dif.x;\r
++ pp[k].y = y->Spline1(dif,v,0,0); g = ay->Spline1(u,v,0)/dif.x;\r
++ pp[k].z = zVal;\r
++ if(mgl_isbad(f+g)) break;\r
++ else for(long m=0;m<k-1;m+=10) // determines encircle\r
++ if(mgl_anorm((pp[k]-pp[m])/dx)<acc) end = true;\r
++ h = hypot(f,g); pp[k].c = gr->GetC(ss,s*h);\r
++ if(end || h<1e-5) break; // stationary point\r
++ if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++;\r
++ // find next point by midpoint method\r
++ h+=1; ff[0]=f*dt/h; gg[0]=g*dt/h;\r
++ e = u+ff[0]/2; h = v+gg[0]/2;\r
++ x->Spline1(dif,e,0,0); f = ax->Spline1(e,h,0)/dif.x;\r
++ y->Spline1(dif,h,0,0); g = ay->Spline1(e,h,0)/dif.x;\r
++ h = 1+hypot(f,g); ff[1]=f*dt/h; gg[1]=g*dt/h;\r
++ e = u+ff[1]/2; h = v+gg[1]/2;\r
++ x->Spline1(dif,e,0,0); f = ax->Spline1(e,h,0)/dif.x;\r
++ y->Spline1(dif,h,0,0); g = ay->Spline1(e,h,0)/dif.x;\r
++ h = 1+hypot(f,g); ff[2]=f*dt/h; gg[2]=g*dt/h;\r
++ e = u+ff[2]; h = v+gg[2];\r
++ x->Spline1(dif,e,0,0); f = ax->Spline1(e,h,0)/dif.x;\r
++ y->Spline1(dif,h,0,0); g = ay->Spline1(e,h,0)/dif.x;\r
++ h = 1+hypot(f,g); ff[3]=f*dt/h; gg[3]=g*dt/h;\r
++ u += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6;\r
++ v += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6;\r
++ // condition of end\r
++ end = end || k>=n || u<0 || v<0 || u>1 || v>1;\r
++ } while(!end);\r
++ else do{\r
++ mglPoint dif;\r
++<<<<<<< HEAD\r
++ register mreal xu,xv,yu,yv,det,xx,yy;\r
++=======\r
++ mreal xu,xv,yu,yv,det,xx,yy;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ pp[k].x = x->Spline1(dif,u,v,0); xu=dif.x; xv=dif.y;\r
++ pp[k].y = y->Spline1(dif,u,v,0); yu=dif.x; yv=dif.y;\r
++ xx = ax->Spline1(u,v,0); yy = ay->Spline1(u,v,0);\r
++ det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det;\r
++ pp[k].z = zVal;\r
++ if(mgl_isbad(f+g)) break;\r
++ else for(long m=0;m<k-1;m+=10) // determines encircle\r
++ if(mgl_anorm((pp[k]-pp[m])/dx)<acc) end = true;\r
++ h = hypot(f,g); pp[k].c = gr->GetC(ss,s*h);\r
++ if(end || h<1e-5) break; // stationary point\r
++ if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++;\r
++ // find next point by midpoint method\r
++ h+=1; ff[0]=f*dt/h; gg[0]=g*dt/h;\r
++ e = u+ff[0]/2; h = v+gg[0]/2;\r
++ x->Spline1(dif,e,h,0); xu=dif.x; xv=dif.y;\r
++ y->Spline1(dif,e,h,0); yu=dif.x; yv=dif.y;\r
++ xx = ax->Spline1(e,h,0); yy = ay->Spline1(e,h,0);\r
++ det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det;\r
++ h = 1+hypot(f,g); ff[1]=f*dt/h; gg[1]=g*dt/h;\r
++ e = u+ff[1]/2; h = v+gg[1]/2;\r
++ x->Spline1(dif,e,h,0); xu=dif.x; xv=dif.y;\r
++ y->Spline1(dif,e,h,0); yu=dif.x; yv=dif.y;\r
++ xx = ax->Spline1(e,h,0); yy = ay->Spline1(e,h,0);\r
++ det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det;\r
++ h = 1+hypot(f,g); ff[2]=f*dt/h; gg[2]=g*dt/h;\r
++ e = u+ff[2]; h = v+gg[2];\r
++ x->Spline1(dif,e,h,0); xu=dif.x; xv=dif.y;\r
++ y->Spline1(dif,e,h,0); yu=dif.x; yv=dif.y;\r
++ xx = ax->Spline1(e,h,0); yy = ay->Spline1(e,h,0);\r
++ det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det;\r
++ h = 1+hypot(f,g); ff[3]=f*dt/h; gg[3]=g*dt/h;\r
++ u += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6;\r
++ v += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6;\r
++ // condition of end\r
++ end = end || k>=n || u<0 || v<0 || u>1 || v>1;\r
++ } while(!end);\r
++ if(k>1)\r
++ {\r
++ long j,a=long(0.3*gr->GetArrowSize()/fabs(dt));\r
++ gr->Reserve(k); j = gr->AddPnt(pp[0],pp[0].c);\r
++ for(long i=1;i<k;i++)\r
++ {\r
++ long jj=j; j = gr->AddPnt(pp[i],pp[i].c);\r
++ if(vv && i%a==0)\r
++ {\r
++ if(dt<0) gr->vect_plot(j,jj,a/3);\r
++ else gr->vect_plot(jj,j,a/3);\r
++ }\r
++ else gr->line_plot(jj,j);\r
++ }\r
++ }\r
++ delete []pp;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_flow_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
++{\r
++ if(mgl_check_dim2(gr,x,y,ax,ay,"Flow")) return;\r
++\r
++ mreal r = gr->SaveState(opt);\r
++ long num = mgl_isnan(r)?5:long(r+0.5);\r
++ static int cgid=1; gr->StartGroup("Flow",cgid++);\r
++\r
++ long ss = gr->AddTexture(sch);\r
++ bool vv = mglchr(sch,'v');\r
++ // allocate memory\r
++ mreal zVal = gr->Min.z;\r
++ bool cnt=!mglchr(sch,'#');\r
++\r
++ std::vector<mreal> u, v;\r
++ if(mglchr(sch,'*')) for(long i=0;i<num;i++) for(long j=0;j<num;j++)\r
++ {\r
++ mreal t = (i+1.)/(num+1.), s = (j+1.)/(num+1.);\r
++ u.push_back(s); v.push_back(t);\r
++ u.push_back(-s); v.push_back(-t);\r
++ }\r
++ else for(long i=0;i<num;i++)\r
++ {\r
++ mreal t = (i+1.)/(num+1.);\r
++ u.push_back(0); v.push_back(t);\r
++ u.push_back(0); v.push_back(-t);\r
++ u.push_back(1); v.push_back(t);\r
++ u.push_back(-1); v.push_back(-t);\r
++ u.push_back(t); v.push_back(0);\r
++ u.push_back(-t); v.push_back(0);\r
++ u.push_back(t); v.push_back(1);\r
++ u.push_back(-t); v.push_back(-1);\r
++ if(cnt)\r
++ {\r
++ u.push_back(t); v.push_back(0.5);\r
++ u.push_back(-t); v.push_back(-0.5);\r
++ u.push_back(0.5); v.push_back(t);\r
++ u.push_back(-0.5); v.push_back(-t);\r
++ }\r
++ }\r
++ for(long k=0;k<ax->GetNz();k++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ if(ax->GetNz()>1) zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(ax->GetNz()-1);\r
++ HMDT bx=mgl_data_subdata(ax,-1,-1,k), by=mgl_data_subdata(ay,-1,-1,k);\r
++#pragma omp parallel for\r
++ for(long i=0;i<long(u.size());i++) if(!gr->NeedStop())\r
++ flow(gr, zVal, u[i], v[i], x, y, bx, by,ss,vv);\r
++ mgl_delete_data(bx); mgl_delete_data(by);\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_flow_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(ax->GetNx()), y(ax->GetNy()); // NOTE mglDataV here is useless\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ mgl_flow_xy(gr,&x,&y,ax,ay,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_flow_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_flow_xy(_GR_, _DA_(x), _DA_(y), _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; }\r
++void MGL_EXPORT mgl_flow_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_flow_2d(_GR_, _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_flowp_xy(HMGL gr, double x0, double y0, double z0, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
++{\r
++ if(mgl_isnan(z0)) z0 = gr->Min.z;\r
++ mreal u,v;\r
++ long n=ax->GetNx(), m=ax->GetNy();\r
++ bool nboth = x->GetNx()*x->GetNy()!=n*m || y->GetNx()*y->GetNy()!=n*m;\r
++ if(mgl_check_dim2(gr,x,y,ax,ay,"FlowP")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("FlowP",cgid++);\r
++\r
++ long ss = gr->AddTexture(sch);\r
++ bool vv = mglchr(sch,'v');\r
++ // find coordinates u, v\r
++ mreal dm=INFINITY;\r
++ long i0=0,j0=0;\r
++ for(long i=0;i<n;i++) for(long j=0;j<m;j++) // first find closest\r
++ {\r
++ mreal d = nboth ? hypot(x->v(i)-x0,y->v(j)-y0) : hypot(x->v(i,j)-x0,y->v(i,j)-y0);\r
++ if(d<dm) { i0=i; j0=j; dm=d; }\r
++ }\r
++ if(dm==0) { u = i0/mreal(n); v = j0/mreal(m); } // we find it\r
++ else\r
++ {\r
++ mreal dxu,dxv,dyu,dyv, dx, dy;\r
++ if(nboth)\r
++ {\r
++ dx = x->v(i0)-x0; dy = y->v(j0)-y0;\r
++ dxu= x->dvx(i0); dyv= y->dvx(j0);\r
++ u = (i0+dx/dxu)/n; v = (j0+dy/dyv)/m;\r
++ }\r
++ else\r
++ {\r
++ dx = x->v(i0,j0)-x0; dy = y->v(i0,j0)-y0;\r
++ dxu= x->dvx(i0,j0); dyu= y->dvx(i0,j0);\r
++ dxv= x->dvy(i0,j0); dyv= y->dvy(i0,j0);\r
++ mreal d = dxv*dyu-dxu*dyv;\r
++ u = (i0+(dxv*dy-dx*dyv)/d)/n;\r
++ v = (j0-(dxu*dy-dx*dyu)/d)/m;\r
++ }\r
++ }\r
++ flow(gr, z0, u, v, x, y, ax, ay,ss,vv);\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_flowp_2d(HMGL gr, double x0, double y0, double z0, HCDT ax, HCDT ay, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(ax->GetNx()), y(ax->GetNy());\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ mgl_flowp_xy(gr,x0,y0,z0,&x,&y,ax,ay,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_flowp_xy_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_flowp_xy(_GR_, *x0,*y0,*z0, _DA_(x), _DA_(y), _DA_(ax), _DA_(ay), s, o); delete []o; delete []s;\r
++}\r
++void MGL_EXPORT mgl_flowp_2d_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, uintptr_t *ax, uintptr_t *ay, const char *sch, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_flowp_2d(_GR_, *x0,*y0,*z0, _DA_(ax), _DA_(ay), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Flow 3d series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void flow(mglBase *gr, double u, double v, double w, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az,long ss,bool vv, bool xo, bool zo)\r
++{\r
++ static long n=100*(ax->GetNx()+ax->GetNy()+ax->GetNz());\r
++ long nn = ax->GetNN();\r
++ bool nboth = x->GetNN()!=nn || y->GetNN()!=nn || z->GetNN()!=nn;\r
++ mglPoint *pp = new mglPoint[n], dp;\r
++ mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z));\r
++ mglPoint nx(ax->GetNx(),ax->GetNy(),ax->GetNz());\r
++\r
++ nn = (ax->GetNx() > ax->GetNy() ? ax->GetNz() : ax->GetNy());\r
++ nn = (nn > ax->GetNz() ? nn : ax->GetNz());\r
++ mreal dt = 0.2/nn, e,f,g,ee[4],ff[4],gg[4],h,s=2,u1,v1,w1,acc=dt/20;\r
++ if(u<0 || v<0 || w<0)\r
++ { dt = -dt; u = -u; v = -v; w = -w; s *= -1;}\r
++ long k=0;\r
++ bool end = false;\r
++ if(nboth) do{\r
++ mglPoint dif;\r
++ pp[k].x = x->Spline1(dif,u,0,0); e = ax->Spline1(u,v,w)/dif.x;\r
++ pp[k].y = y->Spline1(dif,v,0,0); f = ay->Spline1(u,v,w)/dif.x;\r
++ pp[k].z = z->Spline1(dif,w,0,0); g = az->Spline1(u,v,w)/dif.x;\r
++ if(mgl_isbad(e+f+g)) end = true;\r
++ else for(long m=0;m<k-1;m+=10) // determines encircle\r
++ if(mgl_anorm((pp[k]-pp[m])/dx)<acc) end = true;\r
++ if(end) break;\r
++ h = sqrt(e*e+f*f+g*g); pp[k].c = gr->GetC(ss,s*h);\r
++ if(h<1e-5) break; // stationary point\r
++ if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++;\r
++ // find next point by midpoint method\r
++ h+=1; ee[0]=e*dt/h; ff[0]=f*dt/h; gg[0]=g*dt/h;\r
++ u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2;\r
++ x->Spline1(dif,u1,0,0); e = ax->Spline1(u1,v1,w1)/dif.x;\r
++ y->Spline1(dif,v1,0,0); f = ay->Spline1(u1,v1,w1)/dif.x;\r
++ z->Spline1(dif,w1,0,0); g = az->Spline1(u1,v1,w1)/dif.x;\r
++ h = 1+sqrt(e*e+f*f+g*g);\r
++ ee[1]=e*dt/h; ff[1]=f*dt/h; gg[1]=g*dt/h;\r
++ u1 = u+ee[1]/2; v1 = v+ff[1]/2; w1 = w+gg[1]/2;\r
++ x->Spline1(dif,u1,0,0); e = ax->Spline1(u1,v1,w1)/dif.x;\r
++ y->Spline1(dif,v1,0,0); f = ay->Spline1(u1,v1,w1)/dif.x;\r
++ z->Spline1(dif,w1,0,0); g = az->Spline1(u1,v1,w1)/dif.x;\r
++ h = 1+sqrt(e*e+f*f+g*g);\r
++ ee[2]=e*dt/h; ff[2]=f*dt/h; gg[2]=g*dt/h;\r
++ u1 = u+ee[2]; v1 = v+ff[2]; w1 = w+gg[2];\r
++ x->Spline1(dif,u1,0,0); e = ax->Spline1(u1,v1,w1)/dif.x;\r
++ y->Spline1(dif,v1,0,0); f = ay->Spline1(u1,v1,w1)/dif.x;\r
++ z->Spline1(dif,w1,0,0); g = az->Spline1(u1,v1,w1)/dif.x;\r
++ h = 1+sqrt(e*e+f*f+g*g);\r
++ ee[3]=e*dt/h; ff[3]=f*dt/h; gg[3]=g*dt/h;\r
++ u += ee[0]/6+ee[1]/3+ee[2]/3+ee[3]/6;\r
++ v += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6;\r
++ w += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6;\r
++ // condition of end\r
++ end = end || k>=n || u<0 || v<0 || u>1 || v>1 || w<0 || w>1;\r
++ } while(!end);\r
++ else do{\r
++ mglPoint dif;\r
++<<<<<<< HEAD\r
++ register mreal xu,xv,xw,yu,yv,yw,zv,zu,zw,det,xx,yy,zz;\r
++=======\r
++ mreal xu,xv,xw,yu,yv,yw,zv,zu,zw,det,xx,yy,zz;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ pp[k].x = x->Spline1(dif,u,v,w); xu=dif.x; xv=dif.y; xw=dif.z;\r
++ pp[k].y = y->Spline1(dif,u,v,w); yu=dif.x; yv=dif.y; yw=dif.z;\r
++ pp[k].z = z->Spline1(dif,u,v,w); zu=dif.x; zv=dif.y; zw=dif.z;\r
++ xx = ax->Spline1(u,v,w); yy = ay->Spline1(u,v,w); zz = az->Spline1(u,v,w);\r
++ det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu;\r
++ e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det;\r
++ f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det;\r
++ g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det;\r
++ if(mgl_isbad(e+f+g)) end = true;\r
++ else for(long m=0;m<k-1;m+=10) // determines encircle\r
++ if(mgl_anorm((pp[k]-pp[m])/dx)<acc) end = true;\r
++ if(end) break;\r
++ h = sqrt(e*e+f*f+g*g); pp[k].c = gr->GetC(ss,s*h);\r
++ if(h<1e-5) break; // stationary point\r
++ if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++;\r
++ // find next point by midpoint method\r
++ h+=1; ee[0]=e*dt/h; ff[0]=f*dt/h; gg[0]=g*dt/h;\r
++ u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2;\r
++ x->Spline1(dif,u1,v1,w1); xu=dif.x; xv=dif.y; xw=dif.z; xx = ax->Spline1(u1,v1,w1);\r
++ y->Spline1(dif,u1,v1,w1); yu=dif.x; yv=dif.y; yw=dif.z; yy = ay->Spline1(u1,v1,w1);\r
++ z->Spline1(dif,u1,v1,w1); zu=dif.x; zv=dif.y; zw=dif.z; zz = az->Spline1(u1,v1,w1);\r
++ det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu;\r
++ e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det;\r
++ f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det;\r
++ g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det;\r
++ h = 1+sqrt(e*e+f*f+g*g);\r
++ ee[1]=e*dt/h; ff[1]=f*dt/h; gg[1]=g*dt/h;\r
++ u1 = u+ee[1]/2; v1 = v+ff[1]/2; w1 = w+gg[1]/2;\r
++ x->Spline1(dif,u1,v1,w1); xu=dif.x; xv=dif.y; xw=dif.z; xx = ax->Spline1(u1,v1,w1);\r
++ y->Spline1(dif,u1,v1,w1); yu=dif.x; yv=dif.y; yw=dif.z; yy = ay->Spline1(u1,v1,w1);\r
++ z->Spline1(dif,u1,v1,w1); zu=dif.x; zv=dif.y; zw=dif.z; zz = az->Spline1(u1,v1,w1);\r
++ det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu;\r
++ e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det;\r
++ f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det;\r
++ g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det;\r
++ h = 1+sqrt(e*e+f*f+g*g);\r
++ ee[2]=e*dt/h; ff[2]=f*dt/h; gg[2]=g*dt/h;\r
++ u1 = u+ee[2]; v1 = v+ff[2]; w1 = w+gg[2];\r
++ x->Spline1(dif,u1,v1,w1); xu=dif.x; xv=dif.y; xw=dif.z; xx = ax->Spline1(u1,v1,w1);\r
++ y->Spline1(dif,u1,v1,w1); yu=dif.x; yv=dif.y; yw=dif.z; yy = ay->Spline1(u1,v1,w1);\r
++ z->Spline1(dif,u1,v1,w1); zu=dif.x; zv=dif.y; zw=dif.z; zz = az->Spline1(u1,v1,w1);\r
++ det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu;\r
++ e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det;\r
++ f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det;\r
++ g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det;\r
++ h = 1+sqrt(e*e+f*f+g*g);\r
++ ee[3]=e*dt/h; ff[3]=f*dt/h; gg[3]=g*dt/h;\r
++ u += ee[0]/6+ee[1]/3+ee[2]/3+ee[3]/6;\r
++ v += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6;\r
++ w += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6;\r
++ // condition of end\r
++ end = end || k>=n || u<0 || v<0 || u>1 || v>1 || w<0 || w>1;\r
++ } while(!end);\r
++ if(k>1)\r
++ {\r
++ long j,a=long(gr->GetArrowSize()/fabs(dt));\r
++ mreal rr = mgl_anorm(gr->Max-gr->Min)*gr->BarWidth/25, ll;\r
++ mglPoint q1,q2,l;\r
++ long n1=-1,n2=-1,n3=-1,n4=-1;\r
++\r
++ gr->Reserve(4*k); j = gr->AddPnt(pp[0],pp[0].c);\r
++ l = pp[1] - pp[0]; l /= mgl_anorm(l);\r
++ q1.Set(l.y,-l.x,0); ll = mgl_anorm(q1);\r
++ if(ll) q1 /= ll; else q1.Set(0,1,0);\r
++ q2 = q1^l;\r
++ if(xo) { n1 = gr->AddPnt(pp[0],-1,q2); n2 = gr->AddPnt(pp[0]+rr*q1,-1,q2); }\r
++ if(zo) { n3 = gr->AddPnt(pp[0],-1,q1); n4 = gr->AddPnt(pp[0]+rr*q2,-1,q1); }\r
++ for(long i=1;i<k;i++)\r
++ {\r
++ long jj=j; j = gr->AddPnt(pp[i],pp[i].c);\r
++ if(vv && i%a==0)\r
++ {\r
++ if(dt<0) gr->vect_plot(j,jj,a/3);\r
++ else gr->vect_plot(jj,j,a/3);\r
++ }\r
++ else gr->line_plot(jj,j);\r
++ l = pp[i]-pp[i-1]; l /= mgl_anorm(l);\r
++ q1 -= l*(l*q1); q1/= mgl_anorm(q1); q2 = q1^l;\r
++ long m1 = n1, m2 = n2, m3 = n3, m4 = n4;\r
++ if(xo)\r
++ { n1 = gr->AddPnt(pp[i],-1,q2); n2 = gr->AddPnt(pp[i]+rr*q1,-1,q2); gr->quad_plot(n1,n2,m1,m2); }\r
++ if(zo)\r
++ { n3 = gr->AddPnt(pp[i],-1,q1); n4 = gr->AddPnt(pp[i]+rr*q2,-1,q1); gr->quad_plot(n3,n4,m3,m4); }\r
++ }\r
++ }\r
++ delete []pp;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_flow_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt)\r
++{\r
++ if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"Flow3")) return;\r
++\r
++ mreal r = gr->SaveState(opt);\r
++ long num = mgl_isnan(r)?3:long(r+0.5);\r
++ static int cgid=1; gr->StartGroup("Flow3",cgid++);\r
++ bool cnt=!mglchr(sch,'#');\r
++ long ss = gr->AddTexture(sch);\r
++ bool vv = mglchr(sch,'v'), xo = mglchr(sch,'x'), zo = mglchr(sch,'z');\r
++\r
++ std::vector<mreal> u, v, w;\r
++ for(long i=0;i<num;i++) for(long j=0;j<num;j++)\r
++ {\r
++ mreal t = (i+1.)/(num+1.), s = (j+1.)/(num+1.);\r
++ u.push_back(t); v.push_back(s); w.push_back(0);\r
++ u.push_back(-t); v.push_back(-s); w.push_back(0);\r
++ u.push_back(t); v.push_back(s); w.push_back(1);\r
++ u.push_back(-t); v.push_back(-s); w.push_back(-1);\r
++\r
++ u.push_back(t); v.push_back(0); w.push_back(s);\r
++ u.push_back(-t); v.push_back(0); w.push_back(-s);\r
++ u.push_back(t); v.push_back(1); w.push_back(s);\r
++ u.push_back(-t); v.push_back(-1); w.push_back(-s);\r
++\r
++ u.push_back(0); v.push_back(s); w.push_back(t);\r
++ u.push_back(0); v.push_back(-s); w.push_back(-t);\r
++ u.push_back(1); v.push_back(s); w.push_back(t);\r
++ u.push_back(-1); v.push_back(-s); w.push_back(-t);\r
++ if(cnt)\r
++ {\r
++ u.push_back(t); v.push_back(s); w.push_back(0.5);\r
++ u.push_back(-t); v.push_back(-s); w.push_back(-0.5);\r
++ u.push_back(t); v.push_back(0.5); w.push_back(s);\r
++ u.push_back(-t); v.push_back(-0.5); w.push_back(-s);\r
++ u.push_back(0.5); v.push_back(s); w.push_back(t);\r
++ u.push_back(-0.5); v.push_back(-s); w.push_back(-t);\r
++ }\r
++ }\r
++#pragma omp parallel for\r
++ for(long i=0;i<long(u.size());i++) if(!gr->NeedStop())\r
++ flow(gr, u[i], v[i], w[i], x, y, z, ax, ay, az,ss,vv,xo,zo);\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_flow_3d(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz()); // NOTE mglDataV here is useless\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_flow_xyz(gr,&x,&y,&z,ax,ay,az,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_flow_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_flow_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, o); delete []o; delete []s; }\r
++void MGL_EXPORT mgl_flow_3d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_flow_3d(_GR_, _DA_(ax), _DA_(ay), _DA_(az), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_flowp_xyz(HMGL gr, double x0, double y0, double z0, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt)\r
++{\r
++ mglPoint p(x0,y0,z0);\r
++ mreal u,v,w;\r
++ long n=ax->GetNx(),m=ax->GetNy(),l=ax->GetNz();\r
++ bool nboth = !(x->GetNN()==n*m*l && y->GetNN()==n*m*l && z->GetNN()==n*m*l);\r
++ if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"FlowP3")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("FlowP3",cgid++);\r
++ long ss = gr->AddTexture(sch);\r
++ bool vv = mglchr(sch,'v'), xo = mglchr(sch,'x'), zo = mglchr(sch,'z');\r
++\r
++ // find coordinates u, v, w\r
++ mreal dm=INFINITY;\r
++ long i0=0,j0=0,k0=0;\r
++ mreal dx,dy,dz;\r
++ for(long i=0;i<n;i++) for(long j=0;j<m;j++) for(long k=0;k<l;k++) // first find closest\r
++ {\r
++ if(nboth)\r
++ { dx = x->v(i)-p.x; dy = y->v(j)-p.y; dz = x->v(k)-p.z; }\r
++ else\r
++ { dx = x->v(i,j,k)-p.x; dy = y->v(i,j,k)-p.y; dz = x->v(i,j,k)-p.z; }\r
++ mreal d = sqrt(dx*dx+dy*dy+dz*dz);\r
++ if(d<dm) { i0=i; j0=j; k0=k; dm=d; }\r
++ }\r
++ if(dm==0) // we find it\r
++ { u=i0/mreal(n); v=j0/mreal(m); w=k0/mreal(l); }\r
++ else\r
++ {\r
++ mreal dxu,dxv,dxw,dyu,dyv,dyw,dzu,dzv,dzw;\r
++ if(nboth)\r
++ {\r
++ dx = x->v(i0)-p.x; dy = y->v(j0)-p.y; dz = z->v(k0)-p.z;\r
++ dxu= x->dvx(i0); dyv= y->dvx(j0); dzw= z->dvx(k0);\r
++ u = (i0+dx/dxu)/n; v = (j0+dy/dyv)/m; w = (k0+dz/dzw)/m;\r
++ }\r
++ else\r
++ {\r
++ dx = x->v(i0,j0,k0)-p.x; dy = y->v(i0,j0,k0)-p.y; dz = z->v(i0,j0,k0)-p.z;\r
++ dxu= x->dvx(i0,j0,k0); dyu= y->dvx(i0,j0,k0); dzu= z->dvx(i0,j0,k0);\r
++ dxv= x->dvy(i0,j0,k0); dyv= y->dvy(i0,j0,k0); dzv= z->dvy(i0,j0,k0);\r
++ dxw= x->dvz(i0,j0,k0); dyw= y->dvz(i0,j0,k0); dzw= z->dvz(i0,j0,k0);\r
++ mreal d = dxu*(dyw*dzv-dyv*dzw)+dxv*(dyu*dzw-dyw*dzu)+dxw*(dyv*dzu-dyu*dzv);\r
++ u = (i0+(dx*(dyw*dzv-dyv*dzw)+dxv*(dy*dzw-dyw*dz)+dxw*(dyv*dz-dy*dzv))/d)/n;\r
++ v = (j0-(dx*(dyw*dzu-dyu*dzw)+dxu*(dy*dzw-dyw*dz)+dxw*(dyu*dz-dy*dzu))/d)/m;\r
++ w = (i0+(dx*(dyv*dzu-dyu*dzv)+dxu*(dy*dzv-dyv*dz)+dxv*(dyu*dz-dy*dzu))/d)/l;\r
++ }\r
++ }\r
++ flow(gr, u, v, w, x, y, z, ax, ay, az,ss,vv,xo,zo);\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_flowp_3d(HMGL gr, double x0, double y0, double z0, HCDT ax, HCDT ay, HCDT az, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz()); // NOTE mglDataV here is useless\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_flowp_xyz(gr, x0,y0,z0, &x,&y,&z,ax,ay,az,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_flowp_xyz_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_flowp_xyz(_GR_, *x0,*y0,*z0, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, o);\r
++ delete []o; delete []s; }\r
++void MGL_EXPORT mgl_flowp_3d_(uintptr_t *gr, mreal *x0, mreal *y0, mreal *z0, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_flowp_3d(_GR_, *x0,*y0,*z0, _DA_(ax), _DA_(ay), _DA_(az), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Grad series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_grad_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT phi, const char *sch, const char *opt)\r
++{\r
++ mglData ax(phi), ay,az,xx,yy,zz;\r
++ ay.Set(ax); az.Set(ax); xx.Set(ax); yy.Set(ax); zz.Set(ax);\r
++ long n=xx.nx, m=xx.ny, l=xx.nz, nn = n*m*l;\r
++ if(x->GetNN()==nn && y->GetNN()==nn && z->GetNN()==nn)\r
++ { xx.Set(x); yy.Set(y); zz.Set(z); } // nothing to do\r
++ else if(x->GetNx()==n && y->GetNx()==m && z->GetNx()==l)\r
++#pragma omp parallel for collapse(3)\r
++ for(long i=0;i<n;i++) for(long j=0;j<m;j++) for(long k=0;k<l;k++)\r
++ {\r
++ long i0 = i+n*(j+m*k);\r
++ xx.a[i0] = x->v(i); yy.a[i0] = y->v(j); zz.a[i0] = z->v(k);\r
++ }\r
++ else { gr->SetWarn(mglWarnDim,"Grad"); return; }\r
++ ax.Diff(xx,yy,zz); ay.Diff(yy,xx,zz); az.Diff(zz,xx,yy);\r
++ mgl_flow_xyz(gr,&xx,&yy,&zz,&ax,&ay,&az,sch,opt);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_grad_xy(HMGL gr, HCDT x, HCDT y, HCDT phi, const char *sch, const char *opt)\r
++{\r
++ mglData ax(phi), ay,xx,yy;\r
++ ay.Set(ax); xx.Set(ax); yy.Set(ax);\r
++ long n = phi->GetNx(), m=phi->GetNy(), nn=n*m;\r
++ if(x->GetNx()*x->GetNy()==nn && y->GetNx()*y->GetNy()==nn) { xx.Set(x); yy.Set(y); }\r
++ else if(x->GetNx()==n && y->GetNx()==m)\r
++#pragma omp parallel for collapse(2)\r
++ for(long i=0;i<n;i++) for(long j=0;j<m;j++)\r
++ { long i0 = i+n*j; xx.a[i0] = x->v(i); yy.a[i0] = y->v(j); }\r
++ else { gr->SetWarn(mglWarnDim,"Grad"); return; }\r
++ ax.Diff(xx,yy); ay.Diff(yy,xx);\r
++ mgl_flow_xy(gr,&xx,&yy,&ax,&ay,sch,opt);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_grad(HMGL gr, HCDT phi, const char *sch, const char *opt)\r
++{\r
++ mglDataV x(phi->GetNx()), y(phi->GetNy()), z(phi->GetNz());\r
++ gr->SaveState(opt);\r
++ x.Fill(gr->Min.x,gr->Max.x); y.Fill(gr->Min.y,gr->Max.y); z.Fill(gr->Min.z,gr->Max.z);\r
++ if(phi->GetNz()==1) mgl_grad_xy(gr,&x,&y,phi,sch,0);\r
++ else mgl_grad_xyz(gr,&x,&y,&z,phi,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_grad_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ph, const char *sch, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_grad_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ph), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_grad_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ph, const char *sch, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_grad_xy(_GR_, _DA_(x), _DA_(y), _DA_(ph), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_grad_(uintptr_t *gr, uintptr_t *ph, const char *sch, const char *opt, int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_grad(_GR_, _DA_(ph), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Pipe 2d series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_NO_EXPORT flowr(mglBase *gr, double zVal, double u, double v, HCDT x, HCDT y, HCDT ax, HCDT ay, double r0,long sc)\r
++{\r
++ long n=100*(ax->GetNx()+ax->GetNy());\r
++ bool nboth = x->GetNx()*x->GetNy()!=ax->GetNx()*ax->GetNy() || y->GetNx()*y->GetNy()!=ax->GetNx()*ax->GetNy();\r
++\r
++ mglPoint *pp = new mglPoint[n], dp;\r
++ mreal *cc = new mreal[n];\r
++ mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z));\r
++ mglPoint nx(ax->GetNx(),ax->GetNy());\r
++\r
++ mreal dt = 0.5/(ax->GetNx() > ax->GetNy() ? ax->GetNx() : ax->GetNy()),e,f,g,ff[4],gg[4],h,s=2,acc=dt/20;\r
++ mreal ss = 16./mgl_ipow(gr->Max.c - gr->Min.c,2);\r
++ if(u<0 || v<0) { dt = -dt; u = -u; v = -v; s *= -1;}\r
++ long k=0;\r
++ bool end = false;\r
++ if(nboth) do{\r
++ mglPoint dif;\r
++ pp[k].x = x->Spline1(dif,u,0,0); f = ax->Spline1(u,v,0)/dif.x;\r
++ pp[k].y = y->Spline1(dif,v,0,0); g = ay->Spline1(u,v,0)/dif.x;\r
++ pp[k].z = zVal;\r
++ if(mgl_isbad(f+g)) end = true;\r
++ else for(long m=0;m<k-1;m+=10) // determines encircle\r
++ if(mgl_anorm((pp[k]-pp[m])/dx)<acc) end = true;\r
++ if(end) break;\r
++ h = hypot(f,g); cc[k] = gr->GetC(sc,s*h);\r
++ pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5;\r
++ if(h<1e-5) break; // stationary point\r
++ if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++;\r
++ // find next point by midpoint method\r
++ h+=1; ff[0]=f*dt/h; gg[0]=g*dt/h;\r
++ e = u+ff[0]/2; h = v+gg[0]/2;\r
++ x->Spline1(dif,e,0,0); f = ax->Spline1(e,h,0)/dif.x;\r
++ y->Spline1(dif,h,0,0); g = ay->Spline1(e,h,0)/dif.x;\r
++ h = 1+hypot(f,g); ff[1]=f*dt/h; gg[1]=g*dt/h;\r
++ e = u+ff[1]/2; h = v+gg[1]/2;\r
++ x->Spline1(dif,e,0,0); f = ax->Spline1(e,h,0)/dif.x;\r
++ y->Spline1(dif,h,0,0); g = ay->Spline1(e,h,0)/dif.x;\r
++ h = 1+hypot(f,g); ff[2]=f*dt/h; gg[2]=g*dt/h;\r
++ e = u+ff[2]; h = v+gg[2];\r
++ x->Spline1(dif,e,0,0); f = ax->Spline1(e,h,0)/dif.x;\r
++ y->Spline1(dif,h,0,0); g = ay->Spline1(e,h,0)/dif.x;\r
++ h = 1+hypot(f,g); ff[3]=f*dt/h; gg[3]=g*dt/h;\r
++ u += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6;\r
++ v += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6;\r
++ // condition of end\r
++ end = end || k>=n || u<0 || v<0 || u>1 || v>1;\r
++ } while(!end);\r
++ else do{\r
++ mglPoint dif;\r
++<<<<<<< HEAD\r
++ register mreal xu,xv,yu,yv,det,xx,yy;\r
++=======\r
++ mreal xu,xv,yu,yv,det,xx,yy;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ pp[k].x = x->Spline1(dif,u,v,0); xu=dif.x; xv=dif.y;\r
++ pp[k].y = y->Spline1(dif,u,v,0); yu=dif.x; yv=dif.y;\r
++ xx = ax->Spline1(u,v,0); yy = ay->Spline1(u,v,0);\r
++ det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det;\r
++ pp[k].z = zVal;\r
++ if(mgl_isbad(f+g)) end = true;\r
++ else for(long m=0;m<k-1;m+=10) // determines encircle\r
++ if(mgl_anorm((pp[k]-pp[m])/dx)<acc) end = true;\r
++ if(end) break;\r
++ h = hypot(f,g); cc[k] = gr->GetC(sc,s*h);\r
++ pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5;\r
++ if(h<1e-5) break; // stationary point\r
++ if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++;\r
++ // find next point by midpoint method\r
++ h+=1; ff[0]=f*dt/h; gg[0]=g*dt/h;\r
++ e = u+ff[0]/2; h = v+gg[0]/2;\r
++ x->Spline1(dif,e,h,0); xu=dif.x; xv=dif.y;\r
++ y->Spline1(dif,e,h,0); yu=dif.x; yv=dif.y;\r
++ xx = ax->Spline1(e,h,0); yy = ay->Spline1(e,h,0);\r
++ det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det;\r
++ h = 1+hypot(f,g); ff[1]=f*dt/h; gg[1]=g*dt/h;\r
++ e = u+ff[1]/2; h = v+gg[1]/2;\r
++ x->Spline1(dif,e,h,0); xu=dif.x; xv=dif.y;\r
++ y->Spline1(dif,e,h,0); yu=dif.x; yv=dif.y;\r
++ xx = ax->Spline1(e,h,0); yy = ay->Spline1(e,h,0);\r
++ det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det;\r
++ h = 1+hypot(f,g); ff[2]=f*dt/h; gg[2]=g*dt/h;\r
++ e = u+ff[2]; h = v+gg[2];\r
++ x->Spline1(dif,e,h,0); xu=dif.x; xv=dif.y;\r
++ y->Spline1(dif,e,h,0); yu=dif.x; yv=dif.y;\r
++ xx = ax->Spline1(e,h,0); yy = ay->Spline1(e,h,0);\r
++ det = xv*yu-xu*yv; f = (yy*xv-xx*yv)/det; g = (xx*yu-yy*xu)/det;\r
++ h = 1+hypot(f,g); ff[3]=f*dt/h; gg[3]=g*dt/h;\r
++ u += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6;\r
++ v += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6;\r
++ // condition of end\r
++ end = end || k>=n || u<0 || v<0 || u>1 || v>1;\r
++ } while(!end);\r
++ if(k>1)\r
++ {\r
++ int num=!(gr->GetQuality()&3)?13:25;\r
++ long *id=new long[2*num];\r
++ mglPoint p,l=pp[1]-pp[0],t,q,d;\r
++ t = !l; t.Normalize(); q = t^l; q.Normalize();\r
++ mreal rr=pp[0].c,dr=l.c;\r
++ gr->Reserve(num*k);\r
++\r
++ for(long j=0;j<num;j++)\r
++ {\r
++ int fi=j*360/(num-1);\r
++ float co = mgl_cos[fi%360], si = mgl_cos[(270+fi)%360];\r
++ p = pp[0] + t*(rr*co) + q*(rr*si);\r
++ d = (t*si - q*co)^(l + t*(dr*co) + q*(dr*si));\r
++ id[j] = gr->AddPnt(p,cc[0],d);\r
++ }\r
++ for(long i=1;i<k;i++)\r
++ {\r
++ if(i<k-1) l = pp[i+1]-pp[i-1];\r
++ else l = pp[i]-pp[i-1];\r
++ t = !l; t.Normalize(); q = t^l; q.Normalize();\r
++ rr=pp[i].c; dr=l.c;\r
++ memcpy(id+num,id,num*sizeof(long));\r
++ for(long j=0;j<num;j++)\r
++ {\r
++ int fi=j*360/(num-1);\r
++ float co = mgl_cos[fi%360], si = mgl_cos[(270+fi)%360];\r
++ p = pp[i] + t*(rr*co) + q*(rr*si);\r
++ d = (t*si - q*co)^(l + t*(dr*co) + q*(dr*si));\r
++ id[j] = gr->AddPnt(p,cc[i],d);\r
++ if(j>0) gr->quad_plot(id[j-1],id[j],id[j+num-1],id[j+num]);\r
++ }\r
++ }\r
++ delete []id;\r
++ }\r
++ delete []pp; delete []cc;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_pipe_xy(HMGL gr, HCDT x, HCDT y, HCDT ax, HCDT ay, const char *sch, double r0, const char *opt)\r
++{\r
++ if(mgl_check_dim2(gr,x,y,ax,ay,"Pipe")) return;\r
++\r
++ mreal r = gr->SaveState(opt);\r
++ long num = mgl_isnan(r)?5:long(r+0.5);\r
++ static int cgid=1; gr->StartGroup("Pipe",cgid++);\r
++\r
++ long ss = gr->AddTexture(sch);\r
++ // allocate memory\r
++ mreal zVal = gr->Min.z;\r
++ bool cnt=!mglchr(sch,'#');\r
++ if(mglchr(sch,'i')) r0 = -fabs(r0);\r
++\r
++ std::vector<mreal> u, v;\r
++ if(mglchr(sch,'*')) for(long i=0;i<num;i++) for(long j=0;j<num;j++)\r
++ {\r
++ mreal t = (i+1.)/(num+1.), s = (j+1.)/(num+1.);\r
++ u.push_back(s); v.push_back(t);\r
++ u.push_back(-s); v.push_back(-t);\r
++ }\r
++ else for(long i=0;i<num;i++)\r
++ {\r
++ mreal t = (i+1.)/(num+1.);\r
++ u.push_back(0); v.push_back(t);\r
++ u.push_back(0); v.push_back(-t);\r
++ u.push_back(1); v.push_back(t);\r
++ u.push_back(-1); v.push_back(-t);\r
++ u.push_back(t); v.push_back(0);\r
++ u.push_back(-t); v.push_back(0);\r
++ u.push_back(t); v.push_back(1);\r
++ u.push_back(-t); v.push_back(-1);\r
++ if(cnt)\r
++ {\r
++ u.push_back(t); v.push_back(0.5);\r
++ u.push_back(-t); v.push_back(-0.5);\r
++ u.push_back(0.5); v.push_back(t);\r
++ u.push_back(-0.5); v.push_back(-t);\r
++ }\r
++ }\r
++ for(long k=0;k<ax->GetNz();k++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ if(ax->GetNz()>1) zVal = gr->Min.z+(gr->Max.z-gr->Min.z)*mreal(k)/(ax->GetNz()-1);\r
++ HMDT bx=mgl_data_subdata(ax,-1,-1,k), by=mgl_data_subdata(ay,-1,-1,k);\r
++#pragma omp parallel for\r
++ for(long i=0;i<long(u.size());i++) if(!gr->NeedStop())\r
++ flowr(gr, zVal, u[i], v[i], x, y, bx, by,r0,ss);\r
++ mgl_delete_data(bx); mgl_delete_data(by);\r
++ }\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_pipe_2d(HMGL gr, HCDT ax, HCDT ay, const char *sch, double r0, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(ax->GetNx()), y(ax->GetNy()); // NOTE mglDataV here is useless\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ mgl_pipe_xy(gr,&x,&y,ax,ay,sch,r0,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_pipe_xy_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *ax, uintptr_t *ay, const char *sch, mreal *r0, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_pipe_xy(_GR_, _DA_(x), _DA_(y), _DA_(ax), _DA_(ay), s, *r0, o); delete []o; delete []s; }\r
++void MGL_EXPORT mgl_pipe_2d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, const char *sch, mreal *r0, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_pipe_2d(_GR_, _DA_(ax), _DA_(ay), s, *r0, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Pipe 3d series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void flowr(mglBase *gr, double u, double v, double w, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, double r0,long sc)\r
++{\r
++ static long n=100*(ax->GetNx()+ax->GetNy()+ax->GetNz());\r
++ long nn = ax->GetNN();\r
++ bool nboth = x->GetNN()!=nn || y->GetNN()!=nn || z->GetNN()!=nn;\r
++ mglPoint *pp = new mglPoint[n], dp;\r
++ mreal *cc = new mreal[n];\r
++ mglPoint dx(1/fabs(gr->Max.x-gr->Min.x),1/fabs(gr->Max.y-gr->Min.y),1/fabs(gr->Max.z-gr->Min.z));\r
++ mglPoint nx(ax->GetNx(),ax->GetNy(),ax->GetNz());\r
++\r
++ nn = (ax->GetNx() > ax->GetNy() ? ax->GetNx() : ax->GetNy());\r
++ nn = (nn > ax->GetNz() ? nn : ax->GetNz());\r
++ mreal dt = 0.2/nn, e,f,g,ee[4],ff[4],gg[4],h,s=2,u1,v1,w1,acc=dt/20;\r
++ mreal ss = 16./mgl_ipow(gr->Max.c - gr->Min.c,2);\r
++\r
++ if(u<0 || v<0 || w<0)\r
++ { dt = -dt; u = -u; v = -v; w = -w; s *= -1;}\r
++ long k=0;\r
++ bool end = false;\r
++ if(nboth) do{\r
++ mglPoint dif;\r
++ pp[k].x = x->Spline1(dif,u,0,0); e = ax->Spline1(u,v,w)/dif.x;\r
++ pp[k].y = y->Spline1(dif,v,0,0); f = ay->Spline1(u,v,w)/dif.x;\r
++ pp[k].z = z->Spline1(dif,w,0,0); g = az->Spline1(u,v,w)/dif.x;\r
++ if(mgl_isbad(e+f+g)) end = true;\r
++ else for(long m=0;m<k-1;m+=10) // determines encircle\r
++ if(mgl_anorm((pp[k]-pp[m])/dx)<acc) end = true;\r
++ if(end) break;\r
++ h = sqrt(e*e+f*f+g*g); cc[k] = gr->GetC(sc,s*h);\r
++ pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5;\r
++ if(h<1e-5) break; // stationary point\r
++ if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++;\r
++ // find next point by midpoint method\r
++ h+=1; ee[0]=e*dt/h; ff[0]=f*dt/h; gg[0]=g*dt/h;\r
++ u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2;\r
++ x->Spline1(dif,u1,0,0); e = ax->Spline1(u1,v1,w1)/dif.x;\r
++ y->Spline1(dif,v1,0,0); f = ay->Spline1(u1,v1,w1)/dif.x;\r
++ z->Spline1(dif,w1,0,0); g = az->Spline1(u1,v1,w1)/dif.x;\r
++ h = 1+sqrt(e*e+f*f+g*g);\r
++ ee[1]=e*dt/h; ff[1]=f*dt/h; gg[1]=g*dt/h;\r
++ u1 = u+ee[1]/2; v1 = v+ff[1]/2; w1 = w+gg[1]/2;\r
++ x->Spline1(dif,u1,0,0); e = ax->Spline1(u1,v1,w1)/dif.x;\r
++ y->Spline1(dif,v1,0,0); f = ay->Spline1(u1,v1,w1)/dif.x;\r
++ z->Spline1(dif,w1,0,0); g = az->Spline1(u1,v1,w1)/dif.x;\r
++ h = 1+sqrt(e*e+f*f+g*g);\r
++ ee[2]=e*dt/h; ff[2]=f*dt/h; gg[2]=g*dt/h;\r
++ u1 = u+ee[2]; v1 = v+ff[2]; w1 = w+gg[2];\r
++ x->Spline1(dif,u1,0,0); e = ax->Spline1(u1,v1,w1)/dif.x;\r
++ y->Spline1(dif,v1,0,0); f = ay->Spline1(u1,v1,w1)/dif.x;\r
++ z->Spline1(dif,w1,0,0); g = az->Spline1(u1,v1,w1)/dif.x;\r
++ h = 1+sqrt(e*e+f*f+g*g);\r
++ ee[3]=e*dt/h; ff[3]=f*dt/h; gg[3]=g*dt/h;\r
++ u += ee[0]/6+ee[1]/3+ee[2]/3+ee[3]/6;\r
++ v += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6;\r
++ w += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6;\r
++ // condition of end\r
++ end = end || k>=n || u<0 || v<0 || u>1 || v>1 || w<0 || w>1;\r
++ } while(!end);\r
++ else do{\r
++ mglPoint dif;\r
++<<<<<<< HEAD\r
++ register mreal xu,xv,xw,yu,yv,yw,zv,zu,zw,det,xx,yy,zz;\r
++=======\r
++ mreal xu,xv,xw,yu,yv,yw,zv,zu,zw,det,xx,yy,zz;\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ pp[k].x = x->Spline1(dif,u,v,w); xu=dif.x; xv=dif.y; xw=dif.z;\r
++ pp[k].y = y->Spline1(dif,u,v,w); yu=dif.x; yv=dif.y; yw=dif.z;\r
++ pp[k].z = z->Spline1(dif,u,v,w); zu=dif.x; zv=dif.y; zw=dif.z;\r
++ xx = ax->Spline1(u,v,w); yy = ay->Spline1(u,v,w); zz = az->Spline1(u,v,w);\r
++ det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu;\r
++ e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det;\r
++ f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det;\r
++ g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det;\r
++ if(mgl_isbad(e+f+g)) end = true;\r
++ else for(long m=0;m<k-1;m+=10) // determines encircle\r
++ if(mgl_anorm((pp[k]-pp[m])/dx)<acc) end = true;\r
++ if(end) break;\r
++ h = sqrt(e*e+f*f+g*g); cc[k] = gr->GetC(sc,s*h);\r
++ pp[k].c = r0>0 ? r0*sqrt(1e-2+ss*h*h)/2 : -r0/sqrt(1e-2+ss*h*h)/5;\r
++ if(h<1e-5) break; // stationary point\r
++ if(k==0 || mgl_anorm((pp[k]-pp[k-1])/nx)>=1) k++;\r
++ // find next point by midpoint method\r
++ h+=1; ee[0]=e*dt/h; ff[0]=f*dt/h; gg[0]=g*dt/h;\r
++ u1 = u+ee[0]/2; v1 = v+ff[0]/2; w1 = w+gg[0]/2;\r
++ x->Spline1(dif,u1,v1,w1); xu=dif.x; xv=dif.y; xw=dif.z; xx = ax->Spline1(u1,v1,w1);\r
++ y->Spline1(dif,u1,v1,w1); yu=dif.x; yv=dif.y; yw=dif.z; yy = ay->Spline1(u1,v1,w1);\r
++ z->Spline1(dif,u1,v1,w1); zu=dif.x; zv=dif.y; zw=dif.z; zz = az->Spline1(u1,v1,w1);\r
++ det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu;\r
++ e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det;\r
++ f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det;\r
++ g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det;\r
++ h = 1+sqrt(e*e+f*f+g*g);\r
++ ee[1]=e*dt/h; ff[1]=f*dt/h; gg[1]=g*dt/h;\r
++ u1 = u+ee[1]/2; v1 = v+ff[1]/2; w1 = w+gg[1]/2;\r
++ x->Spline1(dif,u1,v1,w1); xu=dif.x; xv=dif.y; xw=dif.z; xx = ax->Spline1(u1,v1,w1);\r
++ y->Spline1(dif,u1,v1,w1); yu=dif.x; yv=dif.y; yw=dif.z; yy = ay->Spline1(u1,v1,w1);\r
++ z->Spline1(dif,u1,v1,w1); zu=dif.x; zv=dif.y; zw=dif.z; zz = az->Spline1(u1,v1,w1);\r
++ det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu;\r
++ e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det;\r
++ f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det;\r
++ g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det;\r
++ h = 1+sqrt(e*e+f*f+g*g);\r
++ ee[2]=e*dt/h; ff[2]=f*dt/h; gg[2]=g*dt/h;\r
++ u1 = u+ee[2]; v1 = v+ff[2]; w1 = w+gg[2];\r
++ x->Spline1(dif,u1,v1,w1); xu=dif.x; xv=dif.y; xw=dif.z; xx = ax->Spline1(u1,v1,w1);\r
++ y->Spline1(dif,u1,v1,w1); yu=dif.x; yv=dif.y; yw=dif.z; yy = ay->Spline1(u1,v1,w1);\r
++ z->Spline1(dif,u1,v1,w1); zu=dif.x; zv=dif.y; zw=dif.z; zz = az->Spline1(u1,v1,w1);\r
++ det = -xu*yv*zw+xv*yu*zw+xu*yw*zv-xw*yu*zv-xv*yw*zu+xw*yv*zu;\r
++ e = (-xv*yw*zz+xw*yv*zz+xv*yy*zw-xx*yv*zw-xw*yy*zv+xx*yw*zv)/det;\r
++ f = (xu*yw*zz-xw*yu*zz-xu*yy*zw+xx*yu*zw+xw*yy*zu-xx*yw*zu)/det;\r
++ g = (-xu*yv*zz+xv*yu*zz+xu*yy*zv-xx*yu*zv-xv*yy*zu+xx*yv*zu)/det;\r
++ h = 1+sqrt(e*e+f*f+g*g);\r
++ ee[3]=e*dt/h; ff[3]=f*dt/h; gg[3]=g*dt/h;\r
++ u += ee[0]/6+ee[1]/3+ee[2]/3+ee[3]/6;\r
++ v += ff[0]/6+ff[1]/3+ff[2]/3+ff[3]/6;\r
++ w += gg[0]/6+gg[1]/3+gg[2]/3+gg[3]/6;\r
++ // condition of end\r
++ end = end || k>=n || u<0 || v<0 || u>1 || v>1 || w<0 || w>1;\r
++ } while(!end);\r
++ if(k>1)\r
++ {\r
++ const int num=24;\r
++ long *id=new long[2*num];\r
++ mglPoint p,l=pp[1]-pp[0],t,q,d;\r
++ t = !l; t.Normalize(); q = t^l; q.Normalize();\r
++ mreal rr=pp[0].c,dr=l.c;\r
++ gr->Reserve(num*k);\r
++\r
++ for(long j=0;j<num;j++)\r
++ {\r
++ int fi=j*360/(num-1);\r
++ float co = mgl_cos[fi%360], si = mgl_cos[(270+fi)%360];\r
++ p = pp[0] + t*(rr*co) + q*(rr*si);\r
++ d = (t*si - q*co)^(l + t*(dr*co) + q*(dr*si));\r
++ id[j] = gr->AddPnt(p,cc[0],d);\r
++ }\r
++ for(long i=1;i<k;i++)\r
++ {\r
++ if(i<k-1) l = pp[i+1]-pp[i-1];\r
++ else l = pp[i]-pp[i-1];\r
++ t = !l; t.Normalize(); q = t^l; q.Normalize();\r
++ rr=pp[i].c; dr=l.c;\r
++ memcpy(id+num,id,num*sizeof(long));\r
++ for(long j=0;j<num;j++)\r
++ {\r
++ int fi=j*360/(num-1);\r
++ float co = mgl_cos[fi%360], si = mgl_cos[(270+fi)%360];\r
++ p = pp[i] + t*(rr*co) + q*(rr*si);\r
++ d = (t*si - q*co)^(l + t*(dr*co) + q*(dr*si));\r
++ id[j] = gr->AddPnt(p,cc[i],d);\r
++ if(j>0) gr->quad_plot(id[j-1],id[j],id[j+num-1],id[j+num]);\r
++ }\r
++ }\r
++ delete []id;\r
++ }\r
++ delete []pp; delete []cc;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_pipe_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT ax, HCDT ay, HCDT az, const char *sch, double r0, const char *opt)\r
++{\r
++ if(mgl_check_vec3(gr,x,y,z,ax,ay,az,"Vect")) return;\r
++\r
++ mreal r = gr->SaveState(opt);\r
++ long num = mgl_isnan(r)?3:long(r+0.5);\r
++ static int cgid=1; gr->StartGroup("Pipe3",cgid++);\r
++ if(mglchr(sch,'i')) r0 = -fabs(r0);\r
++\r
++ long ss = gr->AddTexture(sch);\r
++ bool cnt=!mglchr(sch,'#');\r
++\r
++ std::vector<mreal> u, v, w;\r
++ for(long i=0;i<num;i++) for(long j=0;j<num;j++)\r
++ {\r
++ mreal t = (i+1.)/(num+1.), s = (j+1.)/(num+1.);\r
++ u.push_back(t); v.push_back(s); w.push_back(0);\r
++ u.push_back(-t); v.push_back(-s); w.push_back(0);\r
++ u.push_back(t); v.push_back(s); w.push_back(1);\r
++ u.push_back(-t); v.push_back(-s); w.push_back(-1);\r
++\r
++ u.push_back(t); v.push_back(0); w.push_back(s);\r
++ u.push_back(-t); v.push_back(0); w.push_back(-s);\r
++ u.push_back(t); v.push_back(1); w.push_back(s);\r
++ u.push_back(-t); v.push_back(-1); w.push_back(-s);\r
++\r
++ u.push_back(0); v.push_back(s); w.push_back(t);\r
++ u.push_back(0); v.push_back(-s); w.push_back(-t);\r
++ u.push_back(1); v.push_back(s); w.push_back(t);\r
++ u.push_back(-1); v.push_back(-s); w.push_back(-t);\r
++ if(cnt)\r
++ {\r
++ u.push_back(t); v.push_back(s); w.push_back(0.5);\r
++ u.push_back(-t); v.push_back(-s); w.push_back(-0.5);\r
++ u.push_back(t); v.push_back(0.5); w.push_back(s);\r
++ u.push_back(-t); v.push_back(-0.5); w.push_back(-s);\r
++ u.push_back(0.5); v.push_back(s); w.push_back(t);\r
++ u.push_back(-0.5); v.push_back(-s); w.push_back(-t);\r
++ }\r
++ }\r
++#pragma omp parallel for\r
++ for(long i=0;i<long(u.size());i++) if(!gr->NeedStop())\r
++ flowr(gr, u[i], v[i], w[i], x, y, z, ax, ay, az,r0,ss);\r
++ gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_pipe_3d(HMGL gr, HCDT ax, HCDT ay, HCDT az, const char *sch, double r0, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(ax->GetNx()), y(ax->GetNy()), z(ax->GetNz()); // NOTE mglDataV here is useless\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_pipe_xyz(gr,&x,&y,&z,ax,ay,az,sch,r0,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_pipe_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, mreal *r0, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_pipe_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(ax), _DA_(ay), _DA_(az), s, *r0, o);\r
++ delete []o; delete []s; }\r
++void MGL_EXPORT mgl_pipe_3d_(uintptr_t *gr, uintptr_t *ax, uintptr_t *ay, uintptr_t *az, const char *sch, mreal *r0, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_pipe_3d(_GR_, _DA_(ax), _DA_(ay), _DA_(az), s, *r0, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * surf.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include "mgl2/define.h"\r
++#include "mgl2/volume.h"\r
++#include "mgl2/data.h"\r
++#include "mgl2/eval.h"\r
++#include "mgl2/base.h"\r
++//-----------------------------------------------------------------------------\r
++//\r
++// CloudQ series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cloud_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
++{\r
++ if(!(gr->GetQuality()&3)) return; // do nothing in fast_draw\r
++ long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
++ bool nboth = mgl_isnboth(x,y,z,a);\r
++ if(mgl_check_dim3(gr,!nboth,x,y,z,a,0,"Cloud")) return;\r
++\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Cloud",cgid++);\r
++\r
++ long tx=1,ty=1,tz=1;\r
++ if(gr->MeshNum>1)\r
++ {\r
++ tx=(n-1)/(gr->MeshNum-1); if(tx<1) tx=1;\r
++ ty=(m-1)/(gr->MeshNum-1); if(ty<1) ty=1;\r
++ tz=(l-1)/(gr->MeshNum-1); if(tz<1) tz=1;\r
++ }\r
++\r
++ mreal alpha = gr->AlphaDef;\r
++ bool inv = mglchr(sch,'i');\r
++ bool dot = mglchr(sch,'.');\r
++ alpha /= pow((n/tx)*(m/ty)*(l/tz),1./3)/20;\r
++ if(alpha>1) alpha = 1;\r
++ long ss = gr->AddTexture(sch);\r
++\r
++ // x, y, z -- have the same size as a\r
++ n /= tx; m /= ty; l /= tz;\r
++ long *pos=new long[n*m*l];\r
++ gr->Reserve(n*m*l);\r
++ mglPoint q(NAN);\r
++ for(long k=0;k<l;k++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ for(long j=0;j<m;j++) for(long i=0;i<n;i++)\r
++ {\r
++ mglPoint p = nboth ? mglPoint(x->v(i*tx),y->v(j*ty),z->v(k*tz)) : mglPoint(x->v(i*tx,j*ty,k*tz),y->v(i*tx,j*ty,k*tz),z->v(i*tx,j*ty,k*tz));\r
++ mreal aa = gr->GetA(a->v(i*tx,j*ty,k*tz));\r
++ mreal bb = inv ? (1-aa)*(1-aa)*alpha : aa*aa*alpha;\r
++ pos[i+n*(j+m*k)] = gr->AddPnt(p,gr->GetC(ss,aa,false),q,bb);\r
++ }\r
++ }\r
++ if(dot) for(long i=0;i<n*m*l;i++) gr->mark_plot(pos[i],'.');\r
++ else for(long k=0;k<l;k++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ for(long j=0;j<m;j++) for(long i=0;i<n;i++)\r
++ {\r
++ long i0 = i+n*(j+m*k);\r
++ if(i<n-1 && j<m-1) gr->quad_plot(pos[i0],pos[i0+1],pos[i0+n],pos[i0+n+1]);\r
++ if(i<n-1 && k<l-1) gr->quad_plot(pos[i0],pos[i0+1],pos[i0+n*m],pos[i0+n*m+1]);\r
++ if(k<l-1 && j<m-1) gr->quad_plot(pos[i0],pos[i0+n],pos[i0+n*m],pos[i0+n+n*m]);\r
++ }\r
++ }\r
++ delete []pos; gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cloud(HMGL gr, HCDT a, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_cloud_xyz(gr,&x,&y,&z,a,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cloud_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_cloud_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_cloud_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_cloud(_GR_, _DA_(a), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Surf3 series\r
++//\r
++//-----------------------------------------------------------------------------\r
++mreal MGL_NO_EXPORT mgl_get_norm(mreal x, mreal d1, mreal d2, mreal d3)\r
++{\r
++ mreal nx = d1*(1-x) + d2*x;\r
++ if(mgl_isbad(nx))\r
++ {\r
++ nx = d1*(1+x) - d3*x;\r
++ if(mgl_isbad(nx))\r
++ {\r
++ if(mgl_isfin(d1)) nx = d1;\r
++ if(mgl_isfin(d2)) nx = d2;\r
++ if(mgl_isfin(d3)) nx = d3;\r
++ }\r
++ }\r
++ return nx;\r
++}\r
++mglPoint MGL_NO_EXPORT mgl_normal_3d(HCDT a, mglPoint p, bool inv, long n,long m,long l)\r
++{\r
++ mreal x=p.x, y=p.y, z=p.z;\r
++ mreal nx=0, ny=0, nz=0;\r
++ long i=long(x), j=long(y), k=long(z);\r
++ i = i<n-1 ? i:n-2; j = j<m-1 ? j:m-2; k = k<l-1 ? k:l-2;\r
++ x-=i; y-=j; z-=k;\r
++\r
++ nx = mgl_get_norm(x, a->dvx(i,j,k), a->dvx(i+1,j,k), i>0?a->dvx(i-1,j,k):NAN);\r
++ ny = mgl_get_norm(y, a->dvy(i,j,k), a->dvy(i,j+1,k), j>0?a->dvy(i,j-1,k):NAN);\r
++ nz = mgl_get_norm(z, a->dvz(i,j,k), a->dvz(i,j,k+1), k>0?a->dvz(i,j,k-1):NAN);\r
++ return inv ? mglPoint(nx,ny,nz) : mglPoint(-nx,-ny,-nz);\r
++}\r
++//-----------------------------------------------------------------------------\r
++mreal MGL_NO_EXPORT mgl_normal_1d(HCDT a, mreal x, long n)\r
++{\r
++<<<<<<< HEAD\r
++ register long i=long(x);\r
++=======\r
++ long i=long(x);\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ i = i<n-1 ? i:n-2; x-=i;\r
++ return mgl_get_norm(x, a->dvx(i), a->dvx(i+1), i>0?a->dvx(i-1):NAN);\r
++}\r
++//-----------------------------------------------------------------------------\r
++mglPoint MGL_NO_EXPORT mgl_find_norm(bool nboth, HCDT x, HCDT y, HCDT z, HCDT a, mglPoint u, bool inv, long n,long m,long l)\r
++{\r
++ mglPoint s = mgl_normal_3d(a,u,inv,n,m,l), t, q;\r
++ if(nboth)\r
++ {\r
++ q.x = s.x/mgl_normal_1d(x,u.x,n);\r
++ q.y = s.y/mgl_normal_1d(y,u.y,m);\r
++ q.z = s.z/mgl_normal_1d(z,u.z,l);\r
++ }\r
++ else\r
++ {\r
++ t = mgl_normal_3d(x,u,true,n,m,l); q.x = (s*t)/(t*t);\r
++ t = mgl_normal_3d(y,u,true,n,m,l); q.y = (s*t)/(t*t);\r
++ t = mgl_normal_3d(z,u,true,n,m,l); q.z = (s*t)/(t*t);\r
++ }\r
++ return q;\r
++}\r
++//-----------------------------------------------------------------------------\r
++inline mreal MGL_NO_EXPORT mgl_cos_pp(const mglPoint *kk,long i0,long i1,long i2)\r
++{\r
++ mglPoint dp1 = kk[i1]-kk[i0], dp2 = kk[i2]-kk[i0];\r
++ mreal p1=dp1*dp1,p2=dp2*dp2,pc=dp1*dp2;\r
++ return p1*p2>1e-10 ? pc/sqrt(p1*p2) : NAN;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3_plot(HMGL gr, long n,long m,long *kx1,long *kx2,long *ky1,long *ky2, long *kz, std::vector<mglPoint> kk, int wire)\r
++{\r
++ long id[12],us[12],pd[12];\r
++ mglPoint pp[12];\r
++\r
++#pragma omp parallel for private(id,us,pd,pp) collapse(2)\r
++ for(long j=0;j<m-1;j++) for(long i=0;i<n-1;i++)\r
++ {\r
++ long i0 = i+n*j,ii,jj,k;\r
++ // find ID of points of Surf3 intersection with cell i0\r
++ memset(id,-1,12*sizeof(long)); long ni = 0;\r
++ if(kx1[i0]>=0) id[ni++] = kx1[i0];\r
++ if(ky1[i0]>=0) id[ni++] = ky1[i0];\r
++ if(kx1[i0+n]>=0) id[ni++] = kx1[i0+n];\r
++ if(ky1[i0+1]>=0) id[ni++] = ky1[i0+1];\r
++ if(kz[i0]>=0) id[ni++] = kz[i0];\r
++ if(kz[i0+1]>=0) id[ni++] = kz[i0+1];\r
++ if(kz[i0+n+1]>=0) id[ni++] = kz[i0+n+1];\r
++ if(kz[i0+n]>=0) id[ni++] = kz[i0+n];\r
++ if(kx2[i0]>=0) id[ni++] = kx2[i0];\r
++ if(ky2[i0]>=0) id[ni++] = ky2[i0];\r
++ if(kx2[i0+n]>=0) id[ni++] = kx2[i0+n];\r
++ if(ky2[i0+1]>=0) id[ni++] = ky2[i0+1];\r
++ if(ni<3) continue;\r
++\r
++ for(jj=0;jj<ni;jj++)\r
++ { pp[jj]=kk[id[jj]]; pd[jj]=mgl_int(pp[jj].c); }\r
++ // remove points which is too close to first one\r
++ for(jj=1;jj<ni;)\r
++ {\r
++ mreal d = mgl_norm(pp[jj] - pp[0]);\r
++ if(d>1e-5) jj++;\r
++ else\r
++ { ni--; for(ii=jj;ii<ni;ii++) id[ii]=id[ii+1]; }\r
++ }\r
++ // continue if number of points <3 i.e. there is no triangle\r
++ if(ni<3) continue;\r
++ memset(us,0,12*sizeof(long));\r
++ // firstly let find most outstanding point\r
++ mreal d0=2;\r
++ for(jj=1,ii=2;ii<ni;ii++)\r
++ {\r
++ mreal d = mgl_cos_pp(pp,0,ii,1);\r
++ if(d<d0) { d0=d; jj=ii; }\r
++ }\r
++ // copy first 2 points as base\r
++ long p1 = pd[0], p2 = pd[jj], p3;\r
++ // select the same orientation of all triangles of the surface\r
++ us[0] = us[jj] = 1;\r
++ // find all triangles\r
++ for(k=2;k<ni;k++)\r
++ {\r
++ // find closest point in sence cosine of angle\r
++ for(i0=-1,ii=1,d0=-2;ii<ni;ii++)\r
++ {\r
++ if(us[ii]) continue;\r
++ mreal d = mgl_cos_pp(pp,0,ii,jj);\r
++ if(d>d0) { d0=d; i0=ii; }\r
++ }\r
++ if(i0<0) break; // no more triangles. NOTE: should be never here\r
++ jj = i0; us[jj]=1; p3 = pd[jj];\r
++ if(wire==1)\r
++ {\r
++ gr->line_plot(p1, p2);\r
++ gr->line_plot(p1, p3);\r
++ gr->line_plot(p2, p3);\r
++ }\r
++ else if(wire==2)\r
++ {\r
++ gr->mark_plot(p1, '.');\r
++ gr->mark_plot(p2, '.');\r
++ gr->mark_plot(p3, '.');\r
++ }\r
++ else gr->trig_plot(p1, p2, p3);\r
++ p2 = p3;\r
++ }\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_NO_EXPORT mgl_surf3ca_gen(HMGL gr, double val, HCDT x, HCDT y, HCDT z, HCDT a, HCDT c, HCDT b, const char *sch)\r
++{\r
++ long n=a->GetNx(),m=a->GetNy(),l=a->GetNz();\r
++ bool nboth = mgl_isnboth(x,y,z,a);\r
++ int wire = mglchr(sch,'#')?1:0;\r
++ if(mglchr(sch,'.')) wire = 2;\r
++ bool inv = (mglchr(sch,'-'));\r
++ long ss = gr->AddTexture(sch);\r
++\r
++ long *kx1 = new long[n*m], *kx2 = new long[n*m];\r
++ long *ky1 = new long[n*m], *ky2 = new long[n*m];\r
++ long *kz = new long[n*m];\r
++ std::vector<mglPoint> kk;\r
++ kk.reserve(n*m*l);\r
++\r
++ for(long k=0;k<l;k++)\r
++ {\r
++ if(gr->NeedStop()) break;\r
++ memcpy(kx1,kx2,n*m*sizeof(long)); memset(kx2,-1,n*m*sizeof(long));\r
++ memcpy(ky1,ky2,n*m*sizeof(long)); memset(ky2,-1,n*m*sizeof(long));\r
++ memset(kz ,-1,n*m*sizeof(long));\r
++ gr->Reserve(n*m); gr->Reserve(n*m);\r
++ size_t kk1 = kk.size();\r
++ for(long j=0;j<m;j++) for(long i=0;i<n;i++)\r
++ {\r
++ long i1 = i+n*j;\r
++ mreal a0 = a->v(i,j,k);\r
++ if(mgl_isnan(a0)) continue;\r
++ if(i<n-1)\r
++ {\r
++ mreal d = mgl_d(val,a0,a->v(i+1,j,k));\r
++ if(d>=0 && d<1)\r
++ { kx2[i1] = kk.size(); kk.push_back(mglPoint(i+d,j,k)); }\r
++ }\r
++ if(j<m-1)\r
++ {\r
++ mreal d = mgl_d(val,a0,a->v(i,j+1,k));\r
++ if(d>=0 && d<1)\r
++ { ky2[i1] = kk.size(); kk.push_back(mglPoint(i,j+d,k)); }\r
++ }\r
++ if(k>0)\r
++ {\r
++ mreal d = mgl_d(val,a->v(i,j,k-1),a0);\r
++ if(d>=0 && d<1)\r
++ { kz[i1] = kk.size(); kk.push_back(mglPoint(i,j,k+d-1)); }\r
++ }\r
++ }\r
++ mreal cv=gr->GetC(ss,val);\r
++ if(b && c) for(size_t i=kk1;i<kk.size();i++)\r
++ {\r
++ mglPoint &u = kk[i];\r
++ mreal cc = c->linear(u.x,u.y,u.z), bb = b->linear(u.x,u.y,u.z);\r
++ if(mgl_isnan(cc) || mgl_isnan(bb)) u.c = -1; else\r
++ u.c = gr->AddPnt(nboth ? mglPoint(x->linear(u.x,0,0),y->linear(u.y,0,0),z->linear(u.z,0,0)) :\r
++ mglPoint(x->linear(u.x,u.y,u.z),y->linear(u.x,u.y,u.z),z->linear(u.x,u.y,u.z)),\r
++ gr->GetC(ss,cc), mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l), gr->GetA(bb));\r
++ }\r
++ else if(c) for(size_t i=kk1;i<kk.size();i++)\r
++ {\r
++ mglPoint &u = kk[i];\r
++ mreal cc = c->linear(u.x,u.y,u.z);\r
++ if(mgl_isnan(cc)) u.c = -1; else\r
++ u.c = gr->AddPnt(nboth ? mglPoint(x->linear(u.x,0,0),y->linear(u.y,0,0),z->linear(u.z,0,0)) :\r
++ mglPoint(x->linear(u.x,u.y,u.z),y->linear(u.x,u.y,u.z),z->linear(u.x,u.y,u.z)),\r
++ gr->GetC(ss,cc), mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l));\r
++ }\r
++ else if(b) for(size_t i=kk1;i<kk.size();i++)\r
++ {\r
++ mglPoint &u = kk[i];\r
++ mreal bb = b->linear(u.x,u.y,u.z);\r
++ if(mgl_isnan(bb)) u.c = -1; else\r
++ u.c = gr->AddPnt(nboth ? mglPoint(x->linear(u.x,0,0),y->linear(u.y,0,0),z->linear(u.z,0,0)) :\r
++ mglPoint(x->linear(u.x,u.y,u.z),y->linear(u.x,u.y,u.z),z->linear(u.x,u.y,u.z)),\r
++ cv, mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l), gr->GetA(bb));\r
++ }\r
++ else for(size_t i=kk1;i<kk.size();i++)\r
++ {\r
++ mglPoint &u = kk[i];\r
++ u.c = gr->AddPnt(nboth ? mglPoint(x->linear(u.x,0,0),y->linear(u.y,0,0),z->linear(u.z,0,0)) :\r
++ mglPoint(x->linear(u.x,u.y,u.z),y->linear(u.x,u.y,u.z),z->linear(u.x,u.y,u.z)),\r
++ cv, mgl_find_norm(nboth, x,y,z,a, u, inv,n,m,l));\r
++ }\r
++\r
++ if(k>0) mgl_surf3_plot(gr,n,m,kx1,kx2,ky1,ky2,kz,kk,wire);\r
++ }\r
++ delete []kx1; delete []kx2; delete []ky1;\r
++ delete []ky2; delete []kz; gr->EndGroup();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
++{\r
++ if(mgl_check_dim3(gr,mgl_isboth(x,y,z,a),x,y,z,a,0,"Surf3")) return;\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Surf3",cgid++);\r
++ mgl_surf3ca_gen(gr, val, x, y, z, a, 0, 0, sch);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3_val(HMGL gr, double val, HCDT a, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(a->GetNx()), y(a->GetNy()), z(a->GetNz());\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_surf3_xyz_val(gr,val,&x,&y,&z,a,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long num = mgl_isnan(r)?3:long(r+0.5);\r
++ for(long i=0;i<num;i++)\r
++ {\r
++ mreal v = gr->Max.c + (gr->Min.c-gr->Max.c)*(i+1.)/(num+1);\r
++ mgl_surf3_xyz_val(gr,v,x,y,z,a,sch,0);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3(HMGL gr, HCDT a, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(a->GetNx()), y(a->GetNy()), z(a->GetNz());\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_surf3_xyz(gr,&x,&y,&z,a,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3_xyz_val_(uintptr_t *gr, mreal *Val, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3_xyz_val(_GR_, *Val, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3_val_(uintptr_t *gr, mreal *Val, uintptr_t *a, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3_val(_GR_, *Val, _DA_(a), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3_(uintptr_t *gr, uintptr_t *a, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3(_GR_, _DA_(a), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Surf3A series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3a_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *sch, const char *opt)\r
++{\r
++ if(mgl_check_dim3(gr,!mgl_isnboth(x,y,z,a),x,y,z,a,b,"Surf3A")) return;\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Surf3A",cgid++);\r
++ mgl_surf3ca_gen(gr, val, x, y, z, a, 0, b, sch);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3a_val(HMGL gr, double val, HCDT a, HCDT b, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_surf3a_xyz_val(gr,val,&x,&y,&z,a,b,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3a_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *sch, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long num = mgl_isnan(r)?3:long(r+0.5);\r
++ if(b->GetNx()==num && b->GetNy()==1 && b->GetNz()==1)\r
++ {\r
++ mreal a0=gr->AlphaDef;\r
++ for(long i=0;i<num;i++)\r
++ {\r
++ mreal v = gr->Max.c + (gr->Min.c-gr->Max.c)*(i+1.)/(num+1);\r
++ gr->AlphaDef = gr->GetA(b->v(i));\r
++ mgl_surf3_xyz_val(gr,v,x,y,z,a,sch,0);\r
++ }\r
++ gr->AlphaDef = a0;\r
++ }\r
++ else\r
++ for(long i=0;i<num;i++)\r
++ {\r
++ mreal v = gr->Max.c + (gr->Min.c-gr->Max.c)*(i+1.)/(num+1);\r
++ mgl_surf3a_xyz_val(gr,v,x,y,z,a,b,sch,0);\r
++ }\r
++ gr->LoadState();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3a(HMGL gr, HCDT a, HCDT b, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_surf3a_xyz(gr,&x,&y,&z,a,b,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3a_xyz_val_(uintptr_t *gr, mreal *Val, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3a_xyz_val(_GR_, *Val, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(b), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3a_val_(uintptr_t *gr, mreal *Val, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3a_val(_GR_, *Val, _DA_(a), _DA_(b), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3a_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3a_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(b), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3a_(uintptr_t *gr, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3a(_GR_, _DA_(a), _DA_(b), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Surf3C series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3c_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, HCDT a, HCDT c, const char *sch, const char *opt)\r
++{\r
++ if(mgl_check_dim3(gr,!mgl_isnboth(x,y,z,a),x,y,z,a,c,"Surf3C")) return;\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Surf3C",cgid++);\r
++ mgl_surf3ca_gen(gr, val, x, y, z, a, c, 0, sch);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3c_val(HMGL gr, double val, HCDT a, HCDT b, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_surf3c_xyz_val(gr,val,&x,&y,&z,a,b,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3c_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, HCDT b, const char *sch, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long num = mgl_isnan(r)?3:long(r+0.5);\r
++ for(long i=0;i<num;i++)\r
++ {\r
++ mreal v = gr->Max.c + (gr->Min.c-gr->Max.c)*(i+1.)/(num+1);\r
++ mgl_surf3c_xyz_val(gr,v,x,y,z,a,b,sch,0);\r
++ }\r
++ gr->LoadState();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3c(HMGL gr, HCDT a, HCDT b, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_surf3c_xyz(gr,&x,&y,&z,a,b,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3c_xyz_val_(uintptr_t *gr, mreal *Val, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3c_xyz_val(_GR_, *Val, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(b), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3c_val_(uintptr_t *gr, mreal *Val, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3c_val(_GR_, *Val, _DA_(a), _DA_(b), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3c_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3c_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(b), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3c_(uintptr_t *gr, uintptr_t *a, uintptr_t *b, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3c(_GR_, _DA_(a), _DA_(b), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Surf3C series\r
++//\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3ca_xyz_val(HMGL gr, double val, HCDT x, HCDT y, HCDT z, HCDT a, HCDT c, HCDT b, const char *sch, const char *opt)\r
++{\r
++ if(mgl_check_dim3(gr,!mgl_isnboth(x,y,z,a),x,y,z,a,c,"Surf3C") || mgl_check_dim3(gr,!mgl_isnboth(x,y,z,a),x,y,z,a,b,"Surf3C")) return;\r
++ gr->SaveState(opt);\r
++ static int cgid=1; gr->StartGroup("Surf3C",cgid++);\r
++ mgl_surf3ca_gen(gr, val, x, y, z, a, c, b, sch);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3ca_val(HMGL gr, double val, HCDT a, HCDT c, HCDT b, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_surf3ca_xyz_val(gr,val,&x,&y,&z,a,c,b,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3ca_xyz(HMGL gr, HCDT x, HCDT y, HCDT z, HCDT a, HCDT c, HCDT b, const char *sch, const char *opt)\r
++{\r
++ mreal r = gr->SaveState(opt);\r
++ long num = mgl_isnan(r)?3:long(r+0.5);\r
++ for(long i=0;i<num;i++)\r
++ {\r
++ mreal v = gr->Max.c + (gr->Min.c-gr->Max.c)*(i+1.)/(num+1);\r
++ mgl_surf3ca_xyz_val(gr,v,x,y,z,a,c,b,sch,0);\r
++ }\r
++ gr->LoadState();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3ca(HMGL gr, HCDT a, HCDT c, HCDT b, const char *sch, const char *opt)\r
++{\r
++ gr->SaveState(opt);\r
++ mglDataV x(a->GetNx()), y(a->GetNy()),z(a->GetNz());\r
++ x.Fill(gr->Min.x,gr->Max.x);\r
++ y.Fill(gr->Min.y,gr->Max.y);\r
++ z.Fill(gr->Min.z,gr->Max.z);\r
++ mgl_surf3ca_xyz(gr,&x,&y,&z,a,c,b,sch,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3ca_xyz_val_(uintptr_t *gr, mreal *Val, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *c, uintptr_t *b, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3ca_xyz_val(_GR_, *Val, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(c), _DA_(b), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3ca_val_(uintptr_t *gr, mreal *Val, uintptr_t *a, uintptr_t *c, uintptr_t *b, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3ca_val(_GR_, *Val, _DA_(a), _DA_(c), _DA_(b), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3ca_xyz_(uintptr_t *gr, uintptr_t *x, uintptr_t *y, uintptr_t *z, uintptr_t *a, uintptr_t *c, uintptr_t *b, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3ca_xyz(_GR_, _DA_(x), _DA_(y), _DA_(z), _DA_(a), _DA_(c), _DA_(b), s, o);\r
++ delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_surf3ca_(uintptr_t *gr, uintptr_t *a, uintptr_t *c, uintptr_t *b, const char *sch, const char *opt,int l,int lo)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ char *o=new char[lo+1]; memcpy(o,opt,lo); o[lo]=0;\r
++ mgl_surf3ca(_GR_, _DA_(a), _DA_(c), _DA_(b), s, o); delete []o; delete []s; }\r
++//-----------------------------------------------------------------------------\r
++//\r
++// Beam series\r
++//\r
++//-----------------------------------------------------------------------------\r
++// flag & 0x1 -- accompanied coordinates\r
++// flag & 0x2 -- project to r*z\r
++// flag & 0x4 -- normalize field\r
++void MGL_EXPORT mgl_beam_val(HMGL gr, double val, HCDT tr, HCDT g1, HCDT g2, HCDT a, double r, const char *stl, int flag)\r
++{\r
++ long n = a->GetNz(),m=a->GetNx(),l=a->GetNy();\r
++ if(n<2 || m<2 || l<2) { gr->SetWarn(mglWarnLow,"Beam"); return; }\r
++ if(a->Minimal()<0) { gr->SetWarn(mglWarnNeg,"Beam"); return; }\r
++ if(tr->GetNx()<3 || tr->GetNy()<n || g1->GetNx()<3 || g1->GetNy()<n || g2->GetNx()<3 || g2->GetNy()<n)\r
++ { gr->SetWarn(mglWarnDim,"Beam"); return; }\r
++ mglData x(a),y(a),z(a),b(a);\r
++ mreal asum0=1; r = fabs(r);\r
++ if(flag & 4) for(long j=0;j<m*l;j++) asum0 += a->vthr(j)*a->vthr(j);\r
++ if(asum0==0) { gr->SetWarn(mglWarnZero,"Beam"); return; }\r
++#pragma omp parallel for\r
++ for(long i=0;i<n;i++)\r
++ {\r
++ if(gr->NeedStop()) continue;\r
++ if(flag & 4)\r
++ {\r
++ mreal asum=0, amax=0;\r
++ for(long j=0;j<m*l;j++)\r
++ {\r
++ mreal aa = a->vthr(j+m*l*i);\r
++ asum += aa*aa; amax = amax>aa ? amax : aa;\r
++ }\r
++ amax = amax?sqrt(asum/asum0)/amax:0;\r
++ for(long j=0;j<m*l;j++) b.a[j+m*l*i] = b.a[j+m*l*i]*amax;\r
++<<<<<<< HEAD\r
++ }\r
++ if(flag & 1) for(long j=0;j<m;j++) for(long k=0;k<l;k++)\r
++ {\r
++ register long i0 = j+m*(k+l*i);\r
++ x.a[i0] = 2*j/(m-1.)-1;\r
++ y.a[i0] = 2*k/(l-1.)-1;\r
++ z.a[i0] = gr->Max.z*i/(n-1.);\r
++ }\r
++ else for(long j=0;j<m;j++) for(long k=0;k<l;k++)\r
++ {\r
++ register long i0 = j+m*(k+l*i);\r
++ x.a[i0] = tr->v(0,i) + g1->v(0,i)*(2*j/(m-1.)-1)*r + g2->v(0,i)*(2*k/(l-1.)-1)*r;\r
++ y.a[i0] = tr->v(1,i) + g1->v(1,i)*(2*j/(m-1.)-1)*r + g2->v(1,i)*(2*k/(l-1.)-1)*r;\r
++ z.a[i0] = tr->v(2,i) + g1->v(2,i)*(2*j/(m-1.)-1)*r + g2->v(2,i)*(2*k/(l-1.)-1)*r;\r
++ }\r
++ if(flag & 2) for(long j=0;j<m;j++) for(long k=0;k<l;k++)\r
++ {\r
++ register long i0 = j+m*(k+l*i);\r
++ x.a[i0] = hypot(x.a[i0],y.a[i0]);\r
++ }\r
++=======\r
++ }\r
++ const long ii=m*l*i;\r
++ if(flag & 1) for(long k=0;k<l;k++) for(long j=0;j<m;j++)\r
++ {\r
++ long i0 = ii+j+m*k;\r
++ x.a[i0] = 2*j/(m-1.)-1;\r
++ y.a[i0] = 2*k/(l-1.)-1;\r
++ z.a[i0] = gr->Max.z*i/(n-1.);\r
++ }\r
++ else for(long k=0;k<l;k++) for(long j=0;j<m;j++)\r
++ {\r
++ long i0 = ii+j+m*k;\r
++ x.a[i0] = tr->v(0,i) + g1->v(0,i)*(2*j/(m-1.)-1)*r + g2->v(0,i)*(2*k/(l-1.)-1)*r;\r
++ y.a[i0] = tr->v(1,i) + g1->v(1,i)*(2*j/(m-1.)-1)*r + g2->v(1,i)*(2*k/(l-1.)-1)*r;\r
++ z.a[i0] = tr->v(2,i) + g1->v(2,i)*(2*j/(m-1.)-1)*r + g2->v(2,i)*(2*k/(l-1.)-1)*r;\r
++ }\r
++ if(flag & 2) for(long j=0;j<m*l;j++)\r
++ { long i0 = j+ii; x.a[i0] = hypot(x.a[i0],y.a[i0]); }\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ }\r
++ mgl_surf3_xyz_val(gr,val,&x,&y,&z,&b,stl,0);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_beam(HMGL gr, HCDT tr, HCDT g1, HCDT g2, HCDT a, double r, const char *stl, int flag, int num)\r
++{\r
++ num = num<=0 ? 1 : num;\r
++ for(long i=0;i<num;i++)\r
++ {\r
++ mreal v = gr->Max.c + (gr->Min.c-gr->Max.c)*(i+1.)/(num+1);\r
++ mgl_beam_val(gr,v,tr,g1,g2,a,r,stl,flag);\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_beam_val_(uintptr_t *gr, mreal *val, uintptr_t *tr, uintptr_t *g1, uintptr_t *g2, uintptr_t *a, mreal *r, const char *sch, int *norm,int l)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ mgl_beam_val(_GR_, *val,_DA_(tr),_DA_(g1),_DA_(g2),_DA_(a),*r,s,*norm); delete []s; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_beam_(uintptr_t *gr, uintptr_t *tr, uintptr_t *g1, uintptr_t *g2, uintptr_t *a, mreal *r, const char *sch, int *norm, int *num,int l)\r
++{ char *s=new char[l+1]; memcpy(s,sch,l); s[l]=0;\r
++ mgl_beam(_GR_, _DA_(tr), _DA_(g1), _DA_(g2), _DA_(a), *r,s,*norm,*num); delete []s; }\r
++//-----------------------------------------------------------------------------\r
--- /dev/null
--- /dev/null
++/***************************************************************************\r
++ * window.cpp is part of Math Graphic Library\r
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *\r
++ * *\r
++ * This program is free software; you can redistribute it and/or modify *\r
++ * it under the terms of the GNU Library General Public License as *\r
++ * published by the Free Software Foundation; either version 3 of the *\r
++ * License, or (at your option) any later version. *\r
++ * *\r
++ * This program is distributed in the hope that it will be useful, *\r
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
++ * GNU General Public License for more details. *\r
++ * *\r
++ * You should have received a copy of the GNU Library General Public *\r
++ * License along with this program; if not, write to the *\r
++ * Free Software Foundation, Inc., *\r
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
++ ***************************************************************************/\r
++#include "mgl2/canvas_wnd.h"\r
++//-----------------------------------------------------------------------------\r
++mglCanvasWnd::mglCanvasWnd() : mglCanvas()\r
++{\r
++ Setup(); LoadFunc=0; FuncPar=0; DrawFunc=0; ClickFunc=0;\r
++ GG = 0; NumFig = 0; CurFig = -1;\r
++#if MGL_HAVE_PTHR_WIDGET\r
++ mutex=0;\r
++#endif\r
++}\r
++//-----------------------------------------------------------------------------\r
++mglCanvasWnd::~mglCanvasWnd() { if(GG) free(GG); }\r
++//-----------------------------------------------------------------------------\r
++void mglCanvasWnd::SetCurFig(int c)\r
++{\r
++ CurFig=c;\r
++ if(get(MGL_VECT_FRAME) && c>=0 && c<(long)DrwDat.size() && DrawFunc)\r
++ GetFrame(c);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvasWnd::ResetFrames()\r
++{\r
++ if(GG) free(GG);\r
++ GG = 0; NumFig = CurFig = 0;\r
++ mglCanvas::ResetFrames();\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvasWnd::SetSize(int w,int h,bool)\r
++{\r
++ if(DrawFunc) ResetFrames();\r
++ mglCanvas::SetSize(w,h,false);\r
++// if(Wnd) Wnd->size(w,h);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvasWnd::EndFrame()\r
++{\r
++ CurFig = CurFrameId-1;\r
++ if(!GG)\r
++ {\r
++ GG = (unsigned char *)malloc(3*Width*Height);\r
++ NumFig = 1; CurFig = 0;\r
++ }\r
++ else if(CurFig>NumFig-1)\r
++ {\r
++ GG = (unsigned char *)realloc(GG,3*(CurFig+1)*Width*Height);\r
++ NumFig = CurFig+1;\r
++ }\r
++ mglCanvas::EndFrame();\r
++ memcpy(GG + CurFig*Width*Height*3,G,3*Width*Height);\r
++ CurFig++;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvasWnd::SetFrame(long i)\r
++{\r
++ mglCanvas::SetFrame(i);\r
++ if(i>=0 && i<NumFig) memcpy(GG + i*Width*Height*3,G,3*Width*Height);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvasWnd::DelFrame(long i)\r
++{\r
++ if(i<0 || i>=CurFrameId) return;\r
++ if(CurFig>=i) CurFig--;\r
++ long n = Width*Height*3;\r
++ if(CurFrameId-i>1) memmove(GG+i*n, GG+i*n+n, n*(CurFrameId-i-1));\r
++ mglCanvas::DelFrame(i);\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvasWnd::SetDrawFunc(int (*draw)(mglBase *gr, void *p), void *par, void (*reload)(void *p))\r
++{\r
++ if(draw)\r
++ {\r
++ ResetFrames();\r
++ if(get(MGL_CLF_ON_UPD)) DefaultPlotParam();\r
++<<<<<<< HEAD\r
++ const std::string loc = setlocale(LC_NUMERIC, NULL); setlocale(LC_NUMERIC, "C");\r
++=======\r
++ const std::string loc = setlocale(LC_NUMERIC, "C");\r
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965\r
++ // use frames for quickly redrawing while adding/changing primitives\r
++ if(mgl_is_frames(this)) NewFrame();\r
++\r
++ int n = draw(this,par);\r
++ if(n<NumFig && n>=0) NumFig = n;\r
++ DrawFunc = draw; FuncPar = par;\r
++ LoadFunc = reload;\r
++\r
++ if(mgl_is_frames(this)) EndFrame();\r
++ if(n>=0) SetCurFig(0);\r
++ setlocale(LC_NUMERIC, loc.c_str());\r
++ }\r
++ else LoadFunc = 0;\r
++}\r
++//-----------------------------------------------------------------------------\r
++const unsigned char *mglCanvasWnd::GetBits()\r
++{\r
++ const unsigned char *g = mglCanvas::GetBits();\r
++ if(GG && NumFig>0 && CurFig<NumFig && CurFig>=0 && !get(MGL_VECT_FRAME))\r
++ g = GG + CurFig*Width*Height*3;\r
++ return g;\r
++}\r
++//-----------------------------------------------------------------------------\r
++void mglCanvasWnd::ReLoad()\r
++{\r
++ if(LoadFunc)\r
++ {\r
++ LoadFunc(FuncPar);\r
++ // update number of slides\r
++ ResetFrames();\r
++ const std::string loc = setlocale(LC_NUMERIC, "C");\r
++ // use frames for quickly redrawing while adding/changing primitives\r
++ if(mgl_is_frames(this)) NewFrame();\r
++\r
++ int n = DrawFunc ? DrawFunc(this,FuncPar) : 0;\r
++ if(n<NumFig && n>=0) NumFig = n;\r
++\r
++ if(mgl_is_frames(this)) EndFrame();\r
++ setlocale(LC_NUMERIC, loc.c_str());\r
++ Update();\r
++ }\r
++}\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_wnd_set_func(HMGL gr, int (*draw)(HMGL gr, void *p), void *par, void (*reload)(void *p))\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->SetDrawFunc(draw, par, reload); }\r
++void MGL_EXPORT mgl_wnd_toggle_alpha(HMGL gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->ToggleAlpha(); }\r
++void MGL_EXPORT mgl_wnd_toggle_light(HMGL gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->ToggleLight(); }\r
++void MGL_EXPORT mgl_wnd_toggle_zoom(HMGL gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->ToggleZoom(); }\r
++void MGL_EXPORT mgl_wnd_toggle_rotate(HMGL gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->ToggleRotate(); }\r
++void MGL_EXPORT mgl_wnd_toggle_no(HMGL gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->ToggleNo(); }\r
++void MGL_EXPORT mgl_wnd_update(HMGL gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->Update(); }\r
++void MGL_EXPORT mgl_wnd_reload(HMGL gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->ReLoad(); }\r
++void MGL_EXPORT mgl_wnd_adjust(HMGL gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->Adjust(); }\r
++void MGL_EXPORT mgl_wnd_next_frame(HMGL gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->NextFrame(); }\r
++void MGL_EXPORT mgl_wnd_prev_frame(HMGL gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->PrevFrame(); }\r
++void MGL_EXPORT mgl_wnd_animation(HMGL gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->Animation(); }\r
++void MGL_EXPORT mgl_setup_window(HMGL gr, int clf_upd, int showpos)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->Setup(clf_upd, showpos); }\r
++void MGL_EXPORT mgl_set_click_func(HMGL gr, void (*func)(void *p))\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr); if(g) g->ClickFunc = func; }\r
++void MGL_EXPORT mgl_get_last_mouse_pos(HMGL gr, mreal *x, mreal *y, mreal *z)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);\r
++ mglPoint p; if(g) p=g->GetMousePos();\r
++ *x=p.x; *y=p.y; *z=p.z; }\r
++//-----------------------------------------------------------------------------\r
++void MGL_EXPORT mgl_wnd_toggle_alpha_(uintptr_t *gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ if(g) g->ToggleAlpha(); }\r
++void MGL_EXPORT mgl_wnd_toggle_light_(uintptr_t *gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ if(g) g->ToggleLight(); }\r
++void MGL_EXPORT mgl_wnd_toggle_zoom_(uintptr_t *gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ if(g) g->ToggleZoom(); }\r
++void MGL_EXPORT mgl_wnd_toggle_rotate_(uintptr_t *gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ if(g) g->ToggleRotate(); }\r
++void MGL_EXPORT mgl_wnd_toggle_no_(uintptr_t *gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ if(g) g->ToggleNo(); }\r
++void MGL_EXPORT mgl_wnd_update_(uintptr_t *gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ if(g) g->Update(); }\r
++void MGL_EXPORT mgl_wnd_reload_(uintptr_t *gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ if(g) g->ReLoad(); }\r
++void MGL_EXPORT mgl_wnd_adjust_(uintptr_t *gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ if(g) g->Adjust(); }\r
++void MGL_EXPORT mgl_wnd_next_frame_(uintptr_t *gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ if(g) g->NextFrame(); }\r
++void MGL_EXPORT mgl_wnd_prev_frame_(uintptr_t *gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ if(g) g->PrevFrame(); }\r
++void MGL_EXPORT mgl_wnd_animation_(uintptr_t *gr)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ if(g) g->Animation(); }\r
++void MGL_EXPORT mgl_setup_window_(uintptr_t *gr, int *clf_upd, int *showpos)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ if(g) g->Setup(*clf_upd, *showpos); }\r
++void MGL_EXPORT mgl_get_last_mouse_pos_(uintptr_t *gr, mreal *x, mreal *y, mreal *z)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));\r
++ mglPoint p; if(g) p=g->GetMousePos();\r
++ *x=p.x; *y=p.y; *z=p.z; }\r
++//-----------------------------------------------------------------------------\r
++#if MGL_HAVE_PTHR_WIDGET\r
++void MGL_EXPORT mgl_wnd_set_mutex(HMGL gr, pthread_mutex_t *mutex)\r
++{ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);\r
++ if(g) g->mutex = mutex; }\r
++#endif\r
++//-----------------------------------------------------------------------------\r
++//\r
++// mglDraw class handling\r
++//\r
++//-----------------------------------------------------------------------------\r
++/*int mgl_draw_class(HMGL gr, void *p) // so stupid way to save mglDraw class inheritance :(\r
++{\r
++ mglGraph g(gr); mglWindow *w = (mglWindow *)p;\r
++ return (w && w->dr) ? w->dr->Draw(&g) : 0;\r
++}\r
++void MGL_EXPORT mgl_reload_class(void *p) // so stupid way to save mglDraw class inheritance :(\r
++{ mglWindow *w = (mglWindow *)p; if(w && w->dr) w->dr->Reload();}\r
++void MGL_EXPORT mgl_click_class(void *p) // so stupid way to save mglDraw class inheritance :(\r
++{ mglWindow *w = (mglWindow *)p; if(w && w->dr) w->dr->Click(); }*/\r
++int MGL_EXPORT mgl_draw_class(HMGL gr, void *p)\r
++{ mglGraph g(gr); mglDraw *dr = (mglDraw *)p; return dr?dr->Draw(&g):0; }\r
++void MGL_EXPORT mgl_reload_class(void *p)\r
++{ mglDraw *dr = (mglDraw *)p; if(dr) dr->Reload(); }\r
++void MGL_EXPORT mgl_click_class(void *p)\r
++{ mglDraw *dr = (mglDraw *)p; if(dr) dr->Click(); }\r
++//-----------------------------------------------------------------------------\r
++typedef int (*draw_func)(mglGraph *gr);\r
++int MGL_EXPORT mgl_draw_graph(HMGL gr, void *p)\r
++{\r
++ mglGraph g(gr);\r
++ draw_func func = (draw_func)(p);\r
++ return func ? func(&g) : 0;\r
++}\r
++//-----------------------------------------------------------------------------\r
++MGL_EXPORT void *mgl_draw_calc(void *p)\r
++{\r
++#if MGL_HAVE_PTHR_WIDGET\r
++ mglDraw *d = (mglDraw *)p;\r
++ d->Calc(); d->running = false;\r
++#endif\r
++ return 0;\r
++}\r
++//-----------------------------------------------------------------------------\r
--- /dev/null
--- /dev/null
++@c ------------------------------------------------------------------
++@chapter MathGL core
++@nav{}
++@cindex mglGraph
++
++@ifset UDAV
++This chapter contains a lot of plotting commands for 1D, 2D and 3D data. It also encapsulates parameters for axes drawing. Moreover an arbitrary coordinate transformation can be used for each axis. Additional information about colors, fonts, formula parsing can be found in @ref{General concepts}. The full list of symbols used by MathGL for setting up plots can be found in @ref{Symbols for styles}.
++@end ifset
++
++@ifclear UDAV
++The core of MathGL is @strong{mglGraph} class defined in @code{#include <mgl2/mgl.h>}. It contains a lot of plotting functions for 1D, 2D and 3D data. It also encapsulates parameters for axes drawing. Moreover an arbitrary coordinate transformation can be used for each axis. All plotting functions use data encapsulated in mglData class (see @ref{Data processing}) that allows to check sizes of used arrays easily. Also it have many functions for data handling: modify it by formulas, find momentums and distribution (histogram), apply operator (differentiate, integrate, transpose, Fourier and so on), change data sizes (interpolate, squeeze, crop and so on). Additional information about colors, fonts, formula parsing can be found in @ref{General concepts} and @ref{Other classes}.
++@end ifclear
++
++Some of MathGL features will appear only in novel versions. To test used MathGL version you can use following function.
++@anchor{version}
++@deftypefn {MGL command} {} version 'ver'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{bool} CheckVersion (@code{const char *}ver) static
++@deftypefnx {C function} @code{int} mgl_check_version (@code{const char *}ver)
++@end ifclear
++Return zero if MathGL version is appropriate for required by @var{ver}, i.e. if major version is the same and minor version is greater or equal to one in @var{ver}.
++@end deftypefn
++
++@menu
++* Constructor::
++* Graphics setup::
++* Axis settings::
++* Subplots and rotation::
++* Export picture::
++* Background::
++* Primitives::
++* Text printing::
++* Axis and Colorbar::
++* Legend::
++* 1D plotting::
++* 2D plotting::
++* 3D plotting::
++* Dual plotting::
++* Vector fields::
++* Other plotting::
++* Nonlinear fitting::
++* Data manipulation::
++@c * IDTF functions::
++@end menu
++
++@c ##################################################################
++@external{}
++@node Constructor, Graphics setup, , MathGL core
++@section Create and delete objects
++@nav{}
++
++@ifclear UDAV
++@deftypefn {Constructor on @code{mglGraph}} {} mglGraph (@code{int} kind=@code{0}, @code{int} width=@code{600}, @code{int} height=@code{400})
++@deftypefnx {Constructor on @code{mglGraph}} {} mglGraph (@code{const mglGraph &}gr)
++@deftypefnx {Constructor on @code{mglGraph}} {} mglGraph (@code{HMGL} gr)
++@deftypefnx {C function} @code{HMGL} mgl_create_graph (@code{int} width, @code{int} height)
++@deftypefnx {C function} @code{HMGL} mgl_create_graph_gl ()
++Creates the instance of class mglGraph with specified sizes @var{width} and @var{height}. Parameter @var{kind} may have following values: @samp{0} -- use default plotter, @samp{1} -- use OpenGL plotter.
++@end deftypefn
++
++@deftypefn {Destructor on @code{mglGraph}} {} ~mglGraph ()
++@deftypefnx {C function} @code{HMGL} mgl_delete_graph (@code{HMGL} gr)
++Deletes the instance of class mglGraph.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{HMGL} Self ()
++Returns the pointer to internal object of type @code{HMGL}.
++@end deftypefn
++@end ifclear
++
++@ifset UDAV
++You don't need to create canvas object in MGL.
++@end ifset
++
++@c ##################################################################
++@external{}
++@node Graphics setup, Axis settings, Constructor, MathGL core
++@section Graphics setup
++@nav{}
++@cindex MathGL setup
++
++Functions and variables in this group influences on overall graphics appearance. So all of them should be placed @emph{before} any actual plotting function calls.
++
++@anchor{reset}
++@deftypefn {MGL command} {} reset
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} DefaultPlotParam ()
++@deftypefnx {C function} @code{void} mgl_set_def_param (@code{HMGL} gr)
++@end ifclear
++Restore initial values for all of parameters and clear the image.
++@end deftypefn
++
++@menu
++* Transparency::
++* Lighting::
++* Fog::
++* Default sizes::
++* Cutting::
++* Font settings::
++* Palette and colors::
++* Masks::
++* Error handling::
++* Stop drawing::
++@end menu
++
++@c ==================================================================
++@external{}
++@node Transparency, Lighting, , Graphics setup
++@subsection Transparency
++@nav{}
++@cindex Alpha
++@ifclear UDAV
++@cindex SetAlphaDef
++@cindex SetTranspType
++@end ifclear
++@cindex AlphaDef
++@cindex TranspType
++
++There are several functions and variables for setup transparency. The general function is @ref{alpha} which switch on/off the transparency for overall plot. It influence only for graphics which created after @ref{alpha} call (with one exception, OpenGL). Function @ref{alphadef} specify the default value of alpha-channel. Finally, function @ref{transptype} set the kind of transparency. @sref{Transparency and lighting}
++
++@anchor{alpha}
++@deftypefn {MGL command} {} alpha @code{[val=on]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Alpha (@code{bool} enable)
++@deftypefnx {C function} @code{void} mgl_set_alpha (@code{HMGL} gr, @code{int} enable)
++@end ifclear
++Sets the transparency on/off and returns previous value of transparency. It is recommended to call this function before any plotting command. Default value is transparency off.
++@end deftypefn
++
++@anchor{alphadef}
++@deftypefn {MGL command} {} alphadef @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetAlphaDef (@code{mreal} val)
++@deftypefnx {C function} @code{void} mgl_set_alpha_default (@code{HMGL} gr, @code{mreal} alpha)
++@end ifclear
++Sets default value of alpha channel (transparency) for all plotting functions. Initial value is 0.5.
++@end deftypefn
++
++@anchor{transptype}
++@deftypefn {MGL command} {} transptype @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTranspType (@code{int} type)
++@deftypefnx {C function} @code{void} mgl_set_transp_type (@code{HMGL} gr, @code{int} type)
++@end ifclear
++Set the type of transparency. Possible values are:
++@itemize @bullet
++@item
++Normal transparency (@samp{0}) -- below things is less visible than upper ones. It does not look well in OpenGL mode (mglGraphGL) for several surfaces.
++@item
++Glass-like transparency (@samp{1}) -- below and upper things are commutable and just decrease intensity of light by RGB channel.
++@item
++Lamp-like transparency (@samp{2}) -- below and upper things are commutable and are the source of some additional light. I recommend to set @code{SetAlphaDef(0.3)} or less for lamp-like transparency.
++@end itemize
++@sref{Types of transparency}.
++@end deftypefn
++
++@c ==================================================================
++@external{}
++@node Lighting, Fog, Transparency, Graphics setup
++@subsection Lighting
++@nav{}
++
++@ifclear UDAV
++@cindex SetAmbient
++@cindex AddLight
++@end ifclear
++@cindex Light
++@cindex Ambient
++
++There are several functions for setup lighting. The general function is @ref{light} which switch on/off the lighting for overall plot. It influence only for graphics which created after @ref{light} call (with one exception, OpenGL). Generally MathGL support up to 10 independent light sources. But in OpenGL mode only 8 of light sources is used due to OpenGL limitations. The position, color, brightness of each light source can be set separately. By default only one light source is active. It is source number @code{0} with white color, located at top of the plot. @sref{Lighting sample}
++
++@anchor{light}
++@deftypefn {MGL command} {} light @code{[val=on]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{bool} Light (@code{bool} enable)
++@deftypefnx {C function} @code{void} mgl_set_light (@code{HMGL} gr, @code{int} enable)
++@end ifclear
++Sets the using of light on/off for overall plot. Function returns previous value of lighting. Default value is lightning off.
++@end deftypefn
++
++@deftypefn {MGL command} {} light @code{num} @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Light (@code{int} n, @code{bool} enable)
++@deftypefnx {C function} @code{void} mgl_set_light_n (@code{HMGL} gr, @code{int} n, @code{int} enable)
++@end ifclear
++Switch on/off @var{n}-th light source separately.
++@end deftypefn
++
++@deftypefn {MGL command} {} light @code{num xdir ydir zdir} ['col'='w' @code{br=0.5}]
++@deftypefnx {MGL command} {} light @code{num xdir ydir zdir xpos ypos zpos} ['col'='w' @code{br=0.5 ap=0}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} AddLight (@code{int} n, @code{mglPoint} d, @code{char} c=@code{'w'}, @code{mreal} bright=@code{0.5}, @code{mreal} ap=@code{0})
++@deftypefnx {Method on @code{mglGraph}} @code{void} AddLight (@code{int} n, @code{mglPoint} r, @code{mglPoint} d, @code{char} c=@code{'w'}, @code{mreal} bright=@code{0.5}, @code{mreal} ap=@code{0})
++@deftypefnx {C function} @code{void} mgl_add_light (@code{HMGL} gr, @code{int} n, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz)
++@deftypefnx {C function} @code{void} mgl_add_light_ext (@code{HMGL} gr, @code{int} n, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{char} c, @code{mreal} bright, @code{mreal} ap)
++@deftypefnx {C function} @code{void} mgl_add_light_loc (@code{HMGL} gr, @code{int} n, @code{mreal} rx, @code{mreal} ry, @code{mreal} rz, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{char} c, @code{mreal} bright, @code{mreal} ap)
++@end ifclear
++The function adds a light source with identification @var{n} in direction @var{d} with color @var{c} and with brightness @var{bright} (which must be in range [0,1]). If position @var{r} is specified and isn't NAN then light source is supposed to be local otherwise light source is supposed to be placed at infinity.
++@end deftypefn
++
++@anchor{diffuse}
++@deftypefn {MGL command} {} diffuse @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetDiffuse (@code{mreal} bright)
++@deftypefnx {C function} @code{void} mgl_set_difbr (@code{HMGL} gr, @code{mreal} bright)
++@end ifclear
++Set brightness of diffusive light (only for local light sources).
++@end deftypefn
++
++@anchor{ambient}
++@deftypefn {MGL command} {} ambient @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetAmbient (@code{mreal} bright=@code{0.5})
++@deftypefnx {C function} @code{void} mgl_set_ambbr (@code{HMGL} gr, @code{mreal} bright)
++@end ifclear
++Sets the brightness of ambient light. The value should be in range [0,1].
++@end deftypefn
++
++@anchor{attachlight}
++@deftypefn {MGL command} {} attachlight @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} AttachLight (@code{bool} val)
++@deftypefnx {C function} @code{void} mgl_set_attach_light (@code{HMGL} gr, @code{int} val)
++@end ifclear
++Set to attach light settings to @ref{inplot}/@ref{subplot}. Note, OpenGL and some output formats don't support this feature.
++@end deftypefn
++
++@c ==================================================================
++@external{}
++@node Fog, Default sizes, Lighting, Graphics setup
++@subsection Fog
++@nav{}
++@cindex Fog
++
++@anchor{fog}
++@deftypefn {MGL command} {} fog @code{val [dz=0.25]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Fog (@code{mreal} d, @code{mreal} dz=@code{0.25})
++@deftypefnx {C function} @code{void} mgl_set_fog (@code{HMGL} gr, @code{mreal} d, @code{mreal} dz)
++@end ifclear
++Function imitate a fog in the plot. Fog start from relative distance @var{dz} from view point and its density growths exponentially in depth. So that the fog influence is determined by law ~ 1-exp(-@emph{d*z}). Here @emph{z} is normalized to 1 depth of the plot. If value @var{d}=@code{0} then the fog is absent. Note, that fog was applied at stage of image creation, not at stage of drawing. @sref{Adding fog}
++@end deftypefn
++
++@c ==================================================================
++@external{}
++@node Default sizes, Cutting, Fog, Graphics setup
++@subsection Default sizes
++@nav{}
++@ifclear UDAV
++@cindex SetBarWidth
++@cindex SetMarkSize
++@cindex SetArrowSize
++@cindex SetMeshNum
++@cindex SetPlotId
++@end ifclear
++@cindex BarWidth
++@cindex MarkSize
++@cindex ArrowSize
++@cindex MeshNum
++
++These variables control the default (initial) values for most graphics parameters including sizes of markers, arrows, line width and so on. As any other settings these ones will influence only on plots created after the settings change.
++
++@anchor{barwidth}
++@deftypefn {MGL command} {} barwidth @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetBarWidth ( @code{mreal} val)
++@deftypefnx {C function} @code{void} mgl_set_bar_width (@code{HMGL} gr, @code{mreal} val)
++@end ifclear
++Sets relative width of rectangles in @ref{bars}, @ref{barh}, @ref{boxplot}, @ref{candle}, @ref{ohlc}. Default value is @code{0.7}.
++@end deftypefn
++
++@anchor{marksize}
++@deftypefn {MGL command} {} marksize @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetMarkSize (@code{mreal} val)
++@deftypefnx {C function} @code{void} mgl_set_mark_size (@code{HMGL} gr, @code{mreal} val)
++@end ifclear
++Sets size of marks for @ref{1D plotting}. Default value is @code{1}.
++@end deftypefn
++
++@anchor{arrowsize}
++@deftypefn {MGL command} {} arrowsize @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetArrowSize (@code{mreal} val)
++@deftypefnx {C function} @code{void} mgl_set_arrow_size (@code{HMGL} gr, @code{mreal} val)
++@end ifclear
++Sets size of arrows for @ref{1D plotting}, lines and curves (see @ref{Primitives}). Default value is @code{1}.
++@end deftypefn
++
++@anchor{meshnum}
++@anchor{MeshNum}
++@deftypefn {MGL command} {} meshnum @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetMeshNum (@code{int} val)
++@deftypefnx {C function} @code{void} mgl_set_meshnum (@code{HMGL} gr, @code{int} num)
++@end ifclear
++Sets approximate number of lines in @ref{mesh}, @ref{fall}, @ref{grid2}, and also the number of hachures in @ref{vect}, @ref{dew}, and the number of cells in @ref{cloud}, and the number of markers in @ref{plot}, @ref{tens}, @ref{step}, @ref{mark}, @ref{textmark}. By default (=0) it draws all lines/hachures/cells/markers.
++@end deftypefn
++
++@anchor{facenum}
++@deftypefn {MGL command} {} facenum @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetFaceNum (@code{int} val)
++@deftypefnx {C function} @code{void} mgl_set_facenum (@code{HMGL} gr, @code{int} num)
++@end ifclear
++Sets approximate number of visible faces. Can be used for speeding up drawing by cost of lower quality. By default (=0) it draws all of them.
++@end deftypefn
++
++@anchor{plotid}
++@deftypefn {MGL command} {} plotid 'id'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetPlotId (@code{const char *}id)
++@deftypefnx {C function} @code{void} mgl_set_plotid (@code{HMGL} gr, @code{const char *}id)
++@end ifclear
++Sets default name @var{id} as filename for saving (in FLTK window for example).
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglGraph}} @code{const char *} GetPlotId ()
++@deftypefnx {C function only} @code{const char *} mgl_get_plotid (@code{HMGL} gr)
++@deftypefnx {Fortran subroutine} @code{} mgl_get_plotid (@code{long} gr, @code{char *}out, @code{int} len)
++Gets default name @var{id} as filename for saving (in FLTK window for example).
++@end deftypefn
++@end ifclear
++
++@anchor{pendelta}
++@deftypefn {MGL command} {} pendelta @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetPenDelta (@code{double} val)
++@deftypefnx {C function} @code{void} mgl_pen_delta (@code{HMGL} gr, @code{double} val)
++@end ifclear
++Changes the blur around lines and text (default is 1). For @var{val}>1 the text and lines are more sharped. For @var{val}<1 the text and lines are more blurred.
++@end deftypefn
++
++@c ==================================================================
++@external{}
++@node Cutting, Font settings, Default sizes, Graphics setup
++@subsection Cutting
++@nav{}
++@ifclear UDAV
++@cindex SetCut
++@cindex SetCutBox
++@cindex CutOff
++@end ifclear
++@cindex Cut
++
++These variables and functions set the condition when the points are excluded (cutted) from the drawing. Note, that a point with NAN value(s) of coordinate or amplitude will be automatically excluded from the drawing. @sref{Cutting sample}
++
++@anchor{cut}
++@deftypefn {MGL command} {} cut @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetCut (@code{bool} val)
++@deftypefnx {C function} @code{void} mgl_set_cut (@code{HMGL} gr, @code{int} val)
++@end ifclear
++Flag which determines how points outside bounding box are drawn. If it is @code{true} then points are excluded from plot (it is default) otherwise the points are projected to edges of bounding box.
++@end deftypefn
++
++@deftypefn {MGL command} {} cut @code{x1 y1 z1 x2 y2 z2}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetCutBox (@code{mglPoint} p1, @code{mglPoint} p1)
++@deftypefnx {C function} @code{void} mgl_set_cut_box (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2)
++@end ifclear
++Lower and upper edge of the box in which never points are drawn. If both edges are the same (the variables are equal) then the cutting box is empty.
++@end deftypefn
++
++@deftypefn {MGL command} {} cut 'cond'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} CutOff (@code{const char *}cond)
++@deftypefnx {C function} @code{void} mgl_set_cutoff (@code{HMGL} gr, @code{const char *}cond)
++@end ifclear
++Sets the cutting off condition by formula @var{cond}. This condition determine will point be plotted or not. If value of formula is nonzero then point is omitted, otherwise it plotted. Set argument as @code{""} to disable cutting off condition.
++@end deftypefn
++
++@c ==================================================================
++@external{}
++@node Font settings, Palette and colors, Cutting, Graphics setup
++@subsection Font settings
++@nav{}
++@ifclear UDAV
++@cindex SetFontSize
++@cindex SetFontDef
++@cindex SetRotatedText
++@cindex SetFontSizePT
++@cindex SetFontSizeCM
++@cindex SetFontSizeIN
++@cindex LoadFont
++@cindex CopyFont
++@cindex RestoreFont
++@end ifclear
++@cindex Font
++@cindex RotateText
++
++@anchor{font}
++@deftypefn {MGL command} {} font 'fnt' [@code{val=6}]
++Font style for text and labels (see text). Initial style is 'fnt'=':rC' give Roman font with centering. Parameter @code{val} sets the size of font for tick and axis labels. Default font size of axis labels is 1.4 times large than for tick labels. For more detail, see @ref{Font styles}.
++@end deftypefn
++
++@anchor{rotatetext}
++@deftypefn {MGL command} {} rotatetext @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetRotatedText (@code{bool} val)
++@deftypefnx {C function} @code{void} mgl_set_rotated_text (@code{HMGL} gr, @code{int} val)
++@end ifclear
++Sets to use or not text rotation.
++@end deftypefn
++
++@anchor{loadfont}
++@deftypefn {MGL command} {} loadfont ['name'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} LoadFont (@code{const char *}name, @code{const char *}path=@code{""})
++@deftypefnx {C function} @code{void} mgl_load_font (@code{HMGL} gr, @code{const char *}name, @code{const char *}path)
++@end ifclear
++Load font typeface from @var{path}/@var{name}. Empty name will load default font.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglGraph}} @code{void} SetFontDef (@code{const char *}fnt)
++@deftypefnx {C function} @code{void} mgl_set_font_def (@code{HMGL} gr, @code{const char *} val)
++Sets the font specification (see @ref{Text printing}). Default is @samp{rC} -- Roman font centering.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SetFontSize (@code{mreal} val)
++@deftypefnx {C function} @code{void} mgl_set_font_size (@code{HMGL} gr, @code{mreal} val)
++Sets the size of font for tick and axis labels. Default font size of axis labels is 1.4 times large than for tick labels.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SetFontSizePT (@code{mreal} cm, @code{int} dpi=@code{72})
++Set FontSize by size in pt and picture DPI (default is 16 pt for dpi=72).
++@end deftypefn
++@deftypefn {Method on @code{mglGraph}} @code{inline void} SetFontSizeCM (@code{mreal} cm, @code{int} dpi=@code{72})
++Set FontSize by size in centimeters and picture DPI (default is 0.56 cm = 16 pt).
++@end deftypefn
++@deftypefn {Method on @code{mglGraph}} @code{inline void} SetFontSizeIN (@code{mreal} cm, @code{int} dpi=@code{72})
++Set FontSize by size in inch and picture DPI (default is 0.22 in = 16 pt).
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} CopyFont (@code{mglGraph *} from)
++@deftypefnx {C function} @code{void} mgl_copy_font (@code{HMGL} gr, @code{HMGL} gr_from)
++Copy font data from another @code{mglGraph} object.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} RestoreFont ()
++@deftypefnx {C function} @code{void} mgl_restore_font (@code{HMGL} gr)
++Restore font data to default typeface.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SetDefFont (@code{const char *}name, @code{const char *}path=@code{""}) static
++@deftypefnx {C function} @code{void} mgl_def_font (@code{const char *}name, @code{const char *}path)
++Load default font typeface (for all newly created HMGL/mglGraph objects) from @var{path}/@var{name}.
++@end deftypefn
++
++@end ifclear
++
++@c ==================================================================
++@external{}
++@node Palette and colors, Masks, Font settings, Graphics setup
++@subsection Palette and colors
++@nav{}
++@ifclear UDAV
++@cindex SetPalette
++@end ifclear
++@cindex Palette
++
++@anchor{palette}
++@deftypefn {MGL command} {} palette 'colors'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetPalette (@code{const char *}colors)
++@deftypefnx {C function} @code{void} mgl_set_palette (@code{HMGL} gr, @code{const char *}colors)
++@end ifclear
++Sets the palette as selected colors. Default value is @code{"Hbgrcmyhlnqeup"} that corresponds to colors: dark gray @samp{H}, blue @samp{b}, green @samp{g}, red @samp{r}, cyan @samp{c}, magenta @samp{m}, yellow @samp{y}, gray @samp{h}, blue-green @samp{l}, sky-blue @samp{n}, orange @samp{q}, yellow-green @samp{e}, blue-violet @samp{u}, purple @samp{p}. The palette is used mostly in 1D plots (see @ref{1D plotting}) for curves which styles are not specified. Internal color counter will be nullified by any change of palette. This includes even hidden change (for example, by @ref{box} or @ref{axis} functions).
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglGraph}} @code{void} SetDefScheme (@code{const char *}sch)
++@deftypefnx {C function} @code{void} mgl_set_def_sch (@code{HMGL} gr, @code{const char *}sch)
++Sets the @var{sch} as default color scheme. Default value is @code{"BbcyrR"}.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SetColor (@code{char} id, @code{mreal} r, @code{mreal} g, @code{mreal} b) static
++@deftypefnx {C function} @code{void} mgl_set_color (@code{char} id, @code{mreal} r, @code{mreal} g, @code{mreal} b)
++Sets RGB values for color with given @var{id}. This is global setting which influence on any later usage of symbol @var{id}.
++@end deftypefn
++@end ifclear
++
++
++@anchor{gray}
++<<<<<<< HEAD
++@deftypefn {MGL command} {} gray @code{val}
++=======
++@deftypefn {MGL command} {} gray [@code{val=on}]
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Gray (@code{bool} enable)
++@deftypefnx {C function} @code{void} mgl_set_gray (@code{HMGL} gr, @code{int} enable)
++@end ifclear
++Sets the gray-scale mode on/off.
++@end deftypefn
++
++@c ==================================================================
++@external{}
++@node Masks, Error handling, Palette and colors, Graphics setup
++@subsection Masks
++@nav{}
++@cindex SetMask
++@cindex SetMaskAngle
++
++@anchor{mask}
++@deftypefn {MGL command} {} mask 'id' 'hex'
++@deftypefnx {Команда MGL} {} mask 'id' hex
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetMask (@code{char} id, @code{const char *}hex)
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetMask (@code{char} id, @code{uint64_t} hex)
++@deftypefnx {C function} @code{void} mgl_set_mask (@code{HMGL} gr, @code{const char *}hex)
++@deftypefnx {C function} @code{void} mgl_set_mask_val (@code{HMGL} gr, @code{uint64_t} hex)
++@end ifclear
++Sets new bit matrix @var{hex} of size 8*8 for mask with given @var{id}. This is global setting which influence on any later usage of symbol @var{id}. The predefined masks are (see @ref{Color scheme}): @samp{-} is 000000FF00000000, @samp{+} is 080808FF08080808, @samp{=} is 0000FF00FF000000, @samp{;} is 0000007700000000, @samp{o} is 0000182424180000, @samp{O} is 0000183C3C180000, @samp{s} is 00003C24243C0000, @samp{S} is 00003C3C3C3C0000, @samp{~} is 0000060990600000, @samp{<} is 0060584658600000, @samp{>} is 00061A621A060000, @samp{j} is 0000005F00000000, @samp{d} is 0008142214080000, @samp{D} is 00081C3E1C080000, @samp{*} is 8142241818244281, @samp{^} is 0000001824420000.
++@end deftypefn
++
++@deftypefn {MGL command} {} mask angle
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetMaskAngle (@code{int} angle)
++@deftypefnx {C function} @code{void} mgl_set_mask_angle (@code{HMGL} gr, @code{int} angle)
++@end ifclear
++Sets the default rotation angle (in degrees) for masks. Note, you can use symbols @samp{\}, @samp{/}, @samp{I} in color scheme for setting rotation angles as 45, -45 and 90 degrees correspondingly.
++@end deftypefn
++
++
++@c ==================================================================
++@external{}
++@node Error handling, Stop drawing, Masks, Graphics setup
++@subsection Error handling
++@nav{}
++@ifset UDAV
++All warnings will be displayed automatically in special tool-window or in console.
++@end ifset
++@ifclear UDAV
++@cindex Message
++@cindex SetWarn
++@cindex GetWarn
++
++Normally user should set it to zero by @code{SetWarn(0);} before plotting and check if @code{GetWarn()} or @code{Message()} return non zero after plotting. Only last warning will be saved. All warnings/errors produced by MathGL is not critical -- the plot just will not be drawn. By default, all warnings are printed in stderr. You can disable it by using @code{mgl_suppress_warn(true);}.
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SetWarn (@code{int} code, @code{const char *}info=@code{""})
++@deftypefnx {C function} @code{void} mgl_set_warn (@code{HMGL} gr, @code{int} code, @code{const char *}info)
++Set warning code. Normally you should call this function only for clearing the warning state, i.e. call @code{SetWarn(0);}. Text @var{info} will be printed as is if @var{code}<0.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{const char *}Message ()
++@deftypefnx {C function only} @code{const char *}mgl_get_mess (@code{HMGL} gr)
++@deftypefnx {Fortran subroutine} @code{} mgl_get_mess (@code{long} gr, @code{char *}out, @code{int} len)
++Return messages about matters why some plot are not drawn. If returned string is empty then there are no messages.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{int} GetWarn ()
++@deftypefnx {C function} @code{int} mgl_get_warn (@code{HMGL} gr)
++Return the numerical ID of warning about the not drawn plot. Possible values are:
++@table @code
++@item mglWarnNone=0
++Everything OK
++@item mglWarnDim
++Data dimension(s) is incompatible
++@item mglWarnLow
++Data dimension(s) is too small
++@item mglWarnNeg
++Minimal data value is negative
++@item mglWarnFile
++No file or wrong data dimensions
++@item mglWarnMem
++Not enough memory
++@item mglWarnZero
++Data values are zero
++@item mglWarnLeg
++No legend entries
++@item mglWarnSlc
++Slice value is out of range
++@item mglWarnCnt
++Number of contours is zero or negative
++@item mglWarnOpen
++Couldn't open file
++@item mglWarnLId
++Light: ID is out of range
++@item mglWarnSize
++Setsize: size(s) is zero or negative
++@item mglWarnFmt
++Format is not supported for that build
++@item mglWarnTern
++Axis ranges are incompatible
++@item mglWarnNull
++Pointer is NULL
++@item mglWarnSpc
++Not enough space for plot
++@item mglScrArg
++Wrong argument(s) of a command in MGL script
++@item mglScrCmd
++Wrong command in MGL script
++@item mglScrLong
++Too long line in MGL script
++@item mglScrStr
++Unbalanced ' in MGL script
++@item mglScrTemp
++Change temporary data in MGL script
++@end table
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SuppressWarn (@code{bool} state) static
++@deftypefnx {C function} @code{void} mgl_suppress_warn (@code{int} state)
++Disable printing warnings to @code{stderr} if @var{state} is nonzero.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SetGlobalWarn (@code{const char *}info) static
++@deftypefnx {C function} @code{void} mgl_set_global_warn (@code{const char *}info)
++Set warning message @var{info} for global scope.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{const char *} GlobalWarn () static
++@deftypefnx {C function} @code{const char *} mgl_get_global_warn ()
++Get warning message(s) for global scope.
++@end deftypefn
++
++@end ifclear
++
++@c ==================================================================
++@external{}
++@node Stop drawing, , Error handling, Graphics setup
++@subsection Stop drawing
++@nav{}
++@ifset UDAV
++You can use @ref{stop} command or press corresponding toolbutton to stop drawing and script execution.
++@end ifset
++@ifclear UDAV
++@cindex Stop
++@cindex NeedStop
++@cindex SetEventFunc
++
++@deftypefn {Method on @code{mglGraph}} @code{void} Stop (@code{bool} stop=@code{true})
++@deftypefnx {C function only} @code{void} mgl_ask_stop (@code{HMGL} gr, @code{int} stop)
++Ask to stop drawing if @var{stop} is non-zero, otherwise reset stop flag.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{bool} NeedStop ()
++@deftypefnx {C function only} @code{void} mgl_need_stop (@code{HMGL} gr)
++Return @code{true} if drawing should be terminated. Also it process all events in GUI. User should call this function from time to time inside a long calculation to allow processing events for GUI.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{bool} SetEventFunc (@code{void (*}func@code{)(void *)}, @code{void *}par=@code{NULL})
++@deftypefnx {C function only} @code{void} mgl_set_event_func (@code{HMGL} gr, @code{void (*}func@code{)(void *)}, @code{void *}par)
++Set callback function which will be called to process events of GUI library.
++@end deftypefn
++
++@end ifclear
++
++@c ==================================================================
++@external{}
++@node Axis settings, Subplots and rotation, Graphics setup, MathGL core
++@section Axis settings
++@nav{}
++
++These large set of variables and functions control how the axis and ticks will be drawn. Note that there is 3-step transformation of data coordinates are performed. Firstly, coordinates are projected if @code{Cut=true} (see @ref{Cutting}), after it transformation formulas are applied, and finally the data was normalized in bounding box. Note, that MathGL will produce warning if axis range and transformation formulas are not compatible.
++
++@menu
++* Ranges (bounding box)::
++* Curved coordinates::
++* Ticks::
++@end menu
++
++@c ------------------------------------------------------------------
++@external{}
++@node Ranges (bounding box), Curved coordinates, , Axis settings
++@subsection Ranges (bounding box)
++@nav{}
++@cindex CRange
++@cindex XRange
++@cindex YRange
++@cindex ZRange
++@cindex Ranges
++@cindex Origin
++@ifclear UDAV
++@cindex SetRange
++@cindex SetRanges
++@cindex SetOrigin
++@end ifclear
++
++@anchor{xrange}
++@anchor{yrange}
++@anchor{zrange}
++@anchor{crange}
++@deftypefn {MGL command} {} xrange @code{v1 v2} [@code{add=off}]
++@deftypefnx {MGL command} {} yrange @code{v1 v2} [@code{add=off}]
++@deftypefnx {MGL command} {} zrange @code{v1 v2} [@code{add=off}]
++@deftypefnx {MGL command} {} crange @code{v1 v2} [@code{add=off}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetRange (@code{char} dir, @code{mreal} v1, @code{mreal} v2)
++@deftypefnx {Method on @code{mglGraph}} @code{void} AddRange (@code{char} dir, @code{mreal} v1, @code{mreal} v2)
++@deftypefnx {C function} @code{void} mgl_set_range_val (@code{HMGL} gr, @code{char} dir, @code{mreal} v1, @code{mreal} v2)
++@deftypefnx {C function} @code{void} mgl_add_range_val (@code{HMGL} gr, @code{char} dir, @code{mreal} v1, @code{mreal} v2)
++@end ifclear
++Sets or adds the range for @samp{x}-,@samp{y}-,@samp{z}- coordinate or coloring (@samp{c}). If one of values is @code{NAN} then it is ignored. See also @ref{ranges}.
++@end deftypefn
++
++
++@deftypefn {MGL command} {} xrange dat [@code{add=off}]
++@deftypefnx {MGL command} {} yrange dat [@code{add=off}]
++@deftypefnx {MGL command} {} zrange dat [@code{add=off}]
++@deftypefnx {MGL command} {} crange dat [@code{add=off}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetRange (@code{char} dir, @code{const mglDataA &}dat, @code{bool} add=@code{false})
++@deftypefnx {C function} @code{void} mgl_set_range_dat (@code{HMGL} gr, @code{char} dir, @code{const HCDT} a, @code{int} add)
++@end ifclear
++Sets the range for @samp{x}-,@samp{y}-,@samp{z}- coordinate or coloring (@samp{c}) as minimal and maximal values of data @var{dat}. Parameter @code{add=on} shows that the new range will be joined to existed one (not replace it).
++@end deftypefn
++
++@anchor{ranges}
++@deftypefn {MGL command} {} ranges @code{x1 x2 y1 y2 [z1=0 z2=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetRanges (@code{mglPoint} p1, @code{mglPoint} p2)
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetRanges (@code{double} x1, @code{double} x2, @code{double} y1, @code{double} y2, @code{double} z1=@code{0}, @code{double} z2=@code{0})
++@deftypefnx {C function} @code{void} mgl_set_ranges (@code{HMGL} gr, @code{double} x1, @code{double} x2, @code{double} y1, @code{double} y2, @code{double} z1, @code{double} z2)
++@end ifclear
++Sets the ranges of coordinates. If minimal and maximal values of the coordinate are the same then they are ignored. Also it sets the range for coloring (analogous to @code{crange z1 z2}). This is default color range for 2d plots. Initial ranges are [-1, 1].
++@end deftypefn
++
++@deftypefn {MGL command} {} ranges @code{xx yy [zz cc=zz]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetRanges (@code{const mglDataA &}xx, @code{const mglDataA &}yy)
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetRanges (@code{const mglDataA &}xx, @code{const mglDataA &}yy, @code{const mglDataA &}zz)
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetRanges (@code{const mglDataA &}xx, @code{const mglDataA &}yy, @code{const mglDataA &}zz, @code{const mglDataA &}cc)
++@end ifclear
++Sets the ranges of @samp{x}-,@samp{y}-,@samp{z}-,@samp{c}-coordinates and coloring as minimal and maximal values of data @var{xx}, @var{yy}, @var{zz}, @var{cc} correspondingly.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglGraph}} @code{void} SetAutoRanges (@code{mglPoint} p1, @code{mglPoint} p2)
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetAutoRanges (@code{double} x1, @code{double} x2, @code{double} y1, @code{double} y2, @code{double} z1=@code{0}, @code{double} z2=@code{0}, @code{double} c1=@code{0}, @code{double} c2=@code{0})
++@deftypefnx {C function} @code{void} mgl_set_auto_ranges (@code{HMGL} gr, @code{double} x1, @code{double} x2, @code{double} y1, @code{double} y2, @code{double} z1, @code{double} z2, @code{double} z1, @code{double} z2)
++Sets the ranges for automatic coordinates. If minimal and maximal values of the coordinate are the same then they are ignored.
++@end deftypefn
++@end ifclear
++
++@anchor{origin}
++@deftypefn {MGL command} {} origin @code{x0 y0 [z0=nan]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetOrigin (@code{mglPoint} p0)
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetOrigin (@code{mreal} x0, @code{mreal} y0, @code{mreal} z0=@code{NAN})
++@deftypefnx {C function} @code{void} mgl_set_origin (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0)
++@end ifclear
++Sets center of axis cross section. If one of values is NAN then MathGL try to select optimal axis position.
++@end deftypefn
++
++@anchor{zoomaxis}
++@deftypefn {MGL command} {} zoomaxis @code{x1 x2}
++@deftypefnx {MGL command} {} zoomaxis @code{x1 y1 x2 y2}
++@deftypefnx {MGL command} {} zoomaxis @code{x1 y1 z1 x2 y2 z2}
++@deftypefnx {MGL command} {} zoomaxis @code{x1 y1 z1 c1 x2 y2 z2 c2}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ZoomAxis (@code{mglPoint} p1, @code{mglPoint} p2)
++@deftypefnx {C function} @code{void} mgl_zoom_axis (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} c1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{mreal} c2)
++@end ifclear
++Additionally extend axis range for any settings made by @code{SetRange} or @code{SetRanges} functions according the formula @math{min += (max-min)*p1} and @math{max += (max-min)*p1} (or @math{min *= (max/min)^p1} and @math{max *= (max/min)^p1} for log-axis range when @math{inf>max/min>100} or @math{0<max/min<0.01}). Initial ranges are [0, 1]. Attention! this settings can not be overwritten by any other functions, including @code{DefaultPlotParam()}.
++@end deftypefn
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node Curved coordinates, Ticks, Ranges (bounding box), Axis settings
++@subsection Curved coordinates
++@nav{}
++@cindex Axis
++@ifclear UDAV
++@cindex SetFunc
++@cindex SetCoor
++@cindex Ternary
++@end ifclear
++
++@deftypefn {MGL command} {} axis 'fx' 'fy' 'fz' ['fa'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetFunc (@code{const char *}EqX, @code{const char *}EqY, @code{const char *}EqZ=@code{""}, @code{const char *}EqA=@code{""})
++@deftypefnx {C function} @code{void} mgl_set_func (@code{HMGL} gr, @code{const char *}EqX, @code{const char *}EqY, @code{const char *}EqZ, @code{const char *}EqA)
++@end ifclear
++Sets transformation formulas for curvilinear coordinate. Each string should contain mathematical expression for real coordinate depending on internal coordinates @samp{x}, @samp{y}, @samp{z} and @samp{a} or @samp{c} for colorbar. For example, the cylindrical coordinates are introduced as @code{SetFunc("x*cos(y)", "x*sin(y)", "z");}. For removing of formulas the corresponding parameter should be empty or @code{NULL}. Using transformation formulas will slightly slowing the program. Parameter @var{EqA} set the similar transformation formula for color scheme. @xref{Textual formulas}.
++@end deftypefn
++
++@deftypefn {MGL command} {} axis @code{how}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetCoor (@code{int} how)
++@deftypefnx {C function} @code{void} mgl_set_coor (@code{HMGL} gr, @code{int} how)
++@end ifclear
++Sets one of the predefined transformation formulas for curvilinear coordinate. Parameter @var{how} define the coordinates:
++@table @code
++@item mglCartesian=0
++Cartesian coordinates (no transformation, @{x,y,z@});
++@item mglPolar=1
++Polar coordinates: @{x*cos(y), x*sin(y), z@};
++@item mglSpherical=2
++Sperical coordinates: @{x*sin(y)*cos(z), x*sin(y)*sin(z), x*cos(y)@};
++@item mglParabolic=3
++Parabolic coordinates: @{x*y, (x*x-y*y)/2, z@}
++@item mglParaboloidal=4
++Paraboloidal coordinates: @{(x*x-y*y)*cos(z)/2, (x*x-y*y)*sin(z)/2, x*y@};
++@item mglOblate=5
++Oblate coordinates: @{cosh(x)*cos(y)*cos(z), cosh(x)*cos(y)*sin(z), sinh(x)*sin(y)@};
++@item mglProlate=6
++Prolate coordinates: @{sinh(x)*sin(y)*cos(z), sinh(x)*sin(y)*sin(z), cosh(x)*cos(y)@};
++@item mglElliptic=7
++Elliptic coordinates: @{cosh(x)*cos(y), sinh(x)*sin(y), z@};
++@item mglToroidal=8
++Toroidal coordinates: @{sinh(x)*cos(z)/(cosh(x)-cos(y)), sinh(x)*sin(z)/(cosh(x)-cos(y)), sin(y)/(cosh(x)-cos(y))@};
++@item mglBispherical=9
++Bispherical coordinates: @{sin(y)*cos(z)/(cosh(x)-cos(y)), sin(y)*sin(z)/(cosh(x)-cos(y)), sinh(x)/(cosh(x)-cos(y))@};
++@item mglBipolar=10
++Bipolar coordinates: @{sinh(x)/(cosh(x)-cos(y)), sin(y)/(cosh(x)-cos(y)), z@};
++@item mglLogLog=11
++Log-log coordinates: @{lg(x), lg(y), lg(z)@};
++@item mglLogX=12
++Log-x coordinates: @{lg(x), y, z@};
++@item mglLogY=13
++Log-y coordinates: @{x, lg(y), z@}.
++@end table
++@end deftypefn
++
++@anchor{ternary}
++@deftypefn {MGL command} {} ternary @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Ternary (@code{int} tern)
++@deftypefnx {C function} @code{void} mgl_set_ternary (@code{HMGL} gr, @code{int} tern)
++@end ifclear
++The function sets to draws Ternary (@var{tern}=@code{1}), Quaternary (@var{tern}=@code{2}) plot or projections (@var{tern}=@code{4,5,6}).
++
++Ternary plot is special plot for 3 dependent coordinates (components) @var{a}, @var{b}, @var{c} so that @var{a}+@var{b}+@var{c}=1. MathGL uses only 2 independent coordinates @var{a}=x and @var{b}=y since it is enough to plot everything. At this third coordinate z act as another parameter to produce contour lines, surfaces and so on.
++
++Correspondingly, Quaternary plot is plot for 4 dependent coordinates @var{a}, @var{b}, @var{c} and @var{d} so that @var{a}+@var{b}+@var{c}+@var{d}=1. MathGL uses only 3 independent coordinates @var{a}=x, @var{b}=y and @var{d}=z since it is enough to plot everything.
++
++Projections can be obtained by adding value @code{4} to @var{tern} argument. So, that @var{tern}=@code{4} will draw projections in Cartesian coordinates, @var{tern}=@code{5} will draw projections in Ternary coordinates, @var{tern}=@code{6} will draw projections in Quaternary coordinates. If you add @code{8} instead of @code{4} then all text labels will not be printed on projections.
++
++Use @code{Ternary(0)} for returning to usual axis. @sref{Ternary axis} @sref{Axis projection}
++@end deftypefn
++
++@c ------------------------------------------------------------------
++@external{}
++@node Ticks, , Curved coordinates, Axis settings
++@subsection Ticks
++@nav{}
++@cindex AxisStl
++@cindex TickLen
++@cindex Adjust
++@cindex XTick
++@cindex YTick
++@cindex ZTick
++@cindex CTick
++@ifclear UDAV
++@cindex SetAxisStl
++@cindex SetTickLen
++@cindex SetTicks
++@cindex SetTicksVal
++@cindex SetTuneTicks
++@cindex SetTickTime
++@cindex SetTickTempl
++@cindex SetTickRotate
++@cindex SetTickSkip
++@cindex SetOriginTick
++@cindex AddTick
++@end ifclear
++
++@anchor{adjust}
++@deftypefn {MGL command} {} adjust ['dir'='xyzc']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Adjust (@code{const char *}dir=@code{"xyzc"})
++@deftypefnx {C function} @code{void} mgl_adjust_ticks (@code{HMGL} gr, @code{const char *}dir)
++@end ifclear
++Set the ticks step, number of sub-ticks and initial ticks position to be the most human readable for the axis along direction(s) @var{dir}. Also set @code{SetTuneTicks(true)}. Usually you don't need to call this function except the case of returning to default settings.
++@end deftypefn
++
++@anchor{xtick}
++@anchor{ytick}
++@anchor{ztick}
++@anchor{ctick}
++@deftypefn {MGL command} {} xtick @code{val [sub=0 org=nan 'fact'='']}
++@deftypefnx {MGL command} {} ytick @code{val [sub=0 org=nan 'fact'='']}
++@deftypefnx {MGL command} {} ztick @code{val [sub=0 org=nan 'fact'='']}
++@deftypefnx {MGL command} {} ctick @code{val [sub=0 org=nan 'fact'='']}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTicks (@code{char} dir, @code{mreal} d=@code{0}, @code{int} ns=@code{0}, @code{mreal} org=@code{NAN}, @code{const char *}fact=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTicks (@code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org, @code{const wchar_t *}fact)
++@deftypefnx {C function} @code{void} mgl_set_ticks (@code{HMGL} gr, @code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org)
++@deftypefnx {C function} @code{void} mgl_set_ticks_fact (@code{HMGL} gr, @code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org, @code{const char *}fact)
++@deftypefnx {C function} @code{void} mgl_set_ticks_factw (@code{HMGL} gr, @code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org, @code{const wchar_t *}fact)
++@end ifclear
++Set the ticks step @var{d}, number of sub-ticks @var{ns} (used for positive @var{d}) and initial ticks position @var{org} for the axis along direction @var{dir} (use 'c' for colorbar ticks). Variable @var{d} set step for axis ticks (if positive) or it's number on the axis range (if negative). Zero value set automatic ticks. If @var{org} value is NAN then axis origin is used. Parameter @var{fact} set text which will be printed after tick label (like "\pi" for @var{d}=M_PI).
++@end deftypefn
++
++@deftypefn {MGL command} {} xtick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
++@deftypefnx {MGL command} {} ytick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
++@deftypefnx {MGL command} {} ztick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
++@deftypefnx {MGL command} {} xtick vdat 'lbls' [@code{add=off}]
++@deftypefnx {MGL command} {} ytick vdat 'lbls' [@code{add=off}]
++@deftypefnx {MGL command} {} ztick vdat 'lbls' [@code{add=off}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const char *}lbl, @code{bool} add=@code{false})
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const wchar_t *}lbl, @code{bool} add=@code{false})
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const mglDataA &}val, @code{const char *}lbl, @code{bool} add=@code{false})
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const mglDataA &}val, @code{const wchar_t *}lbl, @code{bool} add=@code{false})
++@deftypefnx {C function} @code{void} mgl_set_ticks_str (@code{HMGL} gr, @code{char} dir, @code{const char *}lbl, @code{bool} add)
++@deftypefnx {C function} @code{void} mgl_set_ticks_wcs (@code{HMGL} gr, @code{char} dir, @code{const wchar_t *}lbl, @code{bool} add)
++@deftypefnx {C function} @code{void} mgl_set_ticks_val (@code{HMGL} gr, @code{char} dir, @code{HCDT} val, @code{const char *}lbl, @code{bool} add)
++@deftypefnx {C function} @code{void} mgl_set_ticks_valw (@code{HMGL} gr, @code{char} dir, @code{HCDT} val, @code{const wchar_t *}lbl, @code{bool} add)
++@end ifclear
++Set the manual positions @var{val} and its labels @var{lbl} for ticks along axis @var{dir}. If array @var{val} is absent then values equidistantly distributed in x-axis range are used. Labels are separated by @samp{\n} symbol. If only one value is specified in MGL command then the label will be @emph{add} to the current ones. Use @code{SetTicks()} to restore automatic ticks.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglGraph}} @code{void} AddTick (@code{char} dir, @code{double} val, @code{const char *}lbl)
++@deftypefnx {Method on @code{mglGraph}} @code{void} AddTick (@code{char} dir, @code{double} val, @code{const wchar_t *}lbl)
++@deftypefnx {C function} @code{void} mgl_add_tick (@code{HMGL} gr, @code{char} dir, @code{double} val, @code{const char *}lbl)
++@deftypefnx {C function} @code{void} mgl_set_tickw (@code{HMGL} gr, @code{char} dir, @code{double} val, @code{const wchar_t *}lbl)
++The same as previous but add single tick label @var{lbl} at position @var{val} to the list of existed ones.
++@end deftypefn
++@end ifclear
++
++@deftypefn {MGL command} {} xtick 'templ'
++@deftypefnx {MGL command} {} ytick 'templ'
++@deftypefnx {MGL command} {} ztick 'templ'
++@deftypefnx {MGL command} {} ctick 'templ'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTickTempl (@code{char} dir, @code{const char *}templ)
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTickTempl (@code{char} dir, @code{const wchar_t *}templ)
++@deftypefnx {C function} @code{void} mgl_set_tick_templ (@code{HMGL} gr, @code{const char *}templ)
++@deftypefnx {C function} @code{void} mgl_set_tick_templw (@code{HMGL} gr, @code{const wchar_t *}templ)
++@end ifclear
++Set template @var{templ} for x-,y-,z-axis ticks or colorbar ticks. It may contain TeX symbols also. If @var{templ}=@code{""} then default template is used (in simplest case it is @samp{%.2g}). If template start with @samp{&} symbol then @code{long} integer value will be passed instead of default type @code{double}. Setting on template switch off automatic ticks tuning.
++@end deftypefn
++
++@anchor{ticktime}
++@deftypefn {MGL command} {} ticktime 'dir' [@code{dv=0} 'tmpl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTicksTime (@code{char} dir, @code{mreal} val, @code{const char *}templ)
++@deftypefnx {C function} @code{void} mgl_set_ticks_time (@code{HMGL} gr, @code{mreal} val, @code{const char *}templ)
++@end ifclear
++Sets time labels with step @var{val} and template @var{templ} for x-,y-,z-axis ticks or colorbar ticks. It may contain TeX symbols also. The format of template @var{templ} is the same as described in @url{http://www.manpagez.com/man/3/strftime/}. Most common variants are @samp{%X} for national representation of time, @samp{%x} for national representation of date, @samp{%Y} for year with century. If @var{val}=0 and/or @var{templ}="" then automatic tick step and/or template will be selected. You can use @code{mgl_get_time}() function for obtaining number of second for given date/time string. Note, that MS Visual Studio couldn't handle date before 1970.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {C function} @code{double} mgl_get_time (@code{const char*}str, @code{const char *}templ)
++Gets number of seconds from 1970 year to specified date/time @var{str}. The format of string is specified by @var{templ}, which is the same as described in @url{http://www.manpagez.com/man/3/strftime/}. Most common variants are @samp{%X} for national representation of time, @samp{%x} for national representation of date, @samp{%Y} for year with century. Note, that MS Visual Studio couldn't handle date before 1970.
++@end deftypefn
++@end ifclear
++
++@anchor{tuneticks}
++@deftypefn {MGL command} {} tuneticks @code{val} [@code{pos=1.15}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTuneTicks (@code{int} tune, @code{mreal} pos=@code{1.15})
++@deftypefnx {C function} @code{void} mgl_tune_ticks (@code{HMGL} gr, @code{int} tune, @code{mreal} pos)
++@end ifclear
++Switch on/off ticks enhancing by factoring common multiplier (for small, like from 0.001 to 0.002, or large, like from 1000 to 2000, coordinate values -- enabled if @var{tune}&1 is nonzero) or common component (for narrow range, like from 0.999 to 1.000 -- enabled if @var{tune}&2 is nonzero). Also set the position @var{pos} of common multiplier/component on the axis: =0 at minimal axis value, =1 at maximal axis value. Default value is 1.15.
++@end deftypefn
++
++@anchor{tickshift}
++@deftypefn {MGL command} {} tickshift @code{dx [dy=0 dz=0 dc=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTickShift (@code{mglPoint} d)
++@deftypefnx {C function} @code{void} mgl_set_tick_shift (@code{HMGL} gr, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{mreal} dc)
++@end ifclear
++Set value of additional shift for ticks labels.
++@end deftypefn
++
++@ifclear UDAV
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SetTickRotate (@code{bool} val)
++@deftypefnx {C function} @code{void} mgl_set_tick_rotate (@code{HMGL} gr, @code{bool} val)
++Enable/disable ticks rotation if there are too many ticks or ticks labels are too long.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SetTickSkip (@code{bool} val)
++@deftypefnx {C function} @code{void} mgl_set_tick_skip (@code{HMGL} gr, @code{bool} val)
++Enable/disable ticks skipping if there are too many ticks or ticks labels are too long.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SetTimeUTC (@code{bool} val)
++@c @deftypefnx {C function} @code{void} mgl_set_tick_skip (@code{HMGL} gr, @code{bool} val)
++Enable/disable using UTC time for ticks labels. In C/Fortran you can use @code{mgl_set_flag(gr,val, MGL_USE_GMTIME);}.
++@end deftypefn
++
++@end ifclear
++
++@anchor{origintick}
++@deftypefn {MGL command} {} origintick @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetOriginTick (@code{bool} val=@code{true})
++@end ifclear
++Enable/disable drawing of ticks labels at axis origin. In C/Fortran you can use @code{mgl_set_flag(gr,val, MGL_NO_ORIGIN);}.
++@end deftypefn
++
++@anchor{ticklen}
++@deftypefn {MGL command} {} ticklen @code{val} [@code{stt=1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetTickLen (@code{mreal} val, @code{mreal} stt=@code{1})
++@deftypefnx {C function} @code{void} mgl_set_tick_len (@code{HMGL} gr, @code{mreal} val, @code{mreal} stt)
++@end ifclear
++The relative length of axis ticks. Default value is @code{0.1}. Parameter @var{stt}>0 set relative length of subticks which is in @code{sqrt(1+stt)} times smaller.
++@end deftypefn
++
++@deftypefn {MGL command} {} axisstl 'stl' ['tck'='' 'sub'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetAxisStl (@code{const char *}stl=@code{"k"}, @code{const char *}tck=@code{0}, @code{const char *}sub=@code{0})
++@deftypefnx {C function} @code{void} mgl_set_axis_stl (@code{HMGL} gr, @code{const char *}stl, @code{const char *}tck, @code{const char *}sub)
++@end ifclear
++The line style of axis (@var{stl}), ticks (@var{tck}) and subticks (@var{sub}). If @var{stl} is empty then default style is used (@samp{k} or @samp{w} depending on transparency type). If @var{tck} or @var{sub} is empty then axis style is used (i.e. @var{stl}).
++@end deftypefn
++
++@c ##################################################################
++@external{}
++@node Subplots and rotation, Export picture, Axis settings, MathGL core
++@section Subplots and rotation
++@nav{}
++@cindex Aspect
++@cindex Rotate
++@cindex RotateN
++@cindex SubPlot
++@cindex MultiPlot
++@cindex StickPlot
++@cindex ColumnPlot
++@cindex InPlot
++@cindex Title
++@cindex Perspective
++@cindex View
++@cindex Push
++@cindex Pop
++
++These functions control how and where further plotting will be placed. There is a certain calling order of these functions for the better plot appearance. First one should be @ref{subplot}, @ref{multiplot} or @ref{inplot} for specifying the place. Second one can be @ref{title} for adding title for the subplot. After it a @ref{rotate}, @ref{shear} and @ref{aspect}. And finally any other plotting functions may be called. Alternatively you can use @ref{columnplot}, @ref{gridplot}, @ref{stickplot}, @ref{shearplot} or relative @ref{inplot} for positioning plots in the column (or grid, or stick) one by another without gap between plot axis (bounding boxes). @sref{Subplots}
++
++@anchor{subplot}
++@deftypefn {MGL command} {} subplot @code{nx ny m} ['stl'='<>_^' @code{dx=0 dy=0}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SubPlot (@code{int} nx, @code{int} ny, @code{int} m, @code{const char *}stl=@code{"<>_^"}, @code{mreal} dx=@code{0}, @code{mreal} dy=@code{0})
++@deftypefnx {C function} @code{void} mgl_subplot (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} m, @code{const char *}stl)
++@deftypefnx {C function} @code{void} mgl_subplot_d (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} m, @code{const char *}stl, @code{mreal} dx, @code{mreal} dy)
++@end ifclear
++Puts further plotting in a @var{m}-th cell of @var{nx}*@var{ny} grid of the whole frame area. The position of the cell can be shifted from its default position by relative size @var{dx}, @var{dy}. This function set off any aspects or rotations. So it should be used first for creating the subplot. Extra space will be reserved for axis/colorbar if @var{stl} contain:
++@itemize @bullet
++@item
++@samp{L} or @samp{<} -- at left side,
++@item
++@samp{R} or @samp{>} -- at right side,
++@item
++@samp{A} or @samp{^} -- at top side,
++@item
++@samp{U} or @samp{_} -- at bottom side,
++@item
++@samp{#} -- reserve none space (use whole region for axis range) -- axis and tick labels will be invisible by default.
++@end itemize
++From the aesthetical point of view it is not recommended to use this function with different matrices in the same frame. Note, colorbar can be invisible (be out of image borders) if you set empty style @samp{}.
++@end deftypefn
++
++@anchor{multiplot}
++@deftypefn {MGL command} {} multiplot @code{nx ny m dx dy} ['style'='<>_^' sx sy]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} MultiPlot (@code{int} nx, @code{int} ny, @code{int} m, @code{int} dx, @code{int} dy, @code{const char *}stl=@code{"<>_^"})
++@deftypefnx {C function} @code{void} mgl_multiplot (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} m, @code{int} dx, @code{int} dy, @code{const char *}stl)
++@end ifclear
++Puts further plotting in a rectangle of @var{dx}*@var{dy} cells starting from @var{m}-th cell of @var{nx}*@var{ny} grid of the whole frame area. The position of the rectangular area can be shifted from its default position by relative size @var{sx}, @var{sy}. This function set off any aspects or rotations. So it should be used first for creating subplot. Extra space will be reserved for axis/colorbar if @var{stl} contain:
++@itemize @bullet
++@item
++@samp{L} or @samp{<} -- at left side,
++@item
++@samp{R} or @samp{>} -- at right side,
++@item
++@samp{A} or @samp{^} -- at top side,
++@item
++@samp{U} or @samp{_} -- at bottom side.
++@samp{#} -- reserve none space (use whole region for axis range) -- axis and tick labels will be invisible by default.
++@end itemize
++@end deftypefn
++
++@anchor{inplot}
++@deftypefn {MGL command} {} inplot @code{x1 x2 y1 y2 [rel=on]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} InPlot (@code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2, @code{bool} rel=@code{true})
++@deftypefnx {C function} @code{void} mgl_inplot (@code{HMGL} gr, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2)
++@deftypefnx {C function} @code{void} mgl_relplot (@code{HMGL} gr, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2)
++@end ifclear
++Puts further plotting in some region of the whole frame surface. This function allows one to create a plot in arbitrary place of the screen. The position is defined by rectangular coordinates [@var{x1}, @var{x2}]*[@var{y1}, @var{y2}]. The coordinates @var{x1}, @var{x2}, @var{y1}, @var{y2} are normalized to interval [0, 1]. If parameter @var{rel}=@code{true} then the relative position to current @ref{subplot} (or @ref{inplot} with @var{rel}=@code{false}) is used. This function set off any aspects or rotations. So it should be used first for creating subplot.
++@end deftypefn
++
++@anchor{columnplot}
++@deftypefn {MGL command} {} columnplot @code{num ind [d=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ColumnPlot (@code{int} num, @code{int} ind, @code{mreal} d=@code{0})
++@deftypefnx {C function} @code{void} mgl_columnplot (@code{HMGL} gr, @code{int} num, @code{int} ind)
++@deftypefnx {C function} @code{void} mgl_columnplot_d (@code{HMGL} gr, @code{int} num, @code{int} ind, @code{mreal} d)
++@end ifclear
++Puts further plotting in @var{ind}-th cell of column with @var{num} cells. The position is relative to previous @ref{subplot} (or @ref{inplot} with @var{rel}=@code{false}). Parameter @var{d} set extra gap between cells.
++@end deftypefn
++
++@anchor{gridplot}
++@deftypefn {MGL command} {} gridplot @code{nx ny ind [d=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} GridPlot (@code{int} nx, @code{int} ny, @code{int} ind, @code{mreal} d=@code{0})
++@deftypefnx {C function} @code{void} mgl_gridplot (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} ind)
++@deftypefnx {C function} @code{void} mgl_gridplot_d (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} ind, @code{mreal} d)
++@end ifclear
++Puts further plotting in @var{ind}-th cell of @var{nx}*@var{ny} grid. The position is relative to previous @ref{subplot} (or @ref{inplot} with @var{rel}=@code{false}). Parameter @var{d} set extra gap between cells.
++@end deftypefn
++
++@anchor{stickplot}
++@deftypefn {MGL command} {} stickplot @code{num ind tet phi}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} StickPlot (@code{int} num, @code{int} ind, @code{mreal} tet, @code{mreal} phi)
++@deftypefnx {C function} @code{void} mgl_stickplot (@code{HMGL} gr, @code{int} num, @code{int} ind, @code{mreal} tet, @code{mreal} phi)
++@end ifclear
++Puts further plotting in @var{ind}-th cell of stick with @var{num} cells. At this, stick is rotated on angles @var{tet}, @var{phi}. The position is relative to previous @ref{subplot} (or @ref{inplot} with @var{rel}=@code{false}).
++@end deftypefn
++
++@anchor{shearplot}
++@deftypefn {MGL command} {} shearplot @code{num ind sx sy [xd yd]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ShearPlot (@code{int} num, @code{int} ind, @code{mreal} sx, @code{mreal} sy, @code{mreal} xd=@code{1}, @code{mreal} yd=@code{0})
++@deftypefnx {C function} @code{void} mgl_shearplot (@code{HMGL} gr, @code{int} num, @code{int} ind, @code{mreal} sx, @code{mreal} sy, @code{mreal} xd, @code{mreal} yd)
++@end ifclear
++Puts further plotting in @var{ind}-th cell of stick with @var{num} cells. At this, cell is sheared on values @var{sx}, @var{sy}. Stick direction is specified be @var{xd} and @var{yd}. The position is relative to previous @ref{subplot} (or @ref{inplot} with @var{rel}=@code{false}).
++@end deftypefn
++
++
++@anchor{title}
++@deftypefn {MGL command} {} title 'title' ['stl'='' @code{size=-2}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Title (@code{const char *}txt, @code{const char *}stl=@code{""}, @code{mreal} size=@code{-2})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Title (@code{const wchar_t *}txt, @code{const char *}stl=@code{""}, @code{mreal} size=@code{-2})
++@deftypefnx {C function} @code{void} mgl_title (@code{HMGL} gr, @code{const char *}txt, @code{const char *}stl, @code{mreal} size)
++@deftypefnx {C function} @code{void} mgl_titlew (@code{HMGL} gr, @code{const wchar_t *}txt, @code{const char *}stl, @code{mreal} size)
++@end ifclear
++Add text @var{title} for current subplot/inplot. Parameter @var{stl} can contain:
++@itemize @bullet
++@item
++font style (see, @ref{Font styles});
++@item
++@samp{#} for box around the title.
++@end itemize
++Parameter @var{size} set font size. This function set off any aspects or rotations. So it should be used just after creating subplot.
++@end deftypefn
++
++@anchor{rotate}
++@deftypefn {MGL command} {} rotate @code{tetx tetz [tety=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Rotate (@code{mreal} TetX, @code{mreal} TetZ, @code{mreal} TetY=@code{0})
++@deftypefnx {C function} @code{void} mgl_rotate (@code{HMGL} gr, @code{mreal} TetX, @code{mreal} TetZ, @code{mreal} TetY)
++@end ifclear
++Rotates a further plotting relative to each axis @{x, z, y@} consecutively on angles @var{TetX}, @var{TetZ}, @var{TetY}.
++@end deftypefn
++
++@deftypefn {MGL command} {} rotate @code{tet x y z}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} RotateN (@code{mreal} Tet, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++@deftypefnx {C function} @code{void} mgl_rotate_vector (@code{HMGL} gr, @code{mreal Tet}, @code{mreal x}, @code{mreal y}, @code{mreal z})
++@end ifclear
++Rotates a further plotting around vector @{@var{x}, @var{y}, @var{z}@} on angle @var{Tet}.
++@end deftypefn
++
++@anchor{shear}
++@deftypefn {MGL command} {} shear @code{sx sy}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Shear (@code{mreal} sx, @code{mreal} sy)
++@deftypefnx {C function} @code{void} mgl_shear (@code{HMGL} gr, @code{mreal} sx, @code{mreal} sy)
++@end ifclear
++Shears a further plotting on values @var{sx}, @var{sy}.
++@end deftypefn
++
++@anchor{aspect}
++@deftypefn {MGL command} {} aspect @code{ax ay [az=1]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Aspect (@code{mreal} Ax, @code{mreal} Ay, @code{mreal} Az=@code{1})
++@deftypefnx {C function} @code{void} mgl_aspect (@code{HMGL} gr, @code{mreal} Ax, @code{mreal} Ay, @code{mreal} Az)
++@end ifclear
++Defines aspect ratio for the plot. The viewable axes will be related one to another as the ratio @var{Ax:Ay:Az}. For the best effect it should be used after @ref{rotate} function. If @var{Ax} is @code{NAN} then function try to select optimal aspect ratio to keep equal ranges for x-y axis. At this, @var{Ay} will specify proportionality factor, or set to use automatic one if @var{Ay}=@code{NAN}.
++@end deftypefn
++
++@ifclear UDAV
++
++@deftypefn {Method on @code{mglGraph}} @code{void} Push ()
++@deftypefnx {C function} @code{void} mgl_mat_push (@code{HMGL} gr)
++Push transformation matrix into stack. Later you can restore its current state by Pop() function.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} Pop ()
++@deftypefnx {C function} @code{void} mgl_mat_pop (@code{HMGL} gr)
++Pop (restore last 'pushed') transformation matrix into stack.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SetPlotFactor (@code{mreal} val)
++@deftypefnx {C function} @code{void} mgl_set_plotfactor (@code{HMGL} gr, @code{mreal} val)
++Sets the factor of plot size. It is not recommended to set it lower then 1.5. This is some analogue of function Zoom() but applied not to overall image but for each InPlot. Use negative value or zero to enable automatic selection.
++@end deftypefn
++
++@end ifclear
++
++There are 3 functions @code{View()}, @code{Zoom()} and @code{Perspective()} which transform whole image. I.e. they act as secondary transformation matrix. They were introduced for rotating/zooming the whole plot by mouse. It is not recommended to call them for picture drawing.
++
++@anchor{perspective}
++@deftypefn {MGL command} {} perspective @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Perspective (@code{mreal} a)
++@deftypefnx {C function} @code{void} mgl_perspective (@code{HMGL} gr, @code{mreal} a)
++@end ifclear
++Add (switch on) the perspective to plot. The parameter @math{a = Depth/(Depth+dz) \in [0,1)}. By default (@code{a=0}) the perspective is off.
++@end deftypefn
++
++@anchor{view}
++@deftypefn {MGL command} {} view @code{tetx tetz [tety=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} View (@code{mreal} TetX, @code{mreal} TetZ, @code{mreal} TetY=@code{0})
++@deftypefnx {C function} @code{void} mgl_view (@code{HMGL} gr, @code{mreal} TetX, @code{mreal} TetZ, @code{mreal} TetY)
++@end ifclear
++Rotates a further plotting relative to each axis @{x, z, y@} consecutively on angles @var{TetX}, @var{TetZ}, @var{TetY}. Rotation is done independently on @ref{rotate}. Attention! this settings can not be overwritten by @code{DefaultPlotParam()}. Use @code{Zoom(0,0,1,1)} to return default view.
++@end deftypefn
++
++@anchor{zoom}
++@deftypefn {MGL command} {} zoom @code{x1 y1 x2 y2}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph} (C++, Python)} @code{void} Zoom (@code{mreal} x1, @code{mreal} y1, @code{mreal} x2, @code{mreal} y2)
++@deftypefnx {C function} @code{void} mgl_set_zoom (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} x2, @code{mreal} y2)
++@end ifclear
++The function changes the scale of graphics that correspond to zoom in/out of the picture. After function call the current plot will be cleared and further the picture will contain plotting from its part [x1,x2]*[y1,y2]. Here picture coordinates @var{x1}, @var{x2}, @var{y1}, @var{y2} changes from 0 to 1. Attention! this settings can not be overwritten by any other functions, including @code{DefaultPlotParam()}. Use @code{Zoom(0,0,1,1)} to return default view.
++@end deftypefn
++
++@c ##################################################################
++@external{}
++@node Export picture, Background, Subplots and rotation, MathGL core
++@section Export picture
++@nav{}
++@cindex SetSize
++
++Functions in this group save or give access to produced picture. So, usually they should be called after plotting is done.
++
++@anchor{setsize}
++@deftypefn {MGL command} {} setsize @code{w h}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetSize (@code{int} width, @code{int} height, @code{bool} clear=@code{true})
++@deftypefnx {C function} @code{void} mgl_set_size (@code{HMGL} gr, @code{int} width, @code{int} height)
++@deftypefnx {C function} @code{void} mgl_scale_size (@code{HMGL} gr, @code{int} width, @code{int} height)
++@end ifclear
++Sets size of picture in pixels. This function @strong{should be} called before any other plotting because it completely remove picture contents if @var{clear}=@code{true}. Function just clear pixels and scale all primitives if @var{clear}=@code{false}.
++@end deftypefn
++
++@anchor{setsizescl}
++@deftypefn {MGL command} {} setsizescl @code{factor}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetSizeScl (@code{double} factor)
++@deftypefnx {C function} @code{void} mgl_set_size_scl (@code{HMGL} gr, @code{double} factor)
++@end ifclear
++Set factor for width and height in all further calls of @ref{setsize}.
++@end deftypefn
++
++@anchor{quality}
++@deftypefn {MGL command} {} quality [@code{val}=2]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetQuality (@code{int} val=@code{MGL_DRAW_NORM})
++@deftypefnx {C function} @code{void} mgl_set_quality (@code{HMGL} gr, @code{int} val)
++@end ifclear
++Sets quality of the plot depending on value @var{val}: @code{MGL_DRAW_WIRE=0} -- no face drawing (fastest), @code{MGL_DRAW_FAST=1} -- no color interpolation (fast), @code{MGL_DRAW_NORM=2} -- high quality (normal), @code{MGL_DRAW_HIGH=3} -- high quality with 3d primitives (arrows and marks); @code{MGL_DRAW_LMEM=0x4} -- direct bitmap drawing (low memory usage); @code{MGL_DRAW_DOTS=0x8} -- for dots drawing instead of primitives (extremely fast).
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglGraph}} @code{int} GetQuality ()
++@deftypefnx {C function} @code{int} mgl_get_quality (@code{HMGL} gr)
++Gets quality of the plot: @code{MGL_DRAW_WIRE=0} -- no face drawing (fastest), @code{MGL_DRAW_FAST=1} -- no color interpolation (fast), @code{MGL_DRAW_NORM=2} -- high quality (normal), @code{MGL_DRAW_HIGH=3} -- high quality with 3d primitives (arrows and marks); @code{MGL_DRAW_LMEM=0x4} -- direct bitmap drawing (low memory usage); @code{MGL_DRAW_DOTS=0x8} -- for dots drawing instead of primitives (extremely fast).
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} StartGroup (const char *name)
++@deftypefnx {C function} @code{void} mgl_start_group (@code{HMGL} gr, @code{const char *}name)
++Starts group definition. Groups contain objects and other groups, they are used to select a part of a model to zoom to or to make invisible or to make semitransparent and so on.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} EndGroup ()
++@deftypefnx {C function} @code{void} mgl_end_group (@code{HMGL} gr)
++Ends group definition.
++@end deftypefn
++@end ifclear
++
++@menu
++* Export to file::
++* Frames/Animation::
++* Bitmap in memory::
++* Parallelization::
++@end menu
++
++@c ==================================================================
++@external{}
++@node Export to file, Frames/Animation, , Export picture
++@subsection Export to file
++@nav{}
++@cindex Write
++@ifclear UDAV
++@cindex WriteFrame
++@cindex WritePNG
++@cindex WriteGIF
++@c @cindex WriteIDTF
++@cindex WriteSVG
++@cindex WriteBMP
++@cindex WriteEPS
++@cindex WriteBPS
++@cindex WriteTGA
++@cindex WriteTEX
++@cindex WritePRC
++@cindex WriteOBJ
++@cindex WriteWGL
++@cindex WriteJPEG
++@cindex ShowImage
++@end ifclear
++
++These functions export current view to a graphic file. The filename @var{fname} should have appropriate extension. Parameter @var{descr} gives the short description of the picture. Just now the transparency is supported in PNG, SVG, OBJ and PRC files.
++
++@anchor{write}
++@deftypefn {MGL command} {} write ['fname'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} WriteFrame (@code{const char *}fname=@code{""}, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_frame (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++@end ifclear
++Exports current frame to a file @var{fname} which type is determined by the extension. Parameter @var{descr} adds description to file (can be @code{""}). If @var{fname}=@code{""} then the file @samp{frame####.jpg} is used, where @samp{####} is current frame id and name @samp{frame} is defined by @ref{plotid} class property.
++@end deftypefn
++
++@anchor{bbox}
++@deftypefn {MGL command} {} bbox x1 y1 [x2=@code{-1} y2=@code{-1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetBBox (@code{int} x1=@code{0}, @code{int} y1=@code{0}, @code{int} x2=@code{-1}, @code{int} y2=@code{-1})
++@deftypefnx {C function} @code{void} mgl_set_bbox (@code{HMGL} gr, @code{int} x1, @code{int} y1, @code{int} x2, @code{int} y2)
++@end ifclear
++Set boundary box for export graphics into 2D file formats. If @var{x2}<0 (@var{y2}<0) then original image width (height) will be used. If @var{x1}<0 or @var{y1}<0 or @var{x1}>=@var{x2}|Width or @var{y1}>=@var{y2}|Height then cropping will be disabled.
++@end deftypefn
++
++
++@ifclear UDAV
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WritePNG (@code{const char *}fname, @code{const char *}descr=@code{""}, @code{int} compr=@code{""}, @code{bool} alpha=@code{true})
++@deftypefnx {C function} @code{void} mgl_write_png (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++@deftypefnx {C function} @code{void} mgl_write_png_solid (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to PNG file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file, @var{alpha} gives the transparency type. By default there are no description added and semitransparent image used. This function does nothing if HAVE_PNG isn't defined during compilation of MathGL library.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteJPEG (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_jpg (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to JPEG file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file. By default there is no description added. This function does nothing if HAVE_JPEG isn't defined during compilation of MathGL library.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteGIF (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_gif (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to GIF file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file. By default there is no description added. This function does nothing if HAVE_GIF isn't defined during compilation of MathGL library.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteBMP (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_bmp (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to BMP file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file. There is no compression used.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteTGA (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_tga (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to TGA file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file. There is no compression used.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteEPS (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_eps (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to EPS file using vector representation. So it is not recommended for the export of large data plot. It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file. By default there is no description added. If file name is terminated by @samp{z} (for example, @samp{fname.eps.gz}) then file will be compressed in gzip format. Note, that EPS format don't support color interpolation, and the resulting plot will look as you use @ref{quality}=1 for plotting.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteBPS (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_eps (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to EPS file using bitmap representation. Parameter @var{fname} specifies the file name, @var{descr} adds description to file. By default there is no description added. If file name is terminated by @samp{z} (for example, @samp{fname.eps.gz}) then file will be compressed in gzip format.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteSVG (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_svg (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to SVG (Scalable Vector Graphics) file using vector representation. In difference of EPS format, SVG format support transparency that allows to correctly draw semitransparent plot (like @ref{surfa}, @ref{surf3a} or @ref{cloud}). Note, the output file may be too large for graphic of large data array (especially for surfaces). It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file (default is file name). If file name is terminated by @samp{z} (for example, @samp{fname.svgz}) then file will be compressed in gzip format. Note, that SVG format don't support color interpolation, and the resulting plot will look as you use @ref{quality}=1 for plotting.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteTEX (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_tex (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to LaTeX (package Tikz/PGF) file using vector representation. Note, the output file may be too large for graphic of large data array (especially for surfaces). It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file (default is file name). Note, there is no text scaling now (for example, in subplots), what may produce miss-aligned labels.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WritePRC (@code{const char *}fname, @code{const char *}descr=@code{""}, @code{bool} make_pdf=@code{true})
++@deftypefnx {C function} @code{void} mgl_write_prc (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr, @code{int} make_pdf)
++Exports current frame to PRC file using vector representation (see @url{http://en.wikipedia.org/wiki/PRC_%28file_format%29}). Note, the output file may be too large for graphic of large data array (especially for surfaces). It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file (default is file name). If parameter @var{make_pdf}=@code{true} and PDF was enabled at MathGL configure then corresponding PDF file with 3D image will be created.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteOBJ (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_obj (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to OBJ/MTL file using vector representation (see @url{http://en.wikipedia.org/wiki/Wavefront_.obj_file, OBJ format} for details). Note, the output file may be too large for graphic of large data array (especially for surfaces). It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file (default is file name).
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteXYZ (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_xyz (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to XYZ/XYZL/XYZF files using vector representation (see @url{http://people.sc.fsu.edu/~jburkardt/data/xyz/xyz.html, XYZ format} for details). Note, the output file may be too large for graphic of large data array (especially for surfaces). It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file (default is file name).
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteSTL (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_stl (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to STL file using vector representation (see @url{http://en.wikipedia.org/wiki/STL_(file_format), STL format} for details). Note, the output file may be too large for graphic of large data array (especially for surfaces). It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file (default is file name.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteOFF (@code{const char *}fname, @code{const char *}descr=@code{""}, @code{bool} colored=@code{false})
++@deftypefnx {C function} @code{void} mgl_write_off (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr, @code{bool} colored)
++Exports current frame to OFF file using vector representation (see @url{http://people.sc.fsu.edu/~jburkardt/data/off/off.html, OFF format} for details). Note, the output file may be too large for graphic of large data array (especially for surfaces). It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file (default is file name).
++@end deftypefn
++
++@c @deftypefn {Method on @code{mglGraph}} @code{void} WriteX3D (@code{const char *}fname, @code{const char *}descr=@code{""})
++@c @deftypefnx {C function} @code{void} mgl_write_x3d (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++@c Exports current frame to X3D file using vector representation (see @url{http://en.wikipedia.org/wiki/X3d, X3D format} for details). Note, the output file may be too large for graphic of large data array (especially for surfaces). It is better to use bitmap format (for example PNG or JPEG). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file (default is file name).
++@c @end deftypefn
++
++
++@c @deftypefn {Method on @code{mglGraph}} @code{void} WriteIDTF (@code{const char *}fname, @code{const char *}descr=@code{""})
++@c @deftypefnx {C function} @code{void} mgl_write_idtf (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++@c Exports current frame to IDTF file. Later this file can be converted to U3D format. The vector representation is used. So, the output file may be too large for graphic of large data array (especially for surfaces). However, program has no internal limitations for size of output file. Parameter @var{fname} specifies the file name, @var{descr} adds description to file (default is file name).
++@c @end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} ShowImage (@code{const char *}viewer, @code{bool} nowait=@code{false})
++@deftypefnx {C function} @code{void} mgl_show_image (@code{const char *}viewer, @code{int} nowait)
++Displays the current picture using external program @var{viewer} for viewing. The function save the picture to temporary file and call @var{viewer} to display it. If @var{nowait}=@code{true} then the function return immediately (it will not wait while window will be closed).
++@end deftypefn
++
++
++@deftypefn {Method on @code{mglGraph}} @code{void} WriteJSON (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_write_json (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports current frame to textual file using @ref{JSON format}. Later this file can be used for faster loading and viewing by JavaScript script. Parameter @var{fname} specifies the file name, @var{descr} adds description to file.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} ExportMGLD (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {C function} @code{void} mgl_export_mgld (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Exports points and primitives in file using @ref{MGLD format}. Later this file can be used for faster loading and viewing by @code{mglview} utility. Parameter @var{fname} specifies the file name, @var{descr} adds description to file (default is file name).
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} ImportMGLD (@code{const char *}fname, @code{bool} add=@code{false})
++@deftypefnx {C function} @code{void} mgl_import_mgld (@code{HMGL} gr, @code{const char *}fname, @code{int} add)
++Imports points and primitives in file using @ref{MGLD format}. Later this file can be used for faster loading and viewing by @code{mglview} utility. Parameter @var{fname} specifies the file name, @var{add} sets to append or replace primitives to existed ones.
++@end deftypefn
++
++@end ifclear
++
++
++@c ##################################################################
++@external{}
++@node Frames/Animation, Bitmap in memory, Export to file, Export picture
++@subsection Frames/Animation
++@nav{}
++
++@ifset UDAV
++There are no commands for making animation in MGL. However you can use features of @code{mglconv} and @code{mglview} utilities. For example, by busing special comments @samp{##a } or @samp{##c }.
++@end ifset
++
++@ifclear UDAV
++@cindex NewFrame
++@cindex EndFrame
++@cindex GetNumFrame
++@cindex ResetFrames
++@cindex StartGIF
++@cindex CloseGIF
++
++These functions provide ability to create several pictures simultaneously. For most of cases it is useless but for widget classes (see @ref{Widget classes}) they can provide a way to show animation. Also you can write several frames into animated GIF file.
++
++@deftypefn {Method on @code{mglGraph}} @code{void} NewFrame ()
++@deftypefnx {C function} @code{void} mgl_new_frame (@code{HMGL} gr)
++Creates new frame. Function returns current frame id. This is not thread safe function in OpenGL mode! Use direct list creation in multi-threading drawing. The function @code{EndFrame()} @strong{must} be call after the finishing of the frame drawing for each call of this function.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} EndFrame ()
++@deftypefnx {C function} @code{void} mgl_end_frame (@code{HMGL} gr)
++Finishes the frame drawing.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{int} GetNumFrame ()
++@deftypefnx {C function} @code{int} mgl_get_num_frame (@code{HMGL} gr)
++Gets the number of created frames.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SetFrame (@code{int} i)
++@deftypefnx {C function} @code{void} mgl_set_frame (@code{HMGL} gr, @code{int} i)
++Finishes the frame drawing and sets drawing data to frame @var{i}, which should be in range [0, @code{GetNumFrame()}-1]. This function is similar to @code{EndFrame()} but don't add frame to the GIF image.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} GetFrame (@code{int} i)
++@deftypefnx {C function} @code{void} mgl_get_frame (@code{HMGL} gr, @code{int} i)
++Replaces drawing data by one from frame @var{i}. Function work if @code{MGL_VECT_FRAME} is set on (by default).
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} ShowFrame (@code{int} i)
++@deftypefnx {C function} @code{void} mgl_show_frame (@code{HMGL} gr, @code{int} i)
++Appends drawing data from frame @var{i} to current one. Function work if @code{MGL_VECT_FRAME} is set on (by default).
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} DelFrame (@code{int} i)
++@deftypefnx {C function} @code{void} mgl_del_frame (@code{HMGL} gr, @code{int} i)
++Deletes drawing data for frame @var{i} and shift all later frame indexes. Function work if @code{MGL_VECT_FRAME} is set on (by default). Do nothing in OpenGL mode.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} ResetFrames ()
++@deftypefnx {C function} @code{void} mgl_reset_frames (@code{HMGL} gr)
++Reset frames counter (start it from zero).
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} ClearFrame (@code{int} i)
++@deftypefnx {C function} @code{void} mgl_clear_frame (@code{HMGL} gr, @code{int} i)
++Clear list of primitives for current drawing.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} StartGIF (@code{const char *}fname, @code{int} ms=@code{100})
++@deftypefnx {C function} @code{void} mgl_start_gif (@code{HMGL} gr, @code{const char *}fname, @code{int} ms)
++Start writing frames into animated GIF file @var{fname}. Parameter @var{ms} set the delay between frames in milliseconds. You @strong{should not} change the picture size during writing the cinema. Use @code{CloseGIF()} to finalize writing. Note, that this function is disabled in OpenGL mode.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} CloseGIF ()
++@deftypefnx {C function} @code{void} mgl_close_gif (@code{HMGL} gr)
++Finish writing animated GIF and close connected pointers.
++@end deftypefn
++@end ifclear
++
++@c ------------------------------------------------------------------
++@external{}
++@node Bitmap in memory, Parallelization, Frames/Animation, Export picture
++@subsection Bitmap in memory
++@nav{}
++
++@ifclear UDAV
++These functions return the created picture (bitmap), its width and height. You may display it by yourself in any graphical library (see also, @ref{Widget classes}) or save in file (see also, @ref{Export to file}).
++
++@deftypefn {Method on @code{mglGraph}} @code{const unsigned char *} GetRGB ()
++@deftypefnx {Method on @code{mglGraph}} @code{void} GetRGB (@code{char *}buf, @code{int} size)
++@deftypefnx {Method on @code{mglGraph}} @code{void} GetBGRN (@code{char *}buf, @code{int} size)
++@deftypefnx {C function} @code{const unsigned char *} mgl_get_rgb (@code{HMGL} gr)
++Gets RGB bitmap of the current state of the image. Format of each element of bits is: @{red, green, blue@}. Number of elements is Width*Height. Position of element @{i,j@} is [3*i + 3*Width*j] (or is [4*i + 4*Width*j] for @code{GetBGRN()}). You have to provide the proper @var{size} of the buffer, @var{buf}, i.e. the code for Python should look like
++@verbatim
++from mathgl import *
++gr = mglGraph();
++bits='\t';
++bits=bits.expandtabs(4*gr.GetWidth()*gr.GetHeight());
++gr.GetBGRN(bits, len(bits));
++@end verbatim
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{const unsigned char *} GetRGBA ()
++@deftypefnx {Method on @code{mglGraph}} @code{void} GetRGBA (@code{char *}buf, @code{int} size)
++@deftypefnx {C function} @code{const unsigned char *} mgl_get_rgba (@code{HMGL} gr)
++Gets RGBA bitmap of the current state of the image. Format of each element of bits is: @{red, green, blue, alpha@}. Number of elements is Width*Height. Position of element @{i,j@} is [4*i + 4*Width*j].
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{int} GetWidth ()
++@deftypefnx {Method on @code{mglGraph}} @code{int} GetHeight ()
++@deftypefnx {C function} @code{int} mgl_get_width (@code{HMGL} gr)
++@deftypefnx {C function} @code{int} mgl_get_height (@code{HMGL} gr)
++Gets width and height of the image.
++@end deftypefn
++
++
++@deftypefn {Method on @code{mglGraph}} @code{mglPoint} CalcXYZ (@code{int} xs, @code{int} ys)
++@deftypefnx {C function} @code{void} mgl_calc_xyz (@code{HMGL} gr, @code{int} xs, @code{int} ys, @code{mreal *}x, @code{mreal *}y, @code{mreal *}z)
++Calculate 3D coordinate @{x,y,z@} for screen point @{xs,ys@}. At this moment it ignore perspective and transformation formulas (curvilinear coordinates). The calculation are done for the last used InPlot (see @ref{Subplots and rotation}).
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{mglPoint} CalcScr (@code{mglPoint} p)
++@deftypefnx {C function} @code{void} mgl_calc_scr (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{int *}xs, @code{int *}ys)
++Calculate screen point @{xs,ys@} for 3D coordinate @{x,y,z@}. The calculation are done for the last used InPlot (see @ref{Subplots and rotation}).
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} SetObjId (@code{int} id)
++@deftypefnx {C function} @code{void} mgl_set_obj_id (@code{HMGL} gr, @code{int} id)
++Set the numeric id for object or subplot/inplot.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{int} GetObjId (@code{int} xs, @code{int} ys)
++@deftypefnx {C function} @code{int} mgl_get_obj_id (@code{HMGL} gr, @code{int} xs, @code{int} ys)
++Get the numeric id for most upper object at pixel @{xs, ys@} of the picture.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{int} GetSplId (@code{int} xs, @code{int} ys)
++@deftypefnx {C function} @code{int} mgl_get_spl_id (@code{HMGL} gr, @code{int} xs, @code{int} ys)
++Get the numeric id for most subplot/inplot at pixel @{xs, ys@} of the picture.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{void} Highlight (@code{int} id)
++@deftypefnx {C function} @code{void} mgl_highlight (@code{HMGL} gr, @code{int} id)
++Highlight the object with given @var{id}.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{long} IsActive (@code{int} xs, @code{int} ys, @code{int} d=@code{1})
++@deftypefnx {C function} @code{long} mgl_is_active (@code{HMGL} gr, @code{int} xs, @code{int} ys, @code{int} d)
++Checks if point @{@var{xs}, @var{ys}@} is close to one of active point (i.e. mglBase::Act) with accuracy @var{d} and return its index or @code{-1} if not found. Active points are special points which characterize primitives (like edges and so on). This function for advanced users only.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{long} SetDrawReg (@code{int} nx=@code{1}, @code{int} ny=@code{1}, @code{int} m=@code{0})
++@deftypefnx {C function} @code{long} mgl_set_draw_reg (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} m)
++Limits drawing region by rectangular area of @var{m}-th cell of matrix with sizes @var{nx}*@var{ny} (like in @ref{subplot}). This function can be used to update only small region of the image for purposes of higher speed. This function for advanced users only.
++@end deftypefn
++
++
++@end ifclear
++
++@c ------------------------------------------------------------------
++@external{}
++@node Parallelization, , Bitmap in memory, Export picture
++@subsection Parallelization
++@nav{}
++
++@ifclear UDAV
++@cindex Combine
++@cindex MPI_Send
++@cindex MPI_Recv
++
++Many of things MathGL do in parallel by default (if MathGL was built with pthread). However, there is function which set the number of threads to be used.
++
++@deftypefn {C function} @code{int} mgl_set_num_thr (@code{int} n)
++Set the number of threads to be used by MathGL. If @var{n}<1 then the number of threads is set as maximal number of processors (cores). If @var{n}=1 then single thread will be used (this is default if pthread was disabled).
++@end deftypefn
++
++Another option is combining bitmap image (taking into account Z-ordering) from different instances of @code{mglGraph}. This method is most appropriate for computer clusters when the data size is so large that it exceed the memory of single computer node.
++
++@deftypefn {Method on @code{mglGraph}} @code{int} Combine (@code{const mglGraph *}g)
++@deftypefnx {C function} @code{int} mgl_combine_gr (@code{HMGL} gr, @code{HMGL} g)
++Combine drawing from instance @var{g} with @var{gr} (or with this) taking into account Z-ordering of pixels. The width and height of both instances must be the same.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{int} MPI_Send (@code{int} id)
++@deftypefnx {C function} @code{int} mgl_mpi_send (@code{HMGL} gr, @code{int} id)
++Send graphical information from node @var{id} using MPI. The width and height in both nodes must be the same.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{int} MPI_Recv (@code{int} id)
++@deftypefnx {C function} @code{int} mgl_mpi_send (@code{HMGL} gr, @code{int} id)
++Receive graphical information from node @var{id} using MPI. The width and height in both nodes must be the same.
++@end deftypefn
++@end ifclear
++
++
++@c ##################################################################
++@external{}
++@node Background, Primitives, Export picture, MathGL core
++@section Background
++@nav{}
++@cindex LoadBackground
++@cindex Clf
++@cindex Rasterize
++
++These functions change background image.
++
++@anchor{clf}
++@deftypefn {MGL command} {} clf ['col']
++@deftypefnx {MGL command} {} clf r g b
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Clf ()
++@deftypefnx {Method on @code{mglGraph}} @code{void} Clf (@code{const char *} col)
++@deftypefnx {Method on @code{mglGraph}} @code{void} Clf (@code{char} col)
++@deftypefnx {Method on @code{mglGraph}} @code{void} Clf (@code{mreal} r, @code{mreal} g, @code{mreal} b)
++@deftypefnx {C function} @code{void} mgl_clf (@code{HMGL} gr)
++@deftypefnx {C function} @code{void} mgl_clf_str (@code{HMGL} gr, @code{const char *} col)
++@deftypefnx {C function} @code{void} mgl_clf_chr (@code{HMGL} gr, @code{char} col)
++@deftypefnx {C function} @code{void} mgl_clf_rgb (@code{HMGL} gr, @code{mreal} r, @code{mreal} g, @code{mreal} b)
++@end ifclear
++Clear the picture and fill background by specified color.
++@end deftypefn
++
++@anchor{rasterize}
++@deftypefn {MGL command} {} rasterize
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Rasterize ()
++@deftypefnx {C function} @code{void} mgl_rasterize (@code{HMGL} gr)
++@end ifclear
++Force drawing the plot and use it as background. After it, function clear the list of primitives, like @ref{clf}. This function is useful if you want save part of plot as bitmap one (for example, large surfaces, isosurfaces or vector fields) and keep some parts as vector one (like annotation, curves, axis and so on).
++@end deftypefn
++
++@anchor{background}
++@deftypefn {MGL command} {} background 'fname' [@code{alpha=1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} LoadBackground (@code{const char *} fname, @code{double} alpha=@code{1})
++@deftypefnx {C function} @code{void} mgl_load_background (@code{HMGL} gr, @code{const char *} fname, @code{double} alpha)
++@end ifclear
++Load PNG or JPEG file @var{fname} as background for the plot. Parameter @var{alpha} manually set transparency of the background.
++@end deftypefn
++
++
++
++@c ##################################################################
++@external{}
++@node Primitives, Text printing, Background, MathGL core
++@section Primitives
++@nav{}
++@cindex Ball
++@cindex Line
++@cindex Curve
++@cindex Glyph
++@cindex Face
++@cindex FaceX
++@cindex FaceY
++@cindex FaceZ
++@cindex Cone
++@cindex Drop
++@cindex Sphere
++
++@ifclear UDAV
++@cindex Mark
++@cindex Error
++@end ifclear
++
++These functions draw some simple objects like line, point, sphere, drop, cone and so on. @sref{Using primitives}
++
++@anchor{ball}
++@deftypefn {MGL command} {} ball @code{x y} ['col'='r.']
++@deftypefnx {MGL command} {} ball @code{x y z} ['col'='r.']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Ball (@code{mglPoint} p, @code{char} col=@code{'r'})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Mark (@code{mglPoint} p, @code{const char *}mark)
++@deftypefnx {C function} @code{void} mgl_mark (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{const char *}mark)
++@end ifclear
++Draws a mark (point @samp{.} by default) at position @var{p}=@{@var{x}, @var{y}, @var{z}@} with color @var{col}.
++@end deftypefn
++
++@anchor{errbox}
++@deftypefn {MGL command} {} errbox @code{x y ex ey} ['stl'='']
++@deftypefnx {MGL command} {} errbox @code{x y z ex ey ez} ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Error (@code{mglPoint} p, @code{mglPoint} e, @code{char} *stl=@code{""})
++@deftypefnx {C function} @code{void} mgl_error_box (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal} ex, @code{mreal} ey, @code{mreal} ez, @code{char *}stl)
++@end ifclear
++Draws a 3d error box at position @var{p}=@{@var{x}, @var{y}, @var{z}@} with sizes @var{e}=@{@var{ex}, @var{ey}, @var{ez}@} and style @var{stl}. Use NAN for component of @var{e} to reduce number of drawn elements.
++@end deftypefn
++
++@anchor{line}
++@deftypefn {MGL command} {} line @code{x1 y1 x2 y2} ['stl'='']
++@deftypefnx {MGL command} {} line @code{x1 y1 z1 x2 y2 z2} ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Line (@code{mglPoint} p1, @code{mglPoint} p2, @code{char *}stl=@code{"B"}, @code{int} num=@code{2})
++@deftypefnx {C function} @code{void} mgl_line (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{char *}stl, @code{int} num)
++@end ifclear
++Draws a geodesic line (straight line in Cartesian coordinates) from point @var{p1} to @var{p2} using line style @var{stl}. Parameter @var{num} define the ``quality'' of the line. If @var{num}=@code{2} then the straight line will be drawn in all coordinate system (independently on transformation formulas (see @ref{Curved coordinates}). Contrary, for large values (for example, =@code{100}) the geodesic line will be drawn in corresponding coordinate system (straight line in Cartesian coordinates, circle in polar coordinates and so on). Line will be drawn even if it lies out of bounding box.
++@end deftypefn
++
++@anchor{curve}
++@deftypefn {MGL command} {} curve @code{x1 y1 dx1 dy1 x2 y2 dx2 dy2} ['stl'='']
++@deftypefnx {MGL command} {} curve @code{x1 y1 z1 dx1 dy1 dz1 x2 y2 z2 dx2 dy2 dz2} ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Curve (@code{mglPoint} p1, @code{mglPoint} d1, @code{mglPoint} p2, @code{mglPoint} d2, @code{const char *}stl=@code{"B"}, @code{int} num=@code{100})
++@deftypefnx {C function} @code{void} mgl_curve (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} dx1, @code{mreal} dy1, @code{mreal} dz1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{mreal} dx2, @code{mreal} dy2, @code{mreal} dz2, @code{const char *}stl, @code{int} num)
++@end ifclear
++Draws Bezier-like curve from point @var{p1} to @var{p2} using line style @var{stl}. At this tangent is codirected with @var{d1}, @var{d2} and proportional to its amplitude. Parameter @var{num} define the ``quality'' of the curve. If @var{num}=@code{2} then the straight line will be drawn in all coordinate system (independently on transformation formulas, see @ref{Curved coordinates}). Contrary, for large values (for example, =@code{100}) the spline like Bezier curve will be drawn in corresponding coordinate system. Curve will be drawn even if it lies out of bounding box.
++@end deftypefn
++
++@anchor{face}
++@deftypefn {MGL command} {} face @code{x1 y1 x2 y2 x3 y3 x4 y4} ['stl'='']
++@deftypefnx {MGL command} {} face @code{x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4} ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Face (@code{mglPoint} p1, @code{mglPoint} p2, @code{mglPoint} p3, @code{mglPoint} p4, @code{const char *}stl=@code{"w"})
++@deftypefnx {C function} @code{void} mgl_face (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{mreal} x3, @code{mreal} y3, @code{mreal} z3, @code{mreal} x4, @code{mreal} y4, @code{mreal} z4, @code{const char *}stl)
++@end ifclear
++Draws the solid quadrangle (face) with vertexes @var{p1}, @var{p2}, @var{p3}, @var{p4} and with color(s) @var{stl}. At this colors can be the same for all vertexes or different if all 4 colors are specified for each vertex. Face will be drawn even if it lies out of bounding box.
++@end deftypefn
++
++@anchor{rect}
++@deftypefn {MGL command} {} rect @code{x1 y1 x2 y2} ['stl'='']
++@deftypefnx {MGL command} {} rect @code{x1 y1 z1 x2 y2 z2} ['stl'='']
++Draws the solid rectangle (face) with vertexes @{@var{x1}, @var{y1}, @var{z1}@} and @{@var{x2}, @var{y2}, @var{z2}@} with color @var{stl}. At this colors can be the same for all vertexes or separately if all 4 colors are specified for each vertex. Face will be drawn even if it lies out of bounding box.
++@end deftypefn
++
++@anchor{facex}
++@anchor{facey}
++@anchor{facez}
++@deftypefn {MGL command} {} facex @code{x0 y0 z0 wy wz} ['stl'='' @code{d1=0 d2=0}]
++@deftypefnx {MGL command} {} facey @code{x0 y0 z0 wx wz} ['stl'='' @code{d1=0 d2=0}]
++@deftypefnx {MGL command} {} facez @code{x0 y0 z0 wx wy} ['stl'='' @code{d1=0 d2=0}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} FaceX (@code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} wy, @code{mreal} wz, @code{const char *}stl=@code{"w"}, @code{mreal} d1=@code{0}, @code{mreal} d2=@code{0})
++@deftypefnx {Method on @code{mglGraph}} @code{void} FaceY (@code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} wx, @code{mreal} wz, @code{const char *}stl=@code{"w"}, @code{mreal} d1=@code{0}, @code{mreal} d2=@code{0})
++@deftypefnx {Method on @code{mglGraph}} @code{void} FaceZ (@code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} wx, @code{mreal} wy, @code{const char *}stl=@code{"w"}, @code{mreal} d1=@code{0}, @code{mreal} d2=@code{0})
++@deftypefnx {C function} @code{void} mgl_facex (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} wy, @code{mreal} wz, @code{const char *}stl, @code{mreal} d1, @code{mreal} d2)
++@deftypefnx {C function} @code{void} mgl_facey (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} wx, @code{mreal} wz, @code{const char *}stl, @code{mreal} d1, @code{mreal} d2)
++@deftypefnx {C function} @code{void} mgl_facez (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} wx, @code{mreal} wy, @code{const char *}stl, @code{mreal} d1, @code{mreal} d2)
++@end ifclear
++Draws the solid rectangle (face) perpendicular to [x,y,z]-axis correspondingly at position @{@var{x0}, @var{y0}, @var{z0}@} with color @var{stl} and with widths @var{wx}, @var{wy}, @var{wz} along corresponding directions. At this colors can be the same for all vertexes or separately if all 4 colors are specified for each vertex. Parameters @var{d1}!=0, @var{d2}!=0 set additional shift of the last vertex (i.e. to draw quadrangle). Face will be drawn even if it lies out of bounding box.
++@end deftypefn
++
++@anchor{sphere}
++@deftypefn {MGL command} {} sphere @code{x0 y0 r} ['col'='r']
++@deftypefnx {MGL command} {} sphere @code{x0 y0 z0 r} ['col'='r']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Sphere (@code{mglPoint} p, @code{mreal} r, @code{const char *}stl=@code{"r"})
++@deftypefnx {C function} @code{void} mgl_sphere (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} r, @code{const char *}stl)
++@end ifclear
++Draw the sphere with radius @var{r} and center at point @var{p}=@{@var{x0}, @var{y0}, @var{z0}@} and color @var{stl}.
++@end deftypefn
++
++@anchor{drop}
++@deftypefn {MGL command} {} drop @code{x0 y0 dx dy r} ['col'='r' @code{sh=1 asp=1}]
++@deftypefnx {MGL command} {} drop @code{x0 y0 z0 dx dy dz r} ['col'='r' @code{sh=1 asp=1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Drop (@code{mglPoint} p, @code{mglPoint} d, @code{mreal} r, @code{const char *}col=@code{"r"}, @code{mreal} shift=@code{1}, @code{mreal} ap=@code{1})
++@deftypefnx {C function} @code{void} mgl_drop (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{mreal} r, @code{const char *}col, @code{mreal} shift, @code{mreal} ap)
++@end ifclear
++Draw the drop with radius @var{r} at point @var{p} elongated in direction @var{d} and with color @var{col}. Parameter @var{shift} set the degree of drop oblongness: @samp{0} is sphere, @samp{1} is maximally oblongness drop. Parameter @var{ap} set relative width of the drop (this is analogue of ``ellipticity'' for the sphere).
++@end deftypefn
++
++@anchor{cone}
++@deftypefn {MGL command} {} cone @code{x1 y1 z1 x2 y2 z2 r1} [@code{r2=-1} 'stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cone (@code{mglPoint} p1, @code{mglPoint} p2, @code{mreal} r1, @code{mreal} r2=@code{-1}, @code{const char *}stl=@code{"B"})
++@deftypefnx {C function} @code{void} mgl_cone (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{mreal} r1, @code{mreal} r2, @code{const char *}stl)
++@end ifclear
++Draw tube (or truncated cone if @var{edge}=@code{false}) between points @var{p1}, @var{p2} with radius at the edges @var{r1}, @var{r2}. If @var{r2}<0 then it is supposed that @var{r2}=@var{r1}. The cone color is defined by string @var{stl}. Parameter @var{stl} can contain:
++@itemize @bullet
++@item
++@samp{@@} for drawing edges;
++@item
++@samp{#} for wired cones;
++@item
++@samp{t} for drawing tubes/cylinder instead of cones/prisms;
++@item
++@samp{4}, @samp{6}, @samp{8} for drawing square, hex- or octo-prism instead of cones.
++@end itemize
++@end deftypefn
++
++@anchor{circle}
++@deftypefn {MGL command} {} circle @code{x0 y0 r} ['col'='r']
++@deftypefnx {MGL command} {} circle @code{x0 y0 z0 r} ['col'='r']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Circle (@code{mglPoint} p, @code{mreal} r, @code{const char *}stl=@code{"r"})
++@end ifclear
++Draw the circle with radius @var{r} and center at point @var{p}=@{@var{x0}, @var{y0}, @var{z0}@}. Parameter @var{col} may contain
++@itemize @bullet
++@item
++colors for filling and boundary (second one if style @samp{@@} is used, black color is used by default);
++@item
++@samp{#} for wire figure (boundary only);
++@item
++@samp{@@} for filling and boundary.
++@end itemize
++@end deftypefn
++
++@anchor{ellipse}
++@deftypefn {MGL command} {} ellipse @code{x1 y1 x2 y2 r} ['col'='r']
++@deftypefnx {MGL command} {} ellipse @code{x1 y1 z1 x2 y2 z2 r} ['col'='r']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Ellipse (@code{mglPoint} p1, @code{mglPoint} p2, @code{mreal} r, @code{const char *}col=@code{"r"})
++@deftypefnx {C function} @code{void} mgl_ellipse (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{mreal} r, @code{const char *}col)
++@end ifclear
++Draw the ellipse with radius @var{r} and focal points @var{p1}, @var{p2}. Parameter @var{col} may contain
++@itemize @bullet
++@item
++colors for filling and boundary (second one if style @samp{@@} is used, black color is used by default);
++@item
++@samp{#} for wire figure (boundary only);
++@item
++@samp{@@} for filling and boundary.
++@end itemize
++@end deftypefn
++
++@anchor{rhomb}
++@deftypefn {MGL command} {} rhomb @code{x1 y1 x2 y2 r} ['col'='r']
++@deftypefnx {MGL command} {} rhomb @code{x1 y1 z1 x2 y2 z2 r} ['col'='r']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Rhomb (@code{mglPoint} p1, @code{mglPoint} p2, @code{mreal} r, @code{const char *}col=@code{"r"})
++@deftypefnx {C function} @code{void} mgl_rhomb (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{mreal} r, @code{const char *}col)
++@end ifclear
++Draw the rhombus with width @var{r} and edge points @var{p1}, @var{p2}. Parameter @var{col} may contain
++@itemize @bullet
++@item
++colors for filling and boundary (second one if style @samp{@@} is used, black color is used by default);
++@item
++@samp{#} for wire figure (boundary only);
++@item
++@samp{@@} for filling and boundary.
++@end itemize
++@end deftypefn
++
++@anchor{arc}
++@deftypefn {MGL command} {} arc @code{x0 y0 x1 y1 a} ['col'='r']
++@deftypefnx {MGL command} {} arc @code{x0 y0 z0 x1 y1 a} ['col'='r']
++@deftypefnx {MGL command} {} arc @code{x0 y0 z0 xa ya za x1 y1 z1 a} ['col'='r']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Arc (@code{mglPoint} p0, @code{mglPoint} p1, @code{mreal} a, @code{const char *}col=@code{"r"})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Arc (@code{mglPoint} p0, @code{mglPoint} pa, @code{mglPoint} p1, @code{mreal} a, @code{const char *}col=@code{"r"})
++@deftypefnx {C function} @code{void} mgl_arc (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} x1, @code{mreal} y1, @code{mreal} a, @code{const char *}col)
++@deftypefnx {C function} @code{void} mgl_arc_ext (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} xa, @code{mreal} ya, @code{mreal} za, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} a, @code{const char *}col)
++@end ifclear
++Draw the arc around axis @var{pa} (default is z-axis @var{pa}=@{0,0,1@}) with center at @var{p0} and starting from point @var{p1}. Parameter @var{a} set the angle of arc in degree. Parameter @var{col} may contain color of the arc and arrow style for arc edges.
++@end deftypefn
++
++@anchor{polygon}
++@deftypefn {MGL command} {} polygon @code{x0 y0 x1 y1 num} ['col'='r']
++@deftypefnx {MGL command} {} polygon @code{x0 y0 z0 x1 y1 z1 num} ['col'='r']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Polygon (@code{mglPoint} p0, @code{mglPoint} p1, @code{int} num, @code{const char *}col=@code{"r"})
++@deftypefnx {C function} @code{void} mgl_polygon (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{int} num, @code{const char *}col)
++@end ifclear
++Draw the polygon with @var{num} edges starting from @var{p1}. The center of polygon is located in @var{p0}. Parameter @var{col} may contain
++@itemize @bullet
++@item
++colors for filling and boundary (second one if style @samp{@@} is used, black color is used by default);
++@item
++@samp{#} for wire figure (boundary only);
++@item
++@samp{@@} for filling and boundary.
++@end itemize
++@end deftypefn
++
++
++@anchor{logo}
++@deftypefn {MGL command} {} logo 'fname' [smooth=off]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Logo (@code{const char *}fname, @code{bool} smooth=@code{false}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Logo (@code{long} w, @code{long} h, @code{const unsigned char *}rgba, @code{bool} smooth=@code{false}, @code{const char *}opt=@code{""})
++@deftypefnx {C function only} @code{void} mgl_logo (@code{HMGL} gr, @code{long} w, @code{long} h, @code{const unsigned char *}rgba, @code{bool} smooth, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_logo_file (@code{HMGL} gr, @code{const char *}fname, @code{bool} smooth, @code{const char *}opt)
++@end ifclear
++Draw bitmap (logo) along whole axis range, which can be changed by @ref{Command options}. Bitmap can be loaded from file or specified as RGBA values for pixels. Parameter @var{smooth} set to draw bitmap without or with color interpolation.
++@end deftypefn
++
++
++@anchor{symbol}
++@deftypefn {MGL command} {} symbol @code{x y} 'id' ['fnt'='' @code{size=-1}]
++@deftypefnx {MGL command} {} symbol @code{x y z} 'id' ['fnt'='' @code{size=-1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Symbol (@code{mglPoint} p, @code{char} id, @code{const char *}fnt=@code{""}, @code{mreal} size=@code{-1})
++@deftypefnx {C function} @code{void} mgl_symbol (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{char} id, @code{const char *}fnt, @code{mreal} size)
++@end ifclear
++Draws user-defined symbol with name @var{id} at position @var{p} with style specifying by @var{fnt}. The size of font is set by @var{size} parameter (default is @code{-1}). The string @var{fnt} may contain color specification ended by @samp{:} symbol; styles @samp{a}, @samp{A} to draw at absolute position @{@var{x}, @var{y}@} (supposed to be in range [0,1]) of picture (for @samp{A}) or subplot/inplot (for @samp{a}); and style @samp{w} to draw wired symbol.
++@end deftypefn
++
++@deftypefn {MGL command} {} symbol @code{x y dx dy} 'id' ['fnt'=':L' @code{size=-1}]
++@deftypefnx {MGL command} {} symbol @code{x y z dx dy dz} 'id' ['fnt'=':L' @code{size=-1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Symbol (@code{mglPoint} p, @code{mglPoint} d, @code{char} id, @code{const char *}fnt=@code{""}, @code{mreal} size=@code{-1})
++@deftypefnx {C function} @code{void} mgl_symbol_dir (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{const char *}text, @code{const char *}fnt, @code{mreal} size)
++@end ifclear
++The same as previous but symbol will be drawn rotated along direction @var{d}.
++@end deftypefn
++
++@anchor{addsymbol}
++@deftypefn {MGL command} {} addsymbol 'id' xdat ydat
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} DefineSymbol (@code{char} id, @code{const mglDataA &}xdat, @code{const mglDataA &}ydat)
++@deftypefnx {C function} @code{void} mgl_define_symbol (@code{HMGL} gr, @code{HCDT} xdat, @code{HCDT} ydat)
++@end ifclear
++Add user-defined symbol with name @var{id} and contour @{@var{xdat}, @var{ydat}@}. You can use @code{NAN} values to set break (jump) of contour curve.
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node Text printing, Axis and Colorbar, Primitives, MathGL core
++@section Text printing
++@nav{}
++@ifclear UDAV
++@cindex Puts
++@cindex Putsw
++@end ifclear
++@cindex Text
++@cindex Label
++@cindex fgets
++
++These functions draw the text. There are functions for drawing text in arbitrary place, in arbitrary direction and along arbitrary curve. MathGL can use arbitrary font-faces and parse many TeX commands (for more details see @ref{Font styles}). All these functions have 2 variant: for printing 8-bit text (@code{char *}) and for printing Unicode text (@code{wchar_t *}). In first case the conversion into the current locale is used. So sometimes you need to specify it by @code{setlocale()} function. The @var{size} argument control the size of text: if positive it give the value, if negative it give the value relative to @code{SetFontSize()}. The font type (STIX, arial, courier, times and so on) can be selected by function LoadFont(). @xref{Font settings}.
++
++The font parameters are described by string. This string may set the text color @samp{wkrgbcymhRGBCYMHW} (see @ref{Color styles}). Starting from MathGL v.2.3, you can set color gradient for text (see @ref{Color scheme}). Also, after delimiter symbol @samp{:}, it can contain characters of font type (@samp{rbiwou}) and/or align (@samp{LRCTV}) specification. The font types are: @samp{r} -- roman (or regular) font, @samp{i} -- italic style, @samp{b} -- bold style, @samp{w} -- wired style, @samp{o} -- over-lined text, @samp{u} -- underlined text. By default roman font is used. The align types are: @samp{L} -- align left (default), @samp{C} -- align center, @samp{R} -- align right, @samp{T} -- align under, @samp{V} -- align center vertical. For example, string @samp{b:iC} correspond to italic font style for centered text which printed by blue color.
++
++If string contains symbols @samp{aA} then text is printed at absolute position @{@var{x}, @var{y}@} (supposed to be in range [0,1]) of picture (for @samp{A}) or subplot/inplot (for @samp{a}). If string contains symbol @samp{@@} then box around text is drawn.
++
++@sref{Text features}
++
++@anchor{text}
++@deftypefn {MGL command} {} text @code{x y} 'text' ['fnt'='' @code{size=-1}]
++@deftypefnx {MGL command} {} text @code{x y z} 'text' ['fnt'='' @code{size=-1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Puts (@code{mglPoint} p, @code{const char *}text, @code{const char *}fnt=@code{":C"}, @code{mreal} size=@code{-1})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Putsw (@code{mglPoint} p, @code{const wchar_t *}text, @code{const char *}fnt=@code{":C"}, @code{mreal} size=@code{-1})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Puts (@code{mreal} x, @code{mreal} y, @code{const char *}text, @code{const char *}fnt=@code{":AC"}, @code{mreal} size=@code{-1})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Putsw (@code{mreal} x, @code{mreal} y, @code{const wchar_t *}text, @code{const char *}fnt=@code{":AC"}, @code{mreal} size=@code{-1})
++@deftypefnx {C function} @code{void} mgl_puts (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{const char *}text, @code{const char *}fnt, @code{mreal} size)
++@deftypefnx {C function} @code{void} mgl_putsw (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{const wchar_t *}text, @code{const char *}fnt, @code{mreal} size)
++@end ifclear
++Draws the string @var{text} at position @var{p} with fonts specifying by the criteria @var{fnt}. The size of font is set by @var{size} parameter (default is @code{-1}).
++@end deftypefn
++
++@deftypefn {MGL command} {} text @code{x y dx dy} 'text' ['fnt'=':L' @code{size=-1}]
++@deftypefnx {MGL command} {} text @code{x y z dx dy dz} 'text' ['fnt'=':L' @code{size=-1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Puts (@code{mglPoint} p, @code{mglPoint} d, @code{const char *}text, @code{const char *}fnt=@code{":L"}, @code{mreal} size=@code{-1})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Putsw (@code{mglPoint} p, @code{mglPoint} d, @code{const wchar_t *}text, @code{const char *}fnt=@code{":L"}, @code{mreal} size=@code{-1})
++@deftypefnx {C function} @code{void} mgl_puts_dir (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{const char *}text, @code{const char *}fnt, @code{mreal} size)
++@deftypefnx {C function} @code{void} mgl_putsw_dir (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{const wchar_t *}text, @code{const char *}fnt, @code{mreal} size)
++@end ifclear
++Draws the string @var{text} at position @var{p} along direction @var{d} with specified @var{size}. Parameter @var{fnt} set text style and text position: under (@samp{T}) or above (@samp{t}) the line.
++@end deftypefn
++
++@anchor{fgets}
++@deftypefn {MGL command} {} fgets @code{x y} 'fname' [@code{n=0} 'fnt'='' @code{size=-1.4}]
++@deftypefnx {MGL command} {} fgets @code{x y z} 'fname' [@code{n=0} 'fnt'='' @code{size=-1.4}]
++Draws unrotated @var{n}-th line of file @var{fname} at position @{@var{x},@var{y},@var{z}@} with specified @var{size}. By default parameters from @ref{font} command are used.
++@end deftypefn
++
++@deftypefn {MGL command} {} text ydat 'text' ['fnt'='']
++@deftypefnx {MGL command} {} text xdat ydat 'text' ['fnt'='']
++@deftypefnx {MGL command} {} text xdat ydat zdat 'text' ['fnt'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Text (@code{const mglDataA &}y, @code{const char *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Text (@code{const mglDataA &}y, @code{const wchar_t *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Text (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Text (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const wchar_t *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Text (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Text (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const wchar_t *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_text_y (@code{HMGL} gr, @code{HCDT} y, @code{const char *}text, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_textw_y (@code{HMGL} gr, @code{HCDT} y, @code{const wchar_t *}text, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_text_xy (@code{HCDT} x, @code{HCDT} y, @code{const char *}text, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_textw_xy (@code{HCDT} x, @code{HCDT} y, @code{const wchar_t *}text, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_text_xyz (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}text, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_textw_xyz (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const wchar_t *}text, @code{const char *}fnt, @code{const char *}opt)
++@end ifclear
++The function draws @var{text} along the curve between points @{@var{x}[i], @var{y}[i], @var{z}[i]@} by font style @var{fnt}. The string @var{fnt} may contain symbols @samp{t} for printing the text under the curve (default), or @samp{T} for printing the text under the curve. The sizes of 1st dimension must be equal for all arrays @code{x.nx=y.nx=z.nx}. If array @var{x} is not specified then its an automatic array is used with values equidistantly distributed in x-axis range (see @ref{Ranges (bounding box)}). If array @var{z} is not specified then @var{z}[i] equal to minimal z-axis value is used. String @var{opt} contain command options (see @ref{Command options}).
++@end deftypefn
++
++@c ##################################################################
++@external{}
++@node Axis and Colorbar, Legend, Text printing, MathGL core
++@section Axis and Colorbar
++@nav{}
++@cindex Axis
++@cindex Box
++@cindex Grid
++@cindex Colorbar
++@cindex Label
++
++These functions draw the ``things for measuring'', like axis with ticks, colorbar with ticks, grid along axis, bounding box and labels for axis. For more information see @ref{Axis settings}.
++
++@anchor{axis}
++@deftypefn {MGL command} {} axis ['dir'='xyz' 'stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Axis (@code{const char *}dir=@code{"xyz"}, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_axis (@code{HMGL} gr, @code{const char *}dir, @code{const char *}stl, @code{const char *}opt)
++@end ifclear
++Draws axes with ticks (see @ref{Axis settings}). Parameter @var{dir} may contain:
++@itemize @bullet
++@item @samp{xyz} for drawing axis in corresponding direction;
++@item @samp{XYZ} for drawing axis in corresponding direction but with inverted positions of labels;
++@item @samp{~} or @samp{_} for disabling tick labels;
++@item @samp{U} for disabling rotation of tick labels;
++@item @samp{^} for inverting default axis origin;
++@item @samp{!} for disabling ticks tuning (see @ref{tuneticks});
++@item @samp{AKDTVISO} for drawing arrow at the end of axis;
++@item @samp{a} for forced adjusting of axis ticks;
++@item @samp{:} for drawing lines through point (0,0,0);
++@item @samp{f} for printing ticks labels in fixed format;
++@item @samp{E} for using @samp{E} instead of @samp{e} in ticks labels;
++@item @samp{F} for printing ticks labels in LaTeX format;
++@item @samp{+} for printing @samp{+} for positive ticks;
++@item @samp{-} for printing usual @samp{-} in ticks labels;
++@item @samp{0123456789} for precision at printing ticks labels.
++@end itemize
++Styles of ticks and axis can be overrided by using @var{stl} string. Option @code{value} set the manual rotation angle for the ticks. @sref{Axis and ticks}
++@end deftypefn
++
++@anchor{colorbar}
++@deftypefn {MGL command} {} colorbar ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Colorbar (@code{const char *}sch=@code{""})
++@deftypefnx {C function} @code{void} mgl_colorbar (@code{HMGL} gr, @code{const char *}sch)
++@end ifclear
++Draws colorbar. Parameter @var{sch} may contain:
++@itemize @bullet
++@item
++color scheme (see @ref{Color scheme});
++@item @samp{<>^_} for positioning at left, at right, at top or at bottom correspondingly;
++@item @samp{I} for positioning near bounding (by default, is positioned at edges of subplot);
++@item @samp{A} for using absolute coordinates;
++@item @samp{~} for disabling tick labels.
++@item @samp{!} for disabling ticks tuning (see @ref{tuneticks});
++@item @samp{f} for printing ticks labels in fixed format;
++@item @samp{E} for using @samp{E} instead of @samp{e} in ticks labels;
++@item @samp{F} for printing ticks labels in LaTeX format;
++@item @samp{+} for printing @samp{+} for positive ticks;
++@item @samp{-} for printing usual @samp{-} in ticks labels;
++@item @samp{0123456789} for precision at printing ticks labels.
++@end itemize
++@sref{Colorbars}
++@end deftypefn
++
++@deftypefn {MGL command} {} colorbar vdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Colorbar (@code{const mglDataA &}v, @code{const char *}sch=@code{""})
++@deftypefnx {C function} @code{void} mgl_colorbar_val (@code{HMGL} gr, @code{HCDT} v, @code{const char *}sch)
++@end ifclear
++The same as previous but with sharp colors @var{sch} (current palette if @code{sch=""}) for values @var{v}. @sref{ContD sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} colorbar 'sch' @code{x y [w=1 h=1]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Colorbar (@code{const char *}sch, @code{mreal} x, @code{mreal} y, @code{mreal} w=@code{1}, @code{mreal} h=@code{1})
++@deftypefnx {C function} @code{void} mgl_colorbar_ext (@code{HMGL} gr, @code{const char *}sch, @code{mreal} x, @code{mreal} y, @code{mreal} w, @code{mreal} h)
++@end ifclear
++The same as first one but at arbitrary position of subplot @{@var{x}, @var{y}@} (supposed to be in range [0,1]). Parameters @var{w}, @var{h} set the relative width and height of the colorbar.
++@end deftypefn
++
++@deftypefn {MGL command} {} colorbar vdat 'sch' @code{x y [w=1 h=1]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Colorbar (@code{const mglDataA &}v, @code{const char *}sch, @code{mreal} x, @code{mreal} y, @code{mreal} w=@code{1}, @code{mreal} h=@code{1})
++@deftypefnx {C function} @code{void} mgl_colorbar_val_ext (@code{HMGL} gr, @code{HCDT} v, @code{const char *}sch, @code{mreal} x, @code{mreal} y, @code{mreal} w, @code{mreal} h)
++@end ifclear
++The same as previous but with sharp colors @var{sch} (current palette if @code{sch=""}) for values @var{v}. @sref{ContD sample}
++@end deftypefn
++
++@anchor{grid}
++@deftypefn {MGL command} {} grid ['dir'='xyz' 'pen'='B']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Grid (@code{const char *}dir=@code{"xyz"}, @code{const char *}pen=@code{"B"}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_axis_grid (@code{HMGL} gr, @code{const char *}dir, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Draws grid lines perpendicular to direction determined by string parameter @var{dir}. If @var{dir} contain @samp{!} then grid lines will be drawn at coordinates of subticks also. The step of grid lines is the same as tick step for @ref{axis}. The style of lines is determined by @var{pen} parameter (default value is dark blue solid line @samp{B-}).
++@end deftypefn
++
++@anchor{box}
++@deftypefn {MGL command} {} box ['stl'='k' @code{ticks=on}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Box (@code{const char *}col=@code{""}, @code{bool} ticks=@code{true})
++@deftypefnx {C function} @code{void} mgl_box (@code{HMGL} gr)
++@deftypefnx {C function} @code{void} mgl_box_str (@code{HMGL} gr, @code{const char *}col, @code{int} ticks)
++@end ifclear
++Draws bounding box outside the plotting volume with color @var{col}. If @var{col} contain @samp{@@} then filled faces are drawn. At this first color is used for faces (default is light yellow), last one for edges. @sref{Bounding box}
++@end deftypefn
++
++@anchor{xlabel}
++@anchor{ylabel}
++@anchor{zlabel}
++@anchor{tlabel}
++@deftypefn {MGL command} {} xlabel 'text' [@code{pos=1}]
++@deftypefnx {MGL command} {} ylabel 'text' [@code{pos=1}]
++@deftypefnx {MGL command} {} zlabel 'text' [@code{pos=1}]
++@deftypefnx {MGL command} {} tlabel 'text' [@code{pos=1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{char} dir, @code{const char *}text, @code{mreal} pos=@code{1}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{char} dir, @code{const wchar_t *}text, @code{mreal} pos=@code{1}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_label (@code{HMGL} gr, @code{char} dir, @code{const char *}text, @code{mreal} pos, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_labelw (@code{HMGL} gr, @code{char} dir, @code{const wchar_t *}text, @code{mreal} pos, @code{const char *}opt)
++@end ifclear
++Prints the label @var{text} for axis @var{dir}=@samp{x},@samp{y},@samp{z},@samp{t} (here @samp{t} is ``ternary'' axis @math{t=1-x-y}). The position of label is determined by @var{pos} parameter. If @var{pos}=0 then label is printed at the center of axis. If @var{pos}>0 then label is printed at the maximum of axis. If @var{pos}<0 then label is printed at the minimum of axis. Option @code{value} set additional shifting of the label. @xref{Text printing}.
++@end deftypefn
++
++@c ##################################################################
++@external{}
++@node Legend, 1D plotting, Axis and Colorbar, MathGL core
++@section Legend
++@nav{}
++@cindex Legend
++@cindex AddLegend
++@cindex ClearLegend
++@cindex SetLegendBox
++@cindex SetLegendMarks
++
++These functions draw legend to the graph (useful for @ref{1D plotting}). Legend entry is a pair of strings: one for style of the line, another one with description text (with included TeX parsing). The arrays of strings may be used directly or by accumulating first to the internal arrays (by function @ref{addlegend}) and further plotting it. The position of the legend can be selected automatic or manually (even out of bounding box). Parameters @var{fnt} and @var{size} specify the font style and size (see @ref{Font settings}). Option @code{value} set the relative width of the line sample and the text indent. If line style string for entry is empty then the corresponding text is printed without indent. Parameter @var{fnt} may contain:
++@itemize @bullet
++@item
++font style for legend text;
++@item
++@samp{A} for positioning in absolute coordinates;
++@item
++@samp{^} for positioning outside of specified point;
++@item
++@samp{#} for drawing box around legend;
++@item
++@samp{-} for arranging legend entries horizontally;
++@item
++colors for face (1st one), for border (2nd one) and for text (last one). If less than 3 colors are specified then the color for border is black (for 2 and less colors), and the color for face is white (for 1 or none colors).
++@end itemize
++@sref{Legend sample}
++
++@anchor{legend}
++@deftypefn {MGL command} {} legend [@code{pos=3} 'fnt'='#']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Legend (@code{int} pos=@code{0x3}, @code{const char *}fnt=@code{"#"}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_legend (@code{HMGL} gr, @code{int} pos, @code{const char *}fnt, @code{const char *}opt)
++@end ifclear
++Draws legend of accumulated legend entries by font @var{fnt} with @var{size}. Parameter @var{pos} sets the position of the legend: @samp{0} is bottom left corner, @samp{1} is bottom right corner, @samp{2} is top left corner, @samp{3} is top right corner (is default). Option @code{value} set the space between line samples and text (default is 0.1).
++@end deftypefn
++
++@deftypefn {MGL command} {} legend @code{x y} ['fnt'='#']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Legend (@code{mreal} x, @code{mreal} y, @code{const char *}fnt=@code{"#"}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_legend_pos (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{const char *}fnt, @code{const char *}opt)
++@end ifclear
++Draws legend of accumulated legend entries by font @var{fnt} with @var{size}. Position of legend is determined by parameter @var{x}, @var{y} which supposed to be normalized to interval [0,1]. Option @code{value} set the space between line samples and text (default is 0.1).
++@end deftypefn
++
++@anchor{addlegend}
++@deftypefn {MGL command} {} addlegend 'text' 'stl'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} AddLegend (@code{const char *}text, @code{const char *}style)
++@deftypefnx {Method on @code{mglGraph}} @code{void} AddLegend (@code{const wchar_t *}text, @code{const char *}style)
++@deftypefnx {C function} @code{void} mgl_add_legend (@code{HMGL} gr, @code{const char *}text, @code{const char *}style)
++@deftypefnx {C function} @code{void} mgl_add_legendw (@code{HMGL} gr, @code{const wchar_t *}text, @code{const char *}style)
++@end ifclear
++Adds string @var{text} to internal legend accumulator. The style of described line and mark is specified in string @var{style} (see @ref{Line styles}).
++@end deftypefn
++
++@anchor{clearlegend}
++@deftypefn {MGL command} {} clearlegend
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ClearLegend ()
++@deftypefnx {C function} @code{void} mgl_clear_legend (@code{HMGL} gr)
++@end ifclear
++Clears saved legend strings.
++@end deftypefn
++
++@anchor{legendmarks}
++@deftypefn {MGL command} {} legendmarks @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SetLegendMarks (@code{int} num)
++@deftypefnx {C function} @code{void} mgl_set_legend_marks (@code{HMGL} gr, @code{int} num)
++@end ifclear
++Set the number of marks in the legend. By default 1 mark is used.
++@end deftypefn
++
++@c ##################################################################
++@external{}
++@node 1D plotting, 2D plotting, Legend, MathGL core
++@section 1D plotting
++@nav{}
++@cindex Plot
++@cindex Radar
++@cindex Tens
++@cindex Area
++@cindex Region
++@cindex Stem
++@cindex Bars
++@cindex Barh
++@cindex Chart
++@cindex Step
++@cindex Torus
++@cindex Tube
++@cindex Mark
++@cindex TextMark
++@cindex Error
++@cindex BoxPlot
++@cindex Candle
++@cindex Tape
++@cindex Label
++@cindex Cones
++
++These functions perform plotting of 1D data. 1D means that data depended from only 1 parameter like parametric curve @{x[i],y[i],z[i]@}, i=1...n. By default (if absent) values of @var{x}[i] are equidistantly distributed in axis range, and @var{z}[i] equal to minimal z-axis value. The plots are drawn for each row if one of the data is the matrix. By any case the sizes of 1st dimension @strong{must be equal} for all arrays @code{x.nx=y.nx=z.nx}.
++
++String @var{pen} specifies the color and style of line and marks (see @ref{Line styles}). By default (@code{pen=""}) solid line with color from palette is used (see @ref{Palette and colors}). Symbol @samp{!} set to use new color from palette for each point (not for each curve, as default). String @var{opt} contain command options (see @ref{Command options}). @sref{1D samples}
++
++@anchor{plot}
++@deftypefn {MGL command} {} plot ydat ['stl'='']
++@deftypefnx {MGL command} {} plot xdat ydat ['stl'='']
++@deftypefnx {MGL command} {} plot xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Plot (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Plot (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Plot (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_plot (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_plot_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_plot_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw continuous lines between points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. If @var{pen} contain @samp{a} then segments between points outside of axis range are drawn too. If @var{pen} contain @samp{~} then number of segments is reduce for quasi-straight curves. See also @ref{area}, @ref{step}, @ref{stem}, @ref{tube}, @ref{mark}, @ref{error}, @ref{belt}, @ref{tens}, @ref{tape}, @ref{meshnum}. @sref{Plot sample}
++@end deftypefn
++
++@anchor{radar}
++@deftypefn {MGL command} {} radar adat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Radar (@code{const mglDataA &}a, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_radar (@code{HMGL} gr, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++This functions draws radar chart which is continuous lines between points located on an radial lines (like plot in Polar coordinates). Option @code{value} set the additional shift of data (i.e. the data @var{a}+@code{value} is used instead of @var{a}). If @code{value<0} then @code{r=max(0, -min(value)}. If @var{pen} containt @samp{#} symbol then "grid" (radial lines and circle for @var{r}) is drawn. If @var{pen} contain @samp{a} then segments between points outside of axis range are drawn too. See also @ref{plot}, @ref{meshnum}. @sref{Radar sample}
++@end deftypefn
++
++@anchor{step}
++@deftypefn {MGL command} {} step ydat ['stl'='']
++@deftypefnx {MGL command} {} step xdat ydat ['stl'='']
++@deftypefnx {MGL command} {} step xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Step (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Step (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Step (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_step (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_step_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_step_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw continuous stairs for points to axis plane. If @var{x}.nx>@var{y}.nx then @var{x} set the edges of bars, rather than its central positions. See also @ref{plot}, @ref{stem}, @ref{tile}, @ref{boxs}, @ref{meshnum}. @sref{Step sample}
++@end deftypefn
++
++@anchor{tens}
++@deftypefn {MGL command} {} tens ydat cdat ['stl'='']
++@deftypefnx {MGL command} {} tens xdat ydat cdat ['stl'='']
++@deftypefnx {MGL command} {} tens xdat ydat zdat cdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tens (@code{const mglDataA &}y, @code{const mglDataA &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tens (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tens (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_tens (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tens_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tens_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw continuous lines between points @{@var{x}[i], @var{y}[i], @var{z}[i]@} with color defined by the special array @var{c}[i] (look like tension plot). String @var{pen} specifies the color scheme (see @ref{Color scheme}) and style and/or width of line (see @ref{Line styles}). If @var{pen} contain @samp{a} then segments between points outside of axis range are drawn too. If @var{pen} contain @samp{~} then number of segments is reduce for quasi-straight curves. See also @ref{plot}, @ref{mesh}, @ref{fall}, @ref{meshnum}. @sref{Tens sample}
++@end deftypefn
++
++@anchor{tape}
++@deftypefn {MGL command} {} tape ydat ['stl'='']
++@deftypefnx {MGL command} {} tape xdat ydat ['stl'='']
++@deftypefnx {MGL command} {} tape xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tape (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tape (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tape (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_tape (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tape_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tape_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw tapes of normals for curve between points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Initial tape(s) was selected in x-y plane (for @samp{x} in @var{pen}) and/or y-z plane (for @samp{x} in @var{pen}). The width of tape is proportional to @ref{barwidth} and can be changed by option @code{value}. See also @ref{plot}, @ref{flow}, @ref{barwidth}. @sref{Tape sample}
++@end deftypefn
++
++@anchor{area}
++@deftypefn {MGL command} {} area ydat ['stl'='']
++@deftypefnx {MGL command} {} area xdat ydat ['stl'='']
++@deftypefnx {MGL command} {} area xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Area (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Area (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Area (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_area (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_area_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_area_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw continuous lines between points and fills it to axis plane. Also you can use gradient filling if number of specified colors is equal to 2*number of curves. If @var{pen} contain @samp{#} then wired plot is drawn. If @var{pen} contain @samp{a} then segments between points outside of axis range are drawn too. See also @ref{plot}, @ref{bars}, @ref{stem}, @ref{region}. @sref{Area sample}
++@end deftypefn
++
++@anchor{region}
++@deftypefn {MGL command} {} region ydat1 ydat2 ['stl'='']
++@deftypefnx {MGL command} {} region xdat ydat1 ydat2 ['stl'='']
++@deftypefnx {MGL command} {} region xdat1 ydat1 xdat2 ydat2 ['stl'='']
++@deftypefnx {MGL command} {} region xdat1 ydat1 zdat1 xdat2 ydat2 zdat2 ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Region (@code{const mglDataA &}y1, @code{const mglDataA &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Region (@code{const mglDataA &}x, @code{const mglDataA &}y1, @code{const mglDataA &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Region (@code{const mglDataA &}x1, @code{const mglDataA &}y1, @code{const mglDataA &}x2, @code{const mglDataA &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Region (@code{const mglDataA &}x1, @code{const mglDataA &}y1, @code{const mglDataA &}z1, @code{const mglDataA &}x2, @code{const mglDataA &}y2, @code{const mglDataA &}z2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_region (@code{HMGL} gr, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_region_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_region_3d (@code{HMGL} gr, @code{HCDT} x1, @code{HCDT} y1, @code{HCDT} z1, @code{HCDT} x2, @code{HCDT} y2, @code{HCDT} z2, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions fill area between 2 curves. Dimensions of arrays @var{y1} and @var{y2} must be equal. Also you can use gradient filling if number of specified colors is equal to 2*number of curves. If for 2D version @var{pen} contain symbol @samp{i} then only area with y1<y<y2 will be filled else the area with y2<y<y1 will be filled too. If @var{pen} contain @samp{#} then wired plot is drawn. If @var{pen} contain @samp{a} then segments between points outside of axis range are drawn too. See also @ref{area}, @ref{bars}, @ref{stem}. @sref{Region sample}
++@end deftypefn
++
++@anchor{stem}
++@deftypefn {MGL command} {} stem ydat ['stl'='']
++@deftypefnx {MGL command} {} stem xdat ydat ['stl'='']
++@deftypefnx {MGL command} {} stem xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Stem (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Stem (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Stem (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_stem (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_stem_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_stem_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw vertical lines from points to axis plane. See also @ref{area}, @ref{bars}, @ref{plot}, @ref{mark}. @sref{Stem sample}
++@end deftypefn
++
++@anchor{bars}
++@deftypefn {MGL command} {} bars ydat ['stl'='']
++@deftypefnx {MGL command} {} bars xdat ydat ['stl'='']
++@deftypefnx {MGL command} {} bars xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Bars (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Bars (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Bars (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_bars (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_bars_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_bars_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw vertical bars from points to axis plane. Parameter @var{pen} can contain:
++@itemize @bullet
++@item
++@samp{a} for drawing lines one above another (like summation);
++@item
++@samp{f} for drawing waterfall chart, which show the cumulative effect of sequential positive or negative values;
++@item
++@samp{F} for using fixed (minimal) width for all bars;
++@item
++@samp{<}, @samp{^} or @samp{>} for aligning boxes left, right or centering them at its x-coordinates.
++@end itemize
++You can give different colors for positive and negative values if number of specified colors is equal to 2*number of curves. If @var{x}.nx>@var{y}.nx then @var{x} set the edges of bars, rather than its central positions. See also @ref{barh}, @ref{cones}, @ref{area}, @ref{stem}, @ref{chart}, @ref{barwidth}. @sref{Bars sample}
++@end deftypefn
++
++@anchor{barh}
++@deftypefn {MGL command} {} barh vdat ['stl'='']
++@deftypefnx {MGL command} {} barh ydat vdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Barh (@code{const mglDataA &}v, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Barh (@code{const mglDataA &}y, @code{const mglDataA &}v, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_barh (@code{HMGL} gr, @code{HCDT} v, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_barh_xy (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} v, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw horizontal bars from points to axis plane. Parameter @var{pen} can contain:
++@itemize @bullet
++@item
++@samp{a} for drawing lines one above another (like summation);
++@item
++@samp{f} for drawing waterfall chart, which show the cumulative effect of sequential positive or negative values;
++@item
++@samp{F} for using fixed (minimal) width for all bars;
++@item
++@samp{<}, @samp{^} or @samp{>} for aligning boxes left, right or centering them at its x-coordinates.
++@end itemize
++You can give different colors for positive and negative values if number of specified colors is equal to 2*number of curves. If @var{x}.nx>@var{y}.nx then @var{x} set the edges of bars, rather than its central positions. See also @ref{bars}, @ref{barwidth}. @sref{Barh sample}
++@end deftypefn
++
++@anchor{cones}
++@deftypefn {MGL command} {} cones ydat ['stl'='']
++@deftypefnx {MGL command} {} cones xdat ydat ['stl'='']
++@deftypefnx {MGL command} {} cones xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cones (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cones (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cones (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_cones (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_cones_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_cones_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw cones from points to axis plane. If string contain symbol @samp{a} then cones are drawn one above another (like summation). You can give different colors for positive and negative values if number of specified colors is equal to 2*number of curves. Parameter @var{pen} can contain:
++@itemize @bullet
++@item
++@samp{@@} for drawing edges;
++@item
++@samp{#} for wired cones;
++@item
++@samp{t} for drawing tubes/cylinders instead of cones/prisms;
++@item
++@samp{4}, @samp{6}, @samp{8} for drawing square, hex- or octo-prism instead of cones;
++@item
++@samp{<}, @samp{^} or @samp{>} for aligning boxes left, right or centering them at its x-coordinates.
++@end itemize
++See also @ref{bars}, @ref{cone}, @ref{barwidth}. @sref{Cones sample}
++@end deftypefn
++
++
++
++@anchor{chart}
++@deftypefn {MGL command} {} chart adat ['col'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Chart (@code{const mglDataA &}a, @code{const char *}col=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_chart (@code{HMGL} gr, @code{HCDT} a, @code{const char *}col, @code{const char *}opt)
++@end ifclear
++The function draws colored stripes (boxes) for data in array @var{a}. The number of stripes is equal to the number of rows in @var{a} (equal to @var{a.ny}). The color of each next stripe is cyclically changed from colors specified in string @var{col} or in palette Pal (see @ref{Palette and colors}). Spaces in colors denote transparent ``color'' (i.e. corresponding stripe(s) are not drawn). The stripe width is proportional to value of element in @var{a}. Chart is plotted only for data with non-negative elements. If string @var{col} have symbol @samp{#} then black border lines are drawn. The most nice form the chart have in 3d (after rotation of coordinates) or in cylindrical coordinates (becomes so called Pie chart). @sref{Chart sample}
++@end deftypefn
++
++@anchor{boxplot}
++@deftypefn {MGL command} {} boxplot adat ['stl'='']
++@deftypefnx {MGL command} {} boxplot xdat adat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} BoxPlot (@code{const mglDataA &}a, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} BoxPlot (@code{const mglDataA &}x, @code{const mglDataA &}a, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_boxplot (@code{HMGL} gr, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_boxplot_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw boxplot (also known as a box-and-whisker diagram) at points @var{x}[i]. This is five-number summaries of data @var{a}[i,j] (minimum, lower quartile (Q1), median (Q2), upper quartile (Q3) and maximum) along second (j-th) direction. If @var{pen} contain @samp{<}, @samp{^} or @samp{>} then boxes will be aligned left, right or centered at its x-coordinates. See also @ref{plot}, @ref{error}, @ref{bars}, @ref{barwidth}. @sref{BoxPlot sample}
++@end deftypefn
++
++@anchor{candle}
++@deftypefn {MGL command} {} candle vdat1 ['stl'='']
++@deftypefnx {MGL command} {} candle vdat1 vdat2 ['stl'='']
++@deftypefnx {MGL command} {} candle vdat1 ydat1 ydat2 ['stl'='']
++@deftypefnx {MGL command} {} candle vdat1 vdat2 ydat1 ydat2 ['stl'='']
++@deftypefnx {MGL command} {} candle xdat vdat1 vdat2 ydat1 ydat2 ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Candle (@code{const mglDataA &}v1, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Candle (@code{const mglDataA &}v1, @code{const mglDataA &}v2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Candle (@code{const mglDataA &}v1, @code{const mglDataA &}y1, @code{const mglDataA &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Candle (@code{const mglDataA &}v1, @code{const mglDataA &}v2, @code{const mglDataA &}y1, @code{const mglDataA &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Candle (@code{const mglDataA &}x, @code{const mglDataA &}v1, @code{const mglDataA &}v2, @code{const mglDataA &}y1, @code{const mglDataA &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_candle (@code{HMGL} gr, @code{HCDT} v1, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_candle_yv (@code{HMGL} gr, @code{HCDT} v1, @code{HCDT} v2, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_candle_xyv (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} v1, @code{HCDT} v2, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw candlestick chart at points @var{x}[i]. This is a combination of a line-chart and a bar-chart, in that each bar represents the range of price movement over a given time interval. Wire (or white) candle correspond to price growth @var{v1}[i]<@var{v2}[i], opposite case -- solid (or dark) candle. You can give different colors for growth and decrease values if number of specified colors is equal to 2. If @var{pen} contain @samp{#} then the wire candle will be used even for 2-color scheme. "Shadows" show the minimal @var{y1} and maximal @var{y2} prices. If @var{v2} is absent then it is determined as @var{v2}[i]=@var{v1}[i+1]. See also @ref{plot}, @ref{bars}, @ref{ohlc}, @ref{barwidth}. @sref{Candle sample}
++@end deftypefn
++
++@anchor{ohlc}
++@deftypefn {MGL command} {} ohlc odat hdat ldat cdat ['stl'='']
++@deftypefnx {MGL command} {} ohlc xdat odat hdat ldat cdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} OHLC (@code{const mglDataA &}o, @code{const mglDataA &}h, @code{const mglDataA &}l, @code{const mglDataA &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} OHLC (@code{const mglDataA &}x, @code{const mglDataA &}o, @code{const mglDataA &}h, @code{const mglDataA &}l, @code{const mglDataA &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_ohlc (@code{HMGL} gr, @code{HCDT} o, @code{HCDT} h, @code{HCDT} l, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_ohlc_x (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} o, @code{HCDT} h, @code{HCDT} l, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw Open-High-Low-Close diagram. This diagram show vertical line for between maximal(high @var{h}) and minimal(low @var{l}) values, as well as horizontal lines before/after vertical line for initial(open @var{o})/final(close @var{c}) values of some process (usually price). You can give different colors for up and down values (when closing values higher or not as in previous point) if number of specified colors is equal to 2*number of curves. See also @ref{candle}, @ref{plot}, @ref{barwidth}. @sref{OHLC sample}
++@end deftypefn
++
++
++@anchor{error}
++@deftypefn {MGL command} {} error ydat yerr ['stl'='']
++@deftypefnx {MGL command} {} error xdat ydat yerr ['stl'='']
++@deftypefnx {MGL command} {} error xdat ydat xerr yerr ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Error (@code{const mglDataA &}y, @code{const mglDataA &}ey, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Error (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ey, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Error (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ex, @code{const mglDataA &}ey, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_error (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_error_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_error_exy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ex, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw error boxes @{@var{ex}[i], @var{ey}[i]@} at points @{@var{x}[i], @var{y}[i]@}. This can be useful, for example, in experimental points, or to show numeric error or some estimations and so on. If string @var{pen} contain symbol @samp{@@} than large semitransparent mark is used instead of error box. See also @ref{plot}, @ref{mark}. @sref{Error sample}
++@end deftypefn
++
++@anchor{mark}
++@deftypefn {MGL command} {} mark ydat rdat ['stl'='']
++@deftypefnx {MGL command} {} mark xdat ydat rdat ['stl'='']
++@deftypefnx {MGL command} {} mark xdat ydat zdat rdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Mark (@code{const mglDataA &}y, @code{const mglDataA &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Mark (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Mark (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_mark_y (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_mark_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_mark_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw marks with size @var{r}[i]*@ref{marksize} at points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. If you need to draw markers of the same size then you can use @ref{plot} function with empty line style @samp{ }. For markers with size in axis range use @ref{error} with style @samp{@@}. See also @ref{plot}, @ref{textmark}, @ref{error}, @ref{stem}, @ref{meshnum}. @sref{Mark sample}
++@end deftypefn
++
++@anchor{textmark}
++@deftypefn {MGL command} {} textmark ydat 'txt' ['stl'='']
++@deftypefnx {MGL command} {} textmark ydat rdat 'txt' ['stl'='']
++@deftypefnx {MGL command} {} textmark xdat ydat rdat 'txt' ['stl'='']
++@deftypefnx {MGL command} {} textmark xdat ydat zdat rdat 'txt' ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}y, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}y, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}y, @code{const mglDataA &}r, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}y, @code{const mglDataA &}r, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}r, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}r, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}r, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}r, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_textmark (@code{HMGL} gr, @code{HCDT} y, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_textmarkw (@code{HMGL} gr, @code{HCDT} y, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_textmark_yr (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_textmarkw_yr (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_textmark_xyr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_textmarkw_xyr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_textmark_xyzr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_textmarkw_xyzr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@end ifclear
++These functions draw string @var{txt} as marks with size proportional to @var{r}[i]*@var{marksize} at points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. By default (if omitted) @var{r}[i]=1. See also @ref{plot}, @ref{mark}, @ref{stem}, @ref{meshnum}. @sref{TextMark sample}
++@end deftypefn
++
++@anchor{label}
++@deftypefn {MGL command} {} label ydat 'txt' ['stl'='']
++@deftypefnx {MGL command} {} label xdat ydat 'txt' ['stl'='']
++@deftypefnx {MGL command} {} label xdat ydat zdat 'txt' ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{const mglDataA &}y, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{const mglDataA &}y, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Label (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_label (@code{HMGL} gr, @code{HCDT} y, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_labelw (@code{HMGL} gr, @code{HCDT} y, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_label_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_labelw_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_label_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_labelw_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@end ifclear
++These functions draw string @var{txt} at points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. If string @var{txt} contain @samp{%x}, @samp{%y}, @samp{%z} or @samp{%n} then it will be replaced by the value of x-,y-,z-coordinate of the point or its index. String @var{fnt} may contain:
++@itemize
++@item font style @ref{Font styles};
++@item @samp{f} for fixed format of printed numbers;
++@item @samp{E} for using @samp{E} instead of @samp{e};
++@item @samp{F} for printing in LaTeX format;
++@item @samp{+} for printing @samp{+} for positive numbers;
++@item @samp{-} for printing usual @samp{-};
++@item @samp{0123456789} for precision at printing numbers.
++@end itemize
++See also @ref{plot}, @ref{mark}, @ref{textmark}, @ref{table}. @sref{Label sample}
++@end deftypefn
++
++@anchor{table}
++@deftypefn {MGL command} {} table vdat 'txt' ['stl'='#']
++@deftypefnx {MGL command} {} table x y vdat 'txt' ['stl'='#']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Table (@code{const mglDataA &}val, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Table (@code{const mglDataA &}val, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Table (@code{mreal} x, @code{mreal} y, @code{const mglDataA &}val, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Table (@code{mreal} x, @code{mreal} y, @code{const mglDataA &}val, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_table (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{HCDT} val, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tablew (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{HCDT} val, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@end ifclear
++These functions draw table with values of @var{val} and captions from string @var{txt} (separated by newline symbol @samp{\n}) at points @{@var{x}, @var{y}@} (default at @{0,0@}) related to current subplot. String @var{fnt} may contain:
++@itemize
++@item font style @ref{Font styles};
++@item @samp{#} for drawing cell borders;
++@item @samp{|} for limiting table widh by subplot one (equal to option @samp{value 1});
++@item @samp{=} for equal width of all cells;
++@item @samp{f} for fixed format of printed numbers;
++@item @samp{E} for using @samp{E} instead of @samp{e};
++@item @samp{F} for printing in LaTeX format;
++@item @samp{+} for printing @samp{+} for positive numbers;
++@item @samp{-} for printing usual @samp{-};
++@item @samp{0123456789} for precision at printing numbers.
++@end itemize
++Option @code{value} set the width of the table (default is 1). See also @ref{plot}, @ref{label}. @sref{Table sample}
++@end deftypefn
++
++@anchor{iris}
++@deftypefn {MGL command} {} iris dats 'ids' ['stl'='']
++@deftypefnx {MGL command} {} iris dats rngs 'ids' ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Iris (@code{const mglDataA &}dats, @code{const char *}ids, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Iris (@code{const mglDataA &}dats, @code{const wchar_t *}ids, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Iris (@code{const mglDataA &}dats, @code{const mglDataA &}rngs, @code{const char *}ids, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Iris (@code{const mglDataA &}dats, @code{const mglDataA &}rngs, @code{const wchar_t *}ids, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_iris_1 (@code{HMGL} gr, @code{HCDT} dats, @code{const char *}ids, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_irisw_1 (@code{HMGL} gr, @code{HCDT} dats, @code{const wchar_t *}ids, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_iris (@code{HMGL} gr, @code{HCDT} dats, @code{HCDT} rngs, @code{const char *}ids, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_irisw (@code{HMGL} gr, @code{HCDT} dats, @code{HCDT} rngs, @code{const wchar_t *}ids, @code{const char *}stl, @code{const char *}opt)
++@end ifclear
++Draws Iris plots for determining cross-dependences of data arrays @var{dats} (see @uref{http://en.wikipedia.org/wiki/Iris_flower_data_set}). Data @var{rngs} of size 2*@var{dats}.nx provide manual axis ranges for each column. String @var{ids} contain column names, separated by @samp{;} symbol. Option @code{value} set the text size for column names. You can add another data set to existing Iris plot by providing the same ranges @var{rngs} and empty column names @var{ids}. See also @ref{plot}. @sref{Iris sample}
++@end deftypefn
++
++@anchor{tube}
++@deftypefn {MGL command} {} tube ydat rdat ['stl'='']
++@deftypefnx {MGL command} {} tube ydat @code{rval} ['stl'='']
++@deftypefnx {MGL command} {} tube xdat ydat rdat ['stl'='']
++@deftypefnx {MGL command} {} tube xdat ydat @code{rval} ['stl'='']
++@deftypefnx {MGL command} {} tube xdat ydat zdat rdat ['stl'='']
++@deftypefnx {MGL command} {} tube xdat ydat zdat @code{rval} ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tube (@code{const mglDataA &}y, @code{const mglDataA &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tube (@code{const mglDataA &}y, @code{mreal} r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tube (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tube (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{mreal} r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tube (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tube (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{mreal} r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_tube_r (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tube (@code{HMGL} gr, @code{HCDT} y, @code{mreal} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tube_xyr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tube_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{mreal} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tube_xyzr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tube_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{mreal} r, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw the tube with variable radius @var{r}[i] along the curve between points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. See also @ref{plot}. @sref{Tube sample}
++@end deftypefn
++
++@anchor{torus}
++@deftypefn {MGL command} {} torus rdat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Torus (@code{const mglDataA &}r, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_torus (@code{HMGL} gr, @code{HCDT} r, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++These functions draw surface which is result of curve @{@var{r}, @var{z}@} rotation around axis. If string @var{pen} contain symbols @samp{x} or @samp{z} then rotation axis will be set to specified direction (default is @samp{y}). If string @var{pen} have symbol @samp{#} then wire plot is produced. If string @var{pen} have symbol @samp{.} then plot by dots is produced. See also @ref{plot}, @ref{axial}. @sref{Torus sample}
++@end deftypefn
++
++@anchor{lamerey}
++@deftypefn {MGL command} {} lamerey @code{x0} ydat ['stl'='']
++@deftypefnx {MGL command} {} lamerey @code{x0} 'y(x)' ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Lamerey (@code{double} x0, @code{const mglDataA &}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Lamerey (@code{double} x0, @code{const char *}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_lamerey_dat (@code{HMGL} gr, @code{double} x0, @code{HCDT} y, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_lamerey_str (@code{HMGL} gr, @code{double} x0, @code{const char *}y, @code{const char *}stl, @code{const char *}opt)
++@end ifclear
++These functions draw Lamerey diagram for mapping x_new = y(x_old) starting from point @var{x0}. String @var{stl} may contain line style, symbol @samp{v} for drawing arrows, symbol @samp{~} for disabling first segment. Option @code{value} set the number of segments to be drawn (default is 20). See also @ref{plot}, @ref{fplot}, @ref{bifurcation}, @ref{pmap}. @sref{Lamerey sample}
++@end deftypefn
++
++@anchor{bifurcation}
++@deftypefn {MGL command} {} bifurcation @code{dx} ydat ['stl'='']
++@deftypefnx {MGL command} {} bifurcation @code{dx} 'y(x)' ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Bifurcation (@code{double} dx, @code{const mglDataA &}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Bifurcation (@code{double} dx, @code{const char *}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_bifurcation_dat (@code{HMGL} gr, @code{double} dx, @code{HCDT} y, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_bifurcation_str (@code{HMGL} gr, @code{double} dx, @code{const char *}y, @code{const char *}stl, @code{const char *}opt)
++@end ifclear
++These functions draw bifurcation diagram for mapping x_new = y(x_old). Parameter @var{dx} set the accuracy along x-direction. String @var{stl} set color. Option @code{value} set the number of stationary points (default is 1024). See also @ref{plot}, @ref{fplot}, @ref{lamerey}. @sref{Bifurcation sample}
++@end deftypefn
++
++@anchor{pmap}
++@deftypefn {MGL command} {} pmap ydat sdat ['stl'='']
++@deftypefnx {MGL command} {} pmap xdat ydat sdat ['stl'='']
++@deftypefnx {MGL command} {} pmap xdat ydat zdat sdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Pmap (@code{const mglDataA &}y, @code{const mglDataA &}s, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Pmap (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}s, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Pmap (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}s, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_pmap (@code{HMGL} gr, @code{HMDT} y, @code{HCDT} s, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_pmap_xy (@code{HMGL} gr, @code{HCDT} x, @code{HMDT} y, @code{HCDT} s, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_pmap_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HMDT} y, @code{HCDT} z, @code{HCDT} s, @code{const char *}stl, @code{const char *}opt)
++@end ifclear
++These functions draw Poincare map for curve @{@var{x}, @var{y}, @var{z}@} at surface @var{s}=0. Basically, it show intersections of the curve and the surface. String @var{stl} set the style of marks. See also @ref{plot}, @ref{mark}, @ref{lamerey}. @sref{Pmap sample}
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node 2D plotting, 3D plotting, 1D plotting, MathGL core
++@section 2D plotting
++@nav{}
++@cindex Mesh
++@cindex Fall
++@cindex Belt
++@cindex Surf
++@cindex Boxs
++@cindex Tile
++@cindex Dens
++@cindex Cont
++@cindex ContF
++@cindex ContD
++@cindex Axial
++@cindex Grad
++@cindex Grid
++
++These functions perform plotting of 2D data. 2D means that data depend from 2 independent parameters like matrix @math{f(x_i,y_j), i=1...n, j=1...m}. By default (if absent) values of @var{x}, @var{y} are equidistantly distributed in axis range. The plots are drawn for each z slice of the data. The minor dimensions of arrays @var{x}, @var{y}, @var{z} should be equal @code{x.nx=z.nx && y.nx=z.ny} or @code{x.nx=y.nx=z.nx && x.ny=y.ny=z.ny}. Arrays @var{x} and @var{y} can be vectors (not matrices as @var{z}). String @var{sch} sets the color scheme (see @ref{Color scheme}) for plot. String @var{opt} contain command options (see @ref{Command options}). @sref{2D samples}
++
++@anchor{surf}
++@deftypefn {MGL command} {} surf zdat ['sch'='']
++@deftypefnx {MGL command} {} surf xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_surf (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_surf_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. If string @var{sch} have symbol @samp{#} then grid lines are drawn. If string @var{sch} have symbol @samp{.} then plot by dots is produced. See also @ref{mesh}, @ref{dens}, @ref{belt}, @ref{tile}, @ref{boxs}, @ref{surfc}, @ref{surfa}. @sref{Surf sample}
++@end deftypefn
++
++@anchor{mesh}
++@deftypefn {MGL command} {} mesh zdat ['sch'='']
++@deftypefnx {MGL command} {} mesh xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Mesh (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Mesh (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_mesh (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_mesh_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws mesh lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. See also @ref{surf}, @ref{fall}, @ref{meshnum}, @ref{cont}, @ref{tens}. @sref{Mesh sample}
++@end deftypefn
++
++@anchor{fall}
++@deftypefn {MGL command} {} fall zdat ['sch'='']
++@deftypefnx {MGL command} {} fall xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Fall (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Fall (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_fall (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_fall_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws fall lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. This plot can be used for plotting several curves shifted in depth one from another. If @var{sch} contain @samp{x} then lines are drawn along x-direction else (by default) lines are drawn along y-direction. See also @ref{belt}, @ref{mesh}, @ref{tens}, @ref{meshnum}. @sref{Fall sample}
++@end deftypefn
++
++@anchor{belt}
++@deftypefn {MGL command} {} belt zdat ['sch'='']
++@deftypefnx {MGL command} {} belt xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Belt (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Belt (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_belt (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_belt_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws belts for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. This plot can be used as 3d generalization of @ref{plot}). If @var{sch} contain @samp{x} then belts are drawn along x-direction else (by default) belts are drawn along y-direction. See also @ref{fall}, @ref{surf}, @ref{beltc}, @ref{plot}, @ref{meshnum}. @sref{Belt sample}
++@end deftypefn
++
++@anchor{boxs}
++@deftypefn {MGL command} {} boxs zdat ['sch'='']
++@deftypefnx {MGL command} {} boxs xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Boxs (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Boxs (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_boxs (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_boxs_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws vertical boxes for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. Symbol @samp{@@} in @var{sch} set to draw filled boxes. See also @ref{surf}, @ref{dens}, @ref{tile}, @ref{step}. @sref{Boxs sample}
++@end deftypefn
++
++@anchor{tile}
++@deftypefn {MGL command} {} tile zdat ['sch'='']
++@deftypefnx {MGL command} {} tile xdat ydat zdat ['sch'='']
++@deftypefnx {MGL command} {} tile xdat ydat zdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tile (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tile (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Tile (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_tile (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tile_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tile_xyc (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws horizontal tiles for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} and color it by matrix @var{c}[i,j] (@var{c}=@var{z} if @var{c} is not provided). If string @var{sch} contain style @samp{x} or @samp{y} then tiles will be oriented perpendicular to x- or y-axis. Such plot can be used as 3d generalization of @ref{step}. See also @ref{surf}, @ref{boxs}, @ref{step}, @ref{tiles}. @sref{Tile sample}
++@end deftypefn
++
++@anchor{dens}
++@deftypefn {MGL command} {} dens zdat ['sch'='']
++@deftypefnx {MGL command} {} dens xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Dens (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{mreal} zVal=@code{NAN})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Dens (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{mreal} zVal=@code{NAN})
++@deftypefnx {C function} @code{void} mgl_dens (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_dens_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws density plot for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z} equal to minimal z-axis value. If string @var{sch} have symbol @samp{#} then grid lines are drawn. If string @var{sch} have symbol @samp{.} then plot by dots is produced. See also @ref{surf}, @ref{cont}, @ref{contf}, @ref{boxs}, @ref{tile}, @code{dens[xyz]}. @sref{Dens sample}
++@end deftypefn
++
++@anchor{cont}
++@deftypefn {MGL command} {} cont vdat zdat ['sch'='']
++@deftypefnx {MGL command} {} cont vdat xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cont (@code{const mglDataA &}v, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cont (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_cont_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_cont_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws contour lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z}=@var{v}[k], or at @var{z} equal to minimal z-axis value if @var{sch} contain symbol @samp{_}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v}. If string @var{sch} have symbol @samp{t} or @samp{T} then contour labels @var{v}[k] will be drawn below (or above) the contours. See also @ref{dens}, @ref{contf}, @ref{contd}, @ref{axial}, @code{cont[xyz]}. @sref{Cont sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} cont zdat ['sch'='']
++@deftypefnx {MGL command} {} cont xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cont (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cont (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_cont (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_cont_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The same as previous with vector @var{v} of @var{num}-th elements equidistantly distributed in color range. Here @var{num} is equal to parameter @code{value} in options @var{opt} (default is 7).
++@end deftypefn
++
++@anchor{contf}
++@deftypefn {MGL command} {} contf vdat zdat ['sch'='']
++@deftypefnx {MGL command} {} contf vdat xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContF (@code{const mglDataA &}v, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContF (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_contf_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_contf_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws solid (or filled) contour lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z}=@var{v}[k], or at @var{z} equal to minimal z-axis value if @var{sch} contain symbol @samp{_}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v} (must be @code{v.nx>2}). See also @ref{dens}, @ref{cont}, @ref{contd}, @code{contf[xyz]}. @sref{ContF sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} contf zdat ['sch'='']
++@deftypefnx {MGL command} {} contf xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContF (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContF (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_contf (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_contf_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The same as previous with vector @var{v} of @var{num}-th elements equidistantly distributed in color range. Here @var{num} is equal to parameter @code{value} in options @var{opt} (default is 7).
++@end deftypefn
++
++@anchor{contd}
++@deftypefn {MGL command} {} contd vdat zdat ['sch'='']
++@deftypefnx {MGL command} {} contd vdat xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContD (@code{const mglDataA &}v, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContD (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_contd_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_contd_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws solid (or filled) contour lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z}=@var{v}[k] (or at @var{z} equal to minimal z-axis value if @var{sch} contain symbol @samp{_}) with manual colors. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v} (must be @code{v.nx>2}). String @var{sch} sets the contour colors: the color of k-th contour is determined by character @code{sch[k%strlen(sch)]}. See also @ref{dens}, @ref{cont}, @ref{contf}. @sref{ContD sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} contd zdat ['sch'='']
++@deftypefnx {MGL command} {} contd xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContD (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContD (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_contd (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_contd_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The same as previous with vector @var{v} of @var{num}-th elements equidistantly distributed in color range. Here @var{num} is equal to parameter @code{value} in options @var{opt} (default is 7).
++@end deftypefn
++
++@anchor{contp}
++@deftypefn {MGL command} {} contp vdat xdat ydat zdat adat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContP (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_contp_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws contour lines on surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. Contours are plotted for @var{a}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v}. If string @var{sch} have symbol @samp{t} or @samp{T} then contour labels @var{v}[k] will be drawn below (or above) the contours. If string @var{sch} have symbol @samp{f} then solid contours will be drawn. See also @ref{cont}, @ref{contf}, @ref{surfc}, @code{cont[xyz]}. @c TODO @sref{Cont sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} contp xdat ydat zdat adat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContP (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_contp (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The same as previous with vector @var{v} of @var{num}-th elements equidistantly distributed in color range. Here @var{num} is equal to parameter @code{value} in options @var{opt} (default is 7).
++@end deftypefn
++
++
++@anchor{contv}
++@deftypefn {MGL command} {} contv vdat zdat ['sch'='']
++@deftypefnx {MGL command} {} contv vdat xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContV (@code{const mglDataA &}v, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContV (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_contv_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_contv_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws vertical cylinder (tube) at contour lines for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z}=@var{v}[k], or at @var{z} equal to minimal z-axis value if @var{sch} contain symbol @samp{_}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v}. See also @ref{cont}, @ref{contf}. @sref{ContV sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} contv zdat ['sch'='']
++@deftypefnx {MGL command} {} contv xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContV (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContV (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_contv (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_contv_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The same as previous with vector @var{v} of @var{num}-th elements equidistantly distributed in color range. Here @var{num} is equal to parameter @code{value} in options @var{opt} (default is 7).
++@end deftypefn
++
++@anchor{axial}
++@deftypefn {MGL command} {} axial vdat zdat ['sch'='']
++@deftypefnx {MGL command} {} axial vdat xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Axial (@code{const mglDataA &}v, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Axial (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_axial_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_axial_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws surface which is result of contour plot rotation for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v}. If string @var{sch} have symbol @samp{#} then wire plot is produced. If string @var{sch} have symbol @samp{.} then plot by dots is produced. If string contain symbols @samp{x} or @samp{z} then rotation axis will be set to specified direction (default is @samp{y}). See also @ref{cont}, @ref{contf}, @ref{torus}, @ref{surf3}. @sref{Axial sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} axial zdat ['sch'='']
++@deftypefnx {MGL command} {} axial xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Axial (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{int} num=@code{3})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Axial (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{int} num=@code{3})
++@deftypefnx {C function} @code{void} mgl_axial (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_axial_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The same as previous with vector @var{v} of @var{num}-th elements equidistantly distributed in color range. Here @var{num} is equal to parameter @code{value} in options @var{opt} (default is 3).
++@end deftypefn
++
++@anchor{grid2}
++@deftypefn {MGL command} {} grid2 zdat ['sch'='']
++@deftypefnx {MGL command} {} grid2 xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Grid (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Grid (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_grid (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_grid_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws grid lines for density plot of surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} at @var{z} equal to minimal z-axis value. See also @ref{dens}, @ref{cont}, @ref{contf}, @ref{grid3}, @ref{meshnum}.
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node 3D plotting, Dual plotting, 2D plotting, MathGL core
++@section 3D plotting
++@nav{}
++@cindex Surf3
++@cindex Dens3
++@cindex Cont3
++@cindex ContF3
++@cindex Grid3
++@cindex Cloud
++@cindex Beam
++
++These functions perform plotting of 3D data. 3D means that data depend from 3 independent parameters like matrix @math{f(x_i,y_j,z_k), i=1...n, j=1...m, k=1...l}. By default (if absent) values of @var{x}, @var{y}, @var{z} are equidistantly distributed in axis range. The minor dimensions of arrays @var{x}, @var{y}, @var{z}, @var{a} should be equal @code{x.nx=a.nx && y.nx=a.ny && z.nz=a.nz} or @code{x.nx=y.nx=z.nx=a.nx && x.ny=y.ny=z.ny=a.ny && x.nz=y.nz=z.nz=a.nz}. Arrays @var{x}, @var{y} and @var{z} can be vectors (not matrices as @var{a}). String @var{sch} sets the color scheme (see @ref{Color scheme}) for plot. String @var{opt} contain command options (see @ref{Command options}). @sref{3D samples}
++
++@anchor{surf3}
++@deftypefn {MGL command} {} surf3 adat @code{val} ['sch'='']
++@deftypefnx {MGL command} {} surf3 xdat ydat zdat adat @code{val} ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3 (@code{mreal} val, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3 (@code{mreal} val, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_surf3_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_surf3_xyz_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws isosurface plot for 3d array specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) at @var{a}(x,y,z)=@var{val}. If string contain @samp{#} then wire plot is produced. If string @var{sch} have symbol @samp{.} then plot by dots is produced. Note, that there is possibility of incorrect plotting due to uncertainty of cross-section defining if there are two or more isosurface intersections inside one cell. See also @ref{cloud}, @ref{dens3}, @ref{surf3c}, @ref{surf3a}, @ref{axial}. @sref{Surf3 sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} surf3 adat ['sch'='']
++@deftypefnx {MGL command} {} surf3 xdat ydat zdat adat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3 (@code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3 (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_surf3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_surf3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Draws @var{num}-th uniformly distributed in color range isosurfaces for 3d data. Here @var{num} is equal to parameter @code{value} in options @var{opt} (default is 3).
++@end deftypefn
++
++@anchor{cloud}
++@deftypefn {MGL command} {} cloud adat ['sch'='']
++@deftypefnx {MGL command} {} cloud xdat ydat zdat adat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cloud (@code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cloud (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_cloud (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_cloud_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws cloud plot for 3d data specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). This plot is a set of cubes with color and transparency proportional to value of @var{a}. The resulting plot is like cloud -- low value is transparent but higher ones are not. The number of plotting cells depend on @ref{meshnum}. If string @var{sch} contain symbol @samp{.} then lower quality plot will produced with much low memory usage. If string @var{sch} contain symbol @samp{i} then transparency will be inversed, i.e. higher become transparent and lower become not transparent. See also @ref{surf3}, @ref{meshnum}. @sref{Cloud sample}
++@end deftypefn
++
++@anchor{dens3}
++@deftypefn {MGL command} {} dens3 adat ['sch'='' @code{sval=-1}]
++@deftypefnx {MGL command} {} dens3 xdat ydat zdat adat ['sch'='' @code{sval=-1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Dens3 (@code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Dens3 (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_dens3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_dens3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++The function draws density plot for 3d data specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). Density is plotted at slice @var{sVal} in direction @{@samp{x}, @samp{y}, @samp{z}@} if @var{sch} contain corresponding symbol (by default, @samp{y} direction is used). If string @var{stl} have symbol @samp{#} then grid lines are drawn. See also @ref{cont3}, @ref{contf3}, @ref{dens}, @ref{grid3}. @sref{Dens3 sample}
++@end deftypefn
++
++@anchor{cont3}
++@deftypefn {MGL command} {} cont3 vdat adat ['sch'='' @code{sval=-1}]
++@deftypefnx {MGL command} {} cont3 vdat xdat ydat zdat adat ['sch'='' @code{sval=-1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cont3 (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cont3 (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_cont3_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_cont3_xyz_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++The function draws contour plot for 3d data specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). Contours are plotted for values specified in array @var{v} at slice @var{sVal} in direction @{@samp{x}, @samp{y}, @samp{z}@} if @var{sch} contain corresponding symbol (by default, @samp{y} direction is used). If string @var{sch} have symbol @samp{#} then grid lines are drawn. If string @var{sch} have symbol @samp{t} or @samp{T} then contour labels will be drawn below (or above) the contours. See also @ref{dens3}, @ref{contf3}, @ref{cont}, @ref{grid3}. @sref{Cont3 sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} cont3 adat ['sch'='' @code{sval=-1}]
++@deftypefnx {MGL command} {} cont3 xdat ydat zdat adat ['sch'='' @code{sval=-1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cont3 (@code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Cont3 (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_cont3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_cont3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++The same as previous with vector @var{v} of @var{num}-th elements equidistantly distributed in color range. Here @var{num} is equal to parameter @code{value} in options @var{opt} (default is 7).
++@end deftypefn
++
++@anchor{contf3}
++@deftypefn {MGL command} {} contf3 vdat adat ['sch'='' @code{sval=-1}]
++@deftypefnx {MGL command} {} contf3 vdat xdat ydat zdat adat ['sch'='' @code{sval=-1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Contf3 (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Contf3 (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_contf3_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_contf3_xyz_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++The function draws solid (or filled) contour plot for 3d data specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). Contours are plotted for values specified in array @var{v} at slice @var{sVal} in direction @{@samp{x}, @samp{y}, @samp{z}@} if @var{sch} contain corresponding symbol (by default, @samp{y} direction is used). If string @var{sch} have symbol @samp{#} then grid lines are drawn. See also @ref{dens3}, @ref{cont3}, @ref{contf}, @ref{grid3}. @sref{ContF3 sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} contf3 adat ['sch'='' @code{sval=-1}]
++@deftypefnx {MGL command} {} contf3 xdat ydat zdat adat ['sch'='' @code{sval=-1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Contf3 (@code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Contf3 (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_contf3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_contf3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++The same as previous with vector @var{v} of @var{num}-th elements equidistantly distributed in color range. Here @var{num} is equal to parameter @code{value} in options @var{opt} (default is 7).
++@end deftypefn
++
++@anchor{grid3}
++@deftypefn {MGL command} {} grid3 adat ['sch'='' @code{sval=-1}]
++@deftypefnx {MGL command} {} grid3 xdat ydat zdat adat ['sch'='' @code{sval=-1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Grid3 (@code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Grid3 (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_grid3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_grid3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++The function draws grid for 3d data specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). Grid is plotted at slice @var{sVal} in direction @{@samp{x}, @samp{y}, @samp{z}@} if @var{sch} contain corresponding symbol (by default, @samp{y} direction is used). See also @ref{cont3}, @ref{contf3}, @ref{dens3}, @ref{grid2}, @ref{meshnum}.
++@end deftypefn
++
++@anchor{beam}
++@deftypefn {MGL command} {} beam tr g1 g2 adat @code{rval} ['sch'='' @code{flag=0 num=3}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Beam (@code{const mglDataA &}tr, @code{const mglDataA &}g1, @code{const mglDataA &}g2, @code{const mglDataA &}a, @code{mreal} r, @code{const char *}stl=@code{""}, @code{int} flag=@code{0}, @code{int} num=@code{3})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Beam (@code{mreal} val, @code{const mglDataA &}tr, @code{const mglDataA &}g1, @code{const mglDataA &}g2, @code{const mglDataA &}a, @code{mreal} r, @code{const char *}stl=@code{""}, @code{int} flag=@code{0})
++@deftypefnx {C function} @code{void} mgl_beam (@code{HMGL} gr, @code{HCDT} tr, @code{HCDT} g1, @code{HCDT} g2, @code{HCDT} a, @code{mreal} r, @code{const char *}stl, @code{int} flag, @code{int} num)
++@deftypefnx {C function} @code{void} mgl_beam_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} tr, @code{HCDT} g1, @code{HCDT} g2, @code{HCDT} a, @code{mreal} r, @code{const char *}stl, @code{int} flag)
++@end ifclear
++Draws the isosurface for 3d array @var{a} at constant values of @var{a}=@var{val}. This is special kind of plot for @var{a} specified in accompanied coordinates along curve @var{tr} with orts @var{g1}, @var{g2} and with transverse scale @var{r}. Variable @var{flag} is bitwise: @samp{0x1} - draw in accompanied (not laboratory) coordinates; @samp{0x2} - draw projection to @math{\rho-z} plane; @samp{0x4} - draw normalized in each slice field. The x-size of data arrays @var{tr}, @var{g1}, @var{g2} must be nx>2. The y-size of data arrays @var{tr}, @var{g1}, @var{g2} and z-size of the data array @var{a} must be equal. See also @ref{surf3}.
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node Dual plotting, Vector fields, 3D plotting, MathGL core
++@section Dual plotting
++@nav{}
++@cindex SurfC
++@cindex SurfA
++@cindex Surf3C
++@cindex Surf3A
++@cindex TileS
++@cindex Map
++@cindex STFA
++
++These plotting functions draw @emph{two matrix} simultaneously. There are 5 generally different types of data representations: surface or isosurface colored by other data (SurfC, Surf3C), surface or isosurface transpared by other data (SurfA, Surf3A), tiles with variable size (TileS), mapping diagram (Map), STFA diagram (STFA). By default (if absent) values of @var{x}, @var{y}, @var{z} are equidistantly distributed in axis range. The minor dimensions of arrays @var{x}, @var{y}, @var{z}, @var{c} should be equal. Arrays @var{x}, @var{y} (and @var{z} for @code{Surf3C, Surf3A}) can be vectors (not matrices as @var{c}). String @var{sch} sets the color scheme (see @ref{Color scheme}) for plot. String @var{opt} contain command options (see @ref{Command options}).
++
++@anchor{surfc}
++@deftypefn {MGL command} {} surfc zdat cdat ['sch'='']
++@deftypefnx {MGL command} {} surfc xdat ydat zdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SurfC (@code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} SurfC (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_surfc (@code{HMGL} gr, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_surfc_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} and color it by matrix @var{c}[i,j]. If string @var{sch} have symbol @samp{#} then grid lines are drawn. If string @var{sch} have symbol @samp{.} then plot by dots is produced. All dimensions of arrays @var{z} and @var{c} must be equal. Surface is plotted for each z slice of the data. See also @ref{surf}, @ref{surfa}, @ref{surfca}, @ref{beltc}, @ref{surf3c}. @sref{SurfC sample}
++@end deftypefn
++
++
++@anchor{beltc}
++@deftypefn {MGL command} {} beltc zdat cdat ['sch'='']
++@deftypefnx {MGL command} {} beltc xdat ydat zdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} BeltC (@code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} BeltC (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_beltc (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_beltc_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws belts for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} and color it by matrix @var{c}[i,j]. This plot can be used as 3d generalization of @ref{plot}). If @var{sch} contain @samp{x} then belts are drawn along x-direction else (by default) belts are drawn along y-direction. See also @ref{belt}, @ref{surfc}, @ref{meshnum}. @c TODO @sref{BeltC sample}
++@end deftypefn
++
++
++
++@anchor{surf3c}
++@deftypefn {MGL command} {} surf3c adat cdat @code{val} ['sch'='']
++@deftypefnx {MGL command} {} surf3c xdat ydat zdat adat cdat @code{val} ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3C (@code{mreal} val, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3C (@code{mreal} val, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_surf3c_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_surf3c_xyz_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws isosurface plot for 3d array specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) at @var{a}(x,y,z)=@var{val}. It is mostly the same as @ref{surf3} function but the color of isosurface depends on values of array @var{c}. If string @var{sch} contain @samp{#} then wire plot is produced. If string @var{sch} have symbol @samp{.} then plot by dots is produced. See also @ref{surf3}, @ref{surfc}, @ref{surf3a}, @ref{surf3ca}. @sref{Surf3C sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} surf3c adat cdat ['sch'='']
++@deftypefnx {MGL command} {} surf3c xdat ydat zdat adat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3C (@code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3C (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_surf3c (@code{HMGL} gr, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_surf3c_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Draws @var{num}-th uniformly distributed in color range isosurfaces for 3d data. Here @var{num} is equal to parameter @code{value} in options @var{opt} (default is 3).
++@end deftypefn
++
++
++@anchor{surfa}
++@deftypefn {MGL command} {} surfa zdat cdat ['sch'='']
++@deftypefnx {MGL command} {} surfa xdat ydat zdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SurfA (@code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} SurfA (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_surfa (@code{HMGL} gr, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_surfa_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} and transparent it by matrix @var{c}[i,j]. If string @var{sch} have symbol @samp{#} then grid lines are drawn. If string @var{sch} have symbol @samp{.} then plot by dots is produced. All dimensions of arrays @var{z} and @var{c} must be equal. Surface is plotted for each z slice of the data. See also @ref{surf}, @ref{surfc}, @ref{surfca}, @ref{surf3a}. @sref{SurfA sample}
++@end deftypefn
++
++@anchor{surf3a}
++@deftypefn {MGL command} {} surf3a adat cdat @code{val} ['sch'='']
++@deftypefnx {MGL command} {} surf3a xdat ydat zdat adat cdat @code{val} ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3A (@code{mreal} val, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3A (@code{mreal} val, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_surf3a_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_surf3a_xyz_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws isosurface plot for 3d array specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) at @var{a}(x,y,z)=@var{val}. It is mostly the same as @ref{surf3} function but the transparency of isosurface depends on values of array @var{c}. If string @var{sch} contain @samp{#} then wire plot is produced. If string @var{sch} have symbol @samp{.} then plot by dots is produced. See also @ref{surf3}, @ref{surfc}, @ref{surf3a}, @ref{surf3ca}. @sref{Surf3A sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} surf3a adat cdat ['sch'='']
++@deftypefnx {MGL command} {} surf3a xdat ydat zdat adat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3A (@code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3A (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_surf3a (@code{HMGL} gr, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_surf3a_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Draws @var{num}-th uniformly distributed in color range isosurfaces for 3d data. At this array @var{c} can be vector with values of transparency and @var{num}=@var{c}.nx. In opposite case @var{num} is equal to parameter @code{value} in options @var{opt} (default is 3).
++@end deftypefn
++
++
++
++@anchor{surfca}
++@deftypefn {MGL command} {} surfca zdat cdat adat ['sch'='']
++@deftypefnx {MGL command} {} surfca xdat ydat zdat cdat adat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} SurfCA (@code{const mglDataA &}z, @code{const mglDataA &}c, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} SurfCA (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_surfca (@code{HMGL} gr, @code{HCDT} z, @code{HCDT} c, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_surfca_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}, color it by matrix @var{c}[i,j] and transparent it by matrix @var{a}[i,j]. If string @var{sch} have symbol @samp{#} then grid lines are drawn. If string @var{sch} have symbol @samp{.} then plot by dots is produced. All dimensions of arrays @var{z} and @var{c} must be equal. Surface is plotted for each z slice of the data. Note, you can use @ref{map}-like coloring if use @samp{%} in color scheme. See also @ref{surf}, @ref{surfc}, @ref{surfa}, @ref{surf3ca}. @sref{SurfCA sample}
++@end deftypefn
++
++@anchor{surf3ca}
++@deftypefn {MGL command} {} surf3ca adat cdat bdat @code{val} ['sch'='']
++@deftypefnx {MGL command} {} surf3ca xdat ydat zdat adat cdat bdat @code{val} ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3CA (@code{mreal} val, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const mglDataA &}b, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3CA (@code{mreal} val, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const mglDataA &}b, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_surf3ca_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} a, @code{HCDT} c, @code{HCDT} b, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_surf3ca_xyz_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{HCDT} b,@code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws isosurface plot for 3d array specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) at @var{a}(x,y,z)=@var{val}. It is mostly the same as @ref{surf3} function but the color and the transparency of isosurface depends on values of array @var{c} and @var{b} correspondingly. If string @var{sch} contain @samp{#} then wire plot is produced. If string @var{sch} have symbol @samp{.} then plot by dots is produced. Note, you can use @ref{map}-like coloring if use @samp{%} in color scheme. See also @ref{surf3}, @ref{surfca}, @ref{surf3c}, @ref{surf3a}. @sref{Surf3CA sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} surf3ca adat cdat bdat ['sch'='']
++@deftypefnx {MGL command} {} surf3ca xdat ydat zdat adat cdat bdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3CA (@code{const mglDataA &}a, @code{const mglDataA &}c, @code{const mglDataA &}b, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Surf3CA (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const mglDataA &}b, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_surf3ca (@code{HMGL} gr, @code{HCDT} a, @code{HCDT} c, @code{HCDT} b, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_surf3ca_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{HCDT} b, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Draws @var{num}-th uniformly distributed in color range isosurfaces for 3d data. Here parameter @var{num} is equal to parameter @code{value} in options @var{opt} (default is 3).
++@end deftypefn
++
++@anchor{tiles}
++@deftypefn {MGL command} {} tiles zdat rdat ['sch'='']
++@deftypefnx {MGL command} {} tiles xdat ydat zdat rdat ['sch'='']
++@deftypefnx {MGL command} {} tiles xdat ydat zdat rdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} TileS (@code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TileS (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}r, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TileS (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}r, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_tiles (@code{HMGL} gr, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tiles_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tiles_xyc (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws horizontal tiles for surface specified parametrically @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} and color it by matrix @var{c}[i,j]. It is mostly the same as @ref{tile} but the size of tiles is determined by @var{r} array. If string @var{sch} contain style @samp{x} or @samp{y} then tiles will be oriented perpendicular to x- or y-axis. This is some kind of ``transparency'' useful for exporting to EPS files. Tiles is plotted for each z slice of the data. See also @ref{surfa}, @ref{tile}. @sref{TileS sample}
++@end deftypefn
++
++@anchor{map}
++@deftypefn {MGL command} {} map udat vdat ['sch'='']
++@deftypefnx {MGL command} {} map xdat ydat udat vdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Map (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Map (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_map (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_map_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws mapping plot for matrices @{@var{ax}, @var{ay} @} which parametrically depend on coordinates @var{x}, @var{y}. The initial position of the cell (point) is marked by color. Height is proportional to Jacobian(ax,ay). This plot is like Arnold diagram ??? If string @var{sch} contain symbol @samp{.} then the color ball at matrix knots are drawn otherwise face is drawn. @sref{Mapping visualization}
++@end deftypefn
++
++@anchor{stfa}
++@deftypefn {MGL command} {} stfa re im @code{dn} ['sch'='']
++@deftypefnx {MGL command} {} stfa xdat ydat re im @code{dn} ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} STFA (@code{const mglDataA &}re, @code{const mglDataA &}im, @code{int} dn, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} STFA (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}re, @code{const mglDataA &}im, @code{int} dn, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_stfa (@code{HMGL} gr, @code{HCDT} re, @code{HCDT} im, @code{int} dn, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_stfa_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} re, @code{HCDT} im, @code{int} dn, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Draws spectrogram of complex array @var{re}+i*@var{im} for Fourier size of @var{dn} points at plane @var{z} equal to minimal z-axis value. For example in 1D case, result is density plot of data @math{res[i,j]=|\sum_d^dn exp(I*j*d)*(re[i*dn+d]+I*im[i*dn+d])|/dn} with size @{int(nx/dn), dn, ny@}. At this array @var{re}, @var{im} parametrically depend on coordinates @var{x}, @var{y}. The size of @var{re} and @var{im} must be the same. The minor dimensions of arrays @var{x}, @var{y}, @var{re} should be equal. Arrays @var{x}, @var{y} can be vectors (not matrix as @var{re}). @sref{STFA sample}
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node Vector fields, Other plotting, Dual plotting, MathGL core
++@section Vector fields
++@nav{}
++@cindex Traj
++@cindex Vect
++@cindex Dew
++@cindex Flow
++@cindex FlowP
++@cindex Pipe
++
++These functions perform plotting of 2D and 3D vector fields. There are 5 generally different types of vector fields representations: simple vector field (Vect), vectors along the curve (Traj), vector field by dew-drops (Dew), flow threads (Flow, FlowP), flow pipes (Pipe). By default (if absent) values of @var{x}, @var{y}, @var{z} are equidistantly distributed in axis range. The minor dimensions of arrays @var{x}, @var{y}, @var{z}, @var{ax} should be equal. The size of @var{ax}, @var{ay} and @var{az} must be equal. Arrays @var{x}, @var{y}, @var{z} can be vectors (not matrices as @var{ax}). String @var{sch} sets the color scheme (see @ref{Color scheme}) for plot. String @var{opt} contain command options (see @ref{Command options}).
++
++@anchor{traj}
++@deftypefn {MGL command} {} traj xdat ydat udat vdat ['sch'='']
++@deftypefnx {MGL command} {} traj xdat ydat zdat udat vdat wdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Traj (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Traj (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_traj_xyz (@code{HMGL} gr, @code{HCDT}x, @code{HCDT}y, @code{HCDT}z, @code{HCDT}ax, @code{HCDT}ay, @code{HCDT}az, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_traj_xy (@code{HMGL} gr, @code{HCDT}x, @code{HCDT}y, @code{HCDT}ax, @code{HCDT}ay, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws vectors @{@var{ax}, @var{ay}, @var{az}@} along a curve @{@var{x}, @var{y}, @var{z}@}. The length of arrows are proportional to @math{\sqrt@{ax^2+ay^2+az^2@}}. String @var{pen} specifies the color (see @ref{Line styles}). By default (@code{pen=""}) color from palette is used (see @ref{Palette and colors}). Option @code{value} set the vector length factor (if non-zero) or vector length to be proportional the distance between curve points (if @code{value=0}). The minor sizes of all arrays must be equal and large 2. The plots are drawn for each row if one of the data is the matrix. See also @ref{vect}. @sref{Traj sample}
++@end deftypefn
++
++@anchor{vect}
++@deftypefn {MGL command} {} vect udat vdat ['sch'='']
++@deftypefnx {MGL command} {} vect xdat ydat udat vdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Vect (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Vect (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_vect_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_vect_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws plane vector field plot for the field @{@var{ax}, @var{ay}@} depending parametrically on coordinates @var{x}, @var{y} at level @var{z} equal to minimal z-axis value. The length and color of arrows are proportional to @math{\sqrt@{ax^2+ay^2@}}. The number of arrows depend on @ref{meshnum}. The appearance of the hachures (arrows) can be changed by symbols:
++@itemize @bullet
++@item
++@samp{f} for drawing arrows with fixed lengths,
++@item
++@samp{>}, @samp{<} for drawing arrows to or from the cell point (default is centering),
++@item
++@samp{.} for drawing hachures with dots instead of arrows,
++@item
++@samp{=} for enabling color gradient along arrows.
++@end itemize
++See also @ref{flow}, @ref{dew}. @sref{Vect sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} vect udat vdat wdat ['sch'='']
++@deftypefnx {MGL command} {} vect xdat ydat zdat udat vdat wdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Vect (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Vect (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_vect_3d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_vect_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++This is 3D version of the first functions. Here arrays @var{ax}, @var{ay}, @var{az} must be 3-ranged tensors with equal sizes and the length and color of arrows is proportional to @math{\sqrt@{ax^2+ay^2+az^2@}}.
++@end deftypefn
++
++@anchor{vect3}
++@deftypefn {MGL command} {} vect3 udat vdat wdat ['sch'='' sval]
++@deftypefnx {MGL command} {} vect3 xdat ydat zdat udat vdat wdat ['sch'='' sval]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Vect3 (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Vect3 (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_vect3 (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_vect3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++The function draws 3D vector field plot for the field @{@var{ax}, @var{ay}, @var{az}@} depending parametrically on coordinates @var{x}, @var{y}, @var{z}. Vector field is drawn at slice @var{sVal} in direction @{@samp{x}, @samp{y}, @samp{z}@} if @var{sch} contain corresponding symbol (by default, @samp{y} direction is used). The length and color of arrows are proportional to @math{\sqrt@{ax^2+ay^2+az^2@}}. The number of arrows depend on @ref{meshnum}. The appearance of the hachures (arrows) can be changed by symbols:
++@itemize @bullet
++@item
++@samp{f} for drawing arrows with fixed lengths,
++@item
++@samp{>}, @samp{<} for drawing arrows to or from the cell point (default is centering),
++@item
++@samp{.} for drawing hachures with dots instead of arrows,
++@item
++@samp{=} for enabling color gradient along arrows.
++@end itemize
++See also @ref{vect}, @ref{flow}, @ref{dew}. @sref{Vect3 sample}
++@end deftypefn
++
++@anchor{dew}
++@deftypefn {MGL command} {} dew udat vdat ['sch'='']
++@deftypefnx {MGL command} {} dew xdat ydat udat vdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Dew (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Dew (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_dew (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_dew_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws dew-drops for plane vector field @{@var{ax}, @var{ay}@} depending parametrically on coordinates @var{x}, @var{y} at level @var{z} equal to minimal z-axis value. Note that this is very expensive plot in memory usage and creation time! The color of drops is proportional to @math{\sqrt@{ax^2+ay^2@}}. The number of drops depend on @ref{meshnum}. See also @ref{vect}. @sref{Dew sample}
++@end deftypefn
++
++@anchor{flow}
++@deftypefn {MGL command} {} flow udat vdat ['sch'='']
++@deftypefnx {MGL command} {} flow xdat ydat udat vdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Flow (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Flow (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_flow_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_flow_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws flow threads for the plane vector field @{@var{ax}, @var{ay}@} parametrically depending on coordinates @var{x}, @var{y} at level @var{z} equal to minimal z-axis value. Number of threads is proportional to @code{value} option (default is 5). String @var{sch} may contain:
++@itemize @bullet
++@item
++color scheme -- up-half (warm) corresponds to normal flow (like attractor), bottom-half (cold) corresponds to inverse flow (like source);
++@item
++@samp{#} for starting threads from edges only;
++@item
++@samp{*} for starting threads from a 2D array of points inside the data;
++@item
++@samp{v} for drawing arrows on the threads;
++@item
++@samp{x}, @samp{z} for drawing tapes of normals in x-y and y-z planes correspondingly.
++@end itemize
++See also @ref{pipe}, @ref{vect}, @ref{tape}, @ref{barwidth}. @sref{Flow sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} flow udat vdat wdat ['sch'='']
++@deftypefnx {MGL command} {} flow xdat ydat zdat udat vdat wdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Flow (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Flow (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_flow_3d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_flow_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++This is 3D version of the first functions. Here arrays @var{ax}, @var{ay}, @var{az} must be 3-ranged tensors with equal sizes and the color of line is proportional to @math{\sqrt@{ax^2+ay^2+az^2@}}.
++@end deftypefn
++
++@deftypefn {MGL command} {} flow @code{x0 y0} udat vdat ['sch'='']
++@deftypefnx {MGL command} {} flow @code{x0 y0} xdat ydat udat vdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_flowp_2d (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_flowp_xy (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The same as first one (@ref{flow}) but draws single flow thread starting from point @var{p0}=@{@var{x0},@var{y0},@var{z0}@}.
++@end deftypefn
++
++@deftypefn {MGL command} {} flow @code{x0 y0 z0} udat vdat wdat ['sch'='']
++@deftypefnx {MGL command} {} flow @code{x0 y0 z0} xdat ydat zdat udat vdat wdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_flowp_3d (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_flowp_xyz (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++This is 3D version of the previous functions.
++@end deftypefn
++
++@anchor{grad}
++@deftypefn {MGL command} {} grad pdat ['sch'='']
++@deftypefnx {MGL command} {} grad xdat ydat pdat ['sch'='']
++@deftypefnx {MGL command} {} grad xdat ydat zdat pdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Grad (@code{const mglDataA &}phi, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Grad (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}phi, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Grad (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}phi, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_grad (@code{HMGL} gr, @code{HCDT} phi, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_grad_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} phi, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_grad_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} phi, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws gradient lines for scalar field @var{phi}[i,j] (or @var{phi}[i,j,k] in 3d case) specified parametrically @{@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]@}. Number of lines is proportional to @code{value} option (default is 5). See also @ref{dens}, @ref{cont}, @ref{flow}.
++@end deftypefn
++
++@anchor{pipe}
++@deftypefn {MGL command} {} pipe udat vdat ['sch'='' @code{r0=0.05}]
++@deftypefnx {MGL command} {} pipe xdat ydat udat vdat ['sch'='' @code{r0=0.05}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Pipe (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{mreal} r0=@code{0.05}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Pipe (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{mreal} r0=@code{0.05}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_pipe_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{mreal} r0, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_pipe_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{mreal} r0, @code{const char *}opt)
++@end ifclear
++The function draws flow pipes for the plane vector field @{@var{ax}, @var{ay}@} parametrically depending on coordinates @var{x}, @var{y} at level @var{z} equal to minimal z-axis value. Number of pipes is proportional to @code{value} option (default is 5). If @samp{#} symbol is specified then pipes start only from edges of axis range. The color of lines is proportional to @math{\sqrt@{ax^2+ay^2@}}. Warm color corresponds to normal flow (like attractor). Cold one corresponds to inverse flow (like source). Parameter @var{r0} set the base pipe radius. If @var{r0}<0 or symbol @samp{i} is specified then pipe radius is inverse proportional to amplitude. The vector field is plotted for each z slice of @var{ax}, @var{ay}. See also @ref{flow}, @ref{vect}. @sref{Pipe sample}
++@end deftypefn
++
++@deftypefn {MGL command} {} pipe udat vdat wdat ['sch'='' @code{r0=0.05}]
++@deftypefnx {MGL command} {} pipe xdat ydat zdat udat vdat wdat ['sch'='' @code{r0=0.05}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Pipe (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{mreal} r0=@code{0.05}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Pipe (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{mreal} r0=@code{0.05}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_pipe_3d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{mreal} r0, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_pipe_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{mreal} r0, @code{const char *}opt)
++@end ifclear
++This is 3D version of the first functions. Here arrays @var{ax}, @var{ay}, @var{az} must be 3-ranged tensors with equal sizes and the color of line is proportional to @math{\sqrt@{ax^2+ay^2+az^2@}}.
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node Other plotting, Nonlinear fitting, Vector fields, MathGL core
++@section Other plotting
++@nav{}
++@cindex DensXYZ
++@cindex ContXYZ
++@cindex ContFXYZ
++@cindex Dots
++@cindex Crust
++@cindex TriPlot
++@cindex TriCont
++@cindex QuadPlot
++@cindex FPlot
++@cindex FSurf
++
++These functions perform miscellaneous plotting. There is unstructured data points plots (Dots), surface reconstruction (Crust), surfaces on the triangular or quadrangular mesh (TriPlot, TriCont, QuadPlot), textual formula plotting (Plots by formula), data plots at edges (Dens[XYZ], Cont[XYZ], ContF[XYZ]). Each type of plotting has similar interface. There are 2 kind of versions which handle the arrays of data and coordinates or only single data array. Parameters of color scheme are specified by the string argument. @xref{Color scheme}.
++
++@anchor{densz} @anchor{densy} @anchor{densx} @anchor{DensXYZ}
++@deftypefn {MGL command} {} densx dat ['sch'='' @code{sval=nan}]
++@deftypefnx {MGL command} {} densy dat ['sch'='' @code{sval=nan}]
++@deftypefnx {MGL command} {} densz dat ['sch'='' @code{sval=nan}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} DensX (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} DensY (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} DensZ (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_dens_x (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_dens_y (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_dens_z (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++These plotting functions draw density plot in x, y, or z plain. If @var{a} is a tensor (3-dimensional data) then interpolation to a given @var{sVal} is performed. These functions are useful for creating projections of the 3D data array to the bounding box. See also @ref{ContXYZ}, @ref{ContFXYZ}, @ref{dens}, @ref{Data manipulation}. @sref{Dens projection sample}
++@end deftypefn
++
++@anchor{contz} @anchor{conty} @anchor{contx} @anchor{ContXYZ}
++@deftypefn {MGL command} {} contx dat ['sch'='' @code{sval=nan}]
++@deftypefnx {MGL command} {} conty dat ['sch'='' @code{sval=nan}]
++@deftypefnx {MGL command} {} contz dat ['sch'='' @code{sval=nan}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContX (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContY (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContZ (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_cont_x (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_cont_y (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_cont_z (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++These plotting functions draw contour lines in x, y, or z plain. If @var{a} is a tensor (3-dimensional data) then interpolation to a given @var{sVal} is performed. These functions are useful for creating projections of the 3D data array to the bounding box. Option @code{value} set the number of contours. See also @ref{ContFXYZ}, @ref{DensXYZ}, @ref{cont}, @ref{Data manipulation}. @sref{Cont projection sample}
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglGraph}} @code{void} ContX (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContY (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContZ (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_cont_x_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_cont_y_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_cont_z_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++The same as previous with manual contour levels.
++@end deftypefn
++@end ifclear
++
++@anchor{contfz} @anchor{contfy} @anchor{contfx} @anchor{ContFXYZ}
++@deftypefn {MGL command} {} contfx dat ['sch'='' @code{sval=nan}]
++@deftypefnx {MGL command} {} contfy dat ['sch'='' @code{sval=nan}]
++@deftypefnx {MGL command} {} contfz dat ['sch'='' @code{sval=nan}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContFX (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContFY (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContFZ (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_contf_x (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_contf_y (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_contf_z (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++These plotting functions draw solid contours in x, y, or z plain. If @var{a} is a tensor (3-dimensional data) then interpolation to a given @var{sVal} is performed. These functions are useful for creating projections of the 3D data array to the bounding box. Option @code{value} set the number of contours. See also @ref{ContFXYZ}, @ref{DensXYZ}, @ref{cont}, @ref{Data manipulation}. @sref{ContF projection sample}
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglGraph}} @code{void} ContFX (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContFY (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} ContFZ (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_contf_x_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_contf_y_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_contf_z_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++The same as previous with manual contour levels.
++@end deftypefn
++@end ifclear
++
++@anchor{fplot}
++@deftypefn {MGL command} {} fplot 'y(x)' ['pen'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} FPlot (@code{const char *}eqY, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_fplot (@code{HMGL} gr, @code{const char *}eqY, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Draws command function @samp{y(x)} at plane @var{z} equal to minimal z-axis value, where @samp{x} variable is changed in @code{xrange}. You do not need to create the data arrays to plot it. Option @code{value} set initial number of points. See also @ref{plot}.
++@end deftypefn
++
++@deftypefn {MGL command} {} fplot 'x(t)' 'y(t)' 'z(t)' ['pen'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} FPlot (@code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}pen, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_fplot_xyz (@code{HMGL} gr, @code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Draws command parametrical curve @{@samp{x(t)}, @samp{y(t)}, @samp{z(t)}@} where @samp{t} variable is changed in range [0, 1]. You do not need to create the data arrays to plot it. Option @code{value} set number of points. See also @ref{plot}.
++@end deftypefn
++
++@anchor{fsurf}
++@deftypefn {MGL command} {} fsurf 'z(x,y)' ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} FSurf (@code{const char *}eqZ, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""});
++@deftypefnx {C function} @code{void} mgl_fsurf (@code{HMGL} gr, @code{const char *}eqZ, @code{const char *}sch, @code{const char *}opt);
++@end ifclear
++Draws command surface for function @samp{z(x,y)} where @samp{x}, @samp{y} variable are changed in @code{xrange, yrange}. You do not need to create the data arrays to plot it. Option @code{value} set number of points. See also @ref{surf}.
++@end deftypefn
++
++@deftypefn {MGL command} {} fsurf 'x(u,v)' 'y(u,v)' 'z(u,v)' ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} FSurf (@code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_fsurf_xyz (@code{HMGL} gr, @code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Draws command parametrical surface @{@samp{x(u,v)}, @samp{y(u,v)}, @samp{z(u,v)}@} where @samp{u}, @samp{v} variable are changed in range [0, 1]. You do not need to create the data arrays to plot it. Option @code{value} set number of points. See also @ref{surf}.
++@end deftypefn
++
++@anchor{triplot}
++@deftypefn {MGL command} {} triplot idat xdat ydat ['sch'='']
++@deftypefnx {MGL command} {} triplot idat xdat ydat zdat ['sch'='']
++@deftypefnx {MGL command} {} triplot idat xdat ydat zdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} TriPlot (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TriPlot (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TriPlot (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_triplot_xy (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_triplot_xyz (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_triplot_xyzc (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws the surface of triangles. Triangle vertexes are set by indexes @var{id} of data points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. String @var{sch} sets the color scheme. If string contain @samp{#} then wire plot is produced. First dimensions of @var{id} must be 3 or greater. Arrays @var{x}, @var{y}, @var{z} must have equal sizes. Parameter @var{c} set the colors of triangles (if @var{id}.ny=@var{c}.nx) or colors of vertexes (if @var{x}.nx=@var{c}.nx). See also @ref{dots}, @ref{crust}, @ref{quadplot}, @ref{triangulation}. @sref{TriPlot and QuadPlot}
++@end deftypefn
++
++@anchor{tricont}
++@deftypefn {MGL command} {} tricont vdat idat xdat ydat zdat cdat ['sch'='']
++@deftypefnx {MGL command} {} tricont vdat idat xdat ydat zdat ['sch'='']
++@deftypefnx {MGL command} {} tricont idat xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} TriCont (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TriCont (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TriContV (@code{const mglDataA &}v, @code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} TriContV (@code{const mglDataA &}v, @code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_tricont_xyzc (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tricont_xyz (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tricont_xyzcv (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_tricont_xyzv (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws contour lines for surface of triangles at @var{z}=@var{v}[k] (or at @var{z} equal to minimal z-axis value if @var{sch} contain symbol @samp{_}). Triangle vertexes are set by indexes @var{id} of data points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Contours are plotted for @var{z}[i,j]=@var{v}[k] where @var{v}[k] are values of data array @var{v}. If @var{v} is absent then arrays of option @code{value} elements equidistantly distributed in color range is used. String @var{sch} sets the color scheme. Array @var{c} (if specified) is used for contour coloring. First dimensions of @var{id} must be 3 or greater. Arrays @var{x}, @var{y}, @var{z} must have equal sizes. Parameter @var{c} set the colors of triangles (if @var{id}.ny=@var{c}.nx) or colors of vertexes (if @var{x}.nx=@var{c}.nx). See also @ref{triplot}, @ref{cont}, @ref{triangulation}.
++@end deftypefn
++
++@anchor{quadplot}
++@deftypefn {MGL command} {} quadplot idat xdat ydat ['sch'='']
++@deftypefnx {MGL command} {} quadplot idat xdat ydat zdat ['sch'='']
++@deftypefnx {MGL command} {} quadplot idat xdat ydat zdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} QuadPlot (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} QuadPlot (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} QuadPlot (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_quadplot_xy (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_quadplot_xyz (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_quadplot_xyzc (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws the surface of quadrangles. Quadrangles vertexes are set by indexes @var{id} of data points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. String @var{sch} sets the color scheme. If string contain @samp{#} then wire plot is produced. First dimensions of @var{id} must be 4 or greater. Arrays @var{x}, @var{y}, @var{z} must have equal sizes. Parameter @var{c} set the colors of quadrangles (if @var{id}.ny=@var{c}.nx) or colors of vertexes (if @var{x}.nx=@var{c}.nx). See also @ref{triplot}. @sref{TriPlot and QuadPlot}
++@end deftypefn
++
++@anchor{dots}
++@deftypefn {MGL command} {} dots xdat ydat zdat ['sch'='']
++@deftypefnx {MGL command} {} dots xdat ydat zdat adat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Dots (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Dots (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Dots (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_dots (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_dots_a (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_dots_ca (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function draws the arbitrary placed points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. String @var{sch} sets the color scheme and kind of marks. If arrays @var{c}, @var{a} are specified then they define colors and transparencies of dots. You can use @ref{tens} plot with style @samp{ .} to draw non-transparent dots with specified colors. Arrays @var{x}, @var{y}, @var{z}, @var{a} must have equal sizes. See also @ref{crust}, @ref{tens}, @ref{mark}, @ref{plot}. @sref{Dots sample}
++@end deftypefn
++
++@anchor{crust}
++@deftypefn {MGL command} {} crust xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Crust (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_crust (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++The function reconstruct and draws the surface for arbitrary placed points @{@var{x}[i], @var{y}[i], @var{z}[i]@}. String @var{sch} sets the color scheme. If string contain @samp{#} then wire plot is produced. Arrays @var{x}, @var{y}, @var{z} must have equal sizes. See also @ref{dots}, @ref{triplot}. @c @sref{Crust sample}
++@end deftypefn
++
++@c ##################################################################
++@external{}
++@node Nonlinear fitting, Data manipulation, Other plotting, MathGL core
++@section Nonlinear fitting
++@nav{}
++@cindex Fit
++@cindex FitS
++@cindex PutsFit
++@cindex mglFitPnts
++@cindex Fit2
++@cindex Fit3
++
++These functions fit data to formula. Fitting goal is to find formula parameters for the best fit the data points, i.e. to minimize the sum @math{\sum_i (f(x_i, y_i, z_i) - a_i)^2/s_i^2}. At this, approximation function @samp{f} can depend only on one argument @samp{x} (1D case), on two arguments @samp{x,y} (2D case) and on three arguments @samp{x,y,z} (3D case). The function @samp{f} also may depend on parameters. Normally the list of fitted parameters is specified by @var{var} string (like, @samp{abcd}). Usually user should supply initial values for fitted parameters by @var{ini} variable. But if he/she don't supply it then the zeros are used. Parameter @var{print}=@code{true} switch on printing the found coefficients to @var{Message} (see @ref{Error handling}).
++
++Functions Fit() and FitS() do not draw the obtained data themselves. They fill the data @var{fit} by formula @samp{f} with found coefficients and return it. At this, the @samp{x,y,z} coordinates are equidistantly distributed in the axis range. Number of points in @var{fit} is defined by option @code{value} (default is @var{mglFitPnts}=100). Note, that this functions use GSL library and do something only if MathGL was compiled with GSL support. @sref{Nonlinear fitting hints}
++
++@anchor{fits}
++@deftypefn {MGL command} {} fits res adat sdat 'func' 'var' [ini=0]
++@deftypefnx {MGL command} {} fits res xdat adat sdat 'func' 'var' [ini=0]
++@deftypefnx {MGL command} {} fits res xdat ydat adat sdat 'func' 'var' [ini=0]
++@deftypefnx {MGL command} {} fits res xdat ydat zdat adat sdat 'func' 'var' [ini=0]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}x, @code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}x, @code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{HMDT} mgl_fit_ys (@code{HMGL} gr, @code{HCDT} a, @code{HCDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {C function} @code{HMDT} mgl_fit_xys (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{HCDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {C function} @code{HMDT} mgl_fit_xyzs (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} a, @code{HCDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {C function} @code{HMDT} mgl_fit_xyzas (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@end ifclear
++Fit data along x-, y- and z-directions for array specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) with weight factor @var{s}[i,j,k].
++@end deftypefn
++
++@anchor{fit}
++@deftypefn {MGL command} {} fit res adat 'func' 'var' [ini=0]
++@deftypefnx {MGL command} {} fit res xdat adat 'func' 'var' [ini=0]
++@deftypefnx {MGL command} {} fit res xdat ydat adat 'func' 'var' [ini=0]
++@deftypefnx {MGL command} {} fit res xdat ydat zdat adat 'func' 'var' [ini=0]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}x, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}x, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{HMDT} mgl_fit_y (@code{HMGL} gr, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {C function} @code{HMDT} mgl_fit_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {C function} @code{HMDT} mgl_fit_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {C function} @code{HMDT} mgl_fit_xyza (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@end ifclear
++Fit data along x-, y- and z-directions for array specified parametrically @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) with weight factor 1.
++@end deftypefn
++
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglGraph}} @code{mglData} Fit2 (@code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit2 (@code{mglData &}fit, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit3 (@code{mglData &}fit, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Fit3 (@code{mglData &}fit, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{HMDT} mgl_fit_2 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {C function} @code{HMDT} mgl_fit_3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++Fit data along all directions for 2d or 3d arrays @var{a} with @var{s}=1 and @var{x}, @var{y}, @var{z} equidistantly distributed in axis range.
++@end deftypefn
++@end ifclear
++
++@anchor{putsfit}
++@deftypefn {MGL command} {} putsfit @code{x y} ['pre'='' 'fnt'='' @code{size=-1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} PutsFit (@code{mglPoint} p, @code{const char *}prefix=@code{""}, @code{const char *}font=@code{""}, @code{mreal} size=@code{-1})
++@deftypefnx {C function} @code{void} mgl_puts_fit (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{const char *}prefix, @code{const char *}font, @code{mreal} size)
++@end ifclear
++Print last fitted formula with found coefficients (as numbers) at position @var{p0}. The string @var{prefix} will be printed before formula. All other parameters are the same as in @ref{Text printing}.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglGraph}} @code{const char *}GetFit ()
++@deftypefnx {C function only} @code{const char *} mgl_get_fit (@code{HMGL} gr)
++@deftypefnx {Fortran subroutine} @code{} mgl_get_fit (@code{long} gr, @code{char *}out, @code{int} len)
++Get last fitted formula with found coefficients (as numbers).
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{mreal} GetFitChi ()
++@deftypefnx {C function} @code{mreal} mgl_get_fit_chi ()
++Get \chi for last fitted formula.
++@end deftypefn
++
++@deftypefn {Method on @code{mglGraph}} @code{mreal} GetFitCovar ()
++@deftypefnx {C function} @code{mreal} mgl_get_fit_covar ()
++Get covariance matrix for last fitted formula.
++@end deftypefn
++@end ifclear
++
++
++@c ##################################################################
++@external{}
++@node Data manipulation, , Nonlinear fitting, MathGL core
++@section Data manipulation
++@nav{}
++@cindex Hist
++@cindex Fill
++@cindex DataGrid
++
++@deftypefn {MGL command} {} hist @sc{res} xdat adat
++@deftypefnx {MGL command} {} hist @sc{res} xdat ydat adat
++@deftypefnx {MGL command} {} hist @sc{res} xdat ydat zdat adat
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Hist (@code{const mglDataA &}x, @code{const mglDataA &}a, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Hist (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}a, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} Hist (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{HMDT} mgl_hist_x (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{const char *}opt)
++@deftypefnx {C function} @code{HMDT} mgl_hist_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} a, @code{const char *}opt)
++@deftypefnx {C function} @code{HMDT} mgl_hist_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}opt)
++@end ifclear
++These functions make distribution (histogram) of data. They do not draw the obtained data themselves. These functions can be useful if user have data defined for random points (for example, after PIC simulation) and he want to produce a plot which require regular data (defined on grid(s)). The range for grids is always selected as axis range. Arrays @var{x}, @var{y}, @var{z} define the positions (coordinates) of random points. Array @var{a} define the data value. Number of points in output array @var{res} is defined by option @code{value} (default is @var{mglFitPnts}=100).
++@end deftypefn
++
++
++@deftypefn {MGL command} {} fill dat 'eq'
++@deftypefnx {MGL command} {} fill dat 'eq' vdat
++@deftypefnx {MGL command} {} fill dat 'eq' vdat wdat
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} Fill (@code{mglData &}u, @code{const char *}eq, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Fill (@code{mglData &}u, @code{const char *}eq, @code{const mglDataA &}v, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglGraph}} @code{void} Fill (@code{mglData &}u, @code{const char *}eq, @code{const mglDataA &}v, @code{const mglDataA &}w, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_data_fill_eq (@code{HMGL} gr, @code{HMDT} u, @code{const char *}eq, @code{HCDT}v, @code{HCDT}w, @code{const char *}opt)
++@end ifclear
++Fills the value of array @samp{u} according to the formula in string @var{eq}. Formula is an arbitrary expression depending on variables @samp{x}, @samp{y}, @samp{z}, @samp{u}, @samp{v}, @samp{w}. Coordinates @samp{x}, @samp{y}, @samp{z} are supposed to be normalized in axis range. Variable @samp{u} is the original value of the array. Variables @samp{v} and @samp{w} are values of arrays @var{v}, @var{w} which can be @code{NULL} (i.e. can be omitted).
++@end deftypefn
++
++@deftypefn {MGL command} {} datagrid dat xdat ydat zdat
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{void} DataGrid (@code{mglData &}u, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_data_grid (@code{HMGL} gr, @code{HMDT} u, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}opt)
++@end ifclear
++Fills the value of array @samp{u} according to the linear interpolation of triangulated surface, found for arbitrary placed points @samp{x}, @samp{y}, @samp{z}. Interpolation is done at points equidistantly distributed in axis range. NAN value is used for grid points placed outside of triangulated surface. @sref{Making regular data}
++@end deftypefn
++
++@deftypefn {MGL command} {} refill dat xdat vdat [sl=-1]
++@deftypefnx {MGL command} {} refill dat xdat ydat vdat [sl=-1]
++@deftypefnx {MGL command} {} refill dat xdat ydat zdat vdat
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Refill (@code{mglDataA &}dat, @code{const mglDataA &}x, @code{const mglDataA &}v, @code{long} sl=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglData}} @code{void} Refill (@code{mglDataA &}dat, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}v, @code{long} sl=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglData}} @code{void} Refill (@code{mglDataA &}dat, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}v, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_data_refill_gr (@code{HMGL} gr, @code{HMDT} a, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} v, @code{long} sl, @code{const char *}opt)
++@end ifclear
++Fills by interpolated values of array @var{v} at the point @{@var{x}, @var{y}, @var{z}@}=@{@code{X[i], Y[j], Z[k]}@} (or @{@var{x}, @var{y}, @var{z}@}=@{@code{X[i,j,k], Y[i,j,k], Z[i,j,k]}@} if @var{x}, @var{y}, @var{z} are not 1d arrays), where @code{X,Y,Z} are equidistantly distributed in axis range and have the same sizes as array @var{dat}. If parameter @var{sl} is 0 or positive then changes will be applied only for slice @var{sl}.
++@end deftypefn
++
++
++@deftypefn {MGL command} {} pde @sc{res} 'ham' ini_re ini_im [@code{dz=0.1 k0=100}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglGraph}} @code{mglData} PDE (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{mreal} dz=@code{0.1}, @code{mreal} k0=@code{100}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{HMDT} mgl_pde_solve (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{mreal} dz, @code{mreal} k0, @code{const char *}opt)
++@end ifclear
++Solves equation du/dz = i*k0*@var{ham}(p,q,x,y,z,|u|)[u], where p=-i/k0*d/dx, q=-i/k0*d/dy are pseudo-differential operators. Parameters @var{ini_re}, @var{ini_im} specify real and imaginary part of initial field distribution. Coordinates @samp{x}, @samp{y}, @samp{z} are supposed to be normalized in axis range. Note, that really this ranges are increased by factor 3/2 for purpose of reducing reflection from boundaries. Parameter @var{dz} set the step along evolutionary coordinate z. At this moment, simplified form of function @var{ham} is supported -- all ``mixed'' terms (like @samp{x*p}->x*d/dx) are excluded. For example, in 2D case this function is effectively @math{ham = f(p,z) + g(x,z,u)}. However commutable combinations (like @samp{x*q}->x*d/dy) are allowed. Here variable @samp{u} is used for field amplitude |u|. This allow one solve nonlinear problems -- for example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. You may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"}, but only if dependence on variable @samp{i} is linear (i.e. @math{ham = hre+i*him}). @sref{PDE solving hints}
++@end deftypefn
++
++@c ##################################################################
++@c @external{}
++@c @node IDTF functions, , Data manipulation, MathGL core
++@c @section IDTF functions
++@c @nav{}
++
++@c These functions provide IDTF specific features. In all other cases they do nothing.
++
++@c @ifclear UDAV
++
++@c @deftypefn {Method on @code{mglGraph}} @code{void} VertexColor (@code{bool} enable)
++@c Enables smooth color change.
++@c @end deftypefn
++
++@c @deftypefn {Method on @code{mglGraph}} @code{void} Compression (@code{bool} enable)
++@c Gives smaller files, but quality degrades.
++@c @end deftypefn
++
++@c inline void DoubleSided(bool){} // NOTE: Add later -- IDTF
++@c inline void TextureColor(bool){} // NOTE: Add later -- IDTF
++
++@c @end ifclear
++
++@external{}
--- /dev/null
--- /dev/null
++@c ------------------------------------------------------------------
++@chapter Ядро MathGL
++@nav{}
++@cindex mglGraph
++
++@ifset UDAV
++Эта глава посвящена описанию множества команд построения графиков для 1D, 2D и 3D массивов данных. Сюда включены также команды настройки графика, вывода текста и примитивов, рисования осей координат и др. Дополнительную информацию о цвете, шрифтах, стилях линий и формулах можно найти в @ref{General concepts}.
++@end ifset
++
++@ifclear UDAV
++Основным классом MathGL является класс @strong{mglGraph}, определённый в @code{#include <mgl2/mgl.h>}. Он включает в себя множество функций для построения графиков от 1D, 2D и 3D массивов. Он также содержит функции вывода текста и построения осей координат. Есть возможность построения в произвольной системе координат, которая задается строковыми формулами. Все графические функции используют класс mglData (см. @ref{Data processing}) для хранения массивов данных. Это позволяет легко контролировать размеры, работу с памятью и производить обработку данных. Дополнительная информация о цветах, шрифтах, вычисления формул может быть найдена в @ref{General concepts} и @ref{Other classes}.
++@end ifclear
++
++Некоторые возможности MathGL доступны только в новых версиях библиотеки. Для проверки текущей версии MathGL можно использовать следующую функцию.
++@anchor{version}
++@deftypefn {Команда MGL} {} version 'ver'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{bool} CheckVersion (@code{const char *}ver) static
++@deftypefnx {Функция С} @code{int} mgl_check_version (@code{const char *}ver)
++@end ifclear
++Возвращает нулевое значение если версия MathGL подходит для требуемой в @var{ver}, т.е. если номер основной версии совпадает и "подверсия" больше или равна указанной в @var{ver}.
++@end deftypefn
++
++@menu
++* Constructor::
++* Graphics setup::
++* Axis settings::
++* Subplots and rotation::
++* Export picture::
++* Background::
++* Primitives::
++* Text printing::
++* Axis and Colorbar::
++* Legend::
++* 1D plotting::
++* 2D plotting::
++* 3D plotting::
++* Dual plotting::
++* Vector fields::
++* Other plotting::
++* Nonlinear fitting::
++* Data manipulation::
++@c * IDTF functions::
++@end menu
++
++@c ##################################################################
++@external{}
++@node Constructor, Graphics setup, , MathGL core
++@section Создание и удаление графического объекта
++@nav{}
++
++@ifclear UDAV
++@deftypefn {Конструктор класса @code{mglGraph}} {} mglGraph (@code{int} kind=@code{0}, @code{int} width=@code{600}, @code{int} height=@code{400})
++@deftypefnx {Конструктор класса @code{mglGraph}} {} mglGraph (@code{const mglGraph &}gr)
++@deftypefnx {Конструктор класса @code{mglGraph}} {} mglGraph (@code{HMGL} gr)
++@deftypefnx {Функция С} @code{HMGL} mgl_create_graph (@code{int} width, @code{int} height)
++@deftypefnx {Функция С} @code{HMGL} mgl_create_graph_gl ()
++Создает (или использует созданный) экземпляр класса, производного от @code{mglGraph} (тип @code{HMGL}) с указанными размерами @var{width} и @var{height}. Параметр @var{kind} может иметь следующие значения: @samp{0} -- использовать рисование по умолчанию, @samp{1} -- использовать рисование в OpenGL.
++@end deftypefn
++
++@deftypefn {Destructor on @code{mglGraph}} {} ~mglGraph ()
++@deftypefnx {Функция С} @code{HMGL} mgl_delete_graph (@code{HMGL} gr)
++Удаляет экземпляр класса mglGraph.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{HMGL} Self ()
++Возвращает указатель на используемый объект типа @code{HMGL}.
++@end deftypefn
++@end ifclear
++
++@ifset UDAV
++MGL не требует создания данного типа объектов.
++@end ifset
++
++@c ##################################################################
++@external{}
++@node Graphics setup, Axis settings, Constructor, MathGL core
++@section Настройка графика
++@nav{}
++@cindex Настройка MathGL
++
++Функции и переменные в этой группе влияют на вид всего рисунка. Соответственно они должны располагаться @emph{перед} вызовом функций непосредственно рисующих графики.
++
++@anchor{reset}
++@deftypefn {Команда MGL} {} reset
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} DefaultPlotParam ()
++@deftypefnx {Функция С} @code{void} mgl_set_def_param (@code{HMGL} gr)
++@end ifclear
++Устанавливает все настройки по умолчанию и очищает рисунок.
++@end deftypefn
++
++@menu
++* Transparency::
++* Lighting::
++* Fog::
++* Default sizes::
++* Cutting::
++* Font settings::
++* Palette and colors::
++* Masks::
++* Error handling::
++* Stop drawing::
++@end menu
++
++@c ==================================================================
++@external{}
++@node Transparency, Lighting, , Graphics setup
++@subsection Прозрачность
++@nav{}
++@cindex Alpha
++@ifclear UDAV
++@cindex SetAlphaDef
++@cindex SetTranspType
++@end ifclear
++@cindex AlphaDef
++@cindex TranspType
++
++Эти функции и переменные настраивают тип и степень прозрачности поверхностей. Главной является функция @ref{alpha}, которая включает/выключает прозрачность для всего графика. Функция @ref{alphadef} устанавливает величину alpha-канала по умолчанию. Наконец, функция @ref{transptype} задает тип прозрачности. @sref{Transparency and lighting}
++
++@anchor{alpha}
++@deftypefn {Команда MGL} {} alpha @code{[val=on]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Alpha (@code{bool} enable)
++@deftypefnx {Функция С} @code{void} mgl_set_alpha (@code{HMGL} gr, @code{int} enable)
++@end ifclear
++Включает/выключает прозрачность и возвращает свое предыдущее состояние. По умолчанию прозрачность выключена. Функция включает прозрачность для @emph{всего} рисунка.
++@end deftypefn
++
++@anchor{alphadef}
++@deftypefn {Команда MGL} {} alphadef @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetAlphaDef (@code{mreal} val)
++@deftypefnx {Функция С} @code{void} mgl_set_alpha_default (@code{HMGL} gr, @code{mreal} alpha)
++@end ifclear
++Задает значение прозрачности по умолчанию для всех графиков. Значение по умолчанию 0.5.
++@end deftypefn
++
++@anchor{transptype}
++@deftypefn {Команда MGL} {} transptype @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTranspType (@code{int} type)
++@deftypefnx {Функция С} @code{void} mgl_set_transp_type (@code{HMGL} gr, @code{int} type)
++@end ifclear
++Задает тип прозрачности. Допустимые значения:
++@itemize @bullet
++@item
++Обычная прозрачность (@samp{0}) -- "закрытые" объекты видны меньше чем закрывающие. Этот режим некорректно отображается в OpenGL (mglGraphGL) для нескольких перекрывающихся поверхностей.
++@item
++"Стеклянная" прозрачность (@samp{1}) -- закрытые и закрывающие объекты единообразно ослабляют интенсивность света (по RGB каналам).
++@item
++"Ламповая" прозрачность (@samp{2}) -- закрытые и закрывающие объекты являются источниками дополнительного освещения (рекомендую установить @code{SetAlphaDef(0.3)} или меньше в этом случае).
++@end itemize
++@sref{Types of transparency}
++@end deftypefn
++
++@c ==================================================================
++@external{}
++@node Lighting, Fog, Transparency, Graphics setup
++@subsection Освещение
++@nav{}
++@ifclear UDAV
++@cindex SetAmbient
++@cindex AddLight
++@end ifclear
++@cindex Light
++@cindex Ambient
++
++Эти функции настраивают освещение графика. Главная функция @ref{light} включает/выключает освещение графиков построенных после ее вызова (в OpenGL работает сразу для всего рисунка). MathGL поддерживает до 10 независимых источников света. Но в режиме OpenGL можно использовать только первые 8 из них. Положение, цвет, яркость каждого источника света можно задавать по отдельности. По умолчанию включен только первый (с порядковым номером @code{0}) источник света белого цвета, расположенный сверху. @sref{Lighting sample}
++
++@anchor{light}
++@deftypefn {Команда MGL} {} light @code{[val=on]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{bool} Light (@code{bool} enable)
++@deftypefnx {Функция С} @code{void} mgl_set_light (@code{HMGL} gr, @code{int} enable)
++@end ifclear
++Включает/выключает освещение графика и возвращает предыдущее состояние. По умолчанию освещение выключено.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} light @code{num} @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Light (@code{int} n, @code{bool} enable)
++@deftypefnx {Функция С} @code{void} mgl_set_light_n (@code{HMGL} gr, @code{int} n, @code{int} enable)
++@end ifclear
++Включает/выключает @var{n}-ый источник света.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} light @code{num xdir ydir zdir} ['col'='w' @code{br=0.5 ap=0}]
++@deftypefnx {Команда MGL} {} light @code{num xdir ydir zdir xpos ypos zpos} ['col'='w' @code{br=0.5}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} AddLight (@code{int} n, @code{mglPoint} d, @code{char} c=@code{'w'}, @code{mreal} bright=@code{0.5}, @code{mreal} ap=@code{0})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} AddLight (@code{int} n, @code{mglPoint} r, @code{mglPoint} d, @code{char} c=@code{'w'}, @code{mreal} bright=@code{0.5}, @code{mreal} ap=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_add_light (@code{HMGL} gr, @code{int} n, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz)
++@deftypefnx {Функция С} @code{void} mgl_add_light_ext (@code{HMGL} gr, @code{int} n, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{char} c, @code{mreal} bright, @code{mreal} ap)
++@deftypefnx {Функция С} @code{void} mgl_add_light_loc (@code{HMGL} gr, @code{int} n, @code{mreal} rx, @code{mreal} ry, @code{mreal} rz, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{char} c, @code{mreal} bright, @code{mreal} ap)
++@end ifclear
++Добавляет источник света с номером @var{n} в положение @var{p} с цветом @var{c} и яркостью @var{bright}, которая должна быть в диапазоне [0,1]. Если указано положение источника @var{r} и оно не NAN, то источник считается локальным, иначе источник полагается бесконечно удалённым (для более быстрого рисования).
++@end deftypefn
++
++@anchor{diffuse}
++@deftypefn {Команда MGL} {} diffuse @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetDifLight (@code{mreal} bright)
++@deftypefnx {Функция С} @code{void} mgl_set_difbr (@code{HMGL} gr, @code{mreal} bright)
++@end ifclear
++Задает яркость диффузного освещения (только для локальных источников света).
++@end deftypefn
++
++@anchor{ambient}
++@deftypefn {Команда MGL} {} ambient @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetAmbient (@code{mreal} bright=@code{0.5})
++@deftypefnx {Функция С} @code{void} mgl_set_ambbr (@code{HMGL} gr, @code{mreal} bright)
++@end ifclear
++Задает яркость рассеянного освещения. Значение должно быть в диапазоне [0,1].
++@end deftypefn
++
++@anchor{attachlight}
++@deftypefn {Команда MGL} {} attachlight @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} AttachLight (@code{bool} val)
++@deftypefnx {Функция С} @code{void} mgl_set_attach_light (@code{HMGL} gr, @code{int} val)
++@end ifclear
++Задает привязку настроек освещения к @ref{inplot}/@ref{subplot}. Отмечу, что OpenGL и некоторые выходные форматы не поддерживают эту возможность.
++@end deftypefn
++
++
++@c ==================================================================
++@external{}
++@node Fog, Default sizes, Lighting, Graphics setup
++@subsection Туман
++@nav{}
++@cindex Fog
++
++@anchor{fog}
++@deftypefn {Команда MGL} {} fog @code{val [dz=0.25]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Fog (@code{mreal} d, @code{mreal} dz=@code{0.25})
++@deftypefnx {Функция С} @code{void} mgl_set_fog (@code{HMGL} gr, @code{mreal} d, @code{mreal} dz)
++@end ifclear
++Имитирует туман на графике. Туман начинается на относительном расстоянии @var{dz} от точки обзора и его плотность растет экспоненциально вглубь по закону ~ 1-exp(-@emph{d*z}). Здесь @emph{z} -- нормализованная на 1 глубина графика. Если @var{d}=@code{0} то туман отсутствует. @sref{Adding fog}
++@end deftypefn
++
++@c ==================================================================
++@external{}
++@node Default sizes, Cutting, Fog, Graphics setup
++@subsection Базовые размеры
++@nav{}
++@ifclear UDAV
++@cindex SetBarWidth
++@cindex SetMarkSize
++@cindex SetArrowSize
++@cindex SetMeshNum
++@cindex SetPlotId
++@end ifclear
++@cindex BarWidth
++@cindex MarkSize
++@cindex ArrowSize
++@cindex MeshNum
++
++Эти функции задают величины большинства параметров графика, включая размеры маркеров, стрелок, толщину линий и т.д. Как и любые другие настройки, они подействуют только на графики созданные после изменения настроек.
++
++@anchor{barwidth}
++@deftypefn {Команда MGL} {} barwidth @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetBarWidth ( @code{mreal} val)
++@deftypefnx {Функция С} @code{void} mgl_set_bar_width (@code{HMGL} gr, @code{mreal} val)
++@end ifclear
++Задает относительный размер прямоугольников в @ref{bars}, @ref{barh}, @ref{boxplot}, @ref{candle}. Значение по умолчанию @code{0.7}.
++@end deftypefn
++
++@anchor{marksize}
++@deftypefn {Команда MGL} {} marksize @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetMarkSize (@code{mreal} val)
++@deftypefnx {Функция С} @code{void} mgl_set_mark_size (@code{HMGL} gr, @code{mreal} val)
++@end ifclear
++Задает размер маркеров для @ref{1D plotting}. Значение по умолчанию @code{1}.
++@end deftypefn
++
++@anchor{arrowsize}
++@deftypefn {Команда MGL} {} arrowsize @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetArrowSize (@code{mreal} val)
++@deftypefnx {Функция С} @code{void} mgl_set_arrow_size (@code{HMGL} gr, @code{mreal} val)
++@end ifclear
++Задает размер стрелок для @ref{1D plotting}, линий и кривых (см. @ref{Primitives}). Значение по умолчанию @code{1}.
++@end deftypefn
++
++@anchor{meshnum}
++@anchor{MeshNum}
++@deftypefn {Команда MGL} {} meshnum @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetMeshNum (@code{int} val)
++@deftypefnx {Функция С} @code{void} mgl_set_meshnum (@code{HMGL} gr, @code{int} num)
++@end ifclear
++Задает ориентировочное число линий в @ref{mesh}, @ref{fall}, и число стрелок (штрихов) в @ref{vect}, @ref{dew}, и число ячеек в @ref{cloud}, и число маркеров в @ref{plot}, @ref{tens}, @ref{step}, @ref{mark}, @ref{textmark}. По умолчанию (=0) рисуются все линии, стрелки, ячейки и т.д.
++@end deftypefn
++
++@anchor{facenum}
++@deftypefn {Команда MGL} {} facenum @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetFaceNum (@code{int} val)
++@deftypefnx {Функция С} @code{void} mgl_set_facenum (@code{HMGL} gr, @code{int} num)
++@end ifclear
++Задает ориентировочное число видимых граней. Может быть использована для ускорения рисования за счет более грубого рисунка. По умолчанию (=0) рисуются все грани.
++@end deftypefn
++
++@anchor{plotid}
++@deftypefn {Команда MGL} {} plotid 'id'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetPlotId (@code{const char *}id)
++@deftypefnx {Функция С} @code{void} mgl_set_plotid (@code{HMGL} gr, @code{const char *}id)
++@end ifclear
++Задает имя графика для сохранения в файл (например, в окне FLTK).
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglGraph}} @code{const char *} GetPlotId ()
++@deftypefnx {Функция С} @code{const char *} mgl_get_plotid (@code{HMGL} gr)
++@deftypefnx {Fortran процедура} @code{} mgl_get_plotid (@code{long} gr, @code{char *}out, @code{int} len)
++Возвращает имя графика для сохранения в файл (например, в окне FLTK).
++@end deftypefn
++@end ifclear
++
++@anchor{pendelta}
++@deftypefn {Команда MGL} {} pendelta @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetPenDelta (@code{double} val)
++@deftypefnx {Функция С} @code{void} mgl_pen_delta (@code{HMGL} gr, @code{double} val)
++@end ifclear
++Изменяет размытие около линий и текста (по умолчанию 1). Для @var{val}>1 текст и линии более резкие. Для @var{val}<1 текст и линии более размытые.
++@end deftypefn
++
++@c ==================================================================
++@external{}
++@node Cutting, Font settings, Default sizes, Graphics setup
++@subsection Обрезание
++@nav{}
++@ifclear UDAV
++@cindex SetCut
++@cindex SetCutBox
++@cindex CutOff
++@end ifclear
++@cindex Cut
++
++Эти функции задают условия когда точка будет исключена (вырезана) из рисования. Замечу, что все точки со значением(-ями) NAN по одной из координат или амплитуде автоматически исключаются из рисования. @sref{Cutting sample}
++
++@anchor{cut}
++@deftypefn {Команда MGL} {} cut @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetCut (@code{bool} val)
++@deftypefnx {Функция С} @code{void} mgl_set_cut (@code{HMGL} gr, @code{int} val)
++@end ifclear
++Задает обрезание точек за пределами осей координат. Если @code{true} то такие точки исключаются из рисования (это по умолчанию) иначе они проецируются на ограничивающий прямоугольник.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} cut @code{x1 y1 z1 x2 y2 z2}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetCutBox (@code{mglPoint} p1, @code{mglPoint} p1)
++@deftypefnx {Функция С} @code{void} mgl_set_cut_box (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2)
++@end ifclear
++Задает границы параллелепипеда внутри которого точки не рисуются. Если границы одинаковы (переменные равны), то параллелепипеда считается пустым.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} cut 'cond'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} CutOff (@code{const char *}cond)
++@deftypefnx {Функция С} @code{void} mgl_set_cutoff (@code{HMGL} gr, @code{const char *}cond)
++@end ifclear
++Задает условие обрезания по формуле @var{cond}. Это условие исключает точки из рисования если результат вычисления формулы не равен нулю. Установите аргумент @code{""} для выключения условия обрезания.
++@end deftypefn
++
++@c ==================================================================
++@external{}
++@node Font settings, Palette and colors, Cutting, Graphics setup
++@subsection Шрифты
++@nav{}
++@ifclear UDAV
++@cindex SetFontSize
++@cindex SetFontDef
++@cindex SetRotatedText
++@cindex SetFontSizePT
++@cindex SetFontSizeCM
++@cindex SetFontSizeIN
++@cindex LoadFont
++@cindex CopyFont
++@cindex RestoreFont
++@end ifclear
++@cindex Font
++@cindex RotateText
++
++@anchor{font}
++@deftypefn {Команда MGL} {} font 'fnt' [@code{val=6}]
++Задает стиль и размер шрифта. Вначале используется @samp{:rC} -- прямой шрифт с выравниванием по центру. По умолчанию размер подписей оси координат в 1.4 раза больше. См. также см. @ref{Font styles}.
++@end deftypefn
++
++@anchor{rotatetext}
++@deftypefn {Команда MGL} {} rotatetext @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRotatedText (@code{bool} val)
++@deftypefnx {Функция С} @code{void} mgl_set_rotated_text (@code{HMGL} gr, @code{int} val)
++@end ifclear
++Включает/выключает вращение меток и подписей осей координат вдоль оси.
++@end deftypefn
++
++@anchor{loadfont}
++@deftypefn {Команда MGL} {} loadfont ['name'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} LoadFont (@code{const char *}name, @code{const char *}path=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_load_font (@code{HMGL} gr, @code{const char *}name, @code{const char *}path)
++@end ifclear
++Загружает начертание шрифта из файла @var{path}/@var{name}. Пустая строка загрузит шрифт по умолчанию.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetFontDef (@code{const char *}fnt)
++@deftypefnx {Функция С} @code{void} mgl_set_font_def (@code{HMGL} gr, @code{const char *} val)
++Задает стиль шрифта (см. @ref{Text printing}). По умолчанию используется @samp{rC} -- прямой шрифт с выравниванием по центру.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetFontSize (@code{mreal} val)
++@deftypefnx {Функция С} @code{void} mgl_set_font_size (@code{HMGL} gr, @code{mreal} val)
++Задает базовый размер шрифта. По умолчанию размер подписей оси координат в 1.4 раза больше.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetFontSizePT (@code{mreal} cm, @code{int} dpi=@code{72})
++Задает размер шрифта в пунктах для заданного DPI (по умолчанию 16 pt для dpi=72).
++@end deftypefn
++@deftypefn {Метод класса @code{mglGraph}} @code{inline void} SetFontSizeCM (@code{mreal} cm, @code{int} dpi=@code{72})
++Задает размер шрифта в сантиметрах для заданного DPI (по умолчанию 0.56 см = 16 pt).
++@end deftypefn
++@deftypefn {Метод класса @code{mglGraph}} @code{inline void} SetFontSizeIN (@code{mreal} cm, @code{int} dpi=@code{72})
++Задает размер шрифта в дюймах для заданного DPI (по умолчанию 0.22 in = 16 pt).
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} CopyFont (@code{mglGraph *} from)
++@deftypefnx {Функция С} @code{void} mgl_copy_font (@code{HMGL} gr, @code{HMGL} gr_from)
++Копирует начертание шрифта из другого объекта @code{mglGraph}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} RestoreFont ()
++@deftypefnx {Функция С} @code{void} mgl_restore_font (@code{HMGL} gr)
++Восстанавливает начертание шрифта по умолчанию.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetDefFont (@code{const char *}name, @code{const char *}path=@code{""}) static
++@deftypefnx {Функция С} @code{void} mgl_def_font (@code{const char *}name, @code{const char *}path)
++Загружает начертание шрифта по умолчанию (для всех вновь создаваемых HMGL/mglGraph объектов) из файла @var{path}/@var{name}.
++@end deftypefn
++
++@end ifclear
++
++@c ==================================================================
++@external{}
++@node Palette and colors, Masks, Font settings, Graphics setup
++@subsection Палитра и цвета
++@nav{}
++@ifclear UDAV
++@cindex SetPalette
++@end ifclear
++@cindex Palette
++
++@anchor{palette}
++@deftypefn {Команда MGL} {} palette 'colors'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetPalette (@code{const char *}colors)
++@deftypefnx {Функция С} @code{void} mgl_set_palette (@code{HMGL} gr, @code{const char *}colors)
++@end ifclear
++Задает палитру как последовательность цветов. Значение по умолчанию @code{"Hbgrcmyhlnqeup"}, что соответствует цветам: темно серый @samp{H}, синий @samp{b}, зелёный @samp{g}, красный @samp{r}, голубой @samp{c}, малиновый @samp{m}, жёлтый @samp{y}, серый @samp{h}, сине-зелёный @samp{l}, небесно-голубой @samp{n}, оранжевый @samp{q}, желто-зелёный @samp{e}, сине-фиолетовый @samp{u}, фиолетовый @samp{p}. Палитра в основном используется в 1D графиках (см. @ref{1D plotting}) для кривых с неопределённым стилем линии. Внутренний счетчик цвета будет сброшен при любом изменении палитры, включая скрытые (например, функциями @ref{box} или @ref{axis}).
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetDefScheme (@code{const char *}sch)
++@deftypefnx {Функция С} @code{void} mgl_set_def_sch (@code{HMGL} gr, @code{const char *}sch)
++Устанавливает @var{sch} в качестве цветовой схемы по умолчанию. Начальное значение @code{"BbcyrR"}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetColor (@code{char} id, @code{mreal} r, @code{mreal} g, @code{mreal} b) static
++@deftypefnx {Функция С} @code{void} mgl_set_color (@code{char} id, @code{mreal} r, @code{mreal} g, @code{mreal} b)
++Задает RGB значения для цвета с заданным @var{id}. Изменения действуют глобально для всех последующих использований данного @var{id}.
++@end deftypefn
++@end ifclear
++
++@anchor{gray}
++<<<<<<< HEAD
++@deftypefn {Команда MGL} {} gray @code{val}
++=======
++@deftypefn {Команда MGL} {} gray [@code{val=on}]
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Gray (@code{bool} enable)
++@deftypefnx {Функция С} @code{void} mgl_set_gray (@code{HMGL} gr, @code{int} enable)
++@end ifclear
++Включает/выключает вывод графика в оттенках серого.
++@end deftypefn
++
++@c ==================================================================
++@external{}
++@node Masks, Error handling, Palette and colors, Graphics setup
++@subsection Маски
++@nav{}
++@cindex SetMask
++@cindex SetMaskAngle
++
++@anchor{mask}
++@deftypefn {Команда MGL} {} mask 'id' 'hex'
++@deftypefnx {Команда MGL} {} mask 'id' hex
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetMask (@code{char} id, @code{const char *}hex)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetMask (@code{char} id, @code{uint64_t} hex)
++@deftypefnx {Функция С} @code{void} mgl_set_mask (@code{HMGL} gr, @code{const char *}hex)
++@deftypefnx {Функция С} @code{void} mgl_set_mask_val (@code{HMGL} gr, @code{uint64_t} hex)
++@end ifclear
++Задает новую матрицу @var{hex} размером 8*8 для маски с заданным @var{id}. Изменения действуют глобально для всех последующих использований данного @var{id}. Значения по умолчанию (см. @ref{Color scheme}): @samp{-} -- 000000FF00000000, @samp{+} -- 080808FF08080808, @samp{=} -- 0000FF00FF000000, @samp{;} -- 0000007700000000, @samp{o} -- 0000182424180000, @samp{O} -- 0000183C3C180000, @samp{s} -- 00003C24243C0000, @samp{S} -- 00003C3C3C3C0000, @samp{~} -- 0000060990600000, @samp{<} -- 0060584658600000, @samp{>} -- 00061A621A060000, @samp{j} -- 0000005F00000000, @samp{d} -- 0008142214080000, @samp{D} -- 00081C3E1C080000, @samp{*} -- 8142241818244281, @samp{^} -- 0000001824420000.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} mask angle
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetMaskAngle (@code{int} angle)
++@deftypefnx {Функция С} @code{void} mgl_set_mask_angle (@code{HMGL} gr, @code{int} angle)
++@end ifclear
++Задает угол поворота маски в градусах. Отмечу, что символы @samp{\}, @samp{/}, @samp{I} в цветовой схеме задают угол поворота в 45, -45 и 90 градусов соответственно.
++@end deftypefn
++
++@c ==================================================================
++@external{}
++@node Error handling, Stop drawing , Masks, Graphics setup
++@subsection Обработка ошибок
++@nav{}
++@ifset UDAV
++Все сообщения будут выведены автоматически в специальном окне или в консоли.
++@end ifset
++@ifclear UDAV
++@cindex Message
++@cindex SetWarn
++@cindex GetWarn
++
++Обычно вы должны сбросить признак ошибки с помощью @code{SetWarn(0);} перед построением и проверить @code{GetWarnCode()} или @code{Message()} на наличие ошибок после построения. Только последнее предупреждение сохраняется. Замечу, что все предупреждения/ошибки в MathGL не являются критичными -- в худшем из вариантов соответствующий график просто не будет построен. По умолчанию, все предупреждения выводятся в @code{stderr}. Этот вывод можно выключить вызовом @code{mgl_suppress_warn(true);}.
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetWarn (@code{int} code, @code{const char *}info=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_set_warn (@code{HMGL} gr, @code{int} code, @code{const char *}info)
++Задает код предупреждения. Обычно вызывается только для очистки предупреждений (@code{SetWarn(0);}) или внутри библиотеки. Текст @var{info} будет добавлен к предупреждениям как есть при @var{code}<0.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{const char *}Message ()
++@deftypefnx {Функция С} @code{const char *}mgl_get_mess (@code{HMGL} gr)
++@deftypefnx {Fortran процедура} @code{} mgl_get_mess (@code{long} gr, @code{char *}out, @code{int} len)
++Возвращает текст предупреждений о причине отсутствия графика. Если возвращаемая строка пустая, то сообщений нет.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{int} GetWarn ()
++@deftypefnx {Функция С} @code{int} mgl_get_warn (@code{HMGL} gr)
++Возвращает код сообщения о причине отсутствия графика. Возможные значения:
++@table @code
++@item mglWarnNone=0
++Предупреждений нет
++@item mglWarnDim
++Неправильные или несовместимые размеры данных
++@item mglWarnLow
++Размеры данных слишком малы
++@item mglWarnNeg
++Минимальное значение отрицательно
++@item mglWarnFile
++Файл не найден или указаны неправильные размерности
++@item mglWarnMem
++Не достаточно памяти
++@item mglWarnZero
++Значение данных равно нулю
++@item mglWarnLeg
++Нет записей в легенде
++@item mglWarnSlc
++Индекс среза вне данных
++@item mglWarnCnt
++Число линий уровня меньше или равно нулю
++@item mglWarnOpen
++Не могу открыть файл
++@item mglWarnLId
++Light: ID вне допустимых значений
++@item mglWarnSize
++Setsize: размер(ы) равны нулю или отрицательны
++@item mglWarnFmt
++Формат не поддерживается
++@item mglWarnTern
++Диапазоны осей несовместимые
++@item mglWarnNull
++Указатель равен NULL
++@item mglWarnSpc
++Не хватает места для графика
++@item mglScrArg
++Неправильные аргументы команды скрипта MGL
++@item mglScrCmd
++Неправильная команда в скрипте MGL
++@item mglScrLong
++Слишком длинная строка в скрипте MGL
++@item mglScrStr
++Одиночная ' в скрипте MGL
++@item mglScrTemp
++Изменяется временная переменная в MGL скрипте
++@end table
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SuppressWarn (@code{bool} state) static
++@deftypefnx {Функция С} @code{void} mgl_suppress_warn (@code{int} state)
++Выключает вывод предупреждений в @code{stderr} если @var{state} не ноль.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetGlobalWarn (@code{const char *}info) static
++@deftypefnx {Функция С} @code{void} mgl_set_global_warn (@code{const char *}info)
++Задает предупреждение @var{info}, не привязанное к конкретному объекту рисования.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{const char *} GlobalWarn () static
++@deftypefnx {Функция С} @code{const char *} mgl_get_global_warn ()
++Возвращает предупреждения, не привязанные к конкретному объекту рисования.
++@end deftypefn
++
++
++@end ifclear
++
++@c ==================================================================
++@external{}
++@node Stop drawing, , Error handling, Graphics setup
++@subsection Остановка рисования
++@nav{}
++@ifset UDAV
++Вы можете использовать команду @ref{stop} или соответствующую кнопку панели инструментов для остановки рисования и выполнения скрипта.
++@end ifset
++@ifclear UDAV
++@cindex Stop
++@cindex NeedStop
++@cindex SetEventFunc
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} Stop (@code{bool} stop=@code{true})
++@deftypefnx {Функция С only} @code{void} mgl_ask_stop (@code{HMGL} gr, @code{int} stop)
++Просит остановить рисование если @var{stop} не ноль, иначе сбрасывает флаг остановки.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{bool} NeedStop ()
++@deftypefnx {Функция С only} @code{void} mgl_need_stop (@code{HMGL} gr)
++Возвращает @code{true} если рисование должно быть остановлено. Также запускает обработку всех отложенных событий в GUI. Пользователь должен вызывать эту функцию время от времени внутри долгих вычислений для плавности отклика GUI.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{bool} SetEventFunc (@code{void (*}func@code{)(void *)}, @code{void *}par=@code{NULL})
++@deftypefnx {Функция С only} @code{void} mgl_set_event_func (@code{HMGL} gr, @code{void (*}func@code{)(void *)}, @code{void *}par)
++Задает функцию, которая будет вызвана для обработки событий в GUI библиотеке.
++@end deftypefn
++
++@end ifclear
++
++
++@c ==================================================================
++@external{}
++@node Axis settings, Subplots and rotation, Graphics setup, MathGL core
++@section Настройки осей координат
++@nav{}
++
++Эти функции управляет видом и масштабом осей координат. Перед построением для каждой точки выполняются 3 преобразования: сначала определяется возможность рисования точки (см. @ref{Cutting}), далее применяются формулы перехода к криволинейным координатам и наконец точка отображается. Отмечу, что MathGL выдает предупреждение если масштабы осей координат лежат вне области определения формул преобразования координат.
++
++@menu
++* Ranges (bounding box)::
++* Curved coordinates::
++* Ticks::
++@end menu
++
++@c ------------------------------------------------------------------
++@external{}
++@node Ranges (bounding box), Curved coordinates, , Axis settings
++@subsection Масштаб осей координат
++@nav{}
++@cindex CRange
++@cindex XRange
++@cindex YRange
++@cindex ZRange
++@cindex Ranges
++@cindex Origin
++@ifclear UDAV
++@cindex SetRange
++@cindex SetRanges
++@cindex SetOrigin
++@end ifclear
++
++@anchor{xrange}
++@anchor{yrange}
++@anchor{zrange}
++@anchor{crange}
++@deftypefn {Команда MGL} {} xrange @code{v1 v2} [@code{add=off}]
++@deftypefnx {Команда MGL} {} yrange @code{v1 v2} [@code{add=off}]
++@deftypefnx {Команда MGL} {} zrange @code{v1 v2} [@code{add=off}]
++@deftypefnx {Команда MGL} {} crange @code{v1 v2} [@code{add=off}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRange (@code{char} dir, @code{mreal} v1, @code{mreal} v2)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} AddRange (@code{char} dir, @code{mreal} v1, @code{mreal} v2)
++@deftypefnx {Функция С} @code{void} mgl_set_range_val (@code{HMGL} gr, @code{char} dir, @code{mreal} v1, @code{mreal} v2)
++@deftypefnx {Функция С} @code{void} mgl_add_range_val (@code{HMGL} gr, @code{char} dir, @code{mreal} v1, @code{mreal} v2)
++@end ifclear
++Задает диапазон изменения @samp{x}-,@samp{y}-,@samp{z}-,@samp{c}-координат. Если одно из значений равно @code{NAN}, то оно игнорируется. Параметр @code{add=on} указывает добавлять новый диапазон к существующему (не заменять его). См. также @ref{ranges}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} xrange dat [@code{add=off}]
++@deftypefnx {Команда MGL} {} yrange dat [@code{add=off}]
++@deftypefnx {Команда MGL} {} zrange dat [@code{add=off}]
++@deftypefnx {Команда MGL} {} crange dat [@code{add=off}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRange (@code{char} dir, @code{const mglDataA &}dat, @code{bool} add=@code{false})
++@deftypefnx {Функция С} @code{void} mgl_set_range_dat (@code{HMGL} gr, @code{char} dir, @code{const HCDT} a, @code{int} add)
++@end ifclear
++Задает диапазон изменения @samp{x}-,@samp{y}-,@samp{z}-,@samp{c}-координат как минимальное и максимальное значение массива @var{dat}. Параметр @code{add=on} указывает добавлять новый диапазон к существующему (не заменять его).
++@end deftypefn
++
++@anchor{ranges}
++@deftypefn {Команда MGL} {} ranges @code{x1 x2 y1 y2 [z1=0 z2=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRanges (@code{mglPoint} p1, @code{mglPoint} p2)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRanges (@code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2, @code{mreal} z1=@code{0}, @code{mreal} z2=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_set_ranges (@code{HMGL} gr, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2, @code{mreal} z1, @code{mreal} z2)
++@end ifclear
++Задает диапазон изменения координат. Если минимальное и максимальное значение координаты равны, то они игнорируются по данному направлению. Также устанавливает размер цветовой шкалы, аналогично команде @code{crange z1 z2}. Начальные диапазоны равны [-1, 1].
++@end deftypefn
++
++@deftypefn {Команда MGL} {} ranges @code{xx yy [zz cc=zz]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRanges (@code{const mglDataA &}xx, @code{const mglDataA &}yy)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRanges (@code{const mglDataA &}xx, @code{const mglDataA &}yy, @code{const mglDataA &}zz)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetRanges (@code{const mglDataA &}xx, @code{const mglDataA &}yy, @code{const mglDataA &}zz, @code{const mglDataA &}cc)
++@end ifclear
++Задает диапазон изменения @samp{x}-,@samp{y}-,@samp{z}-,@samp{c}-координат как минимальное и максимальное значение массивов @var{xx}, @var{yy}, @var{zz}, @var{cc} соответственно.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetAutoRanges (@code{mglPoint} p1, @code{mglPoint} p2)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetAutoRanges (@code{double} x1, @code{double} x2, @code{double} y1, @code{double} y2, @code{double} z1=@code{0}, @code{double} z2=@code{0}, @code{double} c1=@code{0}, @code{double} c2=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_set_auto_ranges (@code{HMGL} gr, @code{double} x1, @code{double} x2, @code{double} y1, @code{double} y2, @code{double} z1, @code{double} z2, @code{double} z1, @code{double} z2)
++Задает диапазон изменения координат для автоматических переменных. Если минимальное и максимальное значение координаты равны, то они игнорируются по данному направлению.
++@end deftypefn
++@end ifclear
++
++@anchor{origin}
++@deftypefn {Команда MGL} {} origin @code{x0 y0 [z0=nan]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetOrigin (@code{mglPoint} p0)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetOrigin (@code{mreal} x0, @code{mreal} y0, @code{mreal} z0=@code{NAN})
++@deftypefnx {Функция С} @code{void} mgl_set_origin (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0)
++@end ifclear
++Задает центр пересечения осей координат. Если одно из значений равно NAN, то MathGL попытается выбрать оптимальное положение осей координат по этому направлению.
++@end deftypefn
++
++@anchor{zoomaxis}
++@deftypefn {Команда MGL} {} zoomaxis @code{x1 x2}
++@deftypefnx {Команда MGL} {} zoomaxis @code{x1 y1 x2 y2}
++@deftypefnx {Команда MGL} {} zoomaxis @code{x1 y1 z1 x2 y2 z2}
++@deftypefnx {Команда MGL} {} zoomaxis @code{x1 y1 z1 c1 x2 y2 z2 c2}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ZoomAxis (@code{mglPoint} p1, @code{mglPoint} p2)
++@deftypefnx {Функция С} @code{void} mgl_zoom_axis (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} c1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{mreal} c2)
++@end ifclear
++Дополнительно расширяет диапазон осей координат, задаваемый функциями @code{SetRange} или @code{SetRanges}, в соответствии с формулами @math{min += (max-min)*p1} и @math{max += (max-min)*p1} (или @math{min *= (max/min)^p1} и @math{max *= (max/min)^p1} для "логарифмических" диапазонов, когда @math{inf>max/min>100} или @math{0<max/min<0.01}). Начальные значения [0, 1]. Внимание! эти настройки не могут быть переписаны никакими другими функциями, включая @code{DefaultPlotParam()}.
++@end deftypefn
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node Curved coordinates, Ticks, Ranges (bounding box), Axis settings
++@subsection Криволинейные координаты
++@nav{}
++@cindex Axis
++@ifclear UDAV
++@cindex SetFunc
++@cindex SetCoor
++@cindex Ternary
++@end ifclear
++
++@deftypefn {Команда MGL} {} axis 'fx' 'fy' 'fz' ['fa'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetFunc (@code{const char *}EqX, @code{const char *}EqY, @code{const char *}EqZ=@code{""}, @code{const char *}EqA=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_set_func (@code{HMGL} gr, @code{const char *}EqX, @code{const char *}EqY, @code{const char *}EqZ, @code{const char *}EqA)
++@end ifclear
++Задает формулы перехода к криволинейным координатам. Каждая строка является математическим выражением, зависящим от старых координат @samp{x}, @samp{y}, @samp{z} и @samp{a} или @samp{c} для цветовой шкалы. Например, для цилиндрических координат будет @code{SetFunc("x*cos(y)", "x*sin(y)", "z");}. Для удаления формул соответствующий параметр должен быть пустым или @code{NULL}. Использование формул преобразования слегка замедляет программу. Параметр @var{EqA} задает аналогичную формулу для цветовой шкалы. @xref{Textual formulas}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} axis @code{how}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetCoor (@code{int} how)
++@deftypefnx {Функция С} @code{void} mgl_set_coor (@code{HMGL} gr, @code{int} how)
++@end ifclear
++Устанавливает одну из предопределенных систем криволинейных координат в зависимости от параметра @var{how}:
++@table @code
++@item mglCartesian=0
++декартова система (нет преобразования координат, @{x,y,z@});
++@item mglPolar=1
++полярные координаты: @{x*cos(y),x*sin(y), z@};
++@item mglSpherical=2
++сферические координаты: @{x*sin(y)*cos(z), x*sin(y)*sin(z), x*cos(y)@};
++@item mglParabolic=3
++параболические координаты: @{x*y, (x*x-y*y)/2, z@};
++@item mglParaboloidal=4
++Paraboloidal coordinates: @{(x*x-y*y)*cos(z)/2, (x*x-y*y)*sin(z)/2, x*y@};
++@item mglOblate=5
++Oblate coordinates: @{cosh(x)*cos(y)*cos(z), cosh(x)*cos(y)*sin(z), sinh(x)*sin(y)@};
++@item mglProlate=6
++Prolate coordinates: @{sinh(x)*sin(y)*cos(z), sinh(x)*sin(y)*sin(z), cosh(x)*cos(y)@};
++@item mglElliptic=7
++эллиптические координаты: @{cosh(x)*cos(y), sinh(x)*sin(y), z@};
++@item mglToroidal=8
++тороидальные координаты: @{sinh(x)*cos(z)/(cosh(x)-cos(y)), sinh(x)*sin(z)/(cosh(x)-cos(y)), sin(y)/(cosh(x)-cos(y))@};
++@item mglBispherical=9
++бисферические координаты: @{sin(y)*cos(z)/(cosh(x)-cos(y)), sin(y)*sin(z)/(cosh(x)-cos(y)), sinh(x)/(cosh(x)-cos(y))@};
++@item mglBipolar=10
++биполярные координаты: @{sinh(x)/(cosh(x)-cos(y)), sin(y)/(cosh(x)-cos(y)), z@};
++@item mglLogLog=11
++Log-log координаты: @{lg(x), lg(y), lg(z)@};
++@item mglLogX=12
++Log-x координаты: @{lg(x), y, z@};
++@item mglLogY=13
++Log-y координаты: @{x, lg(y), z@}.
++@end table
++@end deftypefn
++
++@anchor{ternary}
++@deftypefn {Команда MGL} {} ternary @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Ternary (@code{int} tern)
++@deftypefnx {Функция С} @code{void} mgl_set_ternary (@code{HMGL} gr, @code{int} tern)
++@end ifclear
++Задает рисование треугольных (Ternary, @var{tern}=@code{1}), пирамидальных (Quaternary, @var{tern}=@code{2}) осей координат и проекций осей координат (@var{tern}=@code{4,5,6}).
++
++Ternary -- специальный тип графика для 3 зависимых координат (компонент) @var{a}, @var{b}, @var{c} таких, что @var{a}+@var{b}+@var{c}=1. MathGL использует только 2 независимые координаты @var{a}=x и @var{b}=y поскольку их достаточно для построения всех графиков. При этом третья координата z является независимым параметром для построения линий уровня, поверхностей и т.д.
++
++Соответственно Quaternary координаты -- 4 зависимые координаты @var{a}, @var{b}, @var{c} и @var{d}, такие что @var{a}+@var{b}+@var{c}+@var{d}=1. MathGL использует только 2 независимые координаты @var{a}=x, @var{b}=y и @var{d}=z поскольку их достаточно для построения всех графиков.
++
++Проекции строятся если к переменной @var{tern} добавить число @code{4}. Так что @var{tern}=@code{4} нарисует проекции в декартовых координатах, @var{tern}=@code{5} нарисует проекции в треугольных координатах, @var{tern}=@code{6} нарисует проекции в пирамидальных координатах. Если добавить @code{8} вместо @code{4}, то текст не будет выводиться на проекциях.
++
++Используйте @code{Ternary(0)} для возвращения к привычным координатам. @sref{Ternary axis} @sref{Axis projection}
++@end deftypefn
++
++@c ------------------------------------------------------------------
++@external{}
++@node Ticks, , Curved coordinates, Axis settings
++@subsection Метки осей
++@nav{}
++@cindex AxisStl
++@cindex TickLen
++@cindex Adjust
++@cindex XTick
++@cindex YTick
++@cindex ZTick
++@cindex CTick
++@ifclear UDAV
++@cindex SetAxisStl
++@cindex SetTickLen
++@cindex SetTicks
++@cindex SetTicksVal
++@cindex SetTuneTicks
++@cindex SetTickTime
++@cindex SetTickTempl
++@cindex SetTickRotate
++@cindex SetTickSkip
++@cindex SetOriginTick
++@cindex AddTick
++@end ifclear
++
++@anchor{adjust}
++@deftypefn {Команда MGL} {} adjust ['dir'='xyzc']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Adjust (@code{const char *}dir=@code{"xyzc"})
++@deftypefnx {Функция С} @code{void} mgl_adjust_ticks (@code{HMGL} gr, @code{const char *}dir)
++@end ifclear
++Автоматически задает шаг меток осей, число подметок и начальное положение меток для осей координат @var{dir} в виде наиболее удобном для человека. Также задает @code{SetTuneTicks(true)}. Обычно не требуется вызывать эту функцию кроме случая возвращения настроек по умолчанию.
++@end deftypefn
++
++@anchor{xtick}
++@anchor{ytick}
++@anchor{ztick}
++@anchor{ctick}
++@deftypefn {Команда MGL} {} xtick @code{val [sub=0 org=nan 'fact'='']}
++@deftypefnx {Команда MGL} {} ytick @code{val [sub=0 org=nan 'fact'='']}
++@deftypefnx {Команда MGL} {} ztick @code{val [sub=0 org=nan 'fact'='']}
++@deftypefnx {Команда MGL} {} ctick @code{val [sub=0 org=nan 'fact'='']}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicks (@code{char} dir, @code{mreal} d=@code{0}, @code{int} ns=@code{0}, @code{mreal} org=@code{NAN}, @code{const char *}fact=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicks (@code{char} dir, @code{mreal} d=@code{0}, @code{int} ns=@code{0}, @code{mreal} org=@code{NAN}, @code{const wchar_t *}fact)
++@deftypefnx {Функция С} @code{void} mgl_set_ticks (@code{HMGL} gr, @code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org)
++@deftypefnx {Функция С} @code{void} mgl_set_ticks_fact (@code{HMGL} gr, @code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org, @code{const char *}fact)
++@deftypefnx {Функция С} @code{void} mgl_set_ticks_factw (@code{HMGL} gr, @code{char} dir, @code{mreal} d, @code{int} ns, @code{mreal} org, @code{const wchar_t *} fact)
++@end ifclear
++Задает шаг меток осей @var{d}, число подметок @var{ns} и начальное положение меток @var{org} для оси вдоль направления @var{dir} (используйте 'c' для меток colorbar). Переменная @var{d} задает шаг меток (если положительна) или их число на оси (если отрицательна). Нулевое значение задает автоматическую расстановку меток. Если @var{org}=@code{NAN}, то используется значение из переменной @var{Org}. Параметр @var{fact} задает текст, которые будет напечатан после метки оси (например, "\pi" для @var{d}=M_PI).
++@end deftypefn
++
++@deftypefn {Команда MGL} {} xtick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
++@deftypefnx {Команда MGL} {} ytick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
++@deftypefnx {Команда MGL} {} ztick @code{val1} 'lbl1' [@code{val2} 'lbl2' ...]
++@deftypefnx {Команда MGL} {} xtick vdat 'lbls' [@code{add=off}]
++@deftypefnx {Команда MGL} {} ytick vdat 'lbls' [@code{add=off}]
++@deftypefnx {Команда MGL} {} ztick vdat 'lbls' [@code{add=off}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const char *}lbl, @code{bool} add=@code{false})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const wchar_t *}lbl, @code{bool} add=@code{false})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const mglDataA &}val, @code{const char *}lbl, @code{bool} add=@code{false})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicksVal (@code{char} dir, @code{const mglDataA &}val, @code{const wchar_t *}lbl, @code{bool} add=@code{false})
++@deftypefnx {Функция С} @code{void} mgl_set_ticks_str (@code{HMGL} gr, @code{char} dir, @code{const char *}lbl, @code{bool} add)
++@deftypefnx {Функция С} @code{void} mgl_set_ticks_wcs (@code{HMGL} gr, @code{char} dir, @code{const wchar_t *}lbl, @code{bool} add)
++@deftypefnx {Функция С} @code{void} mgl_set_ticks_val (@code{HMGL} gr, @code{char} dir, @code{HCDT} val, @code{const char *}lbl, @code{bool} add)
++@deftypefnx {Функция С} @code{void} mgl_set_ticks_valw (@code{HMGL} gr, @code{char} dir, @code{HCDT} val, @code{const wchar_t *}lbl, @code{bool} add)
++@end ifclear
++Задает явное положение @var{val} и подписи @var{lbl} для меток вдоль оси @var{dir}. Если массив @var{val} не указан, то используются значения равно распределённые в диапазоне осей координат. Метки разделяются символом @samp{\n}. Если в команде MGL задано только одно значение, то метка будет @emph{добавлена} к существующим меткам. Используйте @code{SetTicks()} для восстановления автоматических меток.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglGraph}} @code{void} AddTick (@code{char} dir, @code{double} val, @code{const char *}lbl)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} AddTick (@code{char} dir, @code{double} val, @code{const wchar_t *}lbl)
++@deftypefnx {Функция С} @code{void} mgl_add_tick (@code{HMGL} gr, @code{char} dir, @code{double} val, @code{const char *}lbl)
++@deftypefnx {Функция С} @code{void} mgl_set_tickw (@code{HMGL} gr, @code{char} dir, @code{double} val, @code{const wchar_t *}lbl)
++Аналогично предыдущему, но добавляет одну метку оси к списку существующих меток.
++@end deftypefn
++@end ifclear
++
++@deftypefn {Команда MGL} {} xtick 'templ'
++@deftypefnx {Команда MGL} {} ytick 'templ'
++@deftypefnx {Команда MGL} {} ztick 'templ'
++@deftypefnx {Команда MGL} {} ctick 'templ'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTickTempl (@code{char} dir, @code{const char *}templ)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTickTempl (@code{char} dir, @code{const wchar_t *}templ)
++@deftypefnx {Функция С} @code{void} mgl_set_tick_templ (@code{HMGL} gr, @code{const char *}templ)
++@deftypefnx {Функция С} @code{void} mgl_set_tick_templw (@code{HMGL} gr, @code{const wchar_t *}templ)
++@end ifclear
++Задает шаблон @var{templ} для меток вдоль x-,y-,z-оси или colorbar. Шаблон может содержать и символы TeX. Если @var{templ}=@code{""}, то используется шаблон по умолчанию (в простейшем случае @samp{%.2g}). Если шаблон начинается с символа @samp{&}, то будет использовано целое @code{long} вместо типа @code{double}. Установка шаблона выключает автоматическое улучшение вида меток.
++@end deftypefn
++
++@anchor{ticktime}
++@deftypefn {Команда MGL} {} ticktime 'dir' [@code{dv=0} 'tmpl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTicksTime (@code{char} dir, @code{mreal} val, @code{const char *}templ)
++@deftypefnx {Функция С} @code{void} mgl_set_ticks_time (@code{HMGL} gr, @code{mreal} val, @code{const char *}templ)
++@end ifclear
++Задает метки времени с шагом @var{val} и шаблоном @var{templ} для меток вдоль x-,y-,z-оси или colorbar. Шаблон может содержать и символы TeX. Формат шаблона @var{templ} такой же как @url{http://www.manpagez.com/man/3/strftime/}. Наиболее употребительные варианты: @samp{%X} для национального представления времени, @samp{%x} для национального представления даты, @samp{%Y} для года с цифрами столетия. Если @var{val}=0 и/или @var{templ}="", то используется автоматическая расстановка меток и/или выбор шаблона. Вы можете использовать функцию @code{mgl_get_time}() для получения числа секунд с 1970 года до указанной даты/времени. Отмечу, что MS Visual Studio не может обрабатывать даты до 1970.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Функция С} @code{double} mgl_get_time (@code{const char*}str, @code{const char *}templ)
++Возвращает число секунд с 1970 года до даты/времени, указанной в строке @var{str}. Формат строки задается @var{templ}, такой же как @url{http://www.manpagez.com/man/3/strftime/}. Наиболее употребительные варианты: @samp{%X} для национального представления времени, @samp{%x} для национального представления даты, @samp{%Y} для года с цифрами столетия. Отмечу, что MS Visual Studio не может обрабатывать даты до 1970.
++@end deftypefn
++@end ifclear
++
++@anchor{tuneticks}
++@deftypefn {Команда MGL} {} tuneticks @code{val} [@code{pos=1.15}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTuneTicks (@code{int} tune, @code{mreal} pos=@code{1.15})
++@deftypefnx {Функция С} @code{void} mgl_tune_ticks (@code{HMGL} gr, @code{int} tune, @code{mreal} pos)
++@end ifclear
++Включает/выключает улучшение вида меток осей путем вынесения общего множителя (для маленьких, типа 0.001...0.002, или больших, типа 1000...2000, значений координат) или общей компоненты (для узкого диапазона, типа 0.999...1.000). Также задает положение @var{pos} общего множителя на оси: =0 около минимального значения, =1 около максимального значения.
++@end deftypefn
++
++@anchor{tickshift}
++@deftypefn {Команда MGL} {} tickshift @code{dx [dy=0 dz=0 dc=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTickShift (@code{mglPoint} d)
++@deftypefnx {Функция С} @code{void} mgl_set_tick_shift (@code{HMGL} gr, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{mreal} dc)
++@end ifclear
++Задает значение дополнительного сдвига меток осей координат.
++@end deftypefn
++
++@ifclear UDAV
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetTickRotate (@code{bool} val)
++@deftypefnx {Функция С} @code{void} mgl_set_tick_rotate (@code{HMGL} gr, @code{bool} val)
++Включает/выключает поворот меток если их число или длина меток слишком велики.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetTickSkip (@code{bool} val)
++@deftypefnx {Функция С} @code{void} mgl_set_tick_skip (@code{HMGL} gr, @code{bool} val)
++Включает/выключает пропуск меток если их число или длина меток слишком велики.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetTimeUTC (@code{bool} val)
++Разрешает/запрещает использование UTC времени в метках осей координат. В C/Fortran следует использовать @code{mgl_set_flag(gr,val, MGL_USE_GMTIME);}.
++@end deftypefn
++
++@end ifclear
++
++@anchor{origintick}
++@deftypefn {Команда MGL} {} origintick @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetOriginTick (@code{bool} val=@code{true})
++@end ifclear
++Разрешает/запрещает рисование меток в точке пересечения осей координат. В C/Fortran следует использовать @code{mgl_set_flag(gr,val, MGL_NO_ORIGIN);}.
++@end deftypefn
++
++@anchor{ticklen}
++@deftypefn {Команда MGL} {} ticklen @code{val} [@code{stt=1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetTickLen (@code{mreal} val, @code{mreal} stt=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_set_tick_len (@code{HMGL} gr, @code{mreal} val, @code{mreal} stt)
++@end ifclear
++Задает относительную длину меток осей координат. Значение по умолчанию @code{0.1}. Параметр @var{stt}>0 задает относительную длину подметок, которые в @code{sqrt(1+stt)} раз меньше.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} axisstl 'stl' ['tck'='' 'sub'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetAxisStl (@code{const char *}stl=@code{"k"}, @code{const char *}tck=@code{0}, @code{const char *}sub=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_set_axis_stl (@code{HMGL} gr, @code{const char *}stl, @code{const char *}tck, @code{const char *}sub)
++@end ifclear
++Задает стиль осей (@var{stl}), меток (@var{tck}) и подметок (@var{sub}) осей координат. Если @var{stl} пустая или ноль, то используется стиль по умолчанию (@samp{k} или @samp{w} в зависимости от типа прозрачности). Если @var{tck}, @var{sub} пустая или ноль, то используется стиль осей (т.е. @var{stl}).
++@end deftypefn
++
++@c ##################################################################
++@external{}
++@node Subplots and rotation, Export picture, Axis settings, MathGL core
++@section Матрица преобразования
++@nav{}
++@cindex Aspect
++@cindex Rotate
++@cindex RotateN
++@cindex SubPlot
++@cindex MultiPlot
++@cindex StickPlot
++@cindex ColumnPlot
++@cindex InPlot
++@cindex Title
++@cindex Perspective
++@cindex View
++@cindex Push
++@cindex Pop
++
++Эти функции контролируют где и как график будет расположен. Существует определенный порядок вызова этих функций для лучшего вида графика. Вначале должны вызываться функции @ref{subplot}, @ref{multiplot} или @ref{inplot} для указания местоположения вывода. После них -- функции вращения @ref{rotate}, @ref{shear} и @ref{aspect}. И наконец любые другие функции для рисования графика. Вместо вращения графика можно вызвать функцию @ref{columnplot}, @ref{gridplot}, @ref{stickplot}, @ref{shearplot} или относительную @ref{inplot} для расположения графиков в столбец одного над другим без зазора между осями. @sref{Subplots}
++
++@anchor{subplot}
++@deftypefn {Команда MGL} {} subplot @code{nx ny m} ['stl'='<>_^' @code{dx=0 dy=0}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SubPlot (@code{int} nx, @code{int} ny, @code{int} m, @code{const char *}stl=@code{"<>_^"}, @code{mreal} dx=@code{0}, @code{mreal} dy=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_subplot (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} m, @code{const char *}stl)
++@deftypefnx {Функция С} @code{void} mgl_subplot_d (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} m, @code{const char *}stl, @code{mreal} dx, @code{mreal} dy)
++@end ifclear
++Помещает последующий вывод в @var{m}-ую ячейку сетки размером @var{nx}*@var{ny} от всего рисунка. Функция сбрасывает матрицу трансформации (повороты и сжатие графика) и должна вызываться первой для создания "подграфика". С эстетической точки зрения не рекомендуется вызывать эту функцию с различными (или не кратными) размерами сетки. Дополнительное место для осей/colorbar резервируется только если строка @var{stl} содержит:
++@itemize @bullet
++@item
++@samp{L} или @samp{<} -- с левого края,
++@item
++@samp{R} или @samp{>} -- с правого края,
++@item
++@samp{A} или @samp{^} -- с верхнего края,
++@item
++@samp{U} или @samp{_} -- с нижнего края,
++@item
++@samp{#} -- место резервироваться не будет -- оси координат будут занимать все доступное пространство.
++@end itemize
++Ячейка может быть дополнительно сдвинута относительно своего обычного положения на относительный размер @var{dx}, @var{dy}. Отмечу, что colorbar может находиться за пределами рисунка если выбран пустой стиль @samp{}.
++@end deftypefn
++
++@anchor{multiplot}
++@deftypefn {Команда MGL} {} multiplot @code{nx ny m dx dy} ['style'='<>_^' sx sy]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} MultiPlot (@code{int} nx, @code{int} ny, @code{int} m, @code{int} dx, @code{int} dy, @code{const char *}stl=@code{"<>_^"})
++@deftypefnx {Функция С} @code{void} mgl_multiplot (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} m, @code{int} dx, @code{int} dy, @code{const char *}stl)
++@end ifclear
++Помещает последующий вывод в прямоугольник из @var{dx}*@var{dy} ячеек, начиная с @var{m}-ой ячейки, сетки размером @var{nx}*@var{ny} от всего рисунка. Функция сбрасывает матрицу трансформации (повороты и сжатие графика) и должна вызываться первой для создания "подграфика". Дополнительное место для осей/colorbar резервируется если строка @var{stl} содержит:
++@itemize @bullet
++@item
++@samp{L} или @samp{<} -- с левого края,
++@item
++@samp{R} или @samp{>} -- с правого края,
++@item
++@samp{A} или @samp{^} -- с верхнего края,
++@item
++@samp{U} или @samp{_} -- с нижнего края,
++@item
++@samp{#} -- место резервироваться не будет -- оси координат будут занимать все доступное пространство.
++@end itemize
++Область вывода может быть дополнительно сдвинута относительно своего обычного положения на относительный размер @var{sx}, @var{sy}.
++@end deftypefn
++
++@anchor{inplot}
++@deftypefn {Команда MGL} {} inplot @code{x1 x2 y1 y2 [rel=on]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} InPlot (@code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2, @code{bool} rel=@code{true})
++@deftypefnx {Функция С} @code{void} mgl_inplot (@code{HMGL} gr, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2)
++@deftypefnx {Функция С} @code{void} mgl_relplot (@code{HMGL} gr, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2)
++@end ifclear
++Помещает последующий вывод в прямоугольную область [@var{x1}, @var{x2}]*[@var{y1}, @var{y2}] (исходный размер [0,1]*[0,1]). Эта функция позволяет поместить график в произвольную область рисунка. Если параметр @var{rel}=@code{true}, то используется позиция относительно текущего @ref{subplot} (или @ref{inplot} с @var{rel}=@code{false}). Функция сбрасывает матрицу трансформации (повороты и сжатие графика) и должна вызываться первой для создания "подграфика".
++@end deftypefn
++
++@anchor{columnplot}
++@deftypefn {Команда MGL} {} columnplot @code{num ind [d=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ColumnPlot (@code{int} num, @code{int} ind, @code{mreal} d=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_columnplot (@code{HMGL} gr, @code{int} num, @code{int} ind)
++@deftypefnx {Функция С} @code{void} mgl_columnplot_d (@code{HMGL} gr, @code{int} num, @code{int} ind, @code{mreal} d)
++@end ifclear
++Помещает последующий вывод в @var{ind}-ую строку столбца из @var{num} строк. Положение столбца выбирается относительно последнего вызова @ref{subplot} (или @ref{inplot} с @var{rel}=@code{false}). Параметр @var{d} задает дополнительный зазор между строк.
++@end deftypefn
++
++@anchor{gridplot}
++@deftypefn {Команда MGL} {} gridplot @code{nx ny ind [d=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} GridPlot (@code{int} nx, @code{int} ny, @code{int} ind, @code{mreal} d=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_gridplot (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} ind)
++@deftypefnx {Функция С} @code{void} mgl_gridplot_d (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} ind, @code{mreal} d)
++@end ifclear
++Помещает последующий вывод в @var{ind}-ую ячейку таблицы @var{nx}*@var{ny}. Положение ячейки выбирается относительно последнего вызова @ref{subplot} (или @ref{inplot} с @var{rel}=@code{false}). Параметр @var{d} задает дополнительный зазор между ячеек.
++@end deftypefn
++
++@anchor{stickplot}
++@deftypefn {Команда MGL} {} stickplot @code{num ind tet phi}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} StickPlot (@code{int} num, @code{int} ind, @code{mreal} tet, @code{mreal} phi)
++@deftypefnx {Функция С} @code{void} mgl_stickplot (@code{HMGL} gr, @code{int} num, @code{int} ind, @code{mreal} tet, @code{mreal} phi)
++@end ifclear
++Помещает последующий вывод в @var{ind}-ую ячейку "бруска" из @var{num} ячеек. При этом сам брусок повернут на углы @var{tet}, @var{phi}. Положение выбирается относительно последнего вызова @ref{subplot} (или @ref{inplot} с @var{rel}=@code{false}).
++@end deftypefn
++
++@anchor{shearplot}
++@deftypefn {Команда MGL} {} shearplot @code{num ind sx sy [xd yd]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ShearPlot (@code{int} num, @code{int} ind, @code{mreal} sx, @code{mreal} sy, @code{mreal} xd=@code{1}, @code{mreal} yd=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_shearplot (@code{HMGL} gr, @code{int} num, @code{int} ind, @code{mreal} sx, @code{mreal} sy, @code{mreal} xd, @code{mreal} yd)
++@end ifclear
++Помещает последующий вывод в @var{ind}-ую ячейку "бруска" из @var{num} ячеек. При этом сама ячейка скошена на @var{sx}, @var{sy}. Направление бруска задается переменными @var{xd} и @var{yd}. Положение выбирается относительно последнего вызова @ref{subplot} (или @ref{inplot} с @var{rel}=@code{false}).
++@end deftypefn
++
++@anchor{title}
++@deftypefn {Команда MGL} {} title 'title' ['stl'='' @code{size=-2}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Title (@code{const char *}txt, @code{const char *}stl=@code{""}, @code{mreal} size=@code{-2})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Title (@code{const wchar_t *}txt, @code{const char *}stl=@code{""}, @code{mreal} size=@code{-2})
++@deftypefnx {Функция С} @code{void} mgl_title (@code{HMGL} gr, @code{const char *}txt, @code{const char *}stl, @code{mreal} size)
++@deftypefnx {Функция С} @code{void} mgl_titlew (@code{HMGL} gr, @code{const wchar_t *}txt, @code{const char *}stl, @code{mreal} size)
++@end ifclear
++Выводит заголовок @var{title} для текущего "подграфика" шрифтом @var{stl} с размером @var{size}. Если строка @var{stl} содержит @samp{#}, то рисуется обрамляющий прямоугольник. Функция сбрасывает матрицу трансформации (повороты и сжатие графика) и должна вызываться сразу после создания "подграфика".
++@end deftypefn
++
++@anchor{rotate}
++@deftypefn {Команда MGL} {} rotate @code{tetx tetz [tety=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Rotate (@code{mreal} TetX, @code{mreal} TetZ, @code{mreal} TetY=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_rotate (@code{HMGL} gr, @code{mreal} TetX, @code{mreal} TetZ, @code{mreal} TetY)
++@end ifclear
++Вращает систему координат относительно осей @{x, z, y@} последовательно на углы @var{TetX}, @var{TetZ}, @var{TetY}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} rotate @code{tet x y z}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} RotateN (@code{mreal} Tet, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++@deftypefnx {Функция С} @code{void} mgl_rotate_vector (@code{HMGL} gr, @code{mreal Tet}, @code{mreal x}, @code{mreal y}, @code{mreal z})
++@end ifclear
++Вращает систему координат относительно вектора @{@var{x}, @var{y}, @var{z}@} на угол @var{Tet}.
++@end deftypefn
++
++
++@anchor{shear}
++@deftypefn {Команда MGL} {} shear @code{sx sy}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Shear (@code{mreal} sx, @code{mreal} sy)
++@deftypefnx {Функция С} @code{void} mgl_shear (@code{HMGL} gr, @code{mreal} sx, @code{mreal} sy)
++@end ifclear
++Сдвигает (скашивает) систему координат на значения @var{sx}, @var{sy}.
++@end deftypefn
++
++
++@anchor{aspect}
++@deftypefn {Команда MGL} {} aspect @code{ax ay [az=1]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Aspect (@code{mreal} Ax, @code{mreal} Ay, @code{mreal} Az=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_aspect (@code{HMGL} gr, @code{mreal} Ax, @code{mreal} Ay, @code{mreal} Az)
++@end ifclear
++Устанавливает соотношение размеров осей в отношении @var{Ax:Ay:Az}. Для лучшего вида следует вызывать после функции @ref{rotate}. Если @var{Ax}=@code{NAN}, то функция выберет оптимальное соотношение размеров, чтобы шаг по осям x-y был одинаков. При этом, @var{Ay} задает фактор пропорциональности шага (обычно 1), или указывает на его автоматический выбор при @var{Ay}=@code{NAN}.
++@end deftypefn
++
++@ifclear UDAV
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} Push ()
++@deftypefnx {Функция С} @code{void} mgl_mat_push (@code{HMGL} gr)
++Помещает матрицу преобразования в стек. Позднее вы можете восстановить текущее состояние с помощью функции Pop().
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} Pop ()
++@deftypefnx {Функция С} @code{void} mgl_mat_pop (@code{HMGL} gr)
++Заменяет (восстанавливает) матрицу преобразования на последнюю помещенную в стек матрицу.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetPlotFactor (@code{mreal} val)
++@deftypefnx {Функция С} @code{void} mgl_set_plotfactor (@code{HMGL} gr, @code{mreal} val)
++Задает масштаб картинки. Не рекомендуется устанавливать значения меньше 1.5. Это аналог функции Zoom(), но применяется только к конкретному подграфику. Используйте ноль для включения автоматического масштабирования.
++@end deftypefn
++
++@end ifclear
++
++
++Также есть 3 функции, которые управляют перспективой @code{Perspective()}, масштабированием @code{Zoom()} и вращением @code{View()} всего рисунка. Т.е. они действуют как ещё одна матрица трансформации. Они были введены для вращения/приближения графика с помощью мыши. Не рекомендуется вызывать их при рисовании графика.
++
++@anchor{perspective}
++@deftypefn {Команда MGL} {} perspective @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Perspective (@code{mreal} a)
++@deftypefnx {Функция С} @code{void} mgl_perspective (@code{HMGL} gr, @code{mreal} a)
++@end ifclear
++Добавляет (включает) перспективу для графика. Параметр @math{a = Depth/(Depth+dz) \in [0,1)}. По умолчанию (@code{a=0}) перспектива отключена.
++@end deftypefn
++
++@anchor{view}
++@deftypefn {Команда MGL} {} view @code{tetx tetz [tety=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} View (@code{mreal} TetX, @code{mreal} TetZ, @code{mreal} TetY=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_view (@code{HMGL} gr, @code{mreal} TetX, @code{mreal} TetZ, @code{mreal} TetY)
++@end ifclear
++Вращает систему координат относительно осей @{x, z, y@} последовательно на углы @var{TetX}, @var{TetZ}, @var{TetY}. Вращение происходит независимо от @ref{rotate}. Внимание! эти настройки не могут быть переписаны функцией @code{DefaultPlotParam()}. Используйте @code{Zoom(0,0,1,1)} для возвращения к виду по умолчанию.
++@end deftypefn
++
++@anchor{zoom}
++@deftypefn {Команда MGL} {} zoom @code{x1 y1 x2 y2}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Zoom (@code{mreal} x1, @code{mreal} y1, @code{mreal} x2, @code{mreal} y2)
++@deftypefnx {Функция С} @code{void} mgl_set_zoom (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} x2, @code{mreal} y2)
++@end ifclear
++Масштабирует весь рисунок. После вызова функции текущий график будет очищен и в дальнейшем рисунок будет содержать только область [x1,x2]*[y1,y2] от исходного рисунка. Координаты @var{x1}, @var{x2}, @var{y1}, @var{y2} меняются в диапазоне от 0 до 1. Внимание! эти настройки не могут быть переписаны никакими другими функциями, включая @code{DefaultPlotParam()}. Используйте @code{Zoom(0,0,1,1)} для возвращения к виду по умолчанию.
++@end deftypefn
++
++@c ##################################################################
++@external{}
++@node Export picture, Background, Subplots and rotation, MathGL core
++@section Экспорт рисунка
++@nav{}
++@cindex SetSize
++
++Функции в этой группе сохраняют или дают доступ к полученному рисунку. Поэтом обычно они должны вызываться в конце рисования.
++
++@anchor{setsize}
++@deftypefn {Команда MGL} {} setsize @code{w h}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetSize (@code{int} width, @code{int} height, @code{bool} clear=@code{true})
++@deftypefnx {Функция С} @code{void} mgl_set_size (@code{HMGL} gr, @code{int} width, @code{int} height)
++@deftypefnx {Функция С} @code{void} mgl_scale_size (@code{HMGL} gr, @code{int} width, @code{int} height)
++@end ifclear
++Изменяет размер картинки в пикселях. Функция должна вызываться @strong{перед} любыми функциями построения потому что полностью очищает содержимое рисунка при @var{clear}=@code{true}. Функция только очищает растровый рисунок и масштабирует примитивы при @var{clear}=@code{false}.
++@end deftypefn
++
++
++@anchor{setsizescl}
++@deftypefn {Команда MGL} {} setsizescl @code{factor}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetSizeScl (@code{double} factor)
++@deftypefnx {Функция С} @code{void} mgl_set_size_scl (@code{HMGL} gr, @code{double} factor)
++@end ifclear
++Задает множитель для высоты и ширины во всех последующих вызовах @ref{setsize}.
++@end deftypefn
++
++
++@anchor{quality}
++@deftypefn {Команда MGL} {} quality [@code{val}=2]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetQuality (@code{int} val=@code{MGL_DRAW_NORM})
++@deftypefnx {Функция С} @code{void} mgl_set_quality (@code{HMGL} gr, @code{int} val)
++@end ifclear
++Задает качество графика в зависимости от значения @var{val}: @code{MGL_DRAW_WIRE=0} -- нет рисования граней (наиболее быстрый), @code{MGL_DRAW_FAST=1} -- нет интерполяции цвета (быстрый), @code{MGL_DRAW_NORM=2} -- высокое качество (нормальный), @code{MGL_DRAW_HIGH=3} -- высокое качество с рисованием 3d примитивов (стрелок и маркеров). Если установлен бит @code{MGL_DRAW_LMEM=0x4}, то происходит прямое рисование в растровое изображение (меньше затраты памяти). Если установлен бит @code{MGL_DRAW_DOTS=0x8}, то рисуются точки вместо примитивов (очень быстро).
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglGraph}} @code{int} GetQuality ()
++@deftypefnx {Функция С} @code{void} mgl_get_quality (@code{HMGL} gr)
++Возвращает качество графика: @code{MGL_DRAW_WIRE=0} -- нет рисования граней (наиболее быстрый), @code{MGL_DRAW_FAST=1} -- нет интерполяции цвета (быстрый), @code{MGL_DRAW_NORM=2} -- высокое качество (нормальный), @code{MGL_DRAW_HIGH=3} -- высокое качество с рисованием 3d примитивов (стрелок и маркеров). Если установлен бит @code{MGL_DRAW_LMEM=0x4}, то происходит прямое рисование в растровое изображение (меньше затраты памяти). Если установлен бит @code{MGL_DRAW_DOTS=0x8}, то рисуются точки вместо примитивов (очень быстро).
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} StartGroup (const char *name)
++@deftypefnx {Функция С} @code{void} mgl_start_group (@code{HMGL} gr, @code{const char *}name)
++Начинает определение группы. Группа может содержать объекты и другие группы. Они используются для выбора части модели при приближении, изменении прозрачности и т.д.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} EndGroup ()
++@deftypefnx {Функция С} @code{void} mgl_end_group (@code{HMGL} gr)
++Завершает определение группы.
++@end deftypefn
++@end ifclear
++
++@menu
++* Export to file::
++* Frames/Animation::
++* Bitmap in memory::
++* Parallelization::
++@end menu
++
++@c ==================================================================
++@external{}
++@node Export to file, Frames/Animation, , Export picture
++@subsection Экспорт в файл
++@nav{}
++@cindex Write
++@ifclear UDAV
++@cindex WriteFrame
++@cindex WritePNG
++@cindex WriteGIF
++@c @cindex WriteIDTF
++@cindex WriteSVG
++@cindex WriteBMP
++@cindex WriteEPS
++@cindex WriteBPS
++@cindex WriteTGA
++@cindex WriteTEX
++@cindex WritePRC
++@cindex WriteOBJ
++@cindex WriteWGL
++@cindex WriteJPEG
++@cindex ShowImage
++@end ifclear
++
++Эти функции экспортируют текущую картинку (кадр) в файл. Имя файла @var{fname} должно иметь соответствующее расширение. Параметр @var{descr} дает краткое описание картинки. Пока прозрачность поддерживается только для форматов PNG, SVG, OBJ и PRC.
++
++@anchor{write}
++@deftypefn {Команда MGL} {} write ['fname'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} WriteFrame (@code{const char *}fname=@code{""}, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_frame (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++@end ifclear
++Экспортирует текущий кадр в файл @var{fname} с типом, определяемым по расширению. Параметр @var{descr} добавляет описание (может быть пустым). Если @var{fname} пустой, то используется имя @samp{frame####.jpg}, где @samp{####} -- текущий номер кадра и имя @samp{frame} определяется переменной @ref{plotid}.
++@end deftypefn
++
++@anchor{bbox}
++@deftypefn {Команда MGL} {} bbox x1 y1 [x2=@code{-1} y2=@code{-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetBBox (@code{int} x1=@code{0}, @code{int} y1=@code{0}, @code{int} x2=@code{-1}, @code{int} y2=@code{-1})
++@deftypefnx {Функция С} @code{void} mgl_set_bbox (@code{HMGL} gr, @code{int} x1, @code{int} y1, @code{int} x2, @code{int} y2)
++@end ifclear
++Задает область изображения, которая будет сохранена в файл 2D формата. Если @var{x2}<0 (@var{y2}<0), то исходная ширина (высота) рисунка будет использована. Если @var{x1}<0 или @var{y1}<0 или @var{x1}>=@var{x2}|Width или @var{y1}>=@var{y2}|Height, то обрезания рисунка не будет.
++@end deftypefn
++
++@ifclear UDAV
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WritePNG (@code{const char *}fname, @code{const char *}descr=@code{""}, @code{int} compr=@code{""}, @code{bool} alpha=@code{true})
++@deftypefnx {Функция С} @code{void} mgl_write_png (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++@deftypefnx {Функция С} @code{void} mgl_write_png_solid (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует текущий кадр в PNG файл. Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла, @var{alpha} -- прозрачность фона. Если при компиляции MathGL не был определен флаг HAVE_PNG, то экспорт в файл не производится.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteJPEG (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_jpg (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует текущий кадр в JPEG файл. Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла. Если при компиляции MathGL не был определен флаг HAVE_JPEG, то экспорт в файл не производится.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteGIF (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_gif (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует текущий кадр в GIF файл. Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла. Если при компиляции MathGL не был определен флаг HAVE_GIF, то экспорт в файл не производится.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteBMP (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_bmp (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует текущий кадр в BMP файл. Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteTGA (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_tga (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует текущий кадр в TGA файл. Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteEPS (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_eps (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует текущий кадр в EPS файл, используя векторное представление графика. Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла. Если имя файла оканчивается на @samp{z} (например, @samp{fname.eps.gz}), то файл автоматически архивируется в формате gzip. Отмечу, что формат EPS не поддерживает интерполяцию цвета, и картинка будет выглядеть как при использовании @ref{quality}=1.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteBPS (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_eps (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует текущий кадр в EPS файл, используя растровое представление графика. Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла. Если имя файла оканчивается на @samp{z} (например, @samp{fname.eps.gz}), то файл автоматически архивируется в формате gzip.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteSVG (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_svg (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует текущий кадр в SVG файл, используя векторное представление графика. Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла. Если имя файла оканчивается на @samp{z} (например, @samp{fname.svgz}), то файл автоматически архивируется в формате gzip. Отмечу, что формат SVG не поддерживает интерполяцию цвета, и картинка будет выглядеть как при использовании @ref{quality}=1.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteTEX (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_tex (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует текущий кадр в LaTeX файл (пакет Tikz/PGF), используя векторное представление графика. Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла. Отмечу, что сейчас отсутствует изменение размера текста (например, в subplot), что может приводить к неправильному положению надписей.
++@end deftypefn
++
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WritePRC (@code{const char *}fname, @code{const char *}descr=@code{""}, @code{bool} make_pdf=@code{true})
++@deftypefnx {Функция С} @code{void} mgl_write_prc (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr, @code{int} make_pdf)
++Экспортирует текущий кадр в PRC файл, используя векторное представление графика (см. @url{http://en.wikipedia.org/wiki/PRC_%28file_format%29}). Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла. Если параметр @var{make_pdf}=@code{true} и PDF был выбран при конфигурировании MathGL, то также создается соответствующий PDF файл с 3D изображением.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteOBJ (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_obj (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует текущий кадр в OBJ/MTL файл, используя векторное представление графика (см. @url{http://en.wikipedia.org/wiki/Wavefront_.obj_file, OBJ формат}). Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла.
++@end deftypefn
++
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteXYZ (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_xyz (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует текущий кадр в XYZ/XYZL/XYZF файлы, используя векторное представление графика (см. @url{http://people.sc.fsu.edu/~jburkardt/data/xyz/xyz.html, XYZ формат}). Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteSTL (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_stl (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует текущий кадр в STL файл, используя векторное представление графика (см. @url{http://en.wikipedia.org/wiki/STL_(file_format), STL формат}). Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteOFF (@code{const char *}fname, @code{const char *}descr=@code{""}, @code{bool} colored=@code{false})
++@deftypefnx {Функция С} @code{void} mgl_write_off (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr, @code{bool} colored)
++Экспортирует текущий кадр в OFF файл, используя векторное представление графика (см. @url{http://people.sc.fsu.edu/~jburkardt/data/off/off.html, OFF формат}). Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла.
++@end deftypefn
++
++@c @deftypefn {Метод класса @code{mglGraph}} @code{void} WriteX3D (@code{const char *}fname, @code{const char *}descr=@code{""})
++@c @deftypefnx {Функция С} @code{void} mgl_write_x3d (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++@c Экспортирует текущий кадр в X3D файл, используя векторное представление графика (см. @url{http://en.wikipedia.org/wiki/X3d, X3D формат}). Вследствие чего не рекомендуется сохранять большие графики (поверхности, а особенно поверхности уровня) из-за большого размера файла. Хотя никаких внутренних ограничений на размер выходного файла нет. Для них лучше использовать растровый формат (например, PNG или JPEG). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла.
++@c @end deftypefn
++
++
++@c @deftypefn {Метод класса @code{mglGraph}} @code{void} WriteIDTF (@code{const char *}fname, @code{const char *}descr=@code{""})
++@c @deftypefnx {Функция С} @code{void} mgl_write_idtf (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++@c Экспортирует текущий кадр в IDTF файл, используя векторное представление графика (класс mglGraphIDTF). Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла.
++@c @end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} ShowImage (@code{const char *}viewer, @code{bool} nowait=@code{false})
++@deftypefnx {Функция С} @code{void} mgl_show_image (@code{const char *}viewer, @code{int} nowait)
++Отображает текущий кадр используя внешнюю программу просмотра @var{viewer}. Функция сохраняет картинку во временный файл и вызывает @var{viewer} для его отображения. Если @var{nowait}=@code{true}, то функция возвращает управление немедленно -- не ждет пока окно просмотра будет закрыто.
++@end deftypefn
++
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} WriteJSON (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_write_json (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует точки и примитивы в текстовый файл используя @ref{JSON format}. В дальнейшем этот файл можно загрузить и просмотреть в JavaScript скрипте. Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} ExportMGLD (@code{const char *}fname, @code{const char *}descr=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_export_mgld (@code{HMGL} gr, @code{const char *}fname, @code{const char *}descr)
++Экспортирует точки и примитивы в файл @ref{MGLD format}. В дальнейшем этот файл можно загрузить и просмотреть с помощью @code{mglview}. Параметры функции следующие: @var{fname} -- имя файла, @var{descr} -- описание файла.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} ImportMGLD (@code{const char *}fname, @code{bool} add=@code{false})
++@deftypefnx {Функция С} @code{void} mgl_import_mgld (@code{HMGL} gr, @code{const char *}fname, @code{int} add)
++Импортирует точки и примитивы из файла в @ref{MGLD format}. Параметры функции следующие: @var{fname} -- имя файла, @var{add} -- флаг добавления или замены существующих точек и примитивов.
++@end deftypefn
++
++@end ifclear
++
++
++@c ##################################################################
++@external{}
++@node Frames/Animation, Bitmap in memory, Export to file, Export picture
++@subsection Кадры/Анимация
++@nav{}
++
++@ifset UDAV
++В MGL нет специальных команд для создания анимации. Однако можно воспользоваться возможностями утилит @code{mglconv} и @code{mglview}. Например, используя комментарии спеиального вида @samp{##a } или @samp{##c }.
++@end ifset
++
++@ifclear UDAV
++@cindex NewFrame
++@cindex EndFrame
++@cindex GetNumFrame
++@cindex ResetFrames
++@cindex StartGIF
++@cindex CloseGIF
++
++Эти функции позволяют создавать несколько картинок одновременно. В большинстве случаев это бесполезно, но для органов управления (см. @ref{Widget classes}) это позволяет показывать анимацию. Также можно записать несколько кадров в анимированный GIF файл.
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} NewFrame ()
++@deftypefnx {Функция С} @code{void} mgl_new_frame (@code{HMGL} gr)
++Создает новый кадр. Функция возвращает номер текущего кадра. В режиме OpenGL функция не должны вызываться в параллельных потоках! -- используйте прямое создание списка. Функция @code{EndFrame()} @strong{должна} быть вызвана после рисования кадра для каждого вызова этой функции.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} EndFrame ()
++@deftypefnx {Функция С} @code{void} mgl_end_frame (@code{HMGL} gr)
++Завершает рисование кадра.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{int} GetNumFrame ()
++@deftypefnx {Функция С} @code{int} mgl_get_num_frame (@code{HMGL} gr)
++Возвращает число созданных кадров.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} GetFrame (@code{int} i)
++@deftypefnx {Функция С} @code{void} mgl_get_frame (@code{HMGL} gr, @code{int} i)
++Завершает рисование кадра и сохраняет объекты рисования в кадр с номером @var{i}, который должен быть в диапазоне [0, @code{GetNumFrame()}-1]. Функция аналогична @code{EndFrame()}, но не добавляет кадр в GIF изображение.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} GetFrame (@code{int} i)
++@deftypefnx {Функция С} @code{void} mgl_get_frame (@code{HMGL} gr, @code{int} i)
++Заменяет объекты рисования на объекты из кадра с номером @var{i}. Функция работает если установлен флаг @code{MGL_VECT_FRAME} (по умолчанию).
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} ShowFrame (@code{int} i)
++@deftypefnx {Функция С} @code{void} mgl_show_frame (@code{HMGL} gr, @code{int} i)
++Добавляет объекты рисования из кадра с номером @var{i} к уже существующим. Функция работает если установлен флаг @code{MGL_VECT_FRAME} (по умолчанию).
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} DelFrame (@code{int} i)
++@deftypefnx {Функция С} @code{void} mgl_del_frame (@code{HMGL} gr, @code{int} i)
++Удаляет объекты рисования для кадра с номером @var{i} и сдвигает нумерацию всех последующих кадров. Функция работает если установлен флаг @code{MGL_VECT_FRAME} (по умолчанию).
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} ResetFrames ()
++@deftypefnx {Функция С} @code{void} mgl_reset_frames (@code{HMGL} gr)
++Сбрасывает счетчик кадров в 0.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} ClearFrame (@code{int} i)
++@deftypefnx {Функция С} @code{void} mgl_clear_frame (@code{HMGL} gr, @code{int} i)
++Очищает текущий список объектов.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} StartGIF (@code{const char *}fname, @code{int} ms=@code{100})
++@deftypefnx {Функция С} @code{void} mgl_start_gif (@code{HMGL} gr, @code{const char *}fname, @code{int} ms)
++Начинает запись кадров в анимированный GIF файл @var{fname}. Параметр @var{ms} задает задержку между кадрами в миллисекундах. Вы @strong{не должны} менять размер рисунка во время создания кино. Используйте CloseGIF() для завершения записи. Эта функция не работает в режиме OpenGL.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} CloseGIF ()
++@deftypefnx {Функция С} @code{void} mgl_close_gif (@code{HMGL} gr)
++Завершает запись анимированного GIF файла.
++@end deftypefn
++@end ifclear
++
++@c ------------------------------------------------------------------
++@external{}
++@node Bitmap in memory, Parallelization, Frames/Animation, Export picture
++@subsection Рисование в памяти
++@nav{}
++
++@ifclear UDAV
++Эти функции возвращают созданный растровый рисунок, его ширину и высоту. В дальнейшем его можно использовать в любой графической библиотеке (см. также, @ref{Widget classes}) или сохранить в файл (см. также, @ref{Export to file}).
++
++@deftypefn {Метод класса @code{mglGraph}} @code{const unsigned char *} GetRGB ()
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} GetRGB (@code{char *}buf, @code{int} size)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} GetBGRN (@code{char *}buf, @code{int} size)
++@deftypefnx {Функция С} @code{const unsigned char *} mgl_get_rgb (@code{HMGL} gr)
++Возвращает растровое изображение в формате RGB для текущего кадра. Формат каждого элемента (пикселя): @{red, green, blue@}. Число элементов Width*Height. Положение элемента @{i,j@} есть [3*i + 3*Width*j] (или [4*i + 4*Width*j] для @code{GetBGRN()}). В Python вы должны предоставить буфер @var{buf} достаточного размера @var{size}, т.е. код должен выглядеть следующим образом (для Python)
++@verbatim
++from mathgl import *
++gr = mglGraph();
++bits='\t';
++bits=bits.expandtabs(4*gr.GetWidth()*gr.GetHeight());
++gr.GetBGRN(bits, len(bits));
++@end verbatim
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{const unsigned char *} GetRGBA ()
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} GetRGBA (@code{char *}buf, @code{int} size)
++@deftypefnx {Функция С} @code{const unsigned char *} mgl_get_rgba (@code{HMGL} gr)
++Возвращает растровое изображение в формате RGBA для текущего кадра. Формат каждого элемента (пикселя): @{red, green, blue, alpha@}. Число элементов Width*Height. Положение элемента @{i,j@} есть [4*i + 4*Width*j].
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{int} GetWidth ()
++@deftypefnx {Метод класса @code{mglGraph}} @code{int} GetHeight ()
++@deftypefnx {Функция С} @code{int} mgl_get_width (@code{HMGL} gr)
++@deftypefnx {Функция С} @code{int} mgl_get_height (@code{HMGL} gr)
++Возвращает ширину и высоту изображения.
++@end deftypefn
++
++
++@deftypefn {Метод класса @code{mglGraph}} @code{mglPoint} CalcXYZ (@code{int} xs, @code{int} ys)
++@deftypefnx {Функция С} @code{void} mgl_calc_xyz (@code{HMGL} gr, @code{int} xs, @code{int} ys, @code{mreal *}x, @code{mreal *}y, @code{mreal *}z)
++Вычисляет 3D координаты @{x,y,z@} для экранной точки @{xs,ys@}. В данный момент игнорируется перспектива графика и формулы перехода в криволинейные координаты. Вычисления производятся для последнего использованного InPlot (см. @ref{Subplots and rotation}).
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{mglPoint} CalcScr (@code{mglPoint} p)
++@deftypefnx {Функция С} @code{void} mgl_calc_scr (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{int *}xs, @code{int *}ys)
++Вычисляет экранные координаты @{xs,ys@} для 3D координат @{x,y,z@}. Вычисления производятся для последнего использованного InPlot (см. @ref{Subplots and rotation}).
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} SetObjId (@code{int} id)
++@deftypefnx {Функция С} @code{void} mgl_set_obj_id (@code{HMGL} gr, @code{int} id)
++Задает числовой идентификатор для объектов или subplot/inplot.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{int} GetObjId (@code{int} xs, @code{int} ys)
++@deftypefnx {Функция С} @code{int} mgl_get_obj_id (@code{HMGL} gr, @code{int} xs, @code{int} ys)
++Возвращает числовой идентификатор верхнего объекта в точке @{xs, ys@} рисунка.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{int} GetSplId (@code{int} xs, @code{int} ys)
++@deftypefnx {Функция С} @code{int} mgl_get_spl_id (@code{HMGL} gr, @code{int} xs, @code{int} ys)
++Возвращает числовой идентификатор верхнего "подграфика" в точке @{xs, ys@} рисунка.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{void} Highlight (@code{int} id)
++@deftypefnx {Функция С} @code{void} mgl_highlight (@code{HMGL} gr, @code{int} id)
++Выделяет объект с заданным @var{id}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{long} IsActive (@code{int} xs, @code{int} ys, @code{int} d=@code{1})
++@deftypefnx {Функция С} @code{long} mgl_is_active (@code{HMGL} gr, @code{int} xs, @code{int} ys, @code{int} d)
++Проверяет близка ли точка @{@var{xs}, @var{ys}@} к активной точке (т.е. mglBase::Act) с точностью @var{d} и возвращает индекс активной точки или @code{-1} если не найдено. Активные точки -- специальные точки, которые характеризуют примитивы (например, вершины). Это функция только для опытных пользователей.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{long} SetDrawReg (@code{int} nx=@code{1}, @code{int} ny=@code{1}, @code{int} m=@code{0})
++@deftypefnx {Функция С} @code{long} mgl_set_draw_reg (@code{HMGL} gr, @code{int} nx, @code{int} ny, @code{int} m)
++Ограничивает рисование прямоугольной областью @var{m}-ой клетки матрицы размером @var{nx}*@var{ny} (аналогично @ref{subplot}). Функция может бытб использована для ускорения вывода путем уменьшения выводимых примитивов. Это функция только для опытных пользователей.
++@end deftypefn
++
++@end ifclear
++
++@c ------------------------------------------------------------------
++@external{}
++@node Parallelization, , Bitmap in memory, Export picture
++@subsection Распараллеливание
++@nav{}
++
++@ifclear UDAV
++@cindex Combine
++@cindex MPI_Send
++@cindex MPI_Recv
++
++Многие функции MathGL используют несколько потоков для ускорения работы (если MathGL была собрана с поддержкой pthread). При этом можно настраивать число используемых потоков.
++
++@deftypefn {Функция С} @code{int} mgl_set_num_thr (@code{int} n)
++Задает число потоков, которое будет использовано в MathGL. При @var{n}<1 число потоков задается как максимальное число процессоров (ядер) в системе. При @var{n}=1 не используется распараллеливание.
++@end deftypefn
++
++Другая возможность -- комбинирование изображений из разных объектов @code{mglGraph}. Эти методы наиболее подходят для компьютерных кластеров, когда данные настолько велики, что не могут поместиться в памяти отдельного компьютера.
++
++@deftypefn {Метод класса @code{mglGraph}} @code{int} Combine (@code{const mglGraph *}g)
++@deftypefnx {Функция С} @code{int} mgl_combine_gr (@code{HMGL} gr, @code{HMGL} g)
++Комбинирует (добавляет) рисунок из @var{g} с @var{gr}, принимая во внимание ``высоту'' пикселей. Ширина и высота обоих рисунков должна быть одинаковы.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{int} MPI_Send (@code{int} id)
++@deftypefnx {Функция С} @code{int} mgl_mpi_send (@code{HMGL} gr, @code{int} id)
++Посылает рисунок из компьютера (ноды) @var{id}, используя MPI. Ширина и высота обоих рисунков должна быть одинаковы.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{int} MPI_Recv (@code{int} id)
++@deftypefnx {Функция С} @code{int} mgl_mpi_send (@code{HMGL} gr, @code{int} id)
++Принимает рисунок из компьютера (ноды) @var{id}, используя MPI. Ширина и высота обоих рисунков должна быть одинаковы.
++@end deftypefn
++@end ifclear
++
++
++@c ##################################################################
++@external{}
++@node Background, Primitives, Export picture, MathGL core
++@section Фоновое изображение
++@nav{}
++@cindex LoadBackground
++@cindex Clf
++@cindex Rasterize
++
++These functions change background image.
++
++@anchor{clf}
++@deftypefn {Команда MGL} {} clf ['col']
++@deftypefnx {Команда MGL} {} clf r g b
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf ()
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf (@code{const char *} col)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf (@code{char} col)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Clf (@code{mreal} r, @code{mreal} g, @code{mreal} b)
++@deftypefnx {Функция С} @code{void} mgl_clf (@code{HMGL} gr)
++@deftypefnx {Функция С} @code{void} mgl_clf_str (@code{HMGL} gr, @code{const char *} col)
++@deftypefnx {Функция С} @code{void} mgl_clf_chr (@code{HMGL} gr, @code{char} col)
++@deftypefnx {Функция С} @code{void} mgl_clf_rgb (@code{HMGL} gr, @code{mreal} r, @code{mreal} g, @code{mreal} b)
++@end ifclear
++Очищает рисунок и заполняет фон заданным цветом.
++@end deftypefn
++
++@anchor{rasterize}
++@deftypefn {Команда MGL} {} rasterize
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Rasterize ()
++@deftypefnx {Функция С} @code{void} mgl_rasterize (@code{HMGL} gr)
++@end ifclear
++Завершает рисование графика и помещает результат в качестве фона. После этого, очищает список примитивов (как @ref{clf}). Функция полезна для сохранения части графика (например, поверхностей или векторных полей) в растровом виде, а другой части (кривых, осей и пр.) в векторном.
++@end deftypefn
++
++@anchor{background}
++@deftypefn {Команда MGL} {} background 'fname' [@code{alpha=1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} LoadBackground (@code{const char *} fname, @code{double} alpha=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_load_background (@code{HMGL} gr, @code{const char *} fname, @code{double} alpha)
++@end ifclear
++Загружает PNG или JPEG файл @var{fname} в качестве фона для графика. Параметр @var{alpha} задает прозрачность фона вручную.
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node Primitives, Text printing, Export picture, MathGL core
++@section Рисование примитивов
++@nav{}
++@cindex Ball
++@cindex Line
++@cindex Curve
++@cindex Glyph
++@cindex Face
++@cindex FaceX
++@cindex FaceY
++@cindex FaceZ
++@cindex Cone
++@cindex Drop
++@cindex Sphere
++
++@ifclear UDAV
++@cindex Mark
++@cindex Error
++@end ifclear
++
++Эти функции рисуют рисуют простые объекты типа линий, точек, сфер, капель, конусов, и т.д.
++
++@anchor{ball}
++@deftypefn {Команда MGL} {} ball @code{x y} ['col'='r.']
++@deftypefnx {Команда MGL} {} ball @code{x y z} ['col'='r.']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Ball (@code{mglPoint} p, @code{char} col=@code{'r'})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Mark (@code{mglPoint} p, @code{const char *}mark)
++@deftypefnx {Функция С} @code{void} mgl_mark (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{const char *}mark)
++@end ifclear
++Рисует маркер (точку по умолчанию) с координатами @var{p}=@{@var{x}, @var{y}, @var{z}@} и цветом @var{col}.
++@end deftypefn
++
++@anchor{errbox}
++@deftypefn {Команда MGL} {} errbox @code{x y ex ey} ['stl'='']
++@deftypefnx {Команда MGL} {} errbox @code{x y z ex ey ez} ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Error (@code{mglPoint} p, @code{mglPoint} e, @code{char} *stl=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_error_box (@code{HMGL} gr, @code{mreal} px, @code{mreal} py, @code{mreal} pz, @code{mreal} ex, @code{mreal} ey, @code{mreal} ez, @code{char *}stl)
++@end ifclear
++Рисует 3d error box в точке @var{p}=@{@var{x}, @var{y}, @var{z}@} размером @var{e}=@{@var{ex}, @var{ey}, @var{ez}@} и стилем @var{stl}. Используйте NAN в компонентах @var{e} для уменьшения рисуемых элементов.
++@end deftypefn
++
++@anchor{line}
++@deftypefn {Команда MGL} {} line @code{x1 y1 x2 y2} ['stl'='']
++@deftypefnx {Команда MGL} {} line @code{x1 y1 z1 x2 y2 z2} ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Line (@code{mglPoint} p1, @code{mglPoint} p2, @code{char *}stl=@code{"B"}, @code{int}num=@code{2})
++@deftypefnx {Функция С} @code{void} mgl_line (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{char *}stl, @code{int}num)
++@end ifclear
++Рисует геодезическую линию (декартовых координатах -- прямую) из точки @var{p1} в @var{p2} использую стиль линии @var{stl}. Параметр @var{num} определяет гладкость линии (число точек на линии). Если @var{num}=@code{2}, то рисуется прямая даже в криволинейных координатах (см. @ref{Curved coordinates}). Наоборот, для больших значений (например, =@code{100}) рисуется геодезическая линия (окружность в полярных координатах, парабола в параболических и т.д.). Линия рисуется даже если часть ее лежит вне диапазона осей координат.
++@end deftypefn
++
++@anchor{curve}
++@deftypefn {Команда MGL} {} curve @code{x1 y1 dx1 dy1 x2 y2 dx2 dy2} ['stl'='']
++@deftypefnx {Команда MGL} {} curve @code{x1 y1 z1 dx1 dy1 dz1 x2 y2 z2 dx2 dy2 dz2} ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Curve (@code{mglPoint} p1, @code{mglPoint} d1, @code{mglPoint} p2, @code{mglPoint} d2, @code{const char *}stl=@code{"B"}, @code{int} num=@code{100})
++@deftypefnx {Функция С} @code{void} mgl_curve (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} dx1, @code{mreal} dy1, @code{mreal} dz1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{mreal} dx2, @code{mreal} dy2, @code{mreal} dz2, @code{const char *}stl, @code{int} num)
++@end ifclear
++Рисует кривую Безье из точки @var{p1} в @var{p2} используя стиль линии @var{stl}. Касательные в точках пропорциональны @var{d1}, @var{d2}. Параметр @var{num} определяет гладкость линии (число точек на линии). Если @var{num}=@code{2}, то рисуется прямая даже в криволинейных координатах (см. @ref{Curved coordinates}). Наоборот, для больших значений (например, =@code{100}) рисуется геодезическая линия (окружность в полярных координатах, парабола в параболических и т.д.). Кривая рисуется даже если часть ее лежит вне диапазона осей координат.
++@end deftypefn
++
++@anchor{face}
++@deftypefn {Команда MGL} {} face @code{x1 y1 x2 y2 x3 y3 x4 y4} ['stl'='']
++@deftypefnx {Команда MGL} {} face @code{x1 y1 z1 x2 y2 z2 x3 y3 z3 x4 y4 z4} ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Face (@code{mglPoint} p1, @code{mglPoint} p2, @code{mglPoint} p3, @code{mglPoint} p4, @code{const char *}stl=@code{"w"})
++@deftypefnx {Функция С} @code{void} mgl_face (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{mreal} x3, @code{mreal} y3, @code{mreal} z3, @code{mreal} x4, @code{mreal} y4, @code{mreal} z4, @code{const char *}stl)
++@end ifclear
++Рисует заполненный четырехугольник (грань) с углами в точках @var{p1}, @var{p2}, @var{p3}, @var{p4} и цветом(-ами) @var{stl}. При этом цвет может быть один для всей грани, или различным если указаны все 4 цвета. Грань будет нарисована даже если часть ее лежит вне диапазона осей координат.
++@end deftypefn
++
++@anchor{rect}
++@deftypefn {Команда MGL} {} rect @code{x1 y1 x2 y2} ['stl'='']
++@deftypefnx {Команда MGL} {} rect @code{x1 y1 z1 x2 y2 z2} ['stl'='']
++Рисует закрашенный прямоугольник (грань) с вершинами @{@var{x1}, @var{y1}, @var{z1}@} и @{@var{x2}, @var{y2}, @var{z2}@} цветом @var{stl}. При этом цвет может быть один для всей грани, или различным для разных вершин если указаны все 4 цвета. Грань будет нарисована даже если часть ее лежит вне диапазона осей координат.
++@end deftypefn
++
++@anchor{facex}
++@anchor{facey}
++@anchor{facez}
++@deftypefn {Команда MGL} {} facex @code{x0 y0 z0 wy wz} ['stl'='' @code{d1=0 d2=0}]
++@deftypefnx {Команда MGL} {} facey @code{x0 y0 z0 wx wz} ['stl'='' @code{d1=0 d2=0}]
++@deftypefnx {Команда MGL} {} facez @code{x0 y0 z0 wx wy} ['stl'='' @code{d1=0 d2=0}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} FaceX (@code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} wy, @code{mreal} wz, @code{const char *}stl=@code{"w"}, @code{mreal} d1=@code{0}, @code{mreal} d2=@code{0})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} FaceY (@code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} wx, @code{mreal} wz, @code{const char *}stl=@code{"w"}, @code{mreal} d1=@code{0}, @code{mreal} d2=@code{0})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} FaceZ (@code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} wx, @code{mreal} wy, @code{const char *}stl=@code{"w"}, @code{mreal} d1=@code{0}, @code{mreal} d2=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_facex (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} wy, @code{mreal} wz, @code{const char *}stl, @code{mreal} d1, @code{mreal} d2)
++@deftypefnx {Функция С} @code{void} mgl_facey (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} wx, @code{mreal} wz, @code{const char *}stl, @code{mreal} d1, @code{mreal} d2)
++@deftypefnx {Функция С} @code{void} mgl_facez (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} wx, @code{mreal} wy, @code{const char *}stl, @code{mreal} d1, @code{mreal} d2)
++@end ifclear
++Рисует закрашенный прямоугольник (грань) перпендикулярно оси [x,y,z] в точке @{@var{x0}, @var{y0}, @var{z0}@} цветом @var{stl} и шириной @var{wx}, @var{wy}, @var{wz} вдоль соответствующего направления. При этом цвет может быть один для всей грани, или различным для разных вершин если указаны все 4 цвета. Параметры @var{d1}!=0, @var{d2}!=0 задают дополнительный сдвиг последней точки (т.е. рисуют четырехугольник). Грань будет нарисована даже если часть ее лежит вне диапазона осей координат.
++@end deftypefn
++
++@anchor{sphere}
++@deftypefn {Команда MGL} {} sphere @code{x0 y0 r} ['col'='r']
++@deftypefnx {Команда MGL} {} sphere @code{x0 y0 z0 r} ['col'='r']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Sphere (@code{mglPoint} p, @code{mreal} r, @code{const char *}stl=@code{"r"})
++@deftypefnx {Функция С} @code{void} mgl_sphere (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} r, @code{const char *}stl)
++@end ifclear
++Рисует сферу радиуса @var{r} с центром в точке @var{p}=@{@var{x0}, @var{y0}, @var{z0}@} цветом @var{stl}.
++@end deftypefn
++
++@anchor{drop}
++@deftypefn {Команда MGL} {} drop @code{x0 y0 dx dy r} ['col'='r' @code{sh=1 asp=1}]
++@deftypefnx {Команда MGL} {} drop @code{x0 y0 z0 dx dy dz r} ['col'='r' @code{sh=1 asp=1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Drop (@code{mglPoint} p, @code{mglPoint} d, @code{mreal} r, @code{const char *}col=@code{"r"}, @code{mreal} shift=@code{1}, @code{mreal} ap=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_drop (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{mreal} r, @code{const char *}col, @code{mreal} shift, @code{mreal} ap)
++@end ifclear
++Рисует каплю радиуса @var{r} в точке @var{p} вытянутую вдоль направления @var{d} цветом @var{col}. Параметр @var{shift} определяет степень вытянутости: @samp{0} -- сфера, @samp{1} -- классическая капля. Параметр @var{ap} определяет относительную ширину капли (аналог "эллиптичности" для сферы).
++@end deftypefn
++
++@anchor{cone}
++@deftypefn {Команда MGL} {} cone @code{x1 y1 z1 x2 y2 z2 r1} [@code{r2=-1} 'stl'='' @code{edge=off}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cone (@code{mglPoint} p1, @code{mglPoint} p2, @code{mreal} r1, @code{mreal} r2=@code{-1}, @code{const char *}stl=@code{"B"}, @code{bool} edge=@code{false})
++@deftypefnx {Функция С} @code{void} mgl_cone (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{mreal} r1, @code{mreal} r2, @code{const char *}stl, @code{int} draw_edge)
++@end ifclear
++Рисует трубу (или усеченный конус если @var{edge}=@code{false}) между точками @var{p1}, @var{p2} с радиусами на концах @var{r1}, @var{r2}. Если @var{r2}<0, то полагается @var{r2}=@var{r1}. Цвет конуса задается строкой @var{stl}. Параметр @var{stl} может содержать:
++@itemize @bullet
++@item
++@samp{@@} для рисования торцов;
++@item
++@samp{#} для сетчатой фигуры;
++@item
++@samp{t} для рисования цилиндра вместо конуса/призмы;
++@item
++@samp{4}, @samp{6}, @samp{8} для рисования квадратной, шестиугольной или восьмиугольной призмы вместо конуса.
++@end itemize
++
++@end deftypefn
++
++@anchor{circle}
++@deftypefn {Команда MGL} {} circle @code{x0 y0 r} ['col'='r']
++@deftypefnx {Команда MGL} {} circle @code{x0 y0 z0 r} ['col'='r']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Circle (@code{mglPoint} p, @code{mreal} r, @code{const char *}stl=@code{"r"})
++@end ifclear
++Рисует круг радиуса @var{r} с центром в точке @var{p}=@{@var{x0}, @var{y0}, @var{z0}@} цветом @var{stl}. Если @var{col} содержит: @samp{#} то рисуется только граница, @samp{@@} то рисуется граница (вторым цветом из @var{col} или черными).
++@end deftypefn
++
++@anchor{ellipse}
++@deftypefn {Команда MGL} {} ellipse @code{x1 y1 x2 y2 r} ['col'='r']
++@deftypefnx {Команда MGL} {} ellipse @code{x1 y1 z1 x2 y2 z2 r} ['col'='r']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Ellipse (@code{mglPoint} p1, @code{mglPoint} p2, @code{mreal} r, @code{const char *}col=@code{"r"})
++@deftypefnx {Функция С} @code{void} mgl_ellipse (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{mreal} r, @code{const char *}col)
++@end ifclear
++Рисует эллипс радиуса @var{r} с фокусами в точках @var{p1}, @var{p2} цветом @var{stl}. Если @var{col} содержит: @samp{#} то рисуется только граница, @samp{@@} то рисуется граница (вторым цветом из @var{col} или черными).
++@end deftypefn
++
++@anchor{rhomb}
++@deftypefn {Команда MGL} {} rhomb @code{x1 y1 x2 y2 r} ['col'='r']
++@deftypefnx {Команда MGL} {} rhomb @code{x1 y1 z1 x2 y2 z2 r} ['col'='r']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Rhomb (@code{mglPoint} p1, @code{mglPoint} p2, @code{mreal} r, @code{const char *}col=@code{"r"})
++@deftypefnx {Функция С} @code{void} mgl_rhomb (@code{HMGL} gr, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} x2, @code{mreal} y2, @code{mreal} z2, @code{mreal} r, @code{const char *}col)
++@end ifclear
++Рисует ромб ширины @var{r} с вершинами в точках @var{p1}, @var{p2} цветом @var{stl}. Если @var{col} содержит: @samp{#} то рисуется только граница, @samp{@@} то рисуется граница (вторым цветом из @var{col} или черными). Если @var{col} содержит 3 цвета, то используется градиентная заливка.
++@end deftypefn
++
++@anchor{arc}
++@deftypefn {Команда MGL} {} arc @code{x0 y0 x1 y1 a} ['col'='r']
++@deftypefnx {Команда MGL} {} arc @code{x0 y0 z0 x1 y1 a} ['col'='r']
++@deftypefnx {Команда MGL} {} arc @code{x0 y0 z0 xa ya za x1 y1 z1 a} ['col'='r']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Arc (@code{mglPoint} p0, @code{mglPoint} p1, @code{mreal} a, @code{const char *}col=@code{"r"})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Arc (@code{mglPoint} p0, @code{mglPoint} pa, @code{mglPoint} p1, @code{mreal} a, @code{const char *}col=@code{"r"})
++@deftypefnx {Функция С} @code{void} mgl_arc (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} x1, @code{mreal} y1, @code{mreal} a, @code{const char *}col)
++@deftypefnx {Функция С} @code{void} mgl_arc_ext (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} xa, @code{mreal} ya, @code{mreal} za, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{mreal} a, @code{const char *}col)
++@end ifclear
++Рисует дугу вокруг оси @var{pa} (по умолчанию вокруг оси z @var{pa}=@{0,0,1@}) с центром в @var{p0}, начиная с точки @var{p1}. Параметр @var{a} задает угол дуги в градусах. Строка @var{col} задает цвет дуги и тип стрелок на краях.
++@end deftypefn
++
++@anchor{polygon}
++@deftypefn {Команда MGL} {} polygon @code{x0 y0 x1 y1 num} ['col'='r']
++@deftypefnx {Команда MGL} {} polygon @code{x0 y0 z0 x1 y1 z1 num} ['col'='r']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Polygon (@code{mglPoint} p0, @code{mglPoint} p1, @code{int} num, @code{const char *}col=@code{"r"})
++@deftypefnx {Функция С} @code{void} mgl_polygon (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} x1, @code{mreal} y1, @code{mreal} z1, @code{int} num, @code{const char *}col)
++@end ifclear
++Рисует правильный @var{num}-угольник с центром в @var{p0} с первой вершиной в @var{p1} цветом @var{col}. Если @var{col} содержит: @samp{#} то рисуется только граница, @samp{@@} то рисуется граница (вторым цветом из @var{col} или черными).
++@c Если @var{col} содержит 3 цвета, то используется градиентная заливка.
++@end deftypefn
++
++@anchor{logo}
++@deftypefn {Команда MGL} {} logo 'fname' [smooth=off]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Logo (@code{const char *}fname, @code{bool} smooth=@code{false}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Logo (@code{long} w, @code{long} h, @code{const unsigned char *}rgba, @code{bool} smooth=@code{false}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_logo (@code{HMGL} gr, @code{long} w, @code{long} h, @code{const unsigned char *}rgba, @code{bool} smooth, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_logo_file (@code{HMGL} gr, @code{const char *}fname, @code{bool} smooth, @code{const char *}opt)
++@end ifclear
++Draw bitmap (logo) along whole axis range, which can be changed by @ref{Command options}. Bitmap can be loaded from file or specified as RGBA values for pixels. Parameter @var{smooth} set to draw bitmap without or with color interpolation.
++@end deftypefn
++
++
++
++@anchor{symbol}
++@deftypefn {Команда MGL} {} symbol @code{x y} 'id' ['fnt'='' @code{size=-1}]
++@deftypefnx {Команда MGL} {} symbol @code{x y z} 'id' ['fnt'='' @code{size=-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Symbol (@code{mglPoint} p, @code{char} id, @code{const char *}fnt=@code{""}, @code{mreal} size=@code{-1})
++@deftypefnx {Функция С} @code{void} mgl_symbol (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{char} id, @code{const char *}fnt, @code{mreal} size)
++@end ifclear
++Рисует определенный пользователем символ с именем @var{id} в точке @var{p} стилем @var{fnt}. Размер задается параметром @var{size} (по умолчанию @code{-1}). Строка @var{fnt} может содержать цвет (до разделителя @samp{:}); стили @samp{a} или @samp{A} для вывода в абсолютной позиции (@{@var{x}, @var{y}@} полагаются в диапазоне [0,1]) относительно рисунка (для @samp{A}) или subplot/inplot (для @samp{a}); и стиль @samp{w} для рисования только контура символа.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} symbol @code{x y dx dy} 'id' ['fnt'=':L' @code{size=-1}]
++@deftypefnx {Команда MGL} {} symbol @code{x y z dx dy dz} 'id' ['fnt'=':L' @code{size=-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Symbol (@code{mglPoint} p, @code{mglPoint} d, @code{char} id, @code{const char *}fnt=@code{""}, @code{mreal} size=@code{-1})
++@deftypefnx {Функция С} @code{void} mgl_symbol_dir (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{const char *}text, @code{const char *}fnt, @code{mreal} size)
++@end ifclear
++Аналогично предыдущему, но символ рисуется в повернутым в направлении @var{d}.
++@end deftypefn
++
++@anchor{addsymbol}
++@deftypefn {Команда MGL} {} addsymbol 'id' xdat ydat
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} DefineSymbol (@code{char} id, @code{const mglDataA &}xdat, @code{const mglDataA &}ydat)
++@deftypefnx {Функция С} @code{void} mgl_define_symbol (@code{HMGL} gr, @code{HCDT} xdat, @code{HCDT} ydat)
++@end ifclear
++Добавляет определенный пользователем символ с именем @var{id} и границей @{@var{xdat}, @var{ydat}@}. Значения @code{NAN} задают разрыв (скачок) граничной кривой.
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node Text printing, Axis and Colorbar, Primitives, MathGL core
++@section Вывод текста
++@nav{}
++@ifclear UDAV
++@cindex Puts
++@cindex Putsw
++@end ifclear
++@cindex Text
++@cindex fgets
++
++Функции для вывода текста позволяют вывести строку текста в произвольном месте рисунка, в произвольном направлении и вдоль произвольной кривой. MathGL позволяет использовать произвольное начертание шрифта и многие ТеХ-ие команды (детальнее см. @ref{Font styles}). Все функции вывода текста имеют варианты для 8-bit строк (@code{char *}) и для Unicode строк (@code{wchar_t *}). В первом случае используется конверсия из текущей локали, т.е. иногда вам требуется явно указать локаль с помощью функции @code{setlocale()}. Аргумент @var{size} определяет размер текста: размер шрифта если положителен или относительный размер (=-@var{size}*@code{SetFontSize()}) если отрицателен. Начертание шрифта (STIX, arial, courier, times и др.) можно изменить с помощью функции LoadFont(). @xref{Font settings}.
++
++Параметры шрифта задаются строкой, которая может содержать символы цвета @samp{wkrgbcymhRGBCYMHW} (см. @ref{Color styles}). Также после символа @samp{:} можно указать символы стиля (@samp{rbiwou}) и/или выравнивания (@samp{LRCTV}). Стили шрифта: @samp{r} -- прямой, @samp{i} -- курсив, @samp{b} -- жирный, @samp{w} -- контурный, @samp{o} -- надчеркнутый, @samp{u} -- подчеркнутый. По умолчанию используется прямой шрифт. Типы выравнивания: @samp{L} -- по левому краю (по умолчанию), @samp{C} -- по центру, @samp{R} -- по правому краю, @samp{T} -- под текстом, @samp{V} -- по центру вертикально. Например, строка @samp{b:iC} соответствует курсиву синего цвета с выравниванием по центру. Начиная с MathGL версии 2.3, вы можете задать цветовой градиент для выводимой строки (см. @ref{Color scheme}).
++
++Если строка содержит символы @samp{aA}, то текст выводится в абсолютных координатах (полагаются в диапазоне [0,1]). При этом используются координаты относительно рисунка (если указано @samp{A}) или относительно последнего subplot/inplot (если указано @samp{a}). Если строка содержит символ @samp{@@}, то вокруг текста рисуется прямоугольник.
++
++@sref{Text features}
++
++@anchor{text}
++@deftypefn {Команда MGL} {} text @code{x y} 'text' ['fnt'='' @code{size=-1}]
++@deftypefnx {Команда MGL} {} text @code{x y z} 'text' ['fnt'='' @code{size=-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Puts (@code{mglPoint} p, @code{const char *}text, @code{const char *}fnt=@code{":C"}, @code{mreal} size=@code{-1})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Putsw (@code{mglPoint} p, @code{const wchar_t *}text, @code{const char *}fnt=@code{":C"}, @code{mreal} size=@code{-1})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Puts (@code{mreal} x, @code{mreal} y, @code{const char *}text, @code{const char *}fnt=@code{":AC"}, @code{mreal} size=@code{-1})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Putsw (@code{mreal} x, @code{mreal} y, @code{const wchar_t *}text, @code{const char *}fnt=@code{":AC"}, @code{mreal} size=@code{-1})
++@deftypefnx {Функция С} @code{void} mgl_puts (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{const char *}text, @code{const char *}fnt, @code{mreal} size)
++@deftypefnx {Функция С} @code{void} mgl_putsw (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{const wchar_t *}text, @code{const char *}fnt, @code{mreal} size)
++@end ifclear
++Выводит строку @var{text} от точки @var{p} шрифтом определяемым строкой @var{fnt}. Размер шрифта задается параметром @var{size} (по умолчанию @code{-1}).
++@end deftypefn
++
++@deftypefn {Команда MGL} {} text @code{x y dx dy} 'text' ['fnt'=':L' @code{size=-1}]
++@deftypefnx {Команда MGL} {} text @code{x y z dx dy dz} 'text' ['fnt'=':L' @code{size=-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Puts (@code{mglPoint} p, @code{mglPoint} d, @code{const char *}text, @code{const char *}fnt=@code{':L'}, @code{mreal} size=@code{-1})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Putsw (@code{mglPoint} p, @code{mglPoint} d, @code{const wchar_t *}text, @code{const char *}fnt=@code{':L'}, @code{mreal} size=@code{-1})
++@deftypefnx {Функция С} @code{void} mgl_puts_dir (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{const char *}text, @code{const char *}fnt, @code{mreal} size)
++@deftypefnx {Функция С} @code{void} mgl_putsw_dir (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal} dx, @code{mreal} dy, @code{mreal} dz, @code{const wchar_t *}text, @code{const char *}fnt, @code{mreal} size)
++@end ifclear
++Выводит строку @var{text} от точки @var{p} вдоль направления @var{d}. Параметр @var{fnt} задает стиль текста и указывает выводить текст под линией (@samp{T}) или над ней (@samp{t}).
++@end deftypefn
++
++@anchor{fgets}
++@deftypefn {Команда MGL} {} fgets @code{x y} 'fname' [@code{n=0} 'fnt'='' @code{size=-1.4}]
++@deftypefnx {Команда MGL} {} fgets @code{x y z} 'fname' [@code{n=0} 'fnt'='' @code{size=-1.4}]
++Выводит @var{n}-ую строку файла @var{fname} от точки @{@var{x},@var{y},@var{z}@} шрифтом @var{fnt} и размером @var{size}. По умолчанию используются параметры заданные командой @ref{font}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} text ydat 'text' ['fnt'='']
++@deftypefnx {Команда MGL} {} text xdat ydat 'text' ['fnt'='' @code{size=-1 zval=nan}]
++@deftypefnx {Команда MGL} {} text xdat ydat zdat 'text' ['fnt'='' @code{size=-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Text (@code{const mglDataA &}y, @code{const char *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Text (@code{const mglDataA &}y, @code{const wchar_t *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Text (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Text (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const wchar_t *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Text (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Text (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const wchar_t *}text, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_text_y (@code{HMGL} gr, @code{HCDT} y, @code{const char *}text, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_textw_y (@code{HMGL} gr, @code{HCDT} y, @code{const wchar_t *}text, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_text_xy (@code{HCDT} x, @code{HCDT} y, @code{const char *}text, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_textw_xy (@code{HCDT} x, @code{HCDT} y, @code{const wchar_t *}text, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_text_xyz (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}text, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_textw_xyz (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const wchar_t *}text, @code{const char *}fnt, @code{const char *}opt)
++@end ifclear
++Выводит строку @var{text} вдоль кривой @{@var{x}[i], @var{y}[i], @var{z}[i]@} шрифтом @var{fnt}. Строка @var{fnt} может содержать символы: @samp{t} для вывода текста под кривой (по умолчанию), или @samp{T} для вывода текста под кривой. Размеры по 1-ой размерности должны быть одинаковы для всех массивов @code{x.nx=y.nx=z.nx}. Если массив @var{x} не указан, то используется "автоматический" массив со значениями в диапазоне осей координат (см. @ref{Ranges (bounding box)}). Если массив @var{z} не указан, то используется минимальное значение оси z. Строка @var{opt} содержит опции команды (см. @ref{Command options}).
++@end deftypefn
++
++@c ##################################################################
++@external{}
++@node Axis and Colorbar, Legend, Text printing, MathGL core
++@section Оси и Colorbar
++@nav{}
++@cindex Axis
++@cindex Box
++@cindex Grid
++@cindex Colorbar
++@cindex Label
++
++Эти функции рисуют объекты для "измерения" типа осей координат, цветовой таблицы (colorbar), сетку по осям, обрамляющий параллелепипед и подписи по осям координат. См. также см. @ref{Axis settings}.
++
++@anchor{axis}
++@deftypefn {Команда MGL} {} axis ['dir'='xyz' 'stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Axis (@code{const char *}dir=@code{"xyz"}, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_axis (@code{HMGL} gr, @code{const char *}dir, @code{const char *}stl, @code{const char *}opt)
++@end ifclear
++Рисует оси координат и метки на них (см. @ref{Axis settings}) в направлениях @samp{xyz}, указанных строкой @var{dir}. Строка @var{dir} может содержать:
++@itemize
++@item @samp{xyz} для рисования соответствующих осей;
++@item @samp{XYZ} для рисования соответствующих осей с метками с другой стороны;
++@item @samp{~} или @samp{_} для осей без подписей;
++@item @samp{U} для невращаемых подписей;
++@item @samp{^} для инвертирования положения по умолчанию;
++@item @samp{!} для отключения улучшения вида меток (см. @ref{tuneticks});
++@item @samp{AKDTVISO} для вывода стрелки на конце оси;
++@item @samp{a} для принудительной автоматической расстановки меток;
++@item @samp{:} для рисования линий через точку (0,0,0);
++@item @samp{f} для вывода чисел в фиксированном формате;
++@item @samp{E} для вывода @samp{E} вместо @samp{e};
++@item @samp{F} для вывода в формате LaTeX;
++@item @samp{+} для вывода @samp{+} для положительных чисел;
++@item @samp{-} для вывода обычного @samp{-};
++@item @samp{0123456789} для задания точности при выводе чисел.
++@end itemize
++Стиль меток и оси(ей) задается строкой @var{stl}. Опция @code{value} задает угол вращения меток оси. @sref{Axis and ticks}
++@end deftypefn
++
++@anchor{colorbar}
++@deftypefn {Команда MGL} {} colorbar ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Colorbar (@code{const char *}sch=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_colorbar (@code{HMGL} gr, @code{const char *}sch)
++@end ifclear
++Рисует полосу соответствия цвета и числовых значений (colorbar) для цветовой схемы @var{sch} (используется текущая для @code{sch=""}) с краю от графика. Строка @var{sch} также может содержать:
++@itemize
++@item @samp{<>^_} для расположения слева, справа, сверху или снизу соответственно;
++@item @samp{I} для расположения около осей (по умолчанию, на краях subplot);
++@item @samp{A} для использования абсолютных координат (относительно рисунка);
++@item @samp{~} для colorbar без подписей;
++@item @samp{!} для отключения улучшения вида меток (см. @ref{tuneticks});
++@item @samp{a} для принудительной автоматической расстановки меток;
++@item @samp{f} для вывода чисел в фиксированном формате;
++@item @samp{E} для вывода @samp{E} вместо @samp{e};
++@item @samp{F} для вывода в формате LaTeX;
++@item @samp{+} для вывода @samp{+} для положительных чисел;
++@item @samp{-} для вывода обычного @samp{-};
++@item @samp{0123456789} для задания точности при выводе чисел.
++@end itemize
++@sref{Colorbars}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} colorbar vdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Colorbar (@code{const mglDataA &}v, @code{const char *}sch=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_colorbar_val (@code{HMGL} gr, @code{HCDT} v, @code{const char *}sch)
++@end ifclear
++Аналогично предыдущему, но для цветовой схемы без сглаживания с заданными значениями @var{v}. @sref{ContD sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} colorbar 'sch' @code{x y [w=1 h=1]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Colorbar (@code{const char *}sch, @code{mreal} x, @code{mreal} y, @code{mreal} w=@code{1}, @code{mreal} h=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_colorbar_ext (@code{HMGL} gr, @code{const char *}sch, @code{mreal} x, @code{mreal} y, @code{mreal} w, @code{mreal} h)
++@end ifclear
++Аналогично первому, но в произвольном месте графика @{@var{x}, @var{y}@} (полагаются в диапазоне [0,1]). Параметры @var{w}, @var{h} задают относительную ширину и высоту colorbar.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} colorbar vdat 'sch' @code{x y [w=1 h=1]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Colorbar (@code{const mglDataA &}v, @code{const char *}sch, @code{mreal} x, @code{mreal} y, @code{mreal} w=@code{1}, @code{mreal} h=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_colorbar_val_ext (@code{HMGL} gr, @code{HCDT} v, @code{const char *}sch, @code{mreal} x, @code{mreal} y, @code{mreal} w, @code{mreal} h)
++@end ifclear
++Аналогично предыдущему, но для цветовой схемы @var{sch} без сглаживания с заданными значениями @var{v}. @sref{ContD sample}
++@end deftypefn
++
++@anchor{grid}
++@deftypefn {Команда MGL} {} grid ['dir'='xyz' 'pen'='B']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grid (@code{const char *}dir=@code{"xyz"}, @code{const char *}pen=@code{"B"}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_axis_grid (@code{HMGL} gr, @code{const char *}dir, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Рисует линии сетки в направлениях перпендикулярным @var{dir}. Если @var{dir} содержит @samp{!}, то линии рисуются также и для координат под-меток. Шаг сетки такой же как у меток осей координат. Стиль линий задается параметром @var{pen} (по умолчанию -- сплошная темно синяя линия @samp{B-}).
++@end deftypefn
++
++@anchor{box}
++@deftypefn {Команда MGL} {} box ['stl'='k' @code{ticks=on}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Box (@code{const char *}col=@code{""}, @code{bool} ticks=@code{true})
++@deftypefnx {Функция С} @code{void} mgl_box (@code{HMGL} gr)
++@deftypefnx {Функция С} @code{void} mgl_box_str (@code{HMGL} gr, @code{const char *}col, @code{int} ticks)
++@end ifclear
++Рисует ограничивающий параллелепипед цветом @var{col}. Если @var{col} содержит @samp{@@}, то рисуются закрашенные задние грани. При этом первый цвет используется для граней (по умолчанию светло жёлтый), а последний для рёбер и меток.
++@end deftypefn
++
++@anchor{xlabel}
++@anchor{ylabel}
++@anchor{zlabel}
++@anchor{tlabel}
++@deftypefn {Команда MGL} {} xlabel 'text' [@code{pos=1}]
++@deftypefnx {Команда MGL} {} ylabel 'text' [@code{pos=1}]
++@deftypefnx {Команда MGL} {} zlabel 'text' [@code{pos=1}]
++@deftypefnx {Команда MGL} {} tlabel 'text' [@code{pos=1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{char} dir, @code{const char *}text, @code{mreal} pos=@code{1}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{char} dir, @code{const wchar_t *}text, @code{mreal} pos=@code{1}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_label (@code{HMGL} gr, @code{char} dir, @code{const char *}text, @code{mreal} pos, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_labelw (@code{HMGL} gr, @code{char} dir, @code{const wchar_t *}text, @code{mreal} pos, @code{const char *}opt)
++@end ifclear
++Выводит подпись @var{text} для оси @var{dir}=@samp{x},@samp{y},@samp{z},@samp{t} (где @samp{t} -- ``тернарная'' ось @math{t=1-x-y}). Параметр @var{pos} задает положение подписи: при @var{pos}=0 -- по центру оси, при @var{pos}>0 -- около максимальных значений, при @var{pos}<0 -- около минимальных значений. Опция @code{value} задает дополнительный сдвиг текста. @xref{Text printing}.
++@end deftypefn
++
++@c ##################################################################
++@external{}
++@node Legend, 1D plotting, Axis and Colorbar, MathGL core
++@section Легенда
++@nav{}
++@cindex Legend
++@cindex AddLegend
++@cindex ClearLegend
++@cindex SetLegendBox
++@cindex SetLegendMarks
++
++Эти функции обеспечивают рисование легенды графика (полезно для @ref{1D plotting}). Запись в легенде состоит из двух строк: одна для стиля линии и маркеров, другая с текстом описания (с включенным разбором TeX-их команд). Можно использовать непосредственно массивы строк, или накопление во внутренние массивы с помощью функции AddLegend() с последующим отображением. Положение легенды можно задать автоматически или вручную. Параметры @var{fnt} и @var{size} задают стиль и размер шрифта (см. @ref{Font settings}). Опция @code{value} задает зазор между примером линии и текстом (по умолчанию 0.1). Опция @code{size} задает размер текста. Если стиль линии пустой, то соответствующий текст печатается без отступа. Строка @var{fnt} может содержать:
++@itemize @bullet
++@item
++стиль текста для записей;
++@item
++@samp{A} для расположения относительно всего рисунка, а не текущего subplot;
++@item
++@samp{^} для размещения снаружи от указанных координат;
++@item
++@samp{#} для вывода прямоугольника вокруг легенды;
++@item
++@samp{-} для горизонтального расположения записей;
++@item
++цвета для заливки (1-ый), для границы (2-ой) и для текста записей (3-ий). Если указано меньше трех цветов, то цвет границы черный (для 2 и менее цветов), и цвет заливки белый (для 1 и менее цвета).
++@end itemize
++@sref{Legend sample}
++
++@anchor{legend}
++@deftypefn {Команда MGL} {} legend [@code{pos=3} 'fnt'='#']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Legend (@code{int} pos=@code{0x3}, @code{const char *}fnt=@code{"#"}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_legend (@code{HMGL} gr, @code{int} pos, @code{const char *}fnt, @code{const char *}opt)
++@end ifclear
++Рисует легенду из накопленных записей шрифтом @var{fnt}. Параметр @var{pos} задает положение легенды: @samp{0} -- в нижнем левом углу, @samp{1} -- нижнем правом углу, @samp{2} -- верхнем левом углу, @samp{3} -- верхнем правом углу (по умолчанию). Опция @code{value} задает зазор между примером линии и текстом (по умолчанию 0.1).
++@end deftypefn
++
++@deftypefn {Команда MGL} {} legend @code{x y} ['fnt'='#']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Legend (@code{mreal} x, @code{mreal} y, @code{const char *}fnt=@code{"#"}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_legend_pos (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{const char *}fnt, @code{const char *}opt)
++@end ifclear
++Рисует легенду из накопленных записей шрифтом @var{fnt}. Положение легенды задается параметрами @var{x}, @var{y}, которые полагаются нормированными в диапазоне [0,1]. Опция @code{value} задает зазор между примером линии и текстом (по умолчанию 0.1).
++@end deftypefn
++
++@anchor{addlegend}
++@deftypefn {Команда MGL} {} addlegend 'text' 'stl'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} AddLegend (@code{const char *}text, @code{const char *}style)
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} AddLegend (@code{const wchar_t *}text, @code{const char *}style)
++@deftypefnx {Функция С} @code{void} mgl_add_legend (@code{HMGL} gr, @code{const char *}text, @code{const char *}style)
++@deftypefnx {Функция С} @code{void} mgl_add_legendw (@code{HMGL} gr, @code{const wchar_t *}text, @code{const char *}style)
++@end ifclear
++Добавляет описание @var{text} кривой со стилем @var{style} (см. @ref{Line styles}) во внутренний массив записей легенды.
++@end deftypefn
++
++@anchor{clearlegend}
++@deftypefn {Команда MGL} {} clearlegend
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ClearLegend ()
++@deftypefnx {Функция С} @code{void} mgl_clear_legend (@code{HMGL} gr)
++@end ifclear
++Очищает внутренний массив записей легенды.
++@end deftypefn
++
++@anchor{legendmarks}
++@deftypefn {Команда MGL} {} legendmarks @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SetLegendMarks (@code{int} num)
++@deftypefnx {Функция С} @code{void} mgl_set_legend_marks (@code{HMGL} gr, @code{int} num)
++@end ifclear
++Задает число маркеров в легенде. По умолчанию используется 1 маркер.
++@end deftypefn
++
++@c ##################################################################
++@external{}
++@node 1D plotting, 2D plotting, Legend, MathGL core
++@section 1D графики
++@nav{}
++@cindex Plot
++@cindex Radar
++@cindex Tens
++@cindex Area
++@cindex Region
++@cindex Stem
++@cindex Bars
++@cindex Barh
++@cindex Chart
++@cindex Step
++@cindex Torus
++@cindex Tube
++@cindex Mark
++@cindex TextMark
++@cindex Error
++@cindex BoxPlot
++@cindex Candle
++@cindex Tape
++@cindex Label
++@cindex Cones
++
++Эти функции строят графики для одномерных (1D) массивов. Одномерными считаются массивы, зависящие только от одного параметра (индекса) подобно кривой в параметрической форме @{x(i),y(i),z(i)@}, i=1...n. По умолчанию (если отсутствуют) значения @var{x}[i] равно распределены в диапазоне оси х, и @var{z}[i] равно минимальному значению оси z. Графики рисуются для каждой строки массива данных если он двумерный. Размер по 1-ой координате @strong{должен быть одинаков} для всех массивов @code{x.nx=y.nx=z.nx}.
++
++Строка @var{pen} задает цвет и стиль линии и маркеров (см. @ref{Line styles}). По умолчанию (@code{pen=""}) рисуется сплошная линия с текущим цветом из палитры (см. @ref{Palette and colors}). Символ @samp{!} в строке задает использование нового цвета из палитры для каждой точки данных (не для всей кривой, как по умолчанию). Строка @var{opt} задает опции графика (см. @ref{Command options}). @sref{1D samples}
++
++@anchor{plot}
++@deftypefn {Команда MGL} {} plot ydat ['stl'='']
++@deftypefnx {Команда MGL} {} plot xdat ydat ['stl'='']
++@deftypefnx {Команда MGL} {} plot xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Plot (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Plot (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Plot (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_plot (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_plot_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_plot_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют ломанную линию по точкам @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Если @var{pen} содержит @samp{a}, то рисуются и сегменты между точками вне диапазона осей координат. Если @var{pen} содержит @samp{~}, то число сегментов уменьшается для квази-линейных участков. См. также @ref{area}, @ref{step}, @ref{stem}, @ref{tube}, @ref{mark}, @ref{error}, @ref{belt}, @ref{tens}, @ref{tape}, @ref{meshnum}. @sref{Plot sample}
++@end deftypefn
++
++@anchor{radar}
++@deftypefn {Команда MGL} {} radar adat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Radar (@code{const mglDataA &}a, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_radar (@code{HMGL} gr, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют radar chart, представляющий собой ломанную с вершинами на радиальных линиях (типа ломанной в полярных координатах). Параметр @code{value} в опциях @var{opt} задает дополнительный сдвиг данных (т.е. использование @var{a}+@code{value} вместо @var{a}). Если @var{pen} содержит @samp{#}, то рисуется "сетка" (радиальные линии). Если @var{pen} содержит @samp{a}, то рисуются и сегменты между точками вне диапазона осей координат. См. также @ref{plot}, @ref{meshnum}. @sref{Radar sample}
++@end deftypefn
++
++@anchor{step}
++@deftypefn {Команда MGL} {} step ydat ['stl'='']
++@deftypefnx {Команда MGL} {} step xdat ydat ['stl'='']
++@deftypefnx {Команда MGL} {} step xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Step (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Step (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Step (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_step (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_step_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_step_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют ступеньки для точек массива. Если @var{x}.nx>@var{y}.nx, то массив @var{x} задает границы ступенек, а не их конец. См. также @ref{plot}, @ref{stem}, @ref{tile}, @ref{boxs}, @ref{meshnum}. @sref{Step sample}
++@end deftypefn
++
++@anchor{tens}
++@deftypefn {Команда MGL} {} tens ydat cdat ['stl'='']
++@deftypefnx {Команда MGL} {} tens xdat ydat cdat ['stl'='']
++@deftypefnx {Команда MGL} {} tens xdat ydat zdat cdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tens (@code{const mglDataA &}y, @code{const mglDataA &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tens (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tens (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_tens (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tens_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tens_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют ломанную линию по точкам с цветом, определяемым массивом @var{c} (типа графика натяжений). Строка @var{pen} задает цветовую схему (см. @ref{Color scheme}) и стиль линий и/или маркеров (см. @ref{Line styles}). Если @var{pen} содержит @samp{a}, то рисуются и сегменты между точками вне диапазона осей координат. Если @var{pen} содержит @samp{~}, то число сегментов уменьшается для квази-линейных участков. См. также @ref{plot}, @ref{mesh}, @ref{fall}, @ref{meshnum}. @sref{Tens sample}
++@end deftypefn
++
++@anchor{tape}
++@deftypefn {Команда MGL} {} tape ydat ['stl'='']
++@deftypefnx {Команда MGL} {} tape xdat ydat ['stl'='']
++@deftypefnx {Команда MGL} {} tape xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tape (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tape (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tape (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_tape (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tape_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tape_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют ленты, которые вращаются вокруг кривой @{@var{x}[i], @var{y}[i], @var{z}[i]@} как её нормали. Начальная лента(ы) выбираются в плоскости x-y (для @samp{x} в @var{pen}) и/или y-z (для @samp{x} в @var{pen}). Ширина лент пропорциональна @ref{barwidth}, а также может быть изменена опцией @code{value}. См. также @ref{plot}, @ref{flow}, @ref{barwidth}. @sref{Tape sample}
++@end deftypefn
++
++@anchor{area}
++@deftypefn {Команда MGL} {} area ydat ['stl'='']
++@deftypefnx {Команда MGL} {} area xdat ydat ['stl'='']
++@deftypefnx {Команда MGL} {} area xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Area (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Area (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Area (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_area (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_area_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_area_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют ломанную линию между точками и закрашивает её вниз до плоскости осей координат. Градиентная заливка используется если число цветов равно удвоенному число кривых. Если @var{pen} содержит @samp{#}, то рисуется только каркас. Если @var{pen} содержит @samp{a}, то рисуются и сегменты между точками вне диапазона осей координат. См. также @ref{plot}, @ref{bars}, @ref{stem}, @ref{region}. @sref{Area sample}
++@end deftypefn
++
++@anchor{region}
++@deftypefn {Команда MGL} {} region ydat1 ydat2 ['stl'='']
++@deftypefnx {Команда MGL} {} region xdat ydat1 ydat2 ['stl'='']
++@deftypefnx {Команда MGL} {} region xdat1 ydat1 xdat2 ydat2 ['stl'='']
++@deftypefnx {Команда MGL} {} region xdat1 ydat1 zdat1 xdat2 ydat2 zdat2 ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Region (@code{const mglDataA &}y1, @code{const mglDataA &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Region (@code{const mglDataA &}x, @code{const mglDataA &}y1, @code{const mglDataA &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Region (@code{const mglDataA &}x1, @code{const mglDataA &}y1, @code{const mglDataA &}x2, @code{const mglDataA &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Region (@code{const mglDataA &}x1, @code{const mglDataA &}y1, @code{const mglDataA &}z1, @code{const mglDataA &}x2, @code{const mglDataA &}y2, @code{const mglDataA &}z2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_region (@code{HMGL} gr, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_region_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_region_3d (@code{HMGL} gr, @code{HCDT} x1, @code{HCDT} y1, @code{HCDT} z1, @code{HCDT} x2, @code{HCDT} y2, @code{HCDT} z2, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции закрашивают область между 2 кривыми. Градиентная заливка используется если число цветов равно удвоенному число кривых. Если в 2d версии @var{pen} содержит @samp{i}, то закрашивается только область y1<y<y2, в противном случае будет закрашена и область y2<y<y1. Если @var{pen} содержит @samp{#}, то рисуется только каркас. Если @var{pen} содержит @samp{a}, то рисуются и сегменты между точками вне диапазона осей координат. См. также @ref{area}, @ref{bars}, @ref{stem}. @sref{Region sample}
++@end deftypefn
++
++@anchor{stem}
++@deftypefn {Команда MGL} {} stem ydat ['stl'='']
++@deftypefnx {Команда MGL} {} stem xdat ydat ['stl'='']
++@deftypefnx {Команда MGL} {} stem xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Stem (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Stem (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Stem (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_stem (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_stem_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_stem_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют вертикальные линии из точек до плоскости осей координат. См. также @ref{area}, @ref{bars}, @ref{plot}, @ref{mark}. @sref{Stem sample}
++@end deftypefn
++
++@anchor{bars}
++@deftypefn {Команда MGL} {} bars ydat ['stl'='']
++@deftypefnx {Команда MGL} {} bars xdat ydat ['stl'='']
++@deftypefnx {Команда MGL} {} bars xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Bars (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Bars (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Bars (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_bars (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_bars_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_bars_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют вертикальные полосы (прямоугольники) из точек до плоскости осей координат. Строка @var{pen} может содержать:
++@itemize @bullet
++@item
++@samp{a} для вывода линий одной поверх другой (как при суммировании);
++@item
++@samp{f} для определения кумулятивного эффекта последовательности положительных и отрицательных значений (график типа waterfall);
++@item
++@samp{F} для использования одинаковой (минимальной) ширины полосок;
++@item
++@samp{<}, @samp{^} or @samp{>} для выравнивания полосок влево, вправо или центрирования относительно их координат.
++@end itemize
++Можно использовать разные цвета для положительных и отрицательных значений если число указанных цветов равно удвоенному числу кривых для построения. Если @var{x}.nx>@var{y}.nx, то массив @var{x} задает границы полос, а не их центр. См. также @ref{barh}, @ref{cones}, @ref{area}, @ref{stem}, @ref{chart}, @ref{barwidth}. @sref{Bars sample}
++@end deftypefn
++
++@anchor{barh}
++@deftypefn {Команда MGL} {} barh vdat ['stl'='']
++@deftypefnx {Команда MGL} {} barh ydat vdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Barh (@code{const mglDataA &}v, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Barh (@code{const mglDataA &}y, @code{const mglDataA &}v, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_barh (@code{HMGL} gr, @code{HCDT} v, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_barh_xy (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} v, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют горизонтальные полосы (прямоугольники) из точек до плоскости осей координат. Строка @var{pen} может содержать:
++@itemize @bullet
++@item
++@samp{a} для вывода линий одной поверх другой (как при суммировании);
++@item
++@samp{f} для определения кумулятивного эффекта последовательности положительных и отрицательных значений (график типа waterfall);
++@item
++@samp{F} для использования одинаковой (минимальной) ширины полосок;
++@item
++@samp{<}, @samp{^} or @samp{>} для выравнивания полосок влево, вправо или центрирования относительно их координат.
++@end itemize
++Можно использовать разные цвета для положительных и отрицательных значений если число указанных цветов равно удвоенному числу кривых для построения. Если @var{x}.nx>@var{y}.nx, то массив @var{x} задает границы полос, а не их центр. См. также @ref{bars}, @ref{barwidth}. @sref{Barh sample}
++@end deftypefn
++
++@anchor{cones}
++@deftypefn {Команда MGL} {} cones ydat ['stl'='']
++@deftypefnx {Команда MGL} {} cones xdat ydat ['stl'='']
++@deftypefnx {Команда MGL} {} cones xdat ydat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cones (@code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cones (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cones (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_cones (@code{HMGL} gr, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_cones_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_cones_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют конусы из точек до плоскости осей координат. Если строка @var{pen} содержит символ @samp{a}, то линии рисуются одна поверх другой. Можно использовать разные цвета для положительных и отрицательных значений если число указанных цветов равно удвоенному числу кривых для построения. Параметр @var{pen} может содержать:
++@itemize @bullet
++@item
++@samp{@@} для рисования торцов;
++@item
++@samp{#} для сетчатой фигуры;
++@item
++@samp{t} для рисования цилиндра вместо конуса/призмы;
++@item
++@samp{4}, @samp{6}, @samp{8} для рисования квадратной, шестиугольной или восьмиугольной призмы вместо конуса;
++@item
++@samp{<}, @samp{^} или @samp{>} для выравнивания конусов влево, вправо или по центру относительно их координат.
++@end itemize
++См. также @ref{bars}, @ref{cone}, @ref{barwidth}. @sref{Cones sample}
++@end deftypefn
++
++
++
++@anchor{chart}
++@deftypefn {Команда MGL} {} chart adat ['col'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Chart (@code{const mglDataA &}a, @code{const char *}col=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_chart (@code{HMGL} gr, @code{HCDT} a, @code{const char *}col, @code{const char *}opt)
++@end ifclear
++Рисует цветные полосы (пояса) для массива данных @var{a}. Число полос равно числу строк @var{a} (равно @var{a.ny}). Цвет полос поочерёдно меняется из цветов указанных в @var{col} или в палитре (см. @ref{Palette and colors}). Пробел в цветах соответствует прозрачному "цвету", т.е. если @var{col} содержит пробел(ы), то соответствующая полоса не рисуется. Ширина полосы пропорциональна значению элемента в @var{a}. График строится только для массивов не содержащих отрицательных значений. Если строка @var{col} содержит @samp{#}, то рисуется также чёрная граница полос. График выглядит лучше в (после вращения системы координат) и/или в полярной системе координат (становится Pie chart). @sref{Chart sample}
++@end deftypefn
++
++@anchor{boxplot}
++@deftypefn {Команда MGL} {} boxplot adat ['stl'='']
++@deftypefnx {Команда MGL} {} boxplot xdat adat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} BoxPlot (@code{const mglDataA &}a, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} BoxPlot (@code{const mglDataA &}x, @code{const mglDataA &}a, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_boxplot (@code{HMGL} gr, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_boxplot_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют boxplot (называемый также как box-and-whisker diagram или как "ящик с усами") в точках @var{x}[i] на плоскости @var{z} = @var{zVal} (по умолчанию @var{z} равно минимальному значению оси z). Это график, компактно изображающий распределение вероятностей @var{a}[i,j] (минимум, нижний квартиль (Q1), медиана (Q2), верхний квартиль (Q3) и максимум) вдоль второго (j-го) направления. Если @var{pen} содержит @samp{<}, @samp{^} или @samp{>}, то полоски будут выровнены влево, вправо или центрированы относительно их координат. См. также @ref{plot}, @ref{error}, @ref{bars}, @ref{barwidth}. @sref{BoxPlot sample}
++@end deftypefn
++
++@anchor{candle}
++@deftypefn {Команда MGL} {} candle vdat1 ['stl'='']
++@deftypefnx {Команда MGL} {} candle vdat1 vdat2 ['stl'='']
++@deftypefnx {Команда MGL} {} candle vdat1 ydat1 ydat2 ['stl'='']
++@deftypefnx {Команда MGL} {} candle vdat1 vdat2 ydat1 ydat2 ['stl'='']
++@deftypefnx {Команда MGL} {} candle xdat vdat1 vdat2 ydat1 ydat2 ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Candle (@code{const mglDataA &}v1, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Candle (@code{const mglDataA &}v1, @code{const mglDataA &}v2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Candle (@code{const mglDataA &}v1, @code{const mglDataA &}y1, @code{const mglDataA &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Candle (@code{const mglDataA &}v1, @code{const mglDataA &}v2, @code{const mglDataA &}y1, @code{const mglDataA &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Candle (@code{const mglDataA &}x, @code{const mglDataA &}v1, @code{const mglDataA &}v2, @code{const mglDataA &}y1, @code{const mglDataA &}y2, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_candle (@code{HMGL} gr, @code{HCDT} v1, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_candle_yv (@code{HMGL} gr, @code{HCDT} v1, @code{HCDT} v2, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_candle_xyv (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} v1, @code{HCDT} v2, @code{HCDT} y1, @code{HCDT} y2, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют candlestick chart в точках @var{x}[i]. Этот график показывает прямоугольником ("свечой") диапазон изменения величины. Прозрачная (белая) свеча соответствует росту величины @var{v1}[i]<@var{v2}[i], чёрная -- уменьшению. "Тени" показывают минимальное @var{y1} и максимальное @var{y2} значения. Если @var{v2} отсутствует, то он определяется как @var{v2}[i]=@var{v1}[i+1]. Можно использовать разные цвета для растущих и падающих дней если число указанных цветов равно удвоенному числу кривых для построения. Если @var{pen} содержит @samp{#}, то прозрачная свеча будет использована и при 2-цветной схеме. См. также @ref{plot}, @ref{bars}, @ref{ohlc}, @ref{barwidth}. @sref{Candle sample}
++@end deftypefn
++
++@anchor{ohlc}
++@deftypefn {Команда MGL} {} ohlc odat hdat ldat cdat ['stl'='']
++@deftypefnx {Команда MGL} {} ohlc xdat odat hdat ldat cdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {MМетод класса @code{mglGraph}} @code{void} OHLC (@code{const mglDataA &}o, @code{const mglDataA &}h, @code{const mglDataA &}l, @code{const mglDataA &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} OHLC (@code{const mglDataA &}x, @code{const mglDataA &}o, @code{const mglDataA &}h, @code{const mglDataA &}l, @code{const mglDataA &}c, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_ohlc (@code{HMGL} gr, @code{HCDT} o, @code{HCDT} h, @code{HCDT} l, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_ohlc_x (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} o, @code{HCDT} h, @code{HCDT} l, @code{HCDT} c, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют Open-High-Low-Close диаграмму. Этот график содержит вертикальные линии между максимальным @var{h} и минимальным @var{l} значениями, и горизонтальные линии перед/после вертикальной линии для начального @var{o} и конечного @var{c} значений процесса (обычно цены). Можно использовать разные цвета для растущих и падающих дней если число указанных цветов равно удвоенному числу кривых для построения. См. также @ref{candle}, @ref{plot}, @ref{barwidth}. @sref{OHLC sample}
++@end deftypefn
++
++
++@anchor{error}
++@deftypefn {Команда MGL} {} error ydat yerr ['stl'='']
++@deftypefnx {Команда MGL} {} error xdat ydat yerr ['stl'='']
++@deftypefnx {Команда MGL} {} error xdat ydat xerr yerr ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Error (@code{const mglDataA &}y, @code{const mglDataA &}ey, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Error (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ey, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Error (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ex, @code{const mglDataA &}ey, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_error (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_error_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_error_exy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ex, @code{HCDT} ey, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют размер ошибки @{@var{ex}[i], @var{ey}[i]@} в точках @{@var{x}[i], @var{y}[i]@} на плоскости @var{z} = @var{zVal} (по умолчанию @var{z} равно минимальному значению оси z). Такой график полезен для отображения ошибки эксперимента, вычислений и пр. Если @var{pen} содержит @samp{@@}, то будут использованы большие полупрозрачные маркеры. См. также @ref{plot}, @ref{mark}. @sref{Error sample}
++@end deftypefn
++
++@anchor{mark}
++@deftypefn {Команда MGL} {} mark ydat rdat ['stl'='']
++@deftypefnx {Команда MGL} {} mark xdat ydat rdat ['stl'='']
++@deftypefnx {Команда MGL} {} mark xdat ydat zdat rdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Mark (@code{const mglDataA &}y, @code{const mglDataA &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Mark (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Mark (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_mark_y (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_mark_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_mark_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют маркеры размером @var{r}[i]*@ref{marksize} (см. @ref{Default sizes}) в точках @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Для рисования маркеров одинакового размера можно использовать функцию @ref{plot} с невидимой линией (со стилем содержащим @samp{ }). Для маркеров с размером как у координат можно использовать @ref{error} со стилем @samp{@@}. См. также @ref{plot}, @ref{textmark}, @ref{error}, @ref{stem}, @ref{meshnum}. @sref{Mark sample}
++@end deftypefn
++
++@anchor{textmark}
++@deftypefn {Команда MGL} {} textmark ydat 'txt' ['stl'='']
++@deftypefnx {Команда MGL} {} textmark ydat rdat 'txt' ['stl'='']
++@deftypefnx {Команда MGL} {} textmark xdat ydat rdat 'txt' ['stl'='']
++@deftypefnx {Команда MGL} {} textmark xdat ydat zdat rdat 'txt' ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}y, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}y, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}y, @code{const mglDataA &}r, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}y, @code{const mglDataA &}r, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}r, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}r, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}r, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TextMark (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}r, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_textmark (@code{HMGL} gr, @code{HCDT} y, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_textmarkw (@code{HMGL} gr, @code{HCDT} y, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_textmark_yr (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_textmarkw_yr (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_textmark_xyr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_textmarkw_xyr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_textmark_xyzr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_textmarkw_xyzr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@end ifclear
++Функции рисуют текст @var{txt} как маркер с размером пропорциональным @var{r}[i]*@var{marksize} в точках @{@var{x}[i], @var{y}[i], @var{z}[i]@}. См. также @ref{plot}, @ref{mark}, @ref{stem}, @ref{meshnum}. @sref{TextMark sample}
++@end deftypefn
++
++@anchor{label}
++@deftypefn {Команда MGL} {} label ydat 'txt' ['stl'='']
++@deftypefnx {Команда MGL} {} label xdat ydat 'txt' ['stl'='']
++@deftypefnx {Команда MGL} {} label xdat ydat zdat 'txt' ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{const mglDataA &}y, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{const mglDataA &}y, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Label (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_label (@code{HMGL} gr, @code{HCDT} y, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_labelw (@code{HMGL} gr, @code{HCDT} y, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_label_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_labelw_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_label_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_labelw_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@end ifclear
++Функции выводят текстовую строку @var{txt} в точках @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Если строка @var{txt} содержит @samp{%x}, @samp{%y}, @samp{%z} или @samp{%n}, то они будут заменены на значения соответствующих координат или на номер точки. Строка @var{fnt} может содержать:
++@itemize
++@item стиль текста @ref{Font styles};
++@item @samp{f} для вывода чисел в фиксированном формате;
++@item @samp{E} для вывода @samp{E} вместо @samp{e};
++@item @samp{F} для вывода в формате LaTeX;
++@item @samp{+} для вывода @samp{+} для положительных чисел;
++@item @samp{-} для вывода обычного @samp{-};
++@item @samp{0123456789} для задания точности при выводе чисел.
++@end itemize
++См. также @ref{plot}, @ref{mark}, @ref{textmark}, @ref{table}. @sref{Label sample}
++@end deftypefn
++
++@anchor{table}
++@deftypefn {Команда MGL} {} table vdat 'txt' ['stl'='#']
++@deftypefnx {Команда MGL} {} table x y vdat 'txt' ['stl'='#']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Table (@code{const mglDataA &}val, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Table (@code{const mglDataA &}val, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Table (@code{mreal} x, @code{mreal} y, @code{const mglDataA &}val, @code{const char *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Table (@code{mreal} x, @code{mreal} y, @code{const mglDataA &}val, @code{const wchar_t *}txt, @code{const char *}fnt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_table (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{HCDT} val, @code{const char *}txt, @code{const char *}fnt, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tablew (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{HCDT} val, @code{const wchar_t *}txt, @code{const char *}fnt, @code{const char *}opt)
++@end ifclear
++Рисует таблицу значений массива @var{val} с заголовками @var{txt} (разделенными символом новой строки @samp{\n}) в точке @{@var{x}, @var{y}@} (по умолчанию @{0,0@}) относительно текущего subplot. Строка @var{fnt} может содержать:
++@itemize
++@item стиль текста @ref{Font styles};
++@item @samp{#} для рисования границ ячеек;
++@item @samp{=} для одинаковой ширины всех ячеек;
++@item @samp{|} для ограничения ширины таблицы шириной subplot (эквивалентно опции @samp{value 1});
++@item @samp{f} для вывода чисел в фиксированном формате;
++@item @samp{E} для вывода @samp{E} вместо @samp{e};
++@item @samp{F} для вывода в формате LaTeX;
++@item @samp{+} для вывода @samp{+} для положительных чисел;
++@item @samp{-} для вывода обычного @samp{-};
++@item @samp{0123456789} для задания точности при выводе чисел.
++@end itemize
++Опция @code{value} задает ширину таблицы (по умолчанию 1). См. также @ref{plot}, @ref{label}. @sref{Table sample}
++@end deftypefn
++
++@anchor{iris}
++@deftypefn {Команда MGL} {} iris dats 'ids' ['stl'='']
++@deftypefnx {Команда MGL} {} iris dats rngs 'ids' ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Iris (@code{const mglDataA &}dats, @code{const char *}ids, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Iris (@code{const mglDataA &}dats, @code{const wchar_t *}ids, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Iris (@code{const mglDataA &}dats, @code{const mglDataA &}rngs, @code{const char *}ids, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Iris (@code{const mglDataA &}dats, @code{const mglDataA &}rngs, @code{const wchar_t *}ids, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_iris_1 (@code{HMGL} gr, @code{HCDT} dats, @code{const char *}ids, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_irisw_1 (@code{HMGL} gr, @code{HCDT} dats, @code{const wchar_t *}ids, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_iris (@code{HMGL} gr, @code{HCDT} dats, @code{HCDT} rngs, @code{const char *}ids, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_irisw (@code{HMGL} gr, @code{HCDT} dats, @code{HCDT} rngs, @code{const wchar_t *}ids, @code{const char *}stl, @code{const char *}opt)
++@end ifclear
++Рисует Ирисы Фишера для определения зависимостей данных @var{dats} друг от друга (см. @uref{http://en.wikipedia.org/wiki/Iris_flower_data_set}). Массив @var{rngs} размером 2*@var{dats}.nx задает диапазон изменения осей для каждой из колонки. Строка @var{ids} содержит имена колонок данных, разделенных символом @samp{;}. Опция @code{value} задает размер текста для имен данных. На график можно добавить новый набор данных если указать тот же размер @var{rngs} и использовать пустую строку имен @var{ids}. См. также @ref{plot}. @sref{Iris sample}
++@end deftypefn
++
++@anchor{tube}
++@deftypefn {Команда MGL} {} tube ydat rdat ['stl'='']
++@deftypefnx {Команда MGL} {} tube ydat @code{rval} ['stl'='']
++@deftypefnx {Команда MGL} {} tube xdat ydat rdat ['stl'='']
++@deftypefnx {Команда MGL} {} tube xdat ydat @code{rval} ['stl'='']
++@deftypefnx {Команда MGL} {} tube xdat ydat zdat rdat ['stl'='']
++@deftypefnx {Команда MGL} {} tube xdat ydat zdat @code{rval} ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tube (@code{const mglDataA &}y, @code{const mglDataA &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tube (@code{const mglDataA &}y, @code{mreal} r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tube (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tube (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{mreal} r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tube (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tube (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{mreal} r, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_tube_r (@code{HMGL} gr, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tube (@code{HMGL} gr, @code{HCDT} y, @code{mreal} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tube_xyr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tube_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{mreal} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tube_xyzr (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}pen, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tube_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{mreal} r, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют трубу радиуса @var{r}[i] вдоль кривой между точками @{@var{x}[i], @var{y}[i], @var{z}[i]@}. См. также @ref{plot}. @sref{Tube sample}
++@end deftypefn
++
++@anchor{torus}
++@deftypefn {Команда MGL} {} torus rdat zdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Torus (@code{const mglDataA &}r, @code{const mglDataA &}z, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_torus (@code{HMGL} gr, @code{HCDT} r, @code{HCDT} z, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Функции рисуют поверхность вращения кривой @{@var{r}, @var{z}@} относительно оси. Если строка @var{pen} содержит @samp{x} или @samp{z}, то ось вращения будет выбрана в указанном направлении (по умолчанию вдоль оси y). Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. См. также @ref{plot}, @ref{axial}. @sref{Torus sample}
++@end deftypefn
++
++
++
++@anchor{lamerey}
++@deftypefn {Команда MGL} {} lamerey @code{x0} ydat ['stl'='']
++@deftypefnx {Команда MGL} {} lamerey @code{x0} 'y(x)' ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Lamerey (@code{double} x0, @code{const mglDataA &}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Lamerey (@code{double} x0, @code{const char *}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_lamerey_dat (@code{HMGL} gr, @code{double} x0, @code{HCDT} y, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_lamerey_str (@code{HMGL} gr, @code{double} x0, @code{const char *}y, @code{const char *}stl, @code{const char *}opt)
++@end ifclear
++Функции рисуют диаграмму Ламерея для точечного отображения x_new = y(x_old) начиная с точки @var{x0}. Строка @var{stl} может содержать стиль линии, символ @samp{v} для стрелок, символ @samp{~} для исключения первого сегмента. Опция @code{value} задает число сегментов для рисования (по умолчанию 20). См. также @ref{plot}, @ref{fplot}, @ref{bifurcation}, @ref{pmap}. @sref{Lamerey sample}
++@end deftypefn
++
++@anchor{bifurcation}
++@deftypefn {Команда MGL} {} bifurcation @code{dx} ydat ['stl'='']
++@deftypefnx {Команда MGL} {} bifurcation @code{dx} 'y(x)' ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Bifurcation (@code{double} dx, @code{const mglDataA &}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Bifurcation (@code{double} dx, @code{const char *}y, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_bifurcation_dat (@code{HMGL} gr, @code{double} dx, @code{HCDT} y, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_bifurcation_str (@code{HMGL} gr, @code{double} dx, @code{const char *}y, @code{const char *}stl, @code{const char *}opt)
++@end ifclear
++Функции рисуют бифуркационную диаграмму (диаграмму удвоения периода) для точечного отображения x_new = y(x_old). Параметр @var{dx} задает точность по оси x. Строка @var{stl} задает цвет. Опция @code{value} задает число учитываемых стационарных точек (по умолчанию 1024). См. также @ref{plot}, @ref{fplot}, @ref{lamerey}. @sref{Bifurcation sample}
++@end deftypefn
++
++@anchor{pmap}
++@deftypefn {Команда MGL} {} pmap ydat sdat ['stl'='']
++@deftypefnx {Команда MGL} {} pmap xdat ydat sdat ['stl'='']
++@deftypefnx {Команда MGL} {} pmap xdat ydat zdat sdat ['stl'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Pmap (@code{const mglDataA &}y, @code{const mglDataA &}s, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Pmap (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}s, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Pmap (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}s, @code{const char *}stl=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_pmap (@code{HMGL} gr, @code{HMDT} y, @code{HCDT} s, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_pmap_xy (@code{HMGL} gr, @code{HCDT} x, @code{HMDT} y, @code{HCDT} s, @code{const char *}stl, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_pmap_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HMDT} y, @code{HCDT} z, @code{HCDT} s, @code{const char *}stl, @code{const char *}opt)
++@end ifclear
++Функции рисуют отображение Пуанкаре для кривой @{@var{x}, @var{y}, @var{z}@} при условии @var{s}=0. Проще говоря, рисуются точки пересечения кривой и поверхности. Строка @var{stl} задает стиль маркеров. См. также @ref{plot}, @ref{mark}, @ref{lamerey}. @sref{Pmap sample}
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node 2D plotting, 3D plotting, 1D plotting, MathGL core
++@section 2D графики
++@nav{}
++@cindex Mesh
++@cindex Fall
++@cindex Belt
++@cindex Surf
++@cindex Boxs
++@cindex Tile
++@cindex Dens
++@cindex Cont
++@cindex ContF
++@cindex ContD
++@cindex Axial
++@cindex Grad
++@cindex Grid
++
++Эти функции строят графики для двумерных (2D) массивов. Двумерными считаются массивы, зависящие только от двух параметров (индексов) подобно матрице @math{f(x_i,y_j), i=1...n, j=1...m}. По умолчанию (если отсутствуют) значения @var{x}, @var{y} равно распределены в диапазоне осей координат. Младшие размерности массивов @var{x}, @var{y}, @var{z} должны быть одинаковы @code{x.nx=z.nx && y.nx=z.ny} или @code{x.nx=y.nx=z.nx && x.ny=y.ny=z.ny}. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{z}). График строится для каждого z среза данных. Строка @var{sch} задает цветовую схему (см. @ref{Color scheme}). Строка @var{opt} задает опции графика (см. @ref{Command options}). @sref{2D samples}
++
++@anchor{surf}
++@deftypefn {Команда MGL} {} surf zdat ['sch'='']
++@deftypefnx {Команда MGL} {} surf xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_surf (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_surf_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует параметрически заданную поверхность @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. Если @var{sch} содержит @samp{#}, то рисуется сетка на поверхности. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. См. также @ref{mesh}, @ref{dens}, @ref{belt}, @ref{tile}, @ref{boxs}, @ref{surfc}, @ref{surfa}. @sref{Surf sample}
++@end deftypefn
++
++@anchor{mesh}
++@deftypefn {Команда MGL} {} mesh zdat ['sch'='']
++@deftypefnx {Команда MGL} {} mesh xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Mesh (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Mesh (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_mesh (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_mesh_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует сетчатую поверхность, заданную параметрически @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. См. также @ref{surf}, @ref{fall}, @ref{meshnum}, @ref{cont}, @ref{tens}. @sref{Mesh sample}
++@end deftypefn
++
++@anchor{fall}
++@deftypefn {Команда MGL} {} fall zdat ['sch'='']
++@deftypefnx {Команда MGL} {} fall xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Fall (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Fall (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_fall (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_fall_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует водопад для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. График удобен для построения нескольких кривых, сдвинутых вглубь друг относительно друга. Если @var{sch} содержит @samp{x}, то линии рисуются вдоль оси x, иначе (по умолчанию) вдоль оси y. См. также @ref{belt}, @ref{mesh}, @ref{tens}, @ref{meshnum}. @sref{Fall sample}
++@end deftypefn
++
++@anchor{belt}
++@deftypefn {Команда MGL} {} belt zdat ['sch'='']
++@deftypefnx {Команда MGL} {} belt xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Belt (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Belt (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_belt (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_belt_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует ленточки для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. График может использоваться как 3d обобщение графика @ref{plot}. Если @var{sch} содержит @samp{x}, то ленточки рисуются вдоль оси x, иначе (по умолчанию) вдоль оси y. См. также @ref{fall}, @ref{surf}, @ref{beltc}, @ref{plot}, @ref{meshnum}. @sref{Belt sample}
++@end deftypefn
++
++@anchor{boxs}
++@deftypefn {Команда MGL} {} boxs zdat ['sch'='']
++@deftypefnx {Команда MGL} {} boxs xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Boxs (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Boxs (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_boxs (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_boxs_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует вертикальные ящики для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. См. также @ref{surf}, @ref{dens}, @ref{tile}, @ref{step}. @sref{Boxs sample}
++@end deftypefn
++
++@anchor{tile}
++@deftypefn {Команда MGL} {} tile zdat ['sch'='']
++@deftypefnx {Команда MGL} {} tile xdat ydat zdat ['sch'='']
++@deftypefnx {Команда MGL} {} tile xdat ydat zdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tile (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tile (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Tile (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_tile (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tile_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tile_xyc (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует плитки для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} с цветом, заданным массивом @var{c}[i,j]. Если строка @var{sch} содержит стиль @samp{x} или @samp{y}, то плитки будут ориентированы перпендикулярно x- или y-оси. График может использоваться как 3d обобщение @ref{step}. См. также @ref{surf}, @ref{boxs}, @ref{step}, @ref{tiles}. @sref{Tile sample}
++@end deftypefn
++
++@anchor{dens}
++@deftypefn {Команда MGL} {} dens zdat ['sch'='']
++@deftypefnx {Команда MGL} {} dens xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dens (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{mreal} zVal=@code{NAN})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dens (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{mreal} zVal=@code{NAN})
++@deftypefnx {Функция С} @code{void} mgl_dens (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_dens_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует график плотности для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z} равном минимальному значению оси z. Если @var{sch} содержит @samp{#}, то рисуется сетка. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. См. также @ref{surf}, @ref{cont}, @ref{contf}, @ref{boxs}, @ref{tile}, @code{dens[xyz]}. @sref{Dens sample}
++@end deftypefn
++
++@anchor{cont}
++@deftypefn {Команда MGL} {} cont vdat zdat ['sch'='']
++@deftypefnx {Команда MGL} {} cont vdat xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont (@code{const mglDataA &}v, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_cont__val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_cont_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует линии уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z} равном минимальному значению оси z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. Если @var{sch} содержит @samp{t} или @samp{T}, то значения @var{v}[k] будут выведены вдоль контуров над (или под) кривой. См. также @ref{dens}, @ref{contf}, @ref{contd}, @ref{axial}, @code{cont[xyz]}. @sref{Cont sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} cont zdat ['sch'='']
++@deftypefnx {Команда MGL} {} cont xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_cont (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_cont_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @code{value} в опциях @var{opt} (по умолчанию 7).
++@end deftypefn
++
++@anchor{contf}
++@deftypefn {Команда MGL} {} contf vdat zdat ['sch'='']
++@deftypefnx {Команда MGL} {} contf vdat xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContF (@code{const mglDataA &}v, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContF (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_contf_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_contf_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует закрашенные линии (контуры) уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z} равном минимальному значению оси z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. См. также @ref{dens}, @ref{cont}, @ref{contd}, @code{contf[xyz]}. @sref{ContF sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} contf zdat ['sch'='']
++@deftypefnx {Команда MGL} {} contf xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContF (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContF (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_contf (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_contf_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @code{value} в опциях @var{opt} (по умолчанию 7).
++@end deftypefn
++
++@anchor{contd}
++@deftypefn {Команда MGL} {} contd vdat zdat ['sch'='']
++@deftypefnx {Команда MGL} {} contd vdat xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContD (@code{const mglDataA &}v, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContD (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_contd_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_contd_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует закрашенные линии (контуры) уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z=v}[k] или при @var{z} равном минимальному значению оси z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. Строка @var{sch} задает цвета контуров: цвет k-го контура определяется как k-ый цвет строки. См. также @ref{dens}, @ref{cont}, @ref{contf}. @sref{ContD sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} contd zdat ['sch'='']
++@deftypefnx {Команда MGL} {} contd xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContD (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContD (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_contd (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_contd_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @code{value} в опциях @var{opt} (по умолчанию 7).
++@end deftypefn
++
++
++@anchor{contp}
++@deftypefn {Команда MGL} {} contp vdat xdat ydat zdat adat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContP (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_contp_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует линии уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. Линии уровня рисуются для @var{a}[i,j]=@var{v}[k]. Если @var{sch} содержит @samp{t} или @samp{T}, то значения @var{v}[k] будут выведены вдоль контуров над (или под) кривой. Если @var{sch} содержит @samp{f}, то контуры будут закрашены. См. также @ref{cont}, @ref{contf}, @ref{surfc}, @code{cont[xyz]}. @c TODO @sref{Cont sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} contp xdat ydat zdat adat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContP (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_contp (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @code{value} в опциях @var{opt} (по умолчанию 7).
++@end deftypefn
++
++@anchor{contv}
++@deftypefn {Команда MGL} {} contv vdat zdat ['sch'='']
++@deftypefnx {Команда MGL} {} contv vdat xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContV (@code{const mglDataA &}v, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContV (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_contv_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_contv_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует вертикальные цилиндры от линий уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z}=@var{v}[k] или при @var{z} равном минимальному значению оси z если @var{sch} содержит @samp{_}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. См. также @ref{cont}, @ref{contf}. @sref{ContV sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} contv zdat ['sch'='']
++@deftypefnx {Команда MGL} {} contv xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContV (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContV (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_contv (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_contv_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @code{value} в опциях @var{opt} (по умолчанию 7).
++@end deftypefn
++
++@anchor{axial}
++@deftypefn {Команда MGL} {} axial vdat zdat ['sch'='']
++@deftypefnx {Команда MGL} {} axial vdat xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Axial (@code{const mglDataA &}v, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Axial (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_axial_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_axial_xy_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует поверхность вращения линии уровня для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@}. Линии уровня рисуются для @var{z}[i,j]=@var{v}[k]. Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. Если строка содержит символы @samp{x} или @samp{z}, то ось вращения устанавливается в указанное направление (по умолчанию вдоль @samp{y}). См. также @ref{cont}, @ref{contf}, @ref{torus}, @ref{surf3}. @sref{Axial sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} axial zdat ['sch'='']
++@deftypefnx {Команда MGL} {} axial xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Axial (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{int} num=@code{3})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Axial (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""}, @code{int} num=@code{3})
++@deftypefnx {Функция С} @code{void} mgl_axial (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_axial_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Как предыдущий с вектором @var{v} из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @code{value} в опциях @var{opt} (по умолчанию 3).
++@end deftypefn
++
++@anchor{grid2}
++@deftypefn {Команда MGL} {} grid2 zdat ['sch'='']
++@deftypefnx {Команда MGL} {} grid2 xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grid (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grid (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_grid (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_grid_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует плоскую сету для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} при @var{z} равном минимальному значению оси z. См. также @ref{dens}, @ref{cont}, @ref{contf}, @ref{grid3}, @ref{meshnum}.
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node 3D plotting, Dual plotting, 2D plotting, MathGL core
++@section 3D графики
++@nav{}
++@cindex Surf3
++@cindex Dens3
++@cindex Cont3
++@cindex ContF3
++@cindex Grid3
++@cindex Cloud
++@cindex Beam
++
++Эти функции строят графики для трехмерных (3D) массивов. Трёхмерными считаются массивы, зависящие от трёх параметров (индексов) подобно матрице @math{f(x_i,y_j,z_k), i=1...n, j=1...m, k=1...l}. По умолчанию (если отсутствуют) значения @var{x}, @var{y}, @var{z} равно распределены в диапазоне осей координат. Младшие размерности массивов @var{x}, @var{y}, @var{z} должны быть одинаковы @code{x.nx=a.nx && y.nx=a.ny && z.nz=a.nz} или @code{x.nx=y.nx=z.nx=a.nx && x.ny=y.ny=z.ny=a.ny && x.nz=y.nz=z.nz=a.nz}. Массивы @var{x}, @var{y} и @var{z} могут быть векторами (не матрицами как @var{a}). Строка @var{sch} задает цветовую схему (см. @ref{Color scheme}). Строка @var{opt} задает опции графика (см. @ref{Command options}). @sref{3D samples}
++
++
++@anchor{surf3}
++@deftypefn {Команда MGL} {} surf3 adat @code{val} ['sch'='']
++@deftypefnx {Команда MGL} {} surf3 xdat ydat zdat adat @code{val} ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3 (@code{mreal} val, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3 (@code{mreal} val, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_surf3_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_surf3_xyz_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует поверхность уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) при @var{a}(x,y,z)=@var{val}. Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. Замечу, что возможно некорректная отрисовка граней вследствие неопределённости построения сечения если поверхность пересекает ячейку данных 2 и более раз. См. также @ref{cloud}, @ref{dens3}, @ref{surf3c}, @ref{surf3a}, @ref{axial}. @sref{Surf3 sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} surf3 adat ['sch'='']
++@deftypefnx {Команда MGL} {} surf3 xdat ydat zdat adat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3 (@code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3 (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_surf3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_surf3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Аналогично предыдущему для @var{num} поверхностей уровня равномерно распределённых в диапазоне изменения цвета. Величина @var{num} равна значению параметра @code{value} в опциях @var{opt} (по умолчанию 3).
++@end deftypefn
++
++@anchor{cloud}
++@deftypefn {Команда MGL} {} cloud adat ['sch'='']
++@deftypefnx {Команда MGL} {} cloud xdat ydat zdat adat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cloud (@code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cloud (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_cloud (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_cloud_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует облачный график для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). График состоит из кубиков с цветом и прозрачностью пропорциональной значениям @var{a}. Результат похож на облако -- малые значения прозрачны, а большие нет. Число кубиков зависит от @ref{meshnum}. Если @var{sch} содержит @samp{.}, то будет построен график более низкого качества, но с заметно меньшим использованием памяти. Если @var{sch} содержит @samp{i}, то прозрачность будет инвертирована, т.е. области с более высокими значениями будут более прозрачны, а с более низким -- менее прозрачны. См. также @ref{surf3}, @ref{meshnum}. @sref{Cloud sample}
++@end deftypefn
++
++@anchor{dens3}
++@deftypefn {Команда MGL} {} dens3 adat ['sch'='' @code{sval=-1}]
++@deftypefnx {Команда MGL} {} dens3 xdat ydat zdat adat ['sch'='' @code{sval=-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dens3 (@code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dens3 (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_dens3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_dens3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++Рисует график плотности для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). График рисуется на срезе @var{sVal} в направлении @{@samp{x}, @samp{y}, @samp{z}@}, указанном в строке @var{sch} (по умолчанию, в напралении @samp{y}). Если @var{sch} содержит @samp{#}, то на срезе рисуется сетка. См. также @ref{cont3}, @ref{contf3}, @ref{dens}, @ref{grid3}. @sref{Dens3 sample}
++@end deftypefn
++
++@anchor{cont3}
++@deftypefn {Команда MGL} {} cont3 vdat adat ['sch'='' @code{sval=-1}]
++@deftypefnx {Команда MGL} {} cont3 vdat xdat ydat zdat adat ['sch'='' @code{sval=-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont3 (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont3 (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_cont3_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_cont3_xyz_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++Рисует линии уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). Линии рисуются для значений из массива @var{v} на срезе @var{sVal} в направлении @{@samp{x}, @samp{y}, @samp{z}@}, указанном в строке @var{sch} (по умолчанию, в напралении @samp{y}). Если @var{sch} содержит @samp{#}, то на срезе рисуется сетка. Если @var{sch} содержит @samp{t} или @samp{T}, то значения @var{v}[k] будут выведены вдоль контуров над (или под) кривой. См. также @ref{dens3}, @ref{contf3}, @ref{cont}, @ref{grid3}. @sref{Cont3 sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} cont3 adat ['sch'='' @code{sval=-1}]
++@deftypefnx {Команда MGL} {} cont3 xdat ydat zdat adat ['sch'='' @code{sval=-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont3 (@code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Cont3 (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_cont3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_cont3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++Аналогично предыдущему для @var{num} линий уровня равномерно распределённых в диапазоне изменения цвета. Величина @var{num} равна значению параметра @code{value} в опциях @var{opt} (по умолчанию 7).
++@end deftypefn
++
++@anchor{contf3}
++@deftypefn {Команда MGL} {} contf3 vdat adat ['sch'='' @code{sval=-1}]
++@deftypefnx {Команда MGL} {} contf3 vdat xdat ydat zdat adat ['sch'='' @code{sval=-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Contf3 (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Contf3 (@code{const mglDataA &}v, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_contf3_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_contf3_xyz_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++Рисует закрашенные линии (контуры) уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). Линии рисуются для значений из массива @var{v} на срезе @var{sVal} в направлении @{@samp{x}, @samp{y}, @samp{z}@}, указанном в строке @var{sch} (по умолчанию, в напралении @samp{y}). Если @var{sch} содержит @samp{#}, то на срезе рисуется сетка. См. также @ref{dens3}, @ref{cont3}, @ref{contf}, @ref{grid3}. @sref{ContF3 sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} contf3 adat ['sch'='' @code{sval=-1}]
++@deftypefnx {Команда MGL} {} contf3 xdat ydat zdat adat ['sch'='' @code{sval=-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Contf3 (@code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Contf3 (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_contf3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_contf3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++Аналогично предыдущему для @var{num} закрашенных линий (контуров) уровня равномерно распределённых в диапазоне изменения цвета. Величина @var{num} равна значению параметра @code{value} в опциях @var{opt} (по умолчанию 7).
++@end deftypefn
++
++@anchor{grid3}
++@deftypefn {Команда MGL} {} grid3 adat ['sch'='' @code{sval=-1}]
++@deftypefnx {Команда MGL} {} grid3 xdat ydat zdat adat ['sch'='' @code{sval=-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grid3 (@code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grid3 (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_grid3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_grid3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++Рисует сетку для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]). График рисуется на срезе @var{sVal} в направлении @{@samp{x}, @samp{y}, @samp{z}@}, указанном в строке @var{sch} (по умолчанию, в напралении @samp{y}). См. также @ref{cont3}, @ref{contf3}, @ref{dens3}, @ref{grid2}, @ref{meshnum}.
++@end deftypefn
++
++@anchor{beam}
++@deftypefn {Команда MGL} {} beam tr g1 g2 adat @code{rval} ['sch'='' @code{flag=0 num=3}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Beam (@code{const mglDataA &}tr, @code{const mglDataA &}g1, @code{const mglDataA &}g2, @code{const mglDataA &}a, @code{mreal} r, @code{const char *}stl=@code{""}, @code{int} flag=@code{0}, @code{int} num=@code{3})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Beam (@code{mreal} val, @code{const mglDataA &}tr, @code{const mglDataA &}g1, @code{const mglDataA &}g2, @code{const mglDataA &}a, @code{mreal} r, @code{const char *}stl=@code{""}, @code{int} flag=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_beam (@code{HMGL} gr, @code{HCDT} tr, @code{HCDT} g1, @code{HCDT} g2, @code{HCDT} a, @code{mreal} r, @code{const char *}stl, @code{int} flag, @code{int} num)
++@deftypefnx {Функция С} @code{void} mgl_beam_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} tr, @code{HCDT} g1, @code{HCDT} g2, @code{HCDT} a, @code{mreal} r, @code{const char *}stl, @code{int} flag)
++@end ifclear
++Рисует поверхность уровня для 3d массива @var{a} при постоянном значении @var{a}=@var{val}. Это специальный тип графика для @var{a} заданного в сопровождающей системе координат вдоль кривой @var{tr} с ортами @var{g1}, @var{g2} и с поперечным размером @var{r}. Переменная @var{flag} -- битовый флаг: @samp{0x1} - рисовать в сопровождающих (не лабораторных) координатах; @samp{0x2} - рисовать проекцию на плоскость @math{\rho-z}; @samp{0x4} - рисовать нормированное в каждом сечении поле. Размеры массивов по 1-му индексу @var{tr}, @var{g1}, @var{g2} должны быть nx>2. Размеры массивов по 2-му индексу @var{tr}, @var{g1}, @var{g2} и размер по 3-му индексу массива @var{a} должны быть одинаковы. См. также @ref{surf3}.
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node Dual plotting, Vector fields, 3D plotting, MathGL core
++@section Парные графики
++@nav{}
++@cindex SurfC
++@cindex SurfA
++@cindex Surf3C
++@cindex Surf3A
++@cindex TileS
++@cindex Map
++@cindex STFA
++
++Эти функции строят графики для двух связанных массивов. Есть несколько основных типов 3D графиков: поверхность и поверхность уровня с окраской по второму массиву (SurfC, Surf3C), поверхность и поверхность уровня с прозрачностью по второму массиву (SurfA, Surf3A), плитки переменного размера (TileS), диаграмма точечного отображения (Map), STFA диаграмма (STFA). По умолчанию (если отсутствуют) значения @var{x}, @var{y} (и @var{z} для @code{Surf3C, Surf3A}) равно распределены в диапазоне осей координат. Младшие размерности массивов @var{x}, @var{y}, @var{z}, @var{c} должны быть одинаковы @code{x.nx=a.nx && y.nx=a.ny && z.nz=a.nz} или @code{x.nx=y.nx=z.nx=a.nx && x.ny=y.ny=z.ny=a.ny && x.nz=y.nz=z.nz=a.nz}. Массивы @var{x}, @var{y} (и @var{z} для @code{Surf3C, Surf3A}) могут быть векторами (не матрицами как @var{c}). Строка @var{sch} задает цветовую схему (см. @ref{Color scheme}). Строка @var{opt} задает опции графика (см. @ref{Command options}).
++
++
++@anchor{surfc}
++@deftypefn {Команда MGL} {} surfc zdat cdat ['sch'='']
++@deftypefnx {Команда MGL} {} surfc xdat ydat zdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SurfC (@code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SurfC (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_surfc (@code{HMGL} gr, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_surfc_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует параметрически заданную поверхность @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} с цветом, заданным массивом @var{c}[i,j]. Если @var{sch} содержит @samp{#}, то на поверхности рисуется сетка. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. Размерность массивов @var{z} и @var{c} должна быть одинакова. График строится для каждого z среза данных. См. также @ref{surf}, @ref{surfa}, @ref{beltc}, @ref{surf3c}. @sref{SurfC sample}
++@end deftypefn
++
++
++@anchor{beltc}
++@deftypefn {Команда MGL} {} beltc zdat cdat ['sch'='']
++@deftypefnx {Команда MGL} {} beltc xdat ydat zdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} BeltC (@code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} BeltC (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_beltc (@code{HMGL} gr, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_beltc_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует ленточки для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} с цветом, заданным массивом @var{c}[i,j]. График может использоваться как 3d обобщение графика @ref{plot}. Если @var{sch} содержит @samp{x}, то ленточки рисуются вдоль оси x, иначе (по умолчанию) вдоль оси y. См. также @ref{belt}, @ref{surfc}, @ref{meshnum}. @c TODO @sref{Belt sample}
++@end deftypefn
++
++
++@anchor{surf3c}
++@deftypefn {Команда MGL} {} surf3c adat cdat @code{val} ['sch'='']
++@deftypefnx {Команда MGL} {} surf3c xdat ydat zdat adat cdat @code{val} ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3C (@code{mreal} val, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3C (@code{mreal} val, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_surf3c_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_surf3c_xyz_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует поверхность уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) при @var{a}(x,y,z)=@var{val}. Аналогично @ref{surf3}, но цвет задается массивом @var{c}. Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. См. также @ref{surf3}, @ref{surfc}, @ref{surf3a}. @sref{Surf3C sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} surf3c adat cdat ['sch'='']
++@deftypefnx {Команда MGL} {} surf3c xdat ydat zdat adat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3C (@code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3C (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_surf3c (@code{HMGL} gr, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_surf3c_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Аналогично предыдущему для @var{num} поверхностей уровня равномерно распределённых в диапазоне изменения цвета. Величина @var{num} равна значению параметра @code{value} в опциях @var{opt} (по умолчанию 3).
++@end deftypefn
++
++
++@anchor{surfa}
++@deftypefn {Команда MGL} {} surfa zdat cdat ['sch'='']
++@deftypefnx {Команда MGL} {} surfa xdat ydat zdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SurfA (@code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SurfA (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_surfa (@code{HMGL} gr, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_surfa_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует параметрически заданную поверхность @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} с прозрачностью, заданной массивом @var{c}[i,j]. Если @var{sch} содержит @samp{#}, то на поверхности рисуется сетка. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. Размерность массивов @var{z} и @var{c} должна быть одинакова. График строится для каждого z среза данных. См. также @ref{surf}, @ref{surfc}, @ref{surf3a}. @sref{SurfA sample}
++@end deftypefn
++
++@anchor{surf3a}
++@deftypefn {Команда MGL} {} surf3a adat cdat @code{val} ['sch'='']
++@deftypefnx {Команда MGL} {} surf3a xdat ydat zdat adat cdat @code{val} ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3A (@code{mreal} val, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3A (@code{mreal} val, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_surf3a_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_surf3a_xyz_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует поверхность уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) при @var{a}(x,y,z)=@var{val}. Аналогично @ref{surf3}, но прозрачность задается массивом @var{c}. Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. См. также @ref{surf3}, @ref{surfc}, @ref{surf3a}. @sref{Surf3A sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} surf3a adat cdat ['sch'='']
++@deftypefnx {Команда MGL} {} surf3a xdat ydat zdat adat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3A (@code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3A (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_surf3a (@code{HMGL} gr, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_surf3a_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Аналогично предыдущему для @var{num} поверхностей уровня равномерно распределённых в диапазоне изменения цвета. При этом массив @var{c} может быть вектором со значениями прозрачности и @var{num}=@var{c}.nx. В противном случае величина @var{num} равна значению параметра @code{value} в опциях @var{opt} (по умолчанию 3).
++@end deftypefn
++
++
++
++@anchor{surfca}
++@deftypefn {Команда MGL} {} surfca zdat cdat adat ['sch'='']
++@deftypefnx {Команда MGL} {} surfca xdat ydat zdat cdat adat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SurfCA (@code{const mglDataA &}z, @code{const mglDataA &}c, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} SurfCA (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_surfca (@code{HMGL} gr, @code{HCDT} z, @code{HCDT} c, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_surfca_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует параметрически заданную поверхность @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} с цветом и прозрачностью, заданными массивами @var{c}[i,j] и @var{a}[i,j] соответственно. Если @var{sch} содержит @samp{#}, то на поверхности рисуется сетка. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. Размерность массивов @var{z} и @var{c} должна быть одинакова. График строится для каждого z среза данных. См. также @ref{surf}, @ref{surfc}, @ref{surfa}, @ref{surf3ca}. @sref{SurfCA sample}
++@end deftypefn
++
++@anchor{surf3ca}
++@deftypefn {Команда MGL} {} surf3ca adat cdat bdat @code{val} ['sch'='']
++@deftypefnx {Команда MGL} {} surf3ca xdat ydat zdat adat cdat bdat @code{val} ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3CA (@code{mreal} val, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const mglDataA &}b, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3CA (@code{mreal} val, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const mglDataA &}b, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_surf3ca_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} a, @code{HCDT} c, @code{HCDT} b, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_surf3ca_xyz_val (@code{HMGL} gr, @code{mreal} val, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{HCDT} b, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует поверхность уровня для 3d массива, заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) при @var{a}(x,y,z)=@var{val}. Аналогично @ref{surf3}, но цвет и прозрачность задается массивами @var{c} и @var{b} соответственно. Если @var{sch} содержит @samp{#}, то рисуется сетчатая поверхность. Если @var{sch} содержит @samp{.}, то рисуется поверхность из точек. См. также @ref{surf3}, @ref{surfc}, @ref{surf3a}. @sref{Surf3A sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} surf3ca adat cdat ['sch'='']
++@deftypefnx {Команда MGL} {} surf3ca xdat ydat zdat adat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3CA (@code{const mglDataA &}a, @code{const mglDataA &}c, @code{const mglDataA &}b, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Surf3CA (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}c, @code{const mglDataA &}b, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_surf3ca (@code{HMGL} gr, @code{HCDT} a, @code{HCDT} c, @code{HCDT} b, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_surf3ca_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} c, @code{HCDT} b, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Аналогично предыдущему для @var{num} поверхностей уровня равномерно распределённых в диапазоне изменения цвета. Здесь величина @var{num} равна значению параметра @code{value} в опциях @var{opt} (по умолчанию 3).
++@end deftypefn
++
++
++@anchor{tiles}
++@deftypefn {Команда MGL} {} tiles zdat rdat ['sch'='']
++@deftypefnx {Команда MGL} {} tiles xdat ydat zdat rdat ['sch'='']
++@deftypefnx {Команда MGL} {} tiles xdat ydat zdat rdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TileS (@code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TileS (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}r, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TileS (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}r, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_tiles (@code{HMGL} gr, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tiles_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tiles_xyc (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} r, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует плитки для параметрически заданной поверхности @{@var{x}[i,j], @var{y}[i,j], @var{z}[i,j]@} с цветом, заданным массивом @var{c}[i,j]. Аналогично Tile(), но размер плиток задается массивов @var{r}. Если строка @var{sch} содержит стиль @samp{x} или @samp{y}, то плитки будут ориентированы перпендикулярно x- или y-оси. Это создает эффект "прозрачности" при экспорте в файлы EPS. График строится для каждого z среза данных. См. также @ref{surfa}, @ref{tile}. @sref{TileS sample}
++@end deftypefn
++
++@anchor{map}
++@deftypefn {Команда MGL} {} map udat vdat ['sch'='']
++@deftypefnx {Команда MGL} {} map xdat ydat udat vdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Map (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Map (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_map (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_map_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует точечное отображение для матриц @{@var{ax}, @var{ay} @} параметрически зависящих от координат @var{x}, @var{y}. Исходное положение ячейки задает ее цвет. Высота пропорциональна якобиану J(ax,ay). График является аналогом диаграммы Арнольда ??? Если @var{sch} содержит @samp{.}, то цветные точки рисуются в узлах матриц (полезно для "запутанного" отображения), иначе рисуются грани. @sref{Mapping visualization}
++@end deftypefn
++
++@anchor{stfa}
++@deftypefn {Команда MGL} {} stfa re im @code{dn} ['sch'='']
++@deftypefnx {Команда MGL} {} stfa xdat ydat re im @code{dn} ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} STFA (@code{const mglDataA &}re, @code{const mglDataA &}im, @code{int} dn, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} STFA (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}re, @code{const mglDataA &}im, @code{int} dn, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_stfa (@code{HMGL} gr, @code{HCDT} re, @code{HCDT} im, @code{int} dn, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_stfa_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} re, @code{HCDT} im, @code{int} dn, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует спектрограмму комплексного массива @var{re}+i*@var{im} для Фурье размером @var{dn} точек в плоскости @var{z} равно минимальному значению оси z. Параметр @var{dn} -- любое чётное число. Например в 1D случае, результатом будет график плотности от массива @math{res[i,j]=|\sum_d^dn exp(I*j*d)*(re[i*dn+d]+I*im[i*dn+d])|/dn} размером @{int(nx/dn), dn, ny@}. Массивы @var{re}, @var{im} параметрически зависят от координат @var{x}, @var{y}. Все размеры массивов @var{re} и @var{im} должны быть одинаковы. Младшие размерности массивов @var{x}, @var{y}, @var{re} должны быть одинаковы. Массивы @var{x} и @var{y} могут быть векторами (не матрицами как @var{re}). @sref{STFA sample}
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node Vector fields, Other plotting, Dual plotting, MathGL core
++@section Векторные поля
++@nav{}
++@cindex Traj
++@cindex Vect
++@cindex Dew
++@cindex Flow
++@cindex FlowP
++@cindex Pipe
++
++Эти функции рисуют графики для 2D и 3D векторных полей. Есть несколько типов графиков: просто векторное поле (Vect), вектора вдоль траектории (Traj), векторное поле каплями (Dew), нити тока (Flow, FlowP), трубки тока (Pipe). По умолчанию (если отсутствуют) значения @var{x}, @var{y} и @var{z} равно распределены в диапазоне осей координат. Младшие размерности массивов @var{x}, @var{y}, @var{z} и @var{ax} должны быть одинаковы. Размеры массивов @var{ax}, @var{ay} и @var{az} должны быть одинаковы. Массивы @var{x}, @var{y} и @var{z} могут быть векторами (не матрицами как @var{ax}). Строка @var{sch} задает цветовую схему (см. @ref{Color scheme}). Строка @var{opt} задает опции графика (см. @ref{Command options}).
++
++@anchor{traj}
++@deftypefn {Команда MGL} {} traj xdat ydat udat vdat ['sch'='']
++@deftypefnx {Команда MGL} {} traj xdat ydat zdat udat vdat wdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Traj (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Traj (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_traj_xyz (@code{HMGL} gr, @code{HCDT}x, @code{HCDT}y, @code{HCDT}z, @code{HCDT}ax, @code{HCDT}ay, @code{HCDT}az, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_traj_xy (@code{HMGL} gr, @code{HCDT}x, @code{HCDT}y, @code{HCDT}ax, @code{HCDT}ay, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует вектора @{@var{ax}, @var{ay}, @var{az}@} вдоль кривой @{@var{x}, @var{y}, @var{z}@}. Длина векторов пропорциональна @math{\sqrt@{ax^2+ay^2+az^2@}}. Строка @var{pen} задает цвет (см. @ref{Line styles}). По умолчанию (@code{pen=""}) используется текущий цвет из палитры (см. @ref{Palette and colors}). Опция @code{value} задает фактор длины векторов (если не нуль) или выбирать длину пропорционально расстоянию между точками кривой (если @code{value=0}). Размер по 1-му индексу должен быть 2 или больше. График рисуется для каждой строки если один из массивов матрица. См. также @ref{vect}. @sref{Traj sample}
++@end deftypefn
++
++@anchor{vect}
++@deftypefn {Команда MGL} {} vect udat vdat ['sch'='']
++@deftypefnx {Команда MGL} {} vect xdat ydat udat vdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Vect (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Vect (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_vect_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_vect_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует векторное поле @{@var{ax}, @var{ay}@} параметрически зависящее от координат @var{x}, @var{y} на плоскости при @var{z} равном минимальному значению оси z. Длина и цвет векторов пропорциональна @math{\sqrt@{ax^2+ay^2@}}. Число рисуемых векторов зависит от @ref{meshnum}. Вид стрелок/штрихов может быть изменён символами:
++@itemize @bullet
++@item
++@samp{f} для стрелок одинаковой длины,
++@item
++@samp{>}, @samp{<} для стрелок начинающихся или заканчивающихся в ячейке сетки (по умолчанию центрированы),
++@item
++@samp{.} для рисования штрихов с точкой в начале вместо стрелок,
++@item
++@samp{=} для использования градиента цвета вдоль стрелок.
++@end itemize
++См. также @ref{flow}, @ref{dew}. @sref{Vect sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} vect udat vdat wdat ['sch'='']
++@deftypefnx {Команда MGL} {} vect xdat ydat zdat udat vdat wdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Vect (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Vect (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_vect_3d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_vect_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Это 3d версия графика. Здесь массивы @var{ax}, @var{ay}, @var{az} должны трёхмерными тензорами и длина вектора пропорциональна @math{\sqrt@{ax^2+ay^2+az^2@}}.
++@end deftypefn
++
++@anchor{vect3}
++@deftypefn {Команда MGL} {} vect3 udat vdat wdat ['sch'='' sval]
++@deftypefnx {Команда MGL} {} vect3 xdat ydat zdat udat vdat wdat ['sch'='' sval]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Vect3 (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Vect3 (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{mreal} sVal=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_vect3 (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_vect3_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++Рисует 3D векторное поле @{@var{ax}, @var{ay}, @var{az}@} параметрически зависящее от координат @var{x}, @var{y}, @var{z}. График рисуется на срезе @var{sVal} в направлении @{@samp{x}, @samp{y}, @samp{z}@}, указанном в строке @var{sch} (по умолчанию, в напралении @samp{y}). Длина и цвет векторов пропорциональна @math{\sqrt@{ax^2+ay^2+az^2@}}. Число рисуемых векторов зависит от @ref{meshnum}. Вид стрелок/штрихов может быть изменён символами:
++@itemize @bullet
++@item
++@samp{f} для стрелок одинаковой длины,
++@item
++@samp{>}, @samp{<} для стрелок начинающихся или заканчивающихся в ячейке сетки (по умолчанию центрированы),
++@item
++@samp{.} для рисования штрихов с точкой в начале вместо стрелок,
++@item
++@samp{=} для использования градиента цвета вдоль стрелок.
++@end itemize
++См. также @ref{vect}, @ref{flow}, @ref{dew}. @sref{Vect sample}
++@end deftypefn
++
++@anchor{dew}
++@deftypefn {Команда MGL} {} dew udat vdat ['sch'='']
++@deftypefnx {Команда MGL} {} dew xdat ydat udat vdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dew (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dew (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_dew (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_dew_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует капли для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} при @var{z} равном минимальному значению оси z. Замечу, что график требует много памяти и процессорного времени для своего создания! Цвет капель пропорционален @math{\sqrt@{ax^2+ay^2@}}. Число капель определяется @ref{meshnum}. См. также @ref{vect}. @sref{Dew sample}
++@end deftypefn
++
++@anchor{flow}
++@deftypefn {Команда MGL} {} flow udat vdat ['sch'='']
++@deftypefnx {Команда MGL} {} flow xdat ydat udat vdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Flow (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Flow (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_flow_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_flow_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует нити тока для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} на плоскости при @var{z} равном минимальному значению оси z. Число нитей пропорционально значению опции @code{value} (по умолчанию 5). Цвет нитей пропорционален @math{\sqrt@{ax^2+ay^2@}}. Строка @var{sch} может содержать
++@itemize @bullet
++@item
++цветовую схему -- тёплые цвета соответствуют нормальному току (типа стока), холодные цвета соответствуют обратному току (типа источника);
++@item
++@samp{#} для использования нитей, начинающихся только на границе;
++@item
++@samp{*} для использования нитей, начинающихся с двумерной сетки внутри данных;
++@item
++@samp{v} для рисования стрелок на нитях;
++@item
++@samp{x}, @samp{z} для рисования лент нормалей, начинающихся в плоскостях x-y и y-z соответственно.
++@end itemize
++См. также @ref{pipe}, @ref{vect}, @ref{tape}, @ref{barwidth}. @sref{Flow sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} flow udat vdat wdat ['sch'='']
++@deftypefnx {Команда MGL} {} flow xdat ydat zdat udat vdat wdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Flow (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Flow (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_flow_3d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_flow_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Это 3d версия графика. Здесь массивы должны трёхмерными тензорами и цвет пропорционален @math{\sqrt@{ax^2+ay^2+az^2@}}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} flow @code{x0 y0} udat vdat ['sch'='']
++@deftypefnx {Команда MGL} {} flow @code{x0 y0} xdat ydat udat vdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_flowp_2d (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_flowp_xy (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Аналогично @ref{flow}, но рисует одну нить из точки @var{p0}=@{@var{x0},@var{y0},@var{z0}@}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} flow @code{x0 y0 z0} udat vdat wdat ['sch'='']
++@deftypefnx {Команда MGL} {} flow @code{x0 y0 z0} xdat ydat zdat udat vdat wdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} FlowP (@code{mglPoint} p0, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_flowp_3d (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_flowp_xyz (@code{HMGL} gr, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Это 3d версия графика.
++@end deftypefn
++
++@anchor{grad}
++@deftypefn {Команда MGL} {} grad pdat ['sch'='']
++@deftypefnx {Команда MGL} {} grad xdat ydat pdat ['sch'='']
++@deftypefnx {Команда MGL} {} grad xdat ydat zdat pdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grad (@code{const mglDataA &}phi, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grad (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}phi, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Grad (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}phi, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_grad (@code{HMGL} gr, @code{HCDT} phi, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_grad_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} phi, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_grad_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} phi, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует линии градиента скалярного поля @var{phi}[i,j] (или @var{phi}[i,j,k] в 3d случае) заданного параметрически @{@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]@}. Число линий пропорционально значению опции @code{value} (по умолчанию 5). См. также @ref{dens}, @ref{cont}, @ref{flow}.
++@end deftypefn
++
++@anchor{pipe}
++@deftypefn {Команда MGL} {} pipe udat vdat ['sch'='' @code{r0=0.05}]
++@deftypefnx {Команда MGL} {} pipe xdat ydat udat vdat ['sch'='' @code{r0=0.05}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Pipe (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{mreal} r0=@code{0.05}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Pipe (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const char *}sch=@code{""}, @code{mreal} r0=@code{0.05}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_pipe_2d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{mreal} r0, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_pipe_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} ax, @code{HCDT} ay, @code{const char *}sch, @code{mreal} r0, @code{const char *}opt)
++@end ifclear
++Рисует трубки тока для векторного поля @{@var{ax}, @var{ay}@}, параметрически зависящего от координат @var{x}, @var{y} на плоскости при @var{z} равном минимальному значению оси z. Число трубок пропорционально значению опции @code{value}. Цвет и радиус трубок пропорционален @math{\sqrt@{ax^2+ay^2@}}. Тёплые цвета соответствуют нормальному току (типа стока). Холодные цвета соответствуют обратному току (типа источника). Параметр @var{r0} задает радиус трубок. При @var{r0}<0 радиус трубок обратно пропорционален их амплитуде. См. также @ref{flow}, @ref{vect}. @sref{Pipe sample}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} pipe udat vdat wdat ['sch'='' @code{r0=0.05}]
++@deftypefnx {Команда MGL} {} pipe xdat ydat zdat udat vdat wdat ['sch'='' @code{r0=0.05}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Pipe (@code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{mreal} r0=@code{0.05}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Pipe (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}ax, @code{const mglDataA &}ay, @code{const mglDataA &}az, @code{const char *}sch=@code{""}, @code{mreal} r0=@code{0.05}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_pipe_3d (@code{HMGL} gr, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{mreal} r0, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_pipe_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} ax, @code{HCDT} ay, @code{HCDT} az, @code{const char *}sch, @code{mreal} r0, @code{const char *}opt)
++@end ifclear
++Это 3d версия графика. Здесь массивы @var{ax}, @var{ay}, @var{az} должны трёхмерными тензорами и цвет пропорционален @math{\sqrt@{ax^2+ay^2+az^2@}}.
++@end deftypefn
++
++
++@c ##################################################################
++@external{}
++@node Other plotting, Nonlinear fitting, Vector fields, MathGL core
++@section Прочие графики
++@nav{}
++@cindex DensXYZ
++@cindex ContXYZ
++@cindex ContFXYZ
++@cindex Dots
++@cindex Crust
++@cindex TriPlot
++@cindex TriCont
++@cindex QuadPlot
++@cindex FPlot
++@cindex FSurf
++
++Это функции, не относящиеся к какой-то специальной категории. Сюда входят функции построения графиков по текстовым формулам (FPlot и FSurf), рисования поверхностей из треугольников и четырёхугольников (TriPlot, TriCont, QuadPlot), произвольных точек в пространстве (Dots) и реконструкции по ним поверхности (Crust), графики плотности и линии уровня на плоскостях, перпендикулярных осям x, y или z (Dens[XYZ], Cont[XYZ], ContF[XYZ]). Каждый тип графика имеет похожий интерфейс. Есть версия для рисования одного массива с автоматическими координатами и версия для параметрически заданного массива. Параметры цветовой схемы задаются строкой. @xref{Color scheme}.
++
++@anchor{densz} @anchor{densy} @anchor{densx} @anchor{DensXYZ}
++@deftypefn {Команда MGL} {} densx dat ['sch'='' @code{sval=nan}]
++@deftypefnx {Команда MGL} {} densy dat ['sch'='' @code{sval=nan}]
++@deftypefnx {Команда MGL} {} densz dat ['sch'='' @code{sval=nan}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} DensX (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} DensY (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} DensZ (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_dens_x (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_dens_y (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_dens_z (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++Эти функции рисуют график плотности на x, y или z плоскостях. Если @var{a} -- 3d массив, то выполняется интерполяция к заданному срезу @var{sVal}. Функции полезны для создания проекций 3D массивов на оси координат. См. также @ref{ContXYZ}, @ref{ContFXYZ}, @ref{dens}, @ref{Data manipulation}. @sref{Dens projection sample}
++@end deftypefn
++
++@anchor{contz} @anchor{conty} @anchor{contx} @anchor{ContXYZ}
++@deftypefn {Команда MGL} {} contx dat ['sch'='' @code{sval=nan}]
++@deftypefnx {Команда MGL} {} conty dat ['sch'='' @code{sval=nan}]
++@deftypefnx {Команда MGL} {} contz dat ['sch'='' @code{sval=nan}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContX (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContY (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContZ (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_cont_x (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_cont_y (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_cont_z (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++Эти функции рисуют линии уровня на x, y или z плоскостях. Если @var{a} -- 3d массив, то выполняется интерполяция к заданному срезу @var{sVal}. Опция @code{value} задает число контуров. Функции полезны для создания проекций 3D массивов на оси координат. См. также @ref{ContFXYZ}, @ref{DensXYZ}, @ref{cont}, @ref{Data manipulation}. @sref{Cont projection sample}
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglGraph}} @code{void} ContX (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContY (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContZ (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_cont_x_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_cont_y_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_cont_z_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++Аналогично предыдущему с ручным заданием значений для линий уровня.
++@end deftypefn
++@end ifclear
++
++@anchor{contfz} @anchor{contfy} @anchor{contfx} @anchor{ContFXYZ}
++@deftypefn {Команда MGL} {} contfx dat ['sch'='' @code{sval=nan}]
++@deftypefnx {Команда MGL} {} contfy dat ['sch'='' @code{sval=nan}]
++@deftypefnx {Команда MGL} {} contfz dat ['sch'='' @code{sval=nan}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContFX (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContFY (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContFZ (@code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_contf_x (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_contf_y (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_contf_z (@code{HMGL} gr, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@end ifclear
++Эти функции рисуют закрашенные контуры уровня на x, y или z плоскостях. Если @var{a} -- 3d массив, то выполняется интерполяция к заданному срезу @var{sVal}. Опция @code{value} задает число контуров. Функции полезны для создания проекций 3D массивов на оси координат. См. также @ref{ContFXYZ}, @ref{DensXYZ}, @ref{cont}, @ref{Data manipulation}. @sref{ContF projection sample}
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglGraph}} @code{void} ContFX (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContFY (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} ContFZ (@code{const mglDataA &}v, @code{const mglDataA &}a, @code{const char *}stl=@code{""}, @code{mreal} sVal=@code{NAN}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_contf_x_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_contf_y_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_contf_z_val (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} a, @code{const char *}stl, @code{mreal} sVal, @code{const char *}opt)
++Аналогично предыдущему с ручным заданием значений для линий уровня.
++@end deftypefn
++@end ifclear
++
++@anchor{fplot}
++@deftypefn {Команда MGL} {} fplot 'y(x)' ['pen'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} FPlot (@code{const char *}eqY, @code{const char *}pen=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_fplot (@code{HMGL} gr, @code{const char *}eqY, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Рисует функцию @samp{eqY(x)} в плоскости @var{z} равно минимальному значению оси z с координатой @samp{x} в диапазоне осей координат. Опция @code{value} задает начальное число точек. См. также @ref{plot}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} fplot 'x(t)' 'y(t)' 'z(t)' ['pen'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} FPlot (@code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}pen, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_fplot_xyz (@code{HMGL} gr, @code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}pen, @code{const char *}opt)
++@end ifclear
++Рисует параметрическую кривую @{@samp{eqX(t)}, @samp{eqY(t)}, @samp{eqZ(t)}@}, где координата @samp{t} меняется в диапазоне [0, 1]. Опция @code{value} задает начальное число точек. См. также @ref{plot}.
++@end deftypefn
++
++@anchor{fsurf}
++@deftypefn {Команда MGL} {} fsurf 'z(x,y)' ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} FSurf (@code{const char *}eqZ, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""});
++@deftypefnx {Функция С} @code{void} mgl_fsurf (@code{HMGL} gr, @code{const char *}eqZ, @code{const char *}sch, @code{const char *}opt);
++@end ifclear
++Рисует поверхность @samp{eqY(x,y)} с координатами @samp{x}, @samp{y} в диапазоне @code{xrange, yrange}. Опция @code{value} задает число точек. См. также @ref{surf}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} fsurf 'x(u,v)' 'y(u,v)' 'z(u,v)' ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} FSurf (@code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_fsurf_xyz (@code{HMGL} gr, @code{const char *}eqX, @code{const char *}eqY, @code{const char *}eqZ, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует параметрическую поверхность @{@samp{eqX(u,v)}, @samp{eqY(u,v)}, @samp{eqZ(u,v)}@}, где координаты @samp{u}, @samp{v} меняются в диапазоне [0, 1]. Опция @code{value} задает число точек. См. также @ref{surf}.
++@end deftypefn
++
++@anchor{triplot}
++@deftypefn {Команда MGL} {} triplot idat xdat ydat ['sch'='']
++@deftypefnx {Команда MGL} {} triplot idat xdat ydat zdat ['sch'='']
++@deftypefnx {Команда MGL} {} triplot idat xdat ydat zdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriPlot (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriPlot (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriPlot (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_triplot_xy (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_triplot_xyz (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_triplot_xyzc (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует поверхность из треугольников. Вершины треугольников задаются индексами @var{id} в массиве точек @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Строка @var{sch} задает цветовую схему. Если строка содержит @samp{#}, то рисуется сетчатая поверхность. Размер по 1-му индексу массива @var{id} должен быть 3 или больше. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. Массив @var{c} задает цвет треугольников (если @var{id}.ny=@var{c}.nx) или цвет вершин (если @var{x}.nx=@var{c}.nx). См. также @ref{dots}, @ref{crust}, @ref{quadplot}, @ref{triangulation}. @sref{TriPlot and QuadPlot}
++@end deftypefn
++
++@anchor{tricont}
++@deftypefn {Команда MGL} {} tricont vdat idat xdat ydat zdat cdat ['sch'='']
++@deftypefnx {Команда MGL} {} tricont vdat idat xdat ydat zdat ['sch'='']
++@deftypefnx {Команда MGL} {} tricont idat xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriCont (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriCont (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriContV (@code{const mglDataA &}v, @code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} TriContV (@code{const mglDataA &}v, @code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_tricont_xyzc (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tricont_xyz (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tricont_xyzcv (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_tricont_xyzv (@code{HMGL} gr, @code{HCDT} v, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует линии уровня поверхности из треугольников при @var{z}=@var{v}[k] (или при @var{z} равном минимальному значению оси z если @var{sch} содержит @samp{_}). Вершины треугольников задаются индексами @var{id} в массиве точек @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Если аргуент @var{v} не задан, то используется массив из @var{num} элементов равно распределенных в диапазоне изменения цвета. Здесь @var{num} равен значению параметра @code{value} в опциях @var{opt} (по умолчанию 7). Строка @var{sch} задает цветовую схему. Размер по 1-му индексу массива @var{id} должен быть 3 или больше. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. Массив @var{c} задает цвет треугольников (если @var{id}.ny=@var{c}.nx) или цвет вершин (если @var{x}.nx=@var{c}.nx). См. также @ref{triplot}, @ref{cont}, @ref{triangulation}.
++@end deftypefn
++
++@anchor{quadplot}
++@deftypefn {Команда MGL} {} quadplot idat xdat ydat ['sch'='']
++@deftypefnx {Команда MGL} {} quadplot idat xdat ydat zdat ['sch'='']
++@deftypefnx {Команда MGL} {} quadplot idat xdat ydat zdat cdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} QuadPlot (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} QuadPlot (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} QuadPlot (@code{const mglDataA &}id, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_quadplot_xy (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_quadplot_xyz (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_quadplot_xyzc (@code{HMGL} gr, @code{HCDT} id, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует поверхность из четырёхугольников. Вершины четырёхугольников задаются индексами @var{id} в массиве точек @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Строка @var{sch} задает цветовую схему. Если строка содержит @samp{#}, то рисуется сетчатая поверхность. Размер по 1-му индексу массива @var{id} должен быть 4 или больше. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. Массив @var{c} задает цвет четырёхугольников (если @var{id}.ny=@var{c}.nx) или цвет вершин (если @var{x}.nx=@var{c}.nx). См. также @ref{triplot}. @sref{TriPlot and QuadPlot}
++@end deftypefn
++
++@anchor{dots}
++@deftypefn {Команда MGL} {} dots xdat ydat zdat ['sch'='']
++@deftypefnx {Команда MGL} {} dots xdat ydat zdat adat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dots (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dots (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Dots (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}c, @code{const mglDataA &}a, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_dots (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_dots_a (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_dots_ca (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} c, @code{HCDT} a, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Рисует произвольно расположенные точки @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Строка @var{sch} задает цветовую схему и тип маркеров. Если определёны массивы @var{c}, @var{a} то они задают цвет и прозрачность точек соответственно. Непрозрачные точки с заданным цветом можно нарисовать с помощью @ref{tens}, используя стиль @samp{ .}. Массивы @var{x}, @var{y}, @var{z}, @var{a} должны иметь одинаковые размеры. См. также @ref{crust}, @ref{tens}, @ref{mark}, @ref{plot}. @sref{Dots sample}
++@end deftypefn
++
++@anchor{crust}
++@deftypefn {Команда MGL} {} crust xdat ydat zdat ['sch'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Crust (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}sch=@code{""}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_crust (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}sch, @code{const char *}opt)
++@end ifclear
++Реконструирует и рисует поверхность по произвольно расположенным точкам @{@var{x}[i], @var{y}[i], @var{z}[i]@}. Опция @var{value} задает радиус ошибки (увеличите для удаления дыр). Строка @var{sch} задает цветовую схему. Если строка содержит @samp{#}, то рисуется сетчатая поверхность. Массивы @var{x}, @var{y}, @var{z} должны иметь одинаковые размеры. См. также @ref{dots}, @ref{triplot}. @c @sref{Crust sample}
++@end deftypefn
++
++@c ##################################################################
++@external{}
++@node Nonlinear fitting, Data manipulation, Other plotting, MathGL core
++@section Nonlinear fitting
++@nav{}
++@cindex Fit
++@cindex FitS
++@cindex PutsFit
++@cindex mglFitPnts
++@cindex Fit2
++@cindex Fit3
++
++Эти функции подбирают параметры функции для наилучшей аппроксимации данных, т.е. минимизируют сумму @math{\sum_i (f(x_i, y_i, z_i) - a_i)^2/s_i^2}. При этом аппроксимирующая функция @samp{f} может зависеть от одного аргумента @samp{x} (1D случай), от двух аргументов @samp{x,y} (2D случай) или от трех аргументов @samp{x,y,z} (3D случай). Функция @samp{f} также может зависеть от параметров. Список параметров задается строкой @var{var} (например, @samp{abcd}). Обычно пользователь должен предоставить начальные значения параметров в переменной @var{ini}. Однако, при его отсутствии используются нулевые значения. Параметр @var{print}=@code{true} включает вывод найденной формулы в @var{Message} (см. @ref{Error handling}).
++
++Функции Fit() и FitS() не рисуют полученные массивы. Они заполняют массив @var{fit} по формуле @samp{f} с найденными коэффициентами и возвращают @math{\chi^2} ошибку аппроксимации. При этом, координаты @samp{x,y,z} равно распределены в диапазоне осей координат. Число точек в @var{fit} определяется опцией @code{value} (по умолчанию @var{mglFitPnts}=100). Функции используют библиотеку GSL. @sref{Nonlinear fitting hints}
++
++@anchor{fits}
++@deftypefn {Команда MGL} {} fits res adat sdat 'func' 'var' [ini=0]
++@deftypefnx {Команда MGL} {} fits res xdat adat sdat 'func' 'var' [ini=0]
++@deftypefnx {Команда MGL} {} fits res xdat ydat adat sdat 'func' 'var' [ini=0]
++@deftypefnx {Команда MGL} {} fits res xdat ydat zdat adat sdat 'func' 'var' [ini=0]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}x, @code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}x, @code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} FitS (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const mglDataA &}s, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{HMDT} mgl_fit_ys (@code{HMGL} gr, @code{HCDT} a, @code{HCDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {Функция С} @code{HMDT} mgl_fit_xys (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{HCDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {Функция С} @code{HMDT} mgl_fit_xyzs (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} a, @code{HCDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {Функция С} @code{HMDT} mgl_fit_xyzas (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{HCDT} s, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@end ifclear
++"Подгоняют" формулу вдоль x-, y- и z-направлений для 3d массива заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) с весовым множителем @var{s}[i,j,k].
++@end deftypefn
++
++@anchor{fit}
++@deftypefn {Команда MGL} {} fit res adat 'func' 'var' [ini=0]
++@deftypefnx {Команда MGL} {} fit res xdat adat 'func' 'var' [ini=0]
++@deftypefnx {Команда MGL} {} fit res xdat ydat adat 'func' 'var' [ini=0]
++@deftypefnx {Команда MGL} {} fit res xdat ydat zdat adat 'func' 'var' [ini=0]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}x, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}x, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{HMDT} mgl_fit_y (@code{HMGL} gr, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {Функция С} @code{HMDT} mgl_fit_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {Функция С} @code{HMDT} mgl_fit_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {Функция С} @code{HMDT} mgl_fit_xyza (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@end ifclear
++"Подгоняют" формулу вдоль x-, y- и z-направлений для 3d массива заданного параметрически @var{a}[i,j,k](@var{x}[i,j,k], @var{y}[i,j,k], @var{z}[i,j,k]) с весовым множителем 1.
++@end deftypefn
++
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglGraph}} @code{mglData} Fit2 (@code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit2 (@code{mglData &}fit, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit3 (@code{mglData &}fit, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Fit3 (@code{mglData &}fit, @code{const mglDataA &}a, @code{const char *}func, @code{const char *}var, @code{mglData &}ini, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{HMDT} mgl_fit_2 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++@deftypefnx {Функция С} @code{HMDT} mgl_fit_3 (@code{HMGL} gr, @code{HCDT} a, @code{const char *}func, @code{const char *}var, @code{HMDT} ini, @code{const char *}opt)
++"Подгоняют" формулу вдоль всех направлений для 2d или 3d массива @var{a} с @var{s}=1 и @var{x}, @var{y}, @var{z} равно распределёнными в диапазоне осей координат.
++@end deftypefn
++@end ifclear
++
++@anchor{putsfit}
++@deftypefn {Команда MGL} {} putsfit @code{x y} ['pre'='' 'fnt'='' @code{size=-1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} PutsFit (@code{mglPoint} p, @code{const char *}prefix=@code{""}, @code{const char *}font=@code{""}, @code{mreal} size=@code{-1})
++@deftypefnx {Функция С} @code{void} mgl_puts_fit (@code{HMGL} gr, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{const char *}prefix, @code{const char *}font, @code{mreal} size)
++@end ifclear
++Печатает последнюю подобранную формулу с найденными коэффициентами в точке @var{p0}. Строка @var{prefix} будет напечатана перед формулой. Все другие параметры такие же как в @ref{Text printing}.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglGraph}} @code{const char *}GetFit ()
++@deftypefnx {Функция С} @code{const char *} mgl_get_fit (@code{HMGL} gr)
++@deftypefnx {Fortran процедура} @code{} mgl_get_fit (@code{long} gr, @code{char *}out, @code{int} len)
++Возвращает последнюю подобранную формулу с найденными коэффициентами.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{mreal} GetFitChi ()
++@deftypefnx {Функция С} @code{mreal} mgl_get_fit_chi ()
++Возвращает величину \chi для последней подобранной формулы.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglGraph}} @code{mreal} GetFitCovar ()
++@deftypefnx {Функция С} @code{mreal} mgl_get_fit_covar ()
++Возвращает ковариационную матрицу для последней подобранной формулы.
++@end deftypefn
++
++@end ifclear
++
++
++@c ##################################################################
++@external{}
++@node Data manipulation, , Nonlinear fitting, MathGL core
++@section Распределение данных
++@nav{}
++@cindex Hist
++@cindex Fill
++@cindex DataGrid
++
++@deftypefn {Команда MGL} {} hist @sc{res} xdat adat
++@deftypefnx {Команда MGL} {} hist @sc{res} xdat ydat adat
++@deftypefnx {Команда MGL} {} hist @sc{res} xdat ydat zdat adat
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Hist (@code{const mglDataA &}x, @code{const mglDataA &}a, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Hist (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}a, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} Hist (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}a, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{HMDT} mgl_hist_x (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} a, @code{const char *}opt)
++@deftypefnx {Функция С} @code{HMDT} mgl_hist_xy (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} a, @code{const char *}opt)
++@deftypefnx {Функция С} @code{HMDT} mgl_hist_xyz (@code{HMGL} gr, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} a, @code{const char *}opt)
++@end ifclear
++Создают распределения данных. Они не рисуют данные. Функции могут быть полезны в случае когда данные пользователя определены на случайно расположенных точка (например, после PIC расчетов) и он хочет построить график, требующий регулярных данных (данных на сетках). Диапазон сеток равен диапазону осей координат. Массивы @var{x}, @var{y}, @var{z} определяют положение (координаты) точек. Массив @var{a} задает значения данных. Число точек в результате @var{res} определяется опцией @code{value} (по умолчанию @var{mglFitPnts}=100).
++@end deftypefn
++
++
++@deftypefn {Команда MGL} {} fill dat 'eq'
++@deftypefnx {Команда MGL} {} fill dat 'eq' vdat
++@deftypefnx {Команда MGL} {} fill dat 'eq' vdat wdat
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Fill (@code{mglData &}u, @code{const char *}eq, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Fill (@code{mglData &}u, @code{const char *}eq, @code{const mglDataA &}v, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} Fill (@code{mglData &}u, @code{const char *}eq, @code{const mglDataA &}v, @code{const mglDataA &}w, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_data_fill_eq (@code{HMGL} gr, @code{HMDT} u, @code{const char *}eq, @code{HCDT}v, @code{HCDT}w, @code{const char *}opt)
++@end ifclear
++Заполняют значения массива @samp{u} в соответствии с формулой в строке @var{eq}. Формула -- произвольное выражение, зависящее от переменных @samp{x}, @samp{y}, @samp{z}, @samp{u}, @samp{v}, @samp{w}. Координаты @samp{x}, @samp{y}, @samp{z} полагаются в диапазоне изменения осей координат. Переменная @samp{u} -- значение исходного массива. Переменные @samp{v} и @samp{w} -- значения массивов @var{v}, @var{w}, которые могут быть @code{NULL} (т.е. могут быть опущены).
++@end deftypefn
++
++@deftypefn {Команда MGL} {} datagrid dat xdat ydat zdat
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{void} DataGrid (@code{mglData &}u, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_data_grid (@code{HMGL} gr, @code{HMDT} u, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}opt)
++@end ifclear
++Заполняет значения массива @samp{u} результатом линейной интерполяции по триангулированной поверхности, найденной по произвольно расположенным точкам @samp{x}, @samp{y}, @samp{z}. NAN значение используется для точек сетки вне триангулированной поверхности. @sref{Making regular data}
++@end deftypefn
++
++@deftypefn {Команда MGL} {} refill dat xdat vdat [sl=-1]
++@deftypefnx {Команда MGL} {} refill dat xdat ydat vdat [sl=-1]
++@deftypefnx {Команда MGL} {} refill dat xdat ydat zdat vdat
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Refill (@code{mglDataA &}dat, @code{const mglDataA &}x, @code{const mglDataA &}v, @code{long} sl=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglData}} @code{void} Refill (@code{mglDataA &}dat, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}v, @code{long} sl=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglData}} @code{void} Refill (@code{mglDataA &}dat, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}v, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_data_refill_gr (@code{HMGL} gr, @code{HMDT} a, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} v, @code{long} sl, @code{const char *}opt)
++@end ifclear
++Заполняет значениями интерполяции массива @var{v} в точках @{@var{x}, @var{y}, @var{z}@}=@{@code{X[i], Y[j], Z[k]}@} (или @{@var{x}, @var{y}, @var{z}@}=@{@code{X[i,j,k], Y[i,j,k], Z[i,j,k]}@} если @var{x}, @var{y}, @var{z} не 1d массивы), где @code{X,Y,Z} равномерно распределены в диапазоне осей координат и имеют такой же размер как и массив @var{dat}. Если параметр @var{sl} равен 0 или положительный, то изменятся будет только @var{sl}-ый срез.
++@end deftypefn
++
++
++
++@deftypefn {Команда MGL} {} pde @sc{res} 'ham' ini_re ini_im [@code{dz=0.1 k0=100}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglGraph}} @code{mglData} PDE (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{mreal} dz=@code{0.1}, @code{mreal} k0=@code{100}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{HMDT} mgl_pde_solve (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{mreal} dz, @code{mreal} k0, @code{const char *}opt)
++@end ifclear
++Решает уравнение в частных производных du/dz = i*k0*@var{ham}(p,q,x,y,z,|u|)[u], где p=-i/k0*d/dx, q=-i/k0*d/dy -- псевдо-дифференциальные оперторы. Параметры @var{ini_re}, @var{ini_im} задают действительную и мнимую часть начального распределения поля. Координаты @samp{x}, @samp{y}, @samp{z} полагаются в диапазоне изменения осей координат. Отмечу, ято в действительности этот диапазон увеличен на 3/2 для уменьшения отражения от границ сетки. Параметр @var{dz} задает шаг по эволюционной координате z. Сейчас используется упрощенный вид функции @var{ham} -- исключены все ``смешанные'' члены (типа @samp{x*p}->x*d/dx). Например, в 2D случае это функция вида @math{ham = f(p,z) + g(x,z,u)}. Однако, коммутирующие члены (типа @samp{x*q}->x*d/dy) разрешены. Переменная @samp{u} используется для амплитуды поля |u|, что позволяет решать нелинейные задачи -- например уравнение Шредингера @code{ham="p^2 + q^2 - u^2"}. Вы можете задавать мнимую часть для поглощения волн, например @code{ham = "p^2 + i*x*(x>0)"}, но только для линейной зависимости от переменной @samp{i} (т.е. @math{ham = hre+i*him}). @sref{PDE solving hints}
++@end deftypefn
++
++@c ##################################################################
++@c @external{}
++@c @node IDTF functions, , Data distributions, MathGL core
++@c @section IDTF функции
++@c @nav{}
++
++@c Эти функции обеспечивают поддержку особых возможностей при создании IDTF. Во всех прочих случаях они не делают ничего.
++
++@c @deftypefn {Метод класса @code{mglGraph}} @code{void} VertexColor (@code{bool} enable)
++@c Разрешает плавное изменение цвета.
++@c @end deftypefn
++
++@c @deftypefn {Метод класса @code{mglGraph}} @code{void} Compression (@code{bool} enable)
++@c Дает меньший объем файла, но с худшим качеством.
++@c @end deftypefn
++
++@c inline void DoubleSided(bool){} // NOTE: Add later -- IDTF
++@c inline void TextureColor(bool){} // NOTE: Add later -- IDTF
++
++@c @end ifclear
++
++@external{}
--- /dev/null
--- /dev/null
++@c ------------------------------------------------------------------
++@chapter Data processing
++@nav{}
++
++@ifset UDAV
++This chapter describe commands for allocation, resizing, loading and saving, modifying of data arrays. Also it can numerically differentiate and integrate data, interpolate, fill data by formula and so on. Class supports data with dimensions up to 3 (like function of 3 variables -- x,y,z). Data arrays are denoted by Small Caps (like @sc{dat}) if it can be (re-)created by MGL commands.
++@end ifset
++
++@ifclear UDAV
++This chapter describe classes @code{mglData} and @code{mglDataC} for working with data arrays of real and complex numbers. Both classes are derived from abstract class @code{mglDataA}, and can be used as arguments of any plotting functions (see @ref{MathGL core}). These classes are defined in @code{#include <mgl2/data.h>} and @code{#include <mgl2/datac.h>} correspondingly. The classes have mostly the same set of functions for easy and safe allocation, resizing, loading, saving, modifying of data arrays. Also it can numerically differentiate and integrate data, interpolate, fill data by formula and so on. Classes support data with dimensions up to 3 (like function of 3 variables -- x,y,z). The internal representation of numbers is mreal (or dual=std::complex<mreal> for @code{mglDataC}), which can be configured as float or double by selecting option @code{--enable-double} at the MathGL configuring (see @ref{Installation}). Float type have smaller size in memory and usually it has enough precision in plotting purposes. However, double type provide high accuracy what can be important for time-axis, for example. Data arrays are denoted by Small Caps (like @sc{dat}) if it can be (re-)created by MGL commands.
++@end ifclear
++
++@menu
++* Public variables::
++* Data constructor::
++* Data resizing::
++* Data filling::
++* File I/O::
++* Make another data::
++* Data changing::
++* Interpolation::
++* Data information::
++* Operators::
++* Global functions::
++* Evaluate expression::
++* Special data classes::
++@end menu
++
++@c ------------------------------------------------------------------
++@external{}
++@node Public variables, Data constructor, , Data processing
++@section Public variables
++@nav{}
++
++@ifset UDAV
++MGL don't support direct access to data arrays. See section @ref{Data filling}
++@end ifset
++
++@ifclear UDAV
++@deftypecv {Variable} mglData @code{mreal *} a
++@deftypecvx {Variable} mglDataC @code{dual *} a
++Data array itself. The flat data representation is used. For example, matrix [nx x ny] is presented as flat (1d-) array with length nx*ny. The element with indexes @{i, j, k@} is a[i+nx*j+nx*ny*k] (indexes are zero based).
++@end deftypecv
++@deftypecv {Variable} mglData @code{long} nx
++@deftypecvx {Variable} mglDataC @code{long} nx
++Number of points in 1st dimensions ('x' dimension).
++@end deftypecv
++@deftypecv {Variable} mglData @code{long} ny
++@deftypecvx {Variable} mglDataC @code{long} ny
++Number of points in 2nd dimensions ('y' dimension).
++@end deftypecv
++@deftypecv {Variable} mglData @code{long} nz
++@deftypecvx {Variable} mglDataC @code{long} nz
++Number of points in 3d dimensions ('z' dimension).
++@end deftypecv
++@deftypecv {Variable} mglData @code{std::string} id
++@deftypecvx {Variable} mglDataC @code{std::string} id
++Names of column (or slice if nz>1) -- one character per column.
++@end deftypecv
++@deftypecv {Variable} mglData @code{bool} link
++@deftypecvx {Variable} mglDataC @code{bool} link
++Flag to use external data, i.e. don't delete it.
++@end deftypecv
++
++@deftypecv {Variable} mglDataA @code{std::wstring} s
++Name of data. It is used in parsing of MGL scripts.
++@end deftypecv
++@deftypecv {Variable} mglDataA @code{bool} temp
++Flag of temporary variable, which should be deleted.
++@end deftypecv
++@deftypecv {Variable} mglDataA @code{void (*)(void *)} func
++Pointer to callback function which will be called at destroying.
++@end deftypecv
++@deftypecv {Variable} mglDataA @code{void *} o
++Pointer to object for callback function.
++@end deftypecv
++
++
++@deftypefn {Method on @code{mglData}} @code{mreal} GetVal (@code{long} i)
++@deftypefnx {Method on @code{mglDataC}} @code{mreal} GetVal (@code{long} i)
++@deftypefnx {Method on @code{mglData}} @code{void} SetVal (@code{mreal} val, @code{long} i)
++@deftypefnx {Method on @code{mglDataC}} @code{void} SetVal (@code{mreal} val, @code{long} i)
++Gets or sets the value in by "flat" index @var{i} without border checking. Index @var{i} should be in range [0, nx*ny*nz-1].
++@end deftypefn
++
++@deftypefn {Method on @code{mglDataA}} @code{long} GetNx ()
++@deftypefnx {Method on @code{mglDataA}} @code{long} GetNy ()
++@deftypefnx {Method on @code{mglDataA}} @code{long} GetNz ()
++@deftypefnx {C function} @code{long} mgl_data_get_nx (@code{HCDT} dat)
++@deftypefnx {C function} @code{long} mgl_data_get_ny (@code{HCDT} dat)
++@deftypefnx {C function} @code{long} mgl_data_get_nz (@code{HCDT} dat)
++Gets the x-, y-, z-size of the data.
++@end deftypefn
++
++@deftypefn {C function} @code{mreal} mgl_data_get_value (@code{HCDT} dat, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {C function} @code{dual} mgl_datac_get_value (@code{HCDT} dat, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {C function} @code{mreal *} mgl_data_value (@code{HMDT} dat, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {C function} @code{dual *} mgl_datac_value (@code{HADT} dat, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {C function} @code{void} mgl_data_set_value (@code{HMDT} dat, @code{mreal} v, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {C function} @code{void} mgl_datac_set_value (@code{HADT} dat, @code{dual} v, @code{int} i, @code{int} j, @code{int} k)
++Gets or sets the value in specified cell of the data with border checking.
++@end deftypefn
++@deftypefn {C function} @code{const mreal *} mgl_data_data (@code{HCDT} dat)
++@deftypefnx {C function} @code{const dual *} mgl_datac_data (@code{HCDT} dat)
++Returns pointer to internal data array.
++@end deftypefn
++
++@deftypefn {C function only} @code{void} mgl_data_set_func (@code{mglDataA *}dat, @code{void (*}func@code{)(void *)}, @code{void *}par)
++Set pointer to callback function which will be called at destroying.
++@end deftypefn
++
++@deftypefn {C function} @code{void} mgl_data_set_name (@code{mglDataA *}dat, @code{const char *}name)
++@deftypefnx {C function} @code{void} mgl_data_set_name_w (@code{mglDataA *}dat, @code{const wchar_t *}name)
++Set name of data, which used in parsing of MGL scripts.
++@end deftypefn
++
++@end ifclear
++
++@c ------------------------------------------------------------------
++@external{}
++@node Data constructor, Data resizing, Public variables, Data processing
++@section Data constructor
++@nav{}
++@cindex mglData
++
++@ifset UDAV
++There are many functions, which can create data for output (see @ref{Data filling}, @ref{File I/O}, @ref{Make another data}, @ref{Global functions}). Here I put most useful of them.
++@end ifset
++
++@anchor{new}
++@deftypefn {MGL command} {} new @sc{dat} [@code{nx=1} 'eq']
++@deftypefnx {MGL command} {} new @sc{dat} @code{nx ny} ['eq']
++@deftypefnx {MGL command} {} new @sc{dat} @code{nx ny nz} ['eq']
++@ifclear UDAV
++@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{int} mx=@code{1}, @code{int} my=@code{1}, @code{int} mz=@code{1})
++@deftypefnx {Constructor on @code{mglDataC}} {} mglDataC (@code{int} mx=@code{1}, @code{int} my=@code{1}, @code{int} mz=@code{1})
++@deftypefnx {C function} @code{HMDT} mgl_create_data ()
++@deftypefnx {C function} @code{HMDT} mgl_create_data_size (@code{int} mx, @code{int} my, @code{int} mz)
++@deftypefnx {C function} @code{HADT} mgl_create_datac ()
++@deftypefnx {C function} @code{HADT} mgl_create_datac_size (@code{int} mx, @code{int} my, @code{int} mz)
++@end ifclear
++Default constructor. Allocates the memory for data array and initializes it by zero. If string @var{eq} is specified then data will be filled by corresponding formula as in @ref{fill}.
++@end deftypefn
++
++@anchor{copy}
++@deftypefn {MGL command} {} copy @sc{dat} dat2 ['eq'='']
++@deftypefnx {MGL command} {} copy @sc{dat} @code{val}
++@ifclear UDAV
++@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{const mglDataA &}dat2)
++@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{const mglDataA *}dat2)
++@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{int} size, @code{const float *}dat2)
++@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{int} size, @code{int} cols, @code{const float *}dat2)
++@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{int} size, @code{const double *}dat2)
++@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{int} size, @code{int} cols, @code{const double *}dat2)
++@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{const double *}dat2, @code{int} size)
++@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{const double *}dat2, @code{int} size, @code{int} cols)
++@deftypefnx {Constructor on @code{mglDataC}} {} mglDataC (@code{const mglDataA &}dat2)
++@deftypefnx {Constructor on @code{mglDataC}} {} mglDataC (@code{const mglDataA *}dat2)
++@deftypefnx {Constructor on @code{mglDataC}} {} mglDataC (@code{int} size, @code{const float *}dat2)
++@deftypefnx {Constructor on @code{mglDataC}} {} mglDataC (@code{int} size, @code{int} cols, @code{const float *}dat2)
++@deftypefnx {Constructor on @code{mglDataC}} {} mglDataC (@code{int} size, @code{const double *}dat2)
++@deftypefnx {Constructor on @code{mglDataC}} {} mglDataC (@code{int} size, @code{int} cols, @code{const double *}dat2)
++@deftypefnx {Constructor on @code{mglDataC}} {} mglDataC (@code{int} size, @code{const dual *}dat2)
++@deftypefnx {Constructor on @code{mglDataC}} {} mglDataC (@code{int} size, @code{int} cols, @code{const dual *}dat2)
++@end ifclear
++Copy constructor. Allocates the memory for data array and copy values from other array. At this, if parameter @var{eq} or @var{val} is specified then the data will be modified by corresponding formula similarly to @ref{fill}.
++@end deftypefn
++
++@deftypefn {MGL command} {} copy @sc{redat} @sc{imdat} dat2 ['eq'='']
++Allocates the memory for data array and copy real and imaginary values from complex array @var{dat2}.
++@end deftypefn
++
++@deftypefn {MGL command} {} copy 'name'
++Allocates the memory for data array and copy values from other array specified by its name, which can be "invalid" for MGL names (like one read from HDF5 files).
++@end deftypefn
++
++
++@deftypefn {MGL command} {} read @sc{dat} 'fname'
++@ifclear UDAV
++@deftypefnx {Constructor on @code{mglData}} {} mglData (@code{const char *}fname)
++@deftypefnx {Constructor on @code{mglDataC}} {} mglDataC (@code{const char *}fname)
++@deftypefnx {C function} @code{HMDT} mgl_create_data_file (@code{const char *}fname)
++@deftypefnx {C function} @code{HADT} mgl_create_datac_file (@code{const char *}fname)
++@end ifclear
++Reads data from tab-separated text file with auto determining sizes of the data.
++@end deftypefn
++
++@deftypefn {MGL command} {} delete dat
++@deftypefnx {MGL command} {} delete 'name'
++@ifclear UDAV
++@deftypefnx {Destructor on @code{mglData}} {} ~mglData ()
++@deftypefnx {C function} @code{void} mgl_delete_data (@code{HMDT} dat)
++@deftypefnx {Destructor on @code{mglDataC}} {} ~mglDataC ()
++@deftypefnx {C function} @code{void} mgl_delete_datac (@code{HADT} dat)
++@end ifclear
++Deletes the data array from memory.
++@end deftypefn
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node Data resizing, Data filling, Data constructor, Data processing
++@section Data resizing
++@nav{}
++@cindex Create
++@cindex Rearrange
++@cindex Extend
++@cindex Transpose
++@cindex Squeeze
++@cindex Crop
++@cindex Insert
++@cindex Delete
++@cindex Sort
++@cindex Clean
++@cindex Join
++
++@deftypefn {MGL command} {} new @sc{dat} [@code{nx=1 ny=1 nz=1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Create (@code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Create (@code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1})
++@deftypefnx {C function} @code{void} mgl_data_create (@code{HMDT} dat, @code{int} mx, @code{int} my, @code{int} mz)
++@deftypefnx {C function} @code{void} mgl_datac_create (@code{HADT} dat, @code{int} mx, @code{int} my, @code{int} mz)
++@end ifclear
++Creates or recreates the array with specified size and fills it by zero. This function does nothing if one of parameters @var{mx}, @var{my}, @var{mz} is zero or negative.
++@end deftypefn
++
++@anchor{rearrange}
++@deftypefn {MGL command} {} rearrange dat @code{mx [my=0 mz=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Rearrange (@code{int} mx, @code{int} my=@code{0}, @code{int} mz=@code{0})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Rearrange (@code{int} mx, @code{int} my=@code{0}, @code{int} mz=@code{0})
++@deftypefnx {C function} @code{void} mgl_data_rearrange (@code{HMDT} dat, @code{int} mx, @code{int} my, @code{int} mz)
++@deftypefnx {C function} @code{void} mgl_datac_rearrange (@code{HADT} dat, @code{int} mx, @code{int} my, @code{int} mz)
++@end ifclear
++Rearrange dimensions without changing data array so that resulting sizes should be @var{mx}*@var{my}*@var{mz} < nx*ny*nz. If some of parameter @var{my} or @var{mz} are zero then it will be selected to optimal fill of data array. For example, if @var{my}=0 then it will be change to @var{my}=nx*ny*nz/@var{mx} and @var{mz}=1.
++@end deftypefn
++
++@anchor{transpose}
++@deftypefn {MGL command} {} transpose dat ['dim'='yxz']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Transpose (@code{const char *}dim=@code{"yx"})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Transpose (@code{const char *}dim=@code{"yx"})
++@deftypefnx {C function} @code{void} mgl_data_transpose (@code{HMDT} dat, @code{const char *}dim)
++@deftypefnx {C function} @code{void} mgl_datac_transpose (@code{HADT} dat, @code{const char *}dim)
++@end ifclear
++Transposes (shift order of) dimensions of the data. New order of dimensions is specified in string @var{dim}. This function can be useful also after reading of one-dimensional data.
++@end deftypefn
++
++@anchor{extend}
++@deftypefn {MGL command} {} extend dat @code{n1 [n2=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Extend (@code{int} n1, @code{int} n2=@code{0})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Extend (@code{int} n1, @code{int} n2=@code{0})
++@deftypefnx {C function} @code{void} mgl_data_extend (@code{HMDT} dat, @code{int} n1, @code{int} n2)
++@deftypefnx {C function} @code{void} mgl_datac_extend (@code{HADT} dat, @code{int} n1, @code{int} n2)
++@end ifclear
++Increase the dimensions of the data by inserting new (|@var{n1}|+1)-th slices after (for @var{n1}>0) or before (for @var{n1}<0) of existed one. It is possible to insert 2 dimensions simultaneously for 1d data by using parameter @var{n2}. Data to new slices is copy from existed one. For example, for @var{n1}>0 new array will be
++@iftex
++@math{a_{ij}^{new} = a_i^{old}} where j=0...@var{n1}. Correspondingly, for @var{n1}<0 new array will be @math{a_{ij}^{new} = a_j^{old}} where i=0...|@var{n1}|.
++@end iftex
++@ifnottex
++a_ij^new = a_i^old where j=0...@var{n1}. Correspondingly, for @var{n1}<0 new array will be a_ij^new = a_j^old where i=0...|@var{n1}|.
++@end ifnottex
++@end deftypefn
++
++@anchor{squeeze}
++@deftypefn {MGL command} {} squeeze dat @code{rx [ry=1 rz=1 sm=off]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Squeeze (@code{int} rx, @code{int} ry=@code{1}, @code{int} rz=@code{1}, @code{bool} smooth=@code{false})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Squeeze (@code{int} rx, @code{int} ry=@code{1}, @code{int} rz=@code{1}, @code{bool} smooth=@code{false})
++@deftypefnx {C function} @code{void} mgl_data_squeeze (@code{HMDT} dat, @code{int} rx, @code{int} ry, @code{int} rz, @code{int} smooth)
++@deftypefnx {C function} @code{void} mgl_datac_squeeze (@code{HADT} dat, @code{int} rx, @code{int} ry, @code{int} rz, @code{int} smooth)
++@end ifclear
++Reduces the data size by excluding data elements which indexes are not divisible by @var{rx}, @var{ry}, @var{rz} correspondingly. Parameter @var{smooth} set to use smoothing
++@iftex
++(i.e. @math{a_{out}[i]=\sum_{j=i,i+r}a[j]/r}) or not (i.e. @math{a_{out}[i]=a[j*r]}).
++@end iftex
++@ifnottex
++(i.e. out[i]=\sum_@{j=i,i+r@} a[j]/r) or not (i.e. out[i]=a[j*r]).
++@end ifnottex
++@end deftypefn
++
++@anchor{crop}
++@deftypefn {MGL command} {} crop dat @code{n1 n2} 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Crop (@code{int} n1, @code{int} n2, @code{char} dir=@code{'x'})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Crop (@code{int} n1, @code{int} n2, @code{char} dir=@code{'x'})
++@deftypefnx {C function} @code{void} mgl_data_crop (@code{HMDT} dat, @code{int} n1, @code{int} n2, @code{char} dir)
++@deftypefnx {C function} @code{void} mgl_datac_crop (@code{HADT} dat, @code{int} n1, @code{int} n2, @code{char} dir)
++@end ifclear
++Cuts off edges of the data @var{i}<@var{n1} and @var{i}>@var{n2} if @var{n2}>0 or @var{i}>@code{n[xyz]}-@var{n2} if @var{n2}<=0 along direction @var{dir}.
++@end deftypefn
++
++@deftypefn {MGL command} {} crop dat 'how'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Crop (@code{const char *}how=@code{"235x"})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Crop (@code{const char *}how=@code{"235x"})
++@deftypefnx {C function} @code{void} mgl_data_crop_opt (@code{HMDT} dat, @code{const char *}how)
++@deftypefnx {C function} @code{void} mgl_datac_crop_opt (@code{HADT} dat, @code{const char *}how)
++@end ifclear
++Cuts off far edge of the data to be more optimal for fast Fourier transform. The resulting size will be the closest value of 2^n*3^m*5^l to the original one. The string @var{how} may contain: @samp{x}, @samp{y}, @samp{z} for directions, and @samp{2}, @samp{3}, @samp{5} for using corresponding bases.
++@end deftypefn
++
++@anchor{insert}
++@deftypefn {MGL command} {} insert dat 'dir' @code{[pos=off num=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Insert (@code{char} dir, @code{int} pos=@code{0}, @code{int} num=@code{1})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Insert (@code{char} dir, @code{int} pos=@code{0}, @code{int} num=@code{1})
++@deftypefnx {C function} @code{void} mgl_data_insert (@code{HMDT} dat, @code{char} dir, @code{int} pos, @code{char} num)
++@deftypefnx {C function} @code{void} mgl_datac_insert (@code{HADT} dat, @code{char} dir, @code{int} pos, @code{char} num)
++@end ifclear
++Insert @var{num} slices along @var{dir}-direction at position @var{pos} and fill it by zeros.
++@end deftypefn
++
++@anchor{delete}
++@deftypefn {MGL command} {} delete dat 'dir' @code{[pos=off num=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Delete (@code{char} dir, @code{int} pos=@code{0}, @code{int} num=@code{1})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Delete (@code{char} dir, @code{int} pos=@code{0}, @code{int} num=@code{1})
++@deftypefnx {C function} @code{void} mgl_data_delete (@code{HMDT} dat, @code{char} dir, @code{int} pos, @code{char} num)
++@deftypefnx {C function} @code{void} mgl_datac_delete (@code{HADT} dat, @code{char} dir, @code{int} pos, @code{char} num)
++@end ifclear
++Delete @var{num} slices along @var{dir}-direction at position @var{pos}.
++@end deftypefn
++
++@deftypefn {MGL command} {} delete dat
++@deftypefnx {MGL command} {} delete 'name'
++Deletes the whole data array.
++@end deftypefn
++
++@anchor{sort}
++@deftypefn {MGL command} {} sort dat @code{idx [idy=-1]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Sort (@code{lond} idx, @code{long} idy=@code{-1})
++@deftypefnx {C function} @code{void} mgl_data_sort (@code{HMDT} dat, @code{lond} idx, @code{long} idy)
++@end ifclear
++Sort data rows (or slices in 3D case) by values of specified column @var{idx} (or cell @{@var{idx},@var{idy}@} for 3D case). Note, this function is not thread safe!
++@end deftypefn
++
++@anchor{clean}
++@deftypefn {MGL command} {} clean dat @code{idx}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Clean (@code{lond} idx)
++@deftypefnx {C function} @code{void} mgl_data_clean (@code{HMDT} dat, @code{lond} idx)
++@end ifclear
++Delete rows which values are equal to next row for given column @var{idx}.
++@end deftypefn
++
++@anchor{join}
++@deftypefn {MGL command} {} join dat vdat [v2dat ...]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Join (@code{const mglDataA &}vdat)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Join (@code{const mglDataA &}vdat)
++@deftypefnx {C function} @code{void} mgl_data_join (@code{HMDT} dat, @code{HCDT} vdat)
++@deftypefnx {C function} @code{void} mgl_datac_join (@code{HADT} dat, @code{HCDT} vdat)
++@end ifclear
++Join data cells from @var{vdat} to @var{dat}. At this, function increase @var{dat} sizes according following: z-size for data arrays arrays with equal x-,y-sizes; or y-size for data arrays with equal x-sizes; or x-size otherwise.
++@end deftypefn
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node Data filling, File I/O, Data resizing, Data processing
++@section Data filling
++@nav{}
++@cindex Fill
++@cindex Modify
++@cindex Set
++@cindex List
++@cindex Var
++@cindex Refill
++
++@anchor{list}
++@deftypefn {MGL command} {} list @sc{dat} @code{v1 ...}
++Creates new variable with name @var{dat} and fills it by numeric values of command arguments @code{v1 ...}. Command can create one-dimensional and two-dimensional arrays with arbitrary values. For creating 2d array the user should use delimiter @samp{|} which means that the following values lie in next row. Array sizes are [maximal of row sizes * number of rows]. For example, command @code{list 1 | 2 3} creates the array [1 0; 2 3]. Note, that the maximal number of arguments is 1000.
++@end deftypefn
++@deftypefn {MGL command} {} list @sc{dat} d1 ...
++Creates new variable with name @var{dat} and fills it by data values of arrays of command arguments @var{d1 ...}. Command can create two-dimensional or three-dimensional (if arrays in arguments are 2d arrays) arrays with arbitrary values. Minor dimensions of all arrays in arguments should be equal to dimensions of first array d1. In the opposite case the argument will be ignored. Note, that the maximal number of arguments is 1000.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglData}} @code{void} Set (@code{const float *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {Method on @code{mglData}} @code{void} Set (@code{const double *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {C function} @code{void} mgl_data_set_float (@code{HMDT} dat, @code{const mreal *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++@deftypefnx {C function} @code{void} mgl_data_set_double (@code{HMDT} dat, @code{const double *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{const float *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{const double *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{const dual *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {C function} @code{void} mgl_datac_set_float (@code{HADT} dat, @code{const mreal *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++@deftypefnx {C function} @code{void} mgl_datac_set_double (@code{HADT} dat, @code{const double *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++@deftypefnx {C function} @code{void} mgl_datac_set_complex (@code{HADT} dat, @code{const dual *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++Allocates memory and copies the data from the @strong{flat} @code{float*} or @code{double*} array.
++@end deftypefn
++
++@deftypefn {Method on @code{mglData}} @code{void} Set (@code{const float **}A, @code{int} N1, @code{int} N2)
++@deftypefnx {Method on @code{mglData}} @code{void} Set (@code{const double **}A, @code{int} N1, @code{int} N2)
++@deftypefnx {C function} @code{void} mgl_data_set_mreal2 (@code{HMDT} dat, @code{const mreal **}A, @code{int} N1, @code{int} N2)
++@deftypefnx {C function} @code{void} mgl_data_set_double2 (@code{HMDT} dat, @code{const double **}A, @code{int} N1, @code{int} N2)
++Allocates memory and copies the data from the @code{float**} or @code{double**} array with dimensions @var{N1}, @var{N2}, i.e. from array defined as @code{mreal a[N1][N2];}.
++@end deftypefn
++
++@deftypefn {Method on @code{mglData}} @code{void} Set (@code{const float ***}A, @code{int} N1, @code{int} N2)
++@deftypefnx {Method on @code{mglData}} @code{void} Set (@code{const double ***}A, @code{int} N1, @code{int} N2)
++@deftypefnx {C function} @code{void} mgl_data_set_mreal3 (@code{HMDT} dat, @code{const mreal ***}A, @code{int} N1, @code{int} N2)
++@deftypefnx {C function} @code{void} mgl_data_set_double3 (@code{HMDT} dat, @code{const double ***}A, @code{int} N1, @code{int} N2)
++Allocates memory and copies the data from the @code{float***} or @code{double***} array with dimensions @var{N1}, @var{N2}, @var{N3}, i.e. from array defined as @code{mreal a[N1][N2][N3];}.
++@end deftypefn
++
++@deftypefn {Method on @code{mglData}} @code{void} Set (@code{gsl_vector *}v)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{gsl_vector *}v)
++@deftypefnx {C function} @code{void} mgl_data_set_vector (@code{HMDT} dat, @code{gsl_vector *}v)
++@deftypefnx {C function} @code{void} mgl_datac_set_vector (@code{HADT} dat, @code{gsl_vector *}v)
++Allocates memory and copies the data from the @code{gsl_vector *} structure.
++@end deftypefn
++@deftypefn {Method on @code{mglData}} @code{void} Set (@code{gsl_matrix *}m)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{gsl_matrix *}m)
++@deftypefnx {C function} @code{void} mgl_data_set_matrix (@code{HMDT} dat, @code{gsl_matrix *}m)
++@deftypefnx {C function} @code{void} mgl_datac_set_matrix (@code{HADT} dat, @code{gsl_matrix *}m)
++Allocates memory and copies the data from the @code{gsl_matrix *} structure.
++@end deftypefn
++
++@deftypefn {Method on @code{mglData}} @code{void} Set (@code{const mglDataA &}from)
++@deftypefnx {Method on @code{mglData}} @code{void} Set (@code{HCDT} from)
++@deftypefnx {C function} @code{void} mgl_data_set (@code{HMDT} dat, @code{HCDT} from)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{const mglDataA &}from)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{HCDT} from)
++@deftypefnx {C function} @code{void} mgl_datac_set (@code{HADT} dat, @code{HCDT} from)
++Copies the data from @code{mglData} (or @code{mglDataA}) instance @var{from}.
++@end deftypefn
++
++@deftypefn {Method on @code{mglDataC}} @code{void} Set (@code{const mglDataA &}re, @code{const mglDataA &}im)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{HCDT} re, @code{HCDT} im)
++@deftypefnx {Method on @code{mglDataC}} @code{void} SetAmpl (@code{HCDT} ampl, @code{const mglDataA &}phase)
++@deftypefnx {C function} @code{void} mgl_datac_set_ri (@code{HADT} dat, @code{HCDT} re, @code{HCDT} im)
++@deftypefnx {C function} @code{void} mgl_datac_set_ap (@code{HADT} dat, @code{HCDT} ampl, @code{HCDT} phase)
++Copies the data from @code{mglData} instances for real and imaginary parts of complex data arrays.
++@end deftypefn
++
++@deftypefn {Method on @code{mglData}} @code{void} Set (@code{const std::vector<int> &}d)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{const std::vector<int> &}d)
++@deftypefnx {Method on @code{mglData}} @code{void} Set (@code{const std::vector<float> &}d)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{const std::vector<float> &}d)
++@deftypefnx {Method on @code{mglData}} @code{void} Set (@code{const std::vector<double> &}d)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{const std::vector<double> &}d)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{const std::vector<dual> &}d)
++Allocates memory and copies the data from the @code{std::vector<T>} array.
++@end deftypefn
++
++@deftypefn {Method on @code{mglData}} @code{void} Set (@code{const char *}str, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {C function} @code{void} mgl_data_set_values (@code{const char *}str, @code{int} NX, @code{int} NY, @code{int} NZ)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Set (@code{const char *}str, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {C function} @code{void} mgl_datac_set_values (@code{const char *}str, @code{int} NX, @code{int} NY, @code{int} NZ)
++Allocates memory and scanf the data from the string.
++@end deftypefn
++
++
++@deftypefn {Method on @code{mglData}} @code{void} SetList (@code{long} n, ...)
++Allocate memory and set data from variable argument list of @emph{double} values. Note, you need to specify decimal point @samp{.} for integer values! For example, the code @code{SetList(2,0.,1.);} is correct, but the code @code{SetList(2,0,1);} is incorrect.
++@end deftypefn
++
++
++
++@deftypefn {Method on @code{mglData}} @code{void} Link (@code{mglData &}from)
++@deftypefnx {Method on @code{mglData}} @code{void} Link (@code{mreal *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {C function} @code{void} mgl_data_link (@code{HMDT} dat, @code{mreal *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Link (@code{mglDataC &}from)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Link (@code{dual *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {C function} @code{void} mgl_datac_link (@code{HADT} dat, @code{dual *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++Links external data array, i.e. don't delete this array at exit.
++@end deftypefn
++@end ifclear
++
++@anchor{var}
++@deftypefn {MGL command} {} var @sc{dat} @code{num v1 [v2=nan]}
++Creates new variable with name @var{dat} for one-dimensional array of size @var{num}. Array elements are equidistantly distributed in range [@var{v1}, @var{v2}]. If @var{v2}=@code{nan} then @var{v2=v1} is used.
++@end deftypefn
++
++@anchor{fill}
++@deftypefn {MGL command} {} fill dat v1 v2 ['dir'='x']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Fill (@code{mreal} v1, @code{mreal} v2, @code{char} dir=@code{'x'})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Fill (@code{dual} v1, @code{dual} v2, @code{char} dir=@code{'x'})
++@deftypefnx {C function} @code{void} mgl_data_fill (@code{HMDT} dat, @code{mreal} v1, @code{mreal} v2, @code{char} dir)
++@deftypefnx {C function} @code{void} mgl_datac_fill (@code{HADT} dat, @code{dual} v1, @code{dual} v2, @code{char} dir)
++@end ifclear
++Equidistantly fills the data values to range [@var{v1}, @var{v2}] in direction @var{dir}=@{@samp{x},@samp{y},@samp{z}@}.
++@end deftypefn
++
++@deftypefn {MGL command} {} fill dat 'eq' [vdat wdat]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglData}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const mglDataA &}vdat, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglData}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const mglDataA &}vdat, @code{const mglDataA &}wdat, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const mglDataA &}vdat, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const mglDataA &}vdat, @code{const mglDataA &}wdat, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_data_fill_eq (@code{HMGL} gr, @code{HMDT} dat, @code{const char *}eq, @code{HCDT} vdat, @code{HCDT} wdat, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_datac_fill_eq (@code{HMGL} gr, @code{HADT} dat, @code{const char *}eq, @code{HCDT} vdat, @code{HCDT} wdat, @code{const char *}opt)
++@end ifclear
++Fills the value of array according to the formula in string @var{eq}. Formula is an arbitrary expression depending on variables @samp{x}, @samp{y}, @samp{z}, @samp{u}, @samp{v}, @samp{w}. Coordinates @samp{x}, @samp{y}, @samp{z} are supposed to be normalized in axis range of canvas @var{gr} (in difference from @code{Modify} functions). Variable @samp{u} is the original value of the array. Variables @samp{v} and @samp{w} are values of @var{vdat}, @var{wdat} which can be @code{NULL} (i.e. can be omitted).
++@end deftypefn
++
++@anchor{modify}
++@deftypefn {MGL command} {} modify dat 'eq' [@code{dim=0}]
++@deftypefnx {MGL command} {} modify dat 'eq' vdat [wdat]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Modify (@code{const char *}eq, @code{int} dim=@code{0})
++@deftypefnx {Method on @code{mglData}} @code{void} Modify (@code{const char *}eq, @code{const mglDataA &}v)
++@deftypefnx {Method on @code{mglData}} @code{void} Modify (@code{const char *}eq, @code{const mglDataA &}v, @code{const mglDataA &}w)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Modify (@code{const char *}eq, @code{int} dim=@code{0})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Modify (@code{const char *}eq, @code{const mglDataA &}v)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Modify (@code{const char *}eq, @code{const mglDataA &}v, @code{const mglDataA &}w)
++@deftypefnx {C function} @code{void} mgl_data_modify (@code{HMDT} dat, @code{const char *}eq, @code{int} dim)
++@deftypefnx {C function} @code{void} mgl_data_modify_vw (@code{HMDT} dat, @code{const char *}eq, @code{HCDT} v, @code{HCDT} w)
++@deftypefnx {C function} @code{void} mgl_datac_modify (@code{HADT} dat, @code{const char *}eq, @code{int} dim)
++@deftypefnx {C function} @code{void} mgl_datac_modify_vw (@code{HADT} dat, @code{const char *}eq, @code{HCDT} v, @code{HCDT} w)
++@end ifclear
++The same as previous ones but coordinates @samp{x}, @samp{y}, @samp{z} are supposed to be normalized in range [0,1]. If @var{dim}>0 is specified then modification will be fulfilled only for slices >=@var{dim}.
++@end deftypefn
++
++@anchor{fillsample}
++@deftypefn {MGL command} {} fillsample dat 'how'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} FillSample (@code{const char *}how)
++@deftypefnx {C function} @code{void} mgl_data_fill_sample (@code{HMDT} a, @code{const char *}how)
++@end ifclear
++Fills data by 'x' or 'k' samples for Hankel ('h') or Fourier ('f') transform.
++@end deftypefn
++
++
++@anchor{datagrid}
++@deftypefn {MGL command} {} datagrid dat xdat ydat zdat
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Grid (@code{HMGL} gr, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglData}} @code{mglData} Grid (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{mglPoint} p1, @code{mglPoint} p2)
++@deftypefnx {C function} @code{void} mgl_data_grid (@code{HMGL} gr, @code{HMDT} u, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}opt)
++@deftypefnx {C function} @code{void} mgl_data_grid_xy (@code{HMDT} u, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2)
++@end ifclear
++Fills the value of array according to the linear interpolation of triangulated surface assuming x-,y-coordinates equidistantly distributed in axis range (or in range [x1,x2]*[y1,y2]). Triangulated surface is found for arbitrary placed points @samp{x}, @samp{y}, @samp{z}. NAN value is used for grid points placed outside of triangulated surface. @sref{Making regular data}
++@end deftypefn
++
++
++@anchor{put}
++@deftypefn {MGL command} {} put dat @code{val [i=all j=all k=all]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Put (@code{mreal} val, @code{int} i=@code{-1}, @code{int} j=@code{-1}, @code{int} k=@code{-1})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Put (@code{dual} val, @code{int} i=@code{-1}, @code{int} j=@code{-1}, @code{int} k=@code{-1})
++@deftypefnx {C function} @code{void} mgl_data_put_val (@code{HMDT} a, @code{mreal} val, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {C function} @code{void} mgl_datac_put_val (@code{HADT} a, @code{dual} val, @code{int} i, @code{int} j, @code{int} k)
++@end ifclear
++Sets value(s) of array a[@var{i}, @var{j}, @var{k}] = @var{val}. Negative indexes @var{i}, @var{j}, @var{k}=-1 set the value @var{val} to whole range in corresponding direction(s). For example, @code{Put(val,-1,0,-1);} sets a[i,0,j]=@var{val} for i=0...(nx-1), j=0...(nz-1).
++@end deftypefn
++
++@deftypefn {MGL command} {} put dat vdat [@code{i=all j=all k=all}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Put (@code{const mglDataA &}v, @code{int} i=@code{-1}, @code{int} j=@code{-1}, @code{int} k=@code{-1})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Put (@code{const mglDataA &}v, @code{int} i=@code{-1}, @code{int} j=@code{-1}, @code{int} k=@code{-1})
++@deftypefnx {C function} @code{void} mgl_data_put_dat (@code{HMDT} a, @code{HCDT} v, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {C function} @code{void} mgl_datac_put_dat (@code{HADT} a, @code{HCDT} v, @code{int} i, @code{int} j, @code{int} k)
++@end ifclear
++Copies value(s) from array @var{v} to the range of original array. Negative indexes @var{i}, @var{j}, @var{k}=-1 set the range in corresponding direction(s). At this minor dimensions of array @var{v} should be large than corresponding dimensions of this array. For example, @code{Put(v,-1,0,-1);} sets a[i,0,j]=v.ny>nz ? v[i,j] : v[i], where i=0...(nx-1), j=0...(nz-1) and condition v.nx>=nx is true.
++@end deftypefn
++
++@anchor{refill}
++@deftypefn {MGL command} {} refill dat xdat vdat [sl=-1]
++@deftypefnx {MGL command} {} refill dat xdat ydat vdat [sl=-1]
++@deftypefnx {MGL command} {} refill dat xdat ydat zdat vdat
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Refill (@code{const mglDataA &}x, @code{const mglDataA &}v, @code{mreal} x1, @code{mreal} x2, @code{long} sl=@code{-1})
++@deftypefnx {Method on @code{mglData}} @code{void} Refill (@code{const mglDataA &}x, @code{const mglDataA &}v, @code{mglPoint} p1, @code{mglPoint} p2, @code{long} sl=@code{-1})
++@deftypefnx {Method on @code{mglData}} @code{void} Refill (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}v, @code{mglPoint} p1, @code{mglPoint} p2, @code{long} sl=@code{-1})
++@deftypefnx {Method on @code{mglData}} @code{void} Refill (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}v, @code{mglPoint} p1, @code{mglPoint} p2)
++@deftypefnx {Method on @code{mglData}} @code{void} Refill (@code{HMGL} gr, @code{const mglDataA &}x, @code{const mglDataA &}v, @code{long} sl=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglData}} @code{void} Refill (@code{HMGL} gr, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}v, @code{long} sl=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Method on @code{mglData}} @code{void} Refill (@code{HMGL} gr, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}v, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{void} mgl_data_refill_x (@code{HMDT} a, @code{HCDT} x, @code{HCDT} v, @code{mreal} x1, @code{mreal} x2, @code{long} sl)
++@deftypefnx {C function} @code{void} mgl_data_refill_xy (@code{HMDT} a, @code{HCDT} x, @code{HCDT} y, @code{HCDT} v, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2, @code{long} sl)
++@deftypefnx {C function} @code{void} mgl_data_refill_xyz (@code{HMDT} a, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} v, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2, @code{mreal} z1, @code{mreal} z2)
++@deftypefnx {C function} @code{void} mgl_data_refill_gr (@code{HMGL} gr, @code{HMDT} a, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} v, @code{long} sl, @code{const char *}opt)
++@end ifclear
++Fills by interpolated values of array @var{v} at the point @{@var{x}, @var{y}, @var{z}@}=@{@code{X[i], Y[j], Z[k]}@} (or @{@var{x}, @var{y}, @var{z}@}=@{@code{X[i,j,k], Y[i,j,k], Z[i,j,k]}@} if @var{x}, @var{y}, @var{z} are not 1d arrays), where @code{X,Y,Z} are equidistantly distributed in range [@var{x1},@var{x2}]*[@var{y1},@var{y2}]*[@var{z1},@var{z2}] and have the same sizes as this array. If parameter @var{sl} is 0 or positive then changes will be applied only for slice @var{sl}.
++@end deftypefn
++
++@anchor{gspline}
++@deftypefn {MGL command} {} gspline dat xdat vdat [sl=-1]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} RefillGS (@code{const mglDataA &}x, @code{const mglDataA &}v, @code{mreal} x1, @code{mreal} x2, @code{long} sl=@code{-1})
++@deftypefnx {C function} @code{void} mgl_data_refill_gs (@code{HMDT} a, @code{HCDT} x, @code{HCDT} v, @code{mreal} x1, @code{mreal} x2, @code{long} sl)
++@end ifclear
++Fills by global cubic spline values of array @var{v} at the point @var{x}=@code{X[i]}, where @code{X} are equidistantly distributed in range [@var{x1},@var{x2}] and have the same sizes as this array. If parameter @var{sl} is 0 or positive then changes will be applied only for slice @var{sl}.
++@end deftypefn
++
++@anchor{idset}
++@deftypefn {MGL command} {} idset dat 'ids'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} SetColumnId (@code{const char *}ids)
++@deftypefnx {Method on @code{mglDataC}} @code{void} SetColumnId (@code{const char *}ids)
++@deftypefnx {C function} @code{void} mgl_data_set_id (@code{HMDT} a, @code{const char *}ids)
++@deftypefnx {C function} @code{void} mgl_datac_set_id (@code{HADT} a, @code{const char *}ids)
++@end ifclear
++Sets the symbol @var{ids} for data columns. The string should contain one symbol 'a'...'z' per column. These ids are used in @ref{column}.
++@end deftypefn
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node File I/O, Make another data, Data filling, Data processing
++@section File I/O
++@nav{}
++@cindex Read
++@cindex ReadMat
++@cindex ReadRange
++@cindex ReadAll
++@cindex Save
++@cindex ReadHDF
++@cindex SaveHDF
++@cindex Import
++@cindex Export
++
++@anchor{read}
++@deftypefn {MGL command} {} read @sc{dat} 'fname'
++@deftypefnx {MGL command} {} read @sc{redat} @sc{imdat} 'fname'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{bool} Read (@code{const char *}fname)
++@deftypefnx {Method on @code{mglDataC}} @code{bool} Read (@code{const char *}fname)
++@deftypefnx {C function} @code{int} mgl_data_read (@code{HMDT} dat, @code{const char *}fname)
++@deftypefnx {C function} @code{int} mgl_datac_read (@code{HADT} dat, @code{const char *}fname)
++@end ifclear
++Reads data from tab-separated text file with auto determining sizes of the data. Double newline means the beginning of new z-slice.
++@end deftypefn
++
++@deftypefn {MGL command} {} read @sc{dat} 'fname' @code{mx [my=1 mz=1]}
++@deftypefnx {MGL command} {} read @sc{redat} @sc{imdat} 'fname' @code{mx [my=1 mz=1]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{bool} Read (@code{const char *}fname, @code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1})
++@deftypefnx {Method on @code{mglDataC}} @code{bool} Read (@code{const char *}fname, @code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1})
++@deftypefnx {C function} @code{int} mgl_data_read_dim (@code{HMDT} dat, @code{const char *}fname, @code{int} mx, @code{int} my, @code{int} mz)
++@deftypefnx {C function} @code{int} mgl_datac_read_dim (@code{HADT} dat, @code{const char *}fname, @code{int} mx, @code{int} my, @code{int} mz)
++@end ifclear
++Reads data from text file with specified data sizes. This function does nothing if one of parameters @var{mx}, @var{my} or @var{mz} is zero or negative.
++@end deftypefn
++
++@anchor{readmat}
++@deftypefn {MGL command} {} readmat @sc{dat} 'fname' [@code{dim=2}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{bool} ReadMat (@code{const char *}fname, @code{int} dim=@code{2})
++@deftypefnx {Method on @code{mglDataC}} @code{bool} ReadMat (@code{const char *}fname, @code{int} dim=@code{2})
++@deftypefnx {C function} @code{int} mgl_data_read_mat (@code{HMDT} dat, @code{const char *}fname, @code{int} dim)
++@deftypefnx {C function} @code{int} mgl_datac_read_mat (@code{HADT} dat, @code{const char *}fname, @code{int} dim)
++@end ifclear
++Read data from text file with size specified at beginning of the file by first @var{dim} numbers. At this, variable @var{dim} set data dimensions.
++@end deftypefn
++
++@anchor{readall}
++@deftypefn {MGL command} {} readall @sc{dat} 'templ' @code{v1 v2 [dv=1 slice=off]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} ReadRange (@code{const char *}templ, @code{mreal} from, @code{mreal} to, @code{mreal} step=@code{1}, @code{bool} as_slice=@code{false})
++@deftypefnx {Method on @code{mglDataC}} @code{void} ReadRange (@code{const char *}templ, @code{mreal} from, @code{mreal} to, @code{mreal} step=@code{1}, @code{bool} as_slice=@code{false})
++@deftypefnx {C function} @code{int} mgl_data_read_range (@code{HMDT} dat, @code{const char *}templ, @code{mreal} from, @code{mreal} to, @code{mreal} step, @code{int} as_slice)
++@deftypefnx {C function} @code{int} mgl_datac_read_range (@code{HADT} dat, @code{const char *}templ, @code{mreal} from, @code{mreal} to, @code{mreal} step, @code{int} as_slice)
++@end ifclear
++Join data arrays from several text files. The file names are determined by function call @code{sprintf(fname,templ,val);}, where @var{val} changes from @var{from} to @var{to} with step @var{step}. The data load one-by-one in the same slice if @var{as_slice}=@code{false} or as slice-by-slice if @var{as_slice}=@code{true}.
++@end deftypefn
++
++@deftypefn {MGL command} {} readall @sc{dat} 'templ' @code{[slice=off]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} ReadAll (@code{const char *}templ, @code{bool} as_slice=@code{false})
++@deftypefnx {Method on @code{mglDataC}} @code{void} ReadAll (@code{const char *}templ, @code{bool} as_slice=@code{false})
++@deftypefnx {C function} @code{int} mgl_data_read_all (@code{HMDT} dat, @code{const char *}templ, @code{int} as_slice)
++@deftypefnx {C function} @code{int} mgl_datac_read_all (@code{HADT} dat, @code{const char *}templ, @code{int} as_slice)
++@end ifclear
++Join data arrays from several text files which filenames satisfied the template @var{templ} (for example, @var{templ}=@code{"t_*.dat"}). The data load one-by-one in the same slice if @var{as_slice}=@code{false} or as slice-by-slice if @var{as_slice}=@code{true}.
++@end deftypefn
++
++@anchor{scanfile}
++@deftypefn {MGL command} {} scanfile @sc{dat} 'fname' 'templ'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{bool} ScanFile (@code{const char *}fname, @code{const char *}templ)
++@deftypefnx {C function} @code{int} mgl_data_scan_file (@code{HMDT} dat, @code{const char *}fname, @code{const char *}templ)
++@end ifclear
++Read file @var{fname} line-by-line and scan each line for numbers according the template @var{templ}. The numbers denoted as @samp{%g} in the template. @sref{Saving and scanning file}
++@end deftypefn
++
++@anchor{save}
++@deftypefn {MGL command} {} save dat 'fname'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglDataA}} @code{void} Save (@code{const char *}fname, @code{int} ns=@code{-1}) @code{const}
++@deftypefnx {C function} @code{void} mgl_data_save (@code{HCDT} dat, @code{const char *}fname, @code{int} ns)
++@deftypefnx {C function} @code{void} mgl_datac_save (@code{HCDT} dat, @code{const char *}fname, @code{int} ns)
++@end ifclear
++Saves the whole data array (for @var{ns}=@code{-1}) or only @var{ns}-th slice to the text file @var{fname}.
++@end deftypefn
++
++@deftypefn {MGL command} {} save 'str' 'fname' ['mode'='a']
++Saves the string @var{str} to the text file @var{fname}. For parameter @var{mode}=@samp{a} will append string to the file (default); for @var{mode}=@samp{w} will overwrite the file. @sref{Saving and scanning file}
++@end deftypefn
++
++
++@anchor{readhdf}
++@deftypefn {MGL command} {} readhdf @sc{dat} 'fname' 'dname'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} ReadHDF (@code{const char *}fname, @code{const char *}dname)
++@deftypefnx {Method on @code{mglDataC}} @code{void} ReadHDF (@code{const char *}fname, @code{const char *}dname)
++@deftypefnx {C function} @code{void} mgl_data_read_hdf (@code{HMDT} dat, @code{const char *}fname, @code{const char *}dname)
++@deftypefnx {C function} @code{void} mgl_datac_read_hdf (@code{HADT} dat, @code{const char *}fname, @code{const char *}dname)
++@end ifclear
++Reads data array named @var{dname} from HDF5 or HDF4 file. This function does nothing if HDF5|HDF4 was disabled during library compilation.
++@end deftypefn
++
++@anchor{savehdf}
++@deftypefn {MGL command} {} savehdf dat 'fname' 'dname' [@code{rewrite}=@code{off}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglDataA}} @code{void} SaveHDF (@code{const char *}fname, @code{const char *}dname, @code{bool} rewrite=@code{false}) @code{const}
++@deftypefnx {C function} @code{void} mgl_data_save_hdf (@code{HCDT} dat, @code{const char *}fname, @code{const char *}dname, @code{int} rewrite)
++@deftypefnx {C function} @code{void} mgl_datac_save_hdf (@code{HCDT} dat, @code{const char *}fname, @code{const char *}dname, @code{int} rewrite)
++@end ifclear
++Saves data array named @var{dname} to HDF5 file. This function does nothing if HDF5 was disabled during library compilation.
++@end deftypefn
++
++@anchor{datas}
++@deftypefn {MGL command} {} datas 'fname'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglDataA}} @code{int} DatasHDF (@code{const char *}fname, @code{char *}buf, @code{long} size) @code{static}
++@deftypefnx {C function} @code{int} mgl_datas_hdf (@code{const char *}fname, @code{char *}buf, @code{long} size)
++@end ifclear
++Put data names from HDF5 file @var{fname} into @var{buf} as '\t' separated fields. In MGL version the list of data names will be printed as message. This function does nothing if HDF5 was disabled during library compilation.
++@end deftypefn
++
++@anchor{openhdf}
++@deftypefn {MGL command} {} openhdf 'fname'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglParse}} @code{void} OpenHDF (@code{const char *}fname)
++@deftypefnx {C function} @code{void} mgl_parser_openhdf (@code{HMPR} pr, @code{const char *}fname)
++@end ifclear
++Reads all data array from HDF5 file @var{fname} and create MGL variables with names of data names in HDF file. Complex variables will be created if data name starts with @samp{!}.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {C function} @code{const char * const *} mgl_datas_hdf_str (@code{HMPR} pr, @code{const char *}fname)
++Put HDF data names as list of strings (last one is ""). The result is valid untill next call of the function.
++@end deftypefn
++@end ifclear
++
++
++@anchor{import}
++@deftypefn {MGL command} {} import @sc{dat} 'fname' 'sch' [@code{v1=0 v2=1}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Import (@code{const char *}fname, @code{const char *}scheme, @code{mreal} v1=@code{0}, mreal v2=@code{1})
++@deftypefnx {C function} @code{void} mgl_data_import (@code{HMDT} dat, @code{const char *}fname, @code{const char *}scheme, @code{mreal} v1, mreal v2)
++@end ifclear
++Reads data from bitmap file (now support only PNG format). The RGB values of bitmap pixels are transformed to mreal values in range [@var{v1}, @var{v2}] using color scheme @var{scheme} (@pxref{Color scheme}).
++@end deftypefn
++
++@anchor{export}
++@deftypefn {MGL command} {} export dat 'fname' 'sch' [@code{v1=0 v2=0}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglDataA}} @code{void} Export (@code{const char *}fname, @code{const char *}scheme, @code{mreal} v1=@code{0}, mreal v2=@code{0}, @code{int} ns=@code{-1}) const
++@deftypefnx {C function} @code{void} mgl_data_export (@code{HMDT} dat, @code{const char *}fname, @code{const char *}scheme, @code{mreal} v1, mreal v2, @code{int} ns) const
++@end ifclear
++Saves data matrix (or @code{ns}-th slice for 3d data) to bitmap file (now support only PNG format). The data values are transformed from range [@var{v1}, @var{v2}] to RGB pixels of bitmap using color scheme @var{scheme} (@pxref{Color scheme}). If @var{v1}>=@var{v2} then the values of @var{v1}, @var{v2} are automatically determined as minimal and maximal value of the data array.
++@end deftypefn
++
++@c ------------------------------------------------------------------
++@external{}
++@node Make another data, Data changing, File I/O, Data processing
++@section Make another data
++@nav{}
++@cindex SubData
++@cindex Column
++@cindex Trace
++@cindex Hist
++@cindex Resize
++@cindex Evaluate
++@cindex Combine
++@cindex Momentum
++@cindex Sum
++@cindex Min
++@cindex Max
++@cindex Roots
++@cindex Correl
++@cindex AutoCorrel
++
++
++@anchor{subdata}
++@deftypefn {MGL command} {} subdata @sc{res} dat @code{xx [yy=all zz=all]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} SubData (@code{mreal} xx, @code{mreal} yy=@code{-1}, @code{mreal} zz=@code{-1}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} SubData (@code{mreal} xx, @code{mreal} yy=@code{-1}, @code{mreal} zz=@code{-1}) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_subdata (@code{HCDT} dat, @code{mreal} xx, @code{mreal} yy, @code{mreal} zz)
++@end ifclear
++Extracts sub-array data from the original data array keeping fixed positive index. For example @code{SubData(-1,2)} extracts 3d row (indexes are zero based), @code{SubData(4,-1)} extracts 5th column, @code{SubData(-1,-1,3)} extracts 4th slice and so on. If argument(s) are non-integer then linear interpolation between slices is used. In MGL version this command usually is used as inline one @code{dat(xx,yy,zz)}. Function return NULL or create empty data if data cannot be created for given arguments.
++@end deftypefn
++
++@deftypefn {MGL command} {} subdata @sc{res} dat xdat [ydat zdat]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} SubData (@code{const mglDataA &}xx, @code{const mglDataA &}yy, @code{const mglDataA &}zz) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} SubData (@code{const mglDataA &}xx, @code{const mglDataA &}yy, @code{const mglDataA &}zz) @code{const}
++@deftypefnx {Method on @code{mglData}} @code{mglData} SubData (@code{const mglDataA &}xx, @code{const mglDataA &}yy) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} SubData (@code{const mglDataA &}xx, @code{const mglDataA &}yy) @code{const}
++@deftypefnx {Method on @code{mglData}} @code{mglData} SubData (@code{const mglDataA &}xx) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} SubData (@code{const mglDataA &}xx) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_subdata_ext (@code{HCDT} dat, @code{HCDT} xx, @code{HCDT} yy, @code{HCDT} zz)
++@deftypefnx {C function} @code{HADT} mgl_datac_subdata_ext (@code{HCDT} dat, @code{HCDT} xx, @code{HCDT} yy, @code{HCDT} zz)
++@end ifclear
++Extracts sub-array data from the original data array for indexes specified by arrays @var{xx}, @var{yy}, @var{zz} (indirect access). This function work like previous one for 1D arguments or numbers, and resulting array dimensions are equal dimensions of 1D arrays for corresponding direction. For 2D and 3D arrays in arguments, the resulting array have the same dimensions as input arrays. The dimensions of all argument must be the same (or to be scalar 1*1*1) if they are 2D or 3D arrays. In MGL version this command usually is used as inline one @code{dat(xx,yy,zz)}. Function return NULL or create empty data if data cannot be created for given arguments. In C function some of @var{xx}, @var{yy}, @var{zz} can be NULL.
++@end deftypefn
++
++@anchor{column}
++@deftypefn {MGL command} {} column @sc{res} dat 'eq'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Column (@code{const char *}eq) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Column (@code{const char *}eq) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_column (@code{HCDT} dat, @code{const char *}eq)
++@end ifclear
++Get column (or slice) of the data filled by formula @var{eq} on column ids. For example, @code{Column("n*w^2/exp(t)");}. The column ids must be defined first by @ref{idset} function or read from files. In MGL version this command usually is used as inline one @code{dat('eq')}. Function return NULL or create empty data if data cannot be created for given arguments.
++@end deftypefn
++
++@anchor{resize}
++@deftypefn {MGL command} {} resize @sc{res} dat @code{mx [my=1 mz=1]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Resize (@code{int} mx, @code{int} my=@code{0}, @code{int} mz=@code{0}, @code{mreal} x1=@code{0}, @code{mreal} x2=@code{1}, @code{mreal} y1=@code{0}, @code{mreal} y2=@code{1}, @code{mreal} z1=@code{0}, @code{mreal} z2=@code{1}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Resize (@code{int} mx, @code{int} my=@code{0}, @code{int} mz=@code{0}, @code{mreal} x1=@code{0}, @code{mreal} x2=@code{1}, @code{mreal} y1=@code{0}, @code{mreal} y2=@code{1}, @code{mreal} z1=@code{0}, @code{mreal} z2=@code{1}) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_resize (@code{HCDT} dat, @code{int} mx, @code{int} my, @code{int} mz)
++@deftypefnx {C function} @code{HMDT} mgl_data_resize_box (@code{HCDT} dat, @code{int} mx, @code{int} my, @code{int} mz, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2, @code{mreal} z1, @code{mreal} z2)
++@end ifclear
++Resizes the data to new size @var{mx}, @var{my}, @var{mz} from box (part) [@var{x1},@var{x2}] x [@var{y1},@var{y2}] x [@var{z1},@var{z2}] of original array. Initially x,y,z coordinates are supposed to be in [0,1]. If one of sizes @var{mx}, @var{my} or @var{mz} is 0 then initial size is used. Function return NULL or create empty data if data cannot be created for given arguments.
++@end deftypefn
++
++@anchor{evaluate}
++@deftypefn {MGL command} {} evaluate @sc{res} dat idat [@code{norm=on}]
++@deftypefnx {MGL command} {} evaluate @sc{res} dat idat jdat [@code{norm=on}]
++@deftypefnx {MGL command} {} evaluate @sc{res} dat idat jdat kdat [@code{norm=on}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Evaluate (@code{const mglDataA &}idat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Method on @code{mglData}} @code{mglData} Evaluate (@code{const mglDataA &}idat, @code{const mglDataA &}jdat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Method on @code{mglData}} @code{mglData} Evaluate (@code{const mglDataA &}idat, @code{const mglDataA &}jdat, @code{const mglDataA &}kdat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Evaluate (@code{const mglDataA &}idat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Evaluate (@code{const mglDataA &}idat, @code{const mglDataA &}jdat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Evaluate (@code{const mglDataA &}idat, @code{const mglDataA &}jdat, @code{const mglDataA &}kdat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_evaluate (@code{HCDT} dat, @code{HCDT} idat, @code{HCDT} jdat, @code{HCDT} kdat, @code{int} norm)
++@end ifclear
++Gets array which values is result of interpolation of original array for coordinates from other arrays. All dimensions must be the same for data @var{idat}, @var{jdat}, @var{kdat}. Coordinates from @var{idat}, @var{jdat}, @var{kdat} are supposed to be normalized in range [0,1] (if @var{norm}=@code{true}) or in ranges [0,nx], [0,ny], [0,nz] correspondingly. Function return NULL or create empty data if data cannot be created for given arguments.
++@end deftypefn
++
++@anchor{section}
++@deftypefn {MGL command} {} section @sc{res} dat ids ['dir'='y' @code{val=nan}]
++@deftypefnx {MGL command} {} section @sc{res} dat @code{id} ['dir'='y' @code{val=nan}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Section (@code{const mglDataA &}ids, @code{const char *}dir=@code{'y'}, @code{mreal} val=@code{NAN}) @code{const}
++@deftypefnx {Method on @code{mglData}} @code{mglData} Section (@code{long} id, @code{const char *}dir=@code{'y'}, @code{mreal} val=@code{NAN}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Section (@code{const mglDataA &}ids, @code{const char *}dir=@code{'y'}, @code{mreal} val=@code{NAN}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Section (@code{long} id, @code{const char *}dir=@code{'y'}, @code{mreal} val=@code{NAN}) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_section (@code{HCDT} dat, @code{HCDT} ids, @code{const char *}dir, @code{mreal} val)
++@deftypefnx {C function} @code{HMDT} mgl_data_section_val (@code{HCDT} dat, @code{long} id, @code{const char *}dir, @code{mreal} val)
++@deftypefnx {C function} @code{HADT} mgl_datac_section (@code{HCDT} dat, @code{HCDT} ids, @code{const char *}dir, @code{mreal} val)
++@deftypefnx {C function} @code{HADT} mgl_datac_section_val (@code{HCDT} dat, @code{long} id, @code{const char *}dir, @code{mreal} val)
++@end ifclear
++Gets array which is @var{id}-th section (range of slices separated by value @var{val}) of original array @var{dat}. For @var{id}<0 the reverse order is used (i.e. -1 give last section). If several @var{ids} are provided then output array will be result of sequential joining of sections.
++@end deftypefn
++
++
++@anchor{solve}
++@deftypefn {MGL command} {} solve @sc{res} dat @code{val} 'dir' [@code{norm=on}]
++@deftypefnx {MGL command} {} solve @sc{res} dat @code{val} 'dir' idat [@code{norm=on}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Solve (@code{mreal} val, @code{char} dir, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Method on @code{mglData}} @code{mglData} Solve (@code{mreal} val, @code{char} dir, @code{const mglDataA &}idat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_solve (@code{HCDT} dat, @code{mreal} val, @code{char} dir, @code{HCDT} idat, @code{int} norm)
++@end ifclear
++Gets array which values is indexes (roots) along given direction @var{dir}, where interpolated values of data @var{dat} are equal to @var{val}. Output data will have the sizes of @var{dat} in directions transverse to @var{dir}. If data @var{idat} is provided then its values are used as starting points. This allows to find several branches by consequentive calls. Indexes are supposed to be normalized in range [0,1] (if @var{norm}=@code{true}) or in ranges [0,nx], [0,ny], [0,nz] correspondingly. Function return NULL or create empty data if data cannot be created for given arguments. @sref{Solve sample}
++@end deftypefn
++
++@anchor{roots}
++@deftypefn {MGL command} {} roots @sc{res} 'func' ini ['var'='x']
++@deftypefnx {MGL command} {} roots @sc{res} 'func' @code{ini} ['var'='x']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Roots (@code{const char *}func, @code{char} var) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_roots (@code{const char *}func, @code{HCDT} ini, @code{char} var)
++@deftypefnx {C function} @code{mreal} mgl_find_root_txt (@code{const char *}func, @code{mreal} ini, @code{char} var)
++@end ifclear
++Find roots of equation 'func'=0 for variable @var{var} with initial guess @var{ini}. Secant method is used for root finding. Function return NULL or create empty data if data cannot be created for given arguments.
++@end deftypefn
++
++@anchor{detect}
++@deftypefn {MGL command} {} detect @sc{res} dat @code{lvl dj [di=0 minlen=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Detect (@code{mreal} lvl, @code{mreal} dj, @code{mreal} di=@code{0}, @code{mreal} minlen=@code{0}) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_detect (@code{HCDT} dat, @code{mreal} lvl, @code{mreal} dj, @code{mreal} di, @code{mreal} minlen)
++@end ifclear
++Get curves @{x,y@}, separated by NAN values, for local maximal values of array @var{dat} as function of x-coordinate. Noises below @var{lvl} amplitude are ignored. Parameter @var{dj} (in range [0,ny]) set the "attraction" y-distance of points to the curve. Similarly, @var{di} continue curve in x-direction through gaps smaller than @var{di} points. Curves with minimal length smaller than @var{minlen} will be ignored.
++@end deftypefn
++
++@anchor{hist}
++@deftypefn {MGL command} {} hist @sc{res} dat @code{num v1 v2 [nsub=0]}
++@deftypefnx {MGL command} {} hist @sc{res} dat wdat @code{num v1 v2 [nsub=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Hist (@code{int} n, @code{mreal} v1=@code{0}, @code{mreal} v2=@code{1}, @code{int} nsub=@code{0}) @code{const}
++@deftypefnx {Method on @code{mglData}} @code{mglData} Hist (@code{const mglDataA &}w, @code{int} n, @code{mreal} v1=@code{0}, @code{mreal} v2=@code{1}, @code{int} nsub=@code{0}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Hist (@code{int} n, @code{mreal} v1=@code{0}, @code{mreal} v2=@code{1}, @code{int} nsub=@code{0}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Hist (@code{const mglDataA &}w, @code{int} n, @code{mreal} v1=@code{0}, @code{mreal} v2=@code{1}, @code{int} nsub=@code{0}) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_hist (@code{HCDT} dat, @code{int} n, @code{mreal} v1, @code{mreal} v2, @code{int} nsub)
++@deftypefnx {C function} @code{HMDT} mgl_data_hist_w (@code{HCDT} dat, @code{HCDT} w, @code{int} n, @code{mreal} v1, @code{mreal} v2, @code{int} nsub)
++@end ifclear
++Creates @var{n}-th points distribution of the data values in range [@var{v1}, @var{v2}]. Array @var{w} specifies weights of the data elements (by default is 1). Parameter @var{nsub} define the number of additional interpolated points (for smoothness of histogram). Function return NULL or create empty data if data cannot be created for given arguments. See also @ref{Data manipulation}
++@end deftypefn
++
++@anchor{momentum}
++@deftypefn {MGL command} {} momentum @sc{res} dat 'how' ['dir'='z']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Momentum (@code{char} dir, @code{const char *}how) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Momentum (@code{char} dir, @code{const char *}how) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_momentum (@code{HCDT} dat, @code{char} dir, @code{const char *}how)
++@end ifclear
++Gets momentum (1d-array) of the data along direction @var{dir}. String @var{how} contain kind of momentum. The momentum is defined like as
++@iftex
++@math{res_k = \sum_{ij} how(x_i,y_j,z_k) a_{ij}/\sum_{ij} a_{ij}}
++@end iftex
++@ifnottex
++res_k = \sum_ij how(x_i,y_j,z_k) a_ij/ \sum_ij a_ij
++@end ifnottex
++if @var{dir}=@samp{z} and so on. Coordinates @samp{x}, @samp{y}, @samp{z} are data indexes normalized in range [0,1]. Function return NULL or create empty data if data cannot be created for given arguments.
++@end deftypefn
++
++@anchor{sum}
++@deftypefn {MGL command} {} sum @sc{res} dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Sum (@code{const char *}dir) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Sum (@code{const char *}dir) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_sum (@code{HCDT} dat, @code{const char *}dir)
++@end ifclear
++Gets array which is the result of summation in given direction or direction(s). Function return NULL or create empty data if data cannot be created for given arguments.
++@end deftypefn
++
++@anchor{max}
++@deftypefn {MGL command} {} max @sc{res} dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Max (@code{const char *}dir) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Max (@code{const char *}dir) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_max_dir (@code{HCDT} dat, @code{const char *}dir)
++@end ifclear
++Gets array which is the maximal data values in given direction or direction(s). Function return NULL or create empty data if data cannot be created for given arguments.
++@end deftypefn
++
++@anchor{min}
++@deftypefn {MGL command} {} min @sc{res} dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Min (@code{const char *}dir) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Min (@code{const char *}dir) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_min_dir (@code{HCDT} dat, @code{const char *}dir)
++@end ifclear
++Gets array which is the maximal data values in given direction or direction(s). Function return NULL or create empty data if data cannot be created for given arguments.
++@end deftypefn
++
++@anchor{combine}
++@deftypefn {MGL command} {} combine @sc{res} adat bdat
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Combine (@code{const mglDataA &}a) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Combine (@code{const mglDataA &}a) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_combine (@code{HCDT} dat, @code{HCDT} a)
++@end ifclear
++Returns direct multiplication of arrays (like, res[i,j] = this[i]*a[j] and so on). Function return NULL or create empty data if data cannot be created for given arguments.
++@end deftypefn
++
++@anchor{trace}
++@deftypefn {MGL command} {} trace @sc{res} dat
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Trace () @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglData} Trace () @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_trace (@code{HCDT} dat)
++@end ifclear
++Gets array of diagonal elements a[i,i] (for 2D case) or a[i,i,i] (for 3D case) where i=0...nx-1. Function return copy of itself for 1D case. Data array must have dimensions ny,nz >= nx or ny,nz = 1. Function return NULL or create empty data if data cannot be created for given arguments.
++@end deftypefn
++
++@anchor{correl}
++@deftypefn {MGL command} {} correl @sc{res} adat bdat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Correl (@code{const mglDataA &}b, @code{const char *}dir) @code{const}
++@deftypefnx {Method on @code{mglData}} @code{mglData} AutoCorrel (@code{const char *}dir) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglDataC} Correl (@code{const mglDataA &}b, @code{const char *}dir) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{mglDataC} AutoCorrel (@code{const char *}dir) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_correl (@code{HCDT} a, @code{HCDT} b, @code{const char *}dir)
++@deftypefnx {C function} @code{HADT} mgl_datac_correl (@code{HCDT} a, @code{HCDT} b, @code{const char *}dir)
++@end ifclear
++Find correlation between data @var{a} (or this in C++) and @var{b} along directions @var{dir}. Fourier transform is used to find the correlation. So, you may want to use functions @ref{swap} or @ref{norm} before plotting it. Function return NULL or create empty data if data cannot be created for given arguments.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglDataC}} @code{mglData} Real () @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_datac_real (@code{HCDT} dat)
++Gets array of real parts of the data.
++@end deftypefn
++@deftypefn {Method on @code{mglDataC}} @code{mglData} Imag () @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_datac_imag (@code{HCDT} dat)
++Gets array of imaginary parts of the data.
++@end deftypefn
++@deftypefn {Method on @code{mglDataC}} @code{mglData} Abs () @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_datac_abs (@code{HCDT} dat)
++Gets array of absolute values of the data.
++@end deftypefn
++@deftypefn {Method on @code{mglDataC}} @code{mglData} Arg () @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_datac_arg (@code{HCDT} dat)
++Gets array of arguments of the data.
++@end deftypefn
++@end ifclear
++
++@anchor{pulse}
++@deftypefn {MGL command} {} pulse @sc{res} dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{mglData} Pulse (@code{const char *}dir) @code{const}
++@deftypefnx {C function} @code{HMDT} mgl_data_pulse (@code{HCDT} dat, @code{const char *}dir)
++@end ifclear
++Find pulse properties along direction @var{dir}: pulse maximum (in column 0) and its position (in column 1), pulse width near maximum (in column 3) and by half height (in column 2), energy in first pulse (in column 4). NAN values are used for widths if maximum is located near the edges. Note, that there is uncertainty for complex data. Usually one should use square of absolute value (i.e. |dat[i]|^2) for them. So, MathGL don't provide this function for complex data arrays. However, C function will work even in this case but use absolute value (i.e. |dat[i]|). Function return NULL or create empty data if data cannot be created for given arguments. See also @ref{max}, @ref{min}, @ref{momentum}, @ref{sum}. @sref{Pulse properties}
++@end deftypefn
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node Data changing, Interpolation, Make another data, Data processing
++@section Data changing
++@nav{}
++@cindex CumSum
++@cindex Integral
++@cindex Diff
++@cindex Diff2
++@cindex SinFFT
++@cindex CosFFT
++@cindex Hankel
++@cindex Swap
++@cindex Roll
++@cindex Mirror
++@cindex Sew
++@cindex Smooth
++@cindex Envelop
++@cindex Norm
++@cindex NormSl
++
++These functions change the data in some direction like differentiations, integrations and so on. The direction in which the change will applied is specified by the string parameter, which may contain @samp{x}, @samp{y} or @samp{z} characters for 1-st, 2-nd and 3-d dimension correspondingly.
++
++@anchor{cumsum}
++@deftypefn {MGL command} {} cumsum dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} CumSum (@code{const char *}dir)
++@deftypefnx {Method on @code{mglDataC}} @code{void} CumSum (@code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_data_cumsum (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_datac_cumsum (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Cumulative summation of the data in given direction or directions.
++@end deftypefn
++
++@anchor{integrate}
++@deftypefn {MGL command} {} integrate dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Integral (@code{const char *}dir)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Integral (@code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_data_integral (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_datac_integral (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Integrates (like cumulative summation) the data in given direction or directions.
++@end deftypefn
++
++@anchor{diff}
++@deftypefn {MGL command} {} diff dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Diff (@code{const char *}dir)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Diff (@code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_data_diff (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_datac_diff (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Differentiates the data in given direction or directions.
++@end deftypefn
++
++@deftypefn {MGL command} {} diff dat xdat ydat [zdat]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Diff (@code{const mglDataA &}x)
++@deftypefnx {Method on @code{mglData}} @code{void} Diff (@code{const mglDataA &}x, @code{const mglDataA &}y)
++@deftypefnx {Method on @code{mglData}} @code{void} Diff (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Diff (@code{const mglDataA &}x)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Diff (@code{const mglDataA &}x, @code{const mglDataA &}y)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Diff (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z)
++@deftypefnx {C function} @code{void} mgl_data_diff_par (@code{HMDT} dat, @code{HCDT} x, @code{HCDT}y, @code{HCDT}z)
++@deftypefnx {C function} @code{void} mgl_datac_diff_par (@code{HADT} dat, @code{HCDT} x, @code{HCDT}y, @code{HCDT}z)
++@end ifclear
++Differentiates the data specified parametrically in direction @var{x} with @var{y}, @var{z}=constant. Parametrical differentiation uses the formula (for 2D case): @math{da/dx = (a_j*y_i-a_i*y_j)/(x_j*y_i-x_i*y_j)} where @math{a_i=da/di, a_j=da/dj} denotes usual differentiation along 1st and 2nd dimensions. The similar formula is used for 3D case. Note, that you may change the order of arguments -- for example, if you have 2D data a(i,j) which depend on coordinates @{x(i,j), y(i,j)@} then usual derivative along @samp{x} will be @code{Diff(x,y);} and usual derivative along @samp{y} will be @code{Diff(y,x);}.
++@end deftypefn
++
++@anchor{diff2}
++@deftypefn {MGL command} {} diff2 dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Diff2 (@code{const char *}dir)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Diff2 (@code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_data_diff2 (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_datac_diff2 (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Double-differentiates (like Laplace operator) the data in given direction.
++@end deftypefn
++
++@anchor{sinfft}
++@deftypefn {MGL command} {} sinfft dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} SinFFT (@code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_data_sinfft (@code{HMDT} dat, @code{const char *}dir)
++@end ifclear
++Do Sine transform of the data in given direction or directions. The Sine transform is @math{\sum a_j \sin(k j)} (see @uref{http://en.wikipedia.org/wiki/Discrete_sine_transform#DST-I}).
++@end deftypefn
++
++@anchor{cosfft}
++@deftypefn {MGL command} {} cosfft dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} CosFFT (@code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_data_cosfft (@code{HMDT} dat, @code{const char *}dir)
++@end ifclear
++Do Cosine transform of the data in given direction or directions. The Cosine transform is @math{\sum a_j \cos(k j)} (see @uref{http://en.wikipedia.org/wiki/Discrete_cosine_transform#DCT-I}).
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglDataC}} @code{void} FFT (@code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_datac_fft (@code{HADT} dat, @code{const char *}dir)
++Do Fourier transform of the data in given direction or directions. If @var{dir} contain @samp{i} then inverse Fourier is used. The Fourier transform is @math{\sum a_j \exp(i k j)} (see @uref{http://en.wikipedia.org/wiki/Discrete_Fourier_transform}).
++@end deftypefn
++@end ifclear
++
++@anchor{hankel}
++@deftypefn {MGL command} {} hankel dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Hankel (@code{const char *}dir)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Hankel (@code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_data_hankel (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_datac_hankel (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Do Hankel transform of the data in given direction or directions. The Hankel transform is @math{\sum a_j J_0(k j)} (see @uref{http://en.wikipedia.org/wiki/Hankel_transform}).
++@end deftypefn
++
++@anchor{wavelet}
++@deftypefn {MGL command} {} wavelet dat 'dir' @code{k}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Wavelet (@code{const char *}dir, @code{int} k)
++@deftypefnx {C function} @code{void} mgl_data_wavelet (@code{HMDT} dat, @code{const char *}dir, @code{int} k)
++@end ifclear
++Apply wavelet transform of the data in given direction or directions. Parameter @var{dir} set the kind of wavelet transform:
++@samp{d} for daubechies, @samp{D} for centered daubechies, @samp{h} for haar, @samp{H} for centered haar, @samp{b} for bspline, @samp{B} for centered bspline. If string @var{dir} contain symbol @samp{i} then inverse wavelet transform is applied. Parameter @var{k} set the size of wavelet transform.
++@end deftypefn
++
++@anchor{swap}
++@deftypefn {MGL command} {} swap dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Swap (@code{const char *}dir)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Swap (@code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_data_swap (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_datac_swap (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Swaps the left and right part of the data in given direction (useful for Fourier spectrum).
++@end deftypefn
++
++@anchor{roll}
++@deftypefn {MGL command} {} roll dat 'dir' num
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Roll (@code{char} dir, @code{num})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Roll (@code{char} dir, @code{num})
++@deftypefnx {C function} @code{void} mgl_data_roll (@code{HMDT} dat, @code{char} dir, @code{num})
++@deftypefnx {C function} @code{void} mgl_datac_roll (@code{HADT} dat, @code{char} dir, @code{num})
++@end ifclear
++Rolls the data along direction @var{dir}. Resulting array will be out[i] = ini[(i+@var{num})%nx] if @code{dir='x'}.
++@end deftypefn
++
++@anchor{mirror}
++@deftypefn {MGL command} {} mirror dat 'dir'
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Mirror (@code{const char *}dir)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Mirror (@code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_data_mirror (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_datac_mirror (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Mirror the left-to-right part of the data in given direction. Looks like change the value index @var{i}->@var{n-i}. Note, that the similar effect in graphics you can reach by using options (@pxref{Command options}), for example, @code{surf dat; xrange 1 -1}.
++@end deftypefn
++
++@anchor{sew}
++@deftypefn {MGL command} {} sew dat ['dir'='xyz' @code{da=2*pi}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Sew (@code{const char *}dir, @code{mreal} da=@code{2*M_PI})
++@deftypefnx {C function} @code{void} mgl_data_sew (@code{HMDT} dat, @code{const char *}dir, @code{mreal} da)
++@end ifclear
++Remove value steps (like phase jumps after inverse trigonometric functions) with period @var{da} in given direction.
++@end deftypefn
++
++@anchor{smooth}
++@deftypefn {MGL command} {} smooth data ['dir'='xyz']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Smooth (@code{const char *}dir=@code{"xyz"}, @code{mreal} delta=@code{0})
++@deftypefnx {Method on @code{mglDataC}} @code{void} Smooth (@code{const char *}dir=@code{"xyz"}, @code{mreal} delta=@code{0})
++@deftypefnx {C function} @code{void} mgl_data_smooth (@code{HMDT} dat, @code{const char *}dir, @code{mreal} delta)
++@deftypefnx {C function} @code{void} mgl_datac_smooth (@code{HADT} dat, @code{const char *}dir, @code{mreal} delta)
++@end ifclear
++Smooths the data on specified direction or directions. String @var{dirs} specifies the dimensions which will be smoothed. It may contain characters:
++@itemize @bullet
++@item
++@samp{xyz} for smoothing along x-,y-,z-directions correspondingly,
++@item
++@samp{0} does nothing,
++@item
++@samp{3} for linear averaging over 3 points,
++@item
++@samp{5} for linear averaging over 5 points,
++@item
++@samp{d1}...@samp{d9} for linear averaging over (2*N+1)-th points.
++@end itemize
++By default quadratic averaging over 5 points is used.
++@end deftypefn
++
++@anchor{envelop}
++@deftypefn {MGL command} {} envelop dat ['dir'='x']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Envelop (@code{char} dir=@code{'x'})
++@deftypefnx {C function} @code{void} mgl_data_envelop (@code{HMDT} dat, @code{char} dir)
++@end ifclear
++Find envelop for data values along direction @var{dir}.
++@end deftypefn
++
++@anchor{diffract}
++@deftypefn {MGL command} {} diffract dat 'how' @code{q}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglDataC}} @code{void} Diffraction (@code{const char *}how, @code{mreal} q)
++@deftypefnx {C function} @code{void} mgl_datac_diffr (@code{HADT} dat, @code{const char *}how, @code{mreal} q)
++@end ifclear
++Calculates one step of diffraction by finite-difference method with parameter @var{q}=@math{\delta t/\delta x^2} using method with 3-d order of accuracy. Parameter @var{how} may contain:
++@itemize @bullet
++ @item @samp{xyz} for calculations along x-,y-,z-directions correspondingly;
++@item
++ @samp{r} for using axial symmetric Laplace operator for x-direction;
++@item
++ @samp{0} for zero boundary conditions;
++@item
++ @samp{1} for constant boundary conditions;
++@item
++ @samp{2} for linear boundary conditions;
++@item
++ @samp{3} for parabolic boundary conditions;
++@item
++ @samp{4} for exponential boundary conditions;
++@item
++ @samp{5} for gaussian boundary conditions.
++@end itemize
++@end deftypefn
++
++<<<<<<< HEAD
++
++=======
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++@anchor{norm}
++@deftypefn {MGL command} {} norm dat @code{v1 v2 [sym=off dim=0]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Norm (@code{mreal} v1=@code{0}, @code{mreal} v2=@code{1}, @code{bool} sym=@code{false}, @code{long} dim=@code{0})
++@deftypefnx {C function} @code{void} mgl_data_norm (@code{HMDT} dat, @code{mreal} v1, @code{mreal} v2, @code{int} sym, @code{long} dim)
++@end ifclear
++Normalizes the data to range [@var{v1},@var{v2}]. If flag @var{sym}=@code{true} then symmetrical interval [-max(|v1|,|v2|), max(|v1|,|v2|)] is used. Modification will be applied only for slices >=@var{dim}.
++@end deftypefn
++
++@anchor{normsl}
++@deftypefn {MGL command} {} normsl dat @code{v1 v2} ['dir'='z' @code{keep=on sym=off}]
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} NormSl (@code{mreal} v1=@code{0}, @code{mreal} v2=@code{1}, @code{char} dir=@code{'z'}, @code{bool} keep=@code{true}, @code{bool} sym=@code{false})
++@deftypefnx {C function} @code{void} mgl_data_norm_slice (@code{HMDT} dat, @code{mreal} v1, @code{mreal} v2, @code{char} dir, @code{int} keep, @code{int} sym)
++@end ifclear
++Normalizes data slice-by-slice along direction @var{dir} the data in slices to range [@var{v1},@var{v2}]. If flag @var{sym}=@code{true} then symmetrical interval [-max(|v1|,|v2|), max(|v1|,|v2|)] is used. If @var{keep} is set then maximal value of k-th slice will be limited by
++@iftex
++@math{\sqrt{\sum a_{ij}(k)/\sum a_{ij}(0)}}.
++@end iftex
++@ifnottex
++@math{\sqrt@{\sum a_ij(k)/\sum a_ij(0)@}}.
++@end ifnottex
++@end deftypefn
++
++@anchor{limit}
++@deftypefn {MGL command} {} limit dat @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Limit (@code{mreal} val)
++@deftypefnx {Method on @code{mglDataC}} @code{void} Limit (@code{mreal} val)
++@deftypefnx {C function} @code{void} mgl_data_limit (@code{HMDT} dat, @code{mreal} val)
++@deftypefnx {C function} @code{void} mgl_datac_limit (@code{HADT} dat, @code{mreal} val)
++@end ifclear
++Limits the data values to be inside the range [-@var{val},@var{val}], keeping the original sign of the value (phase for complex numbers). This is equivalent to operation @code{a[i] *= abs(a[i])<val?1.:val/abs(a[i]);}.
++@end deftypefn
++
++<<<<<<< HEAD
++=======
++@anchor{dilate}
++@deftypefn {MGL command} {} dilate dat @code{[val=1 step=1]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Dilate (@code{mreal} val=@code{1}, @code{long} step=@code{1})
++@deftypefnx {C function} @code{void} mgl_data_dilate (@code{HMDT} dat, @code{mreal} val, @code{long} step)
++@end ifclear
++Return dilated by @var{step} cells array of 0 or 1 for data values larger @var{val}. @c TODO @sref{Dilate and erode sample}
++@end deftypefn
++
++@anchor{erode}
++@deftypefn {MGL command} {} erode dat @code{[val=1 step=1]}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} Erode (@code{mreal} val=@code{1}, @code{long} step=@code{1})
++@deftypefnx {C function} @code{void} mgl_data_erode (@code{HMDT} dat, @code{mreal} val, @code{long} step)
++@end ifclear
++Return eroded by @var{step} cells array of 0 or 1 for data values larger @var{val}. @c TODO @sref{Dilate and erode sample}
++@end deftypefn
++
++
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++@c ------------------------------------------------------------------
++@external{}
++@node Interpolation, Data information, Data changing, Data processing
++@section Interpolation
++@nav{}
++
++MGL scripts can use spline interpolation by @ref{evaluate} or @ref{refill} commands. Also you can use @ref{resize} for obtaining a data array with new sizes.
++
++@ifclear UDAV
++
++However, there are much special faster functions in other modes (C/C++/Fortran/Python/...).
++
++@cindex Spline
++@deftypefn {Method on @code{mglData}} @code{mreal} Spline (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{dual} Spline (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_spline (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++@deftypefnx {C function} @code{dual} mgl_datac_spline (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++Interpolates data by cubic spline to the given point @var{x} in [0...nx-1], @var{y} in [0...ny-1], @var{z} in [0...nz-1].
++@end deftypefn
++@cindex Spline1
++@deftypefn {Method on @code{mglData}} @code{mreal} Spline1 (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{dual} Spline1 (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++Interpolates data by cubic spline to the given point @var{x}, @var{y}, @var{z} which assumed to be normalized in range [0, 1].
++@end deftypefn
++
++@deftypefn {Method on @code{mglData}} @code{mreal} Spline (@code{mglPoint} &dif, @code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_spline_ext (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal *}dx, @code{mreal *}dy, @code{mreal *}dz)
++@deftypefnx {C function} @code{dual} mgl_datac_spline_ext (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{dual *}dx, @code{dual *}dy, @code{dual *}dz)
++Interpolates data by cubic spline to the given point @var{x} in [0...nx-1], @var{y} in [0...ny-1], @var{z} in [0...nz-1]. The values of derivatives at the point are saved in @var{dif}.
++@end deftypefn
++@cindex Spline1
++@deftypefn {Method on @code{mglData}} @code{mreal} Spline1 (@code{mglPoint} &dif, @code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++Interpolates data by cubic spline to the given point @var{x}, @var{y}, @var{z} which assumed to be normalized in range [0, 1]. The values of derivatives at the point are saved in @var{dif}.
++@end deftypefn
++
++@cindex Linear
++@deftypefn {Method on @code{mglData}} @code{mreal} Linear (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{dual} Linear (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_linear (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++@deftypefnx {C function} @code{dual} mgl_datac_linear (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++Interpolates data by linear function to the given point @var{x} in [0...nx-1], @var{y} in [0...ny-1], @var{z} in [0...nz-1].
++@end deftypefn
++@cindex Linear1
++@deftypefn {Method on @code{mglData}} @code{mreal} Linear1 (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{dual} Linear1 (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++Interpolates data by linear function to the given point @var{x}, @var{y}, @var{z} which assumed to be normalized in range [0, 1].
++@end deftypefn
++
++@deftypefn {Method on @code{mglData}} @code{mreal} Linear (@code{mglPoint} &dif, @code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{dual} Linear (@code{mglPoint} &dif, @code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_linear_ext (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal *}dx, @code{mreal *}dy, @code{mreal *}dz)
++@deftypefnx {C function} @code{dual} mgl_datac_linear_ext (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{dual *}dx, @code{dual *}dy, @code{dual *}dz)
++Interpolates data by linear function to the given point @var{x} in [0...nx-1], @var{y} in [0...ny-1], @var{z} in [0...nz-1]. The values of derivatives at the point are saved in @var{dif}.
++@end deftypefn
++@cindex Linear1
++@deftypefn {Method on @code{mglData}} @code{mreal} Linear1 (@code{mglPoint} &dif, @code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Method on @code{mglDataC}} @code{dual} Linear1 (@code{mglPoint} &dif, @code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++Interpolates data by linear function to the given point @var{x}, @var{y}, @var{z} which assumed to be normalized in range [0, 1]. The values of derivatives at the point are saved in @var{dif}.
++@end deftypefn
++
++@end ifclear
++
++@c ------------------------------------------------------------------
++@external{}
++@node Data information, Operators, Interpolation, Data processing
++@section Data information
++@nav{}
++
++There are a set of functions for obtaining data properties in MGL language. However most of them can be found using "suffixes". Suffix can get some numerical value of the data array (like its size, maximal or minimal value, the sum of elements and so on) as number. Later it can be used as usual number in command arguments. The suffixes start from point @samp{.} right after (without spaces) variable name or its sub-array. For example, @code{a.nx} give the x-size of data @var{a}, @code{b(1).max} give maximal value of second row of variable @var{b}, @code{(c(:,0)^2).sum} give the sum of squares of elements in the first column of @var{c} and so on.
++
++
++@cindex PrintInfo
++@anchor{info}
++@deftypefn {MGL command} {} info dat
++@ifclear UDAV
++@deftypefnx {Method on @code{mglDataA}} @code{const char *} PrintInfo () @code{const}
++@deftypefnx {Method on @code{mglDataA}} @code{void} PrintInfo (@code{FILE *}fp) @code{const}
++@deftypefnx {C function only} @code{const char *} mgl_data_info (@code{HCDT} dat)
++@deftypefnx {Fortran subroutine} @code{} mgl_data_info (@code{long} dat, @code{char *}out, @code{int} len)
++@end ifclear
++Gets or prints to file @var{fp} or as message (in MGL) information about the data (sizes, maximum/minimum, momentums and so on).
++@end deftypefn
++
++@deftypefn {MGL command} {} info 'txt'
++Prints string @var{txt} as message.
++@end deftypefn
++
++@deftypefn {MGL command} {} info val
++Prints value of number @var{val} as message.
++@end deftypefn
++
++@anchor{print}
++@deftypefn {MGL command} {} print dat
++@deftypefnx {MGL command} {} print 'txt'
++@deftypefnx {MGL command} {} print val
++The same as @ref{info} but immediately print to stdout.
++@end deftypefn
++
++@anchor{echo}
++@deftypefn {MGL command} {} echo dat
++Prints all values of the data array @var{dat} as message.
++@end deftypefn
++
++
++@cindex GetNx
++@cindex GetNy
++@cindex GetNz
++@anchor{.nx} @anchor{.ny} @anchor{.nz}
++@deftypefn {MGL suffix} {(dat)} .nx
++@deftypefnx {MGL suffix} {(dat)} .ny
++@deftypefnx {MGL suffix} {(dat)} .nz
++@ifclear UDAV
++@deftypefnx {Method on @code{mglDataA}} @code{long} GetNx ()
++@deftypefnx {Method on @code{mglDataA}} @code{long} GetNy ()
++@deftypefnx {Method on @code{mglDataA}} @code{long} GetNz ()
++@deftypefnx {C function} @code{long} mgl_data_get_nx (@code{HCDT} dat)
++@deftypefnx {C function} @code{long} mgl_data_get_ny (@code{HCDT} dat)
++@deftypefnx {C function} @code{long} mgl_data_get_nz (@code{HCDT} dat)
++@end ifclear
++Gets the x-, y-, z-size of the data.
++@end deftypefn
++
++
++
++@cindex Maximal
++@anchor{.max}
++@deftypefn {MGL suffix} {(dat)} .max
++@ifclear UDAV
++@deftypefnx {Method on @code{mglDataA}} @code{mreal} Maximal () @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_max (@code{HCDT} dat)
++@end ifclear
++Gets maximal value of the data.
++@end deftypefn
++
++@cindex Minimal
++@anchor{.min}
++@deftypefn {MGL suffix} {(dat)} .min
++@ifclear UDAV
++@deftypefnx {Method on @code{mglDataA}} @code{mreal} Minimal () @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_min (@code{HMDT} dat) @code{const}
++@end ifclear
++Gets minimal value of the data.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglDataA}} @code{mreal} Minimal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_min_int (@code{HCDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
++Gets position of minimum to variables @var{i}, @var{j}, @var{k} and returns the minimal value.
++@end deftypefn
++@deftypefn {Method on @code{mglDataA}} @code{mreal} Maximal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_max_int (@code{HCDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
++Gets position of maximum to variables @var{i}, @var{j}, @var{k} and returns the maximal value.
++@end deftypefn
++@deftypefn {Method on @code{mglDataA}} @code{mreal} Minimal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_min_real (@code{HCDT} dat, @code{mreal} *x, @code{mreal} *y, @code{mreal} *z)
++Gets approximated (interpolated) position of minimum to variables @var{x}, @var{y}, @var{z} and returns the minimal value.
++@end deftypefn
++@end ifclear
++
++@anchor{.mx} @anchor{.my} @anchor{.mz}
++@deftypefn {MGL suffix} {(dat)} .mx
++@deftypefnx {MGL suffix} {(dat)} .my
++@deftypefnx {MGL suffix} {(dat)} .mz
++@ifclear UDAV
++@deftypefnx {Method on @code{mglDataA}} @code{mreal} Maximal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_max_real (@code{HCDT} dat, @code{mreal} *x, @code{mreal} *y, @code{mreal} *z)
++@end ifclear
++Gets approximated (interpolated) position of maximum to variables @var{x}, @var{y}, @var{z} and returns the maximal value.
++@end deftypefn
++
++
++@anchor{.mxf} @anchor{.myf} @anchor{.mzf}
++@anchor{.mxl} @anchor{.myl} @anchor{.mzl}
++@deftypefn {MGL suffix} {(dat)} .mxf
++@deftypefnx {MGL suffix} {(dat)} .myf
++@deftypefnx {MGL suffix} {(dat)} .mzf
++@deftypefnx {MGL suffix} {(dat)} .mxl
++@deftypefnx {MGL suffix} {(dat)} .myl
++@deftypefnx {MGL suffix} {(dat)} .mzl
++@ifclear UDAV
++@deftypefnx {Method on @code{mglDataA}} @code{long} Maximal (@code{char} dir, @code{long} from) @code{const}
++@deftypefnx {Method on @code{mglDataA}} @code{long} Maximal (@code{char} dir, @code{long} from, @code{long} &p1, @code{long} &p2) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_max_firstl (@code{HCDT} dat, @code{char} dir, @code{long} from, @code{long} *p1, @code{long} *p2)
++@end ifclear
++Get first starting @var{from} give position (or last one if @var{from}<0) maximum along direction @var{dir}, and save its orthogonal coordinates in @var{p1}, @var{p2}.
++@end deftypefn
++
++
++@cindex Momentum
++@anchor{.ax} @anchor{.ay} @anchor{.az} @anchor{.aa} @anchor{.sum}
++@anchor{.wx} @anchor{.wy} @anchor{.wz} @anchor{.wa}
++@anchor{.sx} @anchor{.sy} @anchor{.sz} @anchor{.sa}
++@anchor{.kx} @anchor{.ky} @anchor{.kz} @anchor{.ka}
++@deftypefn {MGL suffix} {(dat)} .sum
++@deftypefnx {MGL suffix} {(dat)} .ax
++@deftypefnx {MGL suffix} {(dat)} .ay
++@deftypefnx {MGL suffix} {(dat)} .az
++@deftypefnx {MGL suffix} {(dat)} .aa
++@deftypefnx {MGL suffix} {(dat)} .wx
++@deftypefnx {MGL suffix} {(dat)} .wy
++@deftypefnx {MGL suffix} {(dat)} .wz
++@deftypefnx {MGL suffix} {(dat)} .wa
++@deftypefnx {MGL suffix} {(dat)} .sx
++@deftypefnx {MGL suffix} {(dat)} .sy
++@deftypefnx {MGL suffix} {(dat)} .sz
++@deftypefnx {MGL suffix} {(dat)} .sa
++@deftypefnx {MGL suffix} {(dat)} .kx
++@deftypefnx {MGL suffix} {(dat)} .ky
++@deftypefnx {MGL suffix} {(dat)} .kz
++@deftypefnx {MGL suffix} {(dat)} .ka
++@ifclear UDAV
++@deftypefnx {Method on @code{mglDataA}} @code{mreal} Momentum (@code{char} dir, @code{mreal} &a, @code{mreal} &w) @code{const}
++@deftypefnx {Method on @code{mglDataA}} @code{mreal} Momentum (@code{char} dir, @code{mreal} &m, @code{mreal} &w, @code{mreal} &s, @code{mreal} &k) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_momentum_val (@code{HCDT} dat, @code{char} dir, @code{mreal} *a, @code{mreal} *w, @code{mreal} *s, @code{mreal} *k)
++@end ifclear
++Gets zero-momentum (energy, @math{I=\sum dat_i}) and write first momentum (median, @math{a = \sum \xi_i dat_i/I}), second momentum (width, @math{w^2 = \sum (\xi_i-a)^2 dat_i/I}), third momentum (skewness, @math{s = \sum (\xi_i-a)^3 dat_i/ I w^3}) and fourth momentum (kurtosis, @math{k = \sum (\xi_i-a)^4 dat_i / 3 I w^4}) to variables. Here @math{\xi} is corresponding coordinate if @var{dir} is @samp{'x'}, @samp{'y'} or @samp{'z'}. Otherwise median is @math{a = \sum dat_i/N}, width is @math{w^2 = \sum (dat_i-a)^2/N} and so on.
++@end deftypefn
++
++@anchor{.fst}
++@deftypefn {MGL suffix} {(dat)} .fst
++@ifclear UDAV
++@cindex Find
++@deftypefnx {Method on @code{mglDataA}} @code{mreal} Find (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_first (@code{HCDT} dat, @code{const char *}cond, @code{int} *i, @code{int} *j, @code{int} *k)
++@end ifclear
++Find position (after specified in @var{i}, @var{j}, @var{k}) of first nonzero value of formula @var{cond}. Function return the data value at found position.
++@end deftypefn
++
++@anchor{.lst}
++@deftypefn {MGL suffix} {(dat)} .lst
++@ifclear UDAV
++@cindex Last
++@deftypefnx {Method on @code{mglDataA}} @code{mreal} Last (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_last (@code{HCDT} dat, @code{const char *}cond, @code{int} *i, @code{int} *j, @code{int} *k)
++@end ifclear
++Find position (before specified in @var{i}, @var{j}, @var{k}) of last nonzero value of formula @var{cond}. Function return the data value at found position.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Method on @code{mglDataA}} @code{int} Find (@code{const char *}cond, @code{char} dir, @code{int} i=@code{0}, @code{int} j=@code{0}, @code{int} k=@code{0}) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_find (@code{HCDT} dat, @code{const char *}cond, @code{int} i, @code{int} j, @code{int} k)
++Return position of first in direction @var{dir} nonzero value of formula @var{cond}. The search is started from point @{i,j,k@}.
++@end deftypefn
++@cindex FindAny
++@deftypefn {Method on @code{mglDataA}} @code{bool} FindAny (@code{const char *}cond) @code{const}
++@deftypefnx {C function} @code{mreal} mgl_data_find_any (@code{HCDT} dat, @code{const char *}cond)
++Determines if any nonzero value of formula in the data array.
++@end deftypefn
++@end ifclear
++
++@anchor{.a}
++@deftypefn {MGL suffix} {(dat)} .a
++Give first (for @code{.a}, i.e. @code{dat->a[0]}).
++@end deftypefn
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node Operators, Global functions, Data information, Data processing
++@section Operators
++@nav{}
++
++@deftypefn {MGL command} {} copy @sc{dat} dat2 ['eq'='']
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} operator= (@code{const mglDataA &}d)
++@end ifclear
++Copies data from other variable.
++@end deftypefn
++
++@deftypefn {MGL command} {} copy dat @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mreal}} @code{void} operator= (@code{mreal} val)
++@end ifclear
++Set all data values equal to @var{val}.
++@end deftypefn
++
++@anchor{multo}
++@deftypefn {MGL command} {} multo dat dat2
++@deftypefnx {MGL command} {} multo dat @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} operator*= (@code{const mglDataA &}d)
++@deftypefnx {Method on @code{mglData}} @code{void} operator*= (@code{mreal} d)
++@deftypefnx {C function} @code{void} mgl_data_mul_dat (@code{HMDT} dat, @code{HCDT} d)
++@deftypefnx {C function} @code{void} mgl_data_mul_num (@code{HMDT} dat, @code{mreal} d)
++@end ifclear
++Multiplies data element by the other one or by value.
++@end deftypefn
++
++@anchor{divto}
++@deftypefn {MGL command} {} divto dat dat2
++@deftypefnx {MGL command} {} divto dat @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} operator/= (@code{const mglDataA &}d)
++@deftypefnx {Method on @code{mglData}} @code{void} operator/= (@code{mreal} d)
++@deftypefnx {C function} @code{void} mgl_data_div_dat (@code{HMDT} dat, @code{HCDT} d)
++@deftypefnx {C function} @code{void} mgl_data_div_num (@code{HMDT} dat, @code{mreal} d)
++@end ifclear
++Divides each data element by the other one or by value.
++@end deftypefn
++
++@anchor{addto}
++@deftypefn {MGL command} {} addto dat dat2
++@deftypefnx {MGL command} {} addto dat @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} operator+= (@code{const mglDataA &}d)
++@deftypefnx {Method on @code{mglData}} @code{void} operator+= (@code{mreal} d)
++@deftypefnx {C function} @code{void} mgl_data_add_dat (@code{HMDT} dat, @code{HCDT} d)
++@deftypefnx {C function} @code{void} mgl_data_add_num (@code{HMDT} dat, @code{mreal} d)
++@end ifclear
++Adds to each data element the other one or the value.
++@end deftypefn
++
++@anchor{subto}
++@deftypefn {MGL command} {} subto dat dat2
++@deftypefnx {MGL command} {} subto dat @code{val}
++@ifclear UDAV
++@deftypefnx {Method on @code{mglData}} @code{void} operator-= (@code{const mglDataA &}d)
++@deftypefnx {Method on @code{mglData}} @code{void} operator-= (@code{mreal} d)
++@deftypefnx {C function} @code{void} mgl_data_sub_dat (@code{HMDT} dat, @code{HCDT} d)
++@deftypefnx {C function} @code{void} mgl_data_sub_num (@code{HMDT} dat, @code{mreal} d)
++@end ifclear
++Subtracts from each data element the other one or the value.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Library Function} mglData operator+ (@code{const mglDataA &}a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator+ (@code{mreal} a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator+ (@code{const mglDataA &}a, @code{mreal} b)
++Adds the other data or the number.
++@end deftypefn
++
++@deftypefn {Library Function} mglData operator- (@code{const mglDataA &}a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator- (@code{mreal} a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator- (@code{const mglDataA &}a, @code{mreal} b)
++Subtracts the other data or the number.
++@end deftypefn
++
++@deftypefn {Library Function} mglData operator* (@code{const mglDataA &}a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator* (@code{mreal} a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator* (@code{const mglDataA &}a, @code{mreal} b)
++Multiplies by the other data or the number.
++@end deftypefn
++
++@deftypefn {Library Function} mglData operator/ (@code{const mglDataA &}a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator/ (@code{const mglDataA &}a, @code{mreal} b)
++Divides by the other data or the number.
++@end deftypefn
++@end ifclear
++
++@c ------------------------------------------------------------------
++@external{}
++@node Global functions, Evaluate expression, Operators, Data processing
++@section Global functions
++@nav{}
++
++@ifclear UDAV
++These functions are not methods of @code{mglData} class. However it provide additional functionality to handle data. So I put it in this chapter.
++@end ifclear
++
++@anchor{transform}
++@deftypefn {MGL command} {} transform @sc{dat} 'type' real imag
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglTransform (@code{const mglDataA &}real, @code{const mglDataA &}imag, @code{const char *}type)
++@deftypefnx {C function} @code{HMDT} mgl_transform (@code{HCDT} real, @code{HCDT} imag, @code{const char *}type)
++@end ifclear
++Does integral transformation of complex data @var{real}, @var{imag} on specified direction. The order of transformations is specified in string @var{type}: first character for x-dimension, second one for y-dimension, third one for z-dimension. The possible character are: @samp{f} is forward Fourier transformation, @samp{i} is inverse Fourier transformation, @samp{s} is Sine transform, @samp{c} is Cosine transform, @samp{h} is Hankel transform, @samp{n} or @samp{ } is no transformation.
++@end deftypefn
++
++@anchor{transforma}
++@deftypefn {MGL command} {} transforma @sc{dat} 'type' ampl phase
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglTransformA @code{const mglDataA &}ampl, @code{const mglDataA &}phase, @code{const char *}type)
++@deftypefnx {C function} @code{HMDT} mgl_transform_a @code{HCDT} ampl, @code{HCDT} phase, @code{const char *}type)
++@end ifclear
++The same as previous but with specified amplitude @var{ampl} and phase @var{phase} of complex numbers.
++@end deftypefn
++
++@anchor{fourier}
++@deftypefn {MGL command} {} fourier reDat imDat 'dir'
++@deftypefnx {MGL command} {} fourier complexDat 'dir'
++@ifclear UDAV
++@deftypefnx {Global function} @code{void} mglFourier @code{const mglDataA &}re, @code{const mglDataA &}im, @code{const char *}dir)
++@deftypefnx {Method on @code{mglDataC}} @code{void} FFT (@code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_data_fourier @code{HCDT} re, @code{HCDT} im, @code{const char *}dir)
++@deftypefnx {C function} @code{void} mgl_datac_fft (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Does Fourier transform of complex data @var{re}+i*@var{im} in directions @var{dir}. Result is placed back into @var{re} and @var{im} data arrays. If @var{dir} contain @samp{i} then inverse Fourier is used.
++@end deftypefn
++
++@anchor{stfad}
++@deftypefn {MGL command} {} stfad @sc{res} real imag @code{dn} ['dir'='x']
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglSTFA (@code{const mglDataA &}real, @code{const mglDataA &}imag, @code{int} dn, @code{char} dir=@code{'x'})
++@deftypefnx {C function} @code{HMDT} mgl_data_stfa (@code{HCDT} real, @code{HCDT} imag, @code{int} dn, @code{char} dir)
++@end ifclear
++Short time Fourier transformation for real and imaginary parts. Output is amplitude of partial Fourier of length @var{dn}. For example if @var{dir}=@samp{x}, result will have size @{int(nx/dn), dn, ny@} and it will contain @math{res[i,j,k]=|\sum_d^dn exp(I*j*d)*(real[i*dn+d,k]+I*imag[i*dn+d,k])|/dn}.
++@end deftypefn
++
++@anchor{tridmat}
++@deftypefn {MGL command} {} tridmat @sc{res adat bdat cdat ddat} 'how'
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglTridMat (@code{const mglDataA &}A, @code{const mglDataA &}B, @code{const mglDataA &}C, @code{const mglDataA &}D, @code{const char *}how)
++@deftypefnx {Global function} @code{mglDataC} mglTridMatC (@code{const mglDataA &}A, @code{const mglDataA &}B, @code{const mglDataA &}C, @code{const mglDataA &}D, @code{const char *}how)
++@deftypefnx {C function} @code{HMDT} mgl_data_tridmat (@code{HCDT} A, @code{HCDT} B, @code{HCDT} C, @code{HCDT} D, @code{const char*}how)
++@deftypefnx {C function} @code{HADT} mgl_datac_tridmat (@code{HCDT} A, @code{HCDT} B, @code{HCDT} C, @code{HCDT} D, @code{const char*}how)
++@end ifclear
++Get array as solution of tridiagonal system of equations @var{A}[i]*x[i-1]+@var{B}[i]*x[i]+@var{C}[i]*x[i+1]=@var{D}[i]. String @var{how} may contain:
++@itemize @bullet
++@item
++@samp{xyz} for solving along x-,y-,z-directions correspondingly;
++@item
++@samp{h} for solving along hexagonal direction at x-y plain (require square matrix);
++@item
++@samp{c} for using periodical boundary conditions;
++@item
++@samp{d} for for diffraction/diffuse calculation (i.e. for using -@var{A}[i]*@var{D}[i-1]+(2-@var{B}[i])*@var{D}[i]-@var{C}[i]*@var{D}[i+1] at right part instead of @var{D}[i]).
++@end itemize
++Data dimensions of arrays @var{A}, @var{B}, @var{C} should be equal. Also their dimensions need to be equal to all or to minor dimension(s) of array @var{D}. @sref{PDE solving hints}
++@end deftypefn
++
++
++@anchor{pde}
++@deftypefn {MGL command} {} pde @sc{res} 'ham' ini_re ini_im [@code{dz=0.1 k0=100}]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglPDE (@code{HMGL} gr, @code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{mreal} dz=@code{0.1}, @code{mreal} k0=@code{100}, @code{const char *}opt=@code{""})
++@deftypefnx {Global function} @code{mglDataC} mglPDEc (@code{HMGL} gr, @code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{mreal} dz=@code{0.1}, @code{mreal} k0=@code{100}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{HMDT} mgl_pde_solve (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{mreal} dz, @code{mreal} k0, @code{const char *}opt)
++@deftypefnx {C function} @code{HADT} mgl_pde_solve_c (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{mreal} dz, @code{mreal} k0, @code{const char *}opt)
++@end ifclear
++Solves equation du/dz = i*k0*@var{ham}(p,q,x,y,z,|u|)[u], where p=-i/k0*d/dx, q=-i/k0*d/dy are pseudo-differential operators. Parameters @var{ini_re}, @var{ini_im} specify real and imaginary part of initial field distribution. Parameters @var{Min}, @var{Max} set the bounding box for the solution. Note, that really this ranges are increased by factor 3/2 for purpose of reducing reflection from boundaries. Parameter @var{dz} set the step along evolutionary coordinate z. At this moment, simplified form of function @var{ham} is supported -- all ``mixed'' terms (like @samp{x*p}->x*d/dx) are excluded. For example, in 2D case this function is effectively @math{ham = f(p,z) + g(x,z,u)}. However commutable combinations (like @samp{x*q}->x*d/dy) are allowed. Here variable @samp{u} is used for field amplitude |u|. This allow one solve nonlinear problems -- for example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. You may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"}. See also @ref{apde}, @ref{qo2d}, @ref{qo3d}. @sref{PDE solving hints}
++@end deftypefn
++
++@anchor{apde}
++@deftypefn {MGL command} {} apde @sc{res} 'ham' ini_re ini_im [@code{dz=0.1 k0=100}]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglAPDE (@code{HMGL} gr, @code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{mreal} dz=@code{0.1}, @code{mreal} k0=@code{100}, @code{const char *}opt=@code{""})
++@deftypefnx {Global function} @code{mglDataC} mglAPDEc (@code{HMGL} gr, @code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{mreal} dz=@code{0.1}, @code{mreal} k0=@code{100}, @code{const char *}opt=@code{""})
++@deftypefnx {C function} @code{HMDT} mgl_pde_solve_adv (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{mreal} dz, @code{mreal} k0, @code{const char *}opt)
++@deftypefnx {C function} @code{HADT} mgl_pde_solve_adv_c (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{mreal} dz, @code{mreal} k0, @code{const char *}opt)
++@end ifclear
++Solves equation du/dz = i*k0*@var{ham}(p,q,x,y,z,|u|)[u], where p=-i/k0*d/dx, q=-i/k0*d/dy are pseudo-differential operators. Parameters @var{ini_re}, @var{ini_im} specify real and imaginary part of initial field distribution. Parameters @var{Min}, @var{Max} set the bounding box for the solution. Note, that really this ranges are increased by factor 3/2 for purpose of reducing reflection from boundaries. Parameter @var{dz} set the step along evolutionary coordinate z. The advanced and rather slow algorithm is used for taking into account both spatial dispersion and inhomogeneities of media [see A.A. Balakin, E.D. Gospodchikov, A.G. Shalashov, JETP letters v.104, p.690-695 (2016)]. Variable @samp{u} is used for field amplitude |u|. This allow one solve nonlinear problems -- for example, for nonlinear Shrodinger equation you may set @code{ham="p^2 + q^2 - u^2"}. You may specify imaginary part for wave absorption, like @code{ham = "p^2 + i*x*(x>0)"}. See also @ref{pde}. @sref{PDE solving hints}
++@end deftypefn
++
++
++@anchor{ray}
++@deftypefn {MGL command} {} ray @sc{res} 'ham' @code{x0 y0 z0 p0 q0 v0 [dt=0.1 tmax=10]}
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglRay (@code{const char *}ham, @code{mglPoint} r0, @code{mglPoint} p0, @code{mreal} dt=@code{0.1}, @code{mreal} tmax=@code{10})
++@deftypefnx {C function} @code{HMDT} mgl_ray_trace (@code{const char *}ham, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} px, @code{mreal} py, @code{mreal} pz, @code{mreal} dt, @code{mreal} tmax)
++@end ifclear
++Solves GO ray equation like dr/dt = d @var{ham}/dp, dp/dt = -d @var{ham}/dr. This is Hamiltonian equations for particle trajectory in 3D case. Here @var{ham} is Hamiltonian which may depend on coordinates @samp{x}, @samp{y}, @samp{z}, momentums @samp{p}=px, @samp{q}=py, @samp{v}=pz and time @samp{t}: @math{ham = H(x,y,z,p,q,v,t)}. The starting point (at @code{t=0}) is defined by variables @var{r0}, @var{p0}. Parameters @var{dt} and @var{tmax} specify the integration step and maximal time for ray tracing. Result is array of @{x,y,z,p,q,v,t@} with dimensions @{7 * int(@var{tmax}/@var{dt}+1) @}.
++@end deftypefn
++
++@anchor{ode}
++@deftypefn {MGL command} {} ode @sc{res} 'df' 'var' ini [@code{dt=0.1 tmax=10}]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglODE (@code{const char *}df, @code{const char *}var, @code{const mglDataA &}ini, @code{mreal} dt=@code{0.1}, @code{mreal} tmax=@code{10})
++@deftypefnx {Global function} @code{mglDataC} mglODEc (@code{const char *}df, @code{const char *}var, @code{const mglDataA &}ini, @code{mreal} dt=@code{0.1}, @code{mreal} tmax=@code{10})
++@deftypefnx {C function} @code{HMDT} mgl_ode_solve_str (@code{const char *}df, @code{const char *}var, @code{HCDT} ini, @code{mreal} dt, @code{mreal} tmax)
++@deftypefnx {C function} @code{HADT} mgl_ode_solve_str_c (@code{const char *}df, @code{const char *}var, @code{HCDT} ini, @code{mreal} dt, @code{mreal} tmax)
++@deftypefnx {C function} @code{HMDT} mgl_ode_solve (@code{void (*}df@code{)(const mreal *x, mreal *dx, void *par)}, @code{int} n, @code{const mreal *}ini, @code{mreal} dt, @code{mreal} tmax)
++@deftypefnx {C function} @code{HMDT} mgl_ode_solve_ex (@code{void (*}df@code{)(const mreal *x, mreal *dx, void *par)}, @code{int} n, @code{const mreal *}ini, @code{mreal} dt, @code{mreal} tmax, @code{void (*}bord@code{)(mreal *x, const mreal *xprev, void *par)})
++@end ifclear
++Solves ODE equations dx/dt = df(x). The functions @var{df} can be specified as string of ';'-separated textual formulas (argument @var{var} set the character ids of variables x[i]) or as callback function, which fill @code{dx} array for give @code{x}'s. Parameters @var{ini}, @var{dt}, @var{tmax} set initial values, time step and maximal time of the calculation. Result is data array with dimensions @{@var{n} * int(@var{tmax}/@var{dt}+1)@}.
++@end deftypefn
++
++@anchor{qo2d}
++@deftypefn {MGL command} {} qo2d @sc{res} 'ham' ini_re ini_im ray [@code{r=1 k0=100} xx yy]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglQO2d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Global function} @code{mglData} mglQO2d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Global function} @code{mglDataC} mglQO2dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Global function} @code{mglDataC} mglQO2dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {C function} @code{HMDT} mgl_qo2d_solve (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
++@deftypefnx {C function} @code{HADT} mgl_qo2d_solve_c (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
++@deftypefnx {C function} @code{HMDT} mgl_qo2d_func (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
++@deftypefnx {C function} @code{HADT} mgl_qo2d_func_c (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
++@end ifclear
++Solves equation du/dt = i*k0*@var{ham}(p,q,x,y,|u|)[u], where p=-i/k0*d/dx, q=-i/k0*d/dy are pseudo-differential operators (see @code{mglPDE()} for details). Parameters @var{ini_re}, @var{ini_im} specify real and imaginary part of initial field distribution. Parameters @var{ray} set the reference ray, i.e. the ray around which the accompanied coordinate system will be maked. You may use, for example, the array created by @ref{ray} function. Note, that the reference ray @strong{must be} smooth enough to make accompanied coodrinates unambiguity. Otherwise errors in the solution may appear. If @var{xx} and @var{yy} are non-zero then Cartesian coordinates for each point will be written into them. See also @ref{pde}, @ref{qo3d}. @sref{PDE solving hints}
++@end deftypefn
++
++
++@anchor{qo3d}
++@deftypefn {MGL command} {} qo3d @sc{res} 'ham' ini_re ini_im ray [@code{r=1 k0=100} xx yy zz]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglQO3d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Global function} @code{mglData} mglQO3d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mglData &}zz, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Global function} @code{mglDataC} mglQO3dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Global function} @code{mglDataC} mglQO3dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mglData &}zz, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {C function} @code{HMDT} mgl_qo3d_solve (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
++@deftypefnx {C function} @code{HADT} mgl_qo3d_solve_c (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
++@deftypefnx {C function} @code{HMDT} mgl_qo3d_func (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
++@deftypefnx {C function} @code{HADT} mgl_qo3d_func_c (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
++@end ifclear
++Solves equation du/dt = i*k0*@var{ham}(p,q,v,x,y,z,|u|)[u], where p=-i/k0*d/dx, q=-i/k0*d/dy, v=-i/k0*d/dz are pseudo-differential operators (see @code{mglPDE()} for details). Parameters @var{ini_re}, @var{ini_im} specify real and imaginary part of initial field distribution. Parameters @var{ray} set the reference ray, i.e. the ray around which the accompanied coordinate system will be maked. You may use, for example, the array created by @ref{ray} function. Note, that the reference ray @strong{must be} smooth enough to make accompanied coodrinates unambiguity. Otherwise errors in the solution may appear. If @var{xx} and @var{yy} and @var{zz} are non-zero then Cartesian coordinates for each point will be written into them. See also @ref{pde}, @ref{qo2d}. @sref{PDE solving hints}
++@end deftypefn
++
++
++@anchor{jacobian}
++@deftypefn {MGL command} {} jacobian @sc{res} xdat ydat [zdat]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglJacobian (@code{const mglDataA &}x, @code{const mglDataA &}y)
++@deftypefnx {Global function} @code{mglData} mglJacobian (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z)
++@deftypefnx {C function} @code{HMDT} mgl_jacobian_2d (@code{HCDT} x, @code{HCDT} y)
++@deftypefnx {C function} @code{HMDT} mgl_jacobian_3d (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z)
++@end ifclear
++Computes the Jacobian for transformation @{i,j,k@} to @{@var{x},@var{y},@var{z}@} where initial coordinates @{i,j,k@} are data indexes normalized in range [0,1]. The Jacobian is determined by formula det||@math{dr_\alpha/d\xi_\beta}|| where @math{r}=@{@var{x},@var{y},@var{z}@} and @math{\xi}=@{i,j,k@}. All dimensions must be the same for all data arrays. Data must be 3D if all 3 arrays @{@var{x},@var{y},@var{z}@} are specified or 2D if only 2 arrays @{@var{x},@var{y}@} are specified.
++@end deftypefn
++
++@anchor{triangulation}
++@deftypefn {MGL command} {} triangulation @sc{res} xdat ydat
++@c @deftypefn {MGL command} {} triangulation @sc{res} xdat ydat [zdat]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglTriangulation (@code{const mglDataA &}x, @code{const mglDataA &}y)
++@c @deftypefnx {Global function} @code{mglData} mglTriangulation (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z)
++@deftypefnx {C function} @code{HMDT} mgl_triangulation_2d (@code{HCDT} x, @code{HCDT} y)
++@c @deftypefnx {C function} @code{HMDT} mgl_triangulation_3d (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z)
++@end ifclear
++Computes triangulation for arbitrary placed points with coordinates @{@var{x},@var{y}@} (i.e. finds triangles which connect points). MathGL use @uref{http://www.s-hull.org/,s-hull} code for triangulation. The sizes of 1st dimension @strong{must be equal} for all arrays @code{x.nx=y.nx}. Resulting array can be used in @ref{triplot} or @ref{tricont} functions for visualization of reconstructed surface. @sref{Making regular data}
++@end deftypefn
++
++@ifclear UDAV
++
++@deftypefn {Global function} @code{mglData} mglGSplineInit (@code{const mglDataA &}x, @code{const mglDataA &}y)
++@deftypefnx {Global function} @code{mglDataC} mglGSplineCInit (@code{const mglDataA &}x, @code{const mglDataA &}y)
++@deftypefnx {C function} @code{HMDT} mgl_gspline_init (@code{HCDT} x, @code{HCDT} y)
++@deftypefnx {C function} @code{HADT} mgl_gsplinec_init (@code{HCDT} x, @code{HCDT} y)
++Prepare coefficients for global cubic spline interpolation.
++@end deftypefn
++
++@deftypefn {Global function} @code{mreal} mglGSpline (@code{const mglDataA &}coef, @code{mreal} dx, @code{mreal *}d1=@code{0}, @code{mreal *}d2=@code{0})
++@deftypefnx {Global function} @code{dual} mglGSplineC (@code{const mglDataA &}coef, @code{mreal} dx, @code{dual *}d1=@code{0}, @code{dual *}d2=@code{0})
++@deftypefnx {C function} @code{mreal} mgl_gspline (@code{HCDT} coef, @code{mreal} dx, @code{mreal *}d1, @code{mreal *}d2)
++@deftypefnx {C function} @code{dual} mgl_gsplinec (@code{HCDT} coef, @code{mreal} dx, @code{dual *}d1, @code{dual *}d2)
++Evaluate global cubic spline (and its 1st and 2nd derivatives @var{d1}, @var{d2} if they are not @code{NULL}) using prepared coefficients @var{coef} at point @var{dx}+@var{x0} (where @var{x0} is 1st element of data @var{x} provided to @code{mglGSpline*Init()} function).
++@end deftypefn
++
++@end ifclear
++
++
++@anchor{ifs2d}
++@deftypefn {MGL command} {} ifs2d @sc{res} dat @code{num} [@code{skip=20}]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglIFS2d (@code{const mglDataA &}dat, @code{long} num, @code{long} skip=@code{20})
++@deftypefnx {C function} @code{HMDT} mgl_data_ifs_2d (@code{HCDT} dat, @code{long} num, @code{long} skip)
++@end ifclear
++Computes @var{num} points @{x[i]=res[0,i], y[i]=res[1,i]@} for fractal using iterated function system. Matrix @var{dat} is used for generation according the formulas
++@verbatim
++x[i+1] = dat[0,i]*x[i] + dat[1,i]*y[i] + dat[4,i];
++y[i+1] = dat[2,i]*x[i] + dat[3,i]*y[i] + dat[5,i];
++@end verbatim
++Value @code{dat[6,i]} is used as weight factor for i-th row of matrix @var{dat}. At this first @var{skip} iterations will be omitted. Data array @var{dat} must have x-size greater or equal to 7. @sref{Fractal sample}
++@end deftypefn
++
++@anchor{ifs3d}
++@deftypefn {MGL command} {} ifs3d @sc{res} dat @code{num} [@code{skip=20}]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglIFS3d (@code{const mglDataA &}dat, @code{long} num, @code{long} skip=@code{20})
++@deftypefnx {C function} @code{HMDT} mgl_data_ifs_3d (@code{HCDT} dat, @code{long} num, @code{long} skip)
++@end ifclear
++Computes @var{num} points @{x[i]=res[0,i], y[i]=res[1,i], z[i]=res[2,i]@} for fractal using iterated function system. Matrix @var{dat} is used for generation according the formulas
++@verbatim
++x[i+1] = dat[0,i]*x[i] + dat[1,i]*y[i] + dat[2,i]*z[i] + dat[9,i];
++y[i+1] = dat[3,i]*x[i] + dat[4,i]*y[i] + dat[5,i]*z[i] + dat[10,i];
++z[i+1] = dat[6,i]*x[i] + dat[7,i]*y[i] + dat[8,i]*z[i] + dat[11,i];
++@end verbatim
++Value @code{dat[12,i]} is used as weight factor for i-th row of matrix @var{dat}. At this first @var{skip} iterations will be omitted. Data array @var{dat} must have x-size greater or equal to 13. @sref{Fractal sample}
++@end deftypefn
++
++@anchor{ifsfile}
++@deftypefn {MGL command} {} ifsfile @sc{res} 'fname' 'name' @code{num} [@code{skip=20}]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglIFSfile (@code{const char *}fname, @code{const char *}name, @code{long} num, @code{long} skip=@code{20})
++@deftypefnx {C function} @code{HMDT} mgl_data_ifs_file (@code{const char *}fname, @code{const char *}name, @code{long} num, @code{long} skip)
++@end ifclear
++Reads parameters of IFS fractal named @var{name} from file @var{fname} and computes @var{num} points for this fractal. At this first @var{skip} iterations will be omitted. See also @ref{ifs2d}, @ref{ifs3d}.
++
++IFS file may contain several records. Each record contain the name of fractal (@samp{binary} in the example below) and the body of fractal, which is enclosed in curly braces @{@}. Symbol @samp{;} start the comment. If the name of fractal contain @samp{(3D)} or @samp{(3d)} then the 3d IFS fractal is specified. The sample below contain two fractals: @samp{binary} -- usual 2d fractal, and @samp{3dfern (3D)} -- 3d fractal.
++
++@verbatim
++ binary
++ { ; comment allowed here
++ ; and here
++ .5 .0 .0 .5 -2.563477 -0.000003 .333333 ; also comment allowed here
++ .5 .0 .0 .5 2.436544 -0.000003 .333333
++ .0 -.5 .5 .0 4.873085 7.563492 .333333
++ }
++
++ 3dfern (3D) {
++ .00 .00 0 .0 .18 .0 0 0.0 0.00 0 0.0 0 .01
++ .85 .00 0 .0 .85 .1 0 -0.1 0.85 0 1.6 0 .85
++ .20 -.20 0 .2 .20 .0 0 0.0 0.30 0 0.8 0 .07
++ -.20 .20 0 .2 .20 .0 0 0.0 0.30 0 0.8 0 .07
++ }
++@end verbatim
++@end deftypefn
++
++<<<<<<< HEAD
++@anchor{ifsfile}
++@deftypefn {MGL command} {} ifsfile @sc{res} 'fname' 'name' @code{num} [@code{skip=20}]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglIFSfile (@code{const char *}fname, @code{const char *}name, @code{long} num, @code{long} skip=@code{20})
++@deftypefnx {C function} @code{HMDT} mgl_data_ifs_file (@code{const char *}fname, @code{const char *}name, @code{long} num, @code{long} skip)
++@end ifclear
++Reads parameters of IFS fractal named @var{name} from file @var{fname} and computes @var{num} points for this fractal. At this first @var{skip} iterations will be omitted. See also @ref{ifs2d}, @ref{ifs3d}.
++
++IFS file may contain several records. Each record contain the name of fractal (@samp{binary} in the example below) and the body of fractal, which is enclosed in curly braces @{@}. Symbol @samp{;} start the comment. If the name of fractal contain @samp{(3D)} or @samp{(3d)} then the 3d IFS fractal is specified. The sample below contain two fractals: @samp{binary} -- usual 2d fractal, and @samp{3dfern (3D)} -- 3d fractal.
++
++@verbatim
++ binary
++ { ; comment allowed here
++ ; and here
++ .5 .0 .0 .5 -2.563477 -0.000003 .333333 ; also comment allowed here
++ .5 .0 .0 .5 2.436544 -0.000003 .333333
++ .0 -.5 .5 .0 4.873085 7.563492 .333333
++ }
++
++ 3dfern (3D) {
++ .00 .00 0 .0 .18 .0 0 0.0 0.00 0 0.0 0 .01
++ .85 .00 0 .0 .85 .1 0 -0.1 0.85 0 1.6 0 .85
++ .20 -.20 0 .2 .20 .0 0 0.0 0.30 0 0.8 0 .07
++ -.20 .20 0 .2 .20 .0 0 0.0 0.30 0 0.8 0 .07
++ }
++@end verbatim
++=======
++@anchor{flame2d}
++@deftypefn {MGL command} {} flame2d @sc{res} dat func @code{num} [@code{skip=20}]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglFlame2d (@code{const mglDataA &}dat, @code{const mglDataA &}func, @code{long} num, @code{long} skip=@code{20})
++@deftypefnx {C function} @code{HMDT} mgl_data_flame_2d (@code{HCDT} dat, @code{HCDT} func, @code{long} num, @code{long} skip)
++@end ifclear
++Computes @var{num} points @{x[i]=res[0,i], y[i]=res[1,i]@} for "flame" fractal using iterated function system. Array @var{func} define "flame" function identificator (@var{func}[0,i,j]), its weight (@var{func}[0,i,j]) and arguments (@var{func}[2 ... 5,i,j]). Matrix @var{dat} set linear transformation of coordinates before applying the function. The resulting coordinates are
++@verbatim
++xx = dat[0,i]*x[j] + dat[1,j]*y[i] + dat[4,j];
++yy = dat[2,i]*x[j] + dat[3,j]*y[i] + dat[5,j];
++x[j+1] = sum_i @var{func}[1,i,j]*@var{func}[0,i,j]_x(xx, yy; @var{func}[2,i,j],...,@var{func}[5,i,j]);
++y[j+1] = sum_i @var{func}[1,i,j]*@var{func}[0,i,j]_y(xx, yy; @var{func}[2,i,j],...,@var{func}[5,i,j]);
++@end verbatim
++The possible function ids are: @code{mglFlame2d_linear=0, mglFlame2d_sinusoidal, mglFlame2d_spherical, mglFlame2d_swirl, mglFlame2d_horseshoe,
++ mglFlame2d_polar, mglFlame2d_handkerchief,mglFlame2d_heart, mglFlame2d_disc, mglFlame2d_spiral,
++ mglFlame2d_hyperbolic, mglFlame2d_diamond, mglFlame2d_ex, mglFlame2d_julia, mglFlame2d_bent,
++ mglFlame2d_waves, mglFlame2d_fisheye, mglFlame2d_popcorn, mglFlame2d_exponential, mglFlame2d_power,
++ mglFlame2d_cosine, mglFlame2d_rings, mglFlame2d_fan, mglFlame2d_blob, mglFlame2d_pdj,
++ mglFlame2d_fan2, mglFlame2d_rings2, mglFlame2d_eyefish, mglFlame2d_bubble, mglFlame2d_cylinder,
++ mglFlame2d_perspective, mglFlame2d_noise, mglFlame2d_juliaN, mglFlame2d_juliaScope, mglFlame2d_blur,
++ mglFlame2d_gaussian, mglFlame2d_radialBlur, mglFlame2d_pie, mglFlame2d_ngon, mglFlame2d_curl,
++ mglFlame2d_rectangles, mglFlame2d_arch, mglFlame2d_tangent, mglFlame2d_square, mglFlame2d_blade,
++ mglFlame2d_secant, mglFlame2d_rays, mglFlame2d_twintrian, mglFlame2d_cross, mglFlame2d_disc2,
++ mglFlame2d_supershape, mglFlame2d_flower, mglFlame2d_conic, mglFlame2d_parabola, mglFlame2d_bent2,
++ mglFlame2d_bipolar, mglFlame2d_boarders, mglFlame2d_butterfly, mglFlame2d_cell, mglFlame2d_cpow,
++ mglFlame2d_curve, mglFlame2d_edisc, mglFlame2d_elliptic, mglFlame2d_escher, mglFlame2d_foci,
++ mglFlame2d_lazySusan, mglFlame2d_loonie, mglFlame2d_preBlur, mglFlame2d_modulus, mglFlame2d_oscope,
++ mglFlame2d_polar2, mglFlame2d_popcorn2, mglFlame2d_scry, mglFlame2d_separation, mglFlame2d_split,
++ mglFlame2d_splits, mglFlame2d_stripes, mglFlame2d_wedge, mglFlame2d_wedgeJulia, mglFlame2d_wedgeSph,
++ mglFlame2d_whorl, mglFlame2d_waves2, mglFlame2d_exp, mglFlame2d_log, mglFlame2d_sin,
++ mglFlame2d_cos, mglFlame2d_tan, mglFlame2d_sec, mglFlame2d_csc, mglFlame2d_cot,
++ mglFlame2d_sinh, mglFlame2d_cosh, mglFlame2d_tanh, mglFlame2d_sech, mglFlame2d_csch,
++ mglFlame2d_coth, mglFlame2d_auger, mglFlame2d_flux.}
++Value @code{dat[6,i]} is used as weight factor for i-th row of matrix @var{dat}. At this first @var{skip} iterations will be omitted. Sizes of data arrays must be: @var{dat}.nx>=7, @var{func}.nx>=2 and @var{func}.nz=@var{dat}.ny. @sref{Fractal sample}
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++@end deftypefn
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node Evaluate expression, Special data classes, Global functions, Data processing
++@section Evaluate expression
++@nav{}
++
++@ifset UDAV
++You can use arbitrary formulas of existed data arrays or constants as any argument of data processing or data plotting commands. There are only 2 limitations: formula shouldn't contain spaces (to be recognized as single argument), and formula cannot be used as argument which will be (re)created by MGL command.
++@end ifset
++
++@ifclear UDAV
++@cindex mglExpr
++@cindex mglExprC
++
++MathGL have a special classes @code{mglExpr} and @code{mglExprC} for evaluating of formula specified by the string for real and complex numbers correspondingly. These classes are defined in @code{#include <mgl2/data.h>} and @code{#include <mgl2/datac.h>} correspondingly. It is the fast variant of formula evaluation. At creation it will be recognized and compiled to tree-like internal code. At evaluation stage only fast calculations are performed. There is no difference between lower or upper case in formulas. If argument value lie outside the range of function definition then function returns NaN. @xref{Textual formulas}.
++
++@deftypefn {Constructor on @code{mglExpr}} @code{} mglExpr (@code{const char *}expr)
++@deftypefnx {Constructor on @code{mglExprC}} @code{} mglExprC (@code{const char *}expr)
++@deftypefnx {C function} @code{HMEX} mgl_create_expr (@code{const char *}expr)
++@deftypefnx {C function} @code{HAEX} mgl_create_cexpr (@code{const char *}expr)
++Parses the formula @var{expr} and creates formula-tree. Constructor recursively parses the formula and creates a tree-like structure containing functions and operators for fast further evaluating by @code{Calc()} or @code{CalcD()} functions.
++@end deftypefn
++
++@deftypefn {Destructor on @code{mglExpr}} @code{} ~mglExpr ()
++@deftypefnx {Destructor on @code{mglExprC}} @code{} ~mglExprC ()
++@deftypefnx {C function} @code{void} mgl_delete_expr (@code{HMEX} ex)
++@deftypefnx {C function} @code{void} mgl_delete_cexpr (@code{HAEX} ex)
++Deletes the instance of class mglExpr.
++@end deftypefn
++
++@deftypefn {Method on @code{mglExpr}} @code{mreal} Eval (@code{mreal} x, @code{mreal} y, @code{mreal} z)
++@deftypefnx {Method on @code{mglExprC}} @code{dual} Eval (@code{dual} x, @code{dual} y, @code{dual} z)
++@deftypefnx {C function} @code{mreal} mgl_expr_eval (@code{HMEX} ex, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++@deftypefnx {C function} @code{dual} mgl_cexpr_eval (@code{HAEX} ex, @code{dual} x, @code{dual} y, @code{dual} z)
++Evaluates the formula for @code{'x','r'}=@var{x}, @code{'y','n'}=@var{y}, @code{'z','t'}=@var{z}, @code{'a','u'}=@var{u}.
++@end deftypefn
++
++@deftypefn {Method on @code{mglExpr}} @code{mreal} Eval (@code{mreal} var[26])
++@deftypefnx {Method on @code{mglExprC}} @code{dual} Eval (@code{dual} var[26])
++@deftypefnx {C function} @code{mreal} mgl_expr_eval_v (@code{HMEX} ex, @code{mreal *}var)
++@deftypefnx {C function} @code{dual} mgl_expr_eval_v (@code{HAEX} ex, @code{dual *}var)
++Evaluates the formula for variables in array @var{var}[0,...,'z'-'a'].
++@end deftypefn
++
++
++@deftypefn {Method on @code{mglExpr}} @code{mreal} Diff (@code{char} dir, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++@deftypefnx {C function} @code{mreal} mgl_expr_diff (@code{HMEX} ex, @code{char} dir, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++Evaluates the formula derivation respect to @var{dir} for @code{'x','r'}=@var{x}, @code{'y','n'}=@var{y}, @code{'z','t'}=@var{z}, @code{'a','u'}=@var{u}.
++@end deftypefn
++
++@deftypefn {Method on @code{mglExpr}} @code{mreal} Diff (@code{char} dir, @code{mreal} var[26])
++@deftypefnx {C function} @code{mreal} mgl_expr_diff_v (@code{HMEX} ex, @code{char} dir, @code{mreal *}var)
++Evaluates the formula derivation respect to @var{dir} for variables in array @var{var}[0,...,'z'-'a'].
++@end deftypefn
++
++@end ifclear
++
++@c ------------------------------------------------------------------
++@external{}
++@node Special data classes, , Evaluate expression, Data processing
++@section Special data classes
++@nav{}
++
++
++@ifset UDAV
++MGL use these special classes automatically.
++@end ifset
++
++@ifclear UDAV
++This section describe special data classes @code{mglDataV}, @code{mglDataF}, @code{mglDataT} and @code{mglDataR} which sometime can noticeable speed up drawing or data handling. These classes are defined in @code{#include <mgl2/data.h>}. Note, that all plotting and data handling routines can be done using usual @code{mglData} or @code{mglDataC} classes. Also these special classes are usable in C++ code only.
++
++@heading Class @code{mglDataV}
++represent variable with values equidistantly distributed in given range.
++@deftypefn {Constructor on @code{mglDataV}} @code{} mglDataV (@code{const mglDataV &} d)
++Copy constructor.
++@end deftypefn
++@deftypefn {Constructor on @code{mglDataV}} @code{} mglDataV (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1}, @code{mreal} v1=@code{0}, @code{mreal} v2=@code{NaN}, @code{char} dir=@code{'x'})
++Create variable with "sizes" @var{nx}x@var{ny}x@var{nz} which changes from @var{v1} to @var{v2} (or is constant if @var{v2}=@code{NaN}) along @var{dir} direction.
++@end deftypefn
++@deftypefn {Method on @code{mglDataV}} @code{void} Create (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1})
++Set "sizes" @var{nx}x@var{ny}x@var{nz}.
++@end deftypefn
++@deftypefn {Method on @code{mglDataV}} @code{void} Fill (@code{mreal} x1, @code{mreal} x2=@code{NaN}, @code{char} dir=@code{'x'})
++Set ranges of the variable.
++@end deftypefn
++@deftypefn {Method on @code{mglDataV}} @code{void} Freq (@code{mreal} dp, @code{char} dir=@code{'x'})
++Set as frequency variable with increment @var{dp}.
++@end deftypefn
++
++@heading Class @code{mglDataF}
++represent function which values are evaluated (instead of access to data array as in @code{mglData}).
++@deftypefn {Constructor on @code{mglDataF}} @code{} mglDataF (@code{const mglDataF &} d)
++Copy constructor.
++@end deftypefn
++@deftypefn {Constructor on @code{mglDataF}} @code{} mglDataF (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1})
++Create variable with "sizes" @var{nx}x@var{ny}x@var{nz} with zero function.
++@end deftypefn
++@deftypefn {Method on @code{mglDataF}} @code{void} Create (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1})
++Set "sizes" @var{nx}x@var{ny}x@var{nz}.
++@end deftypefn
++@deftypefn {Method on @code{mglDataF}} @code{void} SetRanges (@code{mglPoint} p1, @code{mglPoint} p2)
++Set ranges for internal x,y,z variables.
++@end deftypefn
++@deftypefn {Method on @code{mglDataF}} @code{void} SetFormula (@code{const char *}func)
++Set string which will be evaluated at function calls. Note this variant is about 10 times slower than @code{SetFunc}() one.
++@end deftypefn
++@deftypefn {Method on @code{mglDataF}} @code{void} SetFunc (@code{mreal (*}f@code{)(mreal x,mreal y,mreal z,void *p)}, @code{void *}p=@code{NULL})
++Set pointer to function which will be used for data.
++@end deftypefn
++
++@heading Class @code{mglDataT}
++represent named reference to column of another data array.
++@deftypefn {Constructor on @code{mglDataT}} @code{} mglDataT (@code{const mglDataT &} d)
++Copy constructor.
++@end deftypefn
++@deftypefn {Constructor on @code{mglDataT}} @code{} mglDataT (@code{const mglDataA &} d, @code{long} col=@code{0})
++Create variable which reference @var{col}-th column of data @var{d}.
++@end deftypefn
++@deftypefn {Method on @code{mglDataT}} @code{void} SetInd (@code{long} col, @code{wchar_t} name)
++@deftypefnx {Method on @code{mglDataT}} @code{void} SetInd (@code{long} col, @code{const wchar_t *} name)
++Set reference to another column of the same data and its name.
++@end deftypefn
++
++@heading Class @code{mglDataR}
++represent named reference to row of another data array.
++@deftypefn {Constructor on @code{mglDataR}} @code{} mglDataR (@code{const mglDataR &} d)
++Copy constructor.
++@end deftypefn
++@deftypefn {Constructor on @code{mglDataR}} @code{} mglDataR (@code{const mglDataA &} d, @code{long} row=@code{0})
++Create variable which reference @var{row}-th row of data @var{d}.
++@end deftypefn
++@deftypefn {Method on @code{mglDataR}} @code{void} SetInd (@code{long} row, @code{wchar_t} name)
++@deftypefnx {Method on @code{mglDataR}} @code{void} SetInd (@code{long} row, @code{const wchar_t *} name)
++Set reference to another row of the same data and its name.
++@end deftypefn
++
++@heading Class @code{mglDataW}
++represent FFT frequency as data array.
++@deftypefn {Constructor on @code{mglDataW}} @code{} mglDataW (@code{const mglDataW &} d)
++Copy constructor.
++@end deftypefn
++@deftypefn {Constructor on @code{mglDataW}} @code{} mglDataW (@code{long} xx=@code{1}, @code{long} yy=@code{1}, @code{long} zz=@code{1}, @code{double} dp=@code{0}, @code{char} dir=@code{'x'})
++Set frequency sizes, direction @var{dir} and increment @var{dp}.
++@end deftypefn
++@deftypefn {Method on @code{mglDataR}} @code{void} Freq (@code{double} dp, @code{char} dir=@code{'x'})
++Equidistantly fill the data with step @var{dp} in direction @var{dir}.
++@end deftypefn
++
++
++@heading Class @code{mglDataS}
++incapsulate std::vector and present it as data array.
++@deftypecv {Variable} mglDataS @code{std::vector<mreal>} dat
++Data array itself.
++@end deftypecv
++@deftypefn {Constructor on @code{mglDataS}} @code{} mglDataS (@code{const mglDataS &} d)
++Copy constructor.
++@end deftypefn
++@deftypefn {Constructor on @code{mglDataS}} @code{} mglDataS (@code{const std::vector<mreal> &} d)
++Create copy data from @var{d}.
++@end deftypefn
++@deftypefn {Constructor on @code{mglDataS}} @code{} mglDataS (@code{size_t} s)
++Allocate memory for @var{s} .
++@end deftypefn
++@deftypefn {Method on @code{mglDataS}} @code{void} reserve (@code{size_t} num)
++Reserve space for @var{num} elements.
++@end deftypefn
++@deftypefn {Method on @code{mglDataS}} @code{void} push_back (@code{double} v)
++Appends value @var{v} to the end of data.
++@end deftypefn
++
++@end ifclear
++
++@external{}
--- /dev/null
--- /dev/null
++@c ------------------------------------------------------------------
++@chapter Обработка данных
++@nav{}
++
++@ifset UDAV
++В данной главе описываются команды для работы с массивами данных. Они включают команды для выделения памяти и изменения размера данных, чтения данных из файла, численного дифференцирования, интегрирования, интерполяции и пр., заполнения по текстовой формуле и т.д. Класс позволяет работать с данными размерности не более 3 (как функции от трёх переменных -- x,y,z). Массивы которые могут быть созданы командами MGL отображаются Small Caps шрифтом (например, @sc{dat}).
++@end ifset
++
++@ifclear UDAV
++В данной главе описываются классы @code{mglData} и @code{mglDataC} для работы с массивами действительных и комплексных данных, определённые в @code{#include <mgl2/data.h>} и @code{#include <mgl2/datac.h>} соответственно. Оба класса являются наследниками абстрактного класса @code{mglDataA}, и могут быть использованы в аргументах всех функций рисования (см. @ref{MathGL core}). Классы содержат функции для выделения памяти и изменения размера данных, чтения данных из файла, численного дифференцирования, интегрирования, интерполяции и пр., заполнения по текстовой формуле и т.д. Классы позволяют работать с данными размерности не более 3 (как функции от трёх переменных -- x,y,z). По умолчанию внутреннее представление данных использует тип mreal (и dual=std::complex<mreal> для @code{mglDataC}), который может быть сконфигурирован как float или double на этапе установки указав опцию @code{--enable-double} (см. @ref{Installation}). Тип float удобен в силу меньшего размера занимаемой памяти и, как правило, достаточной для построения графиков точности. Однако, тип double имеет большую точность, что может быть важно, например, для осей с метками времени. Массивы которые могут быть созданы командами MGL отображаются Small Caps шрифтом (например, @sc{dat}).
++@end ifclear
++
++@menu
++* Public variables::
++* Data constructor::
++* Data resizing::
++* Data filling::
++* File I/O::
++* Make another data::
++* Data changing::
++* Interpolation::
++* Data information::
++* Operators::
++* Global functions::
++* Evaluate expression::
++* Special data classes::
++@end menu
++
++@c ------------------------------------------------------------------
++@external{}
++@node Public variables, Data constructor, , Data processing
++@section Переменные
++@nav{}
++
++@ifset UDAV
++MGL не поддерживает прямой доступ к элементам массива. См. раздел @ref{Data filling}
++@end ifset
++
++@ifclear UDAV
++@deftypecv {Variable} mglData @code{mreal *} a
++@deftypecvx {Variable} mglDataC @code{dual *} a
++Указатель на массив данных. Это одномерный массив. Например, матрица [nx x ny x nz] представляется одномерным массивом длиной nx*ny*nz, где элемент с индексами @{i, j, k@} находится как a[i+nx*j+nx*ny*k] (индексы отсчитываются от нуля).
++@end deftypecv
++@deftypecv {Variable} mglData @code{int} nx
++@deftypecvx {Variable} mglDataC @code{long} nx
++Размер массива по 1-ой размерности ('x' размерности).
++@end deftypecv
++@deftypecv {Variable} mglData @code{int} ny
++@deftypecvx {Variable} mglDataC @code{long} ny
++Размер массива по 2-ой размерности ('y' размерности).
++@end deftypecv
++@deftypecv {Variable} mglData @code{int} nz
++@deftypecvx {Variable} mglDataC @code{long} nz
++Размер массива по 3-ей размерности ('z' размерности).
++@end deftypecv
++@deftypecv {Variable} mglData @code{std::string} id
++@deftypecvx {Variable} mglDataC @code{std::string} id
++Имена колонки (или среза при nz>1) -- один символ на колонку.
++@end deftypecv
++@deftypecv {Variable} mglData @code{bool} link
++@deftypecvx {Variable} mglDataC @code{bool} link
++Флаг использования указателя на внешние данные, включает запрет на удаление массива данных.
++@end deftypecv
++
++@deftypecv {Variable} mglDataA @code{std::wstring} s
++Имя массива данных, использующееся при разборе MGL скриптов.
++@end deftypecv
++@deftypecv {Variable} mglDataA @code{bool} temp
++Флаг временной переменной, которая может быть удалена в любой момент.
++@end deftypecv
++@deftypecv {Variable} mglDataA @code{void (*)(void *)} func
++Указатель на callback функцию, которая будет вызвана при удлалении данных.
++@end deftypecv
++@deftypecv {Variable} mglDataA @code{void *} o
++Указатель для callback функции.
++@end deftypecv
++
++@deftypefn {Метод класса @code{mglData}} @code{mreal} GetVal (@code{long} i)
++@deftypefnx {Метод класса @code{mglDataC}} @code{mreal} GetVal (@code{long} i)
++@deftypefnx {Метод класса @code{mglData}} @code{void} SetVal (@code{mreal} val, @code{long} i)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} SetVal (@code{mreal} val, @code{long} i)
++Присваивает или возвращает значение используя "непрерывную" индексацию без проверки выхода за границы массива. Индекс @var{i} должен быть в диапазоне [0, nx*ny*nz-1].
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglDataA}} @code{long} GetNx ()
++@deftypefnx {Метод класса @code{mglDataA}} @code{long} GetNy ()
++@deftypefnx {Метод класса @code{mglDataA}} @code{long} GetNz ()
++@deftypefnx {Функция С} @code{long} mgl_data_get_nx (@code{HCDT} dat)
++@deftypefnx {Функция С} @code{long} mgl_data_get_ny (@code{HCDT} dat)
++@deftypefnx {Функция С} @code{long} mgl_data_get_nz (@code{HCDT} dat)
++Возвращает размер данных в направлении x, y и z соответственно.
++@end deftypefn
++
++@deftypefn {Функция С} @code{mreal} mgl_data_get_value (@code{HCDT} dat, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {Функция С} @code{dual} mgl_datac_get_value (@code{HCDT} dat, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {Функция С} @code{mreal *} mgl_data_value (@code{HMDT} dat, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {Функция С} @code{dual *} mgl_datac_value (@code{HADT} dat, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {Функция С} @code{void} mgl_data_set_value (@code{HMDT} dat, @code{mreal} v, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {Функция С} @code{void} mgl_datac_set_value (@code{HADT} dat, @code{dual} v, @code{int} i, @code{int} j, @code{int} k)
++Присваивает или возвращает значение ячейки данных с проверкой выхода за пределы массива.
++@end deftypefn
++@deftypefn {Функция С} @code{const mreal *} mgl_data_data (@code{HCDT} dat)
++Возвращает указатель на внутренний массив данных.
++@end deftypefn
++
++@deftypefn {Функция С} @code{void} mgl_data_set_func (@code{mglDataA *}dat, @code{void (*}func@code{)(void *)}, @code{void *}par)
++Задает указатель на callback функцию, которая будет вызвана при удлалении данных.
++@end deftypefn
++
++@deftypefn {Функция С} @code{void} mgl_data_set_name (@code{mglDataA *}dat, @code{const char *}name)
++@deftypefnx {Функция С} @code{void} mgl_data_set_name_w (@code{mglDataA *}dat, @code{const wchar_t *}name)
++Задает имя массива данных, использующееся при разборе MGL скриптов.
++@end deftypefn
++
++@end ifclear
++
++@c ------------------------------------------------------------------
++@external{}
++@node Data constructor, Data resizing, Public variables, Data processing
++@section Создание и удаление данных
++@nav{}
++@cindex mglData
++
++@ifset UDAV
++There are many functions, which can create data for output (see @ref{Data filling}, @ref{File I/O}, @ref{Make another data}, @ref{Global functions}). Here I put most useful of them.
++@end ifset
++
++@anchor{new}
++@deftypefn {Команда MGL} {} new @sc{dat} [@code{nx=1} 'eq']
++@deftypefnx {Команда MGL} {} new @sc{dat} @code{nx ny} ['eq']
++@deftypefnx {Команда MGL} {} new @sc{dat} @code{nx ny nz} ['eq']
++@ifclear UDAV
++@deftypefnx {Конструктор класса @code{mglData}} {} mglData (@code{int} mx=@code{1}, @code{int} my=@code{1}, @code{int} mz=@code{1})
++@deftypefnx {Конструктор класса @code{mglDataC}} {} mglDataC (@code{int} mx=@code{1}, @code{int} my=@code{1}, @code{int} mz=@code{1})
++@deftypefnx {Функция С} @code{HMDT} mgl_create_data ()
++@deftypefnx {Функция С} @code{HMDT} mgl_create_data_size (@code{int} mx, @code{int} my, @code{int} mz)
++@end ifclear
++Выделяет память для массива данных и заполняет её нулями. Если указана формула @var{eq}, то данные заполняются также как при использовании @ref{fill}.
++@end deftypefn
++
++@anchor{copy}
++@deftypefn {Команда MGL} {} copy @sc{dat} dat2 ['eq'='']
++@deftypefnx {Команда MGL} {} copy @sc{dat} @code{val}
++@ifclear UDAV
++@deftypefnx {Конструктор класса @code{mglData}} {} mglData (@code{const mglData &}dat2)
++@deftypefnx {Конструктор класса @code{mglData}} {} mglData (@code{const mglDataA *}dat2)
++@deftypefnx {Конструктор класса @code{mglData}} {} mglData (@code{int} size, @code{const mreal *}dat2)
++@deftypefnx {Конструктор класса @code{mglData}} {} mglData (@code{int} size, @code{int} cols, @code{const mreal *}dat2)
++@deftypefnx {Конструктор класса @code{mglData}} {} mglData (@code{int} size, @code{const double *}dat2)
++@deftypefnx {Конструктор класса @code{mglData}} {} mglData (@code{int} size, @code{int} cols, @code{const double *}dat2)
++@deftypefnx {Конструктор класса @code{mglData}} {} mglData (@code{const double *}dat2, @code{int} size)
++@deftypefnx {Конструктор класса @code{mglData}} {} mglData (@code{const double *}dat2, @code{int} size, @code{int} cols)
++@deftypefnx {Конструктор класса @code{mglDataC}} {} mglDataC (@code{const mglDataA &}dat2)
++@deftypefnx {Конструктор класса @code{mglDataC}} {} mglDataC (@code{const mglDataA *}dat2)
++@deftypefnx {Конструктор класса @code{mglDataC}} {} mglDataC (@code{int} size, @code{const float *}dat2)
++@deftypefnx {Конструктор класса @code{mglDataC}} {} mglDataC (@code{int} size, @code{int} cols, @code{const float *}dat2)
++@deftypefnx {Конструктор класса @code{mglDataC}} {} mglDataC (@code{int} size, @code{const double *}dat2)
++@deftypefnx {Конструктор класса @code{mglDataC}} {} mglDataC (@code{int} size, @code{int} cols, @code{const double *}dat2)
++@deftypefnx {Конструктор класса @code{mglDataC}} {} mglDataC (@code{int} size, @code{const dual *}dat2)
++@deftypefnx {Конструктор класса @code{mglDataC}} {} mglDataC (@code{int} size, @code{int} cols, @code{const dual *}dat2)
++@end ifclear
++Копирует данные из другого экземпляра данных. Если указана формула @var{eq}, то данные заполняются также как при использовании @ref{fill}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} copy @sc{redat} @sc{imdat} dat2
++Копирует действительную и мнимую часть данных из комплексного массива данных @var{dat2}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} copy @sc{dat} 'name'
++Копирует данные из другого экземпляра данных с именем @var{name}. При этом имя @var{name} может быть некорректным с точки зрения MGL (например, взятым из HDF5 файла).
++@end deftypefn
++
++
++
++@deftypefn {Команда MGL} {} read @sc{dat} 'fname'
++@ifclear UDAV
++@deftypefnx {Конструктор класса @code{mglData}} {} mglData (@code{const char *}fname)
++@deftypefnx {Конструктор класса @code{mglDataC}} {} mglDataC (@code{const char *}fname)
++@deftypefnx {Функция С} @code{HMDT} mgl_create_data_file (@code{const char *}fname)
++@deftypefnx {Функция С} @code{HADT} mgl_create_datac_file (@code{const char *}fname)
++@end ifclear
++Читает данные из текстового файла с автоматическим определением размеров массива.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} delete dat
++@deftypefnx {Команда MGL} {} delete 'name'
++@ifclear UDAV
++@deftypefnx {Destructor on @code{mglData}} {} ~mglData ()
++@deftypefnx {Функция С} @code{void} mgl_delete_data (@code{HMDT} dat)
++@deftypefnx {Destructor on @code{mglDataC}} {} ~mglDataC ()
++@deftypefnx {Функция С} @code{void} mgl_delete_datac (@code{HADT} dat)
++@end ifclear
++Удаляет массив данных из памяти.
++@end deftypefn
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node Data resizing, Data filling, Data constructor, Data processing
++@section Изменение размеров данных
++@nav{}
++@cindex Create
++@cindex Rearrange
++@cindex Extend
++@cindex Transpose
++@cindex Squeeze
++@cindex Crop
++@cindex Insert
++@cindex Delete
++@cindex Sort
++@cindex Clean
++@cindex Join
++
++
++@deftypefn {Команда MGL} {} new @sc{dat} [@code{nx=1 ny=1 nz=1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Create (@code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Create (@code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_data_create (@code{HMDT} dat, @code{int} mx, @code{int} my, @code{int} mz)
++@deftypefnx {Функция С} @code{void} mgl_datac_create (@code{HADT} dat, @code{int} mx, @code{int} my, @code{int} mz)
++@end ifclear
++Создает/пересоздает массив данных указанного размера и заполняет его нулями. Ничего не делает при @var{mx}, @var{my}, @var{mz} отрицательных или равных нулю.
++@end deftypefn
++
++@anchor{rearrange}
++@deftypefn {Команда MGL} {} rearrange dat @code{mx [my=0 mz=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Rearrange (@code{int} mx, @code{int} my=@code{0}, @code{int} mz=@code{0})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Rearrange (@code{int} mx, @code{int} my=@code{0}, @code{int} mz=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_data_rearrange (@code{HMDT} dat, @code{int} mx, @code{int} my, @code{int} mz)
++@deftypefnx {Функция С} @code{void} mgl_datac_rearrange (@code{HADT} dat, @code{int} mx, @code{int} my, @code{int} mz)
++@end ifclear
++Изменяет размерность данных без изменения самого массива данных, так что результирующий массив @var{mx}*@var{my}*@var{mz} < nx*ny*nz. Если один из параметров @var{my} или @var{mz} ноль, то он будет выбран оптимальным образом. Например, если @var{my}=0, то будет @var{my}=nx*ny*nz/@var{mx} и @var{mz}=1.
++@end deftypefn
++
++@anchor{transpose}
++@deftypefn {Команда MGL} {} transpose dat ['dim'='yxz']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Transpose (@code{const char *}dim=@code{"yx"})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Transpose (@code{const char *}dim=@code{"yx"})
++@deftypefnx {Функция С} @code{void} mgl_data_transpose (@code{const char *}dim)
++@deftypefnx {Функция С} @code{void} mgl_datac_transpose (@code{HADT} dat, @code{const char *}dim)
++@end ifclear
++Транспонирует (меняет порядок размерностей) массив данных. Новый порядок размерностей задается строкой @var{dim}. Функция может быть полезна для транспонирования одномерных (или квазиодномерных) массивов после чтения их из файла.
++@end deftypefn
++
++@anchor{extend}
++@deftypefn {Команда MGL} {} extend dat @code{n1 [n2=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Extend (@code{int} n1, @code{int} n2=@code{0})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Extend (@code{int} n1, @code{int} n2=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_data_extend (@code{HMDT} dat, @code{int} n1, @code{int} n2)
++@deftypefnx {Функция С} @code{void} mgl_datac_extend (@code{HADT} dat, @code{int} n1, @code{int} n2)
++@end ifclear
++Увеличивает размер данных путем вставки (|@var{n1}|+1) новых срезов после (для @var{n1}>0) или перед (для @var{n1}<0) существующими данными. Можно добавить сразу 2 размерности для 1d массива, используя второй параметр @var{n2}. Данные в новые срезы будут скопированы из существующих. Например, для @var{n1}>0 новый массив будет
++@iftex
++@math{a_{ij}^{new} = a_i^{old}} where j=0...@var{n1}. Соответственно, для @var{n1}<0 новый массив будет @math{a_{ij}^{new} = a_j^{old}}, где i=0...|@var{n1}|.
++@end iftex
++@ifnottex
++a_ij^new = a_i^old where j=0...@var{n1}. Соответственно, для @var{n1}<0 новый массив будет a_ij^new = a_j^old, где i=0...|@var{n1}|.
++@end ifnottex
++@end deftypefn
++
++@anchor{squeeze}
++@deftypefn {Команда MGL} {} squeeze dat @code{rx [ry=1 rz=1 sm=off]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Squeeze (@code{int} rx, @code{int} ry=@code{1}, @code{int} rz=@code{1}, @code{bool} smooth=@code{false})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Squeeze (@code{int} rx, @code{int} ry=@code{1}, @code{int} rz=@code{1}, @code{bool} smooth=@code{false})
++@deftypefnx {Функция С} @code{void} mgl_data_squeeze (@code{HMDT} dat, @code{int} rx, @code{int} ry, @code{int} rz, @code{int} smooth)
++@deftypefnx {Функция С} @code{void} mgl_datac_squeeze (@code{HADT} dat, @code{int} rx, @code{int} ry, @code{int} rz, @code{int} smooth)
++@end ifclear
++Уменьшает размер данных путём удаления элементов с индексами не кратными @var{rx}, @var{ry}, @var{rz} соответственно. Параметр @var{smooth} задает использовать сглаживания
++@iftex
++(т.е. @math{a_{out}[i]=\sum_{j=i,i+r}a[j]/r}) или нет (т.е. @math{a_{out}[i]=a[j*r]}).
++@end iftex
++@ifnottex
++(т.е. out[i]=\sum_@{j=i,i+r@} a[j]/r) или нет (т.е. out[i]=a[j*r]).
++@end ifnottex
++@end deftypefn
++
++@anchor{crop}
++@deftypefn {Команда MGL} {} crop dat @code{n1 n2} 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Crop (@code{int} n1, @code{int} n2, @code{char} dir=@code{'x'})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Crop (@code{int} n1, @code{int} n2, @code{char} dir=@code{'x'})
++@deftypefnx {Функция С} @code{void} mgl_data_crop (@code{HMDT} dat, @code{int} n1, @code{int} n2, @code{char} dir)
++@deftypefnx {Функция С} @code{void} mgl_datac_crop (@code{HADT} dat, @code{int} n1, @code{int} n2, @code{char} dir)
++@end ifclear
++Обрезает границы данных при @var{i}<@var{n1} и @var{i}>@var{n2} (при @var{n2}>0) или @var{i}>@code{n[xyz]}-@var{n2} (при @var{n2}<=0) вдоль направления @var{dir}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} crop dat 'how'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Crop (@code{const char *}how=@code{"235x"})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Crop (@code{const char *}how=@code{"235x"})
++@deftypefnx {Функция Сn} @code{void} mgl_data_crop_opt (@code{HMDT} dat, @code{const char *}how)
++@deftypefnx {Функция Сn} @code{void} mgl_datac_crop_opt (@code{HADT} dat, @code{const char *}how)
++@end ifclear
++Обрезает дальний край данных, чтобы сделать их более оптимальным для быстрого преобразования Фурье. Размер массива будет равен наиболее близким к исходному из 2^n*3^m*5^l. Строка @var{how} может содержать: @samp{x}, @samp{y}, @samp{z} для направлений, и @samp{2}, @samp{3}, @samp{5} для использования соответствующего основания.
++@end deftypefn
++
++@anchor{insert}
++@deftypefn {Команда MGL} {} insert dat 'dir' @code{[pos=off num=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Insert (@code{char} dir, @code{int} pos=@code{0}, @code{int} num=@code{1})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Insert (@code{char} dir, @code{int} pos=@code{0}, @code{int} num=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_data_insert (@code{HMDT} dat, @code{char} dir, @code{int} pos, @code{char} num)
++@deftypefnx {Функция С} @code{void} mgl_datac_insert (@code{HADT} dat, @code{char} dir, @code{int} pos, @code{char} num)
++@end ifclear
++Вставляет @var{num} срезов вдоль направления @var{dir} с позиции @var{pos} и заполняет их нулями.
++@end deftypefn
++
++@anchor{delete}
++@deftypefn {Команда MGL} {} delete dat 'dir' @code{[pos=off num=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Delete (@code{char} dir, @code{int} pos=@code{0}, @code{int} num=@code{1})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Delete (@code{char} dir, @code{int} pos=@code{0}, @code{int} num=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_data_delete (@code{HMDT} dat, @code{char} dir, @code{int} pos, @code{char} num)
++@deftypefnx {Функция С} @code{void} mgl_datac_delete (@code{HADT} dat, @code{char} dir, @code{int} pos, @code{char} num)
++@end ifclear
++Удаляет @var{num} срезов вдоль направления @var{dir} с позиции @var{pos}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} delete dat
++@deftypefnx {Команда MGL} {} delete 'name'
++Удаляет массив данных из памяти.
++@end deftypefn
++
++@anchor{sort}
++@deftypefn {Команда MGL} {} sort dat @code{idx [idy=-1]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Sort (@code{lond} idx, @code{long} idy=@code{-1})
++@deftypefnx {Функция С} @code{void} mgl_data_sort (@code{HMDT} dat, @code{lond} idx, @code{long} idy)
++@end ifclear
++Сортирует строки (или срезы в 3D случае) по значениям в указанной колонке @var{idx} (или ячейках @{@var{idx},@var{idy}@} для 3D случая). Не используйте в многопоточных функциях!
++@end deftypefn
++
++@anchor{clean}
++@deftypefn {Команда MGL} {} clean dat @code{idx}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Clean (@code{lond} idx)
++@deftypefnx {Функция С} @code{void} mgl_data_clean (@code{HMDT} dat, @code{lond} idx)
++@end ifclear
++Удаляет строки в которых значения для заданной колонки @var{idx} совпадают со значениями в следующей строке.
++@end deftypefn
++
++
++@anchor{join}
++@deftypefn {Команда MGL} {} join dat vdat [v2dat ...]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Join (@code{const mglDataA &}vdat)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Join (@code{const mglDataA &}vdat)
++@deftypefnx {Функция С} @code{void} mgl_data_join (@code{HMDT} dat, @code{HCDT} vdat)
++@deftypefnx {Функция С} @code{void} mgl_datac_join (@code{HADT} dat, @code{HCDT} vdat)
++@end ifclear
++Объединяет данные из массива @var{vdat} с данными массива @var{dat}. При этом, функция увеличивает размер массива @var{dat}: в z-направлении для массивов с одинаковыми размерами по x и y; в y-направлении для массивов с одинаковыми размерами по x; в x-направлении в остальных случаях.
++@end deftypefn
++
++@c ------------------------------------------------------------------
++@external{}
++@node Data filling, File I/O, Data resizing, Data processing
++@section Заполнение данных
++@nav{}
++@cindex Fill
++@cindex Modify
++@cindex Set
++@cindex List
++@cindex Var
++@cindex Refill
++
++@anchor{list}
++@deftypefn {Команда MGL} {} list @sc{dat} @code{v1 ...}
++Создает новый массив данных @var{dat} и заполняет его числовыми значениями аргументов @code{v1 ...}. Команда может создавать одно- и двухмерные массивы с произвольными значениями. Для создания 2d массива следует использовать разделитель @samp{|}, который означает начало новой строки данных. Размер массива данных будет [maximal of row sizes * number of rows]. Например, команда @code{list 1 | 2 3} создаст массив [1 0; 2 3]. Замечу, что максимальное число аргументов равно 1000.
++@end deftypefn
++@deftypefn {Команда MGL} {} list @sc{dat} d1 ...
++Создает новый массив данных @var{dat} и заполняет его значениями из массивов @var{d1 ...}. Команда может создавать двух- и трёхмерные (если аргументы -- двумерные массивы) массивы. Меньшая размерность всех массивов в аргументах должна совпадать. В противном случае аргумент (массив) будет пропущен.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglData}} @code{void} Set (@code{const mreal *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {Метод класса @code{mglData}} @code{void} Set (@code{const double *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_data_set_mreal (@code{HMDT} dat, @code{const mreal *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++@deftypefnx {Функция С} @code{void} mgl_data_set_double (@code{HMDT} dat, @code{const double *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{const float *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{const double *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{const dual *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_datac_set_float (@code{HADT} dat, @code{const mreal *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++@deftypefnx {Функция С} @code{void} mgl_datac_set_double (@code{HADT} dat, @code{const double *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++@deftypefnx {Функция С} @code{void} mgl_datac_set_complex (@code{HADT} dat, @code{const dual *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++Выделяет память и копирует данные из массивов типа @code{mreal*} или @code{double*}, т.е. из массивов определённых как @code{mreal a[NX*NY*NZ];}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglData}} @code{void} Set (@code{const mreal **}A, @code{int} N1, @code{int} N2)
++@deftypefnx {Метод класса @code{mglData}} @code{void} Set (@code{const double **}A, @code{int} N1, @code{int} N2)
++@deftypefnx {Функция С} @code{void} mgl_data_set_mreal2 (@code{HMDT} dat, @code{const mreal **}A, @code{int} N1, @code{int} N2)
++@deftypefnx {Функция С} @code{void} mgl_data_set_double2 (@code{HMDT} dat, @code{const double **}A, @code{int} N1, @code{int} N2)
++Выделяет память и копирует данные из массивов типа @code{mreal**} или @code{double**} с размерностями @var{N1}, @var{N2}, т.е. из массивов определённых как @code{mreal a[N1][N2];}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglData}} @code{void} Set (@code{const mreal ***}A, @code{int} N1, @code{int} N2)
++@deftypefnx {Метод класса @code{mglData}} @code{void} Set (@code{const double ***}A, @code{int} N1, @code{int} N2)
++@deftypefnx {Функция С} @code{void} mgl_data_set_mreal3 (@code{HMDT} dat, @code{const mreal ***}A, @code{int} N1, @code{int} N2)
++@deftypefnx {Функция С} @code{void} mgl_data_set_double3 (@code{HMDT} dat, @code{const double ***}A, @code{int} N1, @code{int} N2)
++Выделяет память и копирует данные из массивов типа @code{mreal***} или @code{double***} с размерностями @var{N1}, @var{N2}, @var{N3}, т.е. из массивов определённых как @code{mreal a[N1][N2][N3];}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglData}} @code{void} Set (@code{gsl_vector *}v)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{gsl_vector *}v)
++@deftypefnx {Функция С} @code{void} mgl_data_set_vector (@code{HMDT} dat, @code{gsl_vector *}v)
++@deftypefnx {Функция С} @code{void} mgl_datac_set_vector (@code{HADT} dat, @code{gsl_vector *}v)
++Выделяет память и копирует данные из структуры типа @code{gsl_vector *}.
++@end deftypefn
++@deftypefn {Метод класса @code{mglData}} @code{void} Set (@code{gsl_matrix *}m)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{gsl_matrix *}m)
++@deftypefnx {Функция С} @code{void} mgl_data_set_matrix (@code{HMDT} dat, @code{gsl_matrix *}m)
++@deftypefnx {Функция С} @code{void} mgl_datac_set_matrix (@code{HADT} dat, @code{gsl_matrix *}m)
++Выделяет память и копирует данные из структуры типа @code{gsl_matrix *}.
++@end deftypefn
++@deftypefn {Метод класса @code{mglData}} @code{void} Set (@code{const mglDataA &}from)
++@deftypefnx {Метод класса @code{mglData}} @code{void} Set (@code{HCDT} from)
++@deftypefnx {Функция С} @code{void} mgl_data_set (@code{HMDT} dat, @code{HCDT} from)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{const mglDataA &}from)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{HCDT} from)
++@deftypefnx {Функция С} @code{void} mgl_datac_set (@code{HADT} dat, @code{HCDT} from)
++Выделяет память и копирует данные из другого экземпляра данных @var{from}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglDataC}} @code{void} Set (@code{const mglDataA &}re, @code{const mglDataA &}im)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{HCDT} re, @code{HCDT} im)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} SetAmpl (@code{HCDT} ampl, @code{const mglDataA &}phase)
++@deftypefnx {Функция С} @code{void} mgl_datac_set_ri (@code{HADT} dat, @code{HCDT} re, @code{HCDT} im)
++@deftypefnx {Функция С} @code{void} mgl_datac_set_ap (@code{HADT} dat, @code{HCDT} ampl, @code{HCDT} phase)
++Выделяет память и копирует данные из экземпляра данных для действительной @var{re} и мнимой @var{im} частей комплексного массива данных.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglData}} @code{void} Set (@code{const std::vector<int> &}d)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{const std::vector<int> &}d)
++@deftypefnx {Метод класса @code{mglData}} @code{void} Set (@code{const std::vector<float> &}d)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{const std::vector<float> &}d)
++@deftypefnx {Метод класса @code{mglData}} @code{void} Set (@code{const std::vector<double> &}d)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{const std::vector<double> &}d)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{const std::vector<dual> &}d)
++Выделяет память и копирует данные из массива типа @code{std::vector<T>}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglData}} @code{void} Set (@code{const char *}str, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_data_set_values (@code{const char *}str, @code{int} NX, @code{int} NY, @code{int} NZ)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Set (@code{const char *}str, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_datac_set_values (@code{const char *}str, @code{int} NX, @code{int} NY, @code{int} NZ)
++Выделяет память и сканирует массив данных из строки.
++@end deftypefn
++
++
++@deftypefn {Метод класса @code{mglData}} @code{void} SetList (@code{long} n, ...)
++Allocate memory and set data from variable argument list of @emph{double} values. Note, you need to specify decimal point @samp{.} for integer values! For example, the code @code{SetList(2,0.,1.);} is correct, but the code @code{SetList(2,0,1);} is incorrect.
++@end deftypefn
++
++
++@deftypefn {Метод класса @code{mglData}} @code{void} Link (@code{mglData &}from)
++@deftypefnx {Метод класса @code{mglData}} @code{void} Link (@code{mreal *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_data_link (@code{HMDT} dat, @code{const mreal *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Link (@code{mglDataC &}from)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Link (@code{dual *}A, @code{int} NX, @code{int} NY=@code{1}, @code{int} NZ=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_datac_link (@code{HADT} dat, @code{const mreal *}A, @code{int} NX, @code{int} NY, @code{int} NZ)
++Устанавливает флаг использования внешнего массива данных, которые не будут удалены. Флаг может быть возвращён в исходное состояние и создан новый внутренний массив если использовались функции изменяющие размер данных.
++@end deftypefn
++@end ifclear
++
++@anchor{var}
++@deftypefn {Команда MGL} {} var @sc{dat} @code{num v1 [v2=nan]}
++Создает новый одномерный массив данных @var{dat} размером @var{num}, и заполняет его равномерно в диапазоне [@var{v1}, @var{v2}]. Если @var{v2}=@code{nan}, то используется @var{v2=v1}.
++@end deftypefn
++
++@anchor{fill}
++@deftypefn {Команда MGL} {} fill dat v1 v2 ['dir'='x']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Fill (@code{mreal} v1, @code{mreal} v2, @code{char} dir=@code{'x'})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Fill (@code{dual} v1, @code{dual} v2, @code{char} dir=@code{'x'})
++@deftypefnx {Функция С} @code{void} mgl_data_fill (@code{HMDT} dat, @code{mreal} v1, @code{mreal} v2, @code{char} dir)
++@deftypefnx {Функция С} @code{void} mgl_datac_fill (@code{HADT} dat, @code{dual} v1, @code{dual} v2, @code{char} dir)
++@end ifclear
++Заполняет значениями равно распределёнными в диапазоне [@var{x1}, @var{x2}] в направлении @var{dir}=@{@samp{x},@samp{y},@samp{z}@}.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} fill dat 'eq'[vdat wdat]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglData}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const mglDataA &}vdat, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglData}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const mglDataA &}vdat, @code{const mglDataA &}wdat, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const mglDataA &}vdat, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Fill (@code{HMGL} gr, @code{const char *}eq, @code{const mglDataA &}vdat, @code{const mglDataA &}wdat, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_data_fill_eq (@code{HMGL} gr, @code{HMDT} dat, @code{const char *}eq, @code{HCDT} vdat, @code{HCDT} wdat, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_datac_fill_eq (@code{HMGL} gr, @code{HADT} dat, @code{const char *}eq, @code{HCDT} vdat, @code{HCDT} wdat, @code{const char *}opt)
++@end ifclear
++Заполняет значениями вычисленными по формуле @var{eq}. Формула представляет собой произвольное выражение, зависящее от переменных @samp{x}, @samp{y}, @samp{z}, @samp{u}, @samp{v}, @samp{w}. Координаты @samp{x}, @samp{y}, @samp{z} полагаются меняющимися в диапазоне @var{Min} x @var{Max} (в отличие от функции @code{Modify}). Переменная @samp{u} -- значения исходного массива, переменные @samp{v}, @samp{w} -- значения массивов @var{vdat}, @var{wdat}. Последние могут быть @code{NULL}, т.е. опущены.
++@end deftypefn
++
++@anchor{modify}
++@deftypefn {Команда MGL} {} modify dat 'eq' [@code{dim=0}]
++@deftypefnx {Команда MGL} {} modify dat 'eq' vdat [wdat]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Modify (@code{const char *}eq, @code{int} dim=@code{0})
++@deftypefnx {Метод класса @code{mglData}} @code{void} Modify (@code{const char *}eq, @code{const mglDataA &}v)
++@deftypefnx {Метод класса @code{mglData}} @code{void} Modify (@code{const char *}eq, @code{const mglDataA &}v, @code{const mglDataA &}w)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Modify (@code{const char *}eq, @code{int} dim=@code{0})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Modify (@code{const char *}eq, @code{const mglDataA &}v)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Modify (@code{const char *}eq, @code{const mglDataA &}v, @code{const mglDataA &}w)
++@deftypefnx {Функция С} @code{void} mgl_data_modify (@code{HMDT} dat, @code{const char *}eq, @code{int} dim)
++@deftypefnx {Функция С} @code{void} mgl_data_modify_vw (@code{HMDT} dat, @code{const char *}eq, @code{HCDT} v, @code{HCDT} w)
++@deftypefnx {Функция С} @code{void} mgl_datac_modify (@code{HADT} dat, @code{const char *}eq, @code{int} dim)
++@deftypefnx {Функция С} @code{void} mgl_datac_modify_vw (@code{HADT} dat, @code{const char *}eq, @code{HCDT} v, @code{HCDT} w)
++@end ifclear
++Аналогично предыдущему с координатами @samp{x}, @samp{y}, @samp{z}, меняющимися в диапазоне [0,1]. Если указан @var{dim}>0, то изменяются только слои >=@var{dim}.
++@end deftypefn
++
++@anchor{fillsample}
++@deftypefn {Команда MGL} {} fillsample dat 'how'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} FillSample (@code{const char *}how)
++@deftypefnx {Функция С} @code{void} mgl_data_fill_sample (@code{HMDT} a, @code{const char *}how)
++@end ifclear
++Заполняет массив данных 'x' или 'k' значениями для преобразований Ханкеля ('h') или Фурье ('f').
++@end deftypefn
++
++
++@anchor{datagrid}
++@deftypefn {Команда MGL} {} datagrid dat xdat ydat zdat
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Grid (@code{HMGL} gr, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Grid (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{mglPoint} p1, @code{mglPoint} p2)
++@deftypefnx {Функция С} @code{void} mgl_data_grid (@code{HMGL} gr, @code{HMDT} u, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{const char *}opt)
++@deftypefnx {Функция С} @code{void} mgl_data_grid_xy (@code{HMDT} u, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2)
++@end ifclear
++Заполняет значения массива результатом линейной интерполяции (считая координаты равнораспределенными в диапазоне осей координат или в диапазоне [x1,x2]*[y1,y2]) по триангулированной поверхности, найденной по произвольно расположенным точкам @samp{x}, @samp{y}, @samp{z}. NAN значение используется для точек сетки вне триангулированной поверхности. @sref{Making regular data}
++@end deftypefn
++
++
++@anchor{put}
++@deftypefn {Команда MGL} {} put dat @code{val [i=all j=all k=all]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Put (@code{mreal} val, @code{int} i=@code{-1}, @code{int} j=@code{-1}, @code{int} k=@code{-1})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Put (@code{dual} val, @code{int} i=@code{-1}, @code{int} j=@code{-1}, @code{int} k=@code{-1})
++@deftypefnx {Функция С} @code{void} mgl_data_put_val (@code{HMDT} a, @code{mreal} val, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {Функция С} @code{void} mgl_datac_put_val (@code{HADT} a, @code{dual} val, @code{int} i, @code{int} j, @code{int} k)
++@end ifclear
++Присваивает значения (под-)массива @var{dat}[@var{i}, @var{j}, @var{k}] = @var{val}. Индексы @var{i}, @var{j}, @var{k} равные @samp{-1} задают значения @var{val} для всего диапазона соответствующего направления(ий). Например, @code{Put(val,-1,0,-1);} задает a[i,0,j]=@var{val} для i=0...(nx-1), j=0...(nz-1).
++@end deftypefn
++
++@deftypefn {Команда MGL} {} put dat vdat [@code{i=all j=all k=all}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Put (@code{const mglDataA &}v, @code{int} i=@code{-1}, @code{int} j=@code{-1}, @code{int} k=@code{-1})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Put (@code{const mglDataA &}v, @code{int} i=@code{-1}, @code{int} j=@code{-1}, @code{int} k=@code{-1})
++@deftypefnx {Функция С} @code{void} mgl_data_put_dat (@code{HMDT} a, @code{HCDT} v, @code{int} i, @code{int} j, @code{int} k)
++@deftypefnx {Функция С} @code{void} mgl_datac_put_dat (@code{HADT} a, @code{HCDT} v, @code{int} i, @code{int} j, @code{int} k)
++@end ifclear
++Копирует значения из массива @var{v} в диапазон значений данного массива. Индексы @var{i}, @var{j}, @var{k} равные @samp{-1} задают диапазон изменения значений в соответствующих направление(ях). Младшие размерности массива @var{v} должны быть больше выбранного диапазона массива. Например, @code{Put(v,-1,0,-1);} присвоит a[i,0,j]=@var{v}.ny>nz ? @var{v}.a[i,j] : @var{v}.a[i], где i=0...(nx-1), j=0...(nz-1) и условие v.nx>=nx выполнено.
++@end deftypefn
++
++@anchor{refill}
++@deftypefn {Команда MGL} {} refill dat xdat vdat [sl=-1]
++@deftypefnx {Команда MGL} {} refill dat xdat ydat vdat [sl=-1]
++@deftypefnx {Команда MGL} {} refill dat xdat ydat zdat vdat
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Refill (@code{const mglDataA &}x, @code{const mglDataA &}v, @code{mreal} x1, @code{mreal} x2, @code{long} sl=@code{-1})
++@deftypefnx {Метод класса @code{mglData}} @code{void} Refill (@code{const mglDataA &}x, @code{const mglDataA &}v, @code{mglPoint} p1, @code{mglPoint} p2, @code{long} sl=@code{-1})
++@deftypefnx {Метод класса @code{mglData}} @code{void} Refill (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}v, @code{mglPoint} p1, @code{mglPoint} p2, @code{long} sl=@code{-1})
++@deftypefnx {Метод класса @code{mglData}} @code{void} Refill (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}v, @code{mglPoint} p1, @code{mglPoint} p2)
++@deftypefnx {Метод класса @code{mglData}} @code{void} Refill (@code{HMGL} gr, @code{const mglDataA &}x, @code{const mglDataA &}v, @code{long} sl=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglData}} @code{void} Refill (@code{HMGL} gr, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}v, @code{long} sl=@code{-1}, @code{const char *}opt=@code{""})
++@deftypefnx {Метод класса @code{mglData}} @code{void} Refill (@code{HMGL} gr, @code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z, @code{const mglDataA &}v, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{void} mgl_data_refill_x (@code{HMDT} a, @code{HCDT} x, @code{HCDT} v, @code{mreal} x1, @code{mreal} x2, @code{long} sl)
++@deftypefnx {Функция С} @code{void} mgl_data_refill_xy (@code{HMDT} a, @code{HCDT} x, @code{HCDT} y, @code{HCDT} v, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2, @code{long} sl)
++@deftypefnx {Функция С} @code{void} mgl_data_refill_xyz (@code{HMDT} a, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} v, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2, @code{mreal} z1, @code{mreal} z2)
++@deftypefnx {Функция С} @code{void} mgl_data_refill_gr (@code{HMGL} gr, @code{HMDT} a, @code{HCDT} x, @code{HCDT} y, @code{HCDT} z, @code{HCDT} v, @code{long} sl, @code{const char *}opt)
++@end ifclear
++Заполняет значениями интерполяции массива @var{v} в точках @{@var{x}, @var{y}, @var{z}@}=@{@code{X[i], Y[j], Z[k]}@} (или @{@var{x}, @var{y}, @var{z}@}=@{@code{X[i,j,k], Y[i,j,k], Z[i,j,k]}@} если @var{x}, @var{y}, @var{z} не 1d массивы), где @code{X,Y,Z} равномерно распределены в диапазоне [@var{x1},@var{x2}]*[@var{y1},@var{y2}]*[@var{z1},@var{z2}] и имеют такой же размер как и заполняемый массив. Если параметр @var{sl} равен 0 или положительный, то изменятся будет только @var{sl}-ый срез.
++@end deftypefn
++
++@anchor{gspline}
++@deftypefn {Команда MGL} {} gspline dat xdat vdat [sl=-1]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} RefillGS (@code{const mglDataA &}x, @code{const mglDataA &}v, @code{mreal} x1, @code{mreal} x2, @code{long} sl=@code{-1})
++@deftypefnx {Функция С} @code{void} mgl_data_refill_gs (@code{HMDT} a, @code{HCDT} x, @code{HCDT} v, @code{mreal} x1, @code{mreal} x2, @code{long} sl)
++@end ifclear
++Заполняет значениями глобального кубического сплайна для массива @var{v} в точках @var{x}=@code{X[i]}, где @code{X} равномерно распределен в диапазоне [@var{x1},@var{x2}] и имеет такой же размер как и заполняемый массив. Если параметр @var{sl} равен 0 или положительный, то изменятся будет только @var{sl}-ый срез.
++@end deftypefn
++
++@anchor{idset}
++@deftypefn {Команда MGL} {} idset dat 'ids'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} SetColumnId (@code{const char *}ids)
++@deftypefnx {Функция С} @code{void} mgl_data_set_id (@code{const char *}ids)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} SetColumnId (@code{const char *}ids)
++@deftypefnx {Функция С} @code{void} mgl_datac_set_id (@code{HADT} a, @code{const char *}ids)
++@end ifclear
++Задает названия @var{ids} для колонок массива данных. Строка должна содержать один символ 'a'...'z' на колонку. Эти названия используются в функции @ref{column}.
++@end deftypefn
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node File I/O, Make another data, Data filling, Data processing
++@section Чтение/сохранение данных
++@nav{}
++@cindex Read
++@cindex ReadMat
++@cindex ReadRange
++@cindex ReadAll
++@cindex Save
++@cindex ReadHDF
++@cindex SaveHDF
++@cindex Import
++@cindex Export
++
++@anchor{read}
++@deftypefn {Команда MGL} {} read @sc{dat} 'fname'
++@deftypefnx {Команда MGL} {} read @sc{redat} @sc{imdat} 'fname'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Read (@code{const char *}fname)
++@deftypefnx {Метод класса @code{mglDataC}} @code{bool} Read (@code{const char *}fname)
++@deftypefnx {Функция С} @code{int} mgl_data_read (@code{HMDT} dat, @code{const char *}fname)
++@deftypefnx {Функция С} @code{int} mgl_datac_read (@code{HADT} dat, @code{const char *}fname)
++@end ifclear
++Читает данные из текстового файла с разделителями символом пробела/табуляции с автоматическим определением размера массива. Двойной перевод строки начинает новый срез данных (по направлению z).
++@end deftypefn
++
++@deftypefn {Команда MGL} {} read @sc{dat} 'fname' @code{mx [my=1 mz=1]}
++@deftypefnx {Команда MGL} {} read @sc{redat} @sc{imdat} 'fname' @code{mx [my=1 mz=1]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Read (@code{const char *}fname, @code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1})
++@deftypefnx {Метод класса @code{mglDataC}} @code{bool} Read (@code{const char *}fname, @code{int} mx, @code{int} my=@code{1}, @code{int} mz=@code{1})
++@deftypefnx {Функция С} @code{int} mgl_data_read_dim (@code{HMDT} dat, @code{const char *}fname, @code{int} mx, @code{int} my, @code{int} mz)
++@deftypefnx {Функция С} @code{int} mgl_datac_read_dim (@code{HADT} dat, @code{const char *}fname, @code{int} mx, @code{int} my, @code{int} mz)
++@end ifclear
++Читает данные из текстового файла с заданными размерами. Ничего не делается если параметры @var{mx}, @var{my} или @var{mz} равны нулю или отрицательны.
++@end deftypefn
++
++@anchor{readmat}
++@deftypefn {Команда MGL} {} readmat @sc{dat} 'fname' [@code{dim=2}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} ReadMat (@code{const char *}fname, @code{int} dim=@code{2})
++@deftypefnx {Метод класса @code{mglDataC}} @code{bool} ReadMat (@code{const char *}fname, @code{int} dim=@code{2})
++@deftypefnx {Функция С} @code{int} mgl_data_read_mat (@code{HMDT} dat, @code{const char *}fname, @code{int} dim)
++@deftypefnx {Функция С} @code{int} mgl_datac_read_mat (@code{HADT} dat, @code{const char *}fname, @code{int} dim)
++@end ifclear
++Читает данные из текстового файла с размерами, указанными в первых @var{dim} числах файла. При этом переменная @var{dim} задает размерность (1d, 2d, 3d) данных.
++@end deftypefn
++
++@anchor{readall}
++@deftypefn {Команда MGL} {} readall @sc{dat} 'templ' @code{v1 v2 [dv=1 slice=off]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} ReadRange (@code{const char *}templ, @code{mreal} from, @code{mreal} to, @code{mreal} step=@code{1.f}, @code{bool} as_slice=@code{false})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} ReadRange (@code{const char *}templ, @code{mreal} from, @code{mreal} to, @code{mreal} step=@code{1}, @code{bool} as_slice=@code{false})
++@deftypefnx {Функция С} @code{int} mgl_data_read_range (@code{HMDT} dat, @code{const char *}templ, @code{mreal} from, @code{mreal} to, @code{mreal} step, @code{int} as_slice)
++@deftypefnx {Функция С} @code{int} mgl_datac_read_range (@code{HADT} dat, @code{const char *}templ, @code{mreal} from, @code{mreal} to, @code{mreal} step, @code{int} as_slice)
++@end ifclear
++Объединяет данные из нескольких текстовых файлов. Имена файлов определяются вызовом функции @code{sprintf(fname,templ,val);}, где @var{val} меняется от @var{from} до @var{to} с шагом @var{step}. Данные загружаются один за другим в один и тот же срез данных (при @var{as_slice}=@code{false}) или срез-за-срезом (при @var{as_slice}=@code{true}).
++@end deftypefn
++
++@deftypefn {Команда MGL} {} readall @sc{dat} 'templ' @code{[slice=off]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} ReadAll (@code{const char *}templ, @code{bool} as_slice=@code{false})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} ReadAll (@code{const char *}templ, @code{bool} as_slice=@code{false})
++@deftypefnx {Функция С} @code{int} mgl_data_read_all (@code{HMDT} dat, @code{const char *}templ, @code{int} as_slice)
++@deftypefnx {Функция С} @code{int} mgl_datac_read_all (@code{HADT} dat, @code{const char *}templ, @code{int} as_slice)
++@end ifclear
++Объединяет данные из нескольких текстовых файлов, чьи имена удовлетворяют шаблону @var{templ} (например, @var{templ}=@code{"t_*.dat"}). Данные загружаются один за другим в один и тот же срез данных (при @var{as_slice}=@code{false}) или срез-за-срезом (при @var{as_slice}=@code{true}).
++@end deftypefn
++
++@anchor{scanfile}
++@deftypefn {Команда MGL} {} scanfile @sc{dat} 'fname' 'templ'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{bool} ScanFile (@code{const char *}fname, @code{const char *}templ)
++@deftypefnx {Функция С} @code{int} mgl_data_scan_file (@code{HMDT} dat, @code{const char *}fname, @code{const char *}templ)
++@end ifclear
++Читает файл @var{fname} построчно и каждую строку сканирует на соответствие шаблону @var{templ}. Полученные числа (обозначаются как @samp{%g} в шаблоне) сохраняются. @sref{Saving and scanning file}
++@end deftypefn
++
++@anchor{save}
++@deftypefn {Команда MGL} {} save dat 'fname'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglDataA}} @code{void} Save (@code{const char *}fname, @code{int} ns=@code{-1}) @code{const}
++@deftypefnx {Функция С} @code{void} mgl_data_save (@code{HCDT} dat, @code{const char *}fname, @code{int} ns)
++@deftypefnx {Функция С} @code{void} mgl_datac_save (@code{HCDT} dat, @code{const char *}fname, @code{int} ns)
++@end ifclear
++Сохраняет весь массив данных при @var{ns}=@code{-1} или только @var{ns}-ый срез в текстовый файл.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} save 'str' 'fname' ['mode'='a']
++Сохраняет строку @var{str} в файл @var{fname}. Для параметра @var{mode}=@samp{a} происходит добавление строки (по умолчанию): для @var{mode}=@samp{w} файл будет перезаписан. @sref{Saving and scanning file}
++@end deftypefn
++
++@anchor{readhdf}
++@deftypefn {Команда MGL} {} readhdf @sc{dat} 'fname' 'dname'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} ReadHDF (@code{const char *}fname, @code{const char *}dname)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} ReadHDF (@code{const char *}fname, @code{const char *}dname)
++@deftypefnx {Функция С} @code{void} mgl_data_read_hdf (@code{HMDT} dat, @code{const char *}fname, @code{const char *}dname)
++@deftypefnx {Функция С} @code{void} mgl_datac_read_hdf (@code{HADT} dat, @code{const char *}fname, @code{const char *}dname)
++@end ifclear
++Читает массив с именем @var{dname} из HDF5 или HDF4 файла @var{fname}. Функция ничего не делает если библиотека была собрана без поддержки HDF5|HDF4.
++@end deftypefn
++
++@anchor{savehdf}
++@deftypefn {Команда MGL} {} savehdf dat 'fname' 'dname' [@code{rewrite}=@code{off}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglDataA}} @code{void} SaveHDF (@code{const char *}fname, @code{const char *}dname, @code{bool} rewrite=@code{false}) @code{const}
++@deftypefnx {Функция С} @code{void} mgl_data_save_hdf (@code{HCDT} dat, @code{const char *}fname, @code{const char *}dname, @code{int} rewrite)
++@deftypefnx {Функция С} @code{void} mgl_datac_save_hdf (@code{HCDT} dat, @code{const char *}fname, @code{const char *}dname, @code{int} rewrite)
++@end ifclear
++Сохраняет массив под именем @var{dname} в HDF5 или HDF4 файл @var{fname}. Функция ничего не делает если библиотека была собрана без поддержки HDF5|HDF4.
++@end deftypefn
++
++@anchor{datas}
++@deftypefn {Команда MGL} {} datas 'fname'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglDataA}} @code{int} DatasHDF (@code{const char *}fname, @code{char *}buf, @code{long} size) @code{static}
++@deftypefnx {Функция С} @code{void} mgl_datas_hdf (@code{const char *}fname, @code{char *}buf, @code{long} size)
++@end ifclear
++Помещает имена массивов данных в HDF5 файле @var{fname} в строку @var{buf} разделёнными символом табуляции '\t'. В версии MGL имена массивов будут выведены как сообщение. Функция ничего не делает если библиотека была собрана без поддержки HDF5.
++@end deftypefn
++
++@anchor{openhdf}
++@deftypefn {Команда MGL} {} openhdf 'fname'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglParse}} @code{void} OpenHDF (@code{const char *}fname)
++@deftypefnx {Функция С} @code{void} mgl_parser_openhdf (@code{HMPR} pr, @code{const char *}fname)
++@end ifclear
++Читает все массивы данных из HDF5 файла @var{fname} и создает переменные MGL с соответствующими именами. Если имя данных начинается с @samp{!}, то будут созданы комплексные массивы.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Функция С} @code{const char * const *} mgl_datas_hdf_str (@code{HMPR} pr, @code{const char *}fname)
++Помещает имена данных из HDF файла @var{fname} в массив строк (последняя строка ""). Массив строк будет изменен при следующем вызове функции.
++@end deftypefn
++@end ifclear
++
++@anchor{import}
++@deftypefn {Команда MGL} {} import @sc{dat} 'fname' 'sch' [@code{v1=0 v2=1}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Import (@code{const char *}fname, @code{const char *}scheme, @code{mreal} v1=@code{0}, mreal v2=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_data_import (@code{HMDT} dat, @code{const char *}fname, @code{const char *}scheme, @code{mreal} v1, mreal v2)
++@end ifclear
++Читает данные из растрового файла. RGB значения пикселов преобразуются в число в диапазоне [@var{v1}, @var{v2}] используя цветовую схему @var{sch} (@pxref{Color scheme}).
++@end deftypefn
++
++@anchor{export}
++@deftypefn {Команда MGL} {} export dat 'fname' 'sch' [@code{v1=0 v2=0}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglDataA}} @code{void} Export (@code{const char *}fname, @code{const char *}scheme, @code{mreal} v1=@code{0}, mreal v2=@code{0}, @code{int} ns=@code{-1}) const
++@deftypefnx {Функция С} @code{void} mgl_data_export (@code{HMDT} dat, @code{const char *}fname, @code{const char *}scheme, @code{mreal} v1, mreal v2, @code{int} ns) const
++@end ifclear
++Сохраняет данные в растровый файл. Числовые значения, нормированные в диапазон [@var{v1}, @var{v2}], преобразуются в RGB значения пикселов, используя цветовую схему @var{sch} (@pxref{Color scheme}). Если @var{v1}>=@var{v2}, то значения @var{v1}, @var{v2} определяются автоматически как минимальное и максимальное значение данных.
++@end deftypefn
++
++@c ------------------------------------------------------------------
++@external{}
++@node Make another data, Data changing, File I/O, Data processing
++@section Make another data
++@nav{}
++@cindex SubData
++@cindex Column
++@cindex Trace
++@cindex Hist
++@cindex Resize
++@cindex Evaluate
++@cindex Combine
++@cindex Momentum
++@cindex Sum
++@cindex Min
++@cindex Max
++@cindex Roots
++@cindex Correl
++@cindex AutoCorrel
++
++@anchor{subdata}
++@deftypefn {Команда MGL} {} subdata @sc{res} dat @code{xx [yy=all zz=all]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} SubData (@code{mreal} xx, @code{mreal} yy=@code{-1}, @code{mreal} zz=@code{-1}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} SubData (@code{mreal} xx, @code{mreal} yy=@code{-1}, @code{mreal} zz=@code{-1}) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_subdata (@code{HCDT} dat, @code{mreal} xx, @code{mreal} yy, @code{mreal} zz)
++@end ifclear
++Возвращает в @var{res} подмассив массива данных @var{dat} с фиксированными значениями индексов с положительными значениями. Например, @code{SubData(-1,2)} выделяет третью строку (индексы начинаются с нуля), @code{SubData(4,-1)} выделяет 5-ую колонку, @code{SubData(-1,-1,3)} выделяет 4-ый срез и т.д. В MGL скриптах обычно используется упрощенная версия @code{dat(xx,yy,zz)}. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} subdata @sc{res} dat xdat [ydat zdat]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} SubData (@code{const mglDataA &}xx, @code{const mglDataA &}yy, @code{const mglDataA &}zz) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} SubData (@code{const mglDataA &}xx, @code{const mglDataA &}yy, @code{const mglDataA &}zz) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_subdata_ext (@code{HCDT} dat, @code{HCDT} xx, @code{HCDT} yy, @code{HCDT} zz)
++@end ifclear
++Возвращает в @var{res} подмассив массива данных @var{dat} с индексами, заданными в массивах @var{xx}, @var{yy}, @var{zz} (косвенная адресация). Результат будет иметь размерность массивов с индексами. Размеры массивов @var{xx}, @var{yy}, @var{zz} с индексами должна быть одинакова, либо должны быть "скаляром" (т.е. 1*1*1). В MGL скриптах обычно используется упрощенная версия @code{dat(xx,yy,zz)}. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@anchor{column}
++@deftypefn {Команда MGL} {} column @sc{res} dat 'eq'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Column (@code{const char *}eq) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Column (@code{const char *}eq) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_column (@code{HCDT} dat, @code{const char *}eq)
++@end ifclear
++Возвращает массив данных заполненный по формуле @var{eq}, вычисленной для именованных колонок (или срезов). Например, @code{Column("n*w^2/exp(t)");}. Имена колонок должны быть предварительно заданы функцией @ref{idset} или при чтении файлов данных. В MGL скриптах обычно используется упрощенная версия @code{dat('eq')}. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@anchor{resize}
++@deftypefn {Команда MGL} {} resize @sc{res} dat @code{mx [my=1 mz=1]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Resize (@code{int} mx, @code{int} my=@code{0}, @code{int} mz=@code{0}, @code{mreal} x1=@code{0}, @code{mreal} x2=@code{1}, @code{mreal} y1=@code{0}, @code{mreal} y2=@code{1}, @code{mreal} z1=@code{0}, @code{mreal} z2=@code{1}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Resize (@code{int} mx, @code{int} my=@code{0}, @code{int} mz=@code{0}, @code{mreal} x1=@code{0}, @code{mreal} x2=@code{1}, @code{mreal} y1=@code{0}, @code{mreal} y2=@code{1}, @code{mreal} z1=@code{0}, @code{mreal} z2=@code{1}) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_resize (@code{HCDT} dat, @code{int} mx, @code{int} my, @code{int} mz)
++@deftypefnx {Функция С} @code{HMDT} mgl_data_resize_box (@code{HCDT} dat, @code{int} mx, @code{int} my, @code{int} mz, @code{mreal} x1, @code{mreal} x2, @code{mreal} y1, @code{mreal} y2, @code{mreal} z1, @code{mreal} z2)
++@end ifclear
++Возвращает массив данных размером @var{mx}, @var{my}, @var{mz} со значениями полученными интерполяцией значений из части [@var{x1},@var{x2}] x [@var{y1},@var{y2}] x [@var{z1},@var{z2}] исходного массива. Величины x,y,z полагаются нормированными в диапазоне [0,1]. Если значение @var{mx}, @var{my} или @var{mz} равно 0, то исходный размер используется. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@anchor{evaluate}
++@deftypefn {Команда MGL} {} evaluate @sc{res} dat idat [@code{norm=on}]
++@deftypefnx {Команда MGL} {} evaluate @sc{res} dat idat jdat [@code{norm=on}]
++@deftypefnx {Команда MGL} {} evaluate @sc{res} dat idat jdat kdat [@code{norm=on}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Evaluate (@code{const mglDataA &}idat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Evaluate (@code{const mglDataA &}idat, @code{const mglDataA &}jdat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Evaluate (@code{const mglDataA &}idat, @code{const mglDataA &}jdat, @code{const mglDataA &}kdat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Evaluate (@code{const mglDataA &}idat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Evaluate (@code{const mglDataA &}idat, @code{const mglDataA &}jdat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Evaluate (@code{const mglDataA &}idat, @code{const mglDataA &}jdat, @code{const mglDataA &}kdat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_evaluate (@code{HCDT} dat, @code{HCDT} idat, @code{HCDT} jdat, @code{HCDT} kdat, @code{int} norm)
++@end ifclear
++Возвращает массив данных, полученный в результате интерполяции исходного массива в точках других массивов (например, res[i,j]=dat[idat[i,j],jdat[i,j]]). Размеры массивов @var{idat}, @var{jdat}, @var{kdat} должны совпадать. Координаты в @var{idat}, @var{jdat}, @var{kdat} полагаются нормированными в диапазон [0,1] (при @var{norm}=@code{true}) или в диапазоны [0,nx], [0,ny], [0,nz] соответственно. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@anchor{section}
++@deftypefn {Команда MGL} {} section @sc{res} dat ids ['dir'='y' @code{val=nan}]
++@deftypefnx {Команда MGL} {} section @sc{res} dat @code{id} ['dir'='y' @code{val=nan}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Section (@code{const mglDataA &}ids, @code{const char *}dir=@code{'y'}, @code{mreal} val=@code{NAN}) @code{const}
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Section (@code{long} id, @code{const char *}dir=@code{'y'}, @code{mreal} val=@code{NAN}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Section (@code{const mglDataA &}ids, @code{const char *}dir=@code{'y'}, @code{mreal} val=@code{NAN}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Section (@code{long} id, @code{const char *}dir=@code{'y'}, @code{mreal} val=@code{NAN}) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_section (@code{HCDT} dat, @code{HCDT} ids, @code{const char *}dir, @code{mreal} val)
++@deftypefnx {Функция С} @code{HMDT} mgl_data_section_val (@code{HCDT} dat, @code{long} id, @code{const char *}dir, @code{mreal} val)
++@deftypefnx {Функция С} @code{HADT} mgl_datac_section (@code{HCDT} dat, @code{HCDT} ids, @code{const char *}dir, @code{mreal} val)
++@deftypefnx {Функция С} @code{HADT} mgl_datac_section_val (@code{HCDT} dat, @code{long} id, @code{const char *}dir, @code{mreal} val)
++@end ifclear
++Возвращает массив данных, являющийся @var{id}-ой секцией (диапазоном срезов, разделенных значениями @var{val}) исходного массива @var{dat}. Для @var{id}<0 используется обратный порядок (т.e. -1 даст последнюю секцию). Если указано несколько @var{ids}, то выходной массив будет результатом последовательного объединения секций.
++@end deftypefn
++
++@anchor{solve}
++@deftypefn {Команда MGL} {} solve @sc{res} dat @code{val} 'dir' [@code{norm=on}]
++@deftypefnx {Команда MGL} {} solve @sc{res} dat @code{val} 'dir' idat [@code{norm=on}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Solve (@code{mreal} val, @code{char} dir, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Solve (@code{mreal} val, @code{char} dir, @code{const mglDataA &}idat, @code{bool} norm=@code{true}) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_solve (@code{HCDT} dat, @code{mreal} val, @code{char} dir, @code{HCDT} idat, @code{int} norm)
++@end ifclear
++Возвращает массив индексов (корней) вдоль выбранного направления @var{dir} в которых значения массива @var{dat} равны @var{val}. Выходной массив будет иметь размеры массива @var{dat} в направлениях поперечных @var{dir}. Если предоставлен массив @var{idat}, то его значения используются как стартовые при поиске. Это позволяет найти несколько веток с помощью последовательного вызова функции. Индексы полагаются нормированными в диапазон [0,1] (при @var{norm}=@code{true}) или в диапазоны [0,nx], [0,ny], [0,nz] соответственно. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов. @sref{Solve sample}
++@end deftypefn
++
++@anchor{roots}
++@deftypefn {Команда MGL} {} roots @sc{res} 'func' ini ['var'='x']
++@deftypefnx {Команда MGL} {} roots @sc{res} 'func' @code{ini} ['var'='x']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Roots (@code{const char *}func, @code{char} var) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_roots (@code{const char *}func, @code{HCDT} ini, @code{char} var)
++@deftypefnx {Функция С} @code{mreal} mgl_find_root_txt (@code{const char *}func, @code{mreal} ini, @code{char} var)
++@end ifclear
++Возвращает массив корней уравнения 'func'=0 для переменной @var{var} с начальными положениями @var{ini}. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@anchor{detect}
++@deftypefn {Команда MGL} {} detect @sc{res} dat @code{lvl dj [di=0 minlen=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Detect (@code{mreal} lvl, @code{mreal} dj, @code{mreal} di=@code{0}, @code{mreal} minlen=@code{0}) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_detect (@code{HCDT} dat, @code{mreal} lvl, @code{mreal} dj, @code{mreal} di, @code{mreal} minlen)
++@end ifclear
++Возвращает массив кривых @{x,y@}, разделенных NAN значениями, для локальных максимумов массива @var{dat} как функцию координаты x. Шумы амплитудой меньше @var{lvl} игнорируются. Параметр @var{dj} (в диапазоне [0,ny]) задает область "притяжения" точек в y-направлении к кривой. Аналогично, @var{di} продолжает кривые в x-направлении через разрывы длиной менее @var{di} точек. Кривые с минимальной длинной менее @var{minlen} игнорируются.
++@end deftypefn
++
++@anchor{hist}
++@deftypefn {Команда MGL} {} hist @sc{res} dat @code{num v1 v2 [nsub=0]}
++@deftypefnx {Команда MGL} {} hist @sc{res} dat wdat @code{num v1 v2 [nsub=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Hist (@code{int} n, @code{mreal} v1=@code{0}, @code{mreal} v2=@code{1}, @code{int} nsub=@code{0}) @code{const}
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Hist (@code{const mglDataA &}w, @code{int} n, @code{mreal} v1=@code{0}, @code{mreal} v2=@code{1}, @code{int} nsub=@code{0}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Hist (@code{int} n, @code{mreal} v1=@code{0}, @code{mreal} v2=@code{1}, @code{int} nsub=@code{0}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Hist (@code{const mglDataA &}w, @code{int} n, @code{mreal} v1=@code{0}, @code{mreal} v2=@code{1}, @code{int} nsub=@code{0}) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_hist (@code{HCDT} dat, @code{int} n, @code{mreal} v1, @code{mreal} v2, @code{int} nsub)
++@deftypefnx {Функция С} @code{HMDT} mgl_data_hist_w (@code{HCDT} dat, @code{HCDT} w, @code{int} n, @code{mreal} v1, @code{mreal} v2, @code{int} nsub)
++@end ifclear
++Возвращает распределение (гистограмму) из @var{n} точек от значений массива в диапазоне [@var{v1}, @var{v2}]. Массив @var{w} задает веса элементов (по умолчанию все веса равны 1). Параметр @var{nsub} задает число дополнительных точек интерполяции (для сглаживания получившейся гистограммы). Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов. См. также @ref{Data manipulation}
++@end deftypefn
++
++@anchor{momentum}
++@deftypefn {Команда MGL} {} momentum @sc{res} dat 'how' ['dir'='z']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Momentum (@code{char} dir, @code{const char *}how) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Momentum (@code{char} dir, @code{const char *}how) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_momentum (@code{HCDT} dat, @code{char} dir, @code{const char *}how)
++@end ifclear
++Возвращает момент (1d массив) данных вдоль направления @var{dir}. Строка @var{how} определяет тип момента. Момент определяется как
++@iftex
++@math{res_k = \sum_{ij} how(x_i,y_j,z_k) a_{ij}/\sum_{ij} a_{ij}}
++@end iftex
++@ifnottex
++res_k = \sum_ij how(x_i,y_j,z_k) a_ij/ \sum_ij a_ij
++@end ifnottex
++если @var{dir}=@samp{z} и т.д. Координаты @samp{x}, @samp{y}, @samp{z} -- индексы массива в диапазоне [0,1]. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@anchor{sum}
++@deftypefn {Команда MGL} {} sum @sc{res} dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Sum (@code{const char *}dir) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Sum (@code{const char *}dir) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_sum (@code{HCDT} dat, @code{const char *}dir)
++@end ifclear
++Возвращает результат суммирования данных вдоль направления(ий) @var{dir}. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@anchor{max}
++@deftypefn {Команда MGL} {} max @sc{res} dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Max (@code{const char *}dir) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Max (@code{const char *}dir) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_max_dir (@code{HCDT} dat, @code{const char *}dir)
++@end ifclear
++Возвращает максимальное значение данных вдоль направления(ий) @var{dir}. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@anchor{min}
++@deftypefn {Команда MGL} {} min @sc{res} dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Min (@code{const char *}dir) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Min (@code{const char *}dir) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_min_dir (@code{HCDT} dat, @code{const char *}dir)
++@end ifclear
++Возвращает минимальное значение данных вдоль направления(ий) @var{dir}. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@anchor{combine}
++@deftypefn {Команда MGL} {} combine @sc{res} adat bdat
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Combine (@code{const mglDataA &}a) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Combine (@code{const mglDataA &}a) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_combine (@code{HCDT} dat, @code{HCDT} a)
++@end ifclear
++Возвращает прямое произведение массивов (наподобие, res[i,j] = adat[i]*bdat[j] и т.д.). Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@anchor{trace}
++@deftypefn {Команда MGL} {} trace @sc{res} dat
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Trace () @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglData} Trace () @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_trace (@code{HCDT} dat)
++@end ifclear
++Возвращает массив диагональных элементов a[i,i] (для 2D данных) или a[i,i,i] (для 3D данных) где i=0...nx-1. В 1D случае возвращается сам массив данных. Размеры массива данных должен быть ny,nz >= nx или ny,nz = 1. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@anchor{correl}
++@deftypefn {Команда MGL} {} correl @sc{res} adat bdat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Correl (@code{const mglDataA &}b, @code{const char *}dir) @code{const}
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} AutoCorrel (@code{const char *}dir) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglDataC} Correl (@code{const mglDataA &}b, @code{const char *}dir) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{mglDataC} AutoCorrel (@code{const char *}dir) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_correl (@code{HCDT} a, @code{HCDT} b, @code{const char *}dir)
++@deftypefnx {Функция С} @code{HADT} mgl_datac_correl (@code{HCDT} a, @code{HCDT} b, @code{const char *}dir)
++@end ifclear
++Возвращает корреляцию массивов @var{a} (или this в C++) и @var{b} вдоль направлений @var{dir}. При вычислении используется преобразование Фурье. Поэтому может потребоваться вызов функций @ref{swap} и/или @ref{norm} перед построением. Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglDataC}} @code{mglData} Real () @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_datac_real (@code{HCDT} dat)
++Возвращает массив действительных частей массива данных.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataC}} @code{mglData} Imag () @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_datac_imag (@code{HCDT} dat)
++Возвращает массив мнимых частей массива данных.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataC}} @code{mglData} Abs () @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_datac_abs (@code{HCDT} dat)
++Возвращает массив абсолютных значений массива данных.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataC}} @code{mglData} Arg () @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_datac_arg (@code{HCDT} dat)
++Возвращает массив аргументов массива данных.
++@end deftypefn
++@end ifclear
++
++@anchor{pulse}
++@deftypefn {Команда MGL} {} pulse @sc{res} dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{mglData} Pulse (@code{const char *}dir) @code{const}
++@deftypefnx {Функция С} @code{HMDT} mgl_data_pulse (@code{HCDT} dat, @code{const char *}dir)
++@end ifclear
++Находит параметры импульса вдоль направления @var{dir}: максимальное значение (в колонке 0), его положение (в колонке 1), ширина по параболлической аппроксимации (в колонке 3) и по полувысоте (в колонке 2), энергию около максимума (в колонке 4). NAN значения используются для ширин если максимум расположен вблизи границ массива. Отмечу, что для комплексных массивов есть неопределенность определения параметров. Обычно следует использовать квадрат абсолютного значения амплитуды (т.е. |dat[i]|^2). Поэтому MathGL не включает эту функцию в @code{mglDataC}, хотя формально C функция будет работать и для них, но будет использовать абсолютное значение амплитуды (т.е. |dat[i]|). Функция возвращает NULL или пустой массив если данные не могут быть созданы при данных значениях аргументов. См. также @ref{max}, @ref{min}, @ref{momentum}, @ref{sum}. @sref{Pulse properties}
++@end deftypefn
++
++@c ------------------------------------------------------------------
++@external{}
++@node Data changing, Interpolation, Make another data, Data processing
++@section Изменение данных
++@nav{}
++@cindex CumSum
++@cindex Integral
++@cindex Diff
++@cindex Diff2
++@cindex SinFFT
++@cindex CosFFT
++@cindex Hankel
++@cindex Swap
++@cindex Roll
++@cindex Mirror
++@cindex Sew
++@cindex Smooth
++@cindex Envelop
++@cindex Norm
++@cindex NormSl
++
++These functions change the data in some direction like differentiations, integrations and so on. The direction in which the change will applied is specified by the string parameter, which may contain @samp{x}, @samp{y} or @samp{z} characters for 1-st, 2-nd and 3-d dimension correspondingly.
++
++@anchor{cumsum}
++@deftypefn {Команда MGL} {} cumsum dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} CumSum (@code{const char *}dir)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} CumSum (@code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_data_cumsum (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_datac_cumsum (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Суммирует с накоплением в выбранном направлении(ях).
++@end deftypefn
++
++@anchor{integrate}
++@deftypefn {Команда MGL} {} integrate dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Integral (@code{const char *}dir)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Integral (@code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_data_integral (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_datac_integral (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Выполняет интегрирование (методом трапеций) в выбранном направлении(ях).
++@end deftypefn
++
++@anchor{diff}
++@deftypefn {Команда MGL} {} diff dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Diff (@code{const char *}dir)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Diff (@code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_data_diff (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_datac_diff (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Выполняет дифференцирование в выбранном направлении(ях).
++@end deftypefn
++
++@deftypefn {Команда MGL} {} diff dat xdat ydat [zdat]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Diff (@code{const mglDataA &}x)
++@deftypefnx {Метод класса @code{mglData}} @code{void} Diff (@code{const mglDataA &}x, @code{const mglDataA &}y)
++@deftypefnx {Метод класса @code{mglData}} @code{void} Diff (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Diff (@code{const mglDataA &}x)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Diff (@code{const mglDataA &}x, @code{const mglDataA &}y)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Diff (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z)
++@deftypefnx {Функция С} @code{void} mgl_data_diff_par (@code{HMDT} dat, @code{HCDT} x, @code{HCDT}y, @code{HCDT}z)
++@deftypefnx {Функция С} @code{void} mgl_datac_diff_par (@code{HADT} dat, @code{HCDT} x, @code{HCDT}y, @code{HCDT}z)
++@end ifclear
++Выполняет дифференцирование данных, параметрически зависящих от координат, в направлении @var{x} с @var{y}, @var{z}=constant. Параметр @var{z} может быть опущен, что соответствует 2D случаю. Используются следующие формулы (2D случай): @math{da/dx = (a_j*y_i-a_i*y_j)/(x_j*y_i-x_i*y_j)}, где @math{a_i=da/di, a_j=da/dj} обозначает дифференцирование вдоль 1-ой и 2-ой размерности. Похожие формулы используются и в 3D случае. Порядок аргументов можно менять -- например, если данные a(i,j) зависят от координат @{x(i,j), y(i,j)@}, то обычная производная по @samp{x} будет равна @code{Diff(x,y);}, а обычная производная по @samp{y} будет равна @code{Diff(y,x);}.
++@end deftypefn
++
++@anchor{diff2}
++@deftypefn {Команда MGL} {} diff2 dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Diff2 (@code{const char *}dir)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Diff2 (@code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_data_diff2 (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_datac_diff2 (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Выполняет двойное дифференцирование (как в операторе Лапласа) в выбранном направлении(ях).
++@end deftypefn
++
++@anchor{sinfft}
++@deftypefn {Команда MGL} {} sinfft dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} SinFFT (@code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_data_sinfft (@code{HMDT} dat, @code{const char *}dir)
++@end ifclear
++Выполняет синус преобразование в выбранном направлении(ях). Синус преобразование есть @math{\sum a_j \sin(k j)} (см. @uref{http://en.wikipedia.org/wiki/Discrete_sine_transform#DST-I}).
++@end deftypefn
++
++@anchor{cosfft}
++@deftypefn {Команда MGL} {} cosfft dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} CosFFT (@code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_data_cosfft (@code{HMDT} dat, @code{const char *}dir)
++@end ifclear
++Выполняет косинус преобразование в выбранном направлении(ях). Синус преобразование есть @math{\sum a_j \cos(k j)} (см. @uref{http://en.wikipedia.org/wiki/Discrete_cosine_transform#DCT-I}).
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglDataC}} @code{void} FFT (@code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_datac_fft (@code{HADT} dat, @code{const char *}dir)
++Выполняет фурье преобразование в выбранном направлении(ях). Если строка @var{dir} содержит @samp{i}, то используется обратное преобразование фурье. Фурье преобразование есть @math{\sum a_j \exp(i k j)} (см. @uref{http://en.wikipedia.org/wiki/Discrete_Fourier_transform}).
++@end deftypefn
++@end ifclear
++
++@anchor{hankel}
++@deftypefn {Команда MGL} {} hankel dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Hankel (@code{const char *}dir)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Hankel (@code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_data_hankel (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_datac_hankel (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Выполняет преобразование Ханкеля в выбранном направлении(ях). Преобразование Ханкеля есть @math{\sum a_j J_0(k j)} (см. @uref{http://en.wikipedia.org/wiki/Hankel_transform}).
++@end deftypefn
++
++@anchor{wavelet}
++@deftypefn {Команда MGL} {} wavelet dat 'dir' @code{k}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Wavelet (@code{const char *}dir, @code{int} k)
++@deftypefnx {Функция С} @code{void} mgl_data_wavelet (@code{HMDT} dat, @code{const char *}dir, @code{int} k)
++@end ifclear
++Выполняет преобразование wavelet в выбранном направлении(ях). Параметр @var{dir} задает тип:
++@samp{d} для daubechies, @samp{D} для центрированного daubechies, @samp{h} для haar, @samp{H} для центрированного haar, @samp{b} для bspline, @samp{B} для центрированного bspline. Если указан символ @samp{i}, то выполняется обратное преобразование. Параметр @var{k} задает размер преобразования.
++@end deftypefn
++
++@anchor{swap}
++@deftypefn {Команда MGL} {} swap dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Swap (@code{const char *}dir)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Swap (@code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_data_swap (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_datac_swap (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Меняет местами левую и правую части данных в выбранном направлении(ях). Полезно для отображения результата FFT.
++@end deftypefn
++
++@anchor{roll}
++@deftypefn {Команда MGL} {} roll dat 'dir' num
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Roll (@code{char} dir, @code{num})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Roll (@code{char} dir, @code{num})
++@deftypefnx {Функция С} @code{void} mgl_data_roll (@code{HMDT} dat, @code{char} dir, @code{num})
++@deftypefnx {Функция С} @code{void} mgl_datac_roll (@code{HADT} dat, @code{char} dir, @code{num})
++@end ifclear
++Сдвигает данные на @var{num} ячеек в выбранном направлении(ях). Соответствует замене индекса на @var{i}->(i+@var{num})%nx при @code{dir='x'}.
++@end deftypefn
++
++@anchor{mirror}
++@deftypefn {Команда MGL} {} mirror dat 'dir'
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Mirror (@code{const char *}dir)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Mirror (@code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_data_mirror (@code{HMDT} dat, @code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_datac_mirror (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Отражает данные в выбранном направлении(ях). Соответствует замене индекса на @var{i}->@var{n}-@var{i}. Отмечу, что похожего эффекта на графике можно достичь используя опции (@pxref{Command options}), например, @code{surf dat; xrange 1 -1}.
++@end deftypefn
++
++@anchor{sew}
++@deftypefn {Команда MGL} {} sew dat ['dir'='xyz' @code{da=2*pi}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Sew (@code{const char *}dir, @code{mreal} da=@code{2*M_PI})
++@deftypefnx {Функция С} @code{void} mgl_data_sew (@code{HMDT} dat, @code{const char *}dir, @code{mreal} da)
++@end ifclear
++Удаляет скачки данных (например, скачки фазы после обратных тригонометрических функций) с периодом @var{da} в выбранном направлении(ях).
++@end deftypefn
++
++@anchor{smooth}
++@deftypefn {Команда MGL} {} smooth data ['dir'='xyz']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Smooth (@code{const char *}dir=@code{"xyz"}, @code{mreal} delta=@code{0})
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Smooth (@code{const char *}dir=@code{"xyz"}, @code{mreal} delta=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_data_smooth (@code{HMDT} dat, @code{const char *}dir, @code{mreal} delta)
++@deftypefnx {Функция С} @code{void} mgl_datac_smooth (@code{HADT} dat, @code{const char *}dir, @code{mreal} delta)
++@end ifclear
++Сглаживает данные в выбранном направлении(ях) @var{dir}. Строка @var{dirs} задает направления вдоль которых будет производиться сглаживание. Строка @var{dir} может содержать:
++@itemize @bullet
++@item
++@samp{xyz} -- сглаживание по x-,y-,z-направлениям,
++@item
++@samp{0} -- ничего не делает,
++@item
++@samp{3} -- линейное усреднение по 3 точкам,
++@item
++@samp{5} -- линейное усреднение по 5 точкам,
++@item
++@samp{d1}...@samp{d9} -- линейное усреднение по (2*N+1) точкам.
++@end itemize
++По умолчанию используется квадратичное усреднение по 5 точкам.
++@end deftypefn
++
++@anchor{envelop}
++@deftypefn {Команда MGL} {} envelop dat ['dir'='x']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Envelop (@code{char} dir=@code{'x'})
++@deftypefnx {Функция С} @code{void} mgl_data_envelop (@code{HMDT} dat, @code{char} dir)
++@end ifclear
++Находит огибающую данных в выбранном направлении @var{dir}.
++@end deftypefn
++
++@anchor{diffract}
++@deftypefn {Команда MGL} {} diffract dat 'how' @code{q}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Diffraction (@code{const char *}how, @code{mreal} q)
++@deftypefnx {Функция С} @code{void} mgl_datac_diffr (@code{HADT} dat, @code{const char *}how, @code{mreal} q)
++@end ifclear
++Вычисляет один шаг диффракции в конечно-разностной схеме с параметром @var{q}=@math{\delta t/\delta x^2} используя метод третьего порядка точности. Параметр @var{how} может содержать:
++@itemize @bullet
++ @item @samp{xyz} для расчета вдоль x-,y-,z-направления;
++@item
++ @samp{r} для аксиально симметричного лапласиана по направлению x;
++@item
++ @samp{0} для нулевых граничных условий;
++@item
++ @samp{1} для постоянных граничных условий;
++@item
++ @samp{2} для линейных граничных условий;
++@item
++ @samp{3} для параболлических граничных условий;
++@item
++ @samp{4} для экспоненциальных граничных условий;
++@item
++ @samp{5} для гауссовых граничных условий.
++@end itemize
++@end deftypefn
++
++@anchor{norm}
++@deftypefn {Команда MGL} {} norm dat @code{v1 v2 [sym=off dim=0]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Norm (@code{mreal} v1=@code{0}, @code{mreal} v2=@code{1}, @code{bool} sym=@code{false}, @code{long} dim=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_data_norm (@code{HMDT} dat, @code{mreal} v1, @code{mreal} v2, @code{int} sym, @code{long} dim)
++@end ifclear
++Нормирует данные в интервал [@var{v1},@var{v2}]. Если @var{sym}=@code{true}, то используется симметричный интервал [-max(|v1|,|v2|), max(|v1|,|v2|)]. Изменения применяются только к срезам >=@var{dim}.
++@end deftypefn
++
++@anchor{normsl}
++@deftypefn {Команда MGL} {} normsl dat @code{v1 v2} ['dir'='z' @code{keep=on sym=off}]
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} NormSl (@code{mreal} v1=@code{0}, @code{mreal} v2=@code{1}, @code{char} dir=@code{'z'}, @code{bool} keep=@code{true}, @code{bool} sym=@code{false})
++@deftypefnx {Функция С} @code{void} mgl_data_norm_slice (@code{HMDT} dat, @code{mreal} v1, @code{mreal} v2, @code{char} dir, @code{int} keep, @code{int} sym)
++@end ifclear
++Нормирует данные срез-за-срезом в выбранном направлении @var{dir} в интервал [@var{v1},@var{v2}]. Если @var{sym}=@code{true}, то используется симметричный интервал [-max(|v1|,|v2|), max(|v1|,|v2|)]. Если @var{keep}=@code{true}, то максимальное значение k-го среза ограничено величиной
++@iftex
++@math{\sqrt{\sum a_{ij}(k)/\sum a_{ij}(0)}}.
++@end iftex
++@ifnottex
++@math{\sqrt@{\sum a_ij(k)/\sum a_ij(0)@}}.
++@end ifnottex
++@end deftypefn
++
++@anchor{limit}
++@deftypefn {Команда MGL} {} limit dat @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Limit (@code{mreal} val)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} Limit (@code{mreal} val)
++@deftypefnx {Функция С} @code{void} mgl_data_limit (@code{HMDT} dat, @code{mreal} val)
++@deftypefnx {Функция С} @code{void} mgl_datac_limit (@code{HADT} dat, @code{mreal} val)
++@end ifclear
++Ограничивает амплитуду данных диапазоном [-@var{val},@var{val}]. При этом сохраняется исходный знак (фаза для комплексных чисел). Эквивалентно операции @code{a[i] *= abs(a[i])<val?1.:val/abs(a[i]);}.
++@end deftypefn
++
++<<<<<<< HEAD
++=======
++@anchor{dilate}
++@deftypefn {Команда MGL} {} dilate dat @code{[val=1 step=1]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Dilate (@code{mreal} val=@code{1}, @code{long} step=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_data_dilate (@code{HMDT} dat, @code{mreal} val, @code{long} step)
++@end ifclear
++Возвращает "расширенный" на @var{step} ячеек массив из 0 и 1 для данных больших порогового значения @var{val}. @c TODO @sref{Dilate and erode sample}
++@end deftypefn
++
++@anchor{erode}
++@deftypefn {Команда MGL} {} erode dat @code{[val=1 step=1]}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} Erode (@code{mreal} val=@code{1}, @code{long} step=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_data_erode (@code{HMDT} dat, @code{mreal} val, @code{long} step)
++@end ifclear
++Возвращает "суженный" на @var{step} ячеек массив из 0 и 1 для данных больших порогового значения @var{val}. @c TODO @sref{Dilate and erode sample}
++@end deftypefn
++
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++@c ------------------------------------------------------------------
++@external{}
++@node Interpolation, Data information, Data changing, Data processing
++@section Интерполяция
++@nav{}
++
++Скрипты MGL могут использовать интерполяцию кубическими сплайнами с помощью команд @ref{evaluate} или @ref{refill}. Также можно использовать @ref{resize} для массива с новыми размерами.
++
++@ifclear UDAV
++
++Однако, есть специальные и более быстрые функции при использовании других языков (C/C++/Fortran/Python/...).
++
++@cindex Spline
++@deftypefn {Метод класса @code{mglData}} @code{mreal} Spline (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{dual} Spline (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_spline (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++@deftypefnx {Функция С} @code{dual} mgl_datac_spline (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++Интерполирует данные кубическим сплайном в точке @var{x} в [0...nx-1], @var{y} в [0...ny-1], @var{z} в [0...nz-1].
++@end deftypefn
++@cindex Spline1
++@deftypefn {Метод класса @code{mglData}} @code{mreal} Spline1 (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{dual} Spline1 (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++Интерполирует данные кубическим сплайном в точке @var{x}, @var{y}, @var{z}, где координаты полагаются в интервале [0, 1].
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglData}} @code{mreal} Spline (@code{mglPoint} &dif, @code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_spline_ext (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal *}dx, @code{mreal *}dy, @code{mreal *}dz)
++@deftypefnx {Функция С} @code{dual} mgl_datac_spline_ext (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{dual *}dx, @code{dual *}dy, @code{dual *}dz)
++Интерполирует данные кубическим сплайном в точке @var{x} в [0...nx-1], @var{y} в [0...ny-1], @var{z} в [0...nz-1]. Значения производных в точке записываются в @var{dif}.
++@end deftypefn
++@cindex Spline1
++@deftypefn {Метод класса @code{mglData}} @code{mreal} Spline1 (@code{mglPoint} &dif, @code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++Интерполирует данные кубическим сплайном в точке @var{x}, @var{y}, @var{z}, где координаты полагаются в интервале [0, 1]. Значения производных в точке записываются в @var{dif}.
++@end deftypefn
++
++
++@cindex Linear
++@deftypefn {Метод класса @code{mglData}} @code{mreal} Linear (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{dual} Linear (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_linear (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++@deftypefnx {Функция С} @code{dual} mgl_datac_linear (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++Интерполирует данные линейной функцией в точке @var{x} в [0...nx-1], @var{y} в [0...ny-1], @var{z} в [0...nz-1].
++@end deftypefn
++@cindex Linear1
++@deftypefn {Метод класса @code{mglData}} @code{mreal} Linear1 (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{dual} Linear1 (@code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++Интерполирует данные линейной функцией в точке @var{x}, @var{y}, @var{z}, где координаты полагаются в интервале [0, 1].
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglData}} @code{mreal} Linear (@code{mglPoint} &dif, @code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{dual} Linear (@code{mglPoint} &dif, @code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_linear_ext (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{mreal *}dx, @code{mreal *}dy, @code{mreal *}dz)
++@deftypefnx {Функция С} @code{dual} mgl_datac_linear_ext (@code{HCDT} dat, @code{mreal} x, @code{mreal} y, @code{mreal} z, @code{dual *}dx, @code{dual *}dy, @code{dual *}dz)
++Интерполирует данные линейной функцией в точке @var{x}, @var{y}, @var{z}, где координаты полагаются в интервале [0, 1]. Значения производных в точке записываются в @var{dif}.
++@end deftypefn
++@cindex Linear1
++@deftypefn {Метод класса @code{mglData}} @code{mreal} Linear1 (@code{mglPoint} &dif, @code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++@deftypefnx {Метод класса @code{mglDataC}} @code{dual} Linear1 (@code{mglPoint} &dif, @code{mreal} x, @code{mreal} y=@code{0}, @code{mreal} z=@code{0}) @code{const}
++Интерполирует данные линейной функцией в точке @var{x}, @var{y}, @var{z}, где координаты полагаются в интервале [0, 1]. Значения производных в точке записываются в @var{dif}.
++@end deftypefn
++
++@end ifclear
++
++@c ------------------------------------------------------------------
++@external{}
++@node Data information, Operators, Interpolation, Data processing
++@section Информационные функции
++@nav{}
++
++В MathGL есть ряд функций для получения свойств массива данных. В MGL скриптах большинство из них реализовано в виде "суффиксов". Суффиксы дают числовое значение некоторой характеристики массива данных. Например, его размер, минимальное и максимальное значение, сумму элементов и т.д. Суффиксы начинаются с точки @samp{.} сразу после массива (без пробелов). Например, @code{a.nx} даст размер массива @var{a} вдоль x, @code{b(1).max} даст максимальное значение второй колонки массива @var{b}, @code{(c(:,0)^2).sum} даст сумму квадратов в первой строке массива @var{c} и т.д.
++
++
++@cindex PrintInfo
++@anchor{info}
++@deftypefn {Команда MGL} {} info dat
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglDataA}} @code{const char *} PrintInfo () @code{const}
++@deftypefnx {Метод класса @code{mglDataA}} @code{void} PrintInfo (@code{FILE *}fp) @code{const}
++@deftypefnx {Функция С} @code{const char *} mgl_data_info (@code{HCDT} dat)
++@deftypefnx {Fortran процедура} @code{} mgl_data_info (@code{long} dat, @code{char *}out, @code{int} len)
++@end ifclear
++Возвращает строку с информацией о данных (размеры, моменты и пр.) или пишет её в файл. В MGL скрипте печатает её как сообщение.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} info 'txt'
++Печатает строку @var{txt} как сообщение.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} info val
++Печатает значение числа @var{val} как сообщение.
++@end deftypefn
++
++@anchor{print}
++@deftypefn {Команда MGL} {} print dat
++@deftypefnx {Команда MGL} {} print 'txt'
++@deftypefnx {Команда MGL} {} print val
++Аналогично @ref{info}, но сразу выводит в stdout.
++@end deftypefn
++
++@anchor{echo}
++@deftypefn {Команда MGL} {} echo dat
++Печатает все значения массива @var{dat} как сообщение.
++@end deftypefn
++
++
++@cindex GetNx
++@cindex GetNy
++@cindex GetNz
++@anchor{.nx} @anchor{.ny} @anchor{.nz}
++@deftypefn {MGL suffix} {(dat)} .nx
++@deftypefnx {MGL suffix} {(dat)} .ny
++@deftypefnx {MGL suffix} {(dat)} .nz
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglDataA}} @code{long} GetNx ()
++@deftypefnx {Метод класса @code{mglDataA}} @code{long} GetNy ()
++@deftypefnx {Метод класса @code{mglDataA}} @code{long} GetNz ()
++@deftypefnx {Функция С} @code{long} mgl_data_get_nx (@code{HCDT} dat)
++@deftypefnx {Функция С} @code{long} mgl_data_get_ny (@code{HCDT} dat)
++@deftypefnx {Функция С} @code{long} mgl_data_get_nz (@code{HCDT} dat)
++@end ifclear
++Возвращает размер данных в направлении x, y и z соответственно.
++@end deftypefn
++
++
++
++@cindex Maximal
++@anchor{.max}
++@deftypefn {MGL suffix} {(dat)} .max
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Maximal () @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_max (@code{HCDT} dat)
++@end ifclear
++Возвращает максимальное значение массива данных.
++@end deftypefn
++
++@cindex Minimal
++@anchor{.min}
++@deftypefn {MGL suffix} {(dat)} .min
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Minimal () @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_min (@code{HMDT} dat) @code{const}
++@end ifclear
++Возвращает минимальное значение массива данных.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglDataA}} @code{mreal} Minimal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_min_int (@code{HCDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
++Возвращает максимальное значение массива данных и сохраняет его положение в переменные @var{i}, @var{j}, @var{k}.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataA}} @code{mreal} Maximal (@code{int} &i, @code{int} &j, @code{int} &k) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_max_int (@code{HCDT} dat, @code{int} *i, @code{int} *j, @code{int} *k)
++Возвращает минимальное значение массива данных и сохраняет его положение в переменные @var{i}, @var{j}, @var{k}.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataA}} @code{mreal} Minimal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_min_real (@code{HCDT} dat, @code{mreal} *x, @code{mreal} *y, @code{mreal} *z)
++Возвращает максимальное значение массива данных и его приближенное (интерполированное) положение в переменные @var{x}, @var{y}, @var{z}.
++@end deftypefn
++@end ifclear
++
++@anchor{.mx} @anchor{.my} @anchor{.mz}
++@deftypefn {MGL suffix} {(dat)} .mx
++@deftypefnx {MGL suffix} {(dat)} .my
++@deftypefnx {MGL suffix} {(dat)} .mz
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Maximal (@code{mreal} &x, @code{mreal} &y, @code{mreal} &z) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_max_real (@code{HCDT} dat, @code{mreal} *x, @code{mreal} *y, @code{mreal} *z)
++@end ifclear
++Возвращает минимальное значение массива данных и его приближенное (интерполированное) положение в переменные @var{x}, @var{y}, @var{z}.
++@end deftypefn
++
++@anchor{.mxf} @anchor{.myf} @anchor{.mzf}
++@anchor{.mxl} @anchor{.myl} @anchor{.mzl}
++@deftypefn {MGL suffix} {(dat)} .mxf
++@deftypefnx {MGL suffix} {(dat)} .myf
++@deftypefnx {MGL suffix} {(dat)} .mzf
++@deftypefnx {MGL suffix} {(dat)} .mxl
++@deftypefnx {MGL suffix} {(dat)} .myl
++@deftypefnx {MGL suffix} {(dat)} .mzl
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglDataA}} @code{long} Maximal (@code{char} dir, @code{long} from) @code{const}
++@deftypefnx {Метод класса @code{mglDataA}} @code{long} Maximal (@code{char} dir, @code{long} from, @code{long} &p1, @code{long} &p2) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_max_firstl (@code{HCDT} dat, @code{char} dir, @code{long} from, @code{long} *p1, @code{long} *p2)
++@end ifclear
++Возвращает положение первого (последнего при @var{from}<0) максимума в направлении @var{dir}, начиная с позиции @var{from}. Положение остальных координат для максимума сохраняется в @var{p1}, @var{p2}.
++@end deftypefn
++
++
++@cindex Momentum
++@anchor{.ax} @anchor{.ay} @anchor{.az} @anchor{.aa} @anchor{.sum}
++@anchor{.wx} @anchor{.wy} @anchor{.wz} @anchor{.wa}
++@anchor{.sx} @anchor{.sy} @anchor{.sz} @anchor{.sa}
++@anchor{.kx} @anchor{.ky} @anchor{.kz} @anchor{.ka}
++@deftypefn {MGL suffix} {(dat)} .sum
++@deftypefnx {MGL suffix} {(dat)} .ax
++@deftypefnx {MGL suffix} {(dat)} .ay
++@deftypefnx {MGL suffix} {(dat)} .az
++@deftypefnx {MGL suffix} {(dat)} .aa
++@deftypefnx {MGL suffix} {(dat)} .wx
++@deftypefnx {MGL suffix} {(dat)} .wy
++@deftypefnx {MGL suffix} {(dat)} .wz
++@deftypefnx {MGL suffix} {(dat)} .wa
++@deftypefnx {MGL suffix} {(dat)} .sx
++@deftypefnx {MGL suffix} {(dat)} .sy
++@deftypefnx {MGL suffix} {(dat)} .sz
++@deftypefnx {MGL suffix} {(dat)} .sa
++@deftypefnx {MGL suffix} {(dat)} .kx
++@deftypefnx {MGL suffix} {(dat)} .ky
++@deftypefnx {MGL suffix} {(dat)} .kz
++@deftypefnx {MGL suffix} {(dat)} .ka
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Momentum (@code{char} dir, @code{mreal} &a, @code{mreal} &w) @code{const}
++@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Momentum (@code{char} dir, @code{mreal} &m, @code{mreal} &w, @code{mreal} &s, @code{mreal} &k) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_momentum_val (@code{HCDT} dat, @code{char} dir, @code{mreal} *a, @code{mreal} *w, @code{mreal} *s, @code{mreal} *k)
++@end ifclear
++Возвращает нулевой момент (энергию, @math{I=\sum a_i}) и записывает первый (среднее, @math{m = \sum \xi_i a_i/I}), второй (ширину, @math{w^2 = \sum (\xi_i-m)^2 a_i/I}), третий (асимметрия, @math{s = \sum (\xi_i-m)^3 a_i/ I w^3}) и четвёртый моменты (эксцесс, @math{k = \sum (\xi_i-m)^4 a_i / 3 I w^4})). Здесь @math{\xi} -- соответствующая координата если @var{dir} равно @samp{'x'}, @samp{'y'}, @samp{'z'}. В противном случае среднее, ширина, асимметрия, эксцесс равны @math{m = \sum a_i/N}, @math{w^2 = \sum (a_i-m)^2/N} и т.д.
++@end deftypefn
++
++@anchor{.fst}
++@deftypefn {MGL suffix} {(dat)} .fst
++@ifclear UDAV
++@cindex Find
++@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Find (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_first (@code{HCDT} dat, @code{const char *}cond, @code{int} *i, @code{int} *j, @code{int} *k)
++@end ifclear
++Находит положение (после заданного в @var{i}, @var{j}, @var{k}) первого не нулевого значения формулы @var{cond}. Функция возвращает найденное значение и записывает его положение в @var{i}, @var{j}, @var{k}.
++@end deftypefn
++
++@anchor{.lst}
++@deftypefn {MGL suffix} {(dat)} .lst
++@ifclear UDAV
++@cindex Last
++@deftypefnx {Метод класса @code{mglDataA}} @code{mreal} Last (@code{const char *}cond, @code{int} &i, @code{int} &j, @code{int} &k) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_last (@code{HCDT} dat, @code{const char *}cond, @code{int} *i, @code{int} *j, @code{int} *k)
++@end ifclear
++Находит положение (перед заданного в @var{i}, @var{j}, @var{k}) последнего не нулевого значения формулы @var{cond}. Функция возвращает найденное значение и записывает его положение в @var{i}, @var{j}, @var{k}.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Метод класса @code{mglDataA}} @code{int} Find (@code{const char *}cond, @code{char} dir, @code{int} i=@code{0}, @code{int} j=@code{0}, @code{int} k=@code{0}) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_find (@code{HCDT} dat, @code{const char *}cond, @code{int} i, @code{int} j, @code{int} k)
++Возвращает положение первого в направлении @var{dir} не нулевого значения формулы @var{cond}. Поиск начинается с точки @{i,j,k@}.
++@end deftypefn
++@cindex FindAny
++@deftypefn {Метод класса @code{mglDataA}} @code{bool} FindAny (@code{const char *}cond) @code{const}
++@deftypefnx {Функция С} @code{mreal} mgl_data_find_any (@code{HCDT} dat, @code{const char *}cond)
++Определяет есть ли хоть одно значение массива, удовлетворяющее условию @var{cond}.
++@end deftypefn
++@end ifclear
++
++@anchor{.a}
++@deftypefn {MGL suffix} {(dat)} .a
++Возвращает первое число массива (для @code{.a} это @code{dat->a[0]}).
++@end deftypefn
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node Operators, Global functions, Data information, Data processing
++@section Операторы
++@nav{}
++
++@deftypefn {Команда MGL} {} copy @sc{dat} dat2 ['eq'='']
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} operator= (@code{const mglDataA &}d)
++@end ifclear
++Копирует данные из другого экземпляра.
++@end deftypefn
++
++@deftypefn {Команда MGL} {} copy dat @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mreal}} @code{void} operator= (@code{mreal} val)
++@end ifclear
++Устанавливает все значения массива равными @var{val}.
++@end deftypefn
++
++@anchor{multo}
++@deftypefn {Команда MGL} {} multo dat dat2
++@deftypefnx {Команда MGL} {} multo dat @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} operator*= (@code{const mglDataA &}d)
++@deftypefnx {Метод класса @code{mglData}} @code{void} operator*= (@code{mreal} d)
++@deftypefnx {Функция С} @code{void} mgl_data_mul_dat (@code{HMDT} dat, @code{HCDT} d)
++@deftypefnx {Функция С} @code{void} mgl_data_mul_num (@code{HMDT} dat, @code{mreal} d)
++@end ifclear
++Поэлементно умножает на массив @var{d} или на число @var{val}.
++@end deftypefn
++
++@anchor{divto}
++@deftypefn {Команда MGL} {} divto dat dat2
++@deftypefnx {Команда MGL} {} divto dat @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} operator/= (@code{const mglDataA &}d)
++@deftypefnx {Метод класса @code{mglData}} @code{void} operator/= (@code{mreal} d)
++@deftypefnx {Функция С} @code{void} mgl_data_div_dat (@code{HMDT} dat, @code{HCDT} d)
++@deftypefnx {Функция С} @code{void} mgl_data_div_num (@code{HMDT} dat, @code{mreal} d)
++@end ifclear
++Поэлементно делит на массив @var{d} или на число @var{val}.
++@end deftypefn
++
++@anchor{addto}
++@deftypefn {Команда MGL} {} addto dat dat2
++@deftypefnx {Команда MGL} {} addto dat @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} operator+= (@code{const mglDataA &}d)
++@deftypefnx {Метод класса @code{mglData}} @code{void} operator+= (@code{mreal} d)
++@deftypefnx {Функция С} @code{void} mgl_data_add_dat (@code{HMDT} dat, @code{HCDT} d)
++@deftypefnx {Функция С} @code{void} mgl_data_add_num (@code{HMDT} dat, @code{mreal} d)
++@end ifclear
++Поэлементно прибавляет @var{d} или число @var{val}.
++@end deftypefn
++
++@anchor{subto}
++@deftypefn {Команда MGL} {} subto dat dat2
++@deftypefnx {Команда MGL} {} subto dat @code{val}
++@ifclear UDAV
++@deftypefnx {Метод класса @code{mglData}} @code{void} operator-= (@code{const mglDataA &}d)
++@deftypefnx {Метод класса @code{mglData}} @code{void} operator-= (@code{mreal} d)
++@deftypefnx {Функция С} @code{void} mgl_data_sub_dat (@code{HMDT} dat, @code{HCDT} d)
++@deftypefnx {Функция С} @code{void} mgl_data_sub_num (@code{HMDT} dat, @code{mreal} d)
++@end ifclear
++Поэлементно вычитает @var{d} или число @var{val}.
++@end deftypefn
++
++@ifclear UDAV
++@deftypefn {Library Function} mglData operator+ (@code{const mglDataA &}a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator+ (@code{mreal} a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator+ (@code{const mglDataA &}a, @code{mreal} b)
++Возвращает поэлементную сумму данных.
++@end deftypefn
++
++@deftypefn {Library Function} mglData operator- (@code{const mglDataA &}a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator- (@code{mreal} a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator- (@code{const mglDataA &}a, @code{mreal} b)
++Возвращает поэлементную разность данных.
++@end deftypefn
++
++@deftypefn {Library Function} mglData operator* (@code{const mglDataA &}a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator* (@code{mreal} a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator* (@code{const mglDataA &}a, @code{mreal} b)
++Возвращает поэлементное произведение данных.
++@end deftypefn
++
++@deftypefn {Library Function} mglData operator/ (@code{const mglDataA &}a, @code{const mglDataA &}b)
++@deftypefnx {Library Function} mglData operator/ (@code{const mglDataA &}a, @code{mreal} b)
++Возвращает поэлементное деление данных.
++@end deftypefn
++@end ifclear
++
++@c ------------------------------------------------------------------
++@external{}
++@node Global functions, Evaluate expression, Operators, Data processing
++@section Глобальные функции
++@nav{}
++
++@ifclear UDAV
++Эти функции не методы класса @code{mglData}, но они дают дополнительные возможности по обработке данных. Поэтому я поместил их в эту главу.
++@end ifclear
++
++@anchor{transform}
++@deftypefn {Команда MGL} {} transform @sc{dat} 'type' real imag
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglTransform (@code{const mglDataA &}real, @code{const mglDataA &}imag, @code{const char *}type)
++@deftypefnx {Функция С} @code{HMDT} mgl_transform (@code{HCDT} real, @code{HCDT} imag, @code{const char *}type)
++@end ifclear
++Выполняет интегральное преобразование комплексных данных @var{real}, @var{imag} в выбранном направлении и возвращает модуль результата. Порядок и тип преобразований задается строкой @var{type}: первый символ для x-направления, второй для y-направления, третий для z-направления. Возможные символы: @samp{f} -- прямое преобразование Фурье, @samp{i} -- обратное преобразование Фурье, @samp{s} -- синус преобразование, @samp{c} -- косинус преобразование, @samp{h} -- преобразование Ханкеля, @samp{n} или @samp{ } -- нет преобразования.
++@end deftypefn
++
++@anchor{transforma}
++@deftypefn {Команда MGL} {} transforma @sc{dat} 'type' ampl phase
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglTransformA @code{const mglDataA &}ampl, @code{const mglDataA &}phase, @code{const char *}type)
++@deftypefnx {Функция С} @code{HMDT} mgl_transform_a @code{HCDT} ampl, @code{HCDT} phase, @code{const char *}type)
++@end ifclear
++Аналогично предыдущему с заданными амплитудой @var{ampl} и фазой @var{phase} комплексных чисел.
++@end deftypefn
++
++@anchor{fourier}
++@deftypefn {Команда MGL} {} fourier reDat imDat 'dir'
++@deftypefnx {Команда MGL} {} fourier complexDat 'dir'
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{void} mglFourier @code{const mglDataA &}re, @code{const mglDataA &}im, @code{const char *}dir)
++@deftypefnx {Метод класса @code{mglDataC}} @code{void} FFT (@code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_data_fourier @code{HCDT} re, @code{HCDT} im, @code{const char *}dir)
++@deftypefnx {Функция С} @code{void} mgl_datac_fft (@code{HADT} dat, @code{const char *}dir)
++@end ifclear
++Выполняет Фурье преобразование для комплексных данных @var{re}+i*@var{im} в направлениях @var{dir}. Результат помещается обратно в массивы @var{re} и @var{im}. Если @var{dir} содержит @samp{i}, то выполняется обратное преобразование Фурье.
++@end deftypefn
++
++@anchor{stfad}
++@deftypefn {Команда MGL} {} stfad @sc{res} real imag @code{dn} ['dir'='x']
++@ifclear UDAV
++<<<<<<< HEAD
++@deftypefnx {Global function} @code{mglData} mglSTFA (@code{const mglDataA &}real, @code{const mglDataA &}imag, @code{int} dn, @code{char} dir=@code{'x'})
++=======
++@deftypefnx {Общая функция} @code{mglData} mglSTFA (@code{const mglDataA &}real, @code{const mglDataA &}imag, @code{int} dn, @code{char} dir=@code{'x'})
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++@deftypefnx {Функция С} @code{HMDT} mgl_data_stfa (@code{HCDT} real, @code{HCDT} imag, @code{int} dn, @code{char} dir)
++@end ifclear
++Выполняет оконное преобразование Фурье длиной @var{dn} для комплексных данных @var{real}, @var{imag} и возвращает модуль результата. Например, для @var{dir}=@samp{x} результат будет иметь размер @{int(nx/dn), dn, ny@} и будет равен @math{res[i,j,k]=|\sum_d^dn exp(I*j*d)*(real[i*dn+d,k]+I*imag[i*dn+d,k])|/dn}.
++@end deftypefn
++
++@anchor{tridmat}
++@deftypefn {Команда MGL} {} tridmat @sc{res adat bdat cdat ddat} 'how'
++@ifclear UDAV
++<<<<<<< HEAD
++@deftypefnx {Global function} @code{mglData} mglTridMat (@code{const mglDataA &}A, @code{const mglDataA &}B, @code{const mglDataA &}C, @code{const mglDataA &}D, @code{const char *}how)
++@deftypefnx {Global function} @code{mglDataC} mglTridMatC (@code{const mglDataA &}A, @code{const mglDataA &}B, @code{const mglDataA &}C, @code{const mglDataA &}D, @code{const char *}how)
++=======
++@deftypefnx {Общая функция} @code{mglData} mglTridMat (@code{const mglDataA &}A, @code{const mglDataA &}B, @code{const mglDataA &}C, @code{const mglDataA &}D, @code{const char *}how)
++@deftypefnx {Общая функция} @code{mglDataC} mglTridMatC (@code{const mglDataA &}A, @code{const mglDataA &}B, @code{const mglDataA &}C, @code{const mglDataA &}D, @code{const char *}how)
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++@deftypefnx {Функция С} @code{HMDT} mgl_data_tridmat (@code{HCDT} A, @code{HCDT} B, @code{HCDT} C, @code{HCDT} D, @code{const char*}how)
++@deftypefnx {Функция С} @code{HADT} mgl_datac_tridmat (@code{HCDT} A, @code{HCDT} B, @code{HCDT} C, @code{HCDT} D, @code{const char*}how)
++@end ifclear
++Возвращает решение трехдиагональной системы уравнений @var{A}[i]*x[i-1]+@var{B}[i]*x[i]+@var{C}[i]*x[i+1]=@var{D}[i]. Строка @var{how} может содержать:
++@itemize @bullet
++@item
++@samp{xyz} для решения вдоль x-,y-,z-направлений;
++@item
++@samp{h} для решения вдоль диагонали на плоскости x-y (требует квадратную матрицу);
++@item
++@samp{c} для использования периодических граничных условий;
++@item
++@samp{d} для расчета диффракции/диффузии (т.е. для использования -@var{A}[i]*@var{D}[i-1]+(2-@var{B}[i])*@var{D}[i]-@var{C}[i]*@var{D}[i+1] в правой частиц вместо @var{D}[i]).
++@end itemize
++Размеры массивов @var{A}, @var{B}, @var{C} должны быть одинаковы. Также их размерности должны совпадать со всеми или с "младшими" размерностями массива @var{D}. @sref{PDE solving hints}
++@end deftypefn
++
++@anchor{pde}
++@deftypefn {Команда MGL} {} pde @sc{res} 'ham' ini_re ini_im [@code{dz=0.1 k0=100}]
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglPDE (@code{HMGL} gr, @code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{mreal} dz=@code{0.1}, @code{mreal} k0=@code{100}, @code{const char *}opt=@code{""})
++@deftypefnx {Общая функция} @code{mglDataC} mglPDEc (@code{HMGL} gr, @code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{mreal} dz=@code{0.1}, @code{mreal} k0=@code{100}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{HMDT} mgl_pde_solve (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{mreal} dz, @code{mreal} k0, @code{const char *}opt)
++@deftypefnx {Функция С} @code{HADT} mgl_pde_solve_c (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{mreal} dz, @code{mreal} k0, @code{const char *}opt)
++@end ifclear
++Решает уравнение в частных производных du/dz = i*k0*@var{ham}(p,q,x,y,z,|u|)[u], где p=-i/k0*d/dx, q=-i/k0*d/dy -- псевдо-дифференциальные операторы. Параметры @var{ini_re}, @var{ini_im} задают начальное распределение поля. Координаты в уравнении и в решении полагаются в диапазоне осей координат. Замечу, что внутри этот диапазон увеличивается в 3/2 раза для уменьшения отражения от границ расчетного интервала. Параметр @var{dz} задает шаг по эволюционной координате z. В данный момент использован упрощенный алгоритм, когда все ``смешанные'' члена (типа @samp{x*p}->x*d/dx) исключаются. Например, в 2D случае это функции типа @math{ham = f(p,z) + g(x,z,u)}. При этом допускаются коммутирующие комбинации (типа @samp{x*q}->x*d/dy). Переменная @samp{u} используется для обозначения амплитуды поля |u|. Это позволяет решать нелинейные задачи -- например, нелинейное уравнение Шредингера @code{ham='p^2+q^2-u^2'}. Также можно указать мнимую часть для поглощения (типа @code{ham = 'p^2+i*x*(x>0)'}). См. также @ref{apde}, @ref{qo2d}, @ref{qo3d}. @sref{PDE solving hints}
++@end deftypefn
++
++@anchor{apde}
++@deftypefn {Команда MGL} {} apde @sc{res} 'ham' ini_re ini_im [@code{dz=0.1 k0=100}]
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglAPDE (@code{HMGL} gr, @code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{mreal} dz=@code{0.1}, @code{mreal} k0=@code{100}, @code{const char *}opt=@code{""})
++@deftypefnx {Общая функция} @code{mglDataC} mglAPDEc (@code{HMGL} gr, @code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{mreal} dz=@code{0.1}, @code{mreal} k0=@code{100}, @code{const char *}opt=@code{""})
++@deftypefnx {Функция С} @code{HMDT} mgl_pde_solve_adv (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{mreal} dz, @code{mreal} k0, @code{const char *}opt)
++@deftypefnx {Функция С} @code{HADT} mgl_pde_solve_adv_c (@code{HMGL} gr, @code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{mreal} dz, @code{mreal} k0, @code{const char *}opt)
++@end ifclear
++Решает уравнение в частных производных du/dz = i*k0*@var{ham}(p,q,x,y,z,|u|)[u], где p=-i/k0*d/dx, q=-i/k0*d/dy -- псевдо-дифференциальные операторы. Параметры @var{ini_re}, @var{ini_im} задают начальное распределение поля. Координаты в уравнении и в решении полагаются в диапазоне осей координат. Замечу, что внутри этот диапазон увеличивается в 3/2 раза для уменьшения отражения от границ расчетного интервала. Параметр @var{dz} задает шаг по эволюционной координате z. Используется достаточно сложный и медленный алгоритм, способный учесть одновременное влияние пространственной дисперсии и неоднородности среды [см. А.А. Балакин, Е.Д. Господчиков, А.Г. Шалашов, Письма ЖЭТФ 104, 701 (2016)]. Переменная @samp{u} используется для обозначения амплитуды поля |u|. Это позволяет решать нелинейные задачи -- например, нелинейное уравнение Шредингера @code{ham='p^2+q^2-u^2'}. Также можно указать мнимую часть для поглощения (типа @code{ham = 'p^2+i*x*(x>0)'}). См. также @ref{apde}. @sref{PDE solving hints}
++@end deftypefn
++
++@anchor{ray}
++@deftypefn {Команда MGL} {} ray @sc{res} 'ham' @code{x0 y0 z0 p0 q0 v0 [dt=0.1 tmax=10]}
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglRay (@code{const char *}ham, @code{mglPoint} r0, @code{mglPoint} p0, @code{mreal} dt=@code{0.1}, @code{mreal} tmax=@code{10})
++@deftypefnx {Функция С} @code{HMDT} mgl_ray_trace (@code{const char *}ham, @code{mreal} x0, @code{mreal} y0, @code{mreal} z0, @code{mreal} px, @code{mreal} py, @code{mreal} pz, @code{mreal} dt, @code{mreal} tmax)
++@end ifclear
++Решает систему геометрооптических уравнений d@emph{r}/dt = d @var{ham}/d@emph{p}, d@emph{p}/dt = -d @var{ham}/d@emph{r}. Это гамильтоновы уравнения для траектории частицы в 3D случае. Гамильтониан @var{ham} может зависеть от координат @samp{x}, @samp{y}, @samp{z}, импульсов @samp{p}=px, @samp{q}=py, @samp{v}=pz и времени @samp{t}: @math{ham = H(x,y,z,p,q,v,t)}. Начальная точка (при @code{t=0}) задается переменными @{@var{x0}, @var{y0}, @var{z0}, @var{p0}, @var{q0}, @var{v0}@}. Параметры @var{dt} и @var{tmax} задают шаг и максимальное время интегрирования. Результат -- массив @{x,y,z,p,q,v,t@} с размером @{7 * int(@var{tmax}/@var{dt}+1) @}.
++@end deftypefn
++
++@anchor{ode}
++@deftypefn {Команда MGL} {} ode @sc{res} 'df' 'var' ini [@code{dt=0.1 tmax=10}]
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglODE (@code{const char *}df, @code{const char *}var, @code{const mglDataA &}ini, @code{mreal} dt=@code{0.1}, @code{mreal} tmax=@code{10})
++@deftypefnx {Общая функция} @code{mglDataC} mglODEc (@code{const char *}df, @code{const char *}var, @code{const mglDataA &}ini, @code{mreal} dt=@code{0.1}, @code{mreal} tmax=@code{10})
++@deftypefnx {Функция С} @code{HMDT} mgl_ode_solve_str (@code{const char *}df, @code{const char *}var, @code{HCDT} ini, @code{mreal} dt, @code{mreal} tmax)
++@deftypefnx {Функция С} @code{HADT} mgl_ode_solve_str_c (@code{const char *}df, @code{const char *}var, @code{HCDT} ini, @code{mreal} dt, @code{mreal} tmax)
++@deftypefnx {Функция С} @code{HMDT} mgl_ode_solve (@code{void (*}df@code{)(const mreal *x, mreal *dx, void *par)}, @code{int} n, @code{const mreal *}ini, @code{mreal} dt, @code{mreal} tmax)
++@deftypefnx {Функция С} @code{HMDT} mgl_ode_solve_ex (@code{void (*}df@code{)(const mreal *x, mreal *dx, void *par)}, @code{int} n, @code{const mreal *}ini, @code{mreal} dt, @code{mreal} tmax, @code{void (*}bord@code{)(mreal *x, const mreal *xprev, void *par)})
++@end ifclear
++Решает систему обыкновенных дифференциальных уравнений dx/dt = df(x). Функции @var{df} могут быть заданны строкой с разделенными ';' формулами (аргумент @var{var} задает символы для переменных x[i]) или указателем на функцию, которая заполняет @code{dx} по заданным значениям @code{x}. Параметры @var{ini}, @var{dt}, @var{tmax} задают начальные значения, шаг и максимальное время интегрирования. Результат -- массив с размером @{@var{n} * int(@var{tmax}/@var{dt}+1)@}.
++@end deftypefn
++
++@anchor{qo2d}
++@deftypefn {Команда MGL} {} qo2d @sc{res} 'ham' ini_re ini_im ray [@code{r=1 k0=100} xx yy]
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglQO2d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100}, @code{mglData *}xx=@code{0}, @code{mglData *}yy=@code{0})
++@deftypefnx {Общая функция} @code{mglData} mglQO2d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Общая функция} @code{mglDataC} mglQO2dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Общая функция} @code{mglDataC} mglQO2dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Функция С} @code{HMDT} mgl_qo2d_solve (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
++@deftypefnx {Функция С} @code{HADT} mgl_qo2d_solve_c (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
++@deftypefnx {Функция С} @code{HMDT} mgl_qo2d_func (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
++@deftypefnx {Функция С} @code{HADT} mgl_qo2d_func_c (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal px, mreal py, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy)
++@end ifclear
++Решает уравнение в частных производных du/dt = i*k0*@var{ham}(p,q,x,y,|u|)[u] в сопровождающей системе координат, где p=-i/k0*d/dx, q=-i/k0*d/dy -- псевдо-дифференциальные операторы. Параметры @var{ini_re}, @var{ini_im} задают начальное распределение поля. Параметр @var{ray} задает опорный луч для сопровождающей системы координат. Можно использовать луч найденный с помощью @ref{ray}. Опорный луч должен быть достаточно гладкий, чтобы система координат была однозначной и для исключения ошибок интегрирования. Если массивы @var{xx} и @var{yy} указаны, то в них записываются декартовы координаты для каждой точки найденного решения. См. также @ref{pde}, @ref{qo3d}. @sref{PDE solving hints}
++@end deftypefn
++
++@anchor{qo3d}
++@deftypefn {Команда MGL} {} qo3d @sc{res} 'ham' ini_re ini_im ray [@code{r=1 k0=100} xx yy zz]
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglQO3d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Общая функция} @code{mglData} mglQO3d (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mglData &}zz, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Общая функция} @code{mglDataC} mglQO3dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Общая функция} @code{mglDataC} mglQO3dc (@code{const char *}ham, @code{const mglDataA &}ini_re, @code{const mglDataA &}ini_im, @code{const mglDataA &}ray, @code{mglData &}xx, @code{mglData &}yy, @code{mglData &}zz, @code{mreal} r=@code{1}, @code{mreal} k0=@code{100})
++@deftypefnx {Функция С} @code{HMDT} mgl_qo3d_solve (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
++@deftypefnx {Функция С} @code{HADT} mgl_qo3d_solve_c (@code{const char *}ham, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
++@deftypefnx {Функция С} @code{HMDT} mgl_qo3d_func (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
++@deftypefnx {Функция С} @code{HADT} mgl_qo3d_func_c (@code{dual (*}ham@code{)(mreal u, mreal x, mreal y, mreal z, mreal px, mreal py, mreal pz, void *par)}, @code{HCDT} ini_re, @code{HCDT} ini_im, @code{HCDT} ray, @code{mreal} r, @code{mreal} k0, @code{HMDT} xx, @code{HMDT} yy, @code{HMDT} zz)
++@end ifclear
++Решает уравнение в частных производных du/dt = i*k0*@var{ham}(p,q,v,x,y,z,|u|)[u] в сопровождающей системе координат, где p=-i/k0*d/dx, q=-i/k0*d/dy, v=-i/k0*d/dz -- псевдо-дифференциальные операторы. Параметры @var{ini_re}, @var{ini_im} задают начальное распределение поля. Параметр @var{ray} задает опорный луч для сопровождающей системы координат. Можно использовать луч найденный с помощью @ref{ray}. Опорный луч должен быть достаточно гладкий, чтобы система координат была однозначной и для исключения ошибок интегрирования. Если массивы @var{xx}, @var{yy} и @var{zz} указаны, то в них записываются декартовы координаты для каждой точки найденного решения. См. также @ref{pde}, @ref{qo2d}.
++@end deftypefn
++
++@anchor{jacobian}
++@deftypefn {Команда MGL} {} jacobian @sc{res} xdat ydat [zdat]
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglJacobian (@code{const mglDataA &}x, @code{const mglDataA &}y)
++@deftypefnx {Общая функция} @code{mglData} mglJacobian (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z)
++@deftypefnx {Функция С} @code{HMDT} mgl_jacobian_2d (@code{HCDT} x, @code{HCDT} y)
++@deftypefnx {Функция С} @code{HMDT} mgl_jacobian_3d (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z)
++@end ifclear
++Вычисляет якобиан преобразования @{i,j,k@} в @{@var{x},@var{y},@var{z}@}, где координаты @{i,j,k@} полагаются нормированными в интервал [0,1]. Якобиан находится по формуле det||@math{dr_\alpha/d\xi_\beta}||, где @math{r}=@{@var{x},@var{y},@var{z}@} и @math{\xi}=@{i,j,k@}. Все размерности всех массивов должны быть одинаковы. Данные должны быть трехмерными если указаны все 3 массива @{@var{x},@var{y},@var{z}@} или двумерными если только 2 массива @{@var{x},@var{y}@}.
++@end deftypefn
++
++@anchor{triangulation}
++@deftypefn {Команда MGL} {} triangulation @sc{res} xdat ydat [zdat]
++@c @deftypefn {Команда MGL} {} triangulation @sc{res} xdat ydat [zdat]
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglTriangulation (@code{const mglDataA &}x, @code{const mglDataA &}y)
++@deftypefnx {Общая функция} @code{mglData} mglTriangulation (@code{const mglDataA &}x, @code{const mglDataA &}y, @code{const mglDataA &}z)
++@deftypefnx {Функция С} @code{HMDT} mgl_triangulation_2d (@code{HCDT} x, @code{HCDT} y)
++@deftypefnx {Функция С} @code{HMDT} mgl_triangulation_3d (@code{HCDT} x, @code{HCDT} y, @code{HCDT} z)
++@end ifclear
++Выполняет триангуляцию для произвольно расположенных точек с координатами @{@var{x},@var{y},@var{z}@} (т.е. находит треугольники, соединяющие точки). Первая размерность всех массивов должна быть одинакова @code{x.nx=y.nx=z.nx}. Получившийся массив можно использовать в @ref{triplot} или @ref{tricont} для визуализации реконструированной поверхности. @sref{Making regular data}
++@end deftypefn
++
++
++@ifclear UDAV
++
++@deftypefn {Общая функция} @code{mglData} mglGSplineInit (@code{const mglDataA &}x, @code{const mglDataA &}y)
++@deftypefnx {Общая функция} @code{mglDataC} mglGSplineCInit (@code{const mglDataA &}x, @code{const mglDataA &}y)
++@deftypefnx {Функция С} @code{HMDT} mgl_gspline_init (@code{HCDT} x, @code{HCDT} y)
++@deftypefnx {Функция С} @code{HADT} mgl_gsplinec_init (@code{HCDT} x, @code{HCDT} y)
++Подготавливает коэффициенты для глобального кубического сплайна.
++@end deftypefn
++
++@deftypefn {Общая функция} @code{mreal} mglGSpline (@code{const mglDataA &}coef, @code{mreal} dx, @code{mreal *}d1=@code{0}, @code{mreal *}d2=@code{0})
++@deftypefnx {Общая функция} @code{dual} mglGSplineC (@code{const mglDataA &}coef, @code{mreal} dx, @code{dual *}d1=@code{0}, @code{dual *}d2=@code{0})
++@deftypefnx {Функция С} @code{mreal} mgl_gspline (@code{HCDT} coef, @code{mreal} dx, @code{mreal *}d1, @code{mreal *}d2)
++@deftypefnx {Функция С} @code{dual} mgl_gsplinec (@code{HCDT} coef, @code{mreal} dx, @code{dual *}d1, @code{dual *}d2)
++Вычисляет глобальный кубический сплайн (а также 1ую и 2ую производные @var{d1}, @var{d2} если они не @code{NULL}), используя коэффициенты @var{coef} в точке @var{dx}+@var{x0} (здесь @var{x0} -- 1ый элемент массива @var{x} в функции @code{mglGSpline*Init()}).
++@end deftypefn
++
++@end ifclear
++
++@anchor{ifs2d}
++@deftypefn {Команда MGL} {} ifs2d @sc{res} dat @code{num} [@code{skip=20}]
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglIFS2d (@code{const mglDataA &}dat, @code{long} num, @code{long} skip=@code{20})
++@deftypefnx {Функция С} @code{HMDT} mgl_data_ifs_2d (@code{HCDT} dat, @code{long} num, @code{long} skip)
++@end ifclear
++Находит @var{num} точек @{x[i]=res[0,i], y[i]=res[1,i]@} фрактала с использованием итерационной системы функций (IFS). Матрица @var{dat} используется для генерации в соответствии с формулами
++@verbatim
++x[i+1] = dat[0,i]*x[i] + dat[1,i]*y[i] + dat[4,i];
++y[i+1] = dat[2,i]*x[i] + dat[3,i]*y[i] + dat[5,i];
++@end verbatim
++Значение @code{dat[6,i]} -- весовой коэффициент для i-ой строки матрицы @var{dat}. Первые @var{skip} итераций будут опущены. Массив @var{dat} должен иметь размер по x больше или равный 7. @sref{Fractal sample}
++@end deftypefn
++
++@anchor{ifs3d}
++@deftypefn {Команда MGL} {} ifs3d @sc{res} dat @code{num} [@code{skip=20}]
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglIFS3d (@code{const mglDataA &}dat, @code{long} num, @code{long} skip=@code{20})
++@deftypefnx {Функция С} @code{HMDT} mgl_data_ifs_3d (@code{HCDT} dat, @code{long} num, @code{long} skip)
++@end ifclear
++Находит @var{num} точек @{x[i]=res[0,i], y[i]=res[1,i], z[i]=res[2,i]@} фрактала с использованием итерационной системы функций (IFS). Матрица @var{dat} используется для генерации в соответствии с формулами
++@verbatim
++x[i+1] = dat[0,i]*x[i] + dat[1,i]*y[i] + dat[2,i]*z[i] + dat[9,i];
++y[i+1] = dat[3,i]*x[i] + dat[4,i]*y[i] + dat[5,i]*z[i] + dat[10,i];
++z[i+1] = dat[6,i]*x[i] + dat[7,i]*y[i] + dat[8,i]*z[i] + dat[11,i];
++@end verbatim
++Значение @code{dat[12,i]} -- весовой коэффициент для i-ой строки матрицы @var{dat}. Первые @var{skip} итераций будут опущены. Массив @var{dat} должен иметь размер по x больше или равный 13. @sref{Fractal sample}
++@end deftypefn
++
++@anchor{ifsfile}
++@deftypefn {Команда MGL} {} ifsfile @sc{res} 'fname' 'name' @code{num} [@code{skip=20}]
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglIFSfile (@code{const char *}fname, @code{const char *}name, @code{long} num, @code{long} skip=@code{20})
++@deftypefnx {Функция С} @code{HMDT} mgl_data_ifs_file (@code{const char *}fname, @code{const char *}name, @code{long} num, @code{long} skip)
++@end ifclear
++Считывает параметры фрактала @var{name} из файла @var{fname} и находит @var{num} точек для него. Первые @var{skip} итераций будут опущены. См. также @ref{ifs2d}, @ref{ifs3d}.
++
++Файл IFS может содержать несколько записей. Каждая запись содержит имя фрактала (@samp{binary} в примере ниже) и тело в фигурных скобках @{@} с параметрами фрактала. Символ @samp{;} начинает комментарий. Если имя содержит @samp{(3D)} или @samp{(3d)}, то определен 3d IFS фрактал. Пример содержит два фрактала: @samp{binary} -- обычный 2d фрактал, и @samp{3dfern (3D)} -- 3d фрактал.
++
++@verbatim
++ binary
++ { ; comment allowed here
++ ; and here
++ .5 .0 .0 .5 -2.563477 -0.000003 .333333 ; also comment allowed here
++ .5 .0 .0 .5 2.436544 -0.000003 .333333
++ .0 -.5 .5 .0 4.873085 7.563492 .333333
++ }
++
++ 3dfern (3D) {
++ .00 .00 0 .0 .18 .0 0 0.0 0.00 0 0.0 0 .01
++ .85 .00 0 .0 .85 .1 0 -0.1 0.85 0 1.6 0 .85
++ .20 -.20 0 .2 .20 .0 0 0.0 0.30 0 0.8 0 .07
++ -.20 .20 0 .2 .20 .0 0 0.0 0.30 0 0.8 0 .07
++ }
++@end verbatim
++@end deftypefn
++
++@anchor{flame2d}
++@deftypefn {Команда MGL} {} flame2d @sc{res} dat func @code{num} [@code{skip=20}]
++@ifclear UDAV
++@deftypefnx {Общая функция} @code{mglData} mglFlame2d (@code{const mglDataA &}dat, @code{const mglDataA &}func, @code{long} num, @code{long} skip=@code{20})
++@deftypefnx {Функция С} @code{HMDT} mgl_data_flame_2d (@code{HCDT} dat, @code{HCDT} func, @code{long} num, @code{long} skip)
++@end ifclear
++Находит @var{num} точек @{x[i]=res[0,i], y[i]=res[1,i]@} фрактала с использованием итерационной системы функций (IFS). Массив @var{func} задает идентификатор функции (@var{func}[0,i,j]), ее вес (@var{func}[0,i,j]) и аргументы (@var{func}[2 ... 5,i,j]). Матрица @var{dat} используется для преобразования координат для аргументов функции. Результирующее преобразование имеет вид:
++@verbatim
++xx = dat[0,i]*x[j] + dat[1,j]*y[i] + dat[4,j];
++yy = dat[2,i]*x[j] + dat[3,j]*y[i] + dat[5,j];
++x[j+1] = sum_i @var{func}[1,i,j]*@var{func}[0,i,j]_x(xx, yy; @var{func}[2,i,j],...,@var{func}[5,i,j]);
++y[j+1] = sum_i @var{func}[1,i,j]*@var{func}[0,i,j]_y(xx, yy; @var{func}[2,i,j],...,@var{func}[5,i,j]);
++@end verbatim
++Значение @code{dat[6,i]} -- весовой коэффициент для i-ой строки матрицы @var{dat}. Первые @var{skip} итераций будут опущены. Массив @var{dat} должен иметь размер по x больше или равный 7.
++Доступные идентификаторы функций: @code{mglFlame2d_linear=0, mglFlame2d_sinusoidal, mglFlame2d_spherical, mglFlame2d_swirl, mglFlame2d_horseshoe,
++ mglFlame2d_polar, mglFlame2d_handkerchief,mglFlame2d_heart, mglFlame2d_disc, mglFlame2d_spiral,
++ mglFlame2d_hyperbolic, mglFlame2d_diamond, mglFlame2d_ex, mglFlame2d_julia, mglFlame2d_bent,
++ mglFlame2d_waves, mglFlame2d_fisheye, mglFlame2d_popcorn, mglFlame2d_exponential, mglFlame2d_power,
++ mglFlame2d_cosine, mglFlame2d_rings, mglFlame2d_fan, mglFlame2d_blob, mglFlame2d_pdj,
++ mglFlame2d_fan2, mglFlame2d_rings2, mglFlame2d_eyefish, mglFlame2d_bubble, mglFlame2d_cylinder,
++ mglFlame2d_perspective, mglFlame2d_noise, mglFlame2d_juliaN, mglFlame2d_juliaScope, mglFlame2d_blur,
++ mglFlame2d_gaussian, mglFlame2d_radialBlur, mglFlame2d_pie, mglFlame2d_ngon, mglFlame2d_curl,
++ mglFlame2d_rectangles, mglFlame2d_arch, mglFlame2d_tangent, mglFlame2d_square, mglFlame2d_blade,
++ mglFlame2d_secant, mglFlame2d_rays, mglFlame2d_twintrian, mglFlame2d_cross, mglFlame2d_disc2,
++ mglFlame2d_supershape, mglFlame2d_flower, mglFlame2d_conic, mglFlame2d_parabola, mglFlame2d_bent2,
++ mglFlame2d_bipolar, mglFlame2d_boarders, mglFlame2d_butterfly, mglFlame2d_cell, mglFlame2d_cpow,
++ mglFlame2d_curve, mglFlame2d_edisc, mglFlame2d_elliptic, mglFlame2d_escher, mglFlame2d_foci,
++ mglFlame2d_lazySusan, mglFlame2d_loonie, mglFlame2d_preBlur, mglFlame2d_modulus, mglFlame2d_oscope,
++ mglFlame2d_polar2, mglFlame2d_popcorn2, mglFlame2d_scry, mglFlame2d_separation, mglFlame2d_split,
++ mglFlame2d_splits, mglFlame2d_stripes, mglFlame2d_wedge, mglFlame2d_wedgeJulia, mglFlame2d_wedgeSph,
++ mglFlame2d_whorl, mglFlame2d_waves2, mglFlame2d_exp, mglFlame2d_log, mglFlame2d_sin,
++ mglFlame2d_cos, mglFlame2d_tan, mglFlame2d_sec, mglFlame2d_csc, mglFlame2d_cot,
++ mglFlame2d_sinh, mglFlame2d_cosh, mglFlame2d_tanh, mglFlame2d_sech, mglFlame2d_csch,
++ mglFlame2d_coth, mglFlame2d_auger, mglFlame2d_flux.}
++Значение @code{dat[6,i]} -- весовой коэффициент для i-ой строки матрицы @var{dat}. Первые @var{skip} итераций будут опущены. Размеры массивов должны удовлетворять требованиям: @var{dat}.nx>=7, @var{func}.nx>=2 и @var{func}.nz=@var{dat}.ny. @sref{Fractal sample}
++@end deftypefn
++
++<<<<<<< HEAD
++@anchor{ifsfile}
++@deftypefn {Команда MGL} {} ifsfile @sc{res} 'fname' 'name' @code{num} [@code{skip=20}]
++@ifclear UDAV
++@deftypefnx {Global function} @code{mglData} mglIFSfile (@code{const char *}fname, @code{const char *}name, @code{long} num, @code{long} skip=@code{20})
++@deftypefnx {Функция С} @code{HMDT} mgl_data_ifs_file (@code{const char *}fname, @code{const char *}name, @code{long} num, @code{long} skip)
++@end ifclear
++Считывает параметры фрактала @var{name} из файла @var{fname} и находит @var{num} точек для него. Первые @var{skip} итераций будут опущены. См. также @ref{ifs2d}, @ref{ifs3d}.
++
++Файл IFS может содержать несколько записей. Каждая запись содержит имя фрактала (@samp{binary} в примере ниже) и тело в фигурных скобках @{@} с параметрами фрактала. Символ @samp{;} начинает комментарий. Если имя содержит @samp{(3D)} или @samp{(3d)}, то определен 3d IFS фрактал. Пример содержит два фрактала: @samp{binary} -- обычный 2d фрактал, и @samp{3dfern (3D)} -- 3d фрактал.
++
++@verbatim
++ binary
++ { ; comment allowed here
++ ; and here
++ .5 .0 .0 .5 -2.563477 -0.000003 .333333 ; also comment allowed here
++ .5 .0 .0 .5 2.436544 -0.000003 .333333
++ .0 -.5 .5 .0 4.873085 7.563492 .333333
++ }
++
++ 3dfern (3D) {
++ .00 .00 0 .0 .18 .0 0 0.0 0.00 0 0.0 0 .01
++ .85 .00 0 .0 .85 .1 0 -0.1 0.85 0 1.6 0 .85
++ .20 -.20 0 .2 .20 .0 0 0.0 0.30 0 0.8 0 .07
++ -.20 .20 0 .2 .20 .0 0 0.0 0.30 0 0.8 0 .07
++ }
++@end verbatim
++@end deftypefn
++=======
++
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++@c ------------------------------------------------------------------
++@external{}
++@node Evaluate expression, Special data classes, Global functions, Data processing
++@section Вычисление выражений
++@nav{}
++
++@ifset UDAV
++В MGL скриптах в качестве аргументов команд можно использовать произвольные формулы от существующих массивов данных и констант. Есть только 2 ограничения: формула не должна содержать пробелов (чтобы распознаваться как один аргумент), формула не может быть аргументом, который может быть пересоздан при выполнении скрипта.
++@end ifset
++
++@ifclear UDAV
++В MathGL есть специальные классы @code{mglExpr} и @code{mglExprC} для вычисления формул заданных строкой для действительных и комплексных чисел соответственно. Классы определены в @code{#include <mgl2/data.h>} и @code{#include <mgl2/datac.h>} соответственно. При создании класса происходит разбор формулы в древовидную структуру. А при вычислении только выполняется достаточно быстрый обход по дереву. В данный момент нет различия между верхним и нижним регистром. Если аргумент какой-либо функции лежит вне её области определения, то возвращается NaN. @xref{Textual formulas}.
++
++@deftypefn {Конструктор класса @code{mglExpr}} @code{} mglExpr (@code{const char *}expr)
++@deftypefnx {Конструктор класса @code{mglExprC}} @code{} mglExprC (@code{const char *}expr)
++@deftypefnx {Функция С} @code{HMEX} mgl_create_expr (@code{const char *}expr)
++@deftypefnx {Функция С} @code{HAEX} mgl_create_cexpr (@code{const char *}expr)
++Разбирает формулу @var{expr} и создает древовидную структуру, содержащую последовательность вызова функций и операторов для последующего быстрого вычисления формулы с помощью функций @code{Calc()} и/или @code{CalcD()}.
++@end deftypefn
++
++@deftypefn {Destructor on @code{mglExpr}} @code{} ~mglExpr ()
++@deftypefnx {Destructor on @code{mglExprC}} @code{} ~mglExprC ()
++@deftypefnx {Функция С} @code{void} mgl_delete_expr (@code{HMEX} ex)
++@deftypefnx {Функция С} @code{void} mgl_delete_cexpr (@code{HAEX} ex)
++Удаляет объект типа @code{mglExpr}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglExpr}} @code{mreal} Eval (@code{mreal} x, @code{mreal} y, @code{mreal} z)
++@deftypefnx {Метод класса @code{mglExprC}} @code{dual} Eval (@code{dual} x, @code{dual} y, @code{dual} z)
++@deftypefnx {Функция С} @code{mreal} mgl_expr_eval (@code{HMEX} ex, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++@deftypefnx {Функция С} @code{dual} mgl_cexpr_eval (@code{HAEX} ex, @code{dual} x, @code{dual} y, @code{dual} z)
++Вычисляет значение формулы для @code{'x','r'}=@var{x}, @code{'y','n'}=@var{y}, @code{'z','t'}=@var{z}, @code{'a','u'}=@var{u}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglExpr}} @code{mreal} Eval (@code{mreal} var[26])
++@deftypefnx {Метод класса @code{mglExprC}} @code{dual} Eval (@code{dual} var[26])
++@deftypefnx {Функция С} @code{mreal} mgl_expr_eval_v (@code{HMEX} ex, @code{mreal *}var)
++@deftypefnx {Функция С} @code{dual} mgl_cexpr_eval_v (@code{HMEX} ex, @code{dual *}var)
++Вычисляет значение формулы для переменных в массиве @var{var}[0,...,'z'-'a'].
++@end deftypefn
++
++
++@deftypefn {Метод класса @code{mglExpr}} @code{mreal} Diff (@code{char} dir, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++@deftypefnx {Функция С} @code{mreal} mgl_expr_diff (@code{HMEX} ex, @code{char} dir, @code{mreal} x, @code{mreal} y, @code{mreal} z)
++Вычисляет производную от формулы по переменной @var{dir} для @code{'x','r'}=@var{x}, @code{'y','n'}=@var{y}, @code{'z','t'}=@var{z}, @code{'a','u'}=@var{u}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglExpr}} @code{mreal} Diff (@code{char} dir, @code{mreal} var[26])
++@deftypefnx {Функция С} @code{mreal} mgl_expr_diff_v (@code{HMEX} ex, @code{char} dir, @code{mreal *}var)
++Вычисляет производную от формулы по переменной @var{dir} для переменных в массиве @var{var}[0,...,'z'-'a'].
++@end deftypefn
++
++@end ifclear
++
++@c ------------------------------------------------------------------
++@external{}
++@node Special data classes, , Evaluate expression, Data processing
++@section Special data classes
++@nav{}
++
++@ifset UDAV
++MGL использует специальные классы автоматически.
++@end ifset
++
++@ifclear UDAV
++Раздел описывает специальные классы данных @code{mglDataV}, @code{mglDataF}, @code{mglDataT} и @code{mglDataR}, которые могут заметно ускорить рисование и обработку данных. Классы определены в @code{#include <mgl2/data.h>}. Отмечу, что все функции рисования и обработки данных можно выполнить используя только основные классы @code{mglData} и/или @code{mglDataC}. Также специальные классы доступны только в коде на С++.
++
++@heading Класс @code{mglDataV}
++представляет переменную со значениями равнораспределенными в заданном интервале.
++@deftypefn {Конструктор @code{mglDataV}} @code{} mglDataV (@code{const mglDataV &} d)
++Конструктор копирования.
++@end deftypefn
++@deftypefn {Конструктор @code{mglDataV}} @code{} mglDataV (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1}, @code{mreal} v1=@code{0}, @code{mreal} v2=@code{NaN}, @code{char} dir=@code{'x'})
++Создает переменную "размером" @var{nx}x@var{ny}x@var{nz}, изменяющуюся от @var{v1} до @var{v2} (или постоянную при @var{v2}=@code{NaN}) вдоль направления @var{dir}.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataV}} @code{void} Create (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1})
++Задает "размеры" переменной @var{nx}x@var{ny}x@var{nz}.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataV}} @code{void} Fill (@code{mreal} x1, @code{mreal} x2=@code{NaN}, @code{char} dir=@code{'x'})
++Задает диапазон изменения переменной.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataV}} @code{void} Freq (@code{mreal} dp, @code{char} dir=@code{'x'})
++Задает переменную для частоты с шагом @var{dp}.
++@end deftypefn
++
++@heading Класс @code{mglDataF}
++представляет функцию, которая будет вызываться вместо обращения к элементам массива (как в классе @code{mglData}).
++@deftypefn {Конструктор @code{mglDataF}} @code{} mglDataF (@code{const mglDataF &} d)
++Конструктор копирования.
++@end deftypefn
++@deftypefn {Конструктор @code{mglDataF}} @code{} mglDataF (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1})
++Создает данные "размером" @var{nx}x@var{ny}x@var{nz} с нулевой функцией.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataF}} @code{void} Create (@code{long} nx=@code{1}, @code{long} ny=@code{1}, @code{long} nz=@code{1})
++Задает "размеры" данных @var{nx}x@var{ny}x@var{nz}.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataF}} @code{void} SetRanges (@code{mglPoint} p1, @code{mglPoint} p2)
++Задает диапазоны изменения внутренних переменных x,y,z.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataF}} @code{void} SetFormula (@code{const char *}func)
++Задает строку, которая будет разобрана в функцию. Это вариант более чем 10 раз медленнее в сравнении с @code{SetFunc}().
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataF}} @code{void} SetFunc (@code{mreal (*}f@code{)(mreal x,mreal y,mreal z,void *p)}, @code{void *}p=@code{NULL})
++Задает указатель на функцию, которая будет использована вместо доступа к элементам массива.
++@end deftypefn
++
++@heading Класс @code{mglDataT}
++представляет именнованную ссылку на столбец в другом массиве данных.
++@deftypefn {Конструктор @code{mglDataT}} @code{} mglDataT (@code{const mglDataT &} d)
++Конструктор копирования.
++@end deftypefn
++@deftypefn {Конструктор @code{mglDataT}} @code{} mglDataT (@code{const mglDataA &} d, @code{long} col=@code{0})
++Создает ссылку на @var{col}-ый столбец данных @var{d}.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataT}} @code{void} SetInd (@code{long} col, @code{wchar_t} name)
++@deftypefnx {Метод класса @code{mglDataT}} @code{void} SetInd (@code{long} col, @code{const wchar_t *} name)
++Задает ссылку на другой столбец того же массива данных.
++@end deftypefn
++
++
++@heading Класс @code{mglDataR}
++представляет именнованную ссылку на строку в другом массиве данных.
++@deftypefn {Конструктор @code{mglDataR}} @code{} mglDataR (@code{const mglDataR &} d)
++Конструктор копирования.
++@end deftypefn
++@deftypefn {Конструктор @code{mglDataR}} @code{} mglDataR (@code{const mglDataA &} d, @code{long} row=@code{0})
++Создает ссылку на @var{row}-ую строку данных @var{d}.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataR}} @code{void} SetInd (@code{long} row, @code{wchar_t} name)
++@deftypefnx {Метод класса @code{mglDataR}} @code{void} SetInd (@code{long} row, @code{const wchar_t *} name)
++Задает ссылку на другой столбец того же массива данных.
++@end deftypefn
++
++
++@heading Class @code{mglDataW}
++представляет часоту для FFT в виде массива данных.
++@deftypefn {Конструктор @code{mglDataW}} @code{} mglDataW (@code{const mglDataW &} d)
++Конструктор копирования.
++@end deftypefn
++@deftypefn {Конструктор @code{mglDataW}} @code{} mglDataW (@code{long} xx=@code{1}, @code{long} yy=@code{1}, @code{long} zz=@code{1}, @code{double} dp=@code{0}, @code{char} dir=@code{'x'})
++Задает размеры, направление @var{dir} и шаг @var{dp} для частоты.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataR}} @code{void} Freq (@code{double} dp, @code{char} dir=@code{'x'})
++Равномерно распределяет данные с шагом @var{dp} в направлении @var{dir}.
++@end deftypefn
++
++
++@heading Class @code{mglDataS}
++представляет std::vector в виде массива данных.
++@deftypecv {Variable} mglDataS @code{std::vector<mreal>} dat
++Собственно данные.
++@end deftypecv
++@deftypefn {Конструктор @code{mglDataS}} @code{} mglDataS (@code{const mglDataS &} d)
++Конструктор копирования.
++@end deftypefn
++@deftypefn {Конструктор @code{mglDataS}} @code{} mglDataS (@code{const std::vector<mreal> &} d)
++Копирует данные из @var{d}.
++@end deftypefn
++@deftypefn {Конструктор @code{mglDataS}} @code{} mglDataS (@code{size_t} s)
++Выделяет память для @var{s} элементов.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataS}} @code{void} reserve (@code{size_t} num)
++Резервирует место для @var{num} элементов.
++@end deftypefn
++@deftypefn {Метод класса @code{mglDataS}} @code{void} push_back (@code{double} v)
++Добавляет значение @var{v} к концу массива данных.
++@end deftypefn
++
++
++@end ifclear
++
++@external{}
Sends stop signal which terminate execution at next command.
@end deftypefn
+@deftypefn {Method on @code{mglParse}} @code{void} SetVariant (@code{int} var=@code{0})
+@deftypefnx {C function} @code{void} mgl_parser_variant (@code{HMPR} p, @code{int} var=@code{0})
+Sets variant of argument(s) separated by @samp{?} symbol to be used in further commands.
+@end deftypefn
+
+ @deftypefn {Method on @code{mglParse}} @code{void} SetVariant (@code{int} var=@code{0})
+ @deftypefnx {C function} @code{void} mgl_parser_variant (@code{HMPR} p, @code{int} var)
+ Sets variant of argument(s) separated by @samp{?} symbol to be used in further commands.
+ @end deftypefn
+
+ @deftypefn {Method on @code{mglParse}} @code{void} StartID (@code{int} id=@code{0})
+ @deftypefnx {C function} @code{void} mgl_parser_start_id (@code{HMPR} p, @code{int} id)
+ Sets id (like, line number) of first line in further script parsing.
+ @end deftypefn
@deftypefn {Method on @code{mglParse}} @code{long} GetCmdNum ()
@deftypefnx {C function} @code{long} mgl_parser_cmd_num (@code{HMPR} p)
--- /dev/null
--- /dev/null
++
++@c ------------------------------------------------------------------
++@chapter MGL scripts
++@nav{}
++
++MathGL library supports the simplest scripts for data handling and plotting. These scripts can be used independently (with the help of UDAV, mglconv, mglview programs and others
++@ifclear UDAV
++, @pxref{Utilities}) or in the frame of the library using.
++@end ifclear
++
++@menu
++* MGL definition::
++* Program flow commands::
++* LaTeX package::
++@ifclear UDAV
++* mglParse class::
++@end ifclear
++@end menu
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node MGL definition, Program flow commands, , MGL scripts
++@section MGL definition
++@nav{}
++
++MGL script language is rather simple. Each string is a command. First word of string is the name of command. Other words are command arguments. Words are separated from each other by space or tabulation symbol. The upper or lower case of words is important, i.e. variables @var{a} and @var{A} are different variables. Symbol @samp{#} starts the comment (all characters after # will be ignored). The exception is situation when @samp{#} is a part of some string. Also options can be specified after symbol @samp{;} (@pxref{Command options}). Symbol @samp{:} starts new command (like new line character) if it is not placed inside a string or inside brackets.
++
++If string contain references to external parameters (substrings @samp{$0}, @samp{$1} ... @samp{$9}) or definitions (substrings @samp{$a}, @samp{$b} ... @samp{$z}) then before execution the values of parameter/definition will be substituted instead of reference. It allows to use the same MGL script for different parameters (filenames, paths, condition and so on).
++
++Argument can be a string, a variable (data arrays) or a number (scalars).
++@itemize @bullet
++@item
++The string is any symbols between ordinary marks @samp{'}. Long strings can be concatenated from several lines by @samp{\} symbol. I.e. the string @samp{'a +\<br> b'} will give string @samp{'a + b'} (here @samp{<br>} is newline). There are several operations which can be performed with string:
++@itemize @bullet
++@item Concatenation of strings and numbers using @samp{,} with out spaces (for example, @samp{'max(u)=',u.max,' a.u.'} or @samp{'u=',!(1+i2)} for complex numbers);
++@item Getting n-th symbol of the string using @samp{[]} (for example, @samp{'abc'[1]} will give @code{'b'});
++@item Adding value to the last character of the string using @samp{+} (for example, @samp{'abc'+3} will give @code{'abf'}).
++@end itemize
++
++@item
++Usually variable have a name which is arbitrary combination of symbols (except spaces and @samp{'}) started from a letter. Note, you can start an expression with @samp{!} symbol if you want to use complex values. For example, the code @code{new x 100 'x':copy !b !exp(1i*x)} will create real valued data @var{x} and complex data @var{b}, which is equal to @math{exp(I*x)}, where @math{I^2=-1}. A temporary array can be used as variable too:
++@itemize @bullet
++@item
++sub-arrays (like in @ref{subdata} command) as command argument. For example, @code{a(1)} or @code{a(1,:)} or @code{a(1,:,:)} is second row, @code{a(:,2)} or @code{a(:,2,:)} is third column, @code{a(:,:,0)} is first slice and so on. Also you can extract a part of array from m-th to n-th element by code @code{a(m:n,:,:)} or just @code{a(m:n)}.
++
++@item
++any column combinations defined by formulas, like @code{a('n*w^2/exp(t)')} if names for data columns was specified (by @ref{idset} command or in the file at string started with @code{##}).
++
++@item
++any expression (without spaces) of existed variables produce temporary variable. For example, @samp{sqrt(dat(:,5)+1)} will produce temporary variable with data values equal to @code{tmp[i,j] = sqrt(dat[i,5,j]+1)}.
++
++@item
++temporary variable of higher dimensions by help of []. For example, @samp{[1,2,3]} will produce a temporary vector of 3 elements @{1, 2, 3@}; @samp{[[11,12],[21,22]]} will produce matrix 2*2 and so on. Here you can join even an arrays of the same dimensions by construction like @samp{[v1,v2,...,vn]}.
++
++@item
++result of code for making new data (@pxref{Make another data}) inside @{@}. For example, @samp{@{sum dat 'x'@}} produce temporary variable which contain result of summation of @var{dat} along direction 'x'. This is the same array @var{tmp} as produced by command @samp{sum tmp dat 'x'}. You can use nested constructions, like @samp{@{sum @{max dat 'z'@} 'x'@}}.
++@end itemize
++Temporary variables can not be used as 1st argument for commands which create (return) the data (like @samp{new}, @samp{read}, @samp{hist} and so on).
++
++@item
++Special names @code{nan=#QNAN, inf=INFINITY, rnd=random value, pi=3.1415926..., on=1, off=0, all=-1, :=-1}, variables with suffixes (@pxref{Data information}), names defined by @ref{define} command, time values (in format "hh-mm-ss_DD.MM.YYYY", "hh-mm-ss" or "DD.MM.YYYY") are treated as number. Also results of formulas with sizes 1x1x1 are treated as number (for example, @samp{pi/dat.nx}).
++@end itemize
++Before the first using all variables must be defined with the help of commands, like, @ref{new}, @ref{var}, @ref{list}, @ref{copy}, @ref{read}, @ref{hist}, @ref{sum} and so on (see sections @ref{Data constructor}, @ref{Data filling} and @ref{Make another data}).
++
++Command may have several set of possible arguments (for example, @code{plot ydat} and @code{plot xdat ydat}). All command arguments for a selected set must be specified. However, some arguments can have default values. These argument are printed in [], like @code{text ydat ['stl'='']} or @code{text x y 'txt' ['fnt'='' size=-1]}. At this, the record @code{[arg1 arg2 arg3 ...]} means @code{[arg1 [arg2 [arg3 ...]]]}, i.e. you can omit only tailing arguments if you agree with its default values. For example, @code{text x y 'txt' '' 1} or @code{text x y 'txt' ''} is correct, but @code{text x y 'txt' 1} is incorrect (argument @code{'fnt'} is missed).
++
++You can provide several variants of arguments for a command by using @samp{?} symbol for separating them. The actual argument being used is set by @ref{variant}. At this, the last argument is used if the value of @ref{variant} is large than the number of provided variants. By default the first argument is used (i.e. as for @code{variant 0}). For example, the first plot will be drawn by blue (default is the first argument @samp{b}), but the plot after @code{variant 1} will be drawn by red dash (the second is @samp{r|}):
++@verbatim
++fplot 'x' 'b'?'r'
++variant 1
++fplot 'x^3' 'b'?'r|'
++@end verbatim
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node Program flow commands, LaTeX package, MGL definition, MGL scripts
++@section Program flow commands
++@nav{}
++
++Below I show commands to control program flow, like, conditions, loops, define script arguments and so on. Other commands can be found in chapters @ref{MathGL core} and @ref{Data processing}. Note, that some of program flow commands (like @ref{define}, @ref{ask}, @ref{call}, @ref{for}, @ref{func}) should be placed alone in the string.
++
++@cindex chdir
++@anchor{chdir}
++@deftypefn {MGL command} {} chdir 'path'
++Changes the current directory to @var{path}.
++@end deftypefn
++
++@cindex ask
++@anchor{ask}
++@deftypefn {MGL command} {} ask $N 'question'
++Sets @var{N}-th script argument to answer which give the user on the @var{question}. Usually this show dialog with question where user can enter some text as answer. Here @var{N} is digit (0...9) or alpha (a...z).
++@end deftypefn
++
++@cindex define
++@anchor{define}
++@deftypefn {MGL command} {} define $N smth
++Sets @var{N}-th script argument to @var{smth}. Note, that @var{smth} is used as is (with @samp{'} symbols if present). Here @var{N} is digit (0...9) or alpha (a...z).
++@end deftypefn
++@deftypefn {MGL command} {} define name smth
++Create scalar variable @code{name} which have the numeric value of @code{smth}. Later you can use this variable as usual number.
++@end deftypefn
++@cindex defchr
++@anchor{defchr}
++@deftypefn {MGL command} {} defchr $N smth
++Sets @var{N}-th script argument to character with value evaluated from @var{smth}. Here @var{N} is digit (0...9) or alpha (a...z).
++@end deftypefn
++@cindex defnum
++@anchor{defnum}
++@deftypefn {MGL command} {} defnum $N smth
++Sets @var{N}-th script argument to number with value evaluated from @var{smth}. Here @var{N} is digit (0...9) or alpha (a...z).
++@end deftypefn
++
++@comment @cindex defpal
++@comment @anchor{defpal}
++@comment @deftypefn {MGL command} {} defpal $N smth
++@comment Sets @var{N}-th script argument to palette character at position evaluated from @var{smth}. Here @var{N} is digit (0...9) or alpha (a...z).
++@comment @end deftypefn
++
++@cindex call
++@anchor{call}
++@deftypefn {MGL command} {} call 'funcname' [ARG1 ARG2 ... ARG9]
++Executes function @var{fname} (or script if function is not found). Optional arguments will be passed to functions. See also @ref{func}.
++@end deftypefn
++@cindex func
++@anchor{func}
++@deftypefn {MGL command} {} func 'funcname' [narg=0]
++Define the function @var{fname} and number of required arguments. The arguments will be placed in script parameters $1, $2, ... $9. Note, script execution is stopped at @code{func} keyword, similarly to @ref{stop} command. See also @ref{return}.
++@end deftypefn
++@cindex return
++@anchor{return}
++@deftypefn {MGL command} {} return
++Return from the function. See also @ref{func}.
++@end deftypefn
++
++@cindex load
++@anchor{load}
++@deftypefn {MGL command} {} load 'filename'
++Load additional MGL command from external module (DLL or .so), located in file @var{filename}. This module have to contain array with name @code{mgl_cmd_extra} of type @code{mglCommand}, which describe provided commands.
++@end deftypefn
++
++
++@cindex if
++@anchor{if}
++@deftypefn {MGL command} {} if dat 'cond'
++Starts block which will be executed if @var{dat} satisfy to @var{cond}.
++@end deftypefn
++@deftypefn {MGL command} {} if @code{val}
++Starts block which will be executed if @code{val} is nonzero.
++@end deftypefn
++@cindex elseif
++@anchor{elseif}
++@deftypefn {MGL command} {} elseif dat 'cond'
++Starts block which will be executed if previous @code{if} or @code{elseif} is false and @var{dat} satisfy to @var{cond}.
++@end deftypefn
++@deftypefn {MGL command} {} elseif @code{val}
++Starts block which will be executed if previous @code{if} or @code{elseif} is false and @code{val} is nonzero.
++@end deftypefn
++@cindex else
++@anchor{else}
++@deftypefn {MGL command} {} else
++Starts block which will be executed if previous @code{if} or @code{elseif} is false.
++@end deftypefn
++@cindex endif
++@anchor{endif}
++@deftypefn {MGL command} {} endif
++Finishes @code{if/elseif/else} block.
++@end deftypefn
++
++@cindex for
++@anchor{for}
++@deftypefn {MGL command} {} for $N @code{v1 v2 [dv=1]}
++Starts cycle with $@var{N}-th argument changing from @var{v1} to @var{v2} with the step @var{dv}. Here @var{N} is digit (0...9) or alpha (a...z).
++@end deftypefn
++@deftypefn {MGL command} {} for $N dat
++Starts cycle with $@var{N}-th argument changing for @var{dat} values. Here @var{N} is digit (0...9) or alpha (a...z).
++@end deftypefn
++@cindex next
++@anchor{next}
++@deftypefn {MGL command} {} next
++Finishes @code{for} cycle.
++@end deftypefn
++
++@cindex once
++@anchor{once}
++@deftypefn {MGL command} {} once @code{val}
++The code between @code{once on} and @code{once off} will be executed only once. Useful for large data manipulation in programs like UDAV.
++@end deftypefn
++@cindex stop
++@anchor{stop}
++@deftypefn {MGL command} {} stop
++Terminate execution.
++@end deftypefn
++
++@cindex variant
++@anchor{variant}
++@deftypefn {MGL command} {} variant @code{val}
++Set variant of argument(s) separated by @samp{?} symbol to be used in further commands.
++@end deftypefn
++
++
++@cindex rkstep
++@anchor{rkstep}
++@deftypefn {MGL command} {} rkstep eq1;... var1;... [@code{dt=1}]
++Make one step for ordinary differential equation(s) @{var1' = eq1, ... @} with time-step @var{dt}. Here variable(s) @samp{var1}, ... are the ones, defined in MGL script previously. The Runge-Kutta 4-th order method is used for solution.
++@end deftypefn
++
++@c ------------------------------------------------------------------
++@external{}
++@ifclear UDAV
++@node LaTeX package, mglParse class, Program flow commands, MGL scripts
++@end ifclear
++@ifset UDAV
++@node LaTeX package, , Program flow commands, MGL scripts
++@end ifset
++@section LaTeX package
++@nav{}
++
++There is LaTeX package @code{mgltex} (was made by Diego Sejas Viscarra) which allow one to make figures directly from MGL script located in LaTeX file.
++
++For using this package you need to specify @code{--shell-escape} option for @emph{latex/pdflatex} or manually run @emph{mglconv} tool with produced MGL scripts for generation of images. Don't forgot to run @emph{latex/pdflatex} second time to insert generated images into the output document. Also you need to run @emph{pdflatex} third time to update converted from EPS images if you are using vector EPS output (default).
++
++The package may have following options: @code{draft}, @code{final} --- the same as in the @emph{graphicx} package; @code{on}, @code{off} --- to activate/deactivate the creation of scripts and graphics; @code{comments}, @code{nocomments} --- to make visible/invisible commentaries contained inside @code{mglcomment} environments; @code{jpg}, @code{jpeg}, @code{png} --- to export graphics as JPEG/PNG images; @code{eps}, @code{epsz} --- to export to uncompressed/compressed EPS format as primitives; @code{bps}, @code{bpsz} --- to export to uncompressed/compressed EPS format as bitmap (doesn't work with @emph{pdflatex}); @code{pdf} --- to export to 3D PDF; @code{tex} --- to export to @emph{LaTeX/tikz} document.
++
++The package defines the following environments:
++@table @samp
++@item mgl
++ It writes its contents to a general script which has the same name as the LaTeX document, but its extension is @emph{.mgl}. The code in this environment is compiled and the image produced is included. It takes exactly the same optional arguments as the @code{\includegraphics} command, plus an additional argument @var{imgext}, which specifies the extension to save the image.
++
++An example of usage of @samp{mgl} environment would be:
++@verbatim
++\begin{mglfunc}{prepare2d}
++ new a 50 40 '0.6*sin(pi*(x+1))*sin(1.5*pi*(y+1))+0.4*cos(0.75*pi*(x+1)*(y+1))'
++ new b 50 40 '0.6*cos(pi*(x+1))*cos(1.5*pi*(y+1))+0.4*cos(0.75*pi*(x+1)*(y+1))'
++\end{mglfunc}
++
++\begin{figure}[!ht]
++ \centering
++ \begin{mgl}[width=0.85\textwidth,height=7.5cm]
++ fog 0.5
++ call 'prepare2d'
++ subplot 2 2 0 : title 'Surf plot (default)' : rotate 50 60 : light on : box : surf a
++
++ subplot 2 2 1 : title '"\#" style; meshnum 10' : rotate 50 60 : box
++ surf a '#'; meshnum 10
++
++ subplot 2 2 2 : title 'Mesh plot' : rotate 50 60 : box
++ mesh a
++
++ new x 50 40 '0.8*sin(pi*x)*sin(pi*(y+1)/2)'
++ new y 50 40 '0.8*cos(pi*x)*sin(pi*(y+1)/2)'
++ new z 50 40 '0.8*cos(pi*(y+1)/2)'
++ subplot 2 2 3 : title 'parametric form' : rotate 50 60 : box
++ surf x y z 'BbwrR'
++ \end{mgl}
++\end{figure}
++@end verbatim
++
++@item mgladdon
++ It adds its contents to the general script, without producing any image.
++@item mglcode
++ Is exactly the same as @samp{mgl}, but it writes its contents verbatim to its own file, whose name is specified as a mandatory argument.
++@item mglscript
++ Is exactly the same as @samp{mglcode}, but it doesn't produce any image, nor accepts optional arguments. It is useful, for example, to create a MGL script, which can later be post processed by another package like "listings".
++@item mglblock
++ It writes its contents verbatim to a file, specified as a mandatory argument, and to the LaTeX document, and numerates each line of code.
++
++@c This last three environments will test if the user is overwriting some file, and will issue a warning in that case.
++@item mglverbatim
++ Exactly the same as @samp{mglblock}, but it doesn't write to a file. This environment doesn't have arguments.
++@item mglfunc
++ Is used to define MGL functions. It takes one mandatory argument, which is the name of the function, plus one additional argument, which specifies the number of arguments of the function. The environment needs to contain only the body of the function, since the first and last lines are appended automatically, and the resulting code is written at the end of the general script, after the @ref{stop} command, which is also written automatically. The warning is produced if 2 or more function with the same name is defined.
++@item mglcomment
++ Is used to contain multiline commentaries. This commentaries will be visible/invisible in the output document, depending on the use of the package options @code{comments} and @code{nocomments} (see above), or the @code{\mglcomments} and @code{\mglnocomments} commands (see bellow).
++@item mglsetup
++ If many scripts with the same code are to be written, the repetitive code can be written inside this environment only once, then this code will be used automatically every time the @samp{\mglplot} command is used (see below). It takes one optional argument, which is a name to be associated to the corresponding contents of the environment; this name can be passed to the @samp{\mglplot} command to use the corresponding block of code automatically (see below).
++@end table
++
++The package also defines the following commands:
++@table @samp
++@item \mglplot
++ It takes one mandatory argument, which is MGL instructions separated by the symbol @samp{:} this argument can be more than one line long. It takes the same optional arguments as the @samp{mgl} environment, plus an additional argument @var{setup}, which indicates the name associated to a block of code inside a @samp{mglsetup} environment. The code inside the mandatory argument will be appended to the block of code specified, and the resulting code will be written to the general script.
++
++An example of usage of @samp{\mglplot} command would be:
++@verbatim
++\begin{mglsetup}
++ box '@{W9}' : axis
++\end{mglsetup}
++\begin{mglsetup}[2d]
++ box : axis
++ grid 'xy' ';k'
++\end{mglsetup}
++\begin{mglsetup}[3d]
++ rotate 50 60
++ box : axis : grid 'xyz' ';k'
++\end{mglsetup}
++\begin{figure}[!ht]
++ \centering
++ \mglplot[scale=0.5]{new a 200 'sin(pi*x)' : plot a '2B'}
++\end{figure}
++\begin{figure}[!ht]
++ \centering
++ \mglplot[scale=0.5,setup=2d]{
++ fplot 'sin(pi*x)' '2B' :
++ fplot 'cos(pi*x^2)' '2R'
++ }
++\end{figure}
++\begin{figure}[!ht]
++ \centering
++ \mglplot[setup=3d]{fsurf 'sin(pi*x)+cos(pi*y)'}
++\end{figure}
++@end verbatim
++
++@item \mglgraphics
++ This command takes the same optional arguments as the @samp{mgl} environment, and one mandatory argument, which is the name of a MGL script. This command will compile the corresponding script and include the resulting image. It is useful when you have a script outside the LaTeX document, and you want to include the image, but you don't want to type the script again.
++@item \mglinclude
++ This is like @samp{\mglgraphics} but, instead of creating/including the corresponding image, it writes the contents of the MGL script to the LaTeX document, and numerates the lines.
++@item \mgldir
++ This command can be used in the preamble of the document to specify a directory where LaTeX will save the MGL scripts and generate the corresponding images. This directory is also where @samp{\mglgraphics} and @samp{\mglinclude} will look for scripts.
++@item \mglquality
++ Adjust the quality of the MGL graphics produced similarly to @ref{quality}.
++@item \mgltexon, \mgltexoff
++ Activate/deactivate the creation of MGL scripts and images. Notice these commands have local behavior in the sense that their effect is from the point they are called on.
++@item \mglcomment, \mglnocomment
++ Make visible/invisible the contents of the @code{mglcomment} environments. These commands have local effect too.
++@item \mglTeX
++ It just pretty prints the name of the package.
++@end table
++
++As an additional feature, when an image is not found or cannot be included, instead of issuing an error, @code{mgltex} prints a box with the word @samp{MGL image not found} in the LaTeX document.
++
++
++
++@ifclear UDAV
++@c ------------------------------------------------------------------
++@external{}
++@node mglParse class, , LaTeX package, MGL scripts
++@section mglParse class
++@nav{}
++@cindex mglParse
++
++Class for parsing and executing MGL script. This class is defined in @code{#include <mgl2/mgl.h>}.
++
++The main function of mglParse class is @code{Execute()}. Exactly this function parses and executes the script string-by-string. Also there are subservient functions for the finding and creation of a variable (object derived from @code{mglDataA}). These functions can be useful for displaying values of variables (arrays) in some external object (like, window) or for providing access to internal data. Function @code{AllowSetSize()} allows one to prevent changing the size of the picture inside the script (forbids the MGL command @code{setsize}).
++
++@c Note an important feature -- if user defines function @var{func} in variable then it will be called before the destroying of this variable (@pxref{mglVar class}).
++
++@deftypefn {Constructor on @code{mglParse}} @code{} mglParse (@code{bool} setsize=@code{false})
++@deftypefnx {Constructor on @code{mglParse}} @code{} mglParse (@code{HMPR} pr)
++@deftypefnx {Constructor on @code{mglParse}} @code{} mglParse (@code{mglParse &}pr)
++@deftypefnx {C function} @code{HMPR} mgl_create_parser ()
++Constructor initializes all values with zero and set @var{AllowSetSize} value.
++@end deftypefn
++
++@deftypefn {Destructor on @code{mglParse}} @code{} ~mglParse ()
++@deftypefnx {C function} @code{void} mgl_delete_parser (@code{HMPR} p)
++Destructor delete parser
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{HMPR} Self ()
++Returns the pointer to internal object of type @code{HMPR}.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{const char *}text)
++@deftypefnx{Method on @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{const wchar_t *}text)
++@deftypefnx {C function} @code{void} mgl_parse_text (@code{HMGL} gr, @code{HMPR} p, @code{const char *}text)
++@deftypefnx {C function} @code{void} mgl_parse_textw (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}text)
++Main function in the class. Function parse and execute line-by-line MGL script in array @var{text}. Lines are separated by newline symbol @samp{\n} as usual.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{FILE *}fp, @code{bool} print=@code{false})
++@deftypefnx {C function} @code{void} mgl_parse_file (@code{HMGL} gr, @code{HMPR} p, @code{FILE *}fp, @code{int} print)
++The same as previous but read script from the file @var{fp}. If @var{print}=@code{true} then all warnings and information will be printed in stdout.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{int} Parse (@code{mglGraph *}gr, @code{const char *}str, @code{long} pos=@code{0})
++@deftypefnx {Method on @code{mglParse}} @code{int} Parse (@code{mglGraph *}gr, @code{const wchar_t *}str, @code{long} pos=@code{0})
++@deftypefnx {C function} @code{int} mgl_parse_line (@code{HMGL} gr, @code{HMPR} p, @code{const char *}str, @code{int} pos)
++@deftypefnx {C function} @code{int} mgl_parse_linew (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}str, @code{int} pos)
++Function parses the string @var{str} and executes it by using @var{gr} as a graphics plotter. Returns the value depending on an error presence in the string @var{str}: 0 -- no error, 1 -- wrong command argument(s), 2 -- unknown command, 3 -- string is too long, 4 -- strings is not closed. Optional argument @var{pos} allows to save the string position in the document (or file) for using @code{for|next} command.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{mglData} Calc (@code{const char *}formula)
++@deftypefnx {Method on @code{mglParse}} @code{mglData} Calc (@code{const wchar_t *}formula)
++@deftypefnx {C function} @code{HMDT} mgl_parser_calc (@code{HMPR} p, @code{const char *}formula)
++@deftypefnx {C function} @code{HMDT} mgl_parser_calcw (@code{HMPR} p, @code{const wchar_t *}formula)
++Function parses the string @var{formula} and return resulting data array. In difference to @code{AddVar()} or @code{FindVar()}, it is usual data array which should be deleted after usage.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{mglDataC} CalcComplex (@code{const char *}formula)
++@deftypefnx {Method on @code{mglParse}} @code{mglDataC} CalcComplex (@code{const wchar_t *}formula)
++@deftypefnx {C function} @code{HADT} mgl_parser_calc_complex (@code{HMPR} p, @code{const char *}formula)
++@deftypefnx {C function} @code{HADT} mgl_parser_calc_complexw (@code{HMPR} p, @code{const wchar_t *}formula)
++Function parses the string @var{formula} and return resulting data array with complex values. In difference to @code{AddVar()} or @code{FindVar()}, it is usual data array which should be deleted after usage.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{void} AddParam (@code{int} n, @code{const char *}str)
++@deftypefnx {Method on @code{mglParse}} @code{void} AddParam (@code{int} n, @code{const wchar_t *}str)
++@deftypefnx {C function} @code{void} mgl_parser_add_param (@code{HMPR} p, @code{int} id, @code{const char *}val)
++@deftypefnx {C function} @code{void} mgl_parser_add_paramw (@code{HMPR} p, @code{int} id, @code{const wchar_t *}val)
++Function set the value of @var{n}-th parameter as string @var{str} (@var{n}=0, 1 ... 'z'-'a'+10). String @var{str} shouldn't contain @samp{$} symbol.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{mglVar *} FindVar (@code{const char *}name)
++@deftypefnx {Method on @code{mglParse}} @code{mglVar *} FindVar (@code{const wchar_t *}name)
++@deftypefnx {C function} @code{HMDT} mgl_parser_find_var (@code{HMPR} p, @code{const char *}name)
++@deftypefnx {C function} @code{HMDT} mgl_parser_find_varw (@code{HMPR} p, @code{const wchar_t *}name)
++Function returns the pointer to variable with name @var{name} or zero if variable is absent. Use this function to put external data array to the script or get the data from the script. You must @strong{not delete} obtained data arrays!
++@end deftypefn
++@deftypefn {Method on @code{mglParse}} @code{mglVar *} AddVar (@code{const char *}name)
++@deftypefnx {Method on @code{mglParse}} @code{mglVar *} AddVar (@code{const wchar_t *}name)
++@deftypefnx {C function} @code{HMDT} mgl_parser_add_var (@code{HMPR} p, @code{const char *}name)
++@deftypefnx {C function} @code{HMDT} mgl_parser_add_varw (@code{HMPR} p, @code{const wchar_t *}name)
++Function returns the pointer to variable with name @var{name}. If variable is absent then new variable is created with name @var{name}. Use this function to put external data array to the script or get the data from the script. You must @strong{not delete} obtained data arrays!
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{void} OpenHDF (@code{const char *}fname)
++@deftypefnx {C function} @code{void} mgl_parser_openhdf (@code{HMPR} pr, @code{const char *}fname)
++Reads all data array from HDF5 file @var{fname} and create MGL variables with names of data names in HDF file. Complex variables will be created if data name starts with @samp{!}.
++@end deftypefn
++
++@deftypefn{Method on @code{mglParse} (C++)} @code{void} DeleteVar (@code{const char *}name)
++@deftypefnx{Method on @code{mglParse} (C++)} @code{void} DeleteVar (@code{const wchar_t *}name)
++@deftypefnx {C function} @code{void} mgl_parser_del_var (@code{HMPR} p, @code{const char *}name)
++@deftypefnx {C function} @code{void} mgl_parser_del_varw (@code{HMPR} p, @code{const wchar_t *}name)
++Function delete the variable with given @var{name}.
++@end deftypefn
++
++@deftypefn{Method on @code{mglParse} (C++)} @code{void} DeleteAll ()
++@deftypefnx {C function} @code{void} mgl_parser_del_all (@code{HMPR} p)
++Function delete all variables and reset list of commands to default one in this parser.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{void} RestoreOnce ()
++@deftypefnx {C function} @code{void} mgl_parser_restore_once (@code{HMPR} p)
++Restore Once flag.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{void} AllowSetSize (@code{bool} a)
++@deftypefnx {C function} @code{void} mgl_parser_allow_setsize (@code{HMPR} p, @code{int} a)
++Allow to parse @ref{setsize} command or not.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{void} AllowFileIO (@code{bool} a)
++@deftypefnx {C function} @code{void} mgl_parser_allow_file_io (@code{HMPR} p, @code{int} a)
++Allow reading/saving files or not.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{void} AllowDllCall (@code{bool} a)
++@deftypefnx {C function} @code{void} mgl_parser_allow_dll_call (@code{HMPR} p, @code{int} a)
++Allow to parse @ref{load} command or not.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{void} Stop ()
++@deftypefnx {C function} @code{void} mgl_parser_stop (@code{HMPR} p)
++Sends stop signal which terminate execution at next command.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{void} SetVariant (@code{int} var=@code{0})
++<<<<<<< HEAD
++@deftypefnx {C function} @code{void} mgl_parser_variant (@code{HMPR} p, @code{int} var=@code{0})
++Sets variant of argument(s) separated by @samp{?} symbol to be used in further commands.
++@end deftypefn
++
++=======
++@deftypefnx {C function} @code{void} mgl_parser_variant (@code{HMPR} p, @code{int} var)
++Sets variant of argument(s) separated by @samp{?} symbol to be used in further commands.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{void} StartID (@code{int} id=@code{0})
++@deftypefnx {C function} @code{void} mgl_parser_start_id (@code{HMPR} p, @code{int} id)
++Sets id (like, line number) of first line in further script parsing.
++@end deftypefn
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++@deftypefn {Method on @code{mglParse}} @code{long} GetCmdNum ()
++@deftypefnx {C function} @code{long} mgl_parser_cmd_num (@code{HMPR} p)
++Return the number of registered MGL commands.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{const char *} GetCmdName (@code{long} id)
++@deftypefnx {C function} @code{const char *} mgl_parser_cmd_name (@code{HMPR} p, @code{long} id)
++Return the name of command with given @var{id}.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{int} CmdType (@code{const char *}name)
++@deftypefnx {C function} @code{int} mgl_parser_cmd_type (@code{HMPR} p, @code{const char *}name)
++Return the type of MGL command @var{name}. Type of commands are: 0 -- not the command, 1 - data plot, 2 - other plot, 3 - setup, 4 - data handle, 5 - data create, 6 - subplot, 7 - program, 8 - 1d plot, 9 - 2d plot, 10 - 3d plot, 11 - dd plot, 12 - vector plot, 13 - axis, 14 - primitives, 15 - axis setup, 16 - text/legend, 17 - data transform.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{const char *} CmdFormat (@code{const char *}name)
++@deftypefnx {C function} @code{const char *} mgl_parser_cmd_frmt (@code{HMPR} p, @code{const char *}name)
++Return the format of arguments for MGL command @var{name}.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{const char *} CmdDesc (@code{const char *}name)
++@deftypefnx {C function} @code{const char *} mgl_parser_cmd_desc (@code{HMPR} p, @code{const char *}name)
++Return the description of MGL command @var{name}.
++@end deftypefn
++
++@deftypefn {Method on @code{mglParse}} @code{void} RK_Step (@code{const char *}eqs, @code{const char *}vars, @code{mreal} dt=@code{1})
++@deftypefnx {Method on @code{mglParse}} @code{void} RK_Step (@code{const wchar_t *}eqs, @code{const wchar_t *}vars, @code{mreal} dt=@code{1})
++@deftypefnx {C function} @code{void} mgl_rk_step (@code{HMPR} p, @code{const char *}eqs, @code{const char *}vars, @code{mreal} dt)
++@deftypefnx {C function} @code{void} mgl_rk_step_w (@code{HMPR} p, @code{const wchar_t *}eqs, @code{const wchar_t *}vars, @code{mreal} dt)
++Make one step for ordinary differential equation(s) @{var1' = eq1, ... @} with time-step @var{dt}. Here strings @var{eqs} and @var{vars} contain the equations and variable names separated by symbol @samp{;}. The variable(s) @samp{var1}, ... are the ones, defined in MGL script previously. The Runge-Kutta 4-th order method is used.
++@end deftypefn
++
++@end ifclear
++
++@external{}
++
--- /dev/null
--- /dev/null
++
++@c ------------------------------------------------------------------
++@chapter Скрипты MGL
++@nav{}
++
++MathGL имеет встроенный скриптовый язык MGL для обработки и отображения данных. Скрипты MGL могут быть выполнены независимо (с помощью программ UDAV, mglconv, mglview и др.
++@ifclear UDAV
++, см. @ref{Utilities}) или с использованием вызовов библиотеки.
++@end ifclear
++
++@menu
++* MGL definition::
++* Program flow commands::
++* LaTeX package::
++@ifclear UDAV
++* mglParse class::
++@end ifclear
++@end menu
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node MGL definition, Program flow commands, , MGL scripts
++@section Основы MGL
++@nav{}
++
++Язык MGL достаточно простой. Каждая строка -- отдельная команда. Первое слово -- имя команды, а все остальные ее аргументы. Команда может иметь до 1000 аргументов (по крайней мере сейчас). Слова разделяются одно от другого пробелом или символом табуляции. Различий между верхним и нижним индексом нет, т.е. переменные @var{a} и @var{A} идентичны. Символ @samp{#} начинает комментарий -- все символы после него игнорируются до конца строки. Исключением является случай, когда @samp{#} входит в строку. Опции команды указываются после символа @samp{;} (@pxref{Command options}). Символ @samp{:} начинает новую команду (подобно переводу строки) если он расположен не внутри скобок или строки.
++
++Если строка содержит ссылки на внешние параметры (@samp{$0}, @samp{$1} ... @samp{$9}) или макроопределения (@samp{$a}, @samp{$b} ... @samp{$z}), то текущие значения параметров/макроопределений подставляются в строку вместо ссылки до выполнением команды. Это позволяет использовать один и тот же скрипт при различных входных параметрах командной строки или вводить макроопределения по ходу исполнения команд скрипта.
++
++Аргументы команды могут быть строками, переменными или числами.
++@itemize @bullet
++@item
++Строка -- произвольный набор символов между метками @samp{'}. Длинные строки могут быть соединены из нескольких линий файла символом @samp{\}. Т.е. строки файла @samp{'a +'\<br>' b'} дадут строку @samp{'a + b'} (здесь @samp{<br>} -- перевод строки). MGL поддерживает несколько операций над строками:
++@itemize @bullet
++@item Соединение строк и чисел, используя @samp{,} без пробелов (например, @samp{'max(u)=',u.max,' a.u.'} или @samp{'u=',!(1+i2)} для комплексных чисел);
++@item Получение n-го символа строки, используя @samp{[]} (например, @samp{'abc'[1]} даст @code{'b'});
++@item Инкремент последнего символа строки, используя @samp{+} (например, @samp{'abc'+3} даст @code{'abf'}).
++@end itemize
++
++@item
++Обычно переменная имеет имя, состоящее из букв и чисел (должно начинаться с буквы и не быть длиннее 64 символов). Если выражение или переменная начинается с символа @samp{!}, то будут использованы комплексные значения. Например, код @code{new x 100 'x':copy !b !exp(1i*x)} создаст массив действительных чисел @var{x} и массив комплексных чисел @var{b}, который будет равен @math{exp(I*x)}, где @math{I^2=-1}.
++В качестве переменной можно использовать также и временные массивы, включающие в себя:
++@itemize @bullet
++@item
++срезы (``подмассивы'') массивов данных (подобно команде @ref{subdata}). Например, @code{a(1)} или @code{a(1,:)} или @code{a(1,:,:)} -- вторая строка массива @var{a}, @code{a(:,2)} или @code{a(:,2,:)} -- третий столбец, @code{a(:,:,0)} -- первый срез и т.д. Также можно выделить часть массива с m-го по n-ый элемент @code{a(m:n,:,:)} или просто @code{a(m:n)}.
++
++@item
++произвольные комбинации столбцов данных (например, @code{a('n*w^2/exp(t)')}), если столбцы данных были именованы командой @ref{idset} или в файле данных (в строке начинающейся с @code{##}).
++
++@item
++произвольное выражение из существующих переменных и констант. Например, @samp{sqrt(dat(:,5)+1)} даст временный массив данных с элементами равными @code{tmp[i,j] = sqrt(dat[i,5,j]+1)}.
++
++@item
++массивы с элементами заданными в квадратных скобках [], разделенные @samp{,}. При этом внутри выражения не должно быть пробелов! Например, @samp{[1,2,3]} даст временный массив из 3 элементов @{1, 2, 3@}; @samp{[[11,12],[21,22]]} даст матрицу 2*2 и т.д. Элементами такой конструкции могут быть и массивы если их размерности одинаковые, например @samp{[v1,v2,...,vn]}.
++
++@item
++результат команд построения новых данных (@pxref{Make another data}), если они заключены в фигурные скобки @{@}. Например, @samp{@{sum dat 'x'@}} даст временный массив, который есть результат суммирования @var{dat} вдоль 'x'. Это такой же массив как и @var{tmp}, полученный командой @samp{sum tmp dat 'x'}. При этом можно использовать вложенные конструкции, например @samp{@{sum @{max dat 'z'@} 'x'@}}.
++@end itemize
++Временные массивы не могут стоять в качестве первого аргумента команд, создающих массивы (например, @samp{new}, @samp{read}, @samp{hist} и т.д.).
++
++@item
++К скалярным переменным, кроме собственно чисел, относятся: специальные переменные @code{nan=#QNAN, inf=бесконечность, rnd=случайное число, pi=3.1415926..., on=1, off=0, all=-1, :=-1}, переменные с суффиксами (@pxref{Data information}), переменные определенные командой @ref{define}, значения времени (в формате "hh-mm-ss_DD.MM.YYYY", "hh-mm-ss" или "DD.MM.YYYY") . Также массивы размером 1x1x1 считаются скалярами (например, @samp{pi/dat.nx}).
++@end itemize
++Перед первым использованием все переменные должны быть определены с помощью команд, создающих массивы (@ref{new}, @ref{var}, @ref{list}, @ref{copy}, @ref{read}, @ref{hist}, @ref{sum} и др., см. @ref{Data constructor}, @ref{Data filling} и @ref{Make another data}).
++
++Команды могут иметь несколько наборов аргументов (например, @code{plot ydat} и @code{plot xdat ydat}). Все аргументы команды для выбранного набора должны быть указаны, однако часть из них могут иметь значения по умолчанию. Такие аргументы в описании команд будут помещены в квадратные скобки [], например @code{plot ydat ['stl'='' zval=nan]}. При этом запись @code{[arg1 arg2 arg3 ...]} подразумевает @code{[arg1 [arg2 [arg3 ...]]]}, т.е. опускать можно только аргументы с конца, если вы согласны с их значениями по умолчанию. Например, @code{plot ydat '' 1} или @code{plot ydat ''} правильно, а @code{plot ydat 1} не правильно (аргумент @code{'stl'} пропущен).
++
++Можно предоставить несколько вариантов аргументов комманд при использовании символа @samp{?} для их разделения. Конкретный вариант аргумента, используемый при выполнении команды, задается значением команды @ref{variant}. При этом будет использован последний вариант, если задано слишком большое значение. По умолчанию используется первый вариант (т.е. как при @code{variant 0}). Например в следующем коде будет сначала нарисован график синим цветом (первый аргумент @samp{b}), а затем красным пунктиром -- после @code{variant 1} будет использован второй аргумент @samp{r|}:
++@verbatim
++fplot 'x' 'b'?'r'
++variant 1
++fplot 'x^3' 'b'?'r|'
++@end verbatim
++
++
++
++@c TODO Translate it!
++
++@c ------------------------------------------------------------------
++@external{}
++@node Program flow commands, LaTeX package, MGL definition, MGL scripts
++@section Управление ходом выполнения
++@nav{}
++
++Ниже собраны команды, управляющие порядком выполнения других команд (условия, циклы, подпрограммы), (пере-)определяют аргументы скрипта и пр. Прочие команды могут быть найдены в главах @ref{MathGL core} и @ref{Data processing}. Отмечу, что некоторые из команд (например, @ref{define}, @ref{ask}, @ref{call}, @ref{for}, @ref{func}) должны быть расположены на отдельной строке.
++
++@cindex chdir
++@anchor{chdir}
++@deftypefn {Команда MGL} {} chdir 'path'
++Переходит в папку @var{path}.
++@end deftypefn
++
++@cindex ask
++@anchor{ask}
++@deftypefn {Команда MGL} {} ask $N 'question'
++Задает @var{N}-ый аргумент скрипта равным ответу пользователя на вопрос @var{question}. Обычно команда показывает диалог с вопросом и полем ввода текста ответа. Здесь @var{N} это цифра (0...9) или буква (a...z).
++@end deftypefn
++
++@cindex define
++@anchor{define}
++@deftypefn {Команда MGL} {} define $N smth
++Задает @var{N}-ый аргумент скрипта равным @var{smth}. Отмечу, что @var{smth} используется как есть (с символами @samp{'} если присутствуют). Выполняется только подстановка других макроопределений $0...$9, $a...$z. Здесь @var{N} это цифра (0...9) или буква (a...z).
++@end deftypefn
++@deftypefn {Команда MGL} {} define name smth
++Определяет константу (скаляр) с именем @code{name} и числовым значением @code{smth}. Позднее она может быть использована как обычное число.
++@end deftypefn
++@cindex defchr
++@anchor{defchr}
++@deftypefn {Команда MGL} {} defchr $N smth
++Задает @var{N}-ый аргумент скрипта равным символу с UTF кодом @var{smth}. Здесь @var{N} это цифра (0...9) или буква (a...z).
++@end deftypefn
++@cindex defnum
++@anchor{defnum}
++@deftypefn {Команда MGL} {} defnum $N smth
++Задает @var{N}-ый аргумент скрипта равным числовому значению @var{smth}. Здесь @var{N} это цифра (0...9) или буква (a...z).
++@end deftypefn
++
++@comment @cindex defpal
++@comment @anchor{defpal}
++@comment @deftypefn {Команда MGL} {} defpal $N smth
++@comment Задает @var{N}-ый аргумент скрипта равным символу палитры с индексом, найденным из @var{smth}. Здесь @var{N} это цифра (0...9) или буква (a...z).
++@comment @end deftypefn
++
++@cindex call
++@anchor{call}
++@deftypefn {Команда MGL} {} call 'fname' [ARG1 ARG2 ... ARG9]
++Переходит к выполнению (вызывает) подпрограммы @var{fname} (или внешнего скрипта, если функция не была найдена). Опциональные аргументы передаются в подпрограмму. См. также @ref{func}.
++@end deftypefn
++
++@cindex func
++@anchor{func}
++@deftypefn {Команда MGL} {} func 'fname' [narg=0]
++Определяет подпрограмму с именем @var{fname} и задает число требуемых аргументов. Аргументы будут помещены в параметры скрипта $1, $2, ... $9. Отмечу, что выполнение основной программы будет остановлено при встрече @code{func} -- действует аналогично комманде @ref{stop}. См. также @ref{return}.
++
++@end deftypefn
++@cindex return
++@anchor{return}
++@deftypefn {Команда MGL} {} return
++Возвращается из подпрограммы. См. также @ref{func}.
++@end deftypefn
++
++@cindex load
++@anchor{load}
++@deftypefn {Команда MGL} {} load 'filename'
++Загружает дополнительные команды MGL из внешней динамической библиотеки @var{filename}. Данная библиотека должна содержать массив с именем @code{mgl_cmd_extra} типа @code{mglCommand}, который содержит описание новых комманд.
++@end deftypefn
++
++
++@cindex if
++@anchor{if}
++@deftypefn {Команда MGL} {} if dat 'cond'
++Начинает блок команд, выполняемый если каждый элемент @var{dat} удовлетворяет условию @var{cond}.
++@end deftypefn
++@deftypefn {Команда MGL} {} if @code{val}
++Начинает блок команд, выполняемый если @code{val} не ноль.
++@end deftypefn
++@cindex elseif
++@anchor{elseif}
++@deftypefn {Команда MGL} {} elseif dat 'cond'
++Начинает блок команд, выполняемый если предыдущий @code{if} или @code{elseif} не был выполнен и каждый элемент @var{dat} удовлетворяет условию @var{cond}.
++@end deftypefn
++@deftypefn {Команда MGL} {} elseif @code{val}
++Начинает блок команд, выполняемый если предыдущий @code{if} или @code{elseif} не был выполнен и @code{val} не ноль.
++@end deftypefn
++@cindex else
++@anchor{else}
++@deftypefn {Команда MGL} {} else
++Начинает блок команд, выполняемый если предыдущий @code{if} или @code{elseif} не был выполнен.
++@end deftypefn
++@cindex endif
++@anchor{endif}
++@deftypefn {Команда MGL} {} endif
++Заканчивает определение блока @code{if/elseif/else}.
++@end deftypefn
++
++@cindex for
++@anchor{for}
++@deftypefn {Команда MGL} {} for $N @code{v1 v2 [dv=1]}
++Начинает блок команд, выполняемый в цикле с $@var{N}-ым аргументом изменяющимся от @var{v1} до @var{v2} с шагом @var{dv}. Здесь @var{N} это цифра (0...9) или буква (a...z).
++@end deftypefn
++@deftypefn {Команда MGL} {} for $N dat
++Начинает блок команд, выполняемый в цикле с $@var{N}-ым аргументом пробегающим значения массива @var{dat}. Здесь @var{N} это цифра (0...9) или буква (a...z).
++@end deftypefn
++@cindex next
++@anchor{next}
++@deftypefn {Команда MGL} {} next
++Заканчивает блок цикла @code{for}.
++@end deftypefn
++
++@cindex once
++@anchor{once}
++@deftypefn {Команда MGL} {} once @code{val}
++Определяет код (между @code{once on} и @code{once off}) который будет выполнен только один раз. Полезно для работы с большими данными в программах типа UDAV.
++@end deftypefn
++@cindex stop
++@anchor{stop}
++@deftypefn {Команда MGL} {} stop
++Останавливает выполнение скрипта.
++@end deftypefn
++
++
++@cindex variant
++@anchor{variant}
++@deftypefn {Команда MGL} {} variant @code{val}
++Задает вариант аргумента(ов), разделенных символом @samp{?}, для всех последующих комманд.
++@end deftypefn
++
++
++
++@cindex rkstep
++@anchor{rkstep}
++@deftypefn {Команда MGL} {} rkstep eq1;... var1;... [@code{dt=1}]
++Выполняет один шаг решения системы обыкновенных дифференциальных уравнений @{var1' = eq1, ... @} с временным шагом @var{dt}. Здесь переменные @samp{var1}, ... -- переменные, определенные в MGL скрипте ранее. При решении используется метод Рунге-Кутта 4-го порядка.
++@end deftypefn
++
++
++@c TODO Translate it!
++
++@c ------------------------------------------------------------------
++@external{}
++@ifclear UDAV
++@node LaTeX package, mglParse class, Program flow commands, MGL scripts
++@end ifclear
++@ifset UDAV
++@node LaTeX package, , Program flow commands, MGL scripts
++@end ifset
++@section LaTeX package
++@nav{}
++
++There is LaTeX package @code{mgltex} (was made by Diego Sejas Viscarra) which allow one to make figures directly from MGL script located in LaTeX file.
++
++For using this package you need to specify @code{--shell-escape} option for @emph{latex/pdflatex} or manually run @emph{mglconv} tool with produced MGL scripts for generation of images. Don't forgot to run @emph{latex/pdflatex} second time to insert generated images into the output document. Also you need to run @emph{pdflatex} third time to update converted from EPS images if you are using vector EPS output (default).
++
++The package may have following options: @code{draft}, @code{final} --- the same as in the @emph{graphicx} package; @code{on}, @code{off} --- to activate/deactivate the creation of scripts and graphics; @code{comments}, @code{nocomments} --- to make visible/invisible commentaries contained inside @code{mglcomment} environments; @code{jpg}, @code{jpeg}, @code{png} --- to export graphics as JPEG/PNG images; @code{eps}, @code{epsz} --- to export to uncompressed/compressed EPS format as primitives; @code{bps}, @code{bpsz} --- to export to uncompressed/compressed EPS format as bitmap (doesn't work with @emph{pdflatex}); @code{pdf} --- to export to 3D PDF; @code{tex} --- to export to @emph{LaTeX/tikz} document.
++
++The package defines the following environments:
++@table @samp
++@item mgl
++ It writes its contents to a general script which has the same name as the LaTeX document, but its extension is @emph{.mgl}. The code in this environment is compiled and the image produced is included. It takes exactly the same optional arguments as the @code{\includegraphics} command, plus an additional argument @var{imgext}, which specifies the extension to save the image.
++
++An example of usage of @samp{mgl} environment would be:
++@verbatim
++\begin{mglfunc}{prepare2d}
++ new a 50 40 '0.6*sin(pi*(x+1))*sin(1.5*pi*(y+1))+0.4*cos(0.75*pi*(x+1)*(y+1))'
++ new b 50 40 '0.6*cos(pi*(x+1))*cos(1.5*pi*(y+1))+0.4*cos(0.75*pi*(x+1)*(y+1))'
++\end{mglfunc}
++
++\begin{figure}[!ht]
++ \centering
++ \begin{mgl}[width=0.85\textwidth,height=7.5cm]
++ fog 0.5
++ call 'prepare2d'
++ subplot 2 2 0 : title 'Surf plot (default)' : rotate 50 60 : light on : box : surf a
++
++ subplot 2 2 1 : title '"\#" style; meshnum 10' : rotate 50 60 : box
++ surf a '#'; meshnum 10
++
++ subplot 2 2 2 : title 'Mesh plot' : rotate 50 60 : box
++ mesh a
++
++ new x 50 40 '0.8*sin(pi*x)*sin(pi*(y+1)/2)'
++ new y 50 40 '0.8*cos(pi*x)*sin(pi*(y+1)/2)'
++ new z 50 40 '0.8*cos(pi*(y+1)/2)'
++ subplot 2 2 3 : title 'parametric form' : rotate 50 60 : box
++ surf x y z 'BbwrR'
++ \end{mgl}
++\end{figure}
++@end verbatim
++
++@item mgladdon
++ It adds its contents to the general script, without producing any image.
++@item mglcode
++ Is exactly the same as @samp{mgl}, but it writes its contents verbatim to its own file, whose name is specified as a mandatory argument.
++@item mglscript
++ Is exactly the same as @samp{mglcode}, but it doesn't produce any image, nor accepts optional arguments. It is useful, for example, to create a MGL script, which can later be post processed by another package like "listings".
++@item mglblock
++ It writes its contents verbatim to a file, specified as a mandatory argument, and to the LaTeX document, and numerates each line of code.
++
++@c This last three environments will test if the user is overwriting some file, and will issue a warning in that case.
++@item mglverbatim
++ Exactly the same as @samp{mglblock}, but it doesn't write to a file. This environment doesn't have arguments.
++@item mglfunc
++ Is used to define MGL functions. It takes one mandatory argument, which is the name of the function, plus one additional argument, which specifies the number of arguments of the function. The environment needs to contain only the body of the function, since the first and last lines are appended automatically, and the resulting code is written at the end of the general script, after the @ref{stop} command, which is also written automatically. The warning is produced if 2 or more function with the same name is defined.
++@item mglcomment
++ Is used to contain multiline commentaries. This commentaries will be visible/invisible in the output document, depending on the use of the package options @code{comments} and @code{nocomments} (see above), or the @code{\mglcomments} and @code{\mglnocomments} commands (see bellow).
++@item mglsetup
++ If many scripts with the same code are to be written, the repetitive code can be written inside this environment only once, then this code will be used automatically every time the @samp{\mglplot} command is used (see below). It takes one optional argument, which is a name to be associated to the corresponding contents of the environment; this name can be passed to the @samp{\mglplot} command to use the corresponding block of code automatically (see below).
++@end table
++
++The package also defines the following commands:
++@table @samp
++@item \mglplot
++ It takes one mandatory argument, which is MGL instructions separated by the symbol @samp{:} this argument can be more than one line long. It takes the same optional arguments as the @samp{mgl} environment, plus an additional argument @var{setup}, which indicates the name associated to a block of code inside a @samp{mglsetup} environment. The code inside the mandatory argument will be appended to the block of code specified, and the resulting code will be written to the general script.
++
++An example of usage of @samp{\mglplot} command would be:
++@verbatim
++\begin{mglsetup}
++ box '@{W9}' : axis
++\end{mglsetup}
++\begin{mglsetup}[2d]
++ box : axis
++ grid 'xy' ';k'
++\end{mglsetup}
++\begin{mglsetup}[3d]
++ rotate 50 60
++ box : axis : grid 'xyz' ';k'
++\end{mglsetup}
++\begin{figure}[!ht]
++ \centering
++ \mglplot[scale=0.5]{new a 200 'sin(pi*x)' : plot a '2B'}
++\end{figure}
++\begin{figure}[!ht]
++ \centering
++ \mglplot[scale=0.5,setup=2d]{
++ fplot 'sin(pi*x)' '2B' :
++ fplot 'cos(pi*x^2)' '2R'
++ }
++\end{figure}
++\begin{figure}[!ht]
++ \centering
++ \mglplot[setup=3d]{fsurf 'sin(pi*x)+cos(pi*y)'}
++\end{figure}
++@end verbatim
++
++@item \mglgraphics
++ This command takes the same optional arguments as the @samp{mgl} environment, and one mandatory argument, which is the name of a MGL script. This command will compile the corresponding script and include the resulting image. It is useful when you have a script outside the LaTeX document, and you want to include the image, but you don't want to type the script again.
++@item \mglinclude
++ This is like @samp{\mglgraphics} but, instead of creating/including the corresponding image, it writes the contents of the MGL script to the LaTeX document, and numerates the lines.
++@item \mgldir
++ This command can be used in the preamble of the document to specify a directory where LaTeX will save the MGL scripts and generate the corresponding images. This directory is also where @samp{\mglgraphics} and @samp{\mglinclude} will look for scripts.
++@item \mglquality
++ Adjust the quality of the MGL graphics produced similarly to @ref{quality}.
++@item \mgltexon, \mgltexoff
++ Activate/deactivate the creation of MGL scripts and images. Notice these commands have local behavior in the sense that their effect is from the point they are called on.
++@item \mglcomment, \mglnocomment
++ Make visible/invisible the contents of the @code{mglcomment} environments. These commands have local effect too.
++@item \mglTeX
++ It just pretty prints the name of the package.
++@end table
++
++As an additional feature, when an image is not found or cannot be included, instead of issuing an error, @code{mgltex} prints a box with the word @samp{MGL image not found} in the LaTeX document.
++
++
++
++@ifclear UDAV
++@c ------------------------------------------------------------------
++@external{}
++@node mglParse class, , LaTeX package, MGL scripts
++@section mglParse class
++@nav{}
++@cindex mglParse
++
++Класс разбирает и выполняет скрипты MGL. Он определен в @code{#include <mgl2/mgl.h>}.
++
++Основная функция класса mglParse -- @code{Execute()}, выполняющая построчный разбор скрипта. Также есть вспомогательные функции для поиска и создания переменных MGL (объектов, производных от @code{mglDataA}). Эти функции полезны для отображения значений массивов во внешних объектах (например, в отдельном окне) или для предоставления доступа к внутренним массивам. Функция @code{AllowSetSize()} позволяет запретить изменение размера картинки (запрещает команду @code{setsize}). Функция @code{AllowFileIO()} позволяет запретить доступ к файлам на диске.
++
++@c Note an important feature -- if user defines function @var{func} in variable then it will be called before the destroying of this variable (@pxref{mglVar class}).
++
++@deftypefn {Конструктор класса @code{mglParse}} @code{} mglParse (@code{bool} setsize=@code{false})
++@deftypefnx {Конструктор класса @code{mglParse}} @code{} mglParse (@code{HMPR} pr)
++@deftypefnx {Конструктор класса @code{mglParse}} @code{} mglParse (@code{mglParse &}pr)
++@deftypefnx {Функция С} @code{HMPR} mgl_create_parser ()
++Создает экземпляр класса @code{mglParse} и устанавливает значение @var{AllowSetSize}.
++@end deftypefn
++
++@deftypefn {Деструктор класса @code{mglParse}} @code{} ~mglParse ()
++@deftypefnx {Функция С} @code{void} mgl_delete_parser (@code{HMPR} p)
++Удаляет экземпляр класса.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{HMPR} Self ()
++Возвращает указатель на используемый объект типа @code{HMPR}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{const char *}text)
++@deftypefnx{Метод класса @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{const wchar_t *}text)
++@deftypefnx {Функция С} @code{void} mgl_parse_text (@code{HMGL} gr, @code{HMPR} p, @code{const char *}text)
++@deftypefnx {Функция С} @code{void} mgl_parse_textw (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}text)
++Выполняет построчно скрипт MGL, содержащийся в @var{text}. Строки считаются разделенными символом @samp{\n}. Это основная функция класса.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{void} Execute (@code{mglGraph *}gr, @code{FILE *}fp, @code{bool} print=@code{false})
++@deftypefnx {Функция С} @code{void} mgl_parse_file (@code{HMGL} gr, @code{HMPR} p, @code{FILE *}fp, @code{int} print)
++Аналогично предыдущему, но скрипт читается из файла @var{fp}. Если @var{print}=@code{true}, то предупреждения и информационные сообщения печатаются в stdout.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{int} Parse (@code{mglGraph *}gr, @code{const char *}str, @code{long} pos=@code{0})
++@deftypefnx {Метод класса @code{mglParse}} @code{int} Parse (@code{mglGraph *}gr, @code{const wchar_t *}str, @code{long} pos=@code{0})
++@deftypefnx {Функция С} @code{int} mgl_parse_line (@code{HMGL} gr, @code{HMPR} p, @code{const char *}str, @code{int} pos)
++@deftypefnx {Функция С} @code{int} mgl_parse_linew (@code{HMGL} gr, @code{HMPR} p, @code{const wchar_t *}str, @code{int} pos)
++Выполняет строку @var{str} с выводом графики на @var{gr}. Возвращает код ошибки: 0 -- нет ошибок, 1 -- неправильные аргументы, 2 -- неизвестная команда, 3 -- строка слишком длинная, 4 -- нет закрывающей скобки или @samp{'}. Аргумент @var{pos} задает позицию строки в документе/файле для использования в команде @ref{for}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{mglData} Calc (@code{const char *}formula)
++@deftypefnx {Метод класса @code{mglParse}} @code{mglData} Calc (@code{const wchar_t *}formula)
++@deftypefnx {Функция С} @code{HMDT} mgl_parser_calc (@code{HMPR} p, @code{const char *}formula)
++@deftypefnx {Функция С} @code{HMDT} mgl_parser_calcw (@code{HMPR} p, @code{const wchar_t *}formula)
++Разбирает строку @var{formula} и возвращает полученный массив. В отличие от @code{AddVar()} или @code{FindVar()}, это обычный массив данных, который следует удалить после использования.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{mglDataC} CalcComplex (@code{const char *}formula)
++@deftypefnx {Метод класса @code{mglParse}} @code{mglDataC} CalcComplex (@code{const wchar_t *}formula)
++@deftypefnx {Функция С} @code{HADT} mgl_parser_calc_complex (@code{HMPR} p, @code{const char *}formula)
++@deftypefnx {Функция С} @code{HADT} mgl_parser_calc_complexw (@code{HMPR} p, @code{const wchar_t *}formula)
++Разбирает строку @var{formula} и возвращает полученный массив с комплексными значениями. В отличие от @code{AddVar()} или @code{FindVar()}, это обычный массив данных, который следует удалить после использования.
++@end deftypefn
++
++
++@deftypefn {Метод класса @code{mglParse}} @code{void} AddParam (@code{int} n, @code{const char *}str)
++@deftypefnx {Метод класса @code{mglParse}} @code{void} AddParam (@code{int} n, @code{const wchar_t *}str)
++@deftypefnx {Функция С} @code{void} mgl_parser_add_param (@code{HMPR} p, @code{int} id, @code{const char *}val)
++@deftypefnx {Функция С} @code{void} mgl_parser_add_paramw (@code{HMPR} p, @code{int} id, @code{const wchar_t *}val)
++Устанавливает значение @var{n}-го параметра строкой @var{str} (@var{n}=0, 1 ... 'z'-'a'+10). Строка @var{str} не должна содержать символ @samp{$}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{mglVar *} FindVar (@code{const char *}name)
++@deftypefnx {Метод класса @code{mglParse}} @code{mglVar *} FindVar (@code{const wchar_t *}name)
++@deftypefnx {Функция С} @code{HMDT} mgl_parser_find_var (@code{HMPR} p, @code{const char *}name)
++@deftypefnx {Функция С} @code{HMDT} mgl_parser_find_varw (@code{HMPR} p, @code{const wchar_t *}name)
++Возвращает указатель на переменную с именем @var{name} или @code{NULL} если переменная отсутствует. Используйте эту функцию для добавления внешних массивов в скрипт. @strong{Не удаляйте} полученный массив!
++@end deftypefn
++@deftypefn {Метод класса @code{mglParse}} @code{mglVar *} AddVar (@code{const char *}name)
++@deftypefnx {Метод класса @code{mglParse}} @code{mglVar *} AddVar (@code{const wchar_t *}name)
++@deftypefnx {Функция С} @code{HMDT} mgl_parser_add_var (@code{HMPR} p, @code{const char *}name)
++@deftypefnx {Функция С} @code{HMDT} mgl_parser_add_varw (@code{HMPR} p, @code{const wchar_t *}name)
++Возвращает указатель на переменную с именем @var{name}. Если переменная отсутствует, то она будет создана. Используйте эту функцию для добавления внешних массивов в скрипт. @strong{Не удаляйте} полученный массив!
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{void} OpenHDF (@code{const char *}fname)
++@deftypefnx {Функция С} @code{void} mgl_parser_openhdf (@code{HMPR} pr, @code{const char *}fname)
++Читает все массивы данных из HDF5 файла @var{fname} и создает переменные MGL с соответствующими именами. Если имя данных начинается с @samp{!}, то будут созданы комплексные массивы.
++@end deftypefn
++
++@deftypefn{Метод класса @code{mglParse} (C++)} @code{void} DeleteVar (@code{const char *}name)
++@deftypefnx{Метод класса @code{mglParse} (C++)} @code{void} DeleteVar (@code{const wchar_t *}name)
++@deftypefnx {Функция С} @code{void} mgl_parser_del_var (@code{HMPR} p, @code{const char *}name)
++@deftypefnx {Функция С} @code{void} mgl_parser_del_varw (@code{HMPR} p, @code{const wchar_t *}name)
++Удаляет переменную по имени @var{name}.
++@end deftypefn
++
++@deftypefn{Метод класса @code{mglParse} (C++)} @code{void} DeleteAll ()
++@deftypefnx {Функция С} @code{void} mgl_parser_del_all (@code{HMPR} p)
++Удаляет все переменные и сбрасывает список команд к списку по умолчанию в данном классе.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{void} RestoreOnce ()
++@deftypefnx {Функция С} @code{void} mgl_parser_restore_once (@code{HMPR} p)
++Восстанавливает состояние флага Once.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{void} AllowSetSize (@code{bool} a)
++@deftypefnx {Функция С} @code{void} mgl_parser_allow_setsize (@code{HMPR} p, @code{int} a)
++Разрешает/запрещает команду @ref{setsize}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{void} AllowFileIO (@code{bool} a)
++@deftypefnx {Функция С} @code{void} mgl_parser_allow_file_io (@code{HMPR} p, @code{int} a)
++Разрешает/запрещает команды чтения файлов.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{void} AllowDllCall (@code{bool} a)
++@deftypefnx {Функция С} @code{void} mgl_parser_allow_dll_call (@code{HMPR} p, @code{int} a)
++Разрешает/запрещает команду @ref{load}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{void} Stop ()
++@deftypefnx {Функция С} @code{void} mgl_parser_stop (@code{HMPR} p)
++Посылает сигнал завершения выполнения для следующей команды.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{void} SetVariant (@code{int} var=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_parser_variant (@code{HMPR} p, @code{int} var=@code{0})
++Задает вариант аргумента(ов), разделенных символом @samp{?}, для всех последующих комманд.
++@end deftypefn
++
++<<<<<<< HEAD
++=======
++@deftypefn {Метод класса @code{mglParse}} @code{void} StartID (@code{int} id=@code{0})
++@deftypefnx {Функция С} @code{void} mgl_parser_start_id (@code{HMPR} p, @code{int} id)
++Задает начальный id (обычно это номер строки) первой строки при последующем выполнении скрипта.
++@end deftypefn
++
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++@deftypefn {Метод класса @code{mglParse}} @code{long} GetCmdNum ()
++@deftypefnx {Функция С} @code{long} mgl_parser_cmd_num (@code{HMPR} p)
++Возвращает число зарегистрированных команд MGL.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{const char *} GetCmdName (@code{long} id)
++@deftypefnx {Функция С} @code{const char *} mgl_parser_cmd_name (@code{HMPR} p, @code{long} id)
++Возвращает имя команды MGL с заданным номером @var{id}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{int} CmdType (@code{const char *}name)
++@deftypefnx {Функция С} @code{int} mgl_parser_cmd_type (@code{HMPR} p, @code{const char *}name)
++Возвращает тип команды MGL с именем @var{name}. Типы команд: 0 -- не команда, 1 - графики по данным, 2 - прочие графики, 3 - настройка, 4 - обработка данных, 5 - создание данных, 6 - трансформация, 7 - ход выполнения, 8 - 1d графики, 9 - 2d графики, 10 - 3d графики, 11 - двойные графики, 12 - векторные поля, 13 - оси координат, 14 - примитивы, 15 - настройка осей, 16 - текст/легенда, 17 - изменение данных.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{const char *} CmdFormat (@code{const char *}name)
++@deftypefnx {Функция С} @code{const char *} mgl_parser_cmd_frmt (@code{HMPR} p, @code{const char *}name)
++Возвращает формат аргументов команды MGL с именем @var{name}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{const char *} CmdDesc (@code{const char *}name)
++@deftypefnx {Функция С} @code{const char *} mgl_parser_cmd_desc (@code{HMPR} p, @code{const char *}name)
++Возвращает описание команды MGL с именем @var{name}.
++@end deftypefn
++
++@deftypefn {Метод класса @code{mglParse}} @code{void} RK_Step (@code{const char *}eqs, @code{const char *}vars, @code{mreal} dt=@code{1})
++@deftypefnx {Метод класса @code{mglParse}} @code{void} RK_Step (@code{const wchar_t *}eqs, @code{const wchar_t *}vars, @code{mreal} dt=@code{1})
++@deftypefnx {Функция С} @code{void} mgl_rk_step (@code{HMPR} p, @code{const char *}eqs, @code{const char *}vars, @code{mreal} dt)
++@deftypefnx {Функция С} @code{void} mgl_rk_step_w (@code{HMPR} p, @code{const wchar_t *}eqs, @code{const wchar_t *}vars, @code{mreal} dt)
++Make one step for ordinary differential equation(s) @{var1' = eq1, ... @} with time-step @var{dt}. Here strings @var{eqs} and @var{vars} contain the equations and variable names separated by symbol @samp{;}. The variable(s) @samp{var1}, ... are the ones, defined in MGL script previously. The Runge-Kutta 4-th order method is used.
++@end deftypefn
++
++@end ifclear
++
++@external{}
--- /dev/null
--- /dev/null
++@nav{}
++
++This appendix contain the full list of symbols (characters) used by MathGL for setting up plot. Also it contain sections for full list of hot-keys supported by mglview tool and by UDAV program.
++
++@menu
++* Symbols for styles::
++* Hot-keys for mglview::
++* Hot-keys for UDAV::
++@end menu
++
++@c ------------------------------------------------------------------
++@external{}
++@node Symbols for styles, Hot-keys for mglview, , Symbols and hot-keys
++@section Symbols for styles
++@nav{}
++
++Below is full list of all characters (symbols) which MathGL use for setting up the plot.
++
++@table @samp
++@item space ' '
++empty line style (see @ref{Line styles});
++
++empty color in @ref{chart}.
++
++@item !
++set to use new color from palette for each point (not for each curve, as default) in @ref{1D plotting};
++
++set to disable ticks tuning in @ref{axis} and @ref{colorbar};
++
++set to draw @ref{grid} lines at subticks coordinates too;
++
++define complex variable/expression in MGL script if placed at beginning.
++
++@item #
++set to use solid marks (see @ref{Line styles}) or solid @ref{error} boxes;
++
++set to draw wired plot for @ref{axial}, @ref{surf3}, @ref{surf3a}, @ref{surf3c}, @ref{triplot}, @ref{quadplot}, @ref{area}, @ref{region}, @ref{bars}, @ref{barh}, @ref{tube}, @ref{tape}, @ref{cone}, @ref{boxs} and draw boundary only for @ref{circle}, @ref{ellipse}, @ref{rhomb};
++
++set to draw also mesh lines for @ref{surf}, @ref{surfc}, @ref{surfa}, @ref{dens}, @ref{densx}, @ref{densy}, @ref{densz}, @ref{dens3}, or boundary for @ref{chart}, @ref{facex}, @ref{facey}, @ref{facez}, @ref{rect};
++
++set to draw boundary and box for @ref{legend}, @ref{title}, or grid lines for @ref{table};
++
++set to draw grid for @ref{radar};
++
++set to start flow threads and pipes from edges only for @ref{flow}, @ref{pipe};
++
++set to use whole are for axis range in @ref{subplot}, @ref{inplot};
++
++change text color inside a string (see @ref{Font styles});
++
++start comment in @ref{MGL scripts} or in @ref{Command options}.
++
++@item $
++denote parameter of @ref{MGL scripts}.
++
++@item %
++set color scheme along 2 coordinates @ref{Color scheme}.
++
++@item &
++
++set to pass long integer number in tick template @ref{xtick}, @ref{ytick}, @ref{ztick}, @ref{ctick};
++
++specifier of drawing user-defined symbols as mark (see @ref{Line styles});
++
++operation in @ref{Textual formulas}.
++
++@item @quoteright{}
++denote string in @ref{MGL scripts} or in @ref{Command options}.
++
++@item *
++one of marks (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++set to start flow threads from 2d array inside data (see @ref{flow});
++
++operation in @ref{Textual formulas}.
++
++@item +
++one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
++
++one of mask for face filling (see @ref{Color scheme});
++
++set to print @samp{+} for positive numbers in @ref{axis}, @ref{label}, @ref{table};
++
++operation of increasing last character value in MGL strings;
++
++operation in @ref{Textual formulas}.
++
++@item ,
++separator for color positions (see @ref{Color styles}) or items in a list
++
++concatenation of MGL string with another string or numerical value.
++
++@item -
++solid line style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++place entries horizontally in @ref{legend};
++
++set to use usual @samp{-} for negative numbers in @ref{axis}, @ref{label}, @ref{table};
++
++operation in @ref{Textual formulas}.
++
++@item .
++one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
++
++set to draw hachures instead of arrows for @ref{vect}, @ref{vect3};
++
++set to use dots instead of faces for @ref{cloud}, @ref{torus}, @ref{axial}, @ref{surf3}, @ref{surf3a}, @ref{surf3c}, @ref{surf}, @ref{surfa}, @ref{surfc}, @ref{dens}, @ref{map};
++
++delimiter of fractional parts for numbers.
++
++@item /
++operation in @ref{Textual formulas}.
++
++@item :
++line dashing style (see @ref{Line styles});
++
++stop color scheme parsing (see @ref{Color scheme});
++
++range operation in @ref{MGL scripts};
++
++<<<<<<< HEAD
++=======
++style for @ref{axis};
++
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++separator of commands in @ref{MGL scripts}.
++
++@item ;
++line dashing style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++<<<<<<< HEAD
++start of an option in @ref{MGL scripts} or in @ref{Command options}.
++=======
++start of an option in @ref{MGL scripts} or in @ref{Command options};
++
++separator of equations in @ref{ode};
++
++separator of labels in @ref{iris}.
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++@item <
++one of marks (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++style of @ref{subplot} and @ref{inplot};
++
++set position of @ref{colorbar};
++
++style of @ref{vect}, @ref{vect3};
++
++align left in @ref{bars}, @ref{barh}, @ref{boxplot}, @ref{cones}, @ref{candle}, @ref{ohlc};
++
++operation in @ref{Textual formulas}.
++
++
++@item >
++one of marks (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++style of @ref{subplot} and @ref{inplot};
++
++set position of @ref{colorbar};
++
++style of @ref{vect}, @ref{vect3};
++
++align right in @ref{bars}, @ref{barh}, @ref{boxplot}, @ref{cones}, @ref{candle}, @ref{ohlc};
++
++operation in @ref{Textual formulas}.
++
++@item =
++line dashing style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++set to use equidistant columns for @ref{table};
++
++set to use color gradient for @ref{vect}, @ref{vect3};
++
++operation in @ref{Textual formulas}.
++
++@item @@
++set to draw box around text for @ref{text} and similar functions;
++
++set to draw boundary and fill it for @ref{circle}, @ref{ellipse}, @ref{rhomb};
++
++set to fill faces for @ref{box};
++
++set to draw large semitransparent mark instead of error box for @ref{error};
++
++set to draw edges for @ref{cone};
++
++set to draw filled boxes for @ref{boxs};
++
++reduce text size inside a string (see @ref{Font styles});
++
++operation in @ref{Textual formulas}.
++
++@item ^
++one of marks (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++style of @ref{subplot} and @ref{inplot};
++
++set position of @ref{colorbar};
++
++set outer position for @ref{legend};
++
++inverse default position for @ref{axis};
++
++switch to upper index inside a string (see @ref{Font styles});
++
++align center in @ref{bars}, @ref{barh}, @ref{boxplot}, @ref{cones}, @ref{candle}, @ref{ohlc};
++
++operation in @ref{Textual formulas}.
++
++@item _
++empty arrow style (see @ref{Line styles});
++
++disable drawing of tick labels for @ref{axis};
++
++style of @ref{subplot} and @ref{inplot};
++
++set position of @ref{colorbar};
++
++set to draw contours at bottom for @ref{cont}, @ref{contf}, @ref{contd}, @ref{contv}, @ref{tricont};
++
++switch to lower index inside a string (see @ref{Font styles}).
++
++@item []
++contain symbols excluded from color scheme parsing (see @ref{Color scheme});
++
++operation of getting n-th character from MGL string.
++
++@item @{@}
++contain extended specification of color (see @ref{Color styles}), dashing (see @ref{Line styles}) or mask (see @ref{Color scheme});
++
++denote special operation in @ref{MGL scripts};
++
++denote 'meta-symbol' for LaTeX like string parsing (see @ref{Font styles}).
++
++@item |
++line dashing style (see @ref{Line styles});
++
++set to use sharp color scheme (see @ref{Color scheme});
++
++set to limit width by subplot width for @ref{table};
++
++delimiter in @ref{list} command;
++
++operation in @ref{Textual formulas}.
++
++@item \
++string continuation symbol on next line for @ref{MGL scripts}.
++
++@item ~
++disable drawing of tick labels for @ref{axis} and @ref{colorbar};
++
++disable first segment in @ref{lamerey};
++
++reduce number of segments in @ref{plot} and @ref{tens};
++
++one of mask for face filling (see @ref{Color scheme}).
++
++@item 0,1,2,3,4,5,6,7,8,9
++line width (see @ref{Line styles});
++
++brightness of a color (see @ref{Color styles});
++
++precision of numbers in @ref{axis}, @ref{label}, @ref{table};
++
++kind of smoothing (for digits 1,3,5) in @ref{smooth};
++
++digits for a value.
++
++@item 4,6,8
++set to draw square, hex- or octo-pyramids instead of cones in @ref{cone}, @ref{cones}.
++
++@item A,B,C,D,E,F,a,b,c,d,e,f
++can be hex-digit for color specification if placed inside @{@} (see @ref{Color styles}).
++
++@item A
++arrow style (see @ref{Line styles});
++
++set to use absolute position in whole picture for @ref{text}, @ref{colorbar}, @ref{legend}.
++
++@item a
++set to use absolute position in subplot for @ref{text};
++
++style of @ref{plot}, @ref{radar}, @ref{tens}, @ref{area}, @ref{region} to draw segments between points outside of axis range;
++
++style of @ref{bars}, @ref{barh}, @ref{cones}.
++
++@item B
++dark blue color (see @ref{Color styles}).
++
++@item b
++blue color (see @ref{Color styles});
++
++bold font face if placed after @samp{:} (see @ref{Font styles}).
++
++@item C
++dark cyan color (see @ref{Color styles});
++
++align text to center if placed after @samp{:} (see @ref{Font styles}).
++
++@item c
++cyan color (see @ref{Color styles});
++
++name of color axis;
++
++cosine transform for @ref{transform}.
++
++@item D
++arrow style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme}).
++
++@item d
++one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
++
++one of mask for face filling (see @ref{Color scheme});
++
++start hex-dash description if placed inside @{@} (see @ref{Line styles}).
++
++@item E
++dark green-yellow color (see @ref{Color styles}).
++
++@item e
++green-yellow color (see @ref{Color styles}).
++
++@item F
++
++set fixed bar widths in @ref{bars}, @ref{barh};
++
++set LaTeX-like format for numbers in @ref{axis}, @ref{label}, @ref{table}.
++
++@item f
++style of @ref{bars}, @ref{barh};
++
++style of @ref{vect}, @ref{vect3};
++
++set fixed format for numbers in @ref{axis}, @ref{label}, @ref{table};
++
++Fourier transform for @ref{transform}.
++
++@item G
++dark green color (see @ref{Color styles}).
++
++@item g
++green color (see @ref{Color styles}).
++
++@item H
++dark gray color (see @ref{Color styles}).
++
++@item h
++gray color (see @ref{Color styles});
++
++Hankel transform for @ref{transform}.
++
++@item I
++arrow style (see @ref{Line styles});
++
++set @ref{colorbar} position near boundary.
++
++@item i
++line dashing style (see @ref{Line styles});
++
++italic font face if placed after @samp{:} (see @ref{Font styles}).
++
++set to use inverse values for @ref{cloud}, @ref{pipe}, @ref{dew};
++
++set to fill only area with y1<y<y2 for @ref{region};
++
++inverse Fourier transform for @ref{transform}, @ref{transforma}, @ref{fourier}.
++
++@item j
++line dashing style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme}).
++
++@item K
++arrow style (see @ref{Line styles}).
++
++@item k
++black color (see @ref{Color styles}).
++
++@item L
++dark green-blue color (see @ref{Color styles});
++
++align text to left if placed after @samp{:} (see @ref{Font styles}).
++
++@item l
++green-blue color (see @ref{Color styles}).
++
++@item M
++dark magenta color (see @ref{Color styles}).
++
++@item m
++magenta color (see @ref{Color styles}).
++
++@item N
++dark sky-blue color (see @ref{Color styles}).
++
++@item n
++sky-blue color (see @ref{Color styles}).
++
++@item O
++arrow style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme}).
++
++@item o
++one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
++
++one of mask for face filling (see @ref{Color scheme});
++
++over-line text if placed after @samp{:} (see @ref{Font styles}).
++
++@item P
++dark purple color (see @ref{Color styles}).
++
++@item p
++purple color (see @ref{Color styles}).
++
++@item Q
++dark orange or brown color (see @ref{Color styles}).
++
++@item q
++orange color (see @ref{Color styles}).
++
++@item R
++dark red color (see @ref{Color styles});
++
++align text to right if placed after @samp{:} (see @ref{Font styles}).
++
++@item r
++red color (see @ref{Color styles}).
++
++@item S
++arrow style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme}).
++
++@item s
++one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
++
++one of mask for face filling (see @ref{Color scheme});
++
++start hex-mask description if placed inside @{@} (see @ref{Color scheme});
++
++sine transform for @ref{transform}.
++
++@item t
++draw tubes instead of cones in @ref{cone}, @ref{cones};
++
++@item T
++arrow style (see @ref{Line styles});
++
++place text under the curve for @ref{text}, @ref{cont}, @ref{cont3}.
++
++@item t
++set to draw text labels for @ref{cont}, @ref{cont3};
++
++name of t-axis (one of ternary axis);
++
++variable in @ref{Textual formulas}, which usually is varied in range [0,1].
++
++@item U
++dark blue-violet color (see @ref{Color styles});
++
++disable rotation of tick labels for @ref{axis}.
++
++@item u
++blue-violet color (see @ref{Color styles});
++
++under-line text if placed after @samp{:} (see @ref{Font styles});
++
++name of u-axis (one of ternary axis);
++
++variable in @ref{Textual formulas}, which usually denote array itself.
++
++@item V
++arrow style (see @ref{Line styles});
++
++place text centering on vertical direction for @ref{text}.
++
++@item v
++one of marks (see @ref{Line styles});
++
++set to draw vectors on flow threads for @ref{flow} and on segments for @ref{lamerey}.
++
++@item W
++bright gray color (see @ref{Color styles}).
++
++@item w
++white color (see @ref{Color styles});
++
++wired text if placed after @samp{:} (see @ref{Font styles});
++
++name of w-axis (one of ternary axis);
++
++@item X
++arrow style (see @ref{Line styles}).
++
++@item x
++
++name of x-axis or x-direction or 1st dimension of a data array;
++
++start hex-color description if placed inside @{@} (see @ref{Color styles});
++
++one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
++
++tiles orientation perpendicular to x-axis in @ref{tile}, @ref{tiles};
++
++style of @ref{tape}.
++
++@item Y
++dark yellow or gold color (see @ref{Color styles}).
++
++@item y
++yellow color (see @ref{Color styles});
++
++name of y-axis or y-direction or 2nd dimension of a data array;
++
++tiles orientation perpendicular to y-axis in @ref{tile}, @ref{tiles}.
++
++@item z
++
++name of z-axis or z-direction or 3d dimension of a data array;
++
++style of @ref{tape}.
++
++@end table
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node Hot-keys for mglview, Hot-keys for UDAV, Symbols for styles, Symbols and hot-keys
++@section Hot-keys for mglview
++@nav{}
++
++@multitable @columnfractions .3 .7
++@headitem Key @tab Description
++@item @key{Ctrl-P}
++@tab Open printer dialog and print graphics.
++
++@item @key{Ctrl-W}
++@tab Close window.
++
++@item @key{Ctrl-T}
++@tab Switch on/off transparency for the graphics.
++
++@item @key{Ctrl-L}
++@tab Switch on/off additional lightning for the graphics.
++
++@item @key{Ctrl-Space}
++@tab Restore default graphics rotation, zoom and perspective.
++
++@item @key{F5}
++@tab Execute script and redraw graphics.
++
++@item @key{F6}
++@tab Change canvas size to fill whole region.
++
++@item @key{F7}
++@tab Stop drawing and script execution.
++
++@item @key{Ctrl-F5}
++@tab Run slideshow. If no parameter specified then the dialog with slideshow options will appear.
++
++@item @key{Ctrl-Comma}, @key{Ctrl-Period}
++@tab Show next/previous slide. If no parameter specified then the dialog with slideshow options will appear.
++
++
++@item @key{Ctrl-Shift-G}
++@tab Copy graphics to clipboard.
++
++
++
++@item @key{Alt-P}
++@tab Export as semitransparent PNG.
++
++@item @key{Alt-F}
++@tab Export as solid PNG.
++
++@item @key{Alt-J}
++@tab Export as JPEG.
++
++@item @key{Alt-E}
++@tab Export as vector EPS.
++
++@item @key{Alt-S}
++@tab Export as vector SVG.
++
++@item @key{Alt-L}
++@tab Export as LaTeX/Tikz image.
++
++@item @key{Alt-M}
++@tab Export as MGLD.
++
++@item @key{Alt-D}
++@tab Export as PRC/PDF.
++
++@item @key{Alt-O}
++@tab Export as OBJ.
++
++@c @item @key{Alt-X}
++@c @tab Export as X3D.
++@end multitable
++
++@c ------------------------------------------------------------------
++@external{}
++@node Hot-keys for UDAV, , Hot-keys for mglview, Symbols and hot-keys
++@section Hot-keys for UDAV
++@nav{}
++
++@multitable @columnfractions .3 .7
++@headitem Key @tab Description
++@item @key{Ctrl-N}
++@tab Create new window with empty script. Note, all scripts share variables. So, second window can be used to see some additional information of existed variables.
++
++@item @key{Ctrl-O}
++@tab Open and execute/show script or data from file. You may switch off automatic exection in UDAV properties
++
++@item @key{Ctrl-S}
++@tab Save script to a file.
++
++@item @key{Ctrl-P}
++@tab Open printer dialog and print graphics.
++
++@item @key{Ctrl-Z}
++@tab Undo changes in script editor.
++
++@item @key{Ctrl-Shift-Z}
++@tab Redo changes in script editor.
++
++@item @key{Ctrl-X}
++@tab Cut selected text into clipboard.
++
++@item @key{Ctrl-C}
++@tab Copy selected text into clipboard.
++
++@item @key{Ctrl-V}
++@tab Paste selected text from clipboard.
++
++@item @key{Ctrl-A}
++@tab Select all text in editor.
++
++@item @key{Ctrl-F}
++@tab Show dialog for text finding.
++
++@item @key{F3}
++@tab Find next occurrence of the text.
++
++
++@item @key{Win-C} or @key{Meta-C}
++@tab Show dialog for new command and put it into the script.
++
++@item @key{Win-F} or @key{Meta-F}
++@tab Insert last fitted formula with found coefficients.
++
++@item @key{Win-S} or @key{Meta-S}
++@tab Show dialog for styles and put it into the script. Styles define the plot view (color scheme, marks, dashing and so on).
++
++@item @key{Win-O} or @key{Meta-O}
++@tab Show dialog for options and put it into the script. Options are used for additional setup the plot.
++
++@item @key{Win-N} or @key{Meta-N}
++@tab Replace selected expression by its numerical value.
++
++@item @key{Win-P} or @key{Meta-P}
++@tab Select file and insert its file name into the script.
++
++@item @key{Win-G} or @key{Meta-G}
++@tab Show dialog for plot setup and put resulting code into the script. This dialog setup axis, labels, lighting and other general things.
++
++
++
++@item @key{Ctrl-Shift-O}
++@tab Load data from file. Data will be deleted only at exit but UDAV will not ask to save it.
++
++@item @key{Ctrl-Shift-S}
++@tab Save data to a file.
++
++@item @key{Ctrl-Shift-C}
++@tab Copy range of numbers to clipboard.
++
++@item @key{Ctrl-Shift-V}
++@tab Paste range of numbers from clipboard.
++
++@item @key{Ctrl-Shift-N}
++@tab Recreate the data with new sizes and fill it by zeros.
++
++@item @key{Ctrl-Shift-R}
++@tab Resize (interpolate) the data to specified sizes.
++
++@item @key{Ctrl-Shift-T}
++@tab Transform data along dimension(s).
++
++@item @key{Ctrl-Shift-M}
++@tab Make another data.
++
++@item @key{Ctrl-Shift-H}
++@tab Find histogram of data.
++
++
++
++@item @key{Ctrl-T}
++@tab Switch on/off transparency for the graphics.
++
++@item @key{Ctrl-L}
++@tab Switch on/off additional lightning for the graphics.
++
++@item @key{Ctrl-G}
++@tab Switch on/off grid of absolute coordinates.
++
++@item @key{Ctrl-Space}
++@tab Restore default graphics rotation, zoom and perspective.
++
++@item @key{F5}
++@tab Execute script and redraw graphics.
++
++@item @key{F6}
++@tab Change canvas size to fill whole region.
++
++@item @key{F7}
++@tab Stop script execution and drawing.
++
++@item @key{F8}
++@tab Show/hide tool window with list of hidden plots.
++
++@item @key{F9}
++@tab Restore status for 'once' command and reload data.
++
++@item @key{Ctrl-F5}
++@tab Run slideshow. If no parameter specified then the dialog with slideshow options will appear.
++
++@item @key{Ctrl-Comma}, @key{Ctrl-Period}
++@tab Show next/previous slide. If no parameter specified then the dialog with slideshow options will appear.
++
++@item @key{Ctrl-W}
++@tab Open dialog with slideshow options.
++
++@item @key{Ctrl-Shift-G}
++@tab Copy graphics to clipboard.
++
++
++@item @key{F1}
++@tab Show help on MGL commands
++
++@item @key{F2}
++@tab Show/hide tool window with messages and information.
++
++@item @key{F4}
++@tab Show/hide calculator which evaluate and help to type textual formulas. Textual formulas may contain data variables too.
++
++
++@item @key{Meta-Shift-Up}, @key{Meta-Shift-Down}
++@tab Change view angle @math{\theta}.
++
++@item @key{Meta-Shift-Left}, @key{Meta-Shift-Right}
++@tab Change view angle @math{\phi}.
++
++@item @key{Alt-Minus}, @key{Alt-Equal}
++@tab Zoom in/out whole image.
++
++@item @key{Alt-Up}, @key{Alt-Down}, @key{Alt-Right}, @key{Alt-Left}
++@tab Shift whole image.
++
++@item @key{Alt-P}
++@tab Export as semitransparent PNG.
++
++@item @key{Alt-F}
++@tab Export as solid PNG.
++
++@item @key{Alt-J}
++@tab Export as JPEG.
++
++@item @key{Alt-E}
++@tab Export as vector EPS.
++
++@item @key{Alt-S}
++@tab Export as vector SVG.
++
++@item @key{Alt-L}
++@tab Export as LaTeX/Tikz image.
++
++@item @key{Alt-M}
++@tab Export as MGLD.
++
++@item @key{Alt-D}
++@tab Export as PRC/PDF.
++
++@item @key{Alt-O}
++@tab Export as OBJ.
++
++@c @item @key{Alt-X}
++@c @tab Export as X3D.
++
++@end multitable
++
++@external{}
--- /dev/null
--- /dev/null
++@nav{}
++
++This appendix contain the full list of symbols (characters) used by MathGL for setting up plot. Also it contain sections for full list of hot-keys supported by mglview tool and by UDAV program.
++
++@menu
++* Symbols for styles::
++* Hot-keys for mglview::
++* Hot-keys for UDAV::
++@end menu
++
++@c ------------------------------------------------------------------
++@external{}
++@node Symbols for styles, Hot-keys for mglview, , Symbols and hot-keys
++@section Symbols for styles
++@nav{}
++
++Below is full list of all characters (symbols) which MathGL use for setting up the plot.
++
++@table @samp
++@item space ' '
++empty line style (see @ref{Line styles});
++
++empty color in @ref{chart}.
++
++@item !
++set to use new color from palette for each point (not for each curve, as default) in @ref{1D plotting};
++
++set to disable ticks tuning in @ref{axis} and @ref{colorbar};
++
++set to draw @ref{grid} lines at subticks coordinates too;
++
++define complex variable/expression in MGL script if placed at beginning.
++
++@item #
++set to use solid marks (see @ref{Line styles}) or solid @ref{error} boxes;
++
++set to draw wired plot for @ref{axial}, @ref{surf3}, @ref{surf3a}, @ref{surf3c}, @ref{triplot}, @ref{quadplot}, @ref{area}, @ref{region}, @ref{bars}, @ref{barh}, @ref{tube}, @ref{tape}, @ref{cone}, @ref{boxs} and draw boundary only for @ref{circle}, @ref{ellipse}, @ref{rhomb};
++
++set to draw also mesh lines for @ref{surf}, @ref{surfc}, @ref{surfa}, @ref{dens}, @ref{densx}, @ref{densy}, @ref{densz}, @ref{dens3}, or boundary for @ref{chart}, @ref{facex}, @ref{facey}, @ref{facez}, @ref{rect};
++
++set to draw boundary and box for @ref{legend}, @ref{title}, or grid lines for @ref{table};
++
++set to draw grid for @ref{radar};
++
++set to start flow threads and pipes from edges only for @ref{flow}, @ref{pipe};
++
++set to use whole are for axis range in @ref{subplot}, @ref{inplot};
++
++change text color inside a string (see @ref{Font styles});
++
++start comment in @ref{MGL scripts} or in @ref{Command options}.
++
++@item $
++denote parameter of @ref{MGL scripts}.
++
++@item %
++set color scheme along 2 coordinates @ref{Color scheme}.
++
++@item &
++
++set to pass long integer number in tick template @ref{xtick}, @ref{ytick}, @ref{ztick}, @ref{ctick};
++
++specifier of drawing user-defined symbols as mark (see @ref{Line styles});
++
++operation in @ref{Textual formulas}.
++
++@item @quoteright{}
++denote string in @ref{MGL scripts} or in @ref{Command options}.
++
++@item *
++one of marks (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++set to start flow threads from 2d array inside data (see @ref{flow});
++
++operation in @ref{Textual formulas}.
++
++@item +
++one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
++
++one of mask for face filling (see @ref{Color scheme});
++
++set to print @samp{+} for positive numbers in @ref{axis}, @ref{label}, @ref{table};
++
++operation of increasing last character value in MGL strings;
++
++operation in @ref{Textual formulas}.
++
++@item ,
++separator for color positions (see @ref{Color styles}) or items in a list
++
++concatenation of MGL string with another string or numerical value.
++
++@item -
++solid line style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++place entries horizontally in @ref{legend};
++
++set to use usual @samp{-} for negative numbers in @ref{axis}, @ref{label}, @ref{table};
++
++operation in @ref{Textual formulas}.
++
++@item .
++one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
++
++set to draw hachures instead of arrows for @ref{vect}, @ref{vect3};
++
++set to use dots instead of faces for @ref{cloud}, @ref{torus}, @ref{axial}, @ref{surf3}, @ref{surf3a}, @ref{surf3c}, @ref{surf}, @ref{surfa}, @ref{surfc}, @ref{dens}, @ref{map};
++
++delimiter of fractional parts for numbers.
++
++@item /
++operation in @ref{Textual formulas}.
++
++@item :
++line dashing style (see @ref{Line styles});
++
++stop color scheme parsing (see @ref{Color scheme});
++
++range operation in @ref{MGL scripts};
++
++<<<<<<< HEAD
++=======
++style for @ref{axis};
++
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++separator of commands in @ref{MGL scripts}.
++
++@item ;
++line dashing style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++<<<<<<< HEAD
++start of an option in @ref{MGL scripts} or in @ref{Command options}.
++=======
++start of an option in @ref{MGL scripts} or in @ref{Command options};
++
++separator of equations in @ref{ode};
++
++separator of labels in @ref{iris}.
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++@item <
++one of marks (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++style of @ref{subplot} and @ref{inplot};
++
++set position of @ref{colorbar};
++
++style of @ref{vect}, @ref{vect3};
++
++align left in @ref{bars}, @ref{barh}, @ref{boxplot}, @ref{cones}, @ref{candle}, @ref{ohlc};
++
++operation in @ref{Textual formulas}.
++
++
++@item >
++one of marks (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++style of @ref{subplot} and @ref{inplot};
++
++set position of @ref{colorbar};
++
++style of @ref{vect}, @ref{vect3};
++
++align right in @ref{bars}, @ref{barh}, @ref{boxplot}, @ref{cones}, @ref{candle}, @ref{ohlc};
++
++operation in @ref{Textual formulas}.
++
++@item =
++line dashing style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++set to use equidistant columns for @ref{table};
++
++set to use color gradient for @ref{vect}, @ref{vect3};
++
++operation in @ref{Textual formulas}.
++
++@item @@
++set to draw box around text for @ref{text} and similar functions;
++
++set to draw boundary and fill it for @ref{circle}, @ref{ellipse}, @ref{rhomb};
++
++set to fill faces for @ref{box};
++
++set to draw large semitransparent mark instead of error box for @ref{error};
++
++set to draw edges for @ref{cone};
++
++set to draw filled boxes for @ref{boxs};
++
++reduce text size inside a string (see @ref{Font styles});
++
++operation in @ref{Textual formulas}.
++
++@item ^
++one of marks (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme});
++
++style of @ref{subplot} and @ref{inplot};
++
++set position of @ref{colorbar};
++
++set outer position for @ref{legend};
++
++inverse default position for @ref{axis};
++
++switch to upper index inside a string (see @ref{Font styles});
++
++align center in @ref{bars}, @ref{barh}, @ref{boxplot}, @ref{cones}, @ref{candle}, @ref{ohlc};
++
++operation in @ref{Textual formulas}.
++
++@item _
++empty arrow style (see @ref{Line styles});
++
++disable drawing of tick labels for @ref{axis};
++
++style of @ref{subplot} and @ref{inplot};
++
++set position of @ref{colorbar};
++
++set to draw contours at bottom for @ref{cont}, @ref{contf}, @ref{contd}, @ref{contv}, @ref{tricont};
++
++switch to lower index inside a string (see @ref{Font styles}).
++
++@item []
++contain symbols excluded from color scheme parsing (see @ref{Color scheme});
++
++operation of getting n-th character from MGL string.
++
++@item @{@}
++contain extended specification of color (see @ref{Color styles}), dashing (see @ref{Line styles}) or mask (see @ref{Color scheme});
++
++denote special operation in @ref{MGL scripts};
++
++denote 'meta-symbol' for LaTeX like string parsing (see @ref{Font styles}).
++
++@item |
++line dashing style (see @ref{Line styles});
++
++set to use sharp color scheme (see @ref{Color scheme});
++
++set to limit width by subplot width for @ref{table};
++
++delimiter in @ref{list} command;
++
++operation in @ref{Textual formulas}.
++
++@item \
++string continuation symbol on next line for @ref{MGL scripts}.
++
++@item ~
++disable drawing of tick labels for @ref{axis} and @ref{colorbar};
++
++disable first segment in @ref{lamerey};
++
++reduce number of segments in @ref{plot} and @ref{tens};
++
++one of mask for face filling (see @ref{Color scheme}).
++
++@item 0,1,2,3,4,5,6,7,8,9
++line width (see @ref{Line styles});
++
++brightness of a color (see @ref{Color styles});
++
++precision of numbers in @ref{axis}, @ref{label}, @ref{table};
++
++kind of smoothing (for digits 1,3,5) in @ref{smooth};
++
++digits for a value.
++
++@item 4,6,8
++set to draw square, hex- or octo-pyramids instead of cones in @ref{cone}, @ref{cones}.
++
++@item A,B,C,D,E,F,a,b,c,d,e,f
++can be hex-digit for color specification if placed inside @{@} (see @ref{Color styles}).
++
++@item A
++arrow style (see @ref{Line styles});
++
++set to use absolute position in whole picture for @ref{text}, @ref{colorbar}, @ref{legend}.
++
++@item a
++set to use absolute position in subplot for @ref{text};
++
++style of @ref{plot}, @ref{radar}, @ref{tens}, @ref{area}, @ref{region} to draw segments between points outside of axis range;
++
++style of @ref{bars}, @ref{barh}, @ref{cones}.
++
++@item B
++dark blue color (see @ref{Color styles}).
++
++@item b
++blue color (see @ref{Color styles});
++
++bold font face if placed after @samp{:} (see @ref{Font styles}).
++
++@item C
++dark cyan color (see @ref{Color styles});
++
++align text to center if placed after @samp{:} (see @ref{Font styles}).
++
++@item c
++cyan color (see @ref{Color styles});
++
++name of color axis;
++
++cosine transform for @ref{transform}.
++
++@item D
++arrow style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme}).
++
++@item d
++one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
++
++one of mask for face filling (see @ref{Color scheme});
++
++start hex-dash description if placed inside @{@} (see @ref{Line styles}).
++
++@item E
++dark green-yellow color (see @ref{Color styles}).
++
++@item e
++green-yellow color (see @ref{Color styles}).
++
++@item F
++
++set fixed bar widths in @ref{bars}, @ref{barh};
++
++set LaTeX-like format for numbers in @ref{axis}, @ref{label}, @ref{table}.
++
++@item f
++style of @ref{bars}, @ref{barh};
++
++style of @ref{vect}, @ref{vect3};
++
++set fixed format for numbers in @ref{axis}, @ref{label}, @ref{table};
++
++Fourier transform for @ref{transform}.
++
++@item G
++dark green color (see @ref{Color styles}).
++
++@item g
++green color (see @ref{Color styles}).
++
++@item H
++dark gray color (see @ref{Color styles}).
++
++@item h
++gray color (see @ref{Color styles});
++
++Hankel transform for @ref{transform}.
++
++@item I
++arrow style (see @ref{Line styles});
++
++set @ref{colorbar} position near boundary.
++
++@item i
++line dashing style (see @ref{Line styles});
++
++italic font face if placed after @samp{:} (see @ref{Font styles}).
++
++set to use inverse values for @ref{cloud}, @ref{pipe}, @ref{dew};
++
++set to fill only area with y1<y<y2 for @ref{region};
++
++inverse Fourier transform for @ref{transform}, @ref{transforma}, @ref{fourier}.
++
++@item j
++line dashing style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme}).
++
++@item K
++arrow style (see @ref{Line styles}).
++
++@item k
++black color (see @ref{Color styles}).
++
++@item L
++dark green-blue color (see @ref{Color styles});
++
++align text to left if placed after @samp{:} (see @ref{Font styles}).
++
++@item l
++green-blue color (see @ref{Color styles}).
++
++@item M
++dark magenta color (see @ref{Color styles}).
++
++@item m
++magenta color (see @ref{Color styles}).
++
++@item N
++dark sky-blue color (see @ref{Color styles}).
++
++@item n
++sky-blue color (see @ref{Color styles}).
++
++@item O
++arrow style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme}).
++
++@item o
++one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
++
++one of mask for face filling (see @ref{Color scheme});
++
++over-line text if placed after @samp{:} (see @ref{Font styles}).
++
++@item P
++dark purple color (see @ref{Color styles}).
++
++@item p
++purple color (see @ref{Color styles}).
++
++@item Q
++dark orange or brown color (see @ref{Color styles}).
++
++@item q
++orange color (see @ref{Color styles}).
++
++@item R
++dark red color (see @ref{Color styles});
++
++align text to right if placed after @samp{:} (see @ref{Font styles}).
++
++@item r
++red color (see @ref{Color styles}).
++
++@item S
++arrow style (see @ref{Line styles});
++
++one of mask for face filling (see @ref{Color scheme}).
++
++@item s
++one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
++
++one of mask for face filling (see @ref{Color scheme});
++
++start hex-mask description if placed inside @{@} (see @ref{Color scheme});
++
++sine transform for @ref{transform}.
++
++@item t
++draw tubes instead of cones in @ref{cone}, @ref{cones};
++
++@item T
++arrow style (see @ref{Line styles});
++
++place text under the curve for @ref{text}, @ref{cont}, @ref{cont3}.
++
++@item t
++set to draw text labels for @ref{cont}, @ref{cont3};
++
++name of t-axis (one of ternary axis);
++
++variable in @ref{Textual formulas}, which usually is varied in range [0,1].
++
++@item U
++dark blue-violet color (see @ref{Color styles});
++
++disable rotation of tick labels for @ref{axis}.
++
++@item u
++blue-violet color (see @ref{Color styles});
++
++under-line text if placed after @samp{:} (see @ref{Font styles});
++
++name of u-axis (one of ternary axis);
++
++variable in @ref{Textual formulas}, which usually denote array itself.
++
++@item V
++arrow style (see @ref{Line styles});
++
++place text centering on vertical direction for @ref{text}.
++
++@item v
++one of marks (see @ref{Line styles});
++
++set to draw vectors on flow threads for @ref{flow} and on segments for @ref{lamerey}.
++
++@item W
++bright gray color (see @ref{Color styles}).
++
++@item w
++white color (see @ref{Color styles});
++
++wired text if placed after @samp{:} (see @ref{Font styles});
++
++name of w-axis (one of ternary axis);
++
++@item X
++arrow style (see @ref{Line styles}).
++
++@item x
++
++name of x-axis or x-direction or 1st dimension of a data array;
++
++start hex-color description if placed inside @{@} (see @ref{Color styles});
++
++one of marks (see @ref{Line styles}) or kind of @ref{error} boxes;
++
++tiles orientation perpendicular to x-axis in @ref{tile}, @ref{tiles};
++
++style of @ref{tape}.
++
++@item Y
++dark yellow or gold color (see @ref{Color styles}).
++
++@item y
++yellow color (see @ref{Color styles});
++
++name of y-axis or y-direction or 2nd dimension of a data array;
++
++tiles orientation perpendicular to y-axis in @ref{tile}, @ref{tiles}.
++
++@item z
++
++name of z-axis or z-direction or 3d dimension of a data array;
++
++style of @ref{tape}.
++
++@end table
++
++
++@c ------------------------------------------------------------------
++@external{}
++@node Hot-keys for mglview, Hot-keys for UDAV, Symbols for styles, Symbols and hot-keys
++@section Hot-keys for mglview
++@nav{}
++
++@multitable @columnfractions .3 .7
++@headitem Key @tab Description
++@item @key{Ctrl-P}
++@tab Open printer dialog and print graphics.
++
++@item @key{Ctrl-W}
++@tab Close window.
++
++@item @key{Ctrl-T}
++@tab Switch on/off transparency for the graphics.
++
++@item @key{Ctrl-L}
++@tab Switch on/off additional lightning for the graphics.
++
++@item @key{Ctrl-Space}
++@tab Restore default graphics rotation, zoom and perspective.
++
++@item @key{F5}
++@tab Execute script and redraw graphics.
++
++@item @key{F6}
++@tab Change canvas size to fill whole region.
++
++@item @key{F7}
++@tab Stop drawing and script execution.
++
++@item @key{Ctrl-F5}
++@tab Run slideshow. If no parameter specified then the dialog with slideshow options will appear.
++
++@item @key{Ctrl-Comma}, @key{Ctrl-Period}
++@tab Show next/previous slide. If no parameter specified then the dialog with slideshow options will appear.
++
++
++@item @key{Ctrl-Shift-G}
++@tab Copy graphics to clipboard.
++
++
++
++@item @key{Alt-P}
++@tab Export as semitransparent PNG.
++
++@item @key{Alt-F}
++@tab Export as solid PNG.
++
++@item @key{Alt-J}
++@tab Export as JPEG.
++
++@item @key{Alt-E}
++@tab Export as vector EPS.
++
++@item @key{Alt-S}
++@tab Export as vector SVG.
++
++@item @key{Alt-L}
++@tab Export as LaTeX/Tikz image.
++
++@item @key{Alt-M}
++@tab Export as MGLD.
++
++@item @key{Alt-D}
++@tab Export as PRC/PDF.
++
++@item @key{Alt-O}
++@tab Export as OBJ.
++
++@c @item @key{Alt-X}
++@c @tab Export as X3D.
++@end multitable
++
++@c ------------------------------------------------------------------
++@external{}
++@node Hot-keys for UDAV, , Hot-keys for mglview, Symbols and hot-keys
++@section Hot-keys for UDAV
++@nav{}
++
++@multitable @columnfractions .3 .7
++@headitem Key @tab Description
++@item @key{Ctrl-N}
++@tab Create new window with empty script. Note, all scripts share variables. So, second window can be used to see some additional information of existed variables.
++
++@item @key{Ctrl-O}
++@tab Open and execute/show script or data from file. You may switch off automatic exection in UDAV properties
++
++@item @key{Ctrl-S}
++@tab Save script to a file.
++
++@item @key{Ctrl-P}
++@tab Open printer dialog and print graphics.
++
++@item @key{Ctrl-Z}
++@tab Undo changes in script editor.
++
++@item @key{Ctrl-Shift-Z}
++@tab Redo changes in script editor.
++
++@item @key{Ctrl-X}
++@tab Cut selected text into clipboard.
++
++@item @key{Ctrl-C}
++@tab Copy selected text into clipboard.
++
++@item @key{Ctrl-V}
++@tab Paste selected text from clipboard.
++
++@item @key{Ctrl-A}
++@tab Select all text in editor.
++
++@item @key{Ctrl-F}
++@tab Show dialog for text finding.
++
++@item @key{F3}
++@tab Find next occurrence of the text.
++
++
++@item @key{Win-C} or @key{Meta-C}
++@tab Show dialog for new command and put it into the script.
++
++@item @key{Win-F} or @key{Meta-F}
++@tab Insert last fitted formula with found coefficients.
++
++@item @key{Win-S} or @key{Meta-S}
++@tab Show dialog for styles and put it into the script. Styles define the plot view (color scheme, marks, dashing and so on).
++
++@item @key{Win-O} or @key{Meta-O}
++@tab Show dialog for options and put it into the script. Options are used for additional setup the plot.
++
++@item @key{Win-N} or @key{Meta-N}
++@tab Replace selected expression by its numerical value.
++
++@item @key{Win-P} or @key{Meta-P}
++@tab Select file and insert its file name into the script.
++
++@item @key{Win-G} or @key{Meta-G}
++@tab Show dialog for plot setup and put resulting code into the script. This dialog setup axis, labels, lighting and other general things.
++
++
++
++@item @key{Ctrl-Shift-O}
++@tab Load data from file. Data will be deleted only at exit but UDAV will not ask to save it.
++
++@item @key{Ctrl-Shift-S}
++@tab Save data to a file.
++
++@item @key{Ctrl-Shift-C}
++@tab Copy range of numbers to clipboard.
++
++@item @key{Ctrl-Shift-V}
++@tab Paste range of numbers from clipboard.
++
++@item @key{Ctrl-Shift-N}
++@tab Recreate the data with new sizes and fill it by zeros.
++
++@item @key{Ctrl-Shift-R}
++@tab Resize (interpolate) the data to specified sizes.
++
++@item @key{Ctrl-Shift-T}
++@tab Transform data along dimension(s).
++
++@item @key{Ctrl-Shift-M}
++@tab Make another data.
++
++@item @key{Ctrl-Shift-H}
++@tab Find histogram of data.
++
++
++
++@item @key{Ctrl-T}
++@tab Switch on/off transparency for the graphics.
++
++@item @key{Ctrl-L}
++@tab Switch on/off additional lightning for the graphics.
++
++@item @key{Ctrl-G}
++@tab Switch on/off grid of absolute coordinates.
++
++@item @key{Ctrl-Space}
++@tab Restore default graphics rotation, zoom and perspective.
++
++@item @key{F5}
++@tab Execute script and redraw graphics.
++
++@item @key{F6}
++@tab Change canvas size to fill whole region.
++
++@item @key{F7}
++@tab Stop script execution and drawing.
++
++@item @key{F8}
++@tab Show/hide tool window with list of hidden plots.
++
++@item @key{F9}
++@tab Restore status for 'once' command and reload data.
++
++@item @key{Ctrl-F5}
++@tab Run slideshow. If no parameter specified then the dialog with slideshow options will appear.
++
++@item @key{Ctrl-Comma}, @key{Ctrl-Period}
++@tab Show next/previous slide. If no parameter specified then the dialog with slideshow options will appear.
++
++@item @key{Ctrl-W}
++@tab Open dialog with slideshow options.
++
++@item @key{Ctrl-Shift-G}
++@tab Copy graphics to clipboard.
++
++
++@item @key{F1}
++@tab Show help on MGL commands
++
++@item @key{F2}
++@tab Show/hide tool window with messages and information.
++
++@item @key{F4}
++@tab Show/hide calculator which evaluate and help to type textual formulas. Textual formulas may contain data variables too.
++
++
++@item @key{Meta-Shift-Up}, @key{Meta-Shift-Down}
++@tab Change view angle @math{\theta}.
++
++@item @key{Meta-Shift-Left}, @key{Meta-Shift-Right}
++@tab Change view angle @math{\phi}.
++
++@item @key{Alt-Minus}, @key{Alt-Equal}
++@tab Zoom in/out whole image.
++
++@item @key{Alt-Up}, @key{Alt-Down}, @key{Alt-Right}, @key{Alt-Left}
++@tab Shift whole image.
++
++@item @key{Alt-P}
++@tab Export as semitransparent PNG.
++
++@item @key{Alt-F}
++@tab Export as solid PNG.
++
++@item @key{Alt-J}
++@tab Export as JPEG.
++
++@item @key{Alt-E}
++@tab Export as vector EPS.
++
++@item @key{Alt-S}
++@tab Export as vector SVG.
++
++@item @key{Alt-L}
++@tab Export as LaTeX/Tikz image.
++
++@item @key{Alt-M}
++@tab Export as MGLD.
++
++@item @key{Alt-D}
++@tab Export as PRC/PDF.
++
++@item @key{Alt-O}
++@tab Export as OBJ.
++
++@c @item @key{Alt-X}
++@c @tab Export as X3D.
++
++@end multitable
++
++@external{}
--- /dev/null
--- /dev/null
++<<<<<<< HEAD
++=======
++2.4.1 Released 20 July 2017
++2.4 Released 17 May 2017
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++2.3.5.1 Released 30 May 2015
++2.3.5 Released 16 May 2015
++2.3.4 Released 11 February 2015
++2.3.3 Released 01 June 2015
++2.3.2 Released 2 February 2015
++2.3.1 Released 21 October 2014
++2.3 Released 7 August 2014
++2.2.2.1 Released 19 March 2014
++2.2.2 Released 10 March 2014
++2.2.1 Released 22 January 2014
++2.2 Released 11 November 2013
++2.1.3.1 Released 8 May 2013
++2.1.3 Released 2 May 2013
++2.1.2 Released 28 January 2013
++2.1.1 Released 24 December 2012
++2.1 Released 13 December 2012
++2.0.3 Released 27 July 2012
++2.0.2 Released 24 May 2012
++2.0.1 Released 23 May 2012
++2.0 Released 12 April 2012
++2.0.b Released 23 August 2011
++
++1.11.3 Released 23 November 2012
++1.11.2 Released 30 May 2011
++1.11.1 Released 28 March 2011
++1.11 Released 8 November 2010
++1.10.2.1 Released 27 March 2010
++1.10.2 Released 22 March 2010
++1.10.1 Released 8 March 2010
++1.10 Released 28 December 2009
++1.9 Released 8 July 2009
++1.8.1 Released 4 March 2009
++1.8 Released 27 November 2008
++1.7 Released 5 June 2008
++1.6.2 Released 5 April 2008
++1.6.1 Released 2 April 2008
++1.6 Released 17 March 2008
++1.5 Released 11 January 2008
++1.4.3.1 Released 24 December 2008
++1.4.3 Released 18 December 2008
++1.4.2 Released 27 November 2007
++1.4.1 Released 14 November 2007
++1.4 Released 30 October 2007
++1.3 Released 15 October 2007
++1.2.2 Released 26 September 2007
++1.2.1 Released 14 September 2007
++1.2 Released 10 September 2007
++1.1 Released 23 May 2007
++1.0 Released 2 April 2007
++
++0.9 Last beta version of the MathGL library. Released 2 March 2007
++0.8.1 Released 19 February 2007
++0.8.0 First public release (24 January 2007)
--- /dev/null
--- /dev/null
++@c ------------------------------------------------------------------
++@chapter Website
++@nav{}
++
++@menu
++* Main::
++* News::
++* Features::
++* Pictures::
++@c * MGL scripts::
++* Download::
++* Other projects::
++@end menu
++
++@external{}
++
++@node Main, News, , Website
++@section MathGL is ...
++@nav{}
++
++@ifhtml
++@html
++<a href="Adding-fog.html"><img border="0" align="right" hspace="30" vspace="20" alt="Surface in fog" src="../small/fog-sm.png"></a>
++@end html
++@end ifhtml
++@itemize @bullet
++@item
++a library for making high-quality scientific graphics under Linux and Windows;
++@item
++a library for the fast data plotting and data processing of large data arrays;
++@item
++a library for working in window and console modes and for easy embedding into other programs;
++@item
++a library with large and growing set of graphics.
++@end itemize
++
++Now MathGL has more than 35000 lines of code, more than 55 general types of graphics for 1d, 2d and 3d data arrays, including special ones for chemical and statistical graphics. It can export graphics to raster and vector (EPS or SVG) formats. It has Qt, FLTK, OpenGL interfaces and can be used even from console programs. It has functions for data processing and script MGL language for simplification of data plotting. Also it has several types of transparency and smoothed lightning, vector fonts and TeX-like symbol parsing, arbitrary curvilinear coordinate system and many over useful things. It can be used from code written on C++/C/Fortran/Python/Octave and many other languages. Finally it is platform independent and free (under GPL v.2.0 license).
++
++There is a @uref{http://sourceforge.net/forum/?group_id=152187, forum} where you can ask a question or suggest an improvement. However the @uref{http://groups.google.com/group/mathgl, MathGL group} is preferable for quicker answer.
++
++For subscribing to @uref{http://groups.google.com/group/mathgl, MathGL group} you can use form below
++@ifhtml
++@html
++<form action="http://groups.google.com/group/mathgl/boxsubscribe">
++Email: <input type=text name=email> <input type=submit name="sub" value="Subscribe">
++</form>
++@end html
++@end ifhtml
++
++@strong{About LGPL and GPL licenses.}
++Generally, MathGL is GPL library. However, you can use LGPL license for MathGL core and widgets if you don't use SWIG-based interfaces and disable GSL features. This can be done by using @code{lgpl} option at build time. According this, I've added the LGPL win32 binaries into @ref{Download} page.
++
++@strong{Latest news}
++@itemize
++
++<<<<<<< HEAD
++@item @strong{20 June 2016.}
++New version (v.@value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are compatibility changes and bugfixes. @strong{NOTE}: there is incompatible change -- the library libmgl-qt is removed. You need to use libmgl-qt4 or libmgl-qt5 explicitly to reduce the possible error of wrong Qt libs linking.
++
++@item @emph{16 May 2016.}
++New version (v.2.3.5) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, some speeding up and bugfixes, which denoted @ref{News, here}.
++@item @emph{7 August 2014.}
++New version (v.2.3) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are many major improvements for both MathGL core and for UDAV, which denoted @ref{News, here}.
++=======
++@item @strong{20 July 2017.}
++New version (v.2.4.1) with bugfixes of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released.
++@item @emph{17 May 2017.}
++New version (v.2.4) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are @code{mgllab} executable, string manipulation in MGL, new functions, plot types and styles, translation to Russian using @code{gettext} and bugfixes, which denoted @ref{News, here}.
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++@end itemize
++
++There is detailed @ref{News, news list}. Sourceforge project page @uref{http://sourceforge.net/projects/mathgl/, here}.
++
++@ifhtml
++@html
++<a href="http://www.datadvance.net"><img border="0" align="right" hspace="10" alt="DATADVANCE" src="../datadvance.png"></a>
++@end html
++@end ifhtml
++Javascript interface was developed with support of @url{http://www.datadvance.net, DATADVANCE} company.
++
++@external{}
++
++@node News, Features, Main, Website
++@section News
++@nav{}
++
++@itemize
++
++<<<<<<< HEAD
++@item @strong{20 June 2016.}
++New version (v.2.3.5.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are compatibility changes and bugfixes. @strong{INCOMPATIBLE}: the library libmgl-qt is removed. You need to use libmgl-qt4 or libmgl-qt5 explicitly to reduce the possible error of wrong Qt libs linking.
++
++@item @strong{16 May 2016.}
++New version (v.2.3.5) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, some speeding up and bugfixes:
++@itemize @bullet
++@item Update @ref{LaTeX package} (thanks to Diego Sejas Viscarra)
++
++@itemize @bullet
++@item
++@code{\MGL@@codes}: Bugfix: category code for tabulators is changed too
++@item
++@code{\MGL@@quality}: 9 is accepted as quality value now
++@item
++@code{\MGL@@scale}: Now accepts any positive value
++@item
++@code{\MGL@@test@@switch}: New command to verify and validate switching arguments
++@item
++@code{\mglTeX}: Add a small negative space in the logo, between the "mgl" and "TEX"
++@item
++@code{\mglTeX}: Declared now as robust command
++@item
++@code{\mglcomments}: Now accepts arguments 0 (equivalent to @code{off}) and 1 (equivalent to @code{on}), besides the usual @code{off} and @code{on}
++@item
++@code{\mglgraphics}: New command options: @code{gray, mglscale, quality, variant}
++@item
++@code{\mglname}: Now writes the MGL code line @samp{setsize 600 400} to the main script
++@item
++@code{\mglplot}: Added @code{\bgroup} and @code{\egroup} in order to keep changes private
++@item
++New command options: @code{gray, mglscale, quality, variant}
++@item
++@code{\mglsettings}: Added options @code{gray} and @code{variant}
++@item
++Now calls the @code{\mglswitch} and @code{\mglcomments} commands for the switch and comments options, respectively
++@item
++@code{\mglswitch}: Now accepts arguments 0 (equivalent to @code{off}) and 1 (equivalent to @code{on}), besides the usual @code{off} and @code{on}
++@item
++mglTeX now depends on the ifpdf package
++@item
++Change definition of @code{\mglcommentname} from MGL comment to mglTEX comment
++@item
++Introduce the concept of global, local and private settings in the documentation
++@item
++New commands: @code{\mglgray} (to activate/deactivate) gray-scale mode locally, and @code{\mglvariant} (to set variant of arguments in MGL scripts locally)
++@item
++New package option @code{9q} for setting quality to 9 (for testing purposes of the author)
++@item
++New package options @code{0v, 1v, 2v} to select variant of arguments in MGL scripts
++@item
++New package options @code{gray, color} to activate/deactivate gray-scale mode for graphics
++@item
++Remove the @code{\MGL@@setkeys} command, since it isn’t needed as first thought
++@item
++Rename @code{\MGL@@document@@scripts} to @code{\MGL@@doc@@scripts}
++@item
++Rename @code{\MGL@@script@@name} to @code{\MGL@@script}
++@item
++Rename command @code{\MGL@@graph@@ext} to @code{\MGL@@imgext}
++@item
++Rename command @code{\mglcommonscriptname} to @code{\mglsetupscriptname}
++@item
++Rename environment @code{mglcommon} to @code{mglsetupscript} (@code{mglcommon} is still available, but deprecated)
++@item
++Rename family @code{MGL@@keys} as @code{MGL@@gr@@keys} for consistency
++@item
++Reorganize and update documentation
++@item
++Some minor bugfixes
++@item
++The MGL code line @samp{setsize 600 400} is now automatically written to the main script in order for the scaling options and commands to work
++@item
++@code{mgl}: New environment options: gray, mglscale, quality, variant
++@item
++@code{\mglcode}: New environment options: gray, mglscale, quality, variant
++@end itemize
++
++@item
++Add MGL command @ref{variant} to select proper variant of arguments (like @samp{var1?var2?var3?...}) in MGL commands.
++@item
++Remove limitation of maximal number (was 1000) of arguments for MGL commands. This is actual for 'list' command.
++@item
++Add mglWnd::Widget() for accessing widget which is used for drawing.
++@item
++Add @ref{gray} for producing gray-scaled image.
++@item
++Add MGL command @ref{setsizescl} for scaling all further @ref{setsize}.
++@item
++Add @ref{shear} for shearing plot.
++@item
++Add @ref{shearplot} for placing plots side-by-side with some shearing.
++@item
++Add @ref{limit} for limit maximal absolute value of data.
++@item
++Add @ref{tridmat} for tridiagonal matrix algorithm.
++@item
++Add MGL command @ref{diffract} for single step diffraction calculation.
++@item
++Add @ref{ifsfile} for reading IFS fractal parameters from *.ifs file.
++@item
++Add style @samp{*} for 2d versions of @ref{flow} to draw threads from points inside axis range.
++@item
++Add @samp{norm()} to the list of known functions
++@item
++Compatibility changes for MS VisualStudio, MacOS, Win64.
++@item
++Bugfix for legend export into EPS and SVG.
++@item
++Bugfix for importing data from std::vector.
++@item
++Improve Surf3*() drawing.
++@item
++Force NAN if divided by 0 in formulas.
++@item
++Option "-S" of mglconv now perform scaling in any cases
++@end itemize
++
++@item @strong{13 February 2016.}
++New version (v.2.3.4) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, some speeding up and bugfixes:
++=======
++@item @strong{20 July 2017.}
++New version (v.2.4.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released.
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++@itemize @bullet
++
++@item Add @ref{beltc} plot, which is @ref{belt} with manual coloring.
++@item Add style @samp{~} for @ref{plot} and @ref{tens} to omit some points at output.
++@item Add style @samp{:} for @ref{axis} to draw lines through point (0,0,0).
++@item Bugfixes.
++
++@end itemize
++
++@item @strong{17 May 2017.}
++New version (v.2.4) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are @code{mgllab} executable, string manipulation in MGL, new functions, plot types and styles, translation to Russian using @code{gettext} and bugfixes:
++@itemize @bullet
++
++@item Add @code{mgllab} executable, which is FLTK based version of @code{UDAV}. So, most things @code{mgllab} do faster.
++@item Add string manipulation in MGL language:
++@itemize @bullet
++ @item 'str'[n] -- get string of only n-th symbol;
++ @item 'str'+v -- add value v to the last character of the string;
++ @item 'str',val or 'str',!val -- append numeric value to the string (as before).
++@end itemize
++@item Add time value to MGL language in format: @samp{hh-mm-ss_DD.MM.YYYY} or @samp{hh-mm-ss} or @samp{DD.MM.YYYY}.
++@item Add @ref{iris} plot to show cross-dependencies of several data arrays.
++@item Add @ref{flame2d} to draw flame fractals.
++@item Add @ref{bbox} to set bounding box for 2D output.
++@item Add @ref{section} to get part of data between specified values.
++@item Add @ref{detect} to found curves along data maximums.
++@item Add @ref{dilate} to extend the region of 1-th value.
++@item Add @ref{erode} to narrow the region of 1-th value.
++@item Add @ref{apde} to solve PDE equation in inhomogeneous nonlinear media with spatial dispersion.
++@item Add @ref{symbol} to draw the glyphs defined by @ref{addsymbol}.
++@item Add @ref{addsymbol} to declare user-defined symbol (or glyph), which can be used as markers for plot (with style '&') or drawn itself by @ref{symbol} command.
++@item Add @ref{openhdf} to open all data arrays from HDF file.
++@item Extend @ref{crop} to cut to optimal size for FFT (i.e. to closest of 2^n*3^m*5^l).
++@item Add function mgl_data_max_first() and data suffixes .m[xyz][fl] to find first/last maximum along direction (see @ref{Data information}).
++@item Add function mgl_datac_diff_par() to parametric derivative of complex data (see @ref{diff}).
++@item Add style @samp{F} for @ref{bars} and @ref{barh} to set fixed bar widths.
++@item Add style @samp{a} for @ref{plot}, @ref{tens}, @ref{area} and @ref{region} to accurate drawing of data, which partially lie out of axis range.
++@item Add style @samp{#} for @ref{region} to draw wired plot.
++@item Add possibility of manual shift in @ref{multiplot}.
++@item Add parsing arguments of options for MGL commands.
++@item MGL command @ref{correl} now can perform 2d and 3d correlations.
++@item Option @ref{meshnum} now change the number of drawn markers for @ref{plot}, @ref{tens}, @ref{step}, @ref{mark} and @ref{textmark}.
++@item Function @ref{step} handle data with x.nx>y.nx similarly to @ref{bars}.
++@item Extend @ref{tile} and @ref{tiles} by adding manual coloring and face orientation.
++@item Add variant of MGL command @ref{copy} to copy data with "incorrect" names.
++@item Improve tick labels drawing.
++@item Improve time-ticks (add weeks) and add subticks to its.
++@item Improve @ref{fplot} to handle several singularities.
++@item Add LaTeX command \dfrac@{@}@{@}. This is full-sized version of \frac@{@}@{@}. Unfortunately, there is no support of nesting. Contrary, \frac allow nesting.
++@item Add mglODEc() -- ODE solver for complex variables (see @ref{ode}).
++@item Add cmplx(a,b)=a+i*b to the list of known functions in formula parsing
++@item Update CMake find_package to find MathGL.
++@item Increase line width for wired text.
++@item Update documentation: add description of new commands, add hint @ref{Mixing bitmap and vector output}.
++@item Add translation to Russian for most of labels and messages.
++@item Name @code{all} are reserved in MGL scripts now as synonym of -1.
++
++@item INCOMPATIBLE: Replace libmgl-qt by libmgl-qt4 and libmgl-qt5 for resolving conflicts of simultaneously installed both Qt4 and Qt5.
++@item Minor bugfixes.
++
++@end itemize
++
++@item @strong{20 June 2016.} Version 2.3.5.1 was released.
++@item @strong{16 May 2016.} Version 2.3.5 was released.
++@item @strong{13 February 2016.} Version 2.3.4 was released.
++@item @strong{1 June 2015.} Version 2.3.3 was released.
++@item @strong{2 February 2015.} Version 2.3.2 was released.
++@item @strong{21 October 2014.} Version 2.3.1 was released.
++@item @strong{7 August 2014.} Version 2.3 was released.
++@item @strong{19 March 2014.} Version 2.2.2.1 was released.
++@item @strong{10 March 2014.} Version 2.2.2 was released.
++@item @strong{22 January 2014.} Version 2.2.1 was released.
++@item @strong{11 November 2013.} Version 2.2 was released.
++@item @strong{8 May 2013.} Version 2.1.3.1 was released.
++@item @strong{2 May 2013.} Version 2.1.3 was released.
++@item @strong{28 January 2013.} Version 2.1.2 was released.
++@item @strong{24 December 2012.} Version 2.1.1 was released.
++@item @strong{13 December 2012.} Version 2.1 was released.
++@item @strong{23 August 2011.} Version 2.0.beta was released.
++@item @strong{30 May 2011.} Version 1.11.2 was released.
++@item @strong{8 November 2010.} Version 1.11 was released.
++@item @strong{28 December 2009.} Version 1.10 was released.
++@item @strong{8 July 2009.} Version 1.9 was released.
++@item @strong{27 November 2008.} Version 1.8 was released.
++@item @strong{5 June 2008.} Version 1.7 was released.
++@item @strong{17 March 2008.} Version 1.6 was released.
++@item @strong{11 January 2008.} Version 1.5 was released.
++@item @strong{30 October 2007.} Version 1.4 was released.
++@item @strong{15 October 2007.} Version 1.3 was released.
++@item @strong{10 September 2007.} Version 1.2 was released.
++@item @strong{23 May 2007.} Version 1.1 was released.
++@item @strong{2 April 2007.} Version 1.0 was released.
++@item @strong{24 January 2007.} First public release (v.0.8).
++@end itemize
++
++@external{}
++
++
++@node Features, Pictures, News, Website
++@section Features
++@nav{}
++
++MathGL can plot a wide range of graphics. It includes:
++@itemize @bullet
++@item
++one-dimensional: Plot, Area, Bars, Step, Stem, Torus, Chart, Error, Tube, Mark, (@ref{1D plotting});
++
++@item
++two-dimensional plots: Mesh, Surf, Dens, Cont, ContF, Boxs, Axial, Fall, Belt, Tile, including surfaces transparent (SurfA) or colored (SurfC) by another data (@ref{2D plotting});
++
++@item
++three-dimensional plots: Surf3, Dens3, Cont3, ContF3, Cloud-like, including isosurfaces transparent (Surf3A) or colored (Surf3C) by another data (@ref{3D plotting});
++
++@item
++vector fields plots: vector fields Vect, Vect3 and Traj, flow threads Flow, flow pipes Pipe, mapping chart Map, and so on (@ref{Vector fields});
++
++@item
++and so on. See also @ref{Extra samples}.
++@end itemize
++
++In fact, I created the functions for drawing of all the types of scientific plots that I know. The list of plots is growing; if you need some special type of a plot then please email me @email{mathgl.abalakin@@gmail.com, e-mail} and it will appear in the new version.
++
++I tried to make plots as nice looking as possible: e.g., a surface can be transparent and highlighted by several (up to 10) light sources. Most of the drawing functions have 2 variants: simple one for the fast plotting of data, complex one for specifying of the exact position of the plot (including parametric representation). Resulting image can be saved in bitmap PNG, JPEG, TGA, BMP format, or in vector EPS, SVG or TeX format, or in 3D formats OBJ, OFF, STL or in PRC format.
++
++All texts are drawn by vector fonts, which allows for high scalability and portability. Texts may contain commands for: some of the TeX-like symbols, changing index (upper or lower indexes) and the style of font inside the text string. Texts of ticks are rotated with axis rotation. It is possible to create a legend of plot and put text in an arbitrary position on the plot. Arbitrary text encoding (by the help of function @code{setlocale()}) and UTF-16 encoding are supported.
++
++Special class mglData is used for data encapsulation. In addition to a safe creation and deletion of data arrays it includes functions for data processing (smoothing, differentiating, integrating, interpolating and so on) and reading of data files with automatic size determination. Class mglData can handle arrays with up to three dimensions (arrays which depend on up to 3 independent indexes @math{a_@{ijk@}}). Using an array with higher number of dimensions is not meaningful, because I do not know how it can be plotted. Data filling and modification may be done manually or by textual formulas.
++
++There is fast evaluation of a textual mathematical expression. It is based on string precompilation to tree-like code at the creation of class instance. At evaluation stage code performs only fast tree-walk and returns the value of the expression. In addition to changing data values, textual formulas are also used for drawing in @emph{arbitrary} curvilinear coordinates. A set of such curvilinear coordinates is limited only by user's imagination rather than a fixed list like: polar, parabolic, spherical, and so on.
++
++@external{}
++
++@node Pictures, Download, Features, Website
++@section Pictures
++@nav{}
++
++There are samples for @ref{1D data plotting, 1D arrays}, @ref{2D data plotting, 2D arrays}, @ref{3D data plotting, 3D arrays}, @ref{Vector fields plotting} and some @ref{Extra samples}.
++
++@anchor{1D data plotting}
++@subheading Examples of graphics for 1d arrays
++
++@sfig{plot, Plot sample}
++@sfig{radar, Radar sample}
++@sfig{step, Step sample}
++@sfig{tens, Tens sample}
++
++@sfig{area, Area sample}
++@sfig{region,Region sample}
++@sfig{stem, Stem sample}
++@sfig{torus,Torus sample}
++
++@sfig{bars, Bars sample}
++@sfig{barh, Barh sample}
++@sfig{cones,Cones sample}
++@sfig{chart,Chart sample}
++
++@sfig{boxplot,BoxPlot sample}
++@sfig{candle, Candle sample}
++@sfig{tube, Tube sample}
++@sfig{tape, Tape sample}
++
++@sfig{error,Error sample}
++@sfig{mark, Mark sample}
++@sfig{textmark, TextMark sample}
++@sfig{label,Label sample}
++
++@anchor{2D data plotting}
++@subheading Examples of graphics for 2d arrays
++
++@sfig{surf, Surf sample}
++@sfig{surfc,SurfC sample}
++@sfig{surfa,SurfA sample}
++@sfig{mesh, Mesh sample}
++
++@sfig{fall, Fall sample}
++@sfig{belt, Belt sample}
++@sfig{boxs, Boxs sample}
++@sfig{axial,Axial sample}
++
++@sfig{dens, Dens sample}
++@sfig{tile, Tile sample}
++@sfig{tiles,TileS sample}
++@sfig{grad, Grad sample}
++
++@sfig{cont, Cont sample}
++@sfig{contf,ContF sample}
++@sfig{contd,ContD sample}
++@sfig{contv,ContV sample}
++
++@anchor{3D data plotting}
++@subheading Examples of graphics for 3d arrays
++
++@sfig{surf3, Surf3 sample}
++@sfig{surf3c,Surf3C sample}
++@sfig{surf3a,Surf3A sample}
++@sfig{cloud, Cloud sample}
++
++@sfig{densa, Dens3 sample}
++@sfig{conta, Cont3 sample}
++@sfig{contfa,ContF3 sample}
++@sfig{dots, Dots sample}
++
++@sfig{dens_xyz, Dens projection sample}
++@sfig{cont_xyz, Cont projection sample}
++@sfig{contf_xyz,ContF projection sample}
++@sfig{triplot, TriPlot and QuadPlot}
++
++@anchor{Vector fields plotting}
++@subheading Examples of graphics for vector fields
++
++@sfig{vect, Vect sample}
++@sfig{vecta,Vect3 sample}
++@sfig{flow, Flow sample}
++@sfig{pipe, Pipe sample}
++
++@sfig{traj, Traj sample}
++@sfig{dew, Dew sample}
++
++@anchor{Extra samples}
++@subheading Examples of additional features
++
++@sfig{inplot, Subplots}
++@sfig{axis, Axis and ticks}
++@sfig{ticks, Axis and ticks}
++@sfig{loglog, Axis and ticks}
++
++@sfig{curvcoor, Curvilinear coordinates}
++@sfig{colorbar, Colorbars}
++@sfig{box, Bounding box}
++@sfig{ternary, Ternary axis}
++
++@sfig{text, Text features}
++@sfig{legend, Legend sample}
++@sfig{cut, Cutting sample}
++@sfig{alpha, Transparency and lighting}
++
++@sfig{type0, Types of transparency}
++@sfig{type1, Types of transparency}
++@sfig{type2, Types of transparency}
++@sfig{fog, Adding fog}
++
++@sfig{combined, ``Compound'' graphics}
++@sfig{several_light, Lighting sample}
++@sfig{stereo, Stereo image}
++@sfig{primitives, Using primitives}
++
++@sfig{stfa, STFA sample}
++@sfig{dat_diff, Change data}
++@sfig{dat_extra, Change data}
++@sfig{map, Mapping visualization}
++
++@sfig{hist, Making histogram}
++@sfig{fit, Nonlinear fitting hints}
++@sfig{pde, PDE solving hints}
++@sfig{parser, Using MGL parser}
++
++@external{}
++
++@node Download, Other projects, Pictures, Website
++@section Download
++@nav{}
++
++@strong{Stable version (v.@value{VERSION})}
++
++You may download current version of MathGL for following configurations:
++@itemize @bullet
++@item
++@uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.tar.gz, Source} file with cmake build system.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}-mingw.win32.7z,GPL} or @uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.LGPL-mingw.win32.7z,LGPL} binaries for MinGW, 32-bit build for Pentium IV.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}-mingw.win64.7z,GPL} or @uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.LGPL-mingw.win64.7z,LGPL} binaries for MinGW, 64-bit build.
++@item
++MathGL utilities with all required DLL files for @uref{http://downloads.sourceforge.net/mathgl/mgl_scripts-@value{VERSION}.win32.7z,32-bit} and @uref{http://downloads.sourceforge.net/mathgl/mgl_scripts-@value{VERSION}.win64.7z,64-bit} versions of MS Windows.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.eng.pdf,PDF} documentation in English.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/mathgl-doc-html-@value{VERSION}@value{MINVER}.7z, Archive} with HTML documentation and figures.
++@c @item
++@c @uref{http://downloads.sourceforge.net/mathgl/mathgl_slides-1.9.pdf,PDF} slideshow of main features
++@end itemize
++
++@strong{Font files}
++
++There are a set of @uref{http://sourceforge.net/project/showfiles.php?group_id=152187&package_id=267177,font files} for MathGL with following typefaces. Note, that the set of glyphs can be less than in default font. As result not all TeX symbols can be displayed.
++@itemize @bullet
++@item
++@uref{http://downloads.sourceforge.net/mathgl/STIX_font.tgz,STIX} font -- default font for MathGL.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/adventor_font.tgz,Adventor font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} sansserif font based on the URW Gothic L family (like Avant Garde Gothic).
++@item
++@uref{http://downloads.sourceforge.net/mathgl/bonum_font.tgz,Bonum font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif font based on the URW Bookman L family.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/chorus_font.tgz,Chorus font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} font based on the URW Chancery L Medium Italic.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/cursor_font.tgz,Cursor font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} monospaced serif font based on the URW Nimbus Mono L (like Courier).
++@item
++@uref{http://downloads.sourceforge.net/mathgl/heros_font.tgz,Heros font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} sansserif font based on the URW Nimbus Sans L (like Helvetica).
++@item
++@uref{http://downloads.sourceforge.net/mathgl/heroscn_font.tgz,HerosCN font} -- the "compressed" version of previous one.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/pagella_font.tgz,Pagella font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif font based on the URW Palladio L (like Palatino).
++@item
++@uref{http://downloads.sourceforge.net/mathgl/schola_font.tgz,Schola font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif fonts is based on the URW Century Schoolbook L.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/termes_font.tgz,Termes font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif fonts is based on the Nimbus Roman No9 L (like Times).
++@end itemize
++
++@external{}
++
++@node Other projects, , Download, Website
++@section Other projects
++@nav{}
++
++Except scientific (non public) projects I also have some general interest projects:
++@itemize @bullet
++@item
++@uref{http://sourceforge.net/projects/pocketmk/, PocketMK} is small program for PocketPC which simulate famous Russian calculators MK-61 and slightly extend it.
++@item
++@uref{http://udav.sourceforge.net/,UDAV} is front-end for MGL scripts. It has windows interface for data viewing, changing and plotting. Also it can execute MGL scripts, setup and rotating graphics and so on.
++@end itemize
++
++Also I recommend to look at:
++@itemize @bullet
++@item
++@uref{http://englab.bugfest.net/,EngLab} is a cross-compile mathematical platform with a C like syntax intended to be used both by engineers and users with small programming knowledge. It is extremely scalable and allows users and the community to easily compile their own functions as shared objects.
++@item
++@uref{http://threedepict.sourceforge.net/,3Depict} is software for analysis of scientific datasets commonly encountered in atom probe tomography. You can manipulate, interact with and analyse point based datasets.
++@item
++@uref{http://www.sourceforge.net/projects/graphplot/,Graphplot} is function plotter based on MathGL.
++@item
++@uref{http://www.sourceforge.net/projects/graphplot/,OscillViewer} is oscilloscope monitoring program. Working with L-Card 14-140 AD-Convertor. Based on Qt and MathGL libraries.
++@end itemize
++
++Finally, few links to free software and libraries:
++@itemize @bullet
++@item
++@uref{http://www.thefreecountry.com/,thefreecountry.com} have a lot of Free Programmers', Webmasters' and Security Resources
++@item
++@uref{http://gnuwin32.sourceforge.net/,GnuWin} provides ports of tools with a GNU or similar open source license, to modern MS-Windows.
++@item
++@uref{http://loll.sourceforge.net/,LLoL} is project collecting, organising, classifying, and maintaining important URLs about Linux and the Open Source movement for all levels of Linux users. The LoLL project now has 4000+ links which are updated usually on a daily basis.
++@end itemize
++
++@external{}
--- /dev/null
--- /dev/null
++@c ------------------------------------------------------------------
++@chapter Website
++@nav{}
++
++@menu
++* Main::
++* News::
++* Features::
++* Pictures::
++@c * MGL scripts::
++* Download::
++* Other projects::
++@end menu
++
++@external{}
++
++@node Main, News, , Website
++@section MathGL is ...
++@nav{}
++
++@ifhtml
++@html
++<a href="Adding-fog.html"><img border="0" align="right" hspace="30" vspace="20" alt="Surface in fog" src="../small/fog-sm.png"></a>
++@end html
++@end ifhtml
++@itemize @bullet
++@item
++a library for making high-quality scientific graphics under Linux and Windows;
++@item
++a library for the fast data plotting and data processing of large data arrays;
++@item
++a library for working in window and console modes and for easy embedding into other programs;
++@item
++a library with large and growing set of graphics.
++@end itemize
++
++Now MathGL has more than 35000 lines of code, more than 55 general types of graphics for 1d, 2d and 3d data arrays, including special ones for chemical and statistical graphics. It can export graphics to raster and vector (EPS or SVG) formats. It has Qt, FLTK, OpenGL interfaces and can be used even from console programs. It has functions for data processing and script MGL language for simplification of data plotting. Also it has several types of transparency and smoothed lightning, vector fonts and TeX-like symbol parsing, arbitrary curvilinear coordinate system and many over useful things. It can be used from code written on C++/C/Fortran/Python/Octave and many other languages. Finally it is platform independent and free (under GPL v.2.0 license).
++
++There is a @uref{http://sourceforge.net/forum/?group_id=152187, forum} where you can ask a question or suggest an improvement. However the @uref{http://groups.google.com/group/mathgl, MathGL group} is preferable for quicker answer.
++
++For subscribing to @uref{http://groups.google.com/group/mathgl, MathGL group} you can use form below
++@ifhtml
++@html
++<form action="http://groups.google.com/group/mathgl/boxsubscribe">
++Email: <input type=text name=email> <input type=submit name="sub" value="Subscribe">
++</form>
++@end html
++@end ifhtml
++
++@strong{About LGPL and GPL licenses.}
++Generally, MathGL is GPL library. However, you can use LGPL license for MathGL core and widgets if you don't use SWIG-based interfaces and disable GSL features. This can be done by using @code{lgpl} option at build time. According this, I've added the LGPL win32 binaries into @ref{Download} page.
++
++@strong{Latest news}
++@itemize
++<<<<<<< HEAD
++@item @strong{20 June 2016.}
++New version (v.@value{VERSION}@value{MINVER}) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are compatibility changes and bugfixes. @strong{NOTE}: there is incompatible change -- the library libmgl-qt is removed. You need to use libmgl-qt4 or libmgl-qt5 explicitly to reduce the possible error of wrong Qt libs linking.
++@item @emph{16 May 2016.}
++New version (v.2.3.5) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, some speeding up and bugfixes, which denoted @ref{News, here}.
++@item @emph{7 August 2014.}
++New version (v.2.3) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are many major improvements for both MathGL core and for UDAV, which denoted @ref{News, here}.
++=======
++
++@item @strong{20 July 2017.}
++New version (v.2.4.1) with bugfixes of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released.
++@item @emph{17 May 2017.}
++New version (v.2.4) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are @code{mgllab} executable, string manipulation in MGL, new functions, plot types and styles, translation to Russian using @code{gettext} and bugfixes, which denoted @ref{News, here}.
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++@end itemize
++
++There is detailed @ref{News, news list}. Sourceforge project page @uref{http://sourceforge.net/projects/mathgl/, here}.
++
++@ifhtml
++@html
++<a href="http://www.datadvance.net"><img border="0" align="right" hspace="10" alt="DATADVANCE" src="../datadvance.png"></a>
++@end html
++@end ifhtml
++Javascript interface was developed with support of @url{http://www.datadvance.net, DATADVANCE} company.
++
++@external{}
++
++@node News, Features, Main, Website
++@section News
++@nav{}
++
++@itemize
++
++<<<<<<< HEAD
++@item @strong{20 June 2016.}
++New version (v.2.3.5.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are compatibility changes and bugfixes. @strong{INCOMPATIBLE}: the library libmgl-qt is removed. You need to use libmgl-qt4 or libmgl-qt5 explicitly to reduce the possible error of wrong Qt libs linking.
++
++@item @strong{16 May 2016.}
++New version (v.2.3.5) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, some speeding up and bugfixes:
++@itemize @bullet
++@item Update @ref{LaTeX package} (thanks to Diego Sejas Viscarra)
++
++@itemize @bullet
++@item
++@code{\MGL@@codes}: Bugfix: category code for tabulators is changed too
++@item
++@code{\MGL@@quality}: 9 is accepted as quality value now
++@item
++@code{\MGL@@scale}: Now accepts any positive value
++@item
++@code{\MGL@@test@@switch}: New command to verify and validate switching arguments
++@item
++@code{\mglTeX}: Add a small negative space in the logo, between the "mgl" and "TEX"
++@item
++@code{\mglTeX}: Declared now as robust command
++@item
++@code{\mglcomments}: Now accepts arguments 0 (equivalent to @code{off}) and 1 (equivalent to @code{on}), besides the usual @code{off} and @code{on}
++@item
++@code{\mglgraphics}: New command options: @code{gray, mglscale, quality, variant}
++@item
++@code{\mglname}: Now writes the MGL code line @samp{setsize 600 400} to the main script
++@item
++@code{\mglplot}: Added @code{\bgroup} and @code{\egroup} in order to keep changes private
++@item
++New command options: @code{gray, mglscale, quality, variant}
++@item
++@code{\mglsettings}: Added options @code{gray} and @code{variant}
++@item
++Now calls the @code{\mglswitch} and @code{\mglcomments} commands for the switch and comments options, respectively
++@item
++@code{\mglswitch}: Now accepts arguments 0 (equivalent to @code{off}) and 1 (equivalent to @code{on}), besides the usual @code{off} and @code{on}
++@item
++mglTeX now depends on the ifpdf package
++@item
++Change definition of @code{\mglcommentname} from MGL comment to mglTEX comment
++@item
++Introduce the concept of global, local and private settings in the documentation
++@item
++New commands: @code{\mglgray} (to activate/deactivate) gray-scale mode locally, and @code{\mglvariant} (to set variant of arguments in MGL scripts locally)
++@item
++New package option @code{9q} for setting quality to 9 (for testing purposes of the author)
++@item
++New package options @code{0v, 1v, 2v} to select variant of arguments in MGL scripts
++@item
++New package options @code{gray, color} to activate/deactivate gray-scale mode for graphics
++@item
++Remove the @code{\MGL@@setkeys} command, since it isn’t needed as first thought
++@item
++Rename @code{\MGL@@document@@scripts} to @code{\MGL@@doc@@scripts}
++@item
++Rename @code{\MGL@@script@@name} to @code{\MGL@@script}
++@item
++Rename command @code{\MGL@@graph@@ext} to @code{\MGL@@imgext}
++@item
++Rename command @code{\mglcommonscriptname} to @code{\mglsetupscriptname}
++@item
++Rename environment @code{mglcommon} to @code{mglsetupscript} (@code{mglcommon} is still available, but deprecated)
++@item
++Rename family @code{MGL@@keys} as @code{MGL@@gr@@keys} for consistency
++@item
++Reorganize and update documentation
++@item
++Some minor bugfixes
++@item
++The MGL code line @samp{setsize 600 400} is now automatically written to the main script in order for the scaling options and commands to work
++@item
++@code{mgl}: New environment options: gray, mglscale, quality, variant
++@item
++@code{\mglcode}: New environment options: gray, mglscale, quality, variant
++@end itemize
++
++@item
++Add MGL command @ref{variant} to select proper variant of arguments (like @samp{var1?var2?var3?...}) in MGL commands.
++@item
++Remove limitation of maximal number (was 1000) of arguments for MGL commands. This is actual for 'list' command.
++@item
++Add mglWnd::Widget() for accessing widget which is used for drawing.
++@item
++Add @ref{gray} for producing gray-scaled image.
++@item
++Add MGL command @ref{setsizescl} for scaling all further @ref{setsize}.
++@item
++Add @ref{shear} for shearing plot.
++@item
++Add @ref{shearplot} for placing plots side-by-side with some shearing.
++@item
++Add @ref{limit} for limit maximal absolute value of data.
++@item
++Add @ref{tridmat} for tridiagonal matrix algorithm.
++@item
++Add MGL command @ref{diffract} for single step diffraction calculation.
++@item
++Add @ref{ifsfile} for reading IFS fractal parameters from *.ifs file.
++@item
++Add style @samp{*} for 2d versions of @ref{flow} to draw threads from points inside axis range.
++@item
++Add @samp{norm()} to the list of known functions
++@item
++Compatibility changes for MS VisualStudio, MacOS, Win64.
++@item
++Bugfix for legend export into EPS and SVG.
++@item
++Bugfix for importing data from std::vector.
++@item
++Improve Surf3*() drawing.
++@item
++Force NAN if divided by 0 in formulas.
++@item
++Option "-S" of mglconv now perform scaling in any cases
++@end itemize
++
++@item @strong{13 February 2016.}
++New version (v.2.3.4) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are new functions, plot types and styles, improvement in MGL scripts and in mgltex, some speeding up and bugfixes:
++@itemize @bullet
++@item Update @ref{LaTeX package} (thanks to Diego Sejas Viscarra)
++
++@item Add @ref{pmap} plot for Poincare map.
++@item Add @ref{lamerey} plot for Lamerey diagram.
++@item Add @ref{bifurcation} plot for Bifurcation diagram.
++@item Add @ref{ifs2d} and @ref{ifs3d} functions for fractal generation using iterated function system (thanks to Diego Sejas Viscarra).
++
++@item Add @ref{pulse} function for determining pulse parameters.
++@item Add @ref{scanfile} function for getting formated data from textual file.
++@item Add mglData::SetList() function for setting data from variable argument list of double values.
++@item Add @ref{echo} command for printing the content of data.
++@item Add @ref{print} command for print messages to stdout immediately.
++@item Add @ref{pendelta} function for changing size of blur area around lines, marks, glyphs, ...
++
++@item Allow MGL command @ref{save} to write/append strings to a file.
++@item Add option to rewrite file in @ref{savehdf} command.
++@item Add option to @ref{setsize} for scaling primitives without its erasing.
++
++@item Add callback functions to mglQt, mglFLTK, and extend @ref{mglDraw class} for simpler drawing in parallel with calculation (see @ref{Draw and calculate}).
++@item Force set focus for editor in UDAV.
++@item Add line numbers to UDAV editor. Cyan number denote current line, red numbers denote lines with errors.
++@item Disable mouse wheel for zooming in UDAV by default.
++
++@item @strong{INCOMPATIBLE} Scale internally d1,d2 arguments in @ref{curve} to be exactly the same as Bezier curve (P0=p1, P1=d1+p1, P2=p2-d2, P3=p2).
++@item Other minor improvements, bugfixes and compatibility changes
++@end itemize
++=======
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++@item @strong{20 July 2017.}
++New version (v.2.4.1) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released.
++@itemize @bullet
++
++@item Add @ref{beltc} plot, which is @ref{belt} with manual coloring.
++@item Add style @samp{~} for @ref{plot} and @ref{tens} to omit some points at output.
++@item Add style @samp{:} for @ref{axis} to draw lines through point (0,0,0).
++@item Bugfixes.
++
++@end itemize
++
++@item @strong{17 May 2017.}
++New version (v.2.4) of @uref{http://sourceforge.net/projects/mathgl, MathGL} is released. There are @code{mgllab} executable, string manipulation in MGL, new functions, plot types and styles, translation to Russian using @code{gettext} and bugfixes:
++@itemize @bullet
++
++@item Add @code{mgllab} executable, which is FLTK based version of @code{UDAV}. So, most things @code{mgllab} do faster.
++@item Add string manipulation in MGL language:
++@itemize @bullet
++ @item 'str'[n] -- get string of only n-th symbol;
++ @item 'str'+v -- add value v to the last character of the string;
++ @item 'str',val or 'str',!val -- append numeric value to the string (as before).
++@end itemize
++@item Add time value to MGL language in format: @samp{hh-mm-ss_DD.MM.YYYY} or @samp{hh-mm-ss} or @samp{DD.MM.YYYY}.
++@item Add @ref{iris} plot to show cross-dependencies of several data arrays.
++@item Add @ref{flame2d} to draw flame fractals.
++@item Add @ref{bbox} to set bounding box for 2D output.
++@item Add @ref{section} to get part of data between specified values.
++@item Add @ref{detect} to found curves along data maximums.
++@item Add @ref{dilate} to extend the region of 1-th value.
++@item Add @ref{erode} to narrow the region of 1-th value.
++@item Add @ref{apde} to solve PDE equation in inhomogeneous nonlinear media with spatial dispersion.
++@item Add @ref{symbol} to draw the glyphs defined by @ref{addsymbol}.
++@item Add @ref{addsymbol} to declare user-defined symbol (or glyph), which can be used as markers for plot (with style '&') or drawn itself by @ref{symbol} command.
++@item Add @ref{openhdf} to open all data arrays from HDF file.
++@item Extend @ref{crop} to cut to optimal size for FFT (i.e. to closest of 2^n*3^m*5^l).
++@item Add function mgl_data_max_first() and data suffixes .m[xyz][fl] to find first/last maximum along direction (see @ref{Data information}).
++@item Add function mgl_datac_diff_par() to parametric derivative of complex data (see @ref{diff}).
++@item Add style @samp{F} for @ref{bars} and @ref{barh} to set fixed bar widths.
++@item Add style @samp{a} for @ref{plot}, @ref{tens}, @ref{area} and @ref{region} to accurate drawing of data, which partially lie out of axis range.
++@item Add style @samp{#} for @ref{region} to draw wired plot.
++@item Add possibility of manual shift in @ref{multiplot}.
++@item Add parsing arguments of options for MGL commands.
++@item MGL command @ref{correl} now can perform 2d and 3d correlations.
++@item Option @ref{meshnum} now change the number of drawn markers for @ref{plot}, @ref{tens}, @ref{step}, @ref{mark} and @ref{textmark}.
++@item Function @ref{step} handle data with x.nx>y.nx similarly to @ref{bars}.
++@item Extend @ref{tile} and @ref{tiles} by adding manual coloring and face orientation.
++@item Add variant of MGL command @ref{copy} to copy data with "incorrect" names.
++@item Improve tick labels drawing.
++@item Improve time-ticks (add weeks) and add subticks to its.
++@item Improve @ref{fplot} to handle several singularities.
++@item Add LaTeX command \dfrac@{@}@{@}. This is full-sized version of \frac@{@}@{@}. Unfortunately, there is no support of nesting. Contrary, \frac allow nesting.
++@item Add mglODEc() -- ODE solver for complex variables (see @ref{ode}).
++@item Add cmplx(a,b)=a+i*b to the list of known functions in formula parsing
++@item Update CMake find_package to find MathGL.
++@item Increase line width for wired text.
++@item Update documentation: add description of new commands, add hint @ref{Mixing bitmap and vector output}.
++@item Add translation to Russian for most of labels and messages.
++@item Name @code{all} are reserved in MGL scripts now as synonym of -1.
++
++@item INCOMPATIBLE: Replace libmgl-qt by libmgl-qt4 and libmgl-qt5 for resolving conflicts of simultaneously installed both Qt4 and Qt5.
++@item Minor bugfixes.
++
++@end itemize
++
++@item @strong{20 June 2016.} Version 2.3.5.1 was released.
++@item @strong{16 May 2016.} Version 2.3.5 was released.
++@item @strong{13 February 2016.} Version 2.3.4 was released.
++@item @strong{1 June 2015.} Version 2.3.3 was released.
++@item @strong{2 February 2015.} Version 2.3.2 was released.
++@item @strong{21 October 2014.} Version 2.3.1 was released.
++@item @strong{7 August 2014.} Version 2.3 was released.
++@item @strong{19 March 2014.} Version 2.2.2.1 was released.
++@item @strong{10 March 2014.} Version 2.2.2 was released.
++@item @strong{22 January 2014.} Version 2.2.1 was released.
++@item @strong{11 November 2013.} Version 2.2 was released.
++@item @strong{8 May 2013.} Version 2.1.3.1 was released.
++@item @strong{2 May 2013.} Version 2.1.3 was released.
++@item @strong{28 January 2013.} Version 2.1.2 was released.
++@item @strong{24 December 2012.} Version 2.1.1 was released.
++@item @strong{13 December 2012.} Version 2.1 was released.
++@item @strong{23 August 2011.} Version 2.0.beta was released.
++@item @strong{30 May 2011.} Version 1.11.2 was released.
++@item @strong{8 November 2010.} Version 1.11 was released.
++@item @strong{28 December 2009.} Version 1.10 was released.
++@item @strong{8 July 2009.} Version 1.9 was released.
++@item @strong{27 November 2008.} Version 1.8 was released.
++@item @strong{5 June 2008.} Version 1.7 was released.
++@item @strong{17 March 2008.} Version 1.6 was released.
++@item @strong{11 January 2008.} Version 1.5 was released.
++@item @strong{30 October 2007.} Version 1.4 was released.
++@item @strong{15 October 2007.} Version 1.3 was released.
++@item @strong{10 September 2007.} Version 1.2 was released.
++@item @strong{23 May 2007.} Version 1.1 was released.
++@item @strong{2 April 2007.} Version 1.0 was released.
++@item @strong{24 January 2007.} First public release (v.0.8).
++@end itemize
++
++@external{}
++
++
++@node Features, Pictures, News, Website
++@section Features
++@nav{}
++
++MathGL can plot a wide range of graphics. It includes:
++@itemize @bullet
++@item
++one-dimensional: Plot, Area, Bars, Step, Stem, Torus, Chart, Error, Tube, Mark, (@ref{1D plotting});
++
++@item
++two-dimensional plots: Mesh, Surf, Dens, Cont, ContF, Boxs, Axial, Fall, Belt, Tile, including surfaces transparent (SurfA) or colored (SurfC) by another data (@ref{2D plotting});
++
++@item
++three-dimensional plots: Surf3, Dens3, Cont3, ContF3, Cloud-like, including isosurfaces transparent (Surf3A) or colored (Surf3C) by another data (@ref{3D plotting});
++
++@item
++vector fields plots: vector fields Vect, Vect3 and Traj, flow threads Flow, flow pipes Pipe, mapping chart Map, and so on (@ref{Vector fields});
++
++@item
++and so on. See also @ref{Extra samples}.
++@end itemize
++
++In fact, I created the functions for drawing of all the types of scientific plots that I know. The list of plots is growing; if you need some special type of a plot then please email me @email{mathgl.abalakin@@gmail.com, e-mail} and it will appear in the new version.
++
++I tried to make plots as nice looking as possible: e.g., a surface can be transparent and highlighted by several (up to 10) light sources. Most of the drawing functions have 2 variants: simple one for the fast plotting of data, complex one for specifying of the exact position of the plot (including parametric representation). Resulting image can be saved in bitmap PNG, JPEG, TGA, BMP format, or in vector EPS, SVG or TeX format, or in 3D formats OBJ, OFF, STL or in PRC format.
++
++All texts are drawn by vector fonts, which allows for high scalability and portability. Texts may contain commands for: some of the TeX-like symbols, changing index (upper or lower indexes) and the style of font inside the text string. Texts of ticks are rotated with axis rotation. It is possible to create a legend of plot and put text in an arbitrary position on the plot. Arbitrary text encoding (by the help of function @code{setlocale()}) and UTF-16 encoding are supported.
++
++Special class mglData is used for data encapsulation. In addition to a safe creation and deletion of data arrays it includes functions for data processing (smoothing, differentiating, integrating, interpolating and so on) and reading of data files with automatic size determination. Class mglData can handle arrays with up to three dimensions (arrays which depend on up to 3 independent indexes @math{a_@{ijk@}}). Using an array with higher number of dimensions is not meaningful, because I do not know how it can be plotted. Data filling and modification may be done manually or by textual formulas.
++
++There is fast evaluation of a textual mathematical expression. It is based on string precompilation to tree-like code at the creation of class instance. At evaluation stage code performs only fast tree-walk and returns the value of the expression. In addition to changing data values, textual formulas are also used for drawing in @emph{arbitrary} curvilinear coordinates. A set of such curvilinear coordinates is limited only by user's imagination rather than a fixed list like: polar, parabolic, spherical, and so on.
++
++@external{}
++
++@node Pictures, Download, Features, Website
++@section Pictures
++@nav{}
++
++There are samples for @ref{1D data plotting, 1D arrays}, @ref{2D data plotting, 2D arrays}, @ref{3D data plotting, 3D arrays}, @ref{Vector fields plotting} and some @ref{Extra samples}.
++
++@anchor{1D data plotting}
++@subheading Examples of graphics for 1d arrays
++
++@sfig{plot, Plot sample}
++@sfig{radar, Radar sample}
++@sfig{step, Step sample}
++@sfig{tens, Tens sample}
++
++@sfig{area, Area sample}
++@sfig{region,Region sample}
++@sfig{stem, Stem sample}
++@sfig{torus,Torus sample}
++
++@sfig{bars, Bars sample}
++@sfig{barh, Barh sample}
++@sfig{cones,Cones sample}
++@sfig{chart,Chart sample}
++
++@sfig{boxplot,BoxPlot sample}
++@sfig{candle, Candle sample}
++@sfig{tube, Tube sample}
++@sfig{tape, Tape sample}
++
++@sfig{error,Error sample}
++@sfig{mark, Mark sample}
++@sfig{textmark, TextMark sample}
++@sfig{label,Label sample}
++
++@anchor{2D data plotting}
++@subheading Examples of graphics for 2d arrays
++
++@sfig{surf, Surf sample}
++@sfig{surfc,SurfC sample}
++@sfig{surfa,SurfA sample}
++@sfig{mesh, Mesh sample}
++
++@sfig{fall, Fall sample}
++@sfig{belt, Belt sample}
++@sfig{boxs, Boxs sample}
++@sfig{axial,Axial sample}
++
++@sfig{dens, Dens sample}
++@sfig{tile, Tile sample}
++@sfig{tiles,TileS sample}
++@sfig{grad, Grad sample}
++
++@sfig{cont, Cont sample}
++@sfig{contf,ContF sample}
++@sfig{contd,ContD sample}
++@sfig{contv,ContV sample}
++
++@anchor{3D data plotting}
++@subheading Examples of graphics for 3d arrays
++
++@sfig{surf3, Surf3 sample}
++@sfig{surf3c,Surf3C sample}
++@sfig{surf3a,Surf3A sample}
++@sfig{cloud, Cloud sample}
++
++@sfig{densa, Dens3 sample}
++@sfig{conta, Cont3 sample}
++@sfig{contfa,ContF3 sample}
++@sfig{dots, Dots sample}
++
++@sfig{dens_xyz, Dens projection sample}
++@sfig{cont_xyz, Cont projection sample}
++@sfig{contf_xyz,ContF projection sample}
++@sfig{triplot, TriPlot and QuadPlot}
++
++@anchor{Vector fields plotting}
++@subheading Examples of graphics for vector fields
++
++@sfig{vect, Vect sample}
++@sfig{vecta,Vect3 sample}
++@sfig{flow, Flow sample}
++@sfig{pipe, Pipe sample}
++
++@sfig{traj, Traj sample}
++@sfig{dew, Dew sample}
++
++@anchor{Extra samples}
++@subheading Examples of additional features
++
++@sfig{inplot, Subplots}
++@sfig{axis, Axis and ticks}
++@sfig{ticks, Axis and ticks}
++@sfig{loglog, Axis and ticks}
++
++@sfig{curvcoor, Curvilinear coordinates}
++@sfig{colorbar, Colorbars}
++@sfig{box, Bounding box}
++@sfig{ternary, Ternary axis}
++
++@sfig{text, Text features}
++@sfig{legend, Legend sample}
++@sfig{cut, Cutting sample}
++@sfig{alpha, Transparency and lighting}
++
++@sfig{type0, Types of transparency}
++@sfig{type1, Types of transparency}
++@sfig{type2, Types of transparency}
++@sfig{fog, Adding fog}
++
++@sfig{combined, ``Compound'' graphics}
++@sfig{several_light, Lighting sample}
++@sfig{stereo, Stereo image}
++@sfig{primitives, Using primitives}
++
++@sfig{stfa, STFA sample}
++@sfig{dat_diff, Change data}
++@sfig{dat_extra, Change data}
++@sfig{map, Mapping visualization}
++
++@sfig{hist, Making histogram}
++@sfig{fit, Nonlinear fitting hints}
++@sfig{pde, PDE solving hints}
++@sfig{parser, Using MGL parser}
++
++@external{}
++
++@node Download, Other projects, Pictures, Website
++@section Download
++@nav{}
++
++@strong{Stable version (v.@value{VERSION})}
++
++You may download current version of MathGL for following configurations:
++@itemize @bullet
++@item
++@uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.tar.gz, Source} file with cmake build system.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}-mingw.win32.7z,GPL} or @uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.LGPL-mingw.win32.7z,LGPL} binaries for MinGW, 32-bit build for Pentium IV.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}-mingw.win64.7z,GPL} or @uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.LGPL-mingw.win64.7z,LGPL} binaries for MinGW, 64-bit build.
++@item
++MathGL utilities with all required DLL files for @uref{http://downloads.sourceforge.net/mathgl/mgl_scripts-@value{VERSION}.win32.7z,32-bit} and @uref{http://downloads.sourceforge.net/mathgl/mgl_scripts-@value{VERSION}.win64.7z,64-bit} versions of MS Windows.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/mathgl-@value{VERSION}@value{MINVER}.eng.pdf,PDF} documentation in English.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/mathgl-doc-html-@value{VERSION}@value{MINVER}.7z, Archive} with HTML documentation and figures.
++@c @item
++@c @uref{http://downloads.sourceforge.net/mathgl/mathgl_slides-1.9.pdf,PDF} slideshow of main features
++@end itemize
++
++@strong{Font files}
++
++There are a set of @uref{http://sourceforge.net/project/showfiles.php?group_id=152187&package_id=267177,font files} for MathGL with following typefaces. Note, that the set of glyphs can be less than in default font. As result not all TeX symbols can be displayed.
++@itemize @bullet
++@item
++@uref{http://downloads.sourceforge.net/mathgl/STIX_font.tgz,STIX} font -- default font for MathGL.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/adventor_font.tgz,Adventor font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} sansserif font based on the URW Gothic L family (like Avant Garde Gothic).
++@item
++@uref{http://downloads.sourceforge.net/mathgl/bonum_font.tgz,Bonum font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif font based on the URW Bookman L family.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/chorus_font.tgz,Chorus font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} font based on the URW Chancery L Medium Italic.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/cursor_font.tgz,Cursor font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} monospaced serif font based on the URW Nimbus Mono L (like Courier).
++@item
++@uref{http://downloads.sourceforge.net/mathgl/heros_font.tgz,Heros font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} sansserif font based on the URW Nimbus Sans L (like Helvetica).
++@item
++@uref{http://downloads.sourceforge.net/mathgl/heroscn_font.tgz,HerosCN font} -- the "compressed" version of previous one.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/pagella_font.tgz,Pagella font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif font based on the URW Palladio L (like Palatino).
++@item
++@uref{http://downloads.sourceforge.net/mathgl/schola_font.tgz,Schola font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif fonts is based on the URW Century Schoolbook L.
++@item
++@uref{http://downloads.sourceforge.net/mathgl/termes_font.tgz,Termes font} -- the @uref{http://www.gust.org.pl/projects/e-foundry/tex-gyre/index_html,TeX Gyre} serif fonts is based on the Nimbus Roman No9 L (like Times).
++@end itemize
++
++@external{}
++
++@node Other projects, , Download, Website
++@section Other projects
++@nav{}
++
++Except scientific (non public) projects I also have some general interest projects:
++@itemize @bullet
++@item
++@uref{http://sourceforge.net/projects/pocketmk/, PocketMK} is small program for PocketPC which simulate famous Russian calculators MK-61 and slightly extend it.
++@item
++@uref{http://udav.sourceforge.net/,UDAV} is front-end for MGL scripts. It has windows interface for data viewing, changing and plotting. Also it can execute MGL scripts, setup and rotating graphics and so on.
++@end itemize
++
++Also I recommend to look at:
++@itemize @bullet
++@item
++@uref{http://englab.bugfest.net/,EngLab} is a cross-compile mathematical platform with a C like syntax intended to be used both by engineers and users with small programming knowledge. It is extremely scalable and allows users and the community to easily compile their own functions as shared objects.
++@item
++@uref{http://threedepict.sourceforge.net/,3Depict} is software for analysis of scientific datasets commonly encountered in atom probe tomography. You can manipulate, interact with and analyse point based datasets.
++@item
++@uref{http://www.sourceforge.net/projects/graphplot/,Graphplot} is function plotter based on MathGL.
++@item
++@uref{http://www.sourceforge.net/projects/graphplot/,OscillViewer} is oscilloscope monitoring program. Working with L-Card 14-140 AD-Convertor. Based on Qt and MathGL libraries.
++@end itemize
++
++Finally, few links to free software and libraries:
++@itemize @bullet
++@item
++@uref{http://www.thefreecountry.com/,thefreecountry.com} have a lot of Free Programmers', Webmasters' and Security Resources
++@item
++@uref{http://gnuwin32.sourceforge.net/,GnuWin} provides ports of tools with a GNU or similar open source license, to modern MS-Windows.
++@item
++@uref{http://loll.sourceforge.net/,LLoL} is project collecting, organising, classifying, and maintaining important URLs about Linux and the Open Source movement for all levels of Linux users. The LoLL project now has 4000+ links which are updated usually on a daily basis.
++@end itemize
++
++@external{}
--- /dev/null
--- /dev/null
++-Wall -Wsuggest-attribute=pure -Wsuggest-attribute=const
++
++============= FAR FUTURE ================
++
++1. Export to COLLADA or X3D !!!
++2. Use mglDataV in 'var' ?!?
++
++3. Contour lines for bilinear interpolation (strong saddle-like faces) -- best way by adding curve primitive (type=5)?!?
++4. 3D text (with depth), and text along 3D curve (for Quality=3) ???
++5. Get true coordinates in CalcXYZ for curved equations too.
++6. Extra markers for '&' and '&#' signs ?!? or user-defined signs
++
++7. Improve z-order for rapidly oscillating surfaces (сравнение проекций центров на грань -- too slow)
++
++8. Enable consecutive (as multiplication of matrices instead of single summary one) rotation of axis + the same in JS. Problem with widgets?!?
++
++9. Export background image to svg ???
++
++10. Frames by mouse in UDAV ???
++ A. мысли о frame??? для группы графиков -- не "удалять" их, а запихивать в отдельный кадр -- вопрос что с анимацией???
++ B. как делать анимацию (кадры) для мышиной версии ... список кадров, кнопки добавить в кадры + вставить из кадра
++
++11. Parallel drawing in QMathGL (looks to complicated -- FLTK is better!)
++12. \overline{\overline{a}} ???
++13. Manual AddPnt() with specified id + openmp ?!? -- possible memory overuse
++
++
++============= NEW FEATURES =============
++
++1. Centered curved text (see text2)
++2. Read MAT files ?!!
++3. Read WFM files ?!!
++4. "latex on" option ?!?
++
++5. Add 'goto' or 'do|while' command
++6. Extend 'ask' as:
++ ask $N1 'text|kind:arg1:arg2:...' $N2 'text|kind:arg1:arg2:...' ...
++ where kind={default=edit,spin,choice,check,slider,float?}
++7. Add ##d comment(s) -- analogue of 'ask' but update figure after each change ???
++8. Add "mgl_zoomview(int x, int y)" for zoom circle around image point {x,y}
++9. Mask in EPS/SVG
++11. Add momentum dat vdat ... where vdat is corresponding coordinate ???
++
++17. Speed up QMathGL + option to whole redraw instead of view
++
++ZZ. Update *.i for new functions {before release!!!}
++
++
++============= DOCUMENTATION =============
++
++A. Paper about MathGL!!!
++B. Add chapter with real samples
++C. Translate to Russian everything
++D. Docs about JS interface
++
++1. Update Qt and UDAV figures
++<<<<<<< HEAD
++2. Sample about PDE -- add 'tridmat' + 'diffract'
++3. Replace mgl-qt!!!
++4. Step_xy() now can have x.nx>y.nx -- same as Bars()
++5. Docs about 'flame2d'
++=======
++
++2. Sample about PDE -- add 'tridmat' + 'diffract'
++3. Sample about complex 'ode' (like Raman scattering)
++4. Sample about earth map
++5. Sample about 'erode' and 'dilate'
++7. Sample about 'detect'
++8. Sample about 'section'
++
++26. Update installation (dll from mgl_script + Qt plugins/ + Win10)
++
++ZZ. Update time.texi {before release!!!}
++
++как начать пользоваться (quickstart)
++как скомпилировать и установить (building & installing)
++как запустить (running)
++как протестировать свои правки (testing)
++как настроить (configuration)
++какие есть примеры использования (examples)
++
++============= mgllab ===========
++
++* Manual data changing should be written into script ?!?
++* Check: "You can shift axis range by pressing middle button and moving mouse. Also, you can zoom in/out axis range by using mouse wheel."
++* Shift/Zoom/Perspective by mouse!!!
++* Hint about string manipulation
++* Progress bar for external loop ?!!
++* 1d view -- over longer size + y-size for current slice only
++
++X. Own file-chooser dialog -- separate path and fname fields + add sorting by date|size
++Y. Window with Zoom/Hidden ???
++Z. Flat toolbuttons ???
++
++
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++============= UDAV =============
++
++1. Zoom rectangle after mouse selection
++
++3. Manual data changing should be written into script
++ a. Suggest to save into HDF5 if data changed manually
++ b. Each manual change in cell produce command like 'put dat val i j k'
++ c. Add command to insert as 'list'
++ d. Reset script after saving to HDF5 or putting to main script
++ e. Ask about script changes before closing data tab
++4. List of constants into the list of data?!
++5. Add color cycle ???
++6. Color position in color scheme dialog
++7. Select 'bbox' by mouse
++9. Save data from the summary panel
++10. Select subdata section (between NAN in curve) by mouse + adding it to script ?!!
++11. Zoom in a region by middle mouse (if not in rotation mode)
++12. Extend 'ask' by adding multiple questions simultaneously (+ set/get default values from file ???)
++
++============= UNSURE ===========
++
++1. GTK window/widgets ???
++2. "Cut off" curves if text is printed inside it (for contour labels) ?!?
++4. Read DICOM files
++5. Check RunThr() in python/octave
++6. Auto axis range for formulas, like AutoRange("y(x)") or AutoRange('x',"x(t)").
++7. Use Hershey as built-in font ??? -- for smaller size only
--- /dev/null
--- /dev/null
++/***************************************************************************
++ * Copyright (C) 2008 by Alexey Balakin *
++ * mathgl.abalakin@gmail.com *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
++ ***************************************************************************/
++#ifndef ANIMPARAM_H
++#define ANIMPARAM_H
++//-----------------------------------------------------------------------------
++#include <QDialog>
++<<<<<<< HEAD
++#if defined(_MSC_VER)
++#include <mgl2/define.h>
++#endif
++=======
++#include "mgl2/define.h"
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++//-----------------------------------------------------------------------------
++class QLineEdit;
++class QTextEdit;
++class QRadioButton;
++class QCheckBox;
++/// Setup animation parqmeters
++class AnimParam : public QDialog
++{
++Q_OBJECT
++public:
++ bool gifOn, jpgOn;
++ /// string with resulting animation parameters
++ const QString &getResult() { return res; }
++ void setResult(const QString &s);
++ void setResult(double a1,double a2,double da);
++ AnimParam(QWidget *parent=0);
++ ~AnimParam();
++signals:
++ void putText(const QString &par);
++private slots:
++ void fillRes();
++ void putTxt();
++ void setRBF();
++ void setRBT();
++private:
++ QString res;
++ QLineEdit *p1, *p2, *dp, *delay;//, *fname;
++ QTextEdit *text;
++ QRadioButton *rbt, *rbf;
++ QCheckBox *gif, *jpg;
++};
++//-----------------------------------------------------------------------------
++#endif
++//-----------------------------------------------------------------------------
--- /dev/null
--- /dev/null
++/***************************************************************************
++ * Copyright (C) 2008 by Alexey Balakin *
++ * mathgl.abalakin@gmail.com *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
++ ***************************************************************************/
++#include <QTableWidget>
++#include <QLabel>
++#include <QAction>
++#include <QLayout>
++#include <QMenuBar>
++#include <QLineEdit>
++#include <QMenu>
++#include <QClipboard>
++#include <QStatusBar>
++#include <QFileDialog>
++#include <QPushButton>
++#include <QApplication>
++#include <QInputDialog>
++#include <QToolButton>
++#include <QSpinBox>
++#include <QComboBox>
++#include <QCheckBox>
++#include <QMessageBox>
++#include <mgl2/mgl.h>
++//-----------------------------------------------------------------------------
++#include "dat_pnl.h"
++#include "info_dlg.h"
++#include "xpm/table.xpm"
++#undef sprintf // fix libintl bug of defining sprintf
++//-----------------------------------------------------------------------------
++extern mglParse parser;
++void updateDataItems();
++void addDataPanel(QWidget *wnd, QWidget *w, QString name);
++void deleteDat(void *o) { if(o) delete ((DatPanel *)o); }
++void refreshData(QWidget *w) { ((DatPanel *)w)->refresh(); }
++//-----------------------------------------------------------------------------
++QWidget *newDataWnd(InfoDialog *inf, QWidget *wnd, mglDataA *v)
++{
++ DatPanel *t = new DatPanel(inf);
++ if(v) t->setVar(v);
++ addDataPanel(wnd,t,t->dataName());
++ return t;
++}
++//-----------------------------------------------------------------------------
++DatPanel::DatPanel(InfoDialog *inf, QWidget *parent) : QWidget(parent)
++{
++ setAttribute(Qt::WA_DeleteOnClose);
++ kz = nx = ny = nz = 0; var = 0;
++ ready = false; infoDlg = inf;
++ QBoxLayout *v,*h,*m;
++
++ menu = new QMenu(_("Data"),this);
++ v = new QVBoxLayout(this);
++ h = new QHBoxLayout(); v->addLayout(h); toolTop(h);
++ h = new QHBoxLayout(); v->addLayout(h);
++ m = new QVBoxLayout(); h->addLayout(m); toolLeft(m);
++ tab = new QTableWidget(this); h->addWidget(tab);
++ connect(tab, SIGNAL(cellChanged(int,int)), this, SLOT(putValue(int, int)));
++
++ setWindowIcon(QPixmap(table_xpm));
++}
++//-----------------------------------------------------------------------------
++DatPanel::~DatPanel() { if(var && var->o==this) var->o = 0; }
++//-----------------------------------------------------------------------------
++void DatPanel::refresh()
++{
++ bool rc = false;
++ if(!var) return;
++ infoDlg->allowRefresh=false;
++ if(nx!=var->GetNx()) { nx = var->GetNx(); tab->setColumnCount(nx); rc=true; }
++ if(ny!=var->GetNy()) { ny = var->GetNy(); tab->setRowCount(ny); rc=true; }
++ if(kz>=var->GetNz()) { kz = 0; emit sliceChanged(0); }
++ if(nz!=var->GetNz()) { nz = var->GetNz(); emit nzChanged(nz); }
++ const mglData *dd = dynamic_cast<const mglData *>(var); if(dd) id = QString(dd->id.c_str());
++ const mglDataC *dc = dynamic_cast<const mglDataC *>(var); if(dc) id = QString(dc->id.c_str());
++ if(nz==1 && ny>1 && !id.isEmpty())
++ {
++ QStringList head;
++ QString s;
++ for(int i=0;i<ny;i++)
++ {
++ s = QString("%1").arg(i);
++ if(id[i]>='a' && id[i]<='z') s=s+" ("+id[i]+")";
++ head<<s;
++ }
++ tab->setHorizontalHeaderLabels(head);
++ }
++ long m=var->s.length();
++ QString s,d;
++ if(rc)
++ {
++ QStringList sh,sv;
++ for(long i=0;i<nx;i++) sh<<QString::number(i);
++ tab->setHorizontalHeaderLabels(sh);
++ for(long i=0;i<ny;i++) sv<<QString::number(i);
++ tab->setVerticalHeaderLabels(sv);
++ for(long i=0;i<nx;i++) for(long j=0;j<ny;j++)
++ tab->setItem(j,i,new QTableWidgetItem);
++ }
++ mglDataC *cc = dynamic_cast<mglDataC*>(var);
++ if(cc) for(long i=0;i<nx;i++) for(long j=0;j<ny;j++)
++ {
++ dual f = cc->a[i+nx*(j+ny*kz)];
++ if(mgl_isnan(f)) s = "nan";
++ else if(mgl_isbad(f)) s="inf";
++ else if(imag(f)>0) s.sprintf("%.15g+%.15gi",real(f),imag(f));
++ else if(imag(f)<0) s.sprintf("%.15g-%.15gi",real(f),-imag(f));
++ else s.sprintf("%15g",real(f));
++ tab->item(j,i)->setText(s);
++ }
++ else for(long i=0;i<nx;i++) for(long j=0;j<ny;j++)
++ {
++ double f = var->v(i,j,kz);
++ if(mgl_isnan(f)) s = "nan";
++ else if(mgl_isbad(f)) s=f>0?"inf":"-inf";
++ else s.sprintf("%.15g",f);
++ tab->item(j,i)->setText(s);
++ }
++ infoDlg->allowRefresh=true; infoDlg->refresh();
++ QChar *ss = new QChar[m+1];
++ for(long i=0;i<m;i++) ss[i] = var->s[i];
++ s = QString(ss, m); delete []ss;
++ d.sprintf("%d * %d * %d", nx, ny, nz);
++ ready = true;
++}
++//-----------------------------------------------------------------------------
++void DatPanel::setVar(mglDataA *v)
++{
++ ready = false;
++ if(var) var->o = 0;
++ var = v; infoDlg->setVar(v);
++ nx = ny = nz = kz = 0;
++ if(v)
++ {
++ QString s = QString::fromWCharArray(v->s.c_str());
++ v->o = this; v->func = deleteDat;
++ refresh();
++ setWindowTitle(s + _(" - UDAV variable"));
++ infoDlg->setWindowTitle(s + _(" - UDAV preview"));
++ }
++ else
++ { tab->setColumnCount(0); tab->setRowCount(0); emit nzChanged(nz); }
++ emit sliceChanged(0);
++}
++//-----------------------------------------------------------------------------
++void DatPanel::setSlice(int k)
++{
++ if(k>=nz) k=nz-1;
++ if(k<0) k=0;
++ if(k!=kz)
++ {
++ infoDlg->setSlice(k);
++ emit sliceChanged(k);
++ kz = k; refresh();
++ }
++}
++//-----------------------------------------------------------------------------
++dual mgl_str2dual(const char *s)
++{
++ setlocale(LC_NUMERIC, "C");
++ double re=0,im=0; size_t ll=strlen(s);
++ while(s[ll]<=' ') ll--;
++ if(*s=='(') sscanf(s,"(%lg,%lg)",&re,&im);
++ else if(*s=='i') { re=0; im=atof(s+1); }
++ else if(*s=='[') sscanf(s,"[%lg,%lg]",&re,&im);
++ else if(*s=='{') sscanf(s,"{%lg,%lg}",&re,&im);
++ else if(s[ll]=='i')
++ {
++ double a,b;
++ int s1=sscanf(s,"%lg+%lgi",&re,&im);
++ int s2=sscanf(s,"%lg-%lgi",&a,&b);
++ if(s1<2)
++ {
++ if(s2==2) { re=a; im=-b; }
++ else { im=atof(s); re=0; }
++ }
++ }
++ else
++ {
++ double a,b;
++ int s1=sscanf(s,"%lg+i%lg",&re,&im);
++ int s2=sscanf(s,"%lg-i%lg",&a,&b);
++ if(s1<2)
++ {
++ if(s2==2) { re=a; im=-b; }
++ else { re=atof(s); im=0; }
++ }
++ }
++ setlocale(LC_NUMERIC, "");
++ return dual(re,im);
++}
++//-----------------------------------------------------------------------------
++void DatPanel::putValue(int r, int c)
++{
++ if(!var || r<0 || c<0 || r>=ny || c>=nx || !ready) return;
++ QString s = tab->item(r,c)->text().toLower();
++ mreal f;
++ dual g;
++ if(s=="nan") f=NAN;
++ else if(s=="inf") f=INFINITY;
++ else if(s=="-inf") f=-INFINITY;
++<<<<<<< HEAD
++ else g = mgl_str2dual(s.toLocal8Bit().constData()); //f = s.toDouble();
++ f = real(g);
++=======
++ else
++ { g = mgl_str2dual(s.toLocal8Bit().constData()); f = real(g); }
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ mglDataC *cc = dynamic_cast<mglDataC*>(var);
++ if(cc)
++ {
++ if(g!=cc->a[c+nx*(r+ny*kz)])
++ {
++ if(mgl_isnan(g)) s="nan";
++ else if(mgl_isbad(g)) s="inf";
++ else if(imag(g)>0) s.sprintf("%g+%gi",real(g),imag(g));
++ else if(imag(g)<0) s.sprintf("%g-%gi",real(g),-imag(g));
++ else s.sprintf("%g",real(g));
++ tab->item(r,c)->setText(s);
++ }
++ cc->a[c+nx*(r+ny*kz)] = g;
++ }
++ else
++ {
++ if(f!=var->v(c,r,kz))
++ {
++ if(mgl_isnan(f)) s="nan";
++ else if(mgl_isbad(f)) s=f>0?"inf":"-inf";
++ else s.sprintf("%g", f);
++ tab->item(r,c)->setText(s);
++ }
++ var->set_v(f,c,r,kz);
++ }
++ infoDlg->refresh();
++}
++//-----------------------------------------------------------------------------
++void DatPanel::save()
++{
++ QString fn = QFileDialog::getSaveFileName(this, _("UDAV - Save/export data"), "",
++ _("Data files (*.dat)\nHDF5 files (*.h5 *.hdf)\nPNG files (*.png)\nAll files (*.*)"));
++ if(fn.isEmpty()) return;
++ QString ext = fn.section(".",-1);
++ if(ext=="png")
++ {
++ bool ok;
++<<<<<<< HEAD
++ QString s = QInputDialog::getText(this, tr("UDAV - Export to PNG"), tr("Enter color scheme for picture"), QLineEdit::Normal, MGL_DEF_SCH, &ok);
++=======
++ QString s = QInputDialog::getText(this, _("UDAV - Export to PNG"), _("Enter color scheme"), QLineEdit::Normal, MGL_DEF_SCH, &ok);
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ if(ok) var->Export(fn.toLocal8Bit().constData(), s.toLocal8Bit().constData());
++ }
++ else if(ext=="h5" || ext=="hdf")
++ {
++ bool ok;
++<<<<<<< HEAD
++ QString s = QInputDialog::getText(this, tr("UDAV - Save to HDF"), tr("Enter data name"), QLineEdit::Normal, QString::fromWCharArray(var->s.c_str()), &ok);
++=======
++ QString s = QInputDialog::getText(this, _("UDAV - Save to HDF"), _("Enter data name"), QLineEdit::Normal, QString::fromWCharArray(var->s.c_str()), &ok);
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ if(ok) var->SaveHDF(fn.toLocal8Bit().constData(), s.toLocal8Bit().constData());
++ }
++ else var->Save(fn.toLocal8Bit().constData());
++}
++//-----------------------------------------------------------------------------
++void DatPanel::load()
++{
++ mglData *d = dynamic_cast<mglData *>(var); if(!d) return;
++ QString fn = QFileDialog::getOpenFileName(this, _("UDAV - Load data"), "",
++ _("Data files (*.dat)\nHDF5 files (*.h5 *.hdf)\nPNG files (*.png)\nAll files (*.*)"));
++ if(fn.isEmpty()) return;
++ QString ext = fn.section(".",-1);
++ if(ext=="png")
++ {
++ bool ok;
++<<<<<<< HEAD
++ QString s = QInputDialog::getText(this, tr("UDAV - Import PNG"), tr("Enter color scheme for picture"), QLineEdit::Normal, MGL_DEF_SCH, &ok);
++=======
++ QString s = QInputDialog::getText(this, _("UDAV - Import PNG"), _("Enter color scheme"), QLineEdit::Normal, MGL_DEF_SCH, &ok);
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ if(ok) d->Import(fn.toLocal8Bit().constData(), s.toLocal8Bit().constData());
++ }
++ else if(ext=="h5" || ext=="hdf")
++ {
++ bool ok;
++<<<<<<< HEAD
++ QString s = QInputDialog::getText(this, tr("UDAV - Read from HDF"), tr("Enter data name"), QLineEdit::Normal, QString::fromWCharArray(var->s.c_str()), &ok);
++=======
++ QString s = QInputDialog::getText(this, _("UDAV - Read from HDF"), _("Enter data name"), QLineEdit::Normal, QString::fromWCharArray(var->s.c_str()), &ok);
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ if(ok) d->ReadHDF(fn.toLocal8Bit().constData(), s.toLocal8Bit().constData());
++ }
++ else d->Read(fn.toLocal8Bit().constData());
++ refresh();
++}
++//-----------------------------------------------------------------------------
++void DatPanel::copy()
++{
++ QTableWidgetSelectionRange ts = tab->selectedRanges().first();
++ QString res, s;
++ for(long j=ts.topRow();j<=ts.bottomRow();j++)
++ {
++ for(long i=ts.leftColumn();i<=ts.rightColumn();i++)
++ {
++ res = res + tab->item(j,i)->text();
++ if(i<ts.rightColumn()) res = res + "\t";
++ }
++ res = res + "\n";
++ }
++ QApplication::clipboard()->setText(res, QClipboard::Clipboard);
++}
++//-----------------------------------------------------------------------------
++void DatPanel::paste()
++{
++ QString txt = QApplication::clipboard()->text(QClipboard::Clipboard);
++ QString s, t;
++ int r = tab->currentRow(), c = tab->currentColumn(), i, j;
++ for(i=0;i<ny-r;i++)
++ {
++ s = txt.section('\n',i,i,QString::SectionSkipEmpty);
++ if(s.isEmpty()) break;
++ for(j=0;j<nx-c;j++)
++ {
++ t = s.section('\t',j,j,QString::SectionSkipEmpty);
++ if(t.isEmpty()) { j=nx; continue; }
++ var->set_v(t.toDouble(),j+c,i+r,kz);
++ }
++ }
++ refresh();
++}
++//-----------------------------------------------------------------------------
++void DatPanel::plot() // TODO: plot dialog
++{
++
++}
++//-----------------------------------------------------------------------------
++void DatPanel::list() // TODO: in which script insert ???
++{
++/* if(nx*ny+ny > 1020)
++ { QMessageBox::warning(this, _("UDAV - To list conversion"), _("Too many numbers (>1000) on slice"), QMessageBox::Ok, 0, 0); return; }
++ if(nz > 1)
++ QMessageBox::information(this, _("UDAV - To list conversion"), _("Only current slice will be inserted"), QMessageBox::Ok, 0, 0);
++ QString res = "list\t", s;
++ for(long j=0;j<ny;j++)
++ {
++ for(long i=0;i<nx;i++)
++ {
++ s.sprintf("%g\t",d->a[i+nx*(j+kz*ny)]);
++ res += s;
++ }
++ if(j<ny-1) res = res + "|\t";
++ }*/
++}
++//-----------------------------------------------------------------------------
++void DatPanel::inrange()
++{
++ QString v1("-1"), v2("1"), dir("x");
++ if(sizesDialog(_("UDAV - Fill data"), _("Enter range for data and direction of filling"), _("From"), _("To"), _("Direction"), v1, v2, dir))
++ {
++ mglData *d = dynamic_cast<mglData *>(var);
++ if(d) d->Fill(v1.toDouble(), v2.toDouble(), dir[0].toLatin1());
++ mglDataC *dc = dynamic_cast<mglDataC *>(var);
++ if(dc) dc->Fill(v1.toDouble(), v2.toDouble(), dir[0].toLatin1());
++ mglDataV *dv = dynamic_cast<mglDataV *>(var);
++ if(dv) dv->Fill(v1.toDouble(), v2.toDouble(), dir[0].toLatin1());
++ refresh();
++ }
++}
++//-----------------------------------------------------------------------------
++void DatPanel::norm()
++{
++ QString v1("0"), v2("1"), how;
++ if(sizesDialog(_("UDAV - Normalize data"), _("Enter range for final data"), _("From"), _("To"), _("Symmetrical?"), v1, v2, how))
++ {
++ mglData *d = dynamic_cast<mglData *>(var);
++ if(d) d->Norm(v1.toDouble(), v2.toDouble(), (how=="on" || how.contains('s')));
++ refresh();
++ }
++}
++//-----------------------------------------------------------------------------
++void DatPanel::normsl()
++{
++ QString v1("0"), v2("1"), dir("z");
++ if(sizesDialog(_("UDAV - Normalize by slice"), _("Enter range for final data"), _("From"), _("To"), _("Direction"), v1, v2, dir))
++ {
++ mglData *d = dynamic_cast<mglData *>(var);
++ if(d) d->NormSl(v1.toDouble(), v2.toDouble(), dir[0].toLatin1());
++ refresh();
++ }
++}
++//-----------------------------------------------------------------------------
++void DatPanel::create()
++{
++ QString mx, my("1"), mz("1");
++ if(sizesDialog(_("UDAV - Clear data"), _("Enter new data sizes"), _("X-size"), _("Y-size"), _("Z-size"), mx, my, mz))
++ {
++ mglData *d = dynamic_cast<mglData *>(var);
++ if(d) d->Create(mx.toInt(), my.toInt(), mz.toInt());
++ mglDataC *c = dynamic_cast<mglDataC *>(var);
++ if(c) c->Create(mx.toInt(), my.toInt(), mz.toInt());
++ refresh(); updateDataItems();
++ }
++}
++//-----------------------------------------------------------------------------
++void DatPanel::reSize()
++{
++ QString mx, my, mz;
++ mx.sprintf("%d",nx); my.sprintf("%d",ny); mz.sprintf("%d",nz);
++ if(sizesDialog(_("UDAV - Resize data"), _("Enter new data sizes"), _("X-size"), _("Y-size"), _("Z-size"), mx, my, mz))
++ {
++ mglData *d = dynamic_cast<mglData *>(var);
++ if(d) d->Set(d->Resize(mx.toInt(), my.toInt(), mz.toInt()));
++ refresh(); updateDataItems();
++ }
++}
++//-----------------------------------------------------------------------------
++void DatPanel::squize()
++{
++ QString mx("1"), my("1"), mz("1");
++ if(sizesDialog(_("UDAV - Squeeze data"), _("Enter step of saved points. For example, '1' save all, '2' save each 2nd point, '3' save each 3d and so on."), _("X-direction"), _("Y-direction"), _("Z-direction"), mx, my, mz))
++ {
++ mglData *d = dynamic_cast<mglData *>(var);
++ if(d) d->Squeeze(mx.toInt(), my.toInt(), mz.toInt());
++ refresh(); updateDataItems();
++ }
++}
++//-----------------------------------------------------------------------------
++void DatPanel::crop()
++{
++ QString n1("1"), n2("1"), dir;
++ if(sizesDialog(_("UDAV - Crop data"), _("Enter range of saved date."), _("From"), _("To"), _("Direction"), n1, n2, dir))
++ {
++ mglData *d = dynamic_cast<mglData *>(var);
++ if(d) d->Squeeze(n1.toInt(), n2.toInt(), dir[0].toLatin1());
++ refresh(); updateDataItems();
++ }
++}
++//-----------------------------------------------------------------------------
++void DatPanel::rearrange()
++{
++ QString mx, my, mz;
++ mx.sprintf("%d",nx); my.sprintf("%d",ny); mz.sprintf("%d",nz);
++ if(sizesDialog(_("UDAV - Rearrange data"), _("Enter new data sizes"), _("X-size"), _("Y-size"), _("Z-size"), mx, my, mz))
++ {
++ mglData *d = dynamic_cast<mglData *>(var);
++ if(d) d->Rearrange(mx.toInt(), my.toInt(), mz.toInt());
++ refresh(); updateDataItems();
++ }
++}
++//-----------------------------------------------------------------------------
++void DatPanel::hist()
++{
++ QLabel *l;
++ QLineEdit *id, *v1, *v2;
++ QSpinBox *nm;
++ QPushButton *b;
++ QDialog *d = new QDialog(this); d->setWindowTitle(_("UDAV - Make histogram"));
++ QGridLayout *g = new QGridLayout(d);
++ l = new QLabel(_("From"), d); g->addWidget(l,0,0);
++ l = new QLabel(_("To"), d); g->addWidget(l,0,1);
++ v1 = new QLineEdit(d); g->addWidget(v1,1,0);
++ v2 = new QLineEdit(d); g->addWidget(v2,1,1);
++ l = new QLabel(_("Number of points"), d); g->addWidget(l,2,0);
++ l = new QLabel(_("Put in variable"), d); g->addWidget(l,2,1);
++ nm = new QSpinBox(d); nm->setRange(2,8192); g->addWidget(nm,3,0);
++ id = new QLineEdit(d); nm->setSingleStep(10); g->addWidget(id,3,1);
++ b = new QPushButton(_("Cancel"), d); g->addWidget(b,4,0);
++ connect(b, SIGNAL(clicked()), d, SLOT(reject()));
++ b = new QPushButton(_("OK"), d); g->addWidget(b,4,1);
++ connect(b, SIGNAL(clicked()), d, SLOT(accept())); b->setDefault(true);
++ // now execute dialog and get values
++ bool res = d->exec();
++ if(res && !v1->text().isEmpty() && !v2->text().isEmpty() && !id->text().isEmpty())
++ {
++ mglData *vv = dynamic_cast<mglData*>(parser.AddVar(id->text().toLocal8Bit().constData()));
++ if(vv) vv->Set(mgl_data_hist(var, nm->value(), v1->text().toDouble(), v2->text().toDouble(),0));
++ updateDataItems();
++ }
++}
++//-----------------------------------------------------------------------------
++void DatPanel::first() { setSlice(0); }
++//-----------------------------------------------------------------------------
++void DatPanel::last() { setSlice(nz-1); }
++//-----------------------------------------------------------------------------
++void DatPanel::next() { setSlice(kz+1); }
++//-----------------------------------------------------------------------------
++void DatPanel::prev() { setSlice(kz-1); }
++//-----------------------------------------------------------------------------
++void DatPanel::gosl()
++{
++ bool ok;
++ QString s = QInputDialog::getText(this, _("UDAV - Go to slice"), _("Enter slice id:"), QLineEdit::Normal, "0", &ok);
++ if(ok) setSlice(s.toInt());
++}
++//-----------------------------------------------------------------------------
++void DatPanel::setNz(int nz) { sb->setMaximum(nz-1); }
++//-----------------------------------------------------------------------------
++bool DatPanel::sizesDialog(const QString &cap, const QString &lab, const QString &desc1, const QString &desc2, const QString &desc3, QString &val1, QString &val2, QString &val3)
++{
++ QLabel *l;
++ QLineEdit *f1, *f2, *f3;
++ QPushButton *b;
++ QDialog *d = new QDialog(this);
++ d->setWindowTitle(cap);
++ QVBoxLayout *v = new QVBoxLayout(d);
++ l = new QLabel(lab, d); v->addWidget(l);
++ l = new QLabel(_("NOTE: All fields must be filled!"), d); v->addWidget(l);
++ QGridLayout *g = new QGridLayout(); v->addLayout(g);
++ l = new QLabel(desc1, d); g->addWidget(l, 0, 0);
++ l = new QLabel(desc2, d); g->addWidget(l, 0, 1);
++ l = new QLabel(desc3, d); g->addWidget(l, 0, 2);
++ f1 = new QLineEdit(val1, d); g->addWidget(f1, 1, 0);
++ f2 = new QLineEdit(val2, d); g->addWidget(f2, 1, 1);
++ f3 = new QLineEdit(val3, d); g->addWidget(f3, 1, 2);
++ QHBoxLayout *h = new QHBoxLayout(); v->addLayout(h);
++ h->addStretch(1);
++ b = new QPushButton(_("Cancel"), d); h->addWidget(b);
++ connect(b, SIGNAL(clicked()), d, SLOT(reject()));
++ b = new QPushButton(_("OK"), d); h->addWidget(b);
++ connect(b, SIGNAL(clicked()), d, SLOT(accept()));
++ b->setDefault(true);
++ // now execute dialog and get values
++ bool res = d->exec();
++ val1 = f1->text(); val2 = f2->text(); val3 = f3->text();
++ if(val1.isEmpty() || val2.isEmpty() || val3.isEmpty()) res = false;
++ delete d;
++ return res;
++}
++//-----------------------------------------------------------------------------
++#include "xpm/size.xpm"
++#include "xpm/crop.xpm"
++#include "xpm/squize.xpm"
++#include "xpm/hist.xpm"
++#include "xpm/oper_dir.xpm"
++#include "xpm/oper_of.xpm"
++//-----------------------------------------------------------------------------
++void DatPanel::newdat()
++{
++ QLabel *l;
++ QLineEdit *f1, *f2;
++ QPushButton *b;
++ QDialog *d = new QDialog(this);
++ d->setWindowTitle(_("UDAV - make new data"));
++ QVBoxLayout *v = new QVBoxLayout(d);
++ QComboBox *c = new QComboBox(d); v->addWidget(c);
++ c->addItem(_("Sum along direction(s)"));
++ c->addItem(_("Min along direction(s)"));
++ c->addItem(_("Max along direction(s)"));
++ c->addItem(_("Momentum along 'x' for function"));
++ c->addItem(_("Momentum along 'y' for function"));
++ c->addItem(_("Momentum along 'z' for function"));
++ c->setCurrentIndex(0);
++
++ f1 = new QLineEdit("z",d); v->addWidget(f1);
++ QCheckBox *cb = new QCheckBox(_("Put into this data array"), d); v->addWidget(cb);
++ l = new QLabel(_("or enter name for new variable"), d); v->addWidget(l);
++ f2 = new QLineEdit(d); v->addWidget(f2);
++ QHBoxLayout *h = new QHBoxLayout(); v->addLayout(h); h->addStretch(1);
++ b = new QPushButton(_("Cancel"), d); h->addWidget(b);
++ connect(b, SIGNAL(clicked()), d, SLOT(reject()));
++ b = new QPushButton(_("OK"), d); h->addWidget(b);
++ connect(b, SIGNAL(clicked()), d, SLOT(accept()));
++ b->setDefault(true);
++ // now execute dialog and get values
++ bool res = d->exec();
++ QString val = f1->text(), mgl;
++ int k = c->currentIndex();
++ QString self = QString::fromWCharArray(var->s.c_str());
++ if(res)
++ {
++ if(k<0)
++ {
++ QMessageBox::warning(d, _("UDAV - make new data"),
++ _("No action is selected. Do nothing."));
++ return;
++ }
++ if(val.isEmpty())
++ {
++ QMessageBox::warning(d, _("UDAV - make new data"),
++ _("No direction/formula is entered. Do nothing."));
++ return;
++ }
++ if(cb->isChecked()) k += 6;
++ QString name = f2->text();
++ switch(k)
++ {
++ case 0: mgl = "sum "+name+" "+self+" '"+val+"'"; break;
++ case 1: mgl = "min "+name+" "+self+" '"+val+"'"; break;
++ case 2: mgl = "max "+name+" "+self+" '"+val+"'"; break;
++ case 3: mgl = "momentum "+name+" "+self+" 'x' '"+val+"'"; break;
++ case 4: mgl = "momentum "+name+" "+self+" 'y' '"+val+"'"; break;
++ case 5: mgl = "momentum "+name+" "+self+" 'z' '"+val+"'"; break;
++ case 6: mgl = "copy "+self+" {sum "+self+" '"+val+"'}"; break;
++ case 7: mgl = "copy "+self+" {min "+self+" '"+val+"'}"; break;
++ case 8: mgl = "copy "+self+" {max "+self+" '"+val+"'}"; break;
++ case 9: mgl = "copy "+self+" {momentum "+self+" 'x' '"+val+"'}"; break;
++ case 10: mgl = "copy "+self+" {momentum "+self+" 'y' '"+val+"'}"; break;
++ case 11: mgl = "copy "+self+" {momentum "+self+" 'z' '"+val+"'}"; break;
++ }
++ }
++ if(!mgl.isEmpty())
++ {
++ mglGraph gr;
++ parser.Execute(&gr,mgl.toLocal8Bit().constData());
++ if(k>=6) opers += mgl+"\n";
++ updateDataItems();
++ }
++}
++//-----------------------------------------------------------------------------
++void DatPanel::oper()
++{
++ QLineEdit *f1;
++ QPushButton *b;
++ QDialog *d = new QDialog(this);
++ d->setWindowTitle(_("UDAV - change data"));
++ QVBoxLayout *v = new QVBoxLayout(d);
++ QComboBox *c = new QComboBox(d); v->addWidget(c);
++ c->addItem(_("Fill data by formula"));
++ c->addItem(_("Transpose data with new dimensions"));
++ c->addItem(_("Smooth data along direction(s)"));
++ c->addItem(_("Summarize data along direction(s)"));
++ c->addItem(_("Integrate data along direction(s)"));
++ c->addItem(_("Differentiate data along direction(s)"));
++ c->addItem(_("Laplace transform along direction(s)"));
++ c->addItem(_("Swap data along direction(s)"));
++ c->addItem(_("Mirror data along direction(s)"));
++ c->addItem(_("Sin-Fourier transform along direction(s)"));
++ c->addItem(_("Cos-Fourier transform along direction(s)"));
++ c->addItem(_("Hankel transform along direction(s)"));
++ c->addItem(_("Sew data along direction(s)"));
++ c->addItem(_("Find envelope along direction(s)"));
++ c->setCurrentIndex(0);
++
++ f1 = new QLineEdit("z",d); v->addWidget(f1);
++ QHBoxLayout *h = new QHBoxLayout(); v->addLayout(h); h->addStretch(1);
++ b = new QPushButton(_("Cancel"), d); h->addWidget(b);
++ connect(b, SIGNAL(clicked()), d, SLOT(reject()));
++ b = new QPushButton(_("OK"), d); h->addWidget(b);
++ connect(b, SIGNAL(clicked()), d, SLOT(accept()));
++ b->setDefault(true);
++ // now execute dialog and get values
++ bool res = d->exec();
++ QString val = f1->text(), mgl;
++ int k = c->currentIndex();
++ QString self = QString::fromWCharArray(var->s.c_str());
++ if(res)
++ {
++ if(k<0)
++ {
++ QMessageBox::warning(d, _("UDAV - make new data"),
++ _("No action is selected. Do nothing."));
++ return;
++ }
++ switch(k)
++ {
++ case 0: mgl = "modify "+self+" '"+val+"'"; break;
++ case 1: mgl = "transpose "+self+" '"+val+"'"; break;
++ case 2: mgl = "smooth "+self+" '"+val+"'"; break;
++ case 3: mgl = "cumsum "+self+" '"+val+"'"; break;
++ case 4: mgl = "integrate "+self+" '"+val+"'"; break;
++ case 5: mgl = "diff "+self+" '"+val+"'"; break;
++ case 6: mgl = "diff2 "+self+" '"+val+"'"; break;
++ case 7: mgl = "swap "+self+" '"+val+"'"; break;
++ case 8: mgl = "mirror "+self+" '"+val+"'"; break;
++ case 9: mgl = "sinfft "+self+" '"+val+"'"; break;
++ case 10: mgl = "cosfft "+self+" '"+val+"'"; break;
++ case 11: mgl = "hankel "+self+" '"+val+"'"; break;
++ case 12: mgl = "sew "+self+" '"+val+"'"; break;
++ case 13: mgl = "envelop "+self+" '"+val+"'"; break;
++ }
++ }
++ if(!mgl.isEmpty())
++ {
++ mglGraph gr;
++ parser.Execute(&gr,mgl.toLocal8Bit().constData());
++ opers += mgl+"\n";
++ updateDataItems();
++ }
++}
++//-----------------------------------------------------------------------------
++void DatPanel::toolTop(QBoxLayout *l)
++{
++ QAction *a;
++ QMenu *o;
++ QToolButton *bb;
++
++ // file menu
++ o = menu->addMenu(_("File"));
++ a = new QAction(QPixmap(":/png/document-open.png"), _("Load data"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(load()));
++ a->setToolTip(_("Load data from file. Data will be deleted only\nat exit but UDAV will not ask to save it (Ctrl+Shift+O)."));
++ a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_O); o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ a = new QAction(QPixmap(":/png/document-save.png"), _("Save data"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(save()));
++ a->setToolTip(_("Save data to a file (Ctrl+Shift+S)."));
++ a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_S); o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++// o->addSeparator(); bb->addSeparator();
++// a = new QAction(QPixmap(insert_xpm), _("Insert as list"), this);
++// connect(a, SIGNAL(triggered()), this, SLOT(list()));
++// o->addAction(a);
++// bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++
++ a = new QAction(QPixmap(":/png/office-chart-line.png"), _("Plot data"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(plot()));
++ a->setToolTip(_("Plot data in new script window. You may select the kind\nof plot, its style and so on."));
++ o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ a = new QAction(QPixmap(":/png/edit-copy.png"), _("Copy data"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(copy()));
++ a->setToolTip(_("Copy range of numbers to clipboard (Ctrl+Shift+C)."));
++ a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_C); o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ a = new QAction(QPixmap(":/png/edit-paste.png"), _("Paste data"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(copy()));
++ a->setToolTip(_("Paste range of numbers from clipboard (Ctrl+Shift+P)."));
++ a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_V); o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ // navigation menu
++ o = menu->addMenu(_("Navigation"));
++ a = new QAction(QPixmap(":/png/go-first.png"), _("First slice"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(first()));
++ a->setToolTip(_("Go to first slice for 3D data (Ctrl-F1)."));
++ a->setShortcut(Qt::CTRL+Qt::Key_F1); o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ a = new QAction(QPixmap(":/png/go-previous.png"), _("Prev slice"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(prev()));
++ a->setToolTip(_("Go to the previous slice for 3D data."));
++ o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ sb = new QSpinBox(this);
++ l->addWidget(sb); sb->setRange(0,0);
++ sb->setToolTip(_("Go to the specified slice for 3D data."));
++ connect(sb, SIGNAL(valueChanged(int)), this, SLOT(setSlice(int)));
++ connect(this, SIGNAL(sliceChanged(int)), sb, SLOT(setValue(int)));
++ connect(this, SIGNAL(nzChanged(int)), this, SLOT(setNz(int)));
++
++ a = new QAction(_("Go to slice"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(gosl()));
++ a->setToolTip(_("Go to the specified slice for 3D data."));
++ o->addAction(a);
++
++ a = new QAction(QPixmap(":/png/go-next.png"), _("Next slice"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(next()));
++ a->setToolTip(_("Go to the next slice for 3D data."));
++ o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ a = new QAction(QPixmap(":/png/go-last.png"), _("Last slice"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(last()));
++ a->setToolTip(_("Go to last slice for 3D data (Ctrl-F4)."));
++ a->setShortcut(Qt::CTRL+Qt::Key_F4); o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++}
++//-----------------------------------------------------------------------------
++void DatPanel::toolLeft(QBoxLayout *l)
++{
++ QAction *a;
++ QMenu *o;
++ QToolButton *bb;
++
++ // size menu
++ o = menu->addMenu(_("Sizes"));
++ a = new QAction(QPixmap(":/png/document-new.png"), _("Create new"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(create()));
++ a->setToolTip(_("Recreate the data with new sizes and fill it by zeros (Ctrl+Shift+N)."));
++ a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_N); o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ a = new QAction(QPixmap(size_xpm), _("Resize"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(reSize()));
++ a->setToolTip(_("Resize (interpolate) the data to specified sizes (Ctrl+Shift+R)."));
++ a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_R); o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ a = new QAction(QPixmap(squize_xpm), _("Squeeze"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(squize()));
++ a->setToolTip(_("Keep only each n-th element of the data array."));
++ o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ a = new QAction(QPixmap(crop_xpm), _("Crop"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(crop()));
++ a->setToolTip(_("Crop the data edges. Useful to cut off the zero-filled area."));
++ o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ a = new QAction(QPixmap(oper_of_xpm), _("Transform"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(newdat()));
++ a->setToolTip(_("Transform data along dimension(s) (Ctrl+Shift+T)."));
++ a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_T); o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ a = new QAction(QPixmap(oper_dir_xpm), _("Make new (Ctrl+Shift+M)"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(oper()));
++ a->setToolTip(_("Make another data."));
++ a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_M); o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++ a = new QAction(QPixmap(hist_xpm), _("Histogram (Ctrl+Shift+H)"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(hist()));
++ a->setToolTip(_("Find histogram of data."));
++ a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_H); o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++
++/* a = new QAction(QPixmap(":/png/view-refresh.png"), _("Refresh"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(refresh()));
++ a->setToolTip(_("Refresh data values."));
++ o->addAction(a);
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);*/
++
++/* a = new QAction(_("Rearrange"), this); // TODO: move in generalized dialog
++ connect(a, SIGNAL(triggered()), this, SLOT(rearrange()));
++ a->setToolTip(_("Rearrange data sizes without changing data values."));
++ o->addAction(a);
++ a = new QAction(_("Fill in range"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(inrange()));
++ a->setToolTip(_("Fill data equidistantly from one value to another."));
++ o->addAction(a);
++ a = new QAction(_("Normalize"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(norm()));
++ a->setToolTip(_("Normalize data so that its minimal\nand maximal values be in specified range."));
++ o->addAction(a);
++ a = new QAction(_("Norm. slices"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(normsl()));
++ a->setToolTip(_("Normalize each data slice perpendicular to some direction\nso that its minimal and maximal values be in specified range."));
++ o->addAction(a);*/
++
++ l->addStretch(1);
++
++ a = new QAction(QPixmap(":/png/tab-close.png"), _("Close tab"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(close()));
++ a->setToolTip(_("Close this data tab."));
++ bb = new QToolButton(this); l->addWidget(bb); bb->setDefaultAction(a);
++}
++//-----------------------------------------------------------------------------
++QString DatPanel::dataName() { return QString::fromWCharArray(var->s.c_str()); }
++//-----------------------------------------------------------------------------
--- /dev/null
--- /dev/null
++/***************************************************************************
++ * Copyright (C) 2008 by Alexey Balakin *
++ * mathgl.abalakin@gmail.com *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
++ ***************************************************************************/
++#include <QSettings>
++#include <QCheckBox>
++#include <QLayout>
++#include <QPushButton>
++#include "hint_dlg.h"
++#include "mgl2/data_cf.h"
++//-----------------------------------------------------------------------------
++//
++// Hint dialog
++//
++//-----------------------------------------------------------------------------
++HintDialog::HintDialog(QWidget *parent) : QDialog(parent)
++{
++<<<<<<< HEAD
++ hints.append(tr("You can shift axis range by pressing middle button and moving mouse. Also, you can zoom in/out axis range by using mouse wheel."));
++ hints.append(tr("You can rotate/shift/zoom whole plot by mouse. Just press 'Rotate' toolbutton, click image and hold a mouse button: left button for rotation, right button for zoom/perspective, middle button for shift."));
++ hints.append(tr("You may quickly draw the data from file. Just use: udav 'filename.dat' in command line."));
++ hints.append(tr("You can copy the current image to clipboard by pressing Ctrl-Shift-C. Later you can paste it directly into yours document or presentation."));
++ hints.append(tr("You can export image into a set of format (EPS, SVG, PNG, JPEG) by pressing right mouse button inside image and selecting 'Export as ...'."));
++ hints.append(tr("You can setup colors for script highlighting in Property dialog. Just select menu item 'Settings/Properties'."));
++ hints.append(tr("You can save the parameter of animation inside MGL script by using comment started from '##a ' or '##c ' for loops."));
++ hints.append(tr("New drawing never clears things drawn already. For example, you can make a surface with contour lines by calling commands 'surf' and 'cont' one after another (in any order). "));
++ hints.append(tr("You can put several plots in the same image by help of commands 'subplot' or 'inplot'."));
++ hints.append(tr("All indexes (of data arrays, subplots and so on) are always start from 0."));
++ hints.append(tr("You can edit MGL file in any text editor. Also you can run it in console by help of commands: mglconv, mglview."));
++ hints.append(tr("You can use command 'once on|off' for marking the block which should be executed only once. For example, this can be the block of large data reading/creating/handling. Press F9 (or menu item 'Graphics/Reload') to re-execute this block."));
++ hints.append(tr("You can use command 'stop' for terminating script parsing. It is useful if you don't want to execute a part of script."));
++ hints.append(tr("You can type arbitrary expression as input argument for data or number. In last case (for numbers), the first value of data array is used."));
++ hints.append(tr("There is powerful calculator with a lot of special functions. You can use buttons or keyboard to type the expression. Also you can use existed variables in the expression."));
++ hints.append(tr("The calculator can help you to put complex expression in the script. Just type the expression (which may depend on coordinates x,y,z and so on) and put it into the script."));
++ hints.append(tr("You can easily insert file or folder names, last fitted formula or numerical value of selection by using menu Edit|Insert."));
++ hints.append(tr("The special dialog (Edit|Insert|New Command) help you select the command, fill its arguments and put it into the script."));
++ hints.append(tr("You can put several plotting commands in the same line or in separate function, for highlighting all of them simultaneously."));
++=======
++ hints.append(_("You can shift axis range by pressing middle button and moving mouse. Also, you can zoom in/out axis range by using mouse wheel."));
++ hints.append(_("You can rotate/shift/zoom whole plot by mouse. Just press 'Rotate' toolbutton, click image and hold a mouse button: left button for rotation, right button for zoom/perspective, middle button for shift."));
++ hints.append(_("You may quickly draw the data from file. Just use: udav 'filename.dat' in command line."));
++ hints.append(_("You can copy the current image to clipboard by pressing Ctrl-Shift-C. Later you can paste it directly into yours document or presentation."));
++ hints.append(_("You can export image into a set of format (EPS, SVG, PNG, JPEG) by pressing right mouse button inside image and selecting 'Export as ...'."));
++ hints.append(_("You can setup colors for script highlighting in Property dialog. Just select menu item 'Settings/Properties'."));
++ hints.append(_("You can save the parameter of animation inside MGL script by using comment started from '##a ' or '##c ' for loops."));
++ hints.append(_("New drawing never clears things drawn already. For example, you can make a surface with contour lines by calling commands 'surf' and 'cont' one after another (in any order). "));
++ hints.append(_("You can put several plots in the same image by help of commands 'subplot' or 'inplot'."));
++ hints.append(_("All indexes (of data arrays, subplots and so on) are always start from 0."));
++ hints.append(_("You can edit MGL file in any text editor. Also you can run it in console by help of commands: mglconv, mglview."));
++ hints.append(_("You can use command 'once on|off' for marking the block which should be executed only once. For example, this can be the block of large data reading/creating/handling. Press F9 (or menu item 'Graphics/Reload') to re-execute this block."));
++ hints.append(_("You can use command 'stop' for terminating script parsing. It is useful if you don't want to execute a part of script."));
++ hints.append(_("You can type arbitrary expression as input argument for data or number. In last case (for numbers), the first value of data array is used."));
++ hints.append(_("There is powerful calculator with a lot of special functions. You can use buttons or keyboard to type the expression. Also you can use existed variables in the expression."));
++ hints.append(_("The calculator can help you to put complex expression in the script. Just type the expression (which may depend on coordinates x,y,z and so on) and put it into the script."));
++ hints.append(_("You can easily insert file or folder names, last fitted formula or numerical value of selection by using menu Edit|Insert."));
++ hints.append(_("The special dialog (Edit|Insert|New Command) help you select the command, fill its arguments and put it into the script."));
++ hints.append(_("You can put several plotting commands in the same line or in separate function, for highlighting all of them simultaneously."));
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++ numHints=hints.size();
++ cur = int(mgl_rnd()*numHints);
++ setWindowTitle(_("UDAV - Hint"));
++ QHBoxLayout *a;
++ QPushButton *b;
++ QVBoxLayout *o = new QVBoxLayout(this);
++ text = new QTextEdit(this); o->addWidget(text);
++ text->setReadOnly(true); text->setText(hints[cur]);
++
++ start = new QCheckBox(_("Show at startup"), this); o->addWidget(start);
++ start->setChecked(true);
++
++ a = new QHBoxLayout; o->addLayout(a);
++ b = new QPushButton(_("Prev"), this); a->addWidget(b);
++ connect(b, SIGNAL(clicked()), this, SLOT(prevClicked()));
++ b = new QPushButton(_("Next"), this); a->addWidget(b);
++ connect(b, SIGNAL(clicked()), this, SLOT(nextClicked()));
++ b = new QPushButton(_("Close"), this); a->addWidget(b);
++ connect(b, SIGNAL(clicked()),this, SLOT(close()));
++}
++//-----------------------------------------------------------------------------
++void HintDialog::closeEvent(QCloseEvent *)
++{
++ QSettings settings("udav","UDAV");
++ settings.setPath(QSettings::IniFormat, QSettings::UserScope, "UDAV");
++ settings.beginGroup("/UDAV");
++ settings.setValue("/showHint", start->isChecked());
++ settings.endGroup();
++}
++//-----------------------------------------------------------------------------
++void udavShowHint(QWidget *p)
++{ HintDialog *hd = new HintDialog(p); hd->exec(); }
++//-----------------------------------------------------------------------------
--- /dev/null
--- /dev/null
++/***************************************************************************
++ * Copyright (C) 2008 by Alexey Balakin *
++ * mathgl.abalakin@gmail.com *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
++ ***************************************************************************/
++#include <QLayout>
++#include <QTableWidget>
++#include <QToolBar>
++#include <QInputDialog>
++#include <QMessageBox>
++#include <mgl2/mgl.h>
++//-----------------------------------------------------------------------------
++#include "mem_pnl.h"
++#include "info_dlg.h"
++#undef sprintf // fix libintl bug of defining sprintf
++//-----------------------------------------------------------------------------
++#include "xpm/table.xpm"
++#include "xpm/preview.xpm"
++//-----------------------------------------------------------------------------
++extern bool mglAutoSave;
++extern mglParse parser;
++QWidget *newDataWnd(InfoDialog *inf, QWidget *wnd, mglDataA *v);
++void refreshData(QWidget *w);
++//-----------------------------------------------------------------------------
++QWidget *createMemPanel(QWidget *p) // NOTE: parent should be MainWindow
++{
++ MemPanel *m = new MemPanel(p);
++ m->wnd = p; return m;
++}
++//-----------------------------------------------------------------------------
++void refreshMemPanel(QWidget *p)
++{
++ MemPanel *m = dynamic_cast<MemPanel *>(p);
++ if(m) m->refresh();
++}
++//-----------------------------------------------------------------------------
++MemPanel::MemPanel(QWidget *parent) : QWidget(parent)
++{
++ infoDlg = new InfoDialog(this);
++ infoDlg->setModal(true); infoDlg->allowRefresh=false;
++
++ QToolBar *t = new QToolBar(this); t->setMovable(false);
++ QVBoxLayout *v = new QVBoxLayout(this); v->addWidget(t);
++ t->addAction(QPixmap(":/png/document-new.png"), _("Create new data array"), this, SLOT(newTable()));
++ t->addAction(QPixmap(table_xpm), _("Edit selected data array"), this, SLOT(editData()));
++ t->addAction(QPixmap(":/png/edit-delete.png"), _("Delete selected data array"), this, SLOT(delData()));
++ t->addAction(QPixmap(preview_xpm), _("Properties of selected data array"), this, SLOT(infoData()));
++ t->addAction(QPixmap(":/png/view-refresh.png"), _("Update list of data arrays"), this, SLOT(refresh()));
++ t->addSeparator();
++ t->addAction(QPixmap(":/png/edit-clear.png"), _("Delete ALL data arrays"), this, SLOT(delAllData()));
++
++ colSort = 0;
++ tab = new QTableWidget(this); tab->setColumnCount(3); v->addWidget(tab);
++ QStringList sl; sl<<_("Name")<<_("Sizes")<<_("Memory");
++ tab->setHorizontalHeaderLabels(sl);
++ connect(tab, SIGNAL(cellClicked(int,int)), this, SLOT(tableClicked(int,int)));
++ connect(tab, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(tableDClicked(int,int)));
++
++ setWindowTitle(_("Memory"));
++}
++//-----------------------------------------------------------------------------
++void MemPanel::tableClicked(int, int col)
++{ colSort = col; tab->sortItems(col); }
++//-----------------------------------------------------------------------------
++void MemPanel::tableDClicked(int row, int) { editData(row); }
++//-----------------------------------------------------------------------------
++void MemPanel::newTable()
++{
++ bool ok;
++ QString name = QInputDialog::getText(this, _("UDAV - New variable"),
++ _("Enter name for new variable"), QLineEdit::Normal, "", &ok);
++ if(!ok || name.isEmpty()) return;
++ mglDataA *v = parser.AddVar(name.toLocal8Bit().constData());
++ QWidget *t;
++ if(v->o) t = (QWidget *)v->o;
++ else t = newDataWnd(infoDlg,wnd,v);
++ t->showMaximized(); t->activateWindow();
++ refresh();
++}
++//-----------------------------------------------------------------------------
++void MemPanel::editData(int n)
++{
++ if(tab->rowCount()<1) return;
++ if(n<0) n = tab->currentRow();
++ if(n<0) n = 0;
++ mglDataA *v = parser.FindVar(tab->item(n,0)->text().toLocal8Bit().constData());
++ if(!v) return;
++ QWidget *t;
++ if(v->o) t = (QWidget *)v->o;
++ else t = newDataWnd(infoDlg,wnd,v);
++ t->showMaximized(); t->activateWindow();
++}
++//-----------------------------------------------------------------------------
++void MemPanel::delData()
++{
++ if(tab->rowCount()<1) return;
++ int n = tab->currentRow();
++ if(n<0) n = 0;
++ mglDataA *v = parser.FindVar(tab->item(n,0)->text().toLocal8Bit().constData());
++<<<<<<< HEAD
++ if(!v && v->o) ((QWidget *)v->o)->close();
++=======
++ if(v && v->o) ((QWidget *)v->o)->close();
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ parser.DeleteVar(tab->item(n,0)->text().toLocal8Bit().constData());
++ refresh();
++}
++//-----------------------------------------------------------------------------
++void MemPanel::delAllData()
++{
++ if(QMessageBox::information(this, _("UDAV - delete all data"),
++ _("Do you want to delete all data?"), QMessageBox::No,
++ QMessageBox::Yes)!=QMessageBox::Yes) return;
++ parser.DeleteAll(); refresh();
++}
++//-----------------------------------------------------------------------------
++void MemPanel::infoData()
++{
++ if(tab->rowCount()<1) return;
++ int n = tab->currentRow();
++ if(n<0) n = 0;
++ mglDataA *v = parser.FindVar(tab->item(n,0)->text().toLocal8Bit().constData());
++ if(!v) return;
++ infoDlg->setVar(v);
++ QString s = QString::fromWCharArray(v->s.c_str());
++<<<<<<< HEAD
++ infoDlg->setWindowTitle(s + tr(" - UDAV preview"));
++=======
++ infoDlg->setWindowTitle(s + _(" - UDAV preview"));
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ infoDlg->refresh();
++ infoDlg->show();
++}
++//-----------------------------------------------------------------------------
++void MemPanel::refresh()
++{
++ long n = parser.GetNumVar(), m=0;
++ for(long i=0;i<n;i++) if(parser.GetVar(i)) m++;
++ tab->setRowCount(m);
++ QString s;
++ QTableWidgetItem *it;
++ Qt::ItemFlags flags=Qt::ItemIsSelectable|Qt::ItemIsEnabled;
++ for(long i=m=0;i<n;i++)
++ {
++ mglDataA *v = parser.GetVar(i);
++ if(!v) continue;
++ s = QString::fromWCharArray(v->s.c_str());
++ it = new QTableWidgetItem(s);
++ tab->setItem(m,0,it); it->setFlags(flags);
++ s.sprintf("%ld * %ld * %ld", v->GetNx(), v->GetNy(), v->GetNz());
++ it = new QTableWidgetItem(s);
++ tab->setItem(m,1,it); it->setFlags(flags);
++ it->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
++ long sv = 0;
++ if(dynamic_cast<mglData*>(v)) sv = v->GetNN()*sizeof(mreal)+sizeof(mglData);
++ else if(dynamic_cast<mglDataC*>(v)) sv = v->GetNN()*sizeof(dual)+sizeof(mglDataC);
++ else if(dynamic_cast<mglDataV*>(v)) sv = sizeof(mglDataV);
++ else if(dynamic_cast<mglDataW*>(v)) sv = sizeof(mglDataW);
++ else if(dynamic_cast<mglDataF*>(v)) sv = sizeof(mglDataF);
++ else if(dynamic_cast<mglDataR*>(v)) sv = sizeof(mglDataR);
++ else if(dynamic_cast<mglDataT*>(v)) sv = sizeof(mglDataT);
++ if(sv==0) s = _("unknown");
++#if MGL_SIZEOF_LONG>4
++// else if((sv>>80L)>0) s.sprintf("%ld Yb",sv>>80L);
++// else if((sv>>70L)>0) s.sprintf("%ld Zb",sv>>70L);
++ else if((sv>>60L)>0) s.sprintf("%ld Eb",sv>>60L);
++ else if((sv>>50L)>0) s.sprintf("%ld Pb",sv>>50L);
++ else if((sv>>40L)>0) s.sprintf("%ld Tb",sv>>40L);
++#endif
++ else if((sv>>30L)>0) s.sprintf("%ld Gb",sv>>30L);
++ else if((sv>>20L)>0) s.sprintf("%ld Mb",sv>>20L);
++ else if((sv>>10L)>0) s.sprintf("%ld Kb",sv>>10L);
++ else s.sprintf("%ld b",sv);
++ it = new QTableWidgetItem(s);
++ tab->setItem(m,2,it); it->setFlags(flags);
++ it->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
++ if(v->o) refreshData((QWidget *)v->o);
++ m++;
++ }
++ tab->sortItems(colSort);
++}
++//-----------------------------------------------------------------------------
--- /dev/null
--- /dev/null
++/***************************************************************************
++ * Copyright (C) 2008 by Alexey Balakin *
++ * mathgl.abalakin@gmail.com *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
++ ***************************************************************************/
++#include <QLabel>
++#include <QLayout>
++#include <QSettings>
++#include <QLineEdit>
++#include <QComboBox>
++#include <QPushButton>
++#include <QFileDialog>
++#include <QTextStream>
++#include <QRadioButton>
++#include <mgl2/mgl.h>
++#include "open_dlg.h"
++int numDataOpened=0;
++extern mglParse parser;
++QStringList dataScr;
++//-----------------------------------------------------------------------------
++QWidget *createDataOpenDlg(QWidget *p) { return new DataOpenDialog(p); }
++QString getOpenDataFile(QWidget *w, QString filename)
++{
++ DataOpenDialog *d = dynamic_cast<DataOpenDialog *>(w);
++ if(d)
++ {
++ d->setFile(filename);
++ if(d->exec()) return d->getCode();
++ }
++ return QString();
++}
++//-----------------------------------------------------------------------------
++DataOpenDialog::DataOpenDialog(QWidget *parent) : QDialog(parent)
++{
++ setWindowTitle(_("UDAV - Open data file"));
++ QHBoxLayout *a;
++ QLabel *l;
++ QPushButton *b;
++ QVBoxLayout *o=new QVBoxLayout(this);
++
++ a = new QHBoxLayout; o->addLayout(a);
++ l = new QLabel(_("Data name")); a->addWidget(l);
++ char buf[32]; snprintf(buf,32,"mgl_%d",numDataOpened); buf[31]=0;
++ name = new QLineEdit(buf,this); a->addWidget(name);
++
++ rA = new QRadioButton(_("Auto detect data sizes"), this);
++ rA->setChecked(true); o->addWidget(rA);
++ rM = new QRadioButton(_("Set data sizes manually"), this);
++ o->addWidget(rM); a = new QHBoxLayout; o->addLayout(a);
++ l = new QLabel(_("Nx")); a->addWidget(l);
++ nx = new QLineEdit("1",this); a->addWidget(nx);
++ l = new QLabel(_("Ny")); a->addWidget(l);
++ ny = new QLineEdit("1",this); a->addWidget(ny);
++ l = new QLabel(_("Nz")); a->addWidget(l);
++ nz = new QLineEdit("1",this); a->addWidget(nz);
++ r2 = new QRadioButton(_("Matrix with sizes from file"), this); o->addWidget(r2);
++ r3 = new QRadioButton(_("3D data with sizes from file"), this);o->addWidget(r3);
++
++
++ QSettings settings("udav","UDAV");
++ settings.setPath(QSettings::IniFormat, QSettings::UserScope, "UDAV");
++ settings.beginGroup("/UDAV");
++ dataScr = settings.value("/dataScr").toStringList().mid(0,10);
++ dataScr.removeDuplicates();
++ settings.endGroup();
++
++ a = new QHBoxLayout; o->addLayout(a);
++ l = new QLabel(_("Template")); a->addWidget(l,0);
++ scr = new QComboBox(this); a->addWidget(scr,1);
++ scr->setEditable(true); scr->lineEdit()->setText("");
++ scr->addItem(_("default")); scr->addItems(dataScr);
++ b = new QPushButton("...", this); a->addWidget(b,0);
++ connect(b, SIGNAL(clicked()),this, SLOT(selectScr()));
++
++ a = new QHBoxLayout; o->addLayout(a); a->addStretch(1);
++ b = new QPushButton(_("Cancel"),this); a->addWidget(b);
++ connect(b,SIGNAL(clicked()),this,SLOT(reject()));
++ b = new QPushButton(_("OK"), this); a->addWidget(b);
++ connect(b, SIGNAL(clicked()),this, SLOT(prepareResult()));
++ b->setDefault(true);
++}
++//-----------------------------------------------------------------------------
++DataOpenDialog::~DataOpenDialog(){}
++//-----------------------------------------------------------------------------
++void DataOpenDialog::selectScr()
++{
++ QString str = QFileDialog::getOpenFileName(this, _("UDAV - Insert filename"),
++ scr->lineEdit()->text(), _("MGL files (*.mgl)"));
++ if(!str.isEmpty())
++ {
++ scr->lineEdit()->setText(str);
++ scr->insertItem(1,str);
++ dataScr.insert(0,str);
++ dataScr.removeDuplicates();
++ }
++}
++
++//-----------------------------------------------------------------------------
++void DataOpenDialog::prepareResult()
++{
++ code = ""; numDataOpened++; data = name->text();
++ // prepare unique value of name for next time
++ char buf[32]; snprintf(buf,32,"mgl_%d",numDataOpened);
++ buf[31]=0; name->setText(buf);
++ mglData *v = dynamic_cast<mglData*>(parser.AddVar(data.toLocal8Bit().constData()));
++ if(!v) return;
++ int dd=0;
++ if(rA->isChecked()) // auto sizes
++ {
++<<<<<<< HEAD
++ setlocale(LC_NUMERIC, "C"); v->Read(file.toLocal8Bit().constData()); setlocale(LC_NUMERIC, "");
++=======
++ v->Read(file.toLocal8Bit().constData());
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ if(v->nx==1) { v->nx = v->ny; v->ny = v->nz; }
++ code=QString("#read %1 '%2'\n").arg(data).arg(file);
++ }
++ else if(rM->isChecked()) // manual sizes
++ {
++ int x=nx->text().toInt(), y=ny->text().toInt(), z=nz->text().toInt();
++<<<<<<< HEAD
++ setlocale(LC_NUMERIC, "C"); v->Read(file.toLocal8Bit().constData(),x,y,z); setlocale(LC_NUMERIC, "");
++=======
++ v->Read(file.toLocal8Bit().constData(),x,y,z);
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ code=QString("#read %1 '%2' %3 %4 %5\n").arg(data).arg(file).arg(x).arg(y).arg(z);
++ }
++ else if(r2->isChecked()) // matrix
++ {
++<<<<<<< HEAD
++ setlocale(LC_NUMERIC, "C"); v->ReadMat(file.toLocal8Bit().constData()); setlocale(LC_NUMERIC, "");
++=======
++ v->ReadMat(file.toLocal8Bit().constData());
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ code=QString("#readmat %1 '%2'\n").arg(data).arg(file); dd=1;
++ }
++ else if(r3->isChecked()) // 3d-data
++ {
++<<<<<<< HEAD
++ setlocale(LC_NUMERIC, "C"); v->ReadMat(file.toLocal8Bit().constData(),3); setlocale(LC_NUMERIC, "");
++=======
++ v->ReadMat(file.toLocal8Bit().constData(),3);
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ code=QString("#readmat %1 '%2' 3\n").arg(data).arg(file); dd=2;
++ }
++ if(scr->lineEdit()->text().isEmpty() || scr->lineEdit()->text()==_("default"))
++ {
++ if(v->nz>1 || dd==2)
++ code+=QString("rotate 40 60\ncrange %1:box\nsurf3 %1\n").arg(data);
++ else if(v->ny>1 || dd==1)
++ code+=QString("rotate 40 60\ncrange %1:zrange %1:box\nsurf %1\n").arg(data);
++ else code+=QString("yrange %1:box\nplot %1\n").arg(data);
++ }
++ else
++ {
++ QString str;
++ QFile fp(scr->lineEdit()->text());
++ if(fp.open(QFile::ReadOnly | QIODevice::Text))
++ {
++ QTextStream in(&fp);
++ str = in.readAll();
++ code += str.arg(data);
++ }
++ }
++
++ QSettings settings("udav","UDAV");
++ settings.setPath(QSettings::IniFormat, QSettings::UserScope, "UDAV");
++ settings.beginGroup("/UDAV");
++ settings.setValue("/dataScr", dataScr);
++ settings.endGroup();
++
++ accept();
++}
++//-----------------------------------------------------------------------------
++void DataOpenDialog::setFile(const QString &fname)
++{
++ file=fname;
++ mglData d(file.toLocal8Bit().constData());
++<<<<<<< HEAD
++ rA->setText(tr("Auto detect data sizes (%1 x %2 x %3)").arg(d.nx).arg(d.ny).arg(d.nz));
++=======
++ rA->setText(QString(_("Auto detect data sizes (%1 x %2 x %3)")).arg(d.nx).arg(d.ny).arg(d.nz));
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
--- /dev/null
--- /dev/null
++/***************************************************************************
++ * Copyright (C) 2008 by Alexey Balakin *
++ * mathgl.abalakin@gmail.com *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
++ ***************************************************************************/
++#include <QPrintDialog>
++#include <QMessageBox>
++#include <QTextStream>
++#include <QFileDialog>
++#include <QToolButton>
++#include <QToolBar>
++#include <QCompleter>
++#include <QBoxLayout>
++#include <QPrinter>
++#include <QMenu>
++#include "mgl2/qmathgl.h"
++//-----------------------------------------------------------------------------
++#include "udav_wnd.h"
++#include "qmglsyntax.h"
++#include "find_dlg.h"
++#include "opt_dlg.h"
++#include "style_dlg.h"
++#include "files_dlg.h"
++#include "newcmd_dlg.h"
++#include "setup_dlg.h"
++#include "text_pnl.h"
++#include "plot_pnl.h"
++#include "subplot_dlg.h"
++//-----------------------------------------------------------------------------
++FilesDialog *files_dlg=0;
++QString defFontFamily;
++int defFontSize;
++bool mglAutoExecute = true;
++extern mglParse parser;
++extern bool mglCompleter;
++QWidget *createDataOpenDlg(QWidget *p);
++QString getOpenDataFile(QWidget *w, QString filename);
++//-----------------------------------------------------------------------------
++TextPanel::TextPanel(QWidget *parent) : QWidget(parent)
++{
++ printer = new QPrinter;
++ findDialog = new FindDialog(this);
++ optDialog = new OptionDialog(this);
++ stlDialog = new StyleDialog(this);
++ newCmdDlg = new NewCmdDialog(this);
++ subplotDlg = new SubplotDialog(this);
++ setupDlg = new SetupDialog(this);
++ dataOpenDlg = createDataOpenDlg(this);
++ if(!files_dlg) files_dlg= new FilesDialog;
++
++<<<<<<< HEAD
++ register int i,n=parser.GetCmdNum();
++ for(i=0;i<n;i++) words<<QString::fromLatin1(parser.GetCmdName(i));
++=======
++ int n=parser.GetCmdNum();
++ for(int i=0;i<n;i++) words<<QString::fromLatin1(parser.GetCmdName(i));
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ vars = words;
++
++ connect(setupDlg, SIGNAL(putText(const QString &)), this, SLOT(animPutText(const QString &)));
++ connect(newCmdDlg, SIGNAL(result(const QString&, bool)), this, SLOT(putLine(const QString&, bool)));
++ connect(subplotDlg, SIGNAL(result(const QString&)), this, SLOT(putLine(const QString&)));
++ connect(findDialog, SIGNAL(findText(const QString &, bool, bool)), this, SLOT(findText(const QString &, bool, bool)));
++ connect(findDialog, SIGNAL(replText(const QString &, const QString &, bool, bool)), this, SLOT(replText(const QString &, const QString &, bool, bool)));
++
++ edit = new TextEdit(this); edit->setAcceptRichText(false);
++ new QMGLSyntax(edit);
++ defFontFamily = edit->fontFamily();
++ defFontSize = int(edit->fontPointSize());
++ edit->setLineWrapMode(QTextEdit::NoWrap);
++ setCompleter(mglCompleter);
++ QFontMetrics metrics(edit->currentFont());
++ edit->setTabStopWidth(4 * metrics.width(' '));
++
++ menu = new QMenu(_("Edit"),this);
++ QBoxLayout *v = new QVBoxLayout(this);
++ toolTop(v); v->addWidget(edit);
++}
++//-----------------------------------------------------------------------------
++TextPanel::~TextPanel() { delete printer; }
++//-----------------------------------------------------------------------------
++void TextPanel::setCompleter(bool en)
++{
++ if(en)
++ {
++ QCompleter *completer = new QCompleter(vars, this);
++ completer->setCaseSensitivity(Qt::CaseInsensitive);
++ completer->setCompletionMode(QCompleter::PopupCompletion);
++ edit->setCompleter(completer);
++ }
++ else edit->setCompleter(0);
++// completer->setCompletionMode(en ? QCompleter::PopupCompletion : QCompleter::InlineCompletion);
++}
++//-----------------------------------------------------------------------------
++void TextPanel::insNVal()
++{
++ QString sel=edit->textCursor().selectedText();
++ if(sel.isEmpty())
++ {
++ QMessageBox::warning(this,_("UDAV"),_("There is no selection to evaluate."));
++ return;
++ }
++ wchar_t *txt=new wchar_t[sel.length()+1];
++ sel.toWCharArray(txt); txt[sel.length()]=0;
++ mglData res=parser.Calc(txt);
++ delete []txt;
++ edit->textCursor().insertText(QString::number(res.GetVal(0)));
++}
++//-----------------------------------------------------------------------------
++void TextPanel::insPrim()
++{
++ QString str(graph->mgl->primitives);
++ if(str.isEmpty())
++ {
++ QMessageBox::warning(this,_("UDAV"),_("There is manual primitives."));
++ return;
++ }
++ edit->moveCursor(QTextCursor::Start);
++ edit->insertPlainText("subplot 1 1 0 '#'\n"+str+"subplot 1 1 0\n#----------\n");
++ graph->mgl->primitives = "";
++}
++//-----------------------------------------------------------------------------
++void TextPanel::insFitF()
++{
++ QString str(graph->getFit());
++ if(str.isEmpty())
++ {
++ QMessageBox::warning(this,_("UDAV"),_("There is no fitted formula."));
++ return;
++ }
++ edit->textCursor().insertText("'"+str+"'");
++}
++//-----------------------------------------------------------------------------
++void TextPanel::insFile()
++{
++ QString str = QFileDialog::getOpenFileName(this, _("UDAV - Insert filename"));
++ if(str.isEmpty()) return;
++ edit->textCursor().insertText("'"+str+"'");
++}
++//-----------------------------------------------------------------------------
++void TextPanel::insPath()
++{
++ QString str = QFileDialog::getExistingDirectory(this, _("UDAV - Insert path"));
++ if(str.isEmpty()) return;
++ edit->textCursor().insertText("'"+str+"'");
++}
++//-----------------------------------------------------------------------------
++void TextPanel::refreshData()
++{
++ vars=words;
++ long i,n=parser.GetNumVar();
++ for(i=0;i<n;i++)
++ {
++ const mglDataA *v=parser.GetVar(i);
++ if(v && v->s.length()>2) vars<<QString::fromWCharArray(v->s.c_str());
++ }
++ setCompleter(mglCompleter);
++}
++//-----------------------------------------------------------------------------
++void TextPanel::printText()
++{
++ QPrintDialog printDlg(printer, this);
++ if (printDlg.exec() == QDialog::Accepted)
++ {
++ setStatus(_("Printing..."));
++ edit->print(printer);
++ setStatus(_("Printing completed"));
++ }
++ else setStatus(_("Printing aborted"));
++}
++//-----------------------------------------------------------------------------
++void TextPanel::find()
++{
++ findDialog->show();
++ findDialog->raise();
++ findDialog->activateWindow();
++}
++//-----------------------------------------------------------------------------
++bool TextPanel::findText(const QString &str, bool cs, bool fw)
++{
++// static int para=0, index=0;
++ static QTextDocument::FindFlags f;
++ static QString stri="";
++ if(!str.isEmpty())
++ {
++ stri = str;
++ f = QTextDocument::FindFlags();
++ if(fw) f = f|QTextDocument::FindBackward;
++ if(cs) f = f|QTextDocument::FindCaseSensitively;
++ }
++ bool res = edit->find(stri, f);
++ if(!res)
++ QMessageBox::information(this, _("UDAV - find text"), _("No string occurrence is found"));
++ return res;
++}
++//-----------------------------------------------------------------------------
++void TextPanel::replText(const QString &str, const QString &txt, bool cs, bool fw)
++{
++ static bool res=false;
++ if(str.isEmpty()) { res = false; return; }
++ if(res) edit->textCursor().insertText(txt);
++ res = findText(str, cs, fw);
++}
++//-----------------------------------------------------------------------------
++void TextPanel::addOptions()
++{
++ if(optDialog->exec()==QDialog::Accepted)
++ {
++ edit->moveCursor(QTextCursor::EndOfLine);
++ edit->insertPlainText(optDialog->getOption());
++ }
++}
++//-----------------------------------------------------------------------------
++void TextPanel::animPutText(const QString &s)
++{ edit->moveCursor(QTextCursor::Start); edit->insertPlainText(s); }
++//-----------------------------------------------------------------------------
++//void TextPanel::putText(const QString &txt) { edit->insertPlainText(txt); }
++//-----------------------------------------------------------------------------
++void TextPanel::putLine(const QString &txt, bool replace)
++{
++ edit->moveCursor(QTextCursor::StartOfLine);
++ if(replace)
++ {
++ QTextCursor c = edit->textCursor();
++ c.select(QTextCursor::BlockUnderCursor);
++ c.removeSelectedText();
++ edit->setTextCursor(c);
++ if(c.atStart()) edit->insertPlainText(txt);
++ else edit->insertPlainText("\n"+txt);
++ }
++ else edit->insertPlainText(txt+"\n");
++}
++//-----------------------------------------------------------------------------
++void TextPanel::addStyle()
++{
++ if(stlDialog->exec()==QDialog::Accepted)
++ {
++ QString s = edit->textCursor().block().text();
++ int i = s.indexOf(';');
++ if(i<0) edit->moveCursor(QTextCursor::EndOfLine);
++ else
++ {
++ edit->moveCursor(QTextCursor::StartOfBlock);
++ // foolish way :(
++ for(;i>0;i--) edit->moveCursor(QTextCursor::Left);
++ }
++ edit->insertPlainText(stlDialog->getStyle());
++ }
++}
++//-----------------------------------------------------------------------------
++void TextPanel::setEditorFont(QFont *f)
++{
++ QFont d(defFontFamily, defFontSize);
++ edit->setFont(f ? *f : d);
++ QFontMetrics metrics(f ? *f : d);
++ edit->setTabStopWidth(4 * metrics.width(' '));
++}
++//-----------------------------------------------------------------------------
++QString TextPanel::selection()
++{ return edit->textCursor().block().text(); }
++//-----------------------------------------------------------------------------
++void TextPanel::setCursorPosition(int n)
++{
++ if(n<0) return;
++ edit->moveCursor(QTextCursor::Start);
++ for(int i=0;i<n;i++) edit->moveCursor(QTextCursor::NextBlock);
++ edit->setFocus();
++}
++//-----------------------------------------------------------------------------
++void TextPanel::newCmd(int n)
++{
++ if(n>0) setCursorPosition(n-1);
++ else if(n==0) return;
++ newCmdDlg->parseCmd(edit->textCursor().block().text());
++ newCmdDlg->show();
++}
++//-----------------------------------------------------------------------------
++#if MGL_HAVE_HDF5
++#define H5_USE_16_API
++#include <hdf5.h>
++void TextPanel::loadHDF5(const QString &fileName)
++{
++ // H5T_C_S1 - C string
++ hid_t hf,hg,hd,hs,ht;
++ hsize_t dims[3];
++ long rank;
++ hf = H5Fopen(fileName.toLocal8Bit().constData(), H5F_ACC_RDONLY, H5P_DEFAULT);
++ if(!hf) return;
++ hg = H5Gopen(hf, "/");
++ hsize_t num, nx, ny, nz, i;
++ char name[256];
++ H5Gget_num_objs(hg, &num);
++ for(i=0;i<num;i++)
++ {
++ if(H5Gget_objtype_by_idx(hg, i)!=H5G_DATASET) continue;
++ H5Gget_objname_by_idx(hg, i, name, 256);
++ hd = H5Dopen(hg,name); hs = H5Dget_space(hd);
++ ht = H5Dget_type(hd);
++ rank = H5Sget_simple_extent_ndims(hs);
++ if(H5Tget_class(ht)==H5T_STRING) // load script
++ {
++ H5Sget_simple_extent_dims(hs,dims,0);
++ char *buf = new char[dims[0]+1];
++ H5Dread(hd, H5T_C_S1, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
++ buf[dims[0]]=0; // to be sure :)
++ QString str = buf;
++ if(str.contains("subplot 1 1 0\n#----- End of QMathGL block -----\n"))
++ {
++ graph->mgl->primitives = str.section("subplot 1 1 0\n#----- End of QMathGL block -----\n",0,0).section("subplot 1 1 0 '#'\n",1);
++ str = str.section("subplot 1 1 0\n#----- End of QMathGL block -----\n",1);
++ }
++ edit->setText(str);
++ graph->animParseText(edit->toPlainText());
++ setCurrentFile(fileName);
++ delete []buf;
++ setStatus(QString(_("Loaded document %1")).arg(fileName));
++ if(mglAutoExecute) graph->execute();
++ }
++ else if(H5Tget_class(ht)==H5T_FLOAT || H5Tget_class(ht)==H5T_INTEGER)
++ {
++ for(int j=0;name[j];j++) if(!isalnum(name[j])) name[j]='_';
++ mglData *v = (mglData*) parser.AddVar(name);
++ nx = ny = nz = 1;
++ if(rank>0 && rank<=3)
++ {
++ H5Sget_simple_extent_dims(hs,dims,0);
++ switch(rank)
++ {
++ case 1: nx=dims[0]; break;
++ case 2: nx=dims[1]; ny=dims[0]; break;
++ case 3: nx=dims[2]; ny=dims[1]; nz=dims[0]; break;
++ }
++ v->Create(nx, ny, nz);
++#if MGL_USE_DOUBLE
++ H5Dread(hd, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, v->a);
++#else
++ H5Dread(hd, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, v->a);
++#endif
++ }
++ }
++ H5Dclose(hd); H5Sclose(hs); H5Tclose(ht);
++ }
++ H5Gclose(hg); H5Fclose(hf);
++}
++//-----------------------------------------------------------------------------
++void TextPanel::saveHDF5(const QString &fileName)
++{
++ hid_t hf,hd,hs;
++ hsize_t dims[3];
++ long rank = 3;
++
++ H5Eset_auto(0,0);
++ hf = H5Fcreate(fileName.toLocal8Bit().constData(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
++ if(hf<0)
++ {
++ setStatus(QString(_("Could not write to %1")).arg(fileName));
++ return;
++ }
++ { // save script
++ QString txt;
++ if(!graph->mgl->primitives.isEmpty())
++ txt += "subplot 1 1 0 '#'\n"+graph->mgl->primitives + "subplot 1 1 0\n#----- End of QMathGL block -----\n";
++ txt += edit->toPlainText();
++ dims[0] = txt.length()+1;
++ char *buf = new char[dims[0]+1];
++ memcpy(buf, txt.toLocal8Bit().constData(), dims[0]);
++ buf[dims[0]]=0;
++ hs = H5Screate_simple(1, dims, 0);
++ hd = H5Dcreate(hf, "mgl_script", H5T_C_S1, hs, H5P_DEFAULT);
++ H5Dwrite(hd, H5T_C_S1, hs, hs, H5P_DEFAULT, buf);
++ H5Dclose(hd); H5Sclose(hs);
++ delete []buf;
++ }
++ long n = parser.GetNumVar();
++ char name[256];
++ for(long i=0;i<n;i++)
++ {
++ const mglData *v = dynamic_cast<const mglData *>(parser.GetVar(i));
++ mglData tmp;
++ if(!v) { tmp.Set(parser.GetVar(i)); v = &tmp; }
++ wcstombs(name,v->s.c_str(),v->s.length()+1);
++ if(v->nz==1 && v->ny == 1)
++ { rank = 1; dims[0] = v->nx; }
++ else if(v->nz==1)
++ { rank = 2; dims[0] = v->ny; dims[1] = v->nx; }
++ else
++ { rank = 3; dims[0] = v->nz; dims[1] = v->ny; dims[2] = v->nx; }
++ hs = H5Screate_simple(rank, dims, 0);
++ hd = H5Dcreate(hf, name, H5T_IEEE_F32LE, hs, H5P_DEFAULT);
++
++ H5Dwrite(hd, H5T_NATIVE_FLOAT, hs, hs, H5P_DEFAULT, v->a);
++ H5Dclose(hd); H5Sclose(hs);
++ }
++ H5Fclose(hf);
++ setCurrentFile(fileName);
++ setStatus(QString(_("File %1 saved")).arg(fileName));
++ return;
++}
++#else
++void TextPanel::saveHDF5(const QString &fileName){}
++void TextPanel::loadHDF5(const QString &fileName){}
++#endif
++//-----------------------------------------------------------------------------
++void TextPanel::load(const QString &fileName)
++{
++ if(fileName.right(4).toLower()==".dat")
++ {
++ QString code = getOpenDataFile(dataOpenDlg, fileName);
++ if(!code.isEmpty())
++ {
++ setCurrentFile(fileName.left(fileName.length()-3)+"mgl");
++ edit->setText(code);
++ }
++ }
++ else if(fileName.right(4).toLower()==".hdf" || fileName.right(3).toLower()==".h5")
++ loadHDF5(fileName);
++ else
++ {
++ QFile f(fileName);
++ if(!f.open(QIODevice::ReadOnly))
++ {
++ QMessageBox::warning(this,_("UDAV - open file"), _("Couldn't open file ") + QString("'") + fileName+"'", QMessageBox::Ok,0,0);
++ return;
++ }
++
++ QTextStream ts(&f);
++ ts.setAutoDetectUnicode(true);
++// ts.setCodec(QTextCodec::codecForLocale());
++
++ QString str=ts.readAll();
++ int narg=0,i=-1;
++ if(str.contains('%'))
++ {
++ while((i = str.indexOf('%',i+1))>0)
++ {
++ char ch = str.at(i+1).toLatin1();
++ if(ch>='1' && ch<='9' && ch-'0'>narg)
++ narg = ch-'0';
++ }
++ if(narg>0)
++ {
++ files_dlg->setNumFiles(narg);
++ if(!files_dlg->exec()) return; // nothing to do
++ str = files_dlg->putFiles(str);
++ }
++ }
++ if(str.contains("#----- End of QMathGL block -----\n"))
++ {
++ graph->mgl->primitives = str.section("#----- End of QMathGL block -----\n",0,0);
++ str = str.section("#----- End of QMathGL block -----\n",1);
++ }
++
++ if(narg>0) setCurrentFile(fileName.left(fileName.length()-3)+"mgl");
++ edit->setText(str);
++ graph->animParseText(edit->toPlainText());
++ if(narg==0) setCurrentFile(fileName);
++ }
++ setStatus(_("Loaded document ")+fileName);
++ if(mglAutoExecute) graph->execute();
++}
++//-----------------------------------------------------------------------------
++void TextPanel::save(const QString &fileName)
++{
++ if(fileName.right(4)==".hdf" || fileName.right(3)==".h5")
++ { saveHDF5(fileName); return; }
++ QString text;
++ if(!graph->mgl->primitives.isEmpty())
++ text += graph->mgl->primitives + "#----- End of QMathGL block -----\n";
++ text += edit->toPlainText();
++ QFile f(fileName);
++ if(!f.open(QIODevice::WriteOnly))
++ {
++ setStatus(QString(_("Could not write to %1")).arg(fileName));
++ return;
++ }
++ QTextStream t(&f);
++ t.setAutoDetectUnicode(true);
++ t << text; f.close();
++ setCurrentFile(fileName);
++ setStatus(QString(_("File %1 saved")).arg(fileName));
++}
++//-----------------------------------------------------------------------------
++void TextPanel::addSetup() { setupDlg->exec(); }
++//-----------------------------------------------------------------------------
++#include "xpm/option.xpm"
++#include "xpm/style.xpm"
++#include "xpm/curve.xpm"
++#include "xpm/box.xpm"
++//-----------------------------------------------------------------------------
++void TextPanel::toolTop(QBoxLayout *v)
++{
++ QToolBar *t = new QToolBar(this); v->addWidget(t); t->setMovable(false);
++ QAction *a, *aa;
++ QMenu *o=menu, *oo;
++ const MainWindow *mw=findMain(this);
++
++ // general buttons
++ if(mw)
++ {
++ t->addAction(mw->aload); t->addAction(mw->asave); t->addAction(mw->acalc);
++ }
++ QToolButton *bb = new QToolButton(this);
++ bb->setPopupMode(QToolButton::MenuButtonPopup);
++ t->addWidget(bb);
++
++ // edit menu
++ a = new QAction(QPixmap(":/png/edit-undo.png"), _("Undo"), this);
++ connect(a, SIGNAL(triggered()), edit, SLOT(undo()));
++ a->setToolTip(_("Undo editor change (Ctrl+Z)."));
++ a->setShortcut(Qt::CTRL+Qt::Key_Z); o->addAction(a); t->addAction(a);
++
++ a = new QAction(QPixmap(":/png/edit-redo.png"), _("Redo"), this);
++ connect(a, SIGNAL(triggered()), edit, SLOT(redo()));
++ a->setToolTip(_("Redo editor change (Ctrl+Shift+Z)."));
++ a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_Z); o->addAction(a); t->addAction(a);
++
++ o->addSeparator();
++ o->addAction(_("Clear all"), edit, SLOT(clear()));
++ a = new QAction(QPixmap(":/png/edit-cut.png"), _("Cut text"), this);
++ connect(a, SIGNAL(triggered()), edit, SLOT(cut()));
++ a->setToolTip(_("Cut selected text to clipboard (Ctrl+X)."));
++ a->setShortcut(Qt::CTRL+Qt::Key_X); o->addAction(a); t->addAction(a);
++
++ a = new QAction(QPixmap(":/png/edit-copy.png"), _("Copy text"), this);
++ connect(a, SIGNAL(triggered()), edit, SLOT(copy()));
++ a->setToolTip(_("Copy selected text or data to clipboard (Ctrl+C)."));
++ a->setShortcut(Qt::CTRL+Qt::Key_C); o->addAction(a); t->addAction(a);
++
++ a = new QAction(QPixmap(":/png/edit-paste.png"), _("Paste text"), this);
++ connect(a, SIGNAL(triggered()), edit, SLOT(paste()));
++ a->setToolTip(_("Paste text or data from clipboard (Ctrl+V)."));
++ a->setShortcut(Qt::CTRL+Qt::Key_V); o->addAction(a); t->addAction(a);
++
++ o->addAction(QPixmap(":/png/edit-select-all.png"), _("Select all"), edit, SLOT(selectAll()), Qt::CTRL+Qt::Key_A);
++ o->addSeparator();
++
++ a = new QAction(QPixmap(":/png/edit-find.png"), _("Find/Replace"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(find()));
++ a->setToolTip(_("Show dialog for text finding (Ctrl+F)."));
++ a->setShortcut(Qt::CTRL+Qt::Key_F); o->addAction(a); t->addAction(a);
++
++ a = new QAction(_("Find next"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(findText()));
++ a->setShortcut(Qt::Key_F3); o->addAction(a);
++ o->addSeparator();
++
++ // insert menu
++ oo = o->addMenu(_("Insert"));
++ aa=a = new QAction(QPixmap(":/png/format-indent-more.png"), _("New command"), this);
++ a->setShortcut(Qt::META+Qt::Key_C); connect(a, SIGNAL(triggered()), this, SLOT(newCmd()));
++ a->setToolTip(_("Show dialog for new command or edit arguments of existed one."));
++ oo->addAction(a);
++ a = new QAction(QPixmap(box_xpm), _("New inplot"), this);
++ a->setShortcut(Qt::META+Qt::Key_C); connect(a, SIGNAL(triggered()), subplotDlg, SLOT(show()));
++ a->setToolTip(_("Show dialog for new inplot and put it into the script."));
++ oo->addAction(a);
++
++ a = new QAction(_("Fitted formula"), this);
++ a->setShortcut(Qt::META+Qt::Key_F); connect(a, SIGNAL(triggered()), this, SLOT(insFitF()));
++ a->setToolTip(_("Insert last fitted formula with found coefficients."));
++ oo->addAction(a);
++ a = new QAction(QPixmap(style_xpm), _("Plot style"), this);
++ a->setShortcut(Qt::META+Qt::Key_S); connect(a, SIGNAL(triggered()), this, SLOT(addStyle()));
++ a->setToolTip(_("Show dialog for styles and put it into the script.\nStyles define the plot view (color scheme, marks, dashing and so on)."));
++ oo->addAction(a);
++ a = new QAction(QPixmap(option_xpm), _("Command options"), this);
++ a->setShortcut(Qt::META+Qt::Key_O); connect(a, SIGNAL(triggered()), this, SLOT(addOptions()));
++ a->setToolTip(_("Show dialog for options and put it into the script.\nOptions are used for additional setup the plot."));
++ oo->addAction(a);
++ a = new QAction(_("Numeric value"), this);
++ a->setShortcut(Qt::META+Qt::Key_N); connect(a, SIGNAL(triggered()), this, SLOT(insNVal()));
++ a->setToolTip(_("Replace expression by its numerical value."));
++ oo->addAction(a);
++ a = new QAction(QPixmap(":/png/text-csv.png"), _("File name"), this);
++ a->setShortcut(Qt::META+Qt::Key_P); connect(a, SIGNAL(triggered()), this, SLOT(insFile()));
++ a->setToolTip(_("Select and insert file name."));
++ oo->addAction(a);
++ a = new QAction(QPixmap(":/png/folder.png"), _("Folder path"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(insPath()));
++ a->setToolTip(_("Select and insert folder name."));
++ oo->addAction(a);
++ a = new QAction(QPixmap(curve_xpm), _("Manual primitives"), this);
++ a->setShortcut(Qt::META+Qt::Key_P); connect(a, SIGNAL(triggered()), this, SLOT(insPrim()));
++ a->setToolTip(_("Move mouse-handled primitives to script."));
++ oo->addAction(a); bb->setMenu(oo); bb->setDefaultAction(aa);
++
++ a = new QAction(QPixmap(":/png/document-properties.png"), _("Graphics setup"), this);
++ a->setShortcut(Qt::META+Qt::Key_G); connect(a, SIGNAL(triggered()), this, SLOT(addSetup()));
++ a->setToolTip(_("Show dialog for plot setup and put code into the script.\nThis dialog setup axis, labels, lighting and other general things."));
++ o->addAction(a); t->addAction(a);
++}
++//-----------------------------------------------------------------------------
--- /dev/null
--- /dev/null
++/***************************************************************************
++ * Copyright (C) 2008 by Alexey Balakin *
++ * mathgl.abalakin@gmail.com *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
++ ***************************************************************************/
++#ifdef WIN32
++#include <io.h>
++#include <direct.h>
++#else
++#include <unistd.h>
++#endif
++#include <QMenuBar>
++#include <QMessageBox>
++#include <QApplication>
++#include <QSettings>
++#include <QSplitter>
++#include <QFileDialog>
++#include <QStatusBar>
++#include <QDockWidget>
++#include <QCloseEvent>
++#include <QTextCodec>
++#include <QTranslator>
++#include <QMimeData>
++#include <QUrl>
++//-----------------------------------------------------------------------------
++#include <mgl2/qmathgl.h>
++#include "udav_wnd.h"
++#include "text_pnl.h"
++#include "plot_pnl.h"
++#include "prop_dlg.h"
++#include "qmglsyntax.h"
++//-----------------------------------------------------------------------------
++extern bool mglAutoExecute;
++PropDialog *propDlg=0;
++int MainWindow::num_wnd=0;
++QStringList recentFiles;
++int MaxRecentFiles=5;
++bool editPosBottom = false;
++bool mglAutoSave = false;
++bool mglHighlight = true;
++bool mglDotsRefr = true;
++// bool mglAutoPure = true;
++bool mglCompleter = true;
++bool loadInNewWnd = false;
++bool mglWheelZoom = false;
++QString pathHelp;
++extern mglParse parser;
++extern QColor mglColorScheme[10];
++extern QString defFontFamily;
++extern int defFontSize;
++extern QString pathFont;
++extern int defWidth, defHeight;
++//-----------------------------------------------------------------------------
++QWidget *createCalcDlg(QWidget *p, QTextEdit *e);
++QDialog *createArgsDlg(QWidget *p);
++QWidget *createMemPanel(QWidget *p);
++QWidget *createHlpPanel(QWidget *p);
++void showHelpMGL(QWidget *hlp, QString s);
++void addDataPanel(QWidget *p, QWidget *w, QString name)
++{
++ MainWindow *wnd = dynamic_cast<MainWindow *>(p);
++ if(wnd) wnd->addPanel(w, name);
++}
++//-----------------------------------------------------------------------------
++#ifndef UDAV_DIR
++#ifdef WIN32
++#define UDAV_DIR ""
++#else
++#define UDAV_DIR "/usr/local/share/udav/"
++#endif
++#endif
++//-----------------------------------------------------------------------------
++int mgl_cmd_cmp(const void *a, const void *b);
++void udavLoadDefCommands();
++void udavShowHint(QWidget *);
++void mgl_ask_qt(const wchar_t *quest, wchar_t *res);
++//-----------------------------------------------------------------------------
++int main(int argc, char **argv)
++{
++ QString lang="";
++ QSettings settings("udav","UDAV");
++ settings.setPath(QSettings::IniFormat, QSettings::UserScope, "UDAV");
++ settings.beginGroup("/UDAV");
++ pathHelp = settings.value("/helpPath", MGL_DOC_DIR).toString();
++ pathFont = settings.value("/userFont", "").toString();
++ lang = settings.value("/udavLang", "").toString();
++
++ const char *loc="";
++ if(lang=="en") loc = "C.UTF8";
++#if WIN32
++ if(lang=="ru") loc = "ru_RU.cp1251";
++#else
++ if(lang=="ru") loc = "ru_RU.utf8";
++#endif
++ if(lang=="es") { loc = "es_ES.utf8"; lang="en"; } // TODO remove lang="en"; then Spanish translation is ready !
++ mgl_textdomain(argv?argv[0]:NULL,loc);
++
++ bool showHint = settings.value("/showHint", true).toBool();
++ mglCompleter = settings.value("/completer", true).toBool();
++ settings.endGroup();
++
++ mgl_suppress_warn(true);
++ QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
++#ifdef WIN32
++ char buf[512]; getcwd(buf,500); strcat(buf,"\\plugins\\");
++ QCoreApplication::addLibraryPath(buf);
++ QCoreApplication::addLibraryPath("c:\\plugins\\");
++#endif
++ mgl_ask_func = mgl_ask_qt;
++ QApplication a(argc, argv);
++ QTranslator translator;
++//QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
++#if defined(WIN32)
++ if(pathHelp.isEmpty()) pathHelp = a.applicationDirPath()+"\\";
++#else
++ if(pathHelp.isEmpty()) pathHelp=MGL_DOC_DIR;
++#endif
++
++ if(!lang.isEmpty())
++ {
++ if(!translator.load("udav_"+lang, UDAV_DIR))
++ translator.load("udav_"+lang, pathHelp);
++ a.installTranslator(&translator);
++ }
++
++ udavLoadDefCommands();
++ parser.AllowSetSize(true);
++ MainWindow *mw = new MainWindow();
++ if(argc>1)
++ {
++ QTextCodec *codec = QTextCodec::codecForLocale();
++ mw->load(codec->toUnicode(argv[1]), true);
++ }
++ mw->show();
++ mw->edit->edit->setFocus();
++ a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
++ if(showHint) udavShowHint(mw);
++ return a.exec();
++}
++//-----------------------------------------------------------------------------
++//
++// mgl addon
++//
++//-----------------------------------------------------------------------------
++void udavLoadDefCommands() {} //{ udavAddCommands(udav_base_cmd); }
++//-----------------------------------------------------------------------------
++//
++// Class MainWindow
++//
++//-----------------------------------------------------------------------------
++MainWindow::MainWindow(QWidget *wp) : QMainWindow(wp)
++{
++ QAction *a;
++ setWindowTitle(_("untitled - UDAV"));
++ setAttribute(Qt::WA_DeleteOnClose);
++
++ split = new QSplitter(this);
++ ltab = new QTabWidget(split);
++ ltab->setMovable(true); ltab->setTabPosition(QTabWidget::South);
++// ltab->setTabsClosable(true);
++ rtab = new QTabWidget(split);
++ rtab->setMovable(true); rtab->setTabPosition(QTabWidget::South);
++
++ messWnd = new QDockWidget(_("Messages and warnings"),this);
++ mess = new QTextEdit(this); messWnd->setWidget(mess);
++ messWnd->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
++ addDockWidget(Qt::BottomDockWidgetArea, messWnd);
++ messWnd->resize(size().width(), 0); new MessSyntax(mess);
++// connect(mess,SIGNAL(cursorPositionChanged()),this,SLOT(messClicked()));
++ connect(mess,SIGNAL(selectionChanged()),this,SLOT(messClicked()));
++
++ hideWnd = new QDockWidget(_("Hidden plots"),this);
++ hidden = new TextEdit(this); hideWnd->setWidget(hidden);
++ hideWnd->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
++ addDockWidget(Qt::BottomDockWidgetArea, hideWnd);
++ hideWnd->resize(size().width(), 0); hidden->setReadOnly(true);
++ connect(hidden,SIGNAL(selectionChanged()),this,SLOT(hiddenClicked())); // TODO
++// connect(hidden,SIGNAL(cursorPositionChanged()),this,SLOT(hiddenClicked()));
++
++ calcWnd = new QDockWidget(_("Calculator"),this);
++
++ aload = a = new QAction(QPixmap(":/png/document-open.png"), _("Open file"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(choose()));
++ a->setToolTip(_("Open and execute/show script or data from file (Ctrl+O).\nYou may switch off automatic exection in UDAV properties."));
++ a->setShortcut(Qt::CTRL+Qt::Key_O);
++
++ asave = a = new QAction(QPixmap(":/png/document-save.png"), _("Save script"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(save()));
++ a->setToolTip(_("Save script to a file (Ctrl+S)"));
++ a->setShortcut(Qt::CTRL+Qt::Key_S);
++
++ acalc = a = new QAction(QPixmap(":/png/accessories-calculator.png"), _("Calculator"), this);
++ a->setShortcut(Qt::Key_F4); a->setCheckable(true);
++ connect(a, SIGNAL(toggled(bool)), calcWnd, SLOT(setVisible(bool)));
++ connect(calcWnd, SIGNAL(visibilityChanged(bool)), a, SLOT(setChecked(bool)));
++ a->setToolTip(_("Show calculator which evaluate and help to type textual formulas.\nTextual formulas may contain data variables too."));
++ a->setChecked(false); calcWnd->setVisible(false);
++
++ ainfo = a = new QAction(_("Show info"), this);
++ a->setShortcut(Qt::Key_F2); a->setCheckable(true);
++ connect(a, SIGNAL(toggled(bool)), messWnd, SLOT(setVisible(bool)));
++ connect(messWnd, SIGNAL(visibilityChanged(bool)), a, SLOT(setChecked(bool)));
++ a->setChecked(false); messWnd->setVisible(false);
++
++ ahide = a = new QAction(QPixmap(":/png/layer-visible-on.png"), _("Show hidden plots"), this);
++ a->setShortcut(Qt::Key_F8); a->setCheckable(true);
++ connect(a, SIGNAL(toggled(bool)), hideWnd, SLOT(setVisible(bool)));
++ connect(hideWnd, SIGNAL(visibilityChanged(bool)), a, SLOT(setChecked(bool)));
++ a->setChecked(false); hideWnd->setVisible(false);
++
++ graph = new PlotPanel(this);
++ rtab->addTab(graph,QPixmap(":/png/office-chart-line.png"),_("Canvas"));
++ // connect(info,SIGNAL(addPanel(QWidget*)),this,SLOT(addPanel(QWidget*)));
++ info = createMemPanel(this);
++ rtab->addTab(info,QPixmap(":/png/system-file-manager.png"),_("Info"));
++ hlp = createHlpPanel(this);
++ rtab->addTab(hlp,QPixmap(":/png/help-contents.png"),_("Help"));
++ edit = new TextPanel(this); edit->graph = graph;
++ graph->textMGL = edit->edit;
++ connect(graph->mgl,SIGNAL(showWarn(QString)),mess,SLOT(setText(QString)));
++ connect(graph->mgl,SIGNAL(showWarn(QString)),edit->edit,SLOT(setErrMessage(QString)));
++ connect(graph,SIGNAL(clearWarn()),mess,SLOT(clear()));
++ ltab->addTab(edit,QPixmap(":/png/text-plain.png"),_("Script"));
++
++ calcWnd->setWidget(createCalcDlg(this, edit->edit));
++ calcWnd->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
++ addDockWidget(Qt::BottomDockWidgetArea, calcWnd);
++ calcWnd->resize(size().width(), 200);
++
++ makeMenu();
++ setCentralWidget(split);
++ setWindowIcon(QIcon(":/udav.png"));
++ readSettings();
++ if(!propDlg) propDlg = new PropDialog;
++
++ connect(graph, SIGNAL(save()), this, SLOT(save()));
++ connect(graph, SIGNAL(setStatus(const QString &)), this, SLOT(setStatus(const QString &)));
++ connect(graph, SIGNAL(animPutText(const QString &)), edit, SLOT(animPutText(const QString &)));
++ connect(graph,SIGNAL(giveFocus()),edit->edit,SLOT(setFocus()));
++ connect(graph->mgl, SIGNAL(objChanged(int)), edit, SLOT(setCursorPosition(int)));
++// connect(graph->mgl, SIGNAL(posChanged(QString)), statusBar(), SLOT(showMessage(QString)));
++ connect(graph->mgl, SIGNAL(refreshData()), this, SLOT(refresh()));
++ connect(graph->mgl, SIGNAL(refreshData()), edit, SLOT(refreshData()));
++ connect(graph->mgl,SIGNAL(doubleClick(int)),edit,SLOT(newCmd(int)));
++
++ connect(edit->edit,SIGNAL(textChanged()),this,SLOT(updateHidden()));
++ connect(mess, SIGNAL(textChanged()), this, SLOT(warnChanged()));
++ connect(propDlg, SIGNAL(sizeChanged(int,int)), graph->mgl, SLOT(imgSize(int,int)));
++ connect(edit->edit,SIGNAL(textChanged()), this, SLOT(setAsterix()));
++ connect(edit->edit, SIGNAL(cursorPositionChanged()), this, SLOT(editPosChanged()));
++ connect(edit,SIGNAL(setCurrentFile(QString)),this,SLOT(setCurrentFile(QString)));
++ connect(edit,SIGNAL(setStatus(QString)),this,SLOT(setStatus(QString)));
++
++ setStatus(_("Ready"));
++ num_wnd++;
++ edit->setAcceptDrops(false); // for disabling default action by 'edit'
++ setAcceptDrops(true);
++}
++//-----------------------------------------------------------------------------
++void MainWindow::makeMenu()
++{
++ QAction *a;
++ QMenu *o;
++
++ // file menu
++ {
++ o = menuBar()->addMenu(_("File"));
++ a = new QAction(QPixmap(":/png/document-new.png"), _("New script"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(newDoc()));
++ a->setToolTip(_("Create new empty script window (Ctrl+N)."));
++ a->setShortcut(Qt::CTRL+Qt::Key_N); o->addAction(a);
++
++ o->addAction(aload);
++ o->addAction(asave);
++
++ a = new QAction(_("Save as ..."), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(saveAs()));
++ o->addAction(a);
++
++ o->addSeparator();
++ o->addAction(_("Print script"), edit, SLOT(printText()));
++ a = new QAction(QPixmap(":/png/document-print.png"), _("Print graphics"), this);
++ connect(a, SIGNAL(triggered()), graph->mgl, SLOT(print()));
++ a->setToolTip(_("Open printer dialog and print graphics (Ctrl+P)"));
++ a->setShortcut(Qt::CTRL+Qt::Key_P); o->addAction(a);
++ o->addSeparator();
++ fileMenu = o->addMenu(_("Recent files"));
++ o->addSeparator();
++ o->addAction(_("Quit"), qApp, SLOT(closeAllWindows()));
++ }
++
++ menuBar()->addMenu(edit->menu);
++ menuBar()->addMenu(graph->menu);
++
++ // settings menu
++ {
++ o = menuBar()->addMenu(_("Settings"));
++ a = new QAction(QPixmap(":/png/preferences-system.png"), _("Properties"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(properties()));
++ a->setToolTip(_("Show dialog for UDAV properties.")); o->addAction(a);
++ o->addAction(_("Set arguments"), createArgsDlg(this), SLOT(exec()));
++
++ o->addAction(acalc);
++ o->addAction(ainfo);
++ o->addAction(ahide);
++ }
++
++ menuBar()->addSeparator();
++ o = menuBar()->addMenu(_("Help"));
++ a = new QAction(QPixmap(":/png/help-contents.png"), _("MGL help"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(showHelp()));
++ a->setToolTip(_("Show help on MGL commands (F1)."));
++ a->setShortcut(Qt::Key_F1); o->addAction(a);
++ a = new QAction(QPixmap(":/png/help-faq.png"), _("Hints"), this);
++ connect(a, SIGNAL(triggered()), this, SLOT(showHint()));
++ a->setToolTip(_("Show hints of MGL usage.")); o->addAction(a);
++ o->addAction(_("About"), this, SLOT(about()));
++ o->addAction(_("About Qt"), this, SLOT(aboutQt()));
++}
++//-----------------------------------------------------------------------------
++void MainWindow::closeEvent(QCloseEvent* ce)
++{
++ bool ok=true;
++ writeSettings();
++ if(edit->isModified())
++ switch(QMessageBox::information(this, _("UDAV"),
++ _("Do you want to save the changes to the document?"),
++ QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel))
++ {
++ case QMessageBox::Yes: save(); break;
++ case QMessageBox::No: break;
++ default: ok=false; break;
++ }
++ if(ok)
++ {
++ num_wnd--;
++ ce->accept();
++ if(num_wnd==0) QApplication::quit();
++ }
++ else ce->ignore();
++}
++//-----------------------------------------------------------------------------
++void MainWindow::dropEvent(QDropEvent * de)
++{
++ // Linux Qt send "text/plain" mime data in drop event
++ // Windows version send "text/uri-list"
++ QTextCodec *codec = QTextCodec::codecForLocale();
++ QString filename;
++ if ( de->mimeData()->hasFormat("text/plain") )
++ {
++ // Under linux just convert the text from the local encodig to Qt's unicode
++ filename = codec->toUnicode(de->mimeData()->data("text/plain"));
++ if (filename.indexOf("file:") == 0)
++ load(filename.remove("file://").trimmed(), false);
++ }else
++ if ( de->mimeData()->hasUrls() )
++ {
++ // Under win - parse the dropped data and find the path to local file
++ QList<QUrl> UrlList;
++ QFileInfo finfo;
++ UrlList = de->mimeData()->urls();
++ if ( UrlList.size() > 0) // if at least one QUrl is present in list
++ {
++ filename = UrlList[0].toLocalFile(); // convert first QUrl to local path
++ finfo.setFile( filename );
++ if ( finfo.isFile() )
++ {
++ load(filename, false);
++ }
++ }
++ }
++}
++//-----------------------------------------------------------------------------
++void MainWindow::dragEnterEvent(QDragEnterEvent *event)
++{
++ QTextCodec *codec = QTextCodec::codecForLocale();
++ QString filename = codec->toUnicode(event->mimeData()->data("text/plain"));
++ /*if ( event->provides("text/plain") )
++ {
++ QTextCodec *codec = QTextCodec::codecForLocale();
++ QString instring = codec->toUnicode(event->mimeData()->data("text/plain"));
++ if ( instring.indexOf("file://") >= 0)
++ {
++ event->acceptProposedAction();
++ setStatus(instring);
++ }
++ }
++ else */
++ if(event->mimeData()->hasUrls())
++ {
++ QList<QUrl> UrlList;
++ QFileInfo finfo;
++ UrlList = event->mimeData()->urls();
++ if ( UrlList.size() > 0) // if at least one QUrl is present in list
++ {
++ filename = UrlList[0].toLocalFile(); // convert first QUrl to local path
++ finfo.setFile(filename);
++ if ( finfo.isFile() )
++ {
++ event->acceptProposedAction();
++ setStatus(filename);
++ }
++ }
++ }
++}
++//-----------------------------------------------------------------------------
++void MainWindow::showHelp()
++{
++ QString s = edit->selection(), dlm(" #;:\t");
++ int i, n = s.length();
++ for(i=0;i<n;i++) if(dlm.contains(s[i])) break;
++ s.truncate(i);
++// s = s.section(' ',0);
++ showHelpMGL(hlp,s);
++}
++//-----------------------------------------------------------------------------
++int mgl_cmd_cmp(const void *a, const void *b);
++void MainWindow::editPosChanged()
++{
++ QString text = edit->selection(), dlm(" #;:\t");
++ int n = text.length(), i;
++ for(i=0;i<n;i++) if(dlm.contains(text[i])) break;
++ text.truncate(i);
++
++ QByteArray qxtext = text.toLatin1();
++ const char *ctext = qxtext.constData();
++ const char *desc = parser.CmdDesc(ctext);
++ const char *form = parser.CmdFormat(ctext);
++ if(form) setStatus(QString(desc)+": "+QString(form));
++<<<<<<< HEAD
++ else setStatus(tr("Not recognized"));
++=======
++ else setStatus(_("Not recognized"));
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
++void MainWindow::setEditPos(bool bottom)
++{ split->setOrientation(bottom ? Qt::Vertical : Qt::Horizontal); }
++//-----------------------------------------------------------------------------
++void MainWindow::properties() { propDlg->exec(); }
++//-----------------------------------------------------------------------------
++void MainWindow::about()
++{
++ QString s = "<a href='http://mathgl.sourceforge.net/doc_en/UDAV-overview.html'>UDAV</a> v. 2."+QString::number(MGL_VER2)+
++ _("<br>(c) Alexey Balakin, 2007-present<br><br><a href='http://www.gnu.org/copyleft/gpl.html'>License is GPL v.2 or later.</a>");
++ QMessageBox::about(this, _("UDAV - about"), s);
++}
++//-----------------------------------------------------------------------------
++void MainWindow::aboutQt()
++{ QMessageBox::aboutQt(this, _("About Qt")); }
++//-----------------------------------------------------------------------------
++void MainWindow::writeSettings()
++{
++ QSettings settings("udav","UDAV");
++ settings.setPath(QSettings::IniFormat, QSettings::UserScope, "UDAV");
++ settings.beginGroup("/UDAV");
++ settings.setValue("/animDelay", animDelay);
++ settings.setValue("/geometry/size", size());
++// settings.setValue("/geometry/dock", messWnd->size());
++ settings.setValue("/geometry/split_e/w1", split->sizes().at(0));
++ settings.setValue("/geometry/split_e/w2", split->sizes().at(1));
++
++ settings.setValue("/recentFiles", recentFiles);
++ settings.setValue("/recentFilesMax", MaxRecentFiles);
++ settings.setValue("/helpPath", pathHelp);
++ settings.setValue("/userFont", pathFont);
++ settings.setValue("/colComment",mglColorScheme[0].name());
++ settings.setValue("/colString", mglColorScheme[1].name());
++ settings.setValue("/colKeyword",mglColorScheme[2].name());
++ settings.setValue("/colOption", mglColorScheme[3].name());
++ settings.setValue("/colSuffix", mglColorScheme[4].name());
++ settings.setValue("/colNumber", mglColorScheme[5].name());
++ settings.setValue("/colACKeyword", mglColorScheme[6].name());
++ settings.setValue("/colFCKeyword", mglColorScheme[7].name());
++ settings.setValue("/colReserved", mglColorScheme[8].name());
++ settings.setValue("/colCurrLine", mglColorScheme[9].name());
++ settings.setValue("/autoExec", mglAutoExecute);
++ settings.setValue("/autoSave", mglAutoSave);
++ settings.setValue("/highlight", mglHighlight);
++ settings.setValue("/dotsRefresh", mglDotsRefr);
++// settings.setValue("/autoPure", mglAutoPure);
++ settings.setValue("/editAtTop", editPosBottom);
++ settings.setValue("/fontFamily", defFontFamily);
++ settings.setValue("/fontSize", defFontSize);
++ settings.setValue("/loadInNewWnd", loadInNewWnd);
++ settings.setValue("/completer", mglCompleter);
++ settings.setValue("/wheelZoom", mglWheelZoom);
++ settings.endGroup();
++}
++//-----------------------------------------------------------------------------
++void MainWindow::readSettings()
++{
++ QSettings settings("udav","UDAV");
++ settings.setPath(QSettings::IniFormat, QSettings::UserScope, "UDAV");
++ settings.beginGroup("/UDAV");
++ pathHelp = settings.value("/helpPath", MGL_DOC_DIR).toString();
++ if(pathHelp.isEmpty()) pathHelp=MGL_DOC_DIR;
++ MaxRecentFiles = settings.value("/recentFilesMax", 5).toInt();
++ animDelay = settings.value("/animDelay", 500).toInt();
++ resize(settings.value("/geometry/size", QSize(880,720)).toSize());
++ QList<int> le;
++ le.append(settings.value("/geometry/split_e/w1", 230).toInt());
++ le.append(settings.value("/geometry/split_e/w2", 604).toInt());
++ split->setSizes(le);
++
++ pathFont = settings.value("/userFont", "").toString();
++ mglColorScheme[0] = QColor(settings.value("/colComment","#007F00").toString());
++ mglColorScheme[1] = QColor(settings.value("/colString", "#FF0000").toString());
++ mglColorScheme[2] = QColor(settings.value("/colKeyword","#00007F").toString());
++ mglColorScheme[3] = QColor(settings.value("/colOption", "#7F0000").toString());
++ mglColorScheme[4] = QColor(settings.value("/colSuffix", "#7F0000").toString());
++ mglColorScheme[5] = QColor(settings.value("/colNumber", "#0000FF").toString());
++ mglColorScheme[6] = QColor(settings.value("/colACKeyword","#7F007F").toString());
++ mglColorScheme[7] = QColor(settings.value("/colFCKeyword","#007F7F").toString());
++ mglColorScheme[8] = QColor(settings.value("/colReserved", "#0000FF").toString());
++ mglColorScheme[9] = QColor(settings.value("/colCurrLine", "#FFFFCC").toString());
++ mglAutoSave = settings.value("/autoSave", false).toBool();
++ mglHighlight = settings.value("/highlight", true).toBool();
++// mglAutoPure = settings.value("/autoPure", true).toBool();
++ mglAutoExecute = settings.value("/autoExec", true).toBool();
++ editPosBottom = settings.value("/editAtTop", false).toBool();
++ mglCompleter = settings.value("/completer", true).toBool();
++ mglWheelZoom = settings.value("/wheelZoom", false).toBool();
++ loadInNewWnd = settings.value("/loadInNewWnd", false).toBool();
++ mglDotsRefr = settings.value("/dotsRefresh", true).toBool();
++ defFontFamily = settings.value("/fontFamily", "Georgia").toString();
++ defFontSize = settings.value("/fontSize", 10).toInt();
++ edit->setEditorFont(); setEditPos(editPosBottom);
++ graph->setMGLFont(pathFont);
++ graph->mgl->enableWheel = mglWheelZoom;
++
++ defWidth = settings.value("/defWidth", 640).toInt();
++ defHeight = settings.value("/defHeight", 480).toInt();
++ graph->mgl->setSize(defWidth, defHeight);
++
++ recentFiles = settings.value("/recentFiles").toStringList();
++ settings.endGroup();
++ updateRecentFileItems();
++}
++//-----------------------------------------------------------------------------
++void MainWindow::setStatus(const QString &txt)
++{ statusBar()->showMessage(txt, 5000); }
++//-----------------------------------------------------------------------------
++void MainWindow::setCurrentFile(const QString &fileName)
++{
++ filename = fileName;
++ mgl_set_plotid(graph->mgl->getGraph(), fileName.toLocal8Bit().constData());
++ edit->setModified(false);
++ if(filename.isEmpty())
++ setWindowTitle(_("untitled - UDAV"));
++ else
++ {
++ setWindowTitle(QFileInfo(filename).fileName()+" - UDAV");
++ int i = recentFiles.indexOf(filename);
++ if(i>=0) recentFiles.removeAt(i);
++ recentFiles.push_front(filename);
++ updateRecentFileItems();
++ if(chdir(qPrintable(QFileInfo(filename).path())))
++ QMessageBox::warning(this, _("UDAV - save current"),
++ _("Couldn't change to folder ")+QFileInfo(filename).path());
++ }
++}
++//-----------------------------------------------------------------------------
++void MainWindow::openRecentFile()
++{
++ QAction *a = qobject_cast<QAction *>(sender());
++ if(!a) return;
++ if(edit->isModified())
++ switch(QMessageBox::information(this, _("UDAV - save current"),
++ _("Do you want to save the changes to the document?"),
++ QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel))
++ {
++ case QMessageBox::Yes: save(); break;
++ case QMessageBox::No: break;
++ default: return;
++ }
++ QString fn = recentFiles[a->data().toInt()];
++ if(!fn.isEmpty()) load(fn);
++}
++//-----------------------------------------------------------------------------
++void MainWindow::updateRecentFileItems()
++{
++ foreach(QWidget *w, QApplication::topLevelWidgets())
++ {
++ MainWindow *wnd = qobject_cast<MainWindow *>(w);
++ if(wnd) wnd->updateRecent();
++ }
++}
++//-----------------------------------------------------------------------------
++void MainWindow::updateRecent()
++{
++ QAction *a;
++ fileMenu->clear(); qApp->processEvents();
++ for(int i=0; i<recentFiles.size() && i<MaxRecentFiles; i++)
++ {
++ QString text="&"+QString::number(i+1)+" "+QFileInfo(recentFiles[i]).fileName();
++ a = fileMenu->addAction(text, this, SLOT(openRecentFile()));
++ a->setData(i);
++ }
++}
++//-----------------------------------------------------------------------------
++void MainWindow::newDoc()
++{
++ MainWindow *ed = new MainWindow;
++ ed->show(); ed->activateWindow();
++}
++//-----------------------------------------------------------------------------
++void MainWindow::choose()
++{
++ if(edit->isModified())
++ switch(QMessageBox::information(this, _("UDAV - save current"),
++ _("Do you want to save the changes to the document?"),
++ QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel))
++ {
++ case QMessageBox::Yes: save(); break;
++ case QMessageBox::No: break;
++ default: return;
++ }
++ QSettings settings("udav","UDAV");
++ settings.setPath(QSettings::IniFormat, QSettings::UserScope, "UDAV");
++ settings.beginGroup("/UDAV");
++ QString fn = QFileDialog::getOpenFileName(this,
++ _("UDAV - Open file"),
++ settings.value("/filePath", MGL_DOC_DIR).toString(),
++ _("MGL scripts (*.mgl)\nHDF5 files (*.hdf *.h5)\nText files (*.txt)\nData files (*.dat)\nAll files (*.*)"));
++ settings.endGroup();
++ if(!fn.isEmpty()) load(fn);
++ else setStatus(_("Loading aborted"));
++}
++//-----------------------------------------------------------------------------
++void MainWindow::load(const QString &fileName, bool noNewWnd)
++{
++ // save current path
++ QFileInfo fi(fileName); filename = fileName;
++ QSettings settings("udav","UDAV");
++ settings.setPath(QSettings::IniFormat, QSettings::UserScope, "UDAV");
++ settings.beginGroup("/UDAV");
++ settings.setValue("/filePath", fi.absolutePath());
++ settings.endGroup();
++ // open new window if it is required
++ if(loadInNewWnd && !noNewWnd)
++ {
++ MainWindow *mw = new MainWindow;
++ mw->edit->load(fileName);
++ mw->show(); //ed->activateWindow();
++ }
++ else edit->load(fileName);
++}
++//-----------------------------------------------------------------------------
++void MainWindow::save()
++{
++ if(filename.isEmpty()) saveAs();
++ else edit->save(filename);
++}
++//-----------------------------------------------------------------------------
++void MainWindow::saveAs()
++{
++ QString fn;
++ fn = QFileDialog::getSaveFileName(this, _("UDAV - save file"), "",
++ _("MGL scripts (*.mgl)\nHDF5 files (*.hdf *.h5)\nAll files (*.*)"));
++ if(fn.isEmpty())
++ { setStatus(_("Saving aborted")); return; }
++ else
++ {
++ int nn=fn.length();
++ if(fn[nn-4]!='.' && fn[nn-3]!='.') fn = fn + ".mgl";
++ filename = fn; save();
++ }
++}
++//-----------------------------------------------------------------------------
++void MainWindow::setAsterix()
++{
++ if(edit->isModified())
++ {
++ if(filename.isEmpty())
++ setWindowTitle(_("untitled* - UDAV"));
++ else
++ setWindowTitle(QFileInfo(filename).fileName()+"* - UDAV");
++ }
++ else
++ {
++ if(filename.isEmpty())
++ setWindowTitle(_("untitled - UDAV"));
++ else
++ setWindowTitle(QFileInfo(filename).fileName()+" - UDAV");
++ }
++}
++//-----------------------------------------------------------------------------
++void updateDataItems()
++{
++ foreach (QWidget *w, QApplication::topLevelWidgets())
++ if(w->inherits("MainWindow")) ((MainWindow *)w)->refresh();
++}
++//-----------------------------------------------------------------------------
++void MainWindow::addPanel(QWidget *w, QString name)
++{
++ ltab->addTab(w,QPixmap(":/png/text-csv.png"),name);
++ ltab->setCurrentWidget(w);
++}
++//-----------------------------------------------------------------------------
++MGL_LOCAL_PURE MainWindow *findMain(QWidget *wnd)
++{
++ MainWindow *mw=0;
++ QObject *w=wnd;
++
++ while(w && !mw)
++ {
++ mw = dynamic_cast<MainWindow *>(w);
++ w = w->parent();
++ }
++ return mw;
++}
++//-----------------------------------------------------------------------------
++void raisePanel(QWidget *w)
++{
++ MainWindow *mw=findMain(w);
++ if(mw) mw->rtab->setCurrentWidget(w);
++}
++//-----------------------------------------------------------------------------
++void MainWindow::updateHidden()
++{
++ QTextCursor tc = edit->edit->textCursor();
++ long pos = tc.position(), i=0;
++ hidden->clear();
++ tc.movePosition(QTextCursor::Start);
++ do {
++ i++;
++ if(tc.block().text().startsWith("#h "))
++ hidden->append("Line "+QString::number(i)+QString::fromWCharArray(L" \u2192 ")+tc.block().text().mid(3)+"\n");
++ } while(tc.movePosition(QTextCursor::NextBlock));
++ tc.setPosition(pos);
++}
++//-----------------------------------------------------------------------------
++void MainWindow::hiddenClicked()
++{
++ QString q = hidden->textCursor().block().text();
++ if(q.contains("Line "))
++ {
++ int n = q.section(' ',1,1).toInt()-1;
++ edit->edit->moveCursor(QTextCursor::Start);
++ for(int i=0;i<n;i++) edit->edit->moveCursor(QTextCursor::NextBlock);
++ edit->edit->textCursor().deleteChar();
++ edit->edit->textCursor().deleteChar();
++ edit->edit->textCursor().deleteChar();
++ }
++ graph->execute();
++}
++//-----------------------------------------------------------------------------
++void MainWindow::messClicked()
++{
++ QString q = mess->textCursor().block().text();
++ if(q.contains("in line "))
++ {
++ QString s = q.section(' ',-1);
++ int n = q.section(' ',-1).toInt()-1; if(n<0) return;
++ edit->moveCursor(QTextCursor::Start);
++ for(int i=0;i<n;i++) edit->moveCursor(QTextCursor::NextBlock);
++ }
++ edit->setFocus();
++}
++//-----------------------------------------------------------------------------
++void MainWindow::warnChanged()
++{
++ if(mess->toPlainText().isEmpty())
++ { messWnd->hide(); ainfo->setChecked(false); }
++ else
++ { messWnd->show(); ainfo->setChecked(true); }
++}
++//-----------------------------------------------------------------------------
--- /dev/null
--- /dev/null
++add_executable(make_pas make_pas.cpp)
++
++add_executable(mglconv mglconv.cpp)
++if(MSVC)
++set(link_type -static)
++else(MSVC)
++set(link_type)
++endif(MSVC)
++target_link_libraries(mglconv mgl${link_type} ${getopt_lib-static})
++install(
++ TARGETS mglconv
++ EXPORT MathGLTargets
++ RUNTIME DESTINATION ${MathGL_INSTALL_BIN_DIR}
++)
++
++add_executable(mgl.cgi mglcgi.cpp)
++target_link_libraries(mgl.cgi mgl${link_type})
++install(
++ TARGETS mgl.cgi
++ EXPORT MathGLTargets
++# should be /usr/lib/cgi-bin/
++ RUNTIME DESTINATION ${MGL_CGI_PATH}
++)
++
++<<<<<<< HEAD
++if(QT_ENABLED)
++ add_executable(mglview mglview.cpp)
++ if(enable-qt5)
++ include(../cmake-qt5.txt)
++ target_link_libraries(mglview mgl-qt5${link_type} ${getopt_lib-static} ${MGL_QT5_LIBS})
++ else(enable-qt5)
++ include(../cmake-qt4.txt)
++ target_link_libraries(mglview mgl-qt4${link_type} ${getopt_lib-static} ${MGL_QT4_LIBS})
++ endif(enable-qt5)
++=======
++mgl_po_src(mglconv.cpp mglview.cpp mglcgi.cpp)
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++
++if(MGL_HAVE_FLTK)
++ add_definitions(-DUSE_FLTK)
++ add_executable(mglview mglview.cpp)
++ target_link_libraries(mglview mgl-fltk ${getopt_lib-static} ${FLTK_LIBRARIES})
++ install(
++ TARGETS mglview
++ EXPORT MathGLTargets
++ RUNTIME DESTINATION ${MathGL_INSTALL_BIN_DIR}
++ )
++
++else(MGL_HAVE_FLTK)
++ if(QT_ENABLED)
++ add_executable(mglview mglview.cpp)
++ if(enable-qt5)
++ include(../scripts/qt5.cmake)
++ target_link_libraries(mglview mgl-qt5${link_type} ${getopt_lib-static} ${MGL_QT5_LIBS})
++ else(enable-qt5)
++ include(../scripts/qt4.cmake)
++ target_link_libraries(mglview mgl-qt4${link_type} ${getopt_lib-static} ${MGL_QT4_LIBS})
++ endif(enable-qt5)
++
++ install(
++ TARGETS mglview
++ EXPORT MathGLTargets
++ RUNTIME DESTINATION ${MathGL_INSTALL_BIN_DIR}
++ )
++ endif(QT_ENABLED)
++endif(MGL_HAVE_FLTK)
--- /dev/null
--- /dev/null
++/***************************************************************************
++ * mglview.cpp is part of Math Graphic Library
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU General Public License as published by *
++ * the Free Software Foundation; either version 2 of the License, or *
++ * (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU General Public License *
++ * along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
++ ***************************************************************************/
++#include <locale.h>
++#include <getopt.h>
++
++#include "mgl2/mgl.h"
++<<<<<<< HEAD
++#include "mgl2/qt.h"
++#include "mgl2/parser.h"
++=======
++#if USE_FLTK
++ #include "mgl2/fltk.h"
++ #include <Fl/Fl.H>
++ #include <Fl/Fl_Preferences.H>
++#else
++ #include "mgl2/qt.h"
++#endif
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++//-----------------------------------------------------------------------------
++std::wstring str, opt;
++mglParse p(true);
++//-----------------------------------------------------------------------------
++int show(mglGraph *gr)
++{
++ p.Execute(gr,str.c_str());
++ printf("%s\n",gr->Message());
++ return 0;
++}
++//-----------------------------------------------------------------------------
++int main(int argc, char **argv)
++{
++ mgl_textdomain(argv?argv[0]:NULL,"");
++ char iname[256]="";
++ mgl_suppress_warn(true);
++ bool gray = false;
++ while(1)
++ {
++ int ch = getopt(argc, argv, "1:2:3:4:5:6:7:8:9:hL:s:g:v:");
++ if(ch>='1' && ch<='9') p.AddParam(ch-'0', optarg);
++ else if(ch=='s')
++ {
++ FILE *fp = fopen(optarg,"r");
++ if(fp)
++ {
++ wchar_t ch;
++ while(!feof(fp) && size_t(ch=fgetwc(fp))!=WEOF) opt.push_back(ch);
++ fclose(fp);
++ }
++ }
++ else if(ch=='v') p.SetVariant(atoi(optarg));
++ else if(ch=='g') gray= atoi(optarg);
++<<<<<<< HEAD
++ else if(ch=='L') setlocale(LC_CTYPE, optarg);
++=======
++ else if(ch=='L')
++ { setlocale(LC_ALL, optarg); setlocale(LC_NUMERIC, "C"); }
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ else if(ch=='h' || (ch==-1 && optind>=argc))
++ {
++ printf(_("mglview show plot from MGL script or MGLD file.\nCurrent version is 2.%g\n"),MGL_VER2);
++ printf(_("Usage:\tmglview [parameter(s)] scriptfile\n"));
++ printf(
++ _("\t-1 str set str as argument $1 for script\n"
++ "\t... ...\n"
++ "\t-9 str set str as argument $9 for script\n"
++ "\t-g val set gray-scale mode (val=0|1)\n"
++ "\t-v val set variant of arguments\n"
++ "\t-s opt set MGL script for setting up the plot\n"
++ "\t-L loc set locale to loc\n"
++ "\t- get script from standard input\n"
++ "\t-h print this message\n") );
++ return 0;
++ }
++ else if(ch==-1 && optind<argc)
++ { mgl_strncpy(iname, argv[optind][0]=='-'?"":argv[optind],256); break; }
++ }
++
++ bool mgld=(*iname && iname[strlen(iname)-1]=='d');
++ if(!mgld)
++ {
++ str = opt + L"\n";
++ FILE *fp = *iname?fopen(iname,"r"):stdin;
++ if(fp)
++ {
++ wchar_t ch;
++ while(!feof(fp) && size_t(ch=fgetwc(fp))!=WEOF) str.push_back(ch);
++ fclose(fp);
++ }
++ else { printf("No file for MGL script\n"); return 0; }
++ }
++
++#if USE_FLTK
++ mgl_ask_func = mgl_ask_fltk;
++ Fl_Preferences pref(Fl_Preferences::USER,"abalakin","mgllab");
++ static const char *sch[4]={"base","gtk+","plastic","gleam"};
++ int scheme; pref.get("scheme",scheme,2);
++ Fl::scheme(sch[scheme]);
++ mglFLTK gr(mgld?NULL:show, *iname?iname:"mglview");
++#else
++ mgl_ask_func = mgl_ask_qt;
++ mglQT gr(mgld?NULL:show, *iname?iname:"mglview");
++<<<<<<< HEAD
++=======
++#endif
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ if(gray) gr.Gray(gray);
++
++ if(mgld)
++ {
++ gr.Setup(false);
++ gr.NewFrame();
++ const std::string loc = setlocale(LC_NUMERIC, "C");
++ if(!opt.empty())
++ {
++ p.Execute(&gr,opt.c_str());
++ printf("Setup script: %s\n",gr.Message());
++ gr.ImportMGLD(iname,true);
++ }
++ else gr.ImportMGLD(iname);
++ setlocale(LC_NUMERIC, loc.c_str());
++ gr.EndFrame(); gr.Update();
++ }
++ if(!mglGlobalMess.empty()) printf("%s",mglGlobalMess.c_str());
++ return gr.Run();
++}
++//-----------------------------------------------------------------------------
--- /dev/null
--- /dev/null
++/***************************************************************************
++ * fltk.cpp is part of Math Graphic Library
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU Library General Public License as *
++ * published by the Free Software Foundation; either version 3 of the *
++ * License, or (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU Library General Public *
++ * License along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
++ ***************************************************************************/
++#include <FL/Fl_Pixmap.H>
++#include <FL/fl_ask.H>
++#include <FL/Fl_Double_Window.H>
++#include <FL/fl_draw.H>
++#include <FL/Fl_Native_File_Chooser.H>
++//-----------------------------------------------------------------------------
++#include "mgl2/canvas_wnd.h"
++#include "mgl2/Fl_MathGL.h"
++#include <limits.h>
++//-----------------------------------------------------------------------------
++#define MGL_MAX_LINES (INT_MAX-1000)
++//-----------------------------------------------------------------------------
++/// Class allows the window creation for displaying plot bitmap with the help of FLTK library
++/** NOTE!!! All frames are saved in memory. So animation with many frames require a lot memory and CPU time (for example, for mouse rotation).*/
++class mglCanvasFL : public mglCanvasWnd
++{
++public:
++using mglCanvasWnd::Window;
++ Fl_Window *Wnd; ///< Pointer to window
++ Fl_MGLView *mgl; ///< Pointer to MGL widget with buttons
++
++ mglCanvasFL();
++ virtual ~mglCanvasFL();
++
++ /// Create a window for plotting. Now implemeted only for GLUT.
++ void Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p), const char *title,
++ void *par=NULL, void (*reload)(void *p)=NULL, bool maximize=false);
++ /// Switch on/off transparency (do not overwrite switches in user drawing function)
++ void ToggleAlpha();
++ /// Switch on/off lighting (do not overwrite switches in user drawing function)
++ void ToggleLight();
++ void ToggleRotate(); ///< Switch on/off rotation by mouse
++ void ToggleZoom(); ///< Switch on/off zooming by mouse
++ void ToggleNo(); ///< Switch off all zooming and rotation
++ void Update(); ///< Update picture by calling user drawing function
++ void Adjust(); ///< Adjust size of bitmap to window size
++ void GotoFrame(int d); ///< Show arbitrary frame (use relative step)
++ void Animation(); ///< Run animation (I'm too lasy to change it)
++};
++//-----------------------------------------------------------------------------
++void MGL_EXPORT mgl_ask_fltk(const wchar_t *quest, wchar_t *res)
++{
++ static char buf[1024]; *res=0; // TODO
++#if FL_MINOR_VERSION>=3
++ fl_utf8fromwc(buf, 1024, quest, mgl_wcslen(quest)+1);
++ const char *str = fl_input("%s",buf,"");
++ if(str) fl_utf8towc(str, strlen(str)+1, res, 1024);
++#else
++ wcstombs(buf,quest,mgl_wcslen(quest)+1);
++ const char *str = fl_input("%s",buf,"");
++ MGL_TO_WCS(str,wcscpy(res,str));
++#endif
++}
++//-----------------------------------------------------------------------------
++//
++// class Fl_MathGL
++//
++//-----------------------------------------------------------------------------
++MGL_EXPORT const char *mgl_file_chooser(const char *mess, const char *filter, bool save)
++{
++ static Fl_Native_File_Chooser fnfc;
++ fnfc.title(mess);
++ fnfc.type(save ? Fl_Native_File_Chooser::BROWSE_SAVE_FILE : Fl_Native_File_Chooser::BROWSE_FILE);
++ fnfc.filter(filter);
++// fnfc.directory("/var/tmp"); // default directory to use
++ fnfc.show();
++ return fnfc.filename();
++}
++MGL_EXPORT const char *mgl_dir_chooser(const char *mess, const char *path)
++{
++ static Fl_Native_File_Chooser fnfc;
++ fnfc.title(mess);
++ fnfc.type(Fl_Native_File_Chooser::BROWSE_DIRECTORY);
++ fnfc.directory(path); // default directory to use
++ fnfc.show();
++ return fnfc.filename();
++}
++//-----------------------------------------------------------------------------
++Fl_MathGL::Fl_MathGL(int xx, int yy, int ww, int hh, const char *lbl) : Fl_Widget(xx,yy,ww,hh,lbl)
++{
++ gr = new mglCanvas; use_pthr = true;
++ tet=phi=x1=y1=0; x2=y2=1; img = 0;
++ zoom = rotate = handle_keys = grid = false;
++ flag=x0=y0=xe=ye=0; show_warn=true;
++ tet_val = phi_val = 0;
++ draw_par = 0; draw_func = 0; draw_cl = 0;
++ last_id = -1; run = false;
++ popup=0; vpar=0; wpar=0; thr=0;
++}
++//-----------------------------------------------------------------------------
++Fl_MathGL::~Fl_MathGL() { if(mgl_use_graph(gr,-1)<1) mgl_delete_graph(gr); }
++//-----------------------------------------------------------------------------
++void Fl_MathGL::stop(bool stop) { gr->AskStop(stop); }
++//-----------------------------------------------------------------------------
++void mgl_fltk_event_func(void *) { Fl::awake(); }
++//-----------------------------------------------------------------------------
++void Fl_MathGL::set_graph(HMGL GR)
++{
++ mglCanvas *gg = dynamic_cast<mglCanvas *>(GR);
++ if(!gg) return;
++ if(gr && mgl_use_graph(gr,-1)<1) mgl_delete_graph(gr);
++ gr=gg; mgl_use_graph(gg,1);
++ gr->SetEventFunc(mgl_fltk_event_func, NULL);
++}
++//-----------------------------------------------------------------------------
++void Fl_MathGL::draw()
++{
++ if(!img) img = mgl_get_rgb(gr);
++ int ww=mgl_get_width(gr), hh=mgl_get_height(gr);
++ if(img) fl_draw_image(img, x(), y(), ww, hh, 3);
++ if(grid)
++ {
++ char str[5]="0.0";
++ fl_color(192,192,192);
++ for(int i=1;i<10;i++)
++ {
++ str[2] = '0'+10-i; fl_draw(str, x(), y()+i*hh/10);
++ fl_line(x(), y()+i*hh/10, x()+ww, y()+i*hh/10);
++ str[2] = '0'+i; fl_draw(str, x()+i*ww/10, y()+hh);
++ fl_line(x()+i*ww/10, y(), x()+i*ww/10, y()+hh);
++ }
++ int d = (hh>ww?ww:hh)/100;
++ for(size_t i=0;i<gr->Act.size();i++)
++ {
++ const mglActivePos &p=gr->Act[i];
++ fl_rectf(x()+p.x-d/2, y()+p.y-d/2-1, d,d, fl_rgb_color(127,255,63));
++ fl_rect(x()+p.x-d/2, y()+p.y-d/2-1, d,d, FL_BLACK);
++ }
++ mgl_set_flag(gr,1,MGL_SHOW_POS);
++ }
++ else mgl_set_flag(gr,0,MGL_SHOW_POS);
++}
++//-----------------------------------------------------------------------------
++inline void Fl_MathGL::draw_plot() // drawing itself
++{
++ if(draw_func || draw_cl)
++ {
++ mgl_set_def_param(gr); mgl_reset_frames(gr);
++ if(mgl_get_flag(gr,MGL_CLF_ON_UPD)) mgl_set_def_param(gr);
++ mgl_set_alpha(gr,flag&1); mgl_set_light(gr,flag&2);
++ if(tet_val) tet = tet_val->value();
++ if(phi_val) phi = phi_val->value();
++ mgl_zoom(gr,x1,y1,x2,y2); mgl_view(gr,-phi,-tet,0);
++ const std::string loc = setlocale(LC_NUMERIC, "C");
++ // use frames for quickly redrawing while adding/changing primitives
++ if(mgl_is_frames(gr)) mgl_new_frame(gr);
++
++ if(draw_func) draw_func(gr, draw_par);
++ else if(draw_cl) { mglGraph g(gr); draw_cl->Draw(&g); }
++
++ if(mgl_is_frames(gr)) mgl_end_frame(gr);
++ setlocale(LC_NUMERIC, loc.c_str());
++ const char *buf = mgl_get_mess(gr);
++ if(show_warn && *buf) fl_message("%s",buf);
++ if(!prim.empty()) // manual primitives
++ {
++ const std::string loc = setlocale(LC_NUMERIC, "C");
++ mgl_subplot(gr,1,1,0,"#");
++ mgl_set_ranges(gr, -1,1, -1,1, -1,1);
++ mglParse pr; pr.StartID(MGL_MAX_LINES);
++ mgl_parse_text(gr,pr.Self(),prim.c_str());
++ setlocale(LC_NUMERIC, loc.c_str());
++ }
++ }
++ else if(mgl_get_num_frame(gr)>0)
++ {
++ mgl_set_alpha(gr,flag&1); mgl_set_light(gr,flag&2);
++ if(tet_val) tet = tet_val->value();
++ if(phi_val) phi = phi_val->value();
++ mgl_zoom(gr,x1,y1,x2,y2); mgl_view(gr,-phi,-tet,0);
++ mgl_get_frame(gr,0);
++ }
++ mgl_finish(gr); img = mgl_get_rgb(gr);
++ run = false; Fl::awake();
++}
++//-----------------------------------------------------------------------------
++MGL_NO_EXPORT void *draw_plot_thr(void *v)
++{ ((Fl_MathGL*)v)->draw_plot(); return 0; }
++//-----------------------------------------------------------------------------
++void Fl_MathGL::update()
++{
++ if(run) return;
++// Fl::lock();
++ run = true;
++#if MGL_HAVE_FL_COPY
++ top_window()->cursor(FL_CURSOR_WAIT);
++#endif
++#if MGL_HAVE_PTHR_WIDGET
++ if(use_pthr)
++ {
++ pthread_create(&thr,0,draw_plot_thr,this);
++ while(run) Fl::wait();
++ pthread_join(thr,0);
++ }
++<<<<<<< HEAD
++ else if(mgl_get_num_frame(gr)>0)
++ {
++ mgl_set_alpha(gr,flag&1); mgl_set_light(gr,flag&2);
++ if(tet_val) tet = tet_val->value();
++ if(phi_val) phi = phi_val->value();
++ mgl_zoom(gr,x1,y1,x2,y2); mgl_view(gr,-phi,-tet,0);
++ mgl_get_frame(gr,0);
++ }
++=======
++ else
++#endif
++ draw_plot();
++// Fl::unlock();
++
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ if(mgl_get_width(gr)!=w() || mgl_get_height(gr)!=h())
++ size(mgl_get_width(gr), mgl_get_height(gr));
++ gr->AskStop(false); redraw();
++#if MGL_HAVE_FL_COPY
++ top_window()->cursor(FL_CURSOR_DEFAULT);
++#endif
++ Fl::flush();
++}
++//-----------------------------------------------------------------------------
++void Fl_MathGL::resize(int xx, int yy, int ww, int hh)
++{ Fl_Widget::resize(xx,yy,ww,hh); }
++//-----------------------------------------------------------------------------
++int Fl_MathGL::handle(int code)
++{
++ static bool busy=false;
++ static int last_pos=-1;
++ if(handle_keys && code==FL_KEYUP && Fl::event_button()!=FL_LEFT_MOUSE)
++ {
++ int key=Fl::event_key();
++ if(!strchr(" .,wasdrfx",key)) return 0;
++ if(key==' ') { update(); return 1; }
++ if(key=='w')
++ {
++ tet += 10;
++ if(tet_val) tet_val->value(tet);
++ update(); return 1;
++ }
++ if(key=='s')
++ {
++ tet -= 10;
++ if(tet_val) tet_val->value(tet);
++ update(); return 1;
++ }
++ if(key=='a')
++ {
++ phi += 10;
++ if(phi_val) phi_val->value(phi);
++ update(); return 1;
++ }
++ if(key=='d')
++ {
++ phi -= 10;
++ if(phi_val) phi_val->value(phi);
++ update(); return 1;
++ }
++ if(key=='x')
++ {
++ mglCanvasFL *g=dynamic_cast<mglCanvasFL *>(gr);
++ if(g && g->mgl->FMGL==this)
++ { g->Wnd->hide(); return 1; }
++ else return 0;
++ // exit(0);
++ }
++ if(key==',')
++ {
++ mglCanvasFL *g=dynamic_cast<mglCanvasFL *>(gr);
++ if(g && g->mgl->FMGL==this)
++ { g->PrevFrame(); return 1; }
++ else return 0;
++ }
++ if(key=='.')
++ {
++ mglCanvasFL *g=dynamic_cast<mglCanvasFL *>(gr);
++ if(g && g->mgl->FMGL==this)
++ { g->NextFrame(); return 1; }
++ else return 0;
++ }
++ if(key=='r')
++ { flag = (flag&2) + ((~(flag&1))&1); update(); return 1; }
++ if(key=='f')
++ { flag = (flag&1) + ((~(flag&2))&2); update(); return 1; }
++ }
++ else if(code==FL_PUSH)
++ {
++ last_pos=-1; xe=x0=Fl::event_x(); ye=y0=Fl::event_y();
++ if(popup && Fl::event_button()==FL_RIGHT_MOUSE)
++ {
++ const Fl_Menu_Item *m = popup->popup(Fl::event_x(), Fl::event_y(), 0, 0, 0);
++ if(m) m->do_callback(wpar, vpar);
++ }
++ else if(!zoom && !rotate && Fl::event_button()==FL_LEFT_MOUSE)
++ {
++ int xx = x0-x(), yy = y0-y();
++ last_id = mgl_get_obj_id(gr,xx, yy);
++ if(last_id>=MGL_MAX_LINES) last_id=-1;
++ mglCanvasWnd *g=dynamic_cast<mglCanvasWnd *>(gr);
++ if(g && g->ClickFunc) g->ClickFunc(draw_par);
++ if(mgl_get_flag(gr,MGL_SHOW_POS))
++ {
++ mglPoint p = gr->CalcXYZ(xx, yy);
++ if(g) g->LastMousePos = p;
++ char s[128];
++ snprintf(s,128,"x=%g, y=%g, z=%g",p.x,p.y,p.z); s[127]=0;
++ draw(); fl_color(FL_BLACK); fl_draw(s,40,70);
++ }
++ if(Fl::event_clicks())
++ {
++ int id = mgl_get_obj_id(gr,x0-x(), y0-y()) - MGL_MAX_LINES-1;
++ if(grid && id>=0) // delete manual primitive
++ {
++ prim = (id>0?mgl_str_arg(prim, '\n', 0,id-1)+'\n':"") + mgl_str_arg(prim, '\n', id+1,INT_MAX);
++ update();
++ }
++ else if(draw_cl) draw_cl->Click();
++ else update();
++ }
++ }
++ return 1;
++ }
++ else if(code==FL_DRAG)
++ {
++ if(busy) return 1; // remove possible conflicts of too often events
++ busy = true; xe=Fl::event_x(); ye=Fl::event_y();
++ mreal ff = 240./sqrt(mreal(w()*h()));
++ // handle primitives
++ int id = mgl_get_obj_id(gr,x0-x(), y0-y()) - MGL_MAX_LINES-1;
++ int ww=mgl_get_width(gr), hh=mgl_get_height(gr), d=(hh>ww?ww:hh)/100;
++ long pos = mgl_is_active(gr,x0-x(),y0-y(),d);
++ if(grid && pos<0) pos=last_pos;
++ if(grid && pos>=0)
++ {
++// Fl::lock();
++ last_pos=pos;
++ const mglActivePos &p = gr->Act[pos];
++ id = long(p.id)-MGL_MAX_LINES-1;
++ if(id<0) return 0;
++ std::string line = mgl_str_arg(prim, '\n', id), res;
++ if(line.empty()) return 0; // NOTE stupid check (never should be here)
++ std::vector<std::string> arg = mgl_str_args(line,' ');
++ // try "attract" mouse
++ for(size_t i=0;i<=10;i++)
++ {
++ int tt = i*(w()/10); if(abs(xe-tt)<2*d) xe = tt;
++ tt = i*(h()/10); if(abs(ye-tt)<2*d) ye = tt;
++ }
++ for(size_t i=0;i<gr->Act.size();i++)
++ {
++ const mglActivePos &q = gr->Act[i];
++ if(abs(xe-q.x)<2*d && abs(ye-q.y)<2*d) { xe=q.x; ye=q.y; }
++ }
++ // now move point
++ float dx = 2*(xe-x0)/float(w()), dy = 2*(y0-ye)/float(h());
++ float xx=atof(arg[1].c_str()), yy=atof(arg[2].c_str());
++ if(p.n==0) { arg[1]=mgl_str_num(xx+dx); arg[2]=mgl_str_num(yy+dy); }
++ else if(arg[0]=="rect")
++ {
++ float x_=atof(arg[3].c_str()), y_=atof(arg[4].c_str());
++ if(p.n==1) { xx+=dx; y_+=dy; }
++ if(p.n==2) { x_+=dx; yy+=dy; }
++ if(p.n==3) { x_+=dx; y_+=dy; }
++ arg[1]=mgl_str_num(xx); arg[2]=mgl_str_num(yy);
++ arg[3]=mgl_str_num(x_); arg[4]=mgl_str_num(y_);
++ }
++ else if(p.n==1)
++ {
++ float xx=atof(arg[3].c_str()), yy=atof(arg[4].c_str());
++ arg[3]=mgl_str_num(xx+dx); arg[4]=mgl_str_num(yy+dy);
++ }
++ else if(arg[0]=="rhomb" || arg[0]=="ellipse")
++ {
++ float x_=atof(arg[3].c_str())-xx, y_=atof(arg[4].c_str())-yy;
++ float r_=atof(arg[5].c_str()), dr=0;
++ if(x_*x_+y_*y_>0)
++ { dr = (dx*x_+dy*y_)/(x_*x_+y_*y_); dr = hypot(dx-dr*x_,dy-dr*y_); }
++ else dr = hypot(dx,dy);
++ arg[5]=mgl_str_num(r_+dr);
++ }
++ else if(arg[0]=="arc")
++ {
++ float x_=atof(arg[3].c_str())-xx, y_=atof(arg[4].c_str())-yy;
++ float a_=atof(arg[5].c_str());
++ double c=cos(M_PI*a_/180), s=sin(M_PI*a_/180);
++ double a = atan2(x_,y_) - atan2(x_*c-y_*s+dx,x_*s+y_*c+dy);
++ arg[5]=mgl_str_num(a*180/M_PI);
++ }
++ else if(p.n==2)
++ {
++ float xx=atof(arg[5].c_str()), yy=atof(arg[6].c_str());
++ arg[5]=mgl_str_num(xx+dx); arg[6]=mgl_str_num(yy+dy);
++ }
++ else if(p.n==3)
++ {
++ float xx=atof(arg[7].c_str()), yy=atof(arg[8].c_str());
++ if(arg[0]=="curve") { dx*=-1; dy*=-1; }
++ arg[7]=mgl_str_num(xx+dx); arg[8]=mgl_str_num(yy+dy);
++ }
++ res = arg[0]; for(size_t i=1;i<arg.size();i++) res += ' '+arg[i];
++ prim = (id>0?mgl_str_arg(prim, '\n', 0,id-1)+'\n':"") + res+'\n' + mgl_str_arg(prim, '\n', id+1,INT_MAX);
++// Fl::unlock();
++ x0 = xe; y0 = ye; update();
++ }
++ else if(grid && id>=0)
++ {
++// Fl::lock();
++ std::string line = mgl_str_arg(prim, '\n', id), res;
++ if(line.empty()) return 0; // NOTE stupid check (never should be here)
++ std::vector<std::string> arg = mgl_str_args(line,' ');
++
++ float dx = 2*(xe-x0)/float(w()), dy = 2*(y0-ye)/float(h());
++ float x1=atof(arg[1].c_str()), y1=atof(arg[2].c_str());
++ arg[1] = mgl_str_num(x1+dx); arg[2] = mgl_str_num(y1+dy);
++ if(arg[0]=="curve")
++ {
++ float x2=atof(arg[5].c_str()), y2=atof(arg[6].c_str());
++ arg[5]=mgl_str_num(x2+dx); arg[6]=mgl_str_num(y2+dy);
++ }
++ else if(arg[0]!="ball")
++ {
++ float x2=atof(mgl_str_arg(line,' ',3).c_str()), y2=atof(mgl_str_arg(line,' ',4).c_str());
++ arg[3]=mgl_str_num(x2+dx); arg[4]=mgl_str_num(y2+dy);
++ }
++ res = arg[0]; for(size_t i=1;i<arg.size();i++) res += ' '+arg[i];
++ prim = (id>0?mgl_str_arg(prim, '\n', 0,id-1)+'\n':"") + res+'\n' + mgl_str_arg(prim, '\n', id+1,INT_MAX);
++// Fl::unlock();
++ x0 = xe; y0 = ye; update();
++ }
++ else if(rotate)
++ {
++ phi += (x0-xe)*ff;
++ tet += (y0-ye)*ff;
++ if(phi>180) phi-=360;
++ if(phi<-180) phi+=360;
++ if(tet>180) tet-=360;
++ if(tet<-180) tet+=360;
++ if(tet_val) tet_val->value(tet);
++ if(phi_val) phi_val->value(phi);
++ x0 = xe; y0 = ye; update();
++ }
++ busy = false; redraw(); return 1;
++ }
++ else if(code==FL_RELEASE)
++ {
++ last_pos=-1;
++ if(zoom)
++ {
++ int w1=w(),h1=h();
++ mreal _x1,_x2,_y1,_y2;
++ _x1 = x1+(x2-x1)*(x0-x())/mreal(w1);
++ _y1 = y2-(y2-y1)*(ye-y())/mreal(h1);
++ _x2 = x1+(x2-x1)*(xe-x())/mreal(w1);
++ _y2 = y2-(y2-y1)*(y0-y())/mreal(h1);
++ x1=_x1; x2=_x2; y1=_y1; y2=_y2;
++ if(x1>x2) { _x1=x1; x1=x2; x2=_x1; }
++ if(y1>y2) { _x1=y1; y1=y2; y2=_x1; }
++ update();
++ }
++ else if(rotate)
++ {
++ if(tet_val) tet_val->value(tet);
++ if(phi_val) phi_val->value(phi);
++ }
++ redraw(); return 1;
++ }
++ return 0;
++}
++//-----------------------------------------------------------------------------
++//
++// class Fl_MGLView
++//
++//-----------------------------------------------------------------------------
++void Fl_MGLView::toggle(int &val, Fl_Button *b, const char *txt)
++{
++ val = 1-val; b->value(val);
++ if(menu && txt && *txt)
++ {
++ Fl_Menu_Item *m = (Fl_Menu_Item *)menu->find_item(_(txt));
++ if(m && val) m->set();
++ if(m && !val) m->clear();
++ }
++ update();
++}
++//-----------------------------------------------------------------------------
++void Fl_MGLView::setoff(int &val, Fl_Button *b, const char *txt)
++{
++ val = 0; b->value(val);
++ if(menu && txt && *txt)
++ {
++ Fl_Menu_Item *m = (Fl_Menu_Item *)menu->find_item(_(txt));
++ if(m && val) m->set();
++ if(m && !val) m->clear();
++ }
++ //update();
++}
++//-----------------------------------------------------------------------------
++void Fl_MGLView::exec_pause()
++{
++#if MGL_HAVE_PTHR_WIDGET
++ pthread_mutex_t *mutex=0;
++ mglCanvasWnd *g=dynamic_cast<mglCanvasWnd *>(FMGL->gr);
++ if(g && g->mutex) mutex = g->mutex;
++ else
++ {
++ mglDraw *d=FMGL->get_class();
++ if(d) mutex = &(d->mutex);
++ }
++ if(mutex)
++ {
++ pthread_mutex_trylock(mutex);
++ if(!pauseC) pthread_mutex_unlock(mutex);
++ }
++#endif
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_pause_cb(Fl_Widget*, void* v)
++{ if(v) ((Fl_MGLView*)v)->toggle_pause(); }
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_grid_cb(Fl_Widget*, void* v)
++{ if(v) ((Fl_MGLView*)v)->toggle_grid(); }
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_alpha_cb(Fl_Widget*, void* v)
++{ if(v) ((Fl_MGLView*)v)->toggle_alpha(); }
++void mglCanvasFL::ToggleAlpha() { mgl->toggle_alpha(); }
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_light_cb(Fl_Widget*, void* v)
++{ if(v) ((Fl_MGLView*)v)->toggle_light(); }
++void mglCanvasFL::ToggleLight() { mgl->toggle_light(); }
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_norm_cb(Fl_Widget*, void* v)
++{
++ Fl_MGLView *e = (Fl_MGLView*)v; if(!e) return;
++ e->setoff_rotate(); e->setoff_zoom();
++ e->FMGL->tet_val->value(0); e->FMGL->phi_val->value(0);
++ e->FMGL->set_zoom(0,0,1,1);
++ e->update();
++}
++void mglCanvasFL::ToggleNo() { mgl_norm_cb(0,mgl); }
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_zoom_cb(Fl_Widget*, void* v)
++{
++ Fl_MGLView *e = (Fl_MGLView*)v; if(!e) return;
++ e->setoff_rotate(); e->toggle_zoom();
++}
++void mglCanvasFL::ToggleZoom() { mgl_zoom_cb(0,mgl); }
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_rotate_cb(Fl_Widget*, void* v)
++{
++ Fl_MGLView *e = (Fl_MGLView*)v; if(!e) return;
++ e->setoff_zoom(); e->toggle_rotate();
++}
++void mglCanvasFL::ToggleRotate() { mgl_rotate_cb(0,mgl); }
++//-----------------------------------------------------------------------------
++void Fl_MGLView::update()
++{
++ FMGL->set_state(zoom_bt->value(), rotate_bt->value(), grid_bt->value());
++ FMGL->set_flag(alpha + 2*light);
++ FMGL->update();
++}
++void MGL_NO_EXPORT mgl_draw_cb(Fl_Widget*, void* v)
++{ if(v) ((Fl_MGLView*)v)->update(); }
++void mglCanvasFL::Update() { mgl->update(); Wnd->show(); }
++//-----------------------------------------------------------------------------
++MGL_NO_EXPORT const char *mgl_save_name(const char *ext)
++{
++ static std::string fname;
++ fname = mgl_file_chooser(_("Save File As?"), ext, true);
++ if(fname.empty()) return NULL;
++ if(fname.find(ext+1)==std::string::npos) fname += ext+1;
++ return fname.c_str();
++}
++#define _FGR_ ((Fl_MGLView*)v)->FMGL->get_graph()
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_png_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.png");
++ if(fname) mgl_write_png(_FGR_,fname,0);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_bps_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.eps");
++ if(fname) mgl_write_bps(_FGR_,fname,0);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_pngn_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.png");
++ if(fname) mgl_write_png_solid(_FGR_,fname,0);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_jpeg_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.jpg");
++ if(fname) mgl_write_jpg(_FGR_,fname,0);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_svg_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.svg");
++ if(fname) mgl_write_svg(_FGR_,fname,0);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_eps_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.eps");
++ if(fname) mgl_write_eps(_FGR_,fname,0);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_gif_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.gif");
++ if(fname) mgl_write_gif(_FGR_,fname,0);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_bmp_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.bmp");
++ if(fname) mgl_write_bmp(_FGR_,fname,0);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_prc_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.prc");
++ if(fname) mgl_write_prc(_FGR_,fname,0,1);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_tex_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.tex");
++ if(fname) mgl_write_tex(_FGR_,fname,0);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_obj_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.obj");
++ if(fname) mgl_write_obj(_FGR_,fname,0,1);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_off_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.off");
++ if(fname) mgl_write_off(_FGR_,fname,0,0);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_stl_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.stl");
++ if(fname) mgl_write_stl(_FGR_,fname,0);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_export_xyz_cb(Fl_Widget*, void* v)
++{
++ const char *fname = mgl_save_name("*.xyz");
++ if(fname) mgl_write_xyz(_FGR_,fname,0);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_su_cb(Fl_Widget*, void* v)
++{
++ Fl_MGLView *e = (Fl_MGLView*)v; if(!e) return;
++ mreal x1,x2,y1,y2,d;
++ e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
++ d = (y2-y1)/3; y1 -= d; y2 -= d;
++ e->FMGL->set_zoom(x1,y1,x2,y2);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_sd_cb(Fl_Widget*, void* v)
++{
++ Fl_MGLView *e = (Fl_MGLView*)v; if(!e) return;
++ mreal x1,x2,y1,y2,d;
++ e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
++ d = (y2-y1)/3; y1 += d; y2 += d;
++ e->FMGL->set_zoom(x1,y1,x2,y2);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_sr_cb(Fl_Widget*, void* v)
++{
++ Fl_MGLView *e = (Fl_MGLView*)v; if(!e) return;
++ mreal x1,x2,y1,y2,d;
++ e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
++ d = (x2-x1)/3; x1 -= d; x2 -= d;
++ e->FMGL->set_zoom(x1,y1,x2,y2);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_sl_cb(Fl_Widget*, void* v)
++{
++ Fl_MGLView *e = (Fl_MGLView*)v; if(!e) return;
++ mreal x1,x2,y1,y2,d;
++ e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
++ d = (x2-x1)/3; x1 += d; x2 += d;
++ e->FMGL->set_zoom(x1,y1,x2,y2);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_sz_cb(Fl_Widget*, void* v)
++{
++ Fl_MGLView *e = (Fl_MGLView*)v; if(!e) return;
++ mreal x1,x2,y1,y2,d;
++ e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
++ d = (y2-y1)/4; y1 += d; y2 -= d;
++ d = (x2-x1)/4; x1 += d; x2 -= d;
++ e->FMGL->set_zoom(x1,y1,x2,y2);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_so_cb(Fl_Widget*, void* v)
++{
++ Fl_MGLView *e = (Fl_MGLView*)v; if(!e) return;
++ mreal x1,x2,y1,y2,d;
++ e->FMGL->get_zoom(&x1,&y1,&x2,&y2);
++ d = (y2-y1)/2; y1 -= d; y2 += d;
++ d = (x2-x1)/2; x1 -= d; x2 += d;
++ e->FMGL->set_zoom(x1,y1,x2,y2);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_adjust_cb(Fl_Widget*, void*v)
++{ Fl_MGLView *e = (Fl_MGLView*)v; if(e) e->adjust(); }
++void mglCanvasFL::Adjust() { mgl_adjust_cb(0,mgl); }
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_oncemore_cb(Fl_Widget*, void*v)
++{ Fl_MGLView *e = (Fl_MGLView*)v; if(e && e->reload) e->reload(e->par); }
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_quit_cb(Fl_Widget*, void*) { Fl::first_window()->hide(); }
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_snext_cb(Fl_Widget*, void* v)
++{ Fl_MGLView *e = (Fl_MGLView*)v; if(e && e->next) e->next(e->par); }
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_sprev_cb(Fl_Widget*, void* v)
++{ Fl_MGLView *e = (Fl_MGLView*)v; if(e && e->prev) e->prev(e->par); }
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_time_cb(void *v)
++{
++ Fl_MGLView *e = (Fl_MGLView*)v;
++ if(!e || !e->is_sshow() || !e->next || !e->delay) return;
++ e->next(e->par);
++ Fl::repeat_timeout(e->delay(e->par), mgl_time_cb, v);
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_sshow_cb(Fl_Widget *, void *v)
++{
++ Fl_MGLView *e = (Fl_MGLView*)v;
++ if(!e || !e->delay || !e->next) return;
++ e->toggle_sshow();
++ if(e->is_sshow()) Fl::add_timeout(e->delay(e->par), mgl_time_cb, v);
++}
++void mglCanvasFL::Animation() { mgl_sshow_cb(0,mgl); }
++void MGL_LOCAL_CONST mgl_no_cb(Fl_Widget *, void *) {}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_stop_cb(Fl_Widget*, void* v)
++{
++ Fl_MGLView *e = (Fl_MGLView*)v;
++ if(e) e->FMGL->stop();
++}
++//-----------------------------------------------------------------------------
++void MGL_NO_EXPORT mgl_fl_next(void *v) { ((mglCanvasWnd*)v)->NextFrame(); } ///< Callback function for next frame
++void MGL_NO_EXPORT mgl_fl_prev(void *v) { ((mglCanvasWnd*)v)->PrevFrame(); } ///< Callback function for prev frame
++void MGL_NO_EXPORT mgl_fl_reload(void *v) { ((mglCanvasWnd*)v)->ReLoad(); } ///< Callback function for reloading
++mreal MGL_LOCAL_PURE mgl_fl_delay(void *v) { return ((mglCanvasWnd*)v)->GetDelay(); } ///< Callback function for delay
++//-----------------------------------------------------------------------------
++void copy_coor_cb(Fl_Widget *,void *v)
++{
++ HMGL gr = ((Fl_MGLView*)v)->get_graph();
++ mreal x,y,z; mgl_get_last_mouse_pos(gr,&x,&y,&z);
++ static char buf[256];
++ snprintf(buf,255,_("click at %g, %g, %g"),x,y,z);
++ Fl::copy(buf,strlen(buf),1);
++}
++//-----------------------------------------------------------------------------
++#if MGL_HAVE_FL_COPY
++#include <FL/Fl_Copy_Surface.H>
++void mgl_copyimg_cb(Fl_Widget *,void *v)
++{
++ Fl_MathGL *g = ((Fl_MGLView*)v)->FMGL;
++ Fl_Copy_Surface *copy_surf = new Fl_Copy_Surface(g->w(), g->h()); // create an Fl_Copy_Surface object
++ copy_surf->set_current(); // direct graphics requests to the clipboard
++ fl_color(FL_WHITE); fl_rectf(0, 0, g->w(), g->h()); // draw a white background
++ copy_surf->draw(g); // draw the g widget in the clipboard
++ delete copy_surf; // after this, the clipboard is loaded
++ Fl_Display_Device::display_device()->set_current(); // direct graphics requests back to the display
++}
++#else
++void mgl_copyimg_cb(Fl_Widget *,void *v) {}
++#endif
++//-----------------------------------------------------------------------------
++Fl_Menu_Item pop_graph[] = {
++ { _("Export as ..."), 0, mgl_no_cb, 0, FL_SUBMENU},
++#if MGL_HAVE_PNG
++ { "PNG", 0, mgl_export_png_cb},
++ { "PNG (solid)", 0, mgl_export_pngn_cb},
++#endif
++#if MGL_HAVE_JPEG
++ { "JPEG", 0, mgl_export_jpeg_cb},
++#endif
++#if MGL_HAVE_GIF
++ { "GIF", 0, mgl_export_gif_cb},
++#endif
++ { "BMP", 0, mgl_export_bmp_cb},
++ { "SVG", 0, mgl_export_svg_cb},
++ { "vector EPS", 0, mgl_export_eps_cb},
++ { "bitmap EPS", 0, mgl_export_bps_cb},
++ { "TeX", 0, mgl_export_tex_cb,0, FL_MENU_DIVIDER},
++ { "OBJ", 0, mgl_export_obj_cb},
++ { "PRC", 0, mgl_export_prc_cb},
++ { "OFF", 0, mgl_export_off_cb},
++ { "STL", 0, mgl_export_stl_cb},
++ { "XYZ", 0, mgl_export_xyz_cb},
++ {0},
++ { _("Copy graphics"), 0, mgl_copyimg_cb, 0, FL_MENU_INACTIVE|FL_MENU_DIVIDER},
++ { _("Normal view"), 0, mgl_norm_cb},
++ { _("Redraw plot"), 0, mgl_draw_cb},
++ { _("Adjust size"), 0, mgl_adjust_cb},
++ { _("Reload data"), 0, mgl_oncemore_cb},
++ {0}
++};
++//-----------------------------------------------------------------------------
++#include "image.h"
++#include "xpm/wire.xpm"
++Fl_MGLView::Fl_MGLView(int xx, int yy, int ww, int hh, const char *lbl) : Fl_Window(xx,yy,ww,hh,lbl)
++{
++ Fl_Button *o;
++ grid = alpha = light = sshow = pauseC = rotate = zoom = 0;
++ menu = NULL; next = prev = reload = NULL; delay = NULL;
++
++ Fl_Group *g = new Fl_Group(0,0,480,30);
++ alpha_bt = new Fl_Button(0, 1, 25, 25); alpha_bt->type(FL_TOGGLE_BUTTON);
++ alpha_bt->image(img_alpha); alpha_bt->callback(mgl_alpha_cb,this);
++ alpha_bt->tooltip(_("Switch on/off transparency in the picture"));
++ light_bt = new Fl_Button(25, 1, 25, 25); light_bt->type(FL_TOGGLE_BUTTON);
++ light_bt->image(img_light); light_bt->callback(mgl_light_cb,this);
++ light_bt->tooltip(_("Switch on/off lightning in the picture"));
++ grid_bt = new Fl_Button(50, 1, 25, 25); grid_bt->type(FL_TOGGLE_BUTTON);
++ grid_bt->image(new Fl_Pixmap(wire_xpm)); grid_bt->callback(mgl_grid_cb,this);
++ grid_bt->tooltip(_("Switch on/off grid drawing"));
++
++ rotate_bt = new Fl_Button(80, 1, 25, 25);rotate_bt->type(FL_TOGGLE_BUTTON);
++ rotate_bt->image(img_move); rotate_bt->callback(mgl_rotate_cb,this);
++ rotate_bt->tooltip(_("Rotate picture by holding left mouse button"));
++ zoom_bt = new Fl_Button(105, 1, 25, 25); zoom_bt->type(FL_TOGGLE_BUTTON);
++ zoom_bt->image(img_zoomIn); zoom_bt->callback(mgl_zoom_cb,this);
++ zoom_bt->tooltip(_("Zoom in selected region of the picture"));
++ o = new Fl_Button(130, 1, 25, 25); o->tooltip(_("Restore default graphics rotation, zoom and perspective"));
++ o->image(img_orig); o->callback(mgl_norm_cb,this);
++
++ o = new Fl_Button(160, 1, 25, 25); o->tooltip(_("Refresh the picture"));
++ o->image(img_update); o->callback(mgl_draw_cb,this);
++ o = new Fl_Button(185, 1, 25, 25); o->tooltip(_("Stop drawing"));
++ o->image(img_stop); o->callback(mgl_stop_cb,this);
++ o = new Fl_Button(210, 1, 25, 25); o->tooltip(_("Adjust picture size to fill drawing area"));
++ o->image(img_adjust); o->callback(mgl_adjust_cb,this);
++ o = new Fl_Button(235, 1, 25, 25); o->tooltip(_("Reload data and refresh the picture"));
++ o->image(img_reload); o->callback(mgl_oncemore_cb,this);
++ o = new Fl_Button(265, 1, 25, 25); o->tooltip(_("Copy image to clipboard"));
++ o->image(img_copy); o->callback(mgl_copyimg_cb,this);
++
++ Fl_Counter *tet, *phi;
++ tet = new Fl_Counter(295, 1, 90, 25, 0); tet->callback(mgl_draw_cb,this);
++ phi = new Fl_Counter(390, 1, 90, 25, 0); phi->callback(mgl_draw_cb,this);
++ tet->lstep(10); tet->step(1); tet->range(-180,180);
++ tet->tooltip(_("Theta angle (tilt z-axis)"));
++ phi->lstep(10); phi->step(1); phi->range(-180,180);
++ phi->tooltip(_("Phi angle (rotate in x*y plane)"));
++ g->end(); g->resizable(0);
++
++ g = new Fl_Group(0,0,30,285);
++ o = new Fl_Button(1, 30, 25, 25); o->tooltip(_("Shift the picture up"));
++ o->image(img_goU); o->callback(mgl_su_cb,this);
++ o = new Fl_Button(1, 55, 25, 25); o->tooltip(_("Shift the picture left"));
++ o->image(img_goL); o->callback(mgl_sl_cb,this);
++ o = new Fl_Button(1, 80, 25, 25); o->tooltip(_("Zoom in the picture"));
++ o->image(img_plus); o->callback(mgl_sz_cb,this);
++ o = new Fl_Button(1, 105, 25, 25); o->tooltip(_("Zoom out the picture"));
++ o->image(img_minus); o->callback(mgl_so_cb,this);
++ o = new Fl_Button(1, 130, 25, 25); o->tooltip(_("Shift the picture right"));
++ o->image(img_goR); o->callback(mgl_sr_cb,this);
++ o = new Fl_Button(1, 155, 25, 25); o->tooltip(_("Shift the picture down"));
++ o->image(img_goD); o->callback(mgl_sd_cb,this);
++
++ o = new Fl_Button(1, 185, 25, 25); o->tooltip(_("Show previous frame in slideshow"));
++ o->image(img_prev); o->callback(mgl_sprev_cb,this);
++ anim_bt = new Fl_Button(1, 210, 25, 25); anim_bt->type(FL_TOGGLE_BUTTON);
++ anim_bt->image(img_play); anim_bt->callback(mgl_sshow_cb,this);
++ anim_bt->tooltip(_("Run/Stop slideshow (graphics animation)"));
++ o = new Fl_Button(1, 235, 25, 25); o->tooltip(_("Show next frame in slideshow"));
++ o->image(img_next); o->callback(mgl_snext_cb,this);
++#if MGL_HAVE_PTHR_WIDGET
++ pause_bt = new Fl_Button(1, 260, 25, 25); pause_bt->type(FL_TOGGLE_BUTTON);
++ pause_bt->image(img_pause); pause_bt->callback(mgl_pause_cb,this);
++ pause_bt->tooltip(_("Pause on/off external calculations"));
++#endif
++ g->end(); g->resizable(0);
++
++ scroll = new Fl_Scroll(30, 30, ww-30, hh-30);
++ FMGL = new Fl_MathGL(30, 30, 800, 600);
++ FMGL->tet_val = tet;
++ FMGL->phi_val = phi;
++ FMGL->set_popup(pop_graph,FMGL,this);
++ scroll->end(); resizable(scroll); end(); par=0;
++}
++Fl_MGLView::~Fl_MGLView() {}
++//-----------------------------------------------------------------------------
++//
++// class mglCanvasFL
++//
++//-----------------------------------------------------------------------------
++mglCanvasFL::mglCanvasFL() : mglCanvasWnd() { Wnd=0; mgl=0; }
++mglCanvasFL::~mglCanvasFL() { if(Wnd) { mgl->FMGL->gr=0; delete Wnd; } }
++//-----------------------------------------------------------------------------
++void mglCanvasFL::GotoFrame(int d)
++{
++ int f = GetCurFig()+d;
++ if(f>=GetNumFig()) f = 0;
++ if(f<0) f = GetNumFig()-1;
++ if(GetNumFig()>0 && d) { SetCurFig(f); mgl->FMGL->redraw(); }
++}
++//-----------------------------------------------------------------------------
++void MGL_EXPORT mgl_makemenu_fltk(Fl_Menu_ *m, Fl_MGLView *w)
++{
++ m->add(_("Graphics/Alpha"), "^t", mgl_alpha_cb, w, FL_MENU_TOGGLE);
++ m->add(_("Graphics/Light"), "^l", mgl_light_cb, w, FL_MENU_TOGGLE);
++ m->add(_("Graphics/Grid"), "^g", mgl_grid_cb, w, FL_MENU_TOGGLE|FL_MENU_DIVIDER);
++
++ m->add(_("Graphics/Restore"), "^ ", mgl_norm_cb, w);
++ m->add(_("Graphics/Redraw"), FL_F+5, mgl_draw_cb, w);
++ m->add(_("Graphics/Adjust size"), FL_F+6, mgl_adjust_cb, w);
++ m->add(_("Graphics/Reload data"), FL_F+9, mgl_oncemore_cb, w);
++ m->add(_("Graphics/Stop"), FL_F+7, mgl_stop_cb, w);
++ m->add(_("Graphics/Copy graphics"), "+^c", mgl_copyimg_cb, w);
++ m->add(_("Graphics/Copy click coor."), 0, copy_coor_cb, w);
++ m->add(_("Graphics/Pause calc"), "^t", mgl_pause_cb, w, FL_MENU_TOGGLE);
++
++#if MGL_HAVE_PNG
++ m->add(_("Graphics/Export/as PNG"), "#p", mgl_export_png_cb, w);
++ m->add(_("Graphics/Export/as solid PNG"), "#f", mgl_export_pngn_cb, w);
++#endif
++#if MGL_HAVE_JPEG
++ m->add(_("Graphics/Export/as JPEG"), "#j", mgl_export_jpeg_cb, w);
++#endif
++#if MGL_HAVE_GIF
++ m->add(_("Graphics/Export/as GIF"), "#g", mgl_export_gif_cb, w);
++#endif
++ m->add(_("Graphics/Export/as BMP"), 0, mgl_export_bmp_cb, w);
++ m->add(_("Graphics/Export/as SVG"), "#s", mgl_export_svg_cb, w);
++ m->add(_("Graphics/Export/as vector EPS"), "#e", mgl_export_eps_cb, w);
++ m->add(_("Graphics/Export/as bitmap EPS"), 0, mgl_export_bps_cb, w);
++ m->add(_("Graphics/Export/as TeX"), "#l", mgl_export_tex_cb, w, FL_MENU_DIVIDER);
++ m->add(_("Graphics/Export/as PRC"), "#d", mgl_export_prc_cb, w);
++ m->add(_("Graphics/Export/as OBJ"), "#o", mgl_export_obj_cb, w);
++ m->add(_("Graphics/Export/as OFF"), 0, mgl_export_off_cb, w);
++ m->add(_("Graphics/Export/as STL"), 0, mgl_export_stl_cb, w);
++ m->add(_("Graphics/Export/as XYZ"), 0, mgl_export_xyz_cb, w);
++
++ m->add(_("Graphics/Animation/Slideshow"), FL_CTRL+FL_F+5, mgl_sshow_cb, w, FL_MENU_TOGGLE);
++ m->add(_("Graphics/Animation/Next frame"), "#<", mgl_snext_cb, w);
++ m->add(_("Graphics/Animation/Prev frame"), "#>", mgl_sprev_cb, w);
++
++ m->add(_("Graphics/Transform/Move left"), FL_ALT+FL_Left, mgl_sl_cb, w);
++ m->add(_("Graphics/Transform/Move up"), FL_ALT+FL_Up, mgl_su_cb, w);
++ m->add(_("Graphics/Transform/Zoom in"), "#=", mgl_sz_cb, w);
++ m->add(_("Graphics/Transform/Zoom out"), "#-", mgl_so_cb, w);
++ m->add(_("Graphics/Transform/Move down"), FL_ALT+FL_Down, mgl_sd_cb, w);
++ m->add(_("Graphics/Transform/Move right"), FL_ALT+FL_Right, mgl_sr_cb, w);
++}
++//-----------------------------------------------------------------------------
++void mglCanvasFL::Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p), const char *title, void *par, void (*reload)(void *p), bool maximize)
++{
++ static bool first=true;
++ if(first) { Fl::lock(); first=false; }
++
++ SetDrawFunc(draw, par, reload);
++ if(Wnd) { Wnd->label(title); Wnd->show(); return; }
++
++ Wnd = new Fl_Double_Window(830,660,title);
++ mgl = new Fl_MGLView(0,30,830,630); mgl->par = this;
++ mgl->menu = new Fl_Menu_Bar(0, 0, 830, 30);
++ mgl_makemenu_fltk(mgl->menu, mgl);
++
++ mgl->next = mgl_fl_next; mgl->reload = mgl_fl_reload;
++ mgl->prev = mgl_fl_prev; mgl->delay= mgl_fl_delay;
++ mgl->FMGL->set_graph(this);
++ mgl->FMGL->set_draw(draw, par);
++
++ Wnd->end();
++ Wnd->resizable(mgl);
++
++ if(maximize)
++ {
++ int x,y,w,h;
++ Fl::screen_xywh(x,y,w,h);
++ Wnd->resize(x,y,w,h);
++ Adjust();
++ }
++
++ static char ctmp[1]; ctmp[0]=0;
++ static char *tmp[1]; tmp[0]=ctmp;
++ Wnd->show(argv ? argc:0, argv ? argv:tmp);
++}
++//-----------------------------------------------------------------------------
++HMGL MGL_EXPORT mgl_create_graph_fltk(int (*draw)(HMGL gr, void *p), const char *title, void *par, void (*load)(void *p))
++{
++ mglCanvasFL *g = new mglCanvasFL;
++ g->Window(0,0,draw,title,par,load);
++ g->mgl->FMGL->set_handle_key(true);
++ return g;
++}
++void* mgl_fltk_widget(HMGL gr)
++{
++ mglCanvasFL *g = dynamic_cast<mglCanvasFL *>(gr);
++ return g?g->mgl:NULL;
++}
++int MGL_EXPORT mgl_fltk_run() { return Fl::run(); }
++//-----------------------------------------------------------------------------
++uintptr_t MGL_EXPORT mgl_create_graph_fltk_(const char *title, int l)
++{
++ char *s = new char[l+1]; memcpy(s,title,l); s[l]=0;
++ uintptr_t t = uintptr_t(mgl_create_graph_fltk(0,s,0,0));
++ delete []s; return t;
++}
++int MGL_EXPORT mgl_fltk_run_() { return mgl_fltk_run(); }
++//-----------------------------------------------------------------------------
++MGL_NO_EXPORT void *mgl_fltk_tmp(void *)
++{ mgl_fltk_run(); return 0; }
++//-----------------------------------------------------------------------------
++int MGL_EXPORT mgl_fltk_thr() // NOTE: Qt couldn't be running in non-primary thread
++{
++#if MGL_HAVE_PTHR_WIDGET
++ static pthread_t thr;
++ pthread_create(&thr,0,mgl_fltk_tmp,0);
++ pthread_detach(thr);
++#endif
++ return 0; // stupid, but I don't want keep result returned by Fl::Run()
++}
++//-----------------------------------------------------------------------------
--- /dev/null
--- /dev/null
++/***************************************************************************
++ * qt.cpp is part of Math Graphic Library *
++ * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru> *
++ * *
++ * This program is free software; you can redistribute it and/or modify *
++ * it under the terms of the GNU Library General Public License as *
++ * published by the Free Software Foundation; either version 3 of the *
++ * License, or (at your option) any later version. *
++ * *
++ * This program is distributed in the hope that it will be useful, *
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
++ * GNU General Public License for more details. *
++ * *
++ * You should have received a copy of the GNU Library General Public *
++ * License along with this program; if not, write to the *
++ * Free Software Foundation, Inc., *
++ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
++ ***************************************************************************/
++#include <QTimer>
++#include <QApplication>
++#include <QMouseEvent>
++#include <QMessageBox>
++#include <QMenu>
++#include <QClipboard>
++#include <QTextEdit>
++#include <QPainter>
++#include <QCursor>
++#include <QImage>
++#include <QScrollArea>
++#include <QMainWindow>
++#include <QToolBar>
++#include <QMenuBar>
++#include <QSpinBox>
++#include <QPrinter>
++#include <QPrintDialog>
++#include <QFileDialog>
++#include <QInputDialog>
++#include <QThread>
++#include <limits.h>
++
++#include "mgl2/canvas_wnd.h"
++#include "mgl2/qmathgl.h"
++#include "mgl2/qt.h"
++#undef sprintf // fix libintl bug of defining sprintf
++//-----------------------------------------------------------------------------
++#define MGL_MAX_LINES (INT_MAX-1000)
++//-----------------------------------------------------------------------------
++/// Base class for windows containing MathGL graphics
++class mglCanvasQT : public mglCanvasWnd
++{
++public:
++using mglCanvasWnd::Window;
++ int sshow; ///< Current state of animation switch (toggle button)
++ QMathGL *QMGL; ///< Control which draw graphics
++ QMainWindow *Wnd; ///< Pointer to window
++
++ mglCanvasQT();
++ virtual ~mglCanvasQT();
++
++ /// Create a window for plotting. Now implemeted only for GLUT.
++ void Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p),const char *title,
++ void *par=NULL, void (*reload)(void *p)=NULL, bool maximize=false);
++ /// Switch on/off transparency (do not overwrite switches in user drawing function)
++ void ToggleAlpha();
++ /// Switch on/off lighting (do not overwrite switches in user drawing function)
++ void ToggleLight();
++ void ToggleRotate();///< Switch on/off rotation by mouse
++ void ToggleZoom(); ///< Switch on/off zooming by mouse
++ void ToggleNo(); ///< Switch off all zooming and rotation
++ void Update(); ///< Update picture by calling user drawing function
++ void Adjust(); ///< Adjust size of bitmap to window size
++ void GotoFrame(int d); ///< Show arbitrary frame (use relative step)
++ void Animation(); ///< Run slideshow (animation) of frames
++
++protected:
++ QScrollArea *scroll; ///< Scrolling area
++ QMenu *popup; ///< Popup menu
++ QSpinBox *tet, *phi; ///< Spin box for angles
++};
++//-----------------------------------------------------------------------------
++void MGL_EXPORT mgl_ask_qt(const wchar_t *quest, wchar_t *res)
++{ QInputDialog::getText(QApplication::activeWindow(), "MathGL",
++ QString::fromWCharArray(quest)).toWCharArray(res); }
++//-----------------------------------------------------------------------------
++/*void mglTask::doWork()
++{
++ setlocale(LC_NUMERIC, "C");
++ if(mgl_is_frames(gr)) mgl_new_frame(gr);
++ if(draw_func) draw_func(gr, draw_par);
++ else if(draw) { mglGraph g(gr); draw->Draw(&g); }
++ if(mgl_is_frames(gr)) mgl_end_frame(gr);
++ setlocale(LC_NUMERIC, "");
++ gr->Finish();
++ emit plotDone();
++}*/
++//-----------------------------------------------------------------------------
++QMathGL::QMathGL(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f)
++{
++ autoResize = false; draw_par = 0; draw_func = 0;
++ dotsRefr = true;
++ gr = new mglCanvas; appName = "MathGL";
++ popup = 0; grBuf = 0; draw = 0; prevQuality=MGL_DRAW_NORM;
++ phi = tet = per = 0; x0=y0=xe=ye=0;
++ x1 = y1 = ax1 = ay1 = 0; x2 = y2 = ax2 = ay2 = 1;
++ alpha = light = zoom = rotate = grid = viewYZ = custZoom = custDraw = pause = false;
++ resize(600, 400); mgl_set_flag(gr, true, MGL_CLF_ON_UPD);
++ timer = new QTimer(this);
++ timerRefr = new QTimer(this); timerRefr->setInterval(100);
++ timerRefr->setSingleShot(true);
++ enableWheel = enableMouse = true;
++ connect(timer, SIGNAL(timeout()), this, SLOT(nextSlide()));
++ connect(timerRefr, SIGNAL(timeout()), this, SLOT(refreshHQ()));
++ sclS = 0.25; sclZ = 0.5;
++
++/* thread = new QThread();
++ task = new mglTask(); task->moveToThread(thread);
++ connect(thread, SIGNAL(started()), task, SLOT(doWork()));
++ connect(task, SIGNAL(plotDone()), thread, SLOT(quit()));
++ connect(thread, SIGNAL(finished()), this, SLOT(afterPlot()));*/
++}
++//-----------------------------------------------------------------------------
++QMathGL::~QMathGL()
++{
++ timer->stop(); timerRefr->stop();
++ if(gr && mgl_use_graph(gr,-1)<1) mgl_delete_graph(gr);
++ if(grBuf) delete []grBuf;
++ if(draw) delete draw;
++}
++//-----------------------------------------------------------------------------
++void QMathGL::setDotsPreview(bool d)
++{ dotsRefr = d; }
++//-----------------------------------------------------------------------------
++void QMathGL::setDraw(int (*func)(mglBase *gr, void *par), void *par)
++{
++ if(draw) delete draw;
++ draw = 0; draw_func = func; draw_par = par;
++ emit usePrimChanged(draw_func || draw);
++}
++//-----------------------------------------------------------------------------
++void QMathGL::setDraw(mglDraw *dr)
++{
++ if(draw) delete draw;
++ draw = dr; draw_func = 0;
++ emit usePrimChanged(draw_func || draw);
++}
++//-----------------------------------------------------------------------------
++double QMathGL::getRatio() { return double(mgl_get_width(gr))/mgl_get_height(gr); }
++void mgl_qt_event_func(void *) { QApplication::processEvents(); }
++//-----------------------------------------------------------------------------
++void QMathGL::setGraph(HMGL GR) ///< Set grapher object
++{
++ mglCanvas *gg = dynamic_cast<mglCanvas *>(GR);
++ if(!gg) return;
++ if(mgl_use_graph(gr,-1)<1) mgl_delete_graph(gr);
++ gr=gg; mgl_use_graph(gg,1);
++ gr->SetEventFunc(mgl_qt_event_func, NULL);
++}
++//-----------------------------------------------------------------------------
++void QMathGL::paintEvent(QPaintEvent *)
++{
++ QPainter paint;
++ paint.begin(this);
++ paint.drawPixmap(0,0,pic);
++ if(zoom) paint.drawRect(x0,y0,xe-x0,ye-y0);
++ if(mgl_get_flag(gr,MGL_SHOW_POS) && !mousePos.isEmpty())
++ paint.drawText(0,12,mousePos);
++ if(grid)
++ {
++ long d, h=pic.height(), w=pic.width();
++ paint.setPen(QColor(192,192,192));
++ for(long i=1;i<10;i++)
++ {
++ paint.drawText(0,i*h/10,QString::number(1-i*0.1));
++ paint.drawLine(0,i*h/10,w,i*h/10);
++ paint.drawText(i*w/10,h,QString::number(i*0.1));
++ paint.drawLine(i*w/10,0,i*w/10,h);
++ }
++ paint.setPen(QColor(0,0,0));
++ d = (h>w?w:h)/100;
++ if(mgl_is_frames(gr))
++ for(size_t i=0;i<gr->Act.size();i++)
++ {
++ const mglActivePos &p=gr->Act[i];
++ QRect rf(p.x-d/2,p.y-d/2-1,d,d);
++ paint.drawRect(rf);
++ paint.fillRect(rf,QBrush(QColor(127,255,63)));
++ }
++ }
++ paint.end();
++}
++//-----------------------------------------------------------------------------
++void QMathGL::resizeEvent(QResizeEvent *ev)
++{
++ if(autoResize && ev->size().width()>0 && ev->size().height()>0)
++ { mgl_set_size(gr, ev->size().width(), ev->size().height()); update(); }
++// else resize(graph->GetWidth(), graph->GetHeight());
++}
++//-----------------------------------------------------------------------------
++void QMathGL::setPer(int p)
++{
++ if(per!=p && p>=0 && p<100)
++ { per = 100*p; emit perChanged(p); refresh(); }
++}
++//-----------------------------------------------------------------------------
++void QMathGL::setPhi(int p)
++{ if(phi!=p) { phi = p; emit phiChanged(p); refresh(); } }
++//-----------------------------------------------------------------------------
++void QMathGL::setTet(int t)
++{ if(tet!=t) { tet = t; emit tetChanged(t); refresh(); } }
++//-----------------------------------------------------------------------------
++void QMathGL::setAlpha(bool a)
++{ if(alpha!=a) { alpha = a; emit alphaChanged(a); update(); } }
++//-----------------------------------------------------------------------------
++void QMathGL::setLight(bool l)
++{ if(light!=l) { light = l; emit lightChanged(l); update(); } }
++//-----------------------------------------------------------------------------
++void QMathGL::setGrid(bool g)
++{ if(grid!=g) { grid = g; emit gridChanged(g); refresh(); } }
++//-----------------------------------------------------------------------------
++void QMathGL::setViewYZ(bool a)
++{ if(viewYZ!=a) { viewYZ = a; emit viewYZChanged(a); refresh(); } }
++//-----------------------------------------------------------------------------
++void QMathGL::setPause(bool p)
++{
++#if MGL_HAVE_PTHR_WIDGET
++ if(pause!=p)
++ {
++ pthread_mutex_t *mutex=0;
++ mglCanvasWnd *g=dynamic_cast<mglCanvasWnd *>(gr);
++ if(g && g->mutex) mutex = g->mutex;
++ else
++ {
++ mglDraw *d=getClass();
++ if(d) mutex = &(d->mutex);
++ }
++ if(mutex)
++ {
++ if(p) pthread_mutex_lock(mutex);
++ else pthread_mutex_unlock(mutex);
++ }
++ pause=p;
++ emit pauseChanged(p);
++ }
++#endif
++}
++//-----------------------------------------------------------------------------
++void QMathGL::setRotate(bool r)
++{
++ if(rotate!=r)
++ { zoom=false; rotate=r; refresh(); emit rotateChanged(r); }
++}
++//-----------------------------------------------------------------------------
++void QMathGL::setZoom(bool z)
++{
++ if(zoom!=z)
++ { zoom=z; rotate=false; refresh();
++ emit zoomChanged(z); emit rotateChanged(false); }
++}
++//-----------------------------------------------------------------------------
++void QMathGL::setCustZoom(bool z) { custZoom = z; }
++//-----------------------------------------------------------------------------
++void QMathGL::setCustDraw(bool z) { custDraw = z; }
++//-----------------------------------------------------------------------------
++void QMathGL::setZoomScl(double s) { if(s>0) sclZ = s; }
++//-----------------------------------------------------------------------------
++void QMathGL::setShiftScl(double s) { if(s) sclS = s; }
++//-----------------------------------------------------------------------------
++void QMathGL::shiftDown()
++{ mreal d=(y2-y1)*sclS; y1+=d; y2+=d; refresh(); }
++//-----------------------------------------------------------------------------
++void QMathGL::shiftUp()
++{ mreal d=(y2-y1)*sclS; y1-=d; y2-=d; refresh(); }
++//-----------------------------------------------------------------------------
++void QMathGL::shiftRight()
++{ mreal d=(x2-x1)*sclS; x1-=d; x2-=d; refresh(); }
++//-----------------------------------------------------------------------------
++void QMathGL::shiftLeft()
++{ mreal d=(x2-x1)*sclS; x1+=d; x2+=d; refresh(); }
++//-----------------------------------------------------------------------------
++void QMathGL::zoomIn()
++{
++ mreal d,c;
++ d = (y2-y1)*sclZ/2; c = (y2+y1)/2; y1 = c-d; y2 = c+d;
++ d = (x2-x1)*sclZ/2; c = (x2+x1)/2; x1 = c-d; x2 = c+d;
++ refresh();
++}
++//-----------------------------------------------------------------------------
++void QMathGL::zoomOut()
++{
++ mreal d,c;
++ d = (y2-y1)/sclZ/2; c = (y2+y1)/2; y1 = c-d; y2 = c+d;
++ d = (x2-x1)/sclZ/2; c = (x2+x1)/2; x1 = c-d; x2 = c+d;
++ refresh();
++}
++//-----------------------------------------------------------------------------
++void QMathGL::restore()
++{
++ setPhi(0); setTet(0); setPer(0);
++ x1=y1=0; x2=y2=1; zoom=rotate=false;
++ emit zoomChanged(false); emit rotateChanged(false);
++ if(ax1!=0 || ay1!=0 || ax2!=1 || ay2!=1)
++ {
++ ax1=ay1=0; ax2=ay2=1;
++ mgl_zoom_axis(gr,0,0,0,0,1,1,1,1);
++ update();
++ }
++ else refresh();
++}
++//-----------------------------------------------------------------------------
++void QMathGL::stop() { gr->AskStop(true); }
++//-----------------------------------------------------------------------------
++void QMathGL::update()
++{
++ if(draw_func || draw)
++ {
++ mgl_reset_frames(gr); // remove previous frames
++ if(mgl_get_flag(gr,MGL_CLF_ON_UPD)) mgl_set_def_param(gr);
++ mgl_set_alpha(gr,alpha); mgl_set_light(gr,light);
++ // use frames for quickly redrawing while adding/changing primitives
++ if(custDraw) emit customDraw(x1,y1,x2,y2,true);
++
++ if(!isHidden()) QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
++/* task->gr = gr; task->draw = draw;
++ task->draw_func = draw_func;
++ task->draw_par = draw_par;
++ thread->start();*/
++ const std::string loc = setlocale(LC_NUMERIC, "C");
++ if(mgl_is_frames(gr)) mgl_new_frame(gr);
++ if(draw_func) draw_func(gr, draw_par);
++ else if(draw) { mglGraph g(gr); draw->Draw(&g); }
++ if(mgl_is_frames(gr)) mgl_end_frame(gr);
++<<<<<<< HEAD
++ setlocale(LC_NUMERIC, "");
++ gr->AskStop(false);
++ }
++ else if(mgl_get_num_frame(gr)>0)
++ {
++ mgl_set_alpha(gr,alpha); mgl_set_light(gr,light);
++// mgl_zoom(gr,x1,y1,x2,y2); mgl_view(gr,-phi,-tet,0);
++ mgl_get_frame(gr,0);
++ }
++=======
++ setlocale(LC_NUMERIC, loc.c_str());
++ gr->AskStop(false);
++ }
++ else if(mgl_get_num_frame(gr)>0)
++ {
++ mgl_set_alpha(gr,alpha); mgl_set_light(gr,light);
++// mgl_zoom(gr,x1,y1,x2,y2); mgl_view(gr,-phi,-tet,0);
++ mgl_get_frame(gr,0);
++ }
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++ afterPlot();
++}
++//-----------------------------------------------------------------------------
++void QMathGL::afterPlot()
++{
++ emit refreshData();
++ emit showWarn(mgl_get_mess(gr));
++ mousePos="";
++ if(!isHidden()) QApplication::restoreOverrideCursor();
++ refresh();
++}
++//-----------------------------------------------------------------------------
++void QMathGL::drawPrim()
++{
++ if(!gr) return;
++ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);
++ mgl_get_frame(gr, g?g->GetCurFig():mgl_get_num_frame(gr)-1);
++ mglParse pr;
++ long i, n=primitives.count('\n');
++ mglGraph gg(gr);
++ const std::string loc = setlocale(LC_NUMERIC, "C");
++ gg.Push(); gg.SubPlot(1,1,0,"#");
++ mglPoint ox1=gr->Min, ox2=gr->Max;
++ gg.SetRanges(mglPoint(-1,-1,-1),mglPoint(1,1,1));
++ for(i=0;i<n;i++)
++ {
++ mgl_set_obj_id(gr,i+MGL_MAX_LINES);
++ QString tst = primitives.section('\n',i,i);
++ pr.Parse(&gg,primitives.section('\n',i,i).toLocal8Bit().constData(),i+MGL_MAX_LINES);
++ }
++ gg.SetRanges(ox1,ox2); gg.Pop(); setlocale(LC_NUMERIC, loc.c_str());
++}
++//-----------------------------------------------------------------------------
++void QMathGL::refresh()
++{
++ if(dotsRefr)
++ {
++ timerRefr->start();
++ int q = gr->GetQuality();
++ prevQuality = q!=MGL_DRAW_DOTS?q:prevQuality;
++ gr->SetQuality(MGL_DRAW_DOTS);
++ }
++ if(mgl_is_frames(gr) && mgl_get_num_frame(gr)>0)
++ {
++ drawPrim();
++ if(custZoom) emit customZoom(x1,y1,x2,y2,tet,phi,per);
++ else
++ { mgl_zoom(gr,x1,y1,x2,y2);
++ mgl_ask_perspective(gr,per);
++ if(viewYZ) mgl_view(gr,0,-tet,-phi);
++ else mgl_view(gr,-phi,-tet,0);
++ }
++ }
++ mglConvertFromGraph(pic, gr, &grBuf);
++ if(pic.size()!=size()) setSize(pic.width(), pic.height());
++ repaint();
++}
++//-----------------------------------------------------------------------------
++void QMathGL::refreshHQ()
++{
++ gr->SetQuality(prevQuality);
++ if(mgl_is_frames(gr) && mgl_get_num_frame(gr)>0)
++ {
++ drawPrim();
++ if(custZoom) emit customZoom(x1,y1,x2,y2,tet,phi,per);
++ else
++ { mgl_zoom(gr,x1,y1,x2,y2);
++ mgl_ask_perspective(gr,per);
++ if(viewYZ) mgl_view(gr,0,-tet,-phi);
++ else mgl_view(gr,-phi,-tet,0);
++ }
++ }
++ mglConvertFromGraph(pic, gr, &grBuf, &img);
++ if(pic.size()!=size()) setSize(pic.width(), pic.height());
++ repaint();
++}
++//-----------------------------------------------------------------------------
++void QMathGL::mousePressEvent(QMouseEvent *ev)
++{
++ if(!zoom && !rotate && ev->button()&Qt::LeftButton)
++ {
++ mglPoint p = gr->CalcXYZ(ev->x(), ev->y());
++ mglCanvasWnd *g=dynamic_cast<mglCanvasWnd *>(gr);
++ if(g) g->LastMousePos = p;
++ if(g && g->ClickFunc) g->ClickFunc(draw_par);
++ emit mouseClick(p.x,p.y,p.z);
++ int id = mgl_get_obj_id(gr,ev->x(),ev->y());
++ if(id<MGL_MAX_LINES) emit objChanged(id-1);
++
++ p = gr->CalcXYZ(ev->x(), ev->y(), true);
++ if(mgl_isnan(p.x)) mousePos = "";
++ else mousePos.sprintf("x=%g, y=%g, z=%g",p.x,p.y,p.z);
++ emit posChanged(mousePos);
++ repaint();
++ }
++ xe=x0=ev->x(); ye=y0=ev->y(); ev->accept();
++}
++//-----------------------------------------------------------------------------
++void QMathGL::mouseReleaseEvent(QMouseEvent *ev)
++{
++ if(ev->button()&Qt::LeftButton && enableMouse)
++ {
++ if(zoom)
++ {
++ int w1=width(),h1=height();
++ mreal _x1,_x2,_y1,_y2;
++ _x1 = x1+(x2-x1)*(x0-x())/mreal(w1); _y1 = y2-(y2-y1)*(ye-y())/mreal(h1);
++ _x2 = x1+(x2-x1)*(xe-x())/mreal(w1); _y2 = y2-(y2-y1)*(y0-y())/mreal(h1);
++ x1=_x1; x2=_x2; y1=_y1; y2=_y2;
++ if(x1>x2) { _x1=x1; x1=x2; x2=_x1; }
++ if(y1>y2) { _x1=y1; y1=y2; y2=_x1; }
++ x0 = xe; y0 = ye;
++ if(custDraw)
++ {
++ emit customDraw(x1,y1,x2,y2,false);
++ update();
++ }
++ else refresh();
++ }
++ }
++ if(ev->button()&Qt::RightButton && popup && !rotate) // popup menu
++ popup->popup(QCursor::pos());
++ ev->accept();
++}
++//-----------------------------------------------------------------------------
++void QMathGL::mouseMoveEvent(QMouseEvent *ev)
++{
++ if(!enableMouse) { ev->ignore(); return; }
++ xe=ev->x(); ye=ev->y();
++ if(rotate)
++ {
++ if(ev->buttons()&Qt::LeftButton) // rotate
++ {
++ mreal ff = 240/sqrt(mreal(width()*height()));
++ phi += int((x0-xe)*ff);
++ tet -= int((y0-ye)*ff);
++ if(phi>180) phi-=360;
++ if(phi<-180) phi+=360;
++ if(tet>180) tet-=360;
++ if(tet<-180) tet+=360;
++ emit tetChanged(int(tet)); emit phiChanged(int(phi));
++ refresh();
++ }
++ if(ev->buttons()&Qt::RightButton) // zoom and perspective
++ {
++ mreal ff = 2.*(y0-ye)/width(), gg = 0.5*(xe-x0)/height();
++ mreal cx = (x1+x2)/2, cy = (y1+y2)/2;
++ x1 = cx+(x1-cx)*exp(-ff); x2 = cx+(x2-cx)*exp(-ff);
++ y1 = cy+(y1-cy)*exp(-ff); y2 = cy+(y2-cy)*exp(-ff);
++ per = per + gg;
++ if(per<0) per = 0;
++ if(per>=1) per = 0.9999;
++ if(gg) emit perChanged(int(per));
++ refresh();
++ }
++ if(ev->buttons()&Qt::MidButton) // shift
++ {
++ mreal ff = 1./sqrt(mreal(width()*height()));
++ mreal dx = (x0-xe)*ff*(x2-x1), dy = (y0-ye)*ff*(y2-y1);
++ x1 += dx; x2 += dx; y1 -= dy; y2 -= dy;
++ }
++ x0 = xe; y0 = ye;
++ refresh();
++ }
++ else if(zoom) refresh();
++ else if(ev->buttons()&Qt::MidButton) // shift axis
++ {
++ mreal ff = 1./sqrt(mreal(width()*height()));
++ mreal dx = (x0-xe)*ff*(ax2-ax1), dy = (y0-ye)*ff*(ay2-ay1);
++ ax1 += dx; ax2 += dx; ay1 -= dy; ay2 -= dy;
++ mgl_zoom_axis(gr,ax1,ay1,0,0,ax2,ay2,0,0);
++ update(); x0 = xe; y0 = ye;
++ }
++ else if(ev->buttons()&Qt::LeftButton) // move primitives
++ {
++ long h=pic.height(), w=pic.width(), d=(h>w?w:h)/100;
++ long pos = mgl_is_active(gr,x0,y0,d);
++ long id = long(mgl_get_obj_id(gr,x0,y0))-MGL_MAX_LINES;
++ if(grid && pos>=0) // this active point
++ {
++ const mglActivePos &p = gr->Act[pos];
++ id = long(p.id)-MGL_MAX_LINES;
++ if(id>=0) // this is our primitive
++ {
++ // try "attract" mouse
++ for(size_t i=0;i<=10;i++)
++ {
++ int tt = i*(w/10); if(abs(xe-tt)<2*d) xe = tt;
++ tt = i*(h/10); if(abs(ye-tt)<2*d) ye = tt;
++ }
++ for(size_t i=0;i<gr->Act.size();i++)
++ {
++ const mglActivePos &q = gr->Act[i];
++ if(abs(xe-q.x)<2*d && abs(ye-q.y)<2*d) { xe=q.x; ye=q.y; }
++ }
++ // now move point
++ QString tst = primitives.section('\n',id,id), cmd=tst.section(' ',0,0), res;
++ float dx = 2*(xe-x0)/float(w), dy = 2*(y0-ye)/float(h);
++ float xx=tst.section(' ',1,1).toFloat(), yy=tst.section(' ',2,2).toFloat();
++ if(p.n==0)
++ res = cmd+" "+QString::number(xx+dx)+" "+QString::number(yy+dy)+" "+tst.section(' ',3);
++ else if(cmd=="rect")
++ {
++ float x_=tst.section(' ',3,3).toFloat(), y_=tst.section(' ',4,4).toFloat();
++ if(p.n==1) { xx+=dx; y_+=dy; }
++ if(p.n==2) { x_+=dx; yy+=dy; }
++ if(p.n==3) { x_+=dx; y_+=dy; }
++ res = "rect "+QString::number(xx)+" "+QString::number(yy)+" "+
++ QString::number(x_)+" "+QString::number(y_)+" "+tst.section(' ',5);
++ }
++ else if(p.n==1)
++ {
++ xx=tst.section(' ',3,3).toFloat(); yy=tst.section(' ',4,4).toFloat();
++ res = tst.section(' ',0,2)+" "+QString::number(xx+dx)+" "+QString::number(yy+dy)+" "+tst.section(' ',5);
++ }
++ else if(cmd=="rhomb" || cmd=="ellipse")
++ {
++ float x_=tst.section(' ',3,3).toFloat()-xx, y_=tst.section(' ',4,4).toFloat()-yy, dr=0;
++ if(x_*x_+y_*y_>0)
++ {
++ dr = (dx*x_+dy*y_)/(x_*x_+y_*y_);
++ dr = hypot(dx-dr*x_,dy-dr*y_);
++ }
++ else dr = hypot(dx,dy);
++ res = tst.section(' ',0,4)+" "+QString::number(tst.section(' ',5,5).toFloat()+dr)+" "+tst.section(' ',6);
++ }
++ else if(cmd=="arc")
++ {
++ double x_=tst.section(' ',3,3).toFloat()-xx, y_=tst.section(' ',4,4).toFloat()-yy, a_=tst.section(' ',5,5).toFloat();
++ double c=cos(M_PI*a_/180), s=sin(M_PI*a_/180);
++ double a = atan2(x_,y_) - atan2(x_*c-y_*s+dx,x_*s+y_*c+dy);
++ res = tst.section(' ',0,4)+" "+QString::number(a*180/M_PI)+" "+tst.section(' ',6);
++ }
++ else if(p.n==2)
++ {
++ xx=tst.section(' ',5,5).toFloat(); yy=tst.section(' ',6,6).toFloat();
++ res = tst.section(' ',0,4)+" "+QString::number(xx+dx)+" "+QString::number(yy+dy)+" "+tst.section(' ',7);
++ }
++ else if(p.n==3)
++ {
++ xx=tst.section(' ',7,7).toFloat(); yy=tst.section(' ',8,8).toFloat();
++ if(cmd=="curve") { dx*=-1; dy*=-1; }
++ res = tst.section(' ',0,6)+" "+QString::number(xx+dx)+" "+QString::number(yy+dy)+" "+tst.section(' ',9);
++ }
++ if(id>0) res = primitives.section('\n',0,id-1) + "\n" + res;
++ primitives = res + "\n" + primitives.section('\n',id+1);
++ refresh(); x0 = xe; y0 = ye;
++ }
++ }
++ else if(id>=0) // this is primitive
++ {
++ QString tst = primitives.section('\n',id,id), cmd=tst.section(' ',0,0), res;
++ float dx = 2*(xe-x0)/float(w), dy = 2*(y0-ye)/float(h);
++ float x1=tst.section(' ',1,1).toFloat(), y1=tst.section(' ',2,2).toFloat(),x2,y2;
++ if(cmd=="ball")
++ res = cmd+" "+QString::number(x1+dx)+" "+QString::number(y1+dy)+" "+tst.section(' ',3);
++ else if(cmd=="curve")
++ {
++ x2=tst.section(' ',5,5).toFloat(); y2=tst.section(' ',6,6).toFloat();
++ res = cmd+" "+QString::number(x1+dx)+" "+QString::number(y1+dy)+" "+tst.section(' ',3,4)+
++ " "+QString::number(x2+dx)+" "+QString::number(y2+dy)+" "+tst.section(' ',7);
++ }
++ else
++ {
++ x2=tst.section(' ',3,3).toFloat(); y2=tst.section(' ',4,4).toFloat();
++ res = cmd+" "+QString::number(x1+dx)+" "+QString::number(y1+dy)+" "+
++ QString::number(x2+dx)+" "+QString::number(y2+dy)+" "+tst.section(' ',5);
++ }
++ if(id>0) res = primitives.section('\n',0,id-1) + "\n" + res;
++ primitives = res + "\n" + primitives.section('\n',id+1);
++ refresh(); x0 = xe; y0 = ye;
++ }
++ }
++ ev->accept();
++}
++//-----------------------------------------------------------------------------
++void QMathGL::mouseDoubleClickEvent(QMouseEvent *ev)
++{
++ long h=pic.height(), w=pic.width(), d=(h>w?w:h)/100;
++ long pos = mgl_is_active(gr,x0,y0,d);
++ long id = long(mgl_get_obj_id(gr,x0,y0));
++ if(grid && pos>=0) // this active point -> delete primitive
++ {
++ const mglActivePos &p = gr->Act[pos];
++ id = long(p.id)-MGL_MAX_LINES;
++ QString res;
++ if(id>0) res = primitives.section('\n',0,id-1) + "\n";
++ if(id>=0) primitives = res + primitives.section('\n',id+1);
++ refresh(); x0 = xe; y0 = ye;
++ }
++ else if(id>=MGL_MAX_LINES) // option for primitives
++ emit askStyle(id-MGL_MAX_LINES);
++ else emit doubleClick(id);
++ ev->accept();
++}
++//-----------------------------------------------------------------------------
++void QMathGL::setStyle(int id, QString stl)
++{
++ QString tst = primitives.section('\n',id,id), res;
++ res = tst.section(' ',0,-2) + " " + stl;
++ if(id>0) res = primitives.section('\n',0,id-1) + "\n" + res;
++ primitives = res + "\n" + primitives.section('\n',id+1);
++ refresh(); x0 = xe; y0 = ye;
++}
++//-----------------------------------------------------------------------------
++void QMathGL::wheelEvent(QWheelEvent *ev)
++{
++ if(!enableWheel) { ev->ignore(); return; }
++ if(rotate) // zoom
++ {
++ mreal d,c,f=exp(0.001*ev->delta())/2;
++ d = (y2-y1)*f; c = (y2+y1)/2; y1 = c-d; y2 = c+d;
++ d = (x2-x1)*f; c = (x2+x1)/2; x1 = c-d; x2 = c+d;
++ refresh(); ev->accept();
++ }
++ else // zoom axis
++ {
++ mreal d,c,f=exp(0.001*ev->delta())/2;
++ d = (ay2-ay1)*f; c = (ay2+ay1)/2; ay1 = c-d; ay2 = c+d;
++ d = (ax2-ax1)*f; c = (ax2+ax1)/2; ax1 = c-d; ax2 = c+d;
++ mgl_zoom_axis(gr,ax1,ay1,0,0,ax2,ay2,0,0);
++ update(); ev->accept();
++ }
++}
++//-----------------------------------------------------------------------------
++void QMathGL::imgSize(int w, int h)
++{ if(w>0 && h>0) { mgl_set_size(gr,w,h); update(); } }
++//-----------------------------------------------------------------------------
++QString setExtension(const QString &fname, const char *ext)
++{
++ QString oname=fname;
++ if(fname.right(4)!="."+QString(ext)) oname = fname+"."+QString(ext);
++ return oname;
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportGIF(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++#if MGL_HAVE_GIF
++ mgl_write_gif(gr,setExtension(fname,"png").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++#else
++ img.save(setExtension(fname,"gif"));
++#endif
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportPNG(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++#if MGL_HAVE_PNG
++ mgl_write_png(gr,setExtension(fname,"png").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++#else
++ img.save(setExtension(fname,"png"));
++#endif
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportPNGs(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++#if MGL_HAVE_PNG
++ mgl_write_png_solid(gr,setExtension(fname,"png").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++#else
++ img.save(setExtension(fname,"png"));
++#endif
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportJPG(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++#if MGL_HAVE_JPEG
++ mgl_write_jpg(gr,setExtension(fname,"jpg").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++#else
++ img.save(setExtension(fname,"jpg"));
++#endif
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportBPS(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++<<<<<<< HEAD
++ {
++ setlocale(LC_NUMERIC, "C");
++ mgl_write_bps(gr,setExtension(fname,"eps").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++ setlocale(LC_NUMERIC, "");
++ }
++=======
++ mgl_write_bps(gr,setExtension(fname,"eps").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportEPS(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++<<<<<<< HEAD
++ {
++ setlocale(LC_NUMERIC, "C");
++ mgl_write_eps(gr,setExtension(fname,"eps").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++ setlocale(LC_NUMERIC, "");
++ }
++=======
++ mgl_write_eps(gr,setExtension(fname,"eps").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportSVG(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++<<<<<<< HEAD
++ {
++ setlocale(LC_NUMERIC, "C");
++ mgl_write_svg(gr,setExtension(fname,"svg").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++ setlocale(LC_NUMERIC, "");
++ }
++=======
++ mgl_write_svg(gr,setExtension(fname,"svg").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportXYZ(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++<<<<<<< HEAD
++ {
++ setlocale(LC_NUMERIC, "C");
++ mgl_write_xyz(gr,setExtension(fname,"xyz").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++ setlocale(LC_NUMERIC, "");
++ }
++=======
++ mgl_write_xyz(gr,setExtension(fname,"xyz").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportTEX(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++<<<<<<< HEAD
++ {
++ setlocale(LC_NUMERIC, "C");
++ mgl_write_tex(gr,setExtension(fname,"tex").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++ setlocale(LC_NUMERIC, "");
++ }
++=======
++ mgl_write_tex(gr,setExtension(fname,"tex").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportOFF(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++<<<<<<< HEAD
++ {
++ setlocale(LC_NUMERIC, "C");
++ mgl_write_off(gr,setExtension(fname,"off").toLocal8Bit().constData(), appName.toLocal8Bit().constData(),0);
++ setlocale(LC_NUMERIC, "");
++ }
++=======
++ mgl_write_off(gr,setExtension(fname,"off").toLocal8Bit().constData(), appName.toLocal8Bit().constData(),0);
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportOBJ(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++<<<<<<< HEAD
++ {
++ setlocale(LC_NUMERIC, "C");
++ mgl_write_obj(gr,setExtension(fname,"obj").toLocal8Bit().constData(), appName.toLocal8Bit().constData(),1);
++ setlocale(LC_NUMERIC, "");
++ }
++=======
++ mgl_write_obj(gr,setExtension(fname,"obj").toLocal8Bit().constData(), appName.toLocal8Bit().constData(),1);
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportSTL(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++<<<<<<< HEAD
++ {
++ setlocale(LC_NUMERIC, "C");
++ mgl_write_stl(gr,setExtension(fname,"stl").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++ setlocale(LC_NUMERIC, "");
++ }
++=======
++ mgl_write_stl(gr,setExtension(fname,"stl").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
++/*void QMathGL::exportX3D(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++<<<<<<< HEAD
++ {
++ setlocale(LC_NUMERIC, "C");
++ mgl_write_x3d(gr,setExtension(fname,"x3d").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++ setlocale(LC_NUMERIC, "");
++ }
++=======
++ mgl_write_x3d(gr,setExtension(fname,"x3d").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}*/
++//-----------------------------------------------------------------------------
++void QMathGL::exportTGA(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++<<<<<<< HEAD
++ {
++ setlocale(LC_NUMERIC, "C");
++ mgl_write_tga(gr,setExtension(fname,"tga").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++ setlocale(LC_NUMERIC, "");
++ }
++=======
++ mgl_write_tga(gr,setExtension(fname,"tga").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportPRC(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++<<<<<<< HEAD
++ {
++ setlocale(LC_NUMERIC, "C");
++ mgl_write_prc(gr,setExtension(fname,"prc").toLocal8Bit().constData(), appName.toLocal8Bit().constData(),1);
++ setlocale(LC_NUMERIC, "");
++ }
++=======
++ mgl_write_prc(gr,setExtension(fname,"prc").toLocal8Bit().constData(), appName.toLocal8Bit().constData(),1);
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
++void QMathGL::exportMGLD(QString fname)
++{
++ if(fname.isEmpty()) fname = mgl_get_plotid(gr);
++ if(fname.isEmpty()) QMessageBox::critical(this, appName, _("No filename."),QMessageBox::Ok,0,0);
++ else
++<<<<<<< HEAD
++ {
++ setlocale(LC_NUMERIC, "C");
++ mgl_export_mgld(gr,setExtension(fname,"mgld").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++ setlocale(LC_NUMERIC, "");
++ }
++=======
++ mgl_export_mgld(gr,setExtension(fname,"mgld").toLocal8Bit().constData(), appName.toLocal8Bit().constData());
++>>>>>>> 92ae9b8fae4c900177b8b7d36736919646f2b965
++}
++//-----------------------------------------------------------------------------
++void mglConvertFromGraph(QPixmap &pic, mglCanvas *gr, uchar **buf, QImage *out)
++{
++ const uchar *bb = mgl_get_rgb(gr);
++ long w=mgl_get_width(gr), h=mgl_get_height(gr);
++ if(*buf) delete [](*buf);
++ *buf = new uchar[4*w*h];
++ for(long i=0;i<w*h;i++)
++ {
++ (*buf)[4*i] = bb[3*i+2];
++ (*buf)[4*i+1] = bb[3*i+1];
++ (*buf)[4*i+2] = bb[3*i];
++ (*buf)[4*i+3] = 255;
++ }
++ QImage img(*buf, w, h, QImage::Format_RGB32);
++ if(out) *out = img;
++ pic = QPixmap::fromImage(img);
++}
++//-----------------------------------------------------------------------------
++void QMathGL::copy()
++{ QClipboard *cb = QApplication::clipboard();
++ cb->setPixmap(pic, QClipboard::Clipboard); }
++//-----------------------------------------------------------------------------
++void QMathGL::copyClickCoor()
++{ QApplication::clipboard()->setText(mousePos); }
++//-----------------------------------------------------------------------------
++void QMathGL::setMGLFont(QString path)
++{ if(path.isEmpty()) mgl_restore_font(gr);
++ else mgl_load_font(gr,path.toLocal8Bit().constData(),0); }
++//-----------------------------------------------------------------------------
++void QMathGL::setSize(int w, int h)
++{
++ resize(w, h);
++ if(w!=pic.width() || h!=pic.height()) // update only when image size is changed
++ { mgl_set_size(gr,w,h); update(); }
++}
++//-----------------------------------------------------------------------------
++void QMathGL::about()
++{
++ QString s = _("MathGL v. 2.") + QString::number(MGL_VER2) + _("\n(c) Alexey Balakin, 2007\nhttp://mathgl.sourceforge.net/");
++ QMessageBox::about(this, _("MathGL - about"), s);
++}
++//-----------------------------------------------------------------------------
++void QMathGL::aboutQt() { QMessageBox::aboutQt(this, _("About Qt")); }
++//-----------------------------------------------------------------------------
++void QMathGL::print()
++{
++ QPrinter *printer = new QPrinter;
++ printer->setOrientation(getRatio()>1 ? QPrinter::Landscape : QPrinter::Portrait);
++ QPrintDialog printDlg(printer, this);
++ if (printDlg.exec() == QDialog::Accepted)
++ {
++ QRectF r = printer->pageRect(QPrinter::Inch);
++ int d1 = int(pic.width()/r.width()), d2 = int(pic.height()/r.height());
++ int dpi = printer->resolution();
++ if(dpi<d1) dpi=d1;
++ if(dpi<d2) dpi=d2;
++ printer->setResolution(dpi);
++
++ QPainter p;
++ if(!p.begin(printer)) return; // paint on printer
++ p.drawPixmap(0,0,pic);
++ }
++ delete printer;
++}
++//-----------------------------------------------------------------------------
++void QMathGL::nextSlide()
++{
++ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);
++ if(g && g->GetNumFig()>1) g->NextFrame();
++ emit frameChanged(+1);
++}
++void QMathGL::prevSlide()
++{
++ mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);
++ if(g && g->GetNumFig()>1) g->PrevFrame();
++ emit frameChanged(-1);
++}
++//-----------------------------------------------------------------------------
++void QMathGL::animation(bool st)
++{
++ if(!st) timer->stop();
++ else timer->start(int(mgl_wnd_get_delay(gr)*1000));
++}
++//-----------------------------------------------------------------------------
++void QMathGL::adjust()
++{
++ mgl_set_size(gr, parentWidget()->width()-3, parentWidget()->height()-3);
++ setSize(parentWidget()->width()-3, parentWidget()->height()-3);
++ update(); // TODO replace to refresh ?!?
++}
++//-----------------------------------------------------------------------------
++void QMathGL::addMark()
++{ primitives += "ball 0 0 'r*'\n"; refresh(); }
++//-----------------------------------------------------------------------------
++void QMathGL::addLine()
++{ primitives += "line -0.2 0 0.2 0 'r2'\n"; refresh(); }
++//-----------------------------------------------------------------------------
++void QMathGL::addRect()
++{ primitives += "rect -0.2 -0.2 0.2 0.2 'r'\n"; refresh(); }
++//-----------------------------------------------------------------------------
++void QMathGL::addCurve()
++{ primitives += "curve -0.2 0 0 0.5 0.2 0 0 0.5 'r2'\n"; refresh(); }
++//-----------------------------------------------------------------------------
++void QMathGL::addRhomb()
++{ primitives += "rhomb -0.2 0 0.2 0 0.1 'r'\n"; refresh(); }
++//-----------------------------------------------------------------------------
++void QMathGL::addEllipse()
++{ primitives += "ellipse -0.2 0 0.2 0 0.1 'r'\n"; refresh(); }
++//-----------------------------------------------------------------------------
++void QMathGL::addArc()
++{ primitives += "arc 0 0 0.2 0 60 'r2'\n"; refresh(); }
++//-----------------------------------------------------------------------------
++void QMathGL::addPolygon(int n)
++{
++ if(n<3)
++ n = QInputDialog::getText(QApplication::activeWindow(), "MathGL", _("Enter number of vertexes")).toInt();
++ if(n>=3)
++ { primitives += "polygon 0 0 0 0.2 "+QString::number(n)+" 'r'\n"; refresh(); }
++}
++//{ primitives += "arc -0.2 0 0.2 0 0.1 'r'\n"; refresh(); }
++//-----------------------------------------------------------------------------
++void QMathGL::addText(QString txt)
++{
++ if(txt.isEmpty())
++ txt = QInputDialog::getText(QApplication::activeWindow(), "MathGL", _("Enter text"));
++ if(!txt.isEmpty())
++ { primitives += "text 0 0 0.1 0 '"+txt+"' ''\n"; refresh(); }
++}
++//-----------------------------------------------------------------------------
++//
++// class mglCanvasQT
++//
++//-----------------------------------------------------------------------------
++mglCanvasQT::mglCanvasQT() : mglCanvasWnd()
++{ Wnd = 0; }
++mglCanvasQT::~mglCanvasQT()
++{ if(Wnd) { QMGL->gr=0; delete Wnd; } }
++//-----------------------------------------------------------------------------
++void mglCanvasQT::GotoFrame(int d)
++{
++ int f = GetCurFig()+d;
++ if(f>=GetNumFig()) f = 0;
++ if(f<0) f = GetNumFig()-1;
++ if(GetNumFig()>0 && d) { SetCurFig(f); QMGL->refresh(); }
++}
++//-----------------------------------------------------------------------------
++void mglCanvasQT::Animation()
++{
++ static bool start=true;
++ QMGL->animation(start);
++ start = !start;
++}
++//-----------------------------------------------------------------------------
++void mglCanvasQT::ToggleAlpha() { QMGL->setAlpha(!QMGL->getAlpha()); }
++//-----------------------------------------------------------------------------
++void mglCanvasQT::ToggleLight() { QMGL->setLight(!QMGL->getLight()); }
++//-----------------------------------------------------------------------------
++void mglCanvasQT::ToggleNo() { QMGL->restore(); }
++//-----------------------------------------------------------------------------
++void mglCanvasQT::ToggleZoom() { QMGL->setZoom(!QMGL->getZoom()); }
++//-----------------------------------------------------------------------------
++void mglCanvasQT::ToggleRotate(){ QMGL->setRotate(!QMGL->getRotate());}
++//-----------------------------------------------------------------------------
++void mglCanvasQT::Update() { SetCurFig(0); QMGL->update(); Wnd->show(); }
++//-----------------------------------------------------------------------------
++void mglCanvasQT::Adjust() { QMGL->adjust(); }
++//-----------------------------------------------------------------------------
++void mglCanvasQT::Window(int argc, char **argv, int (*draw)(mglBase *gr, void *p), const char *title, void *par, void (*reload)(void *p), bool maximize)
++{
++ static char arg=0, *parg=&arg, **argv_=&parg;
++ static int argc_=0;
++ SetDrawFunc(draw, par, reload);
++ if(Wnd)
++ {
++ Wnd->setWindowTitle(title);
++ if(maximize)
++ { Wnd->showMaximized(); }
++ else Wnd->show();
++ return;
++ }
++
++ if(!qApp)
++ {
++ QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
++ if(!argv) { argc_ = 0; argv_=&parg; }
++ else { argc_ = argc; argv_=argv; }
++ QApplication *a = new QApplication(argc_, argv_);
++ a->connect(a, SIGNAL(lastWindowClosed()), a, SLOT(quit()));
++ }
++
++ Wnd = new QMainWindow; Wnd->resize(850,680);
++ Wnd->setWindowTitle(title);
++ scroll = new QScrollArea(Wnd);
++
++ QMGL = new QMathGL(Wnd);
++ popup = mglMakeMenu(Wnd, QMGL, tet, phi);
++ QMGL->setPopup(popup); QMGL->setGraph(this);
++ QMGL->setDraw(draw, par);
++ QMGL->appName = title;
++ qApp->processEvents();
++ scroll->setWidget(QMGL);
++ Wnd->setCentralWidget(scroll);
++ QMGL->refresh();
++ if(!maximize) Wnd->show();
++ else Wnd->showMaximized();
++}
++//-----------------------------------------------------------------------------
++#include "xpm/alpha.xpm"
++#include "xpm/arc.xpm"
++#include "xpm/copy.xpm"
++#include "xpm/curve.xpm"
++#include "xpm/down_1.xpm"
++#include "xpm/fileprint.xpm"
++#include "xpm/left_1.xpm"
++#include "xpm/light.xpm"
++#include "xpm/line.xpm"
++#include "xpm/mark_a.xpm"
++#include "xpm/mark_d.xpm"
++#include "xpm/mark_o.xpm"
++#include "xpm/mark_s.xpm"
++#include "xpm/right_1.xpm"
++#include "xpm/next_sl.xpm"
++#include "xpm/norm_1.xpm"
++#include "xpm/ok.xpm"
++#include "xpm/prev_sl.xpm"
++#include "xpm/rotate.xpm"
++#include "xpm/show_sl.xpm"
++#include "xpm/text.xpm"
++#include "xpm/polygon.xpm"
++#include "xpm/zoom_1.xpm"
++#include "xpm/zoom_in.xpm"
++#include "xpm/zoom_out.xpm"
++#include "xpm/up_1.xpm"
++#include "xpm/stop.xpm"
++#include "xpm/pause.xpm"
++//-----------------------------------------------------------------------------
++MGL_EXPORT QMenu *mglMakeMenu(QMainWindow *Wnd, QMathGL *QMGL, QSpinBox *&tet, QSpinBox *&phi)
++{
++ QAction *a;
++ QMenu *o, *oo, *f;
++ QToolBar *bb;
++
++ QMenu *popup = new QMenu(Wnd);
++ // file menu
++ {
++ f = o = Wnd->menuBar()->addMenu(_("File"));
++ oo = new QMenu(_("Export as 2D ..."),Wnd);
++ oo->addAction(_("PNG"), QMGL, SLOT(exportPNG()),Qt::ALT+Qt::Key_P);
++ oo->addAction(_("solid PNG"), QMGL, SLOT(exportPNGs()),Qt::ALT+Qt::Key_F);
++ oo->addAction(_("JPEG"), QMGL, SLOT(exportJPG()),Qt::ALT+Qt::Key_J);
++ oo->addAction(_("bitmap EPS"), QMGL, SLOT(exportBPS()));
++ oo->addAction(_("vector EPS"), QMGL, SLOT(exportEPS()),Qt::ALT+Qt::Key_E);
++ oo->addAction(_("SVG"), QMGL, SLOT(exportSVG()),Qt::ALT+Qt::Key_S);
++ oo->addAction(_("LaTeX"), QMGL, SLOT(exportTEX()),Qt::ALT+Qt::Key_L);
++ o->addMenu(oo); popup->addMenu(oo);
++ oo = new QMenu(_("Export as 3D ..."),Wnd);
++ oo->addAction(_("MGLD"), QMGL, SLOT(exportMGLD()),Qt::ALT+Qt::Key_M);
++ oo->addAction(_("PRC"), QMGL, SLOT(exportPRC()),Qt::ALT+Qt::Key_D);
++ oo->addAction(_("OBJ"), QMGL, SLOT(exportOBJ()),Qt::ALT+Qt::Key_O);
++ oo->addAction(_("STL"), QMGL, SLOT(exportSTL()));
++ oo->addAction(_("XYZ"), QMGL, SLOT(exportXYZ()));
++// oo->addAction(_("X3D"), QMGL, SLOT(exportX3D()),Qt::ALT+Qt::Key_X);
++ o->addMenu(oo); popup->addMenu(oo);
++
++ o->addSeparator();
++ a = new QAction(QPixmap(fileprint), _("Print graphics"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(print()));
++ a->setToolTip(_("Open printer dialog and print graphics (Ctrl+P)"));
++ a->setShortcut(Qt::CTRL+Qt::Key_P); o->addAction(a);
++ o->addSeparator();
++ o->addAction(_("Close"), Wnd, SLOT(close()), Qt::CTRL+Qt::Key_W);
++ }
++ // graphics menu
++ {
++ bb = new QToolBar(_("Graphics"),Wnd);
++ Wnd->addToolBar(Qt::TopToolBarArea, bb);
++ o = Wnd->menuBar()->addMenu(_("Graphics"));
++ a = new QAction(QPixmap(alpha_xpm), _("Alpha"), Wnd);
++ a->setShortcut(Qt::ALT+Qt::Key_T); a->setCheckable(true);
++ Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(setAlpha(bool)));
++ Wnd->connect(QMGL, SIGNAL(alphaChanged(bool)), a, SLOT(setChecked(bool)));
++ a->setToolTip(_("Switch on/off transparency for the graphics (Alt+T)."));
++ o->addAction(a); bb->addAction(a);
++ a = new QAction(QPixmap(light_xpm), _("Light"), Wnd);
++ a->setShortcut(Qt::ALT+Qt::Key_L); a->setCheckable(true);
++ Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(setLight(bool)));
++ Wnd->connect(QMGL, SIGNAL(lightChanged(bool)), a, SLOT(setChecked(bool)));
++ a->setToolTip(_("Switch on/off lightning for the graphics (Alt+L)."));
++ o->addAction(a); bb->addAction(a);
++ a = new QAction(QPixmap(rotate_xpm), _("Rotate by mouse"), Wnd);
++ a->setCheckable(true);
++ Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(setRotate(bool)));
++ Wnd->connect(QMGL, SIGNAL(rotateChanged(bool)), a, SLOT(setChecked(bool)));
++ a->setToolTip(_("Switch on/off mouse handling of the graphics\n(rotation, shifting, zooming and perspective)."));
++ bb->addAction(a);
++ a = new QAction(QPixmap(zoom_in_xpm), _("Zoom by mouse"), Wnd);
++ a->setCheckable(true);
++ Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(setZoom(bool)));
++ Wnd->connect(QMGL, SIGNAL(zoomChanged(bool)), a, SLOT(setChecked(bool)));
++ a->setToolTip(_("Switch on/off mouse zoom of selected region."));
++ bb->addAction(a);
++ o->addSeparator();
++ a = new QAction(QPixmap(zoom_out_xpm), _("Restore"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(restore()));
++ a->setToolTip(_("Restore default graphics rotation, zoom and perspective (Alt+Space)."));
++ a->setShortcut(Qt::ALT+Qt::Key_Space);
++ o->addAction(a); bb->addAction(a); popup->addAction(a);
++ bb->addSeparator();
++ o->addAction(a); bb->addAction(a); popup->addAction(a);
++ a = new QAction(QPixmap(ok_xpm), _("Redraw"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(update()));
++ a->setToolTip(_("Execute script and redraw graphics (F5)."));
++ a->setShortcut(Qt::Key_F5);
++ o->addAction(a); bb->addAction(a); popup->addAction(a);
++ a = new QAction(QPixmap(stop_xpm), _("Stop"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(stop()));
++ a->setToolTip(_("Ask to stop plot drawing (F7)."));
++ a->setShortcut(Qt::Key_F7);
++ a = new QAction(_("Adjust size"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(adjust()));
++ a->setToolTip(_("Change canvas size to fill whole region (F6)."));
++ a->setShortcut(Qt::Key_F6); o->addAction(a);
++ a = new QAction(QPixmap(copy_xpm), _("Copy plot"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(copy()));
++ a->setToolTip(_("Copy graphics to clipboard (Ctrl+Shift+G)."));
++ a->setShortcut(Qt::CTRL+Qt::SHIFT+Qt::Key_G);
++ o->addAction(a); bb->addAction(a); popup->addAction(a);
++
++ bb->addSeparator();
++ oo = new QMenu(_("Primitives ..."),Wnd);
++ a = new QAction(QPixmap(line_xpm), _("Add line"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addLine()));
++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
++ a->setToolTip(_("Add line which properties can be changed later by mouse."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(arc_xpm), _("Add arc"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addArc()));
++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
++ a->setToolTip(_("Add arc which properties can be changed later by mouse."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(curve_xpm), _("Add curve"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addCurve()));
++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
++ a->setToolTip(_("Add curve which properties can be changed later by mouse."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(mark_s_xpm), _("Add rect"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addRect()));
++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
++ a->setToolTip(_("Add rectangle which properties can be changed later by mouse."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(mark_d_xpm), _("Add rhombus"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addRhomb()));
++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
++ a->setToolTip(_("Add rhombus which properties can be changed later by mouse."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(mark_o_xpm), _("Add ellipse"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addEllipse()));
++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
++ a->setToolTip(_("Add ellipse which properties can be changed later by mouse."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(polygon_xpm), _("Add polygon"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addPolygon()));
++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
++ a->setToolTip(_("Add polygon which properties can be changed later by mouse."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(mark_a_xpm), _("Add mark"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addMark()));
++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
++ a->setToolTip(_("Add marker which properties can be changed later by mouse."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(text_xpm), _("Add text"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(addText()));
++ Wnd->connect(QMGL, SIGNAL(usePrimChanged(bool)), a, SLOT(setVisible(bool)));
++ a->setToolTip(_("Add text which properties can be changed later by mouse."));
++ bb->addAction(a); oo->addAction(a);
++ o->addMenu(oo);
++
++ bb->addSeparator();
++ tet = new QSpinBox(Wnd); tet->setWrapping(true);
++ bb->addWidget(tet); tet->setRange(-180, 180); tet->setSingleStep(10);
++ Wnd->connect(tet, SIGNAL(valueChanged(int)), QMGL, SLOT(setTet(int)));
++ Wnd->connect(QMGL, SIGNAL(tetChanged(int)), tet, SLOT(setValue(int)));
++ tet->setToolTip(_("Set value of \\theta angle."));
++ bb->addSeparator();
++ phi = new QSpinBox(Wnd); phi->setWrapping(true);
++ bb->addWidget(phi); phi->setRange(-180, 180); phi->setSingleStep(10);
++ Wnd->connect(phi, SIGNAL(valueChanged(int)), QMGL, SLOT(setPhi(int)));
++ Wnd->connect(QMGL, SIGNAL(phiChanged(int)), phi, SLOT(setValue(int)));
++ phi->setToolTip(_("Set value of \\phi angle."));
++// bb->addSeparator();
++ }
++ // zooming menu
++ {
++ oo = o->addMenu(_("Zoom/move"));
++ bb = new QToolBar(_("Zoom graphics"),Wnd);
++ Wnd->addToolBar(Qt::LeftToolBarArea, bb);
++ a = new QAction(QPixmap(left_1_xpm), _("Move left"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(shiftLeft()));
++ a->setToolTip(_("Move graphics left by 1/3 of its width."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(up_1_xpm), _("Move up"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(shiftUp()));
++ a->setToolTip(_("Move graphics up by 1/3 of its height."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(zoom_1_xpm), _("Zoom in"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(zoomIn()));
++ a->setToolTip(_("Zoom in graphics."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(norm_1_xpm), _("Zoom out"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(zoomOut()));
++ a->setToolTip(_("Zoom out graphics."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(down_1_xpm), _("Move down"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(shiftDown()));
++ a->setToolTip(_("Move graphics up down 1/3 of its height."));
++ bb->addAction(a); oo->addAction(a);
++ a = new QAction(QPixmap(right_1_xpm), _("Move right"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(shiftRight()));
++ a->setToolTip(_("Move graphics right by 1/3 of its width."));
++ bb->addAction(a); oo->addAction(a);
++ }
++ // animation menu
++ {
++ o = Wnd->menuBar()->addMenu(_("Animation"));
++ bb = new QToolBar(_("Animation"),Wnd);
++ Wnd->addToolBar(Qt::LeftToolBarArea, bb);
++ a = new QAction(QPixmap(next_sl_xpm), _("Next slide"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(nextSlide()));
++ a->setToolTip(_("Show next slide (Ctrl+.)."));
++ a->setShortcut(Qt::CTRL+Qt::Key_Period); o->addAction(a); bb->addAction(a);
++ a = new QAction(QPixmap(show_sl_xpm), _("Slideshow"), Wnd);
++ a->setCheckable(true);
++ Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(animation(bool)));
++ a->setToolTip(_("Run slideshow (CTRl+F5)."));
++ a->setShortcut(Qt::CTRL+Qt::Key_F5); o->addAction(a); bb->addAction(a);
++ a = new QAction(QPixmap(prev_sl_xpm), _("Prev slide"), Wnd);
++ Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(prevSlide()));
++ a->setToolTip(_("Show previous slide (Ctrl+,)."));
++ a->setShortcut(Qt::CTRL+Qt::Key_Comma); o->addAction(a); bb->addAction(a);
++ }
++#if MGL_HAVE_PTHR_WIDGET
++ {
++ bb = new QToolBar(_("Calculations"),Wnd);
++ Wnd->addToolBar(Qt::LeftToolBarArea, bb);
++ a = new QAction(QPixmap(pause_xpm), _("Pause calculation"), Wnd);
++ a->setCheckable(true);
++ Wnd->connect(a, SIGNAL(toggled(bool)), QMGL, SLOT(setPause(bool)));
++ Wnd->connect(QMGL, SIGNAL(pauseChanged(bool)), a, SLOT(setChecked(bool)));
++// Wnd->connect(a, SIGNAL(triggered()), QMGL, SLOT(setPause()));
++ a->setToolTip(_("Pause on/off external calculations"));
++ f->addSeparator(); f->addAction(a); bb->addAction(a);
++ }
++#endif
++
++ Wnd->menuBar()->addSeparator();
++ o = Wnd->menuBar()->addMenu(_("Help"));
++ o->addAction(_("About"), QMGL, SLOT(about()));
++ o->addAction(_("About Qt"), QMGL, SLOT(aboutQt()));
++ return popup;
++}
++//-----------------------------------------------------------------------------
++HMGL MGL_EXPORT mgl_create_graph_qt(int (*draw)(HMGL gr, void *p), const char *title, void *par, void (*load)(void *p))
++{
++ mglCanvasQT *g = new mglCanvasQT;
++ g->Window(0,0,draw,title,par,load);
++ return g;
++}
++void* mgl_qt_widget(HMGL gr)
++{
++ mglCanvasQT *g = dynamic_cast<mglCanvasQT *>(gr);
++ return g?g->QMGL:NULL;
++}
++int MGL_EXPORT mgl_qt_run() { return (qApp)?qApp->exec():-1; }
++//-----------------------------------------------------------------------------
++uintptr_t MGL_EXPORT mgl_create_graph_qt_(const char *title, int l)
++{
++ char *s = new char[l+1]; memcpy(s,title,l); s[l]=0;
++ uintptr_t t = uintptr_t(mgl_create_graph_qt(0,s,0,0));
++ delete []s; return t;
++}
++int MGL_EXPORT mgl_qt_run_() { return mgl_qt_run(); }
++//-----------------------------------------------------------------------------