diff --git a/doc/manual/manual/visualization/figures.rst b/doc/manual/manual/visualization/figures.rst index 13d92725e..f25f0aad9 100644 --- a/doc/manual/manual/visualization/figures.rst +++ b/doc/manual/manual/visualization/figures.rst @@ -2,3 +2,101 @@ The Figure classes ================== + +This page describes the classes used in Codac for 2D visualization. + +.. _subsec-graphics-figures-graphical-outputs: + +Graphical outputs +----------------- + +Two graphical outputs are currently supported in Codac: :ref:`VIBes ` and :ref:`IPE `. VIBes is used for real-time +visualization while IPE creates a file that can be edited by the IPE editor. These outputs are referenced by the enumeration GraphicOutput: + +.. tabs:: + + .. code-tab:: py + + GraphicOutput.VIBES # for VIBes + GraphicOutput.IPE # for IPE + GraphicOutput.VIBES | GraphicOutput.IPE # for both + + .. code-tab:: c++ + + GraphicOutput::VIBES // for VIBes + GraphicOutput::IPE // for IPE + GraphicOutput::VIBES | GraphicOutput::IPE // for both + +Note that for the VIBes output to work, the VIBes viewer must be launched before the program is run. + +.. _subsec-graphics-figures-figure2d: + +Figure2D +-------- + +The basic class for 2D visualization is Figure2D. It is used to create a figure that can be displayed in VIBes or saved in an xml file for IPE. +The constructor takes two arguments: the name of the figure and the graphical output. A boolean can be added to specify if the figure is to be used +DefaultView (see :ref:`subsec-graphics-figures-figure2d-defaultview`). + +.. tabs:: + + .. code-tab:: py + + fig = Figure2D("My figure", GraphicOutput.VIBES | GraphicOutput.IPE) + + .. code-tab:: c++ + + Figure2D figure ("My Figure",GraphicOutput::VIBES|GraphicOutput::IPE); + +.. _subsec-graphics-figures-figure2d-defaultview: + +DefaultView +----------- + +A DefaultView using only VIBes as graphical output is available. This figure is the one used by the function `draw_while_paving` by default. +Any Figure2D object can be used as DefaultView with the set method: + +.. tabs:: + + .. code-tab:: py + + figure = Figure2D("My figure", GraphicOutput.VIBES | GraphicOutput.IPE) + DefaultView.set(figure) + + .. code-tab:: c++ + + std::shared_ptr figure = std::make_shared("My Figure",GraphicOutput::VIBES|GraphicOutput::IPE); + DefaultView::set(figure); + +Note that in C++ the figure must be a shared pointer in order to be passed to the `set` method. + +Equivalently, a Figure2D can be used as DefaultView by setting the flag `set_as_default` to true in the constructor: + +.. tabs:: + + .. code-tab:: py + + fig = Figure2D("My figure", GraphicOutput.VIBES | GraphicOutput.IPE, True) + + .. code-tab:: c++ + + Figure2D figure ("My Figure",GraphicOutput::VIBES|GraphicOutput::IPE,true); + +.. _subsec-graphics-figures-figure2d-figure-properties: + +Figure properties +----------------- + +Once created, the properties of a Figure2D object can be modified using the following methods: + +.. tabs:: + + .. code-tab:: py + + fig.set_window_properties([50,50],[500,500]) # set the window position and size + fig.set_axes(axis(0,[-10,10]), axis(1,[-10,10])) # set the range of values on each axis : 0 for x-axis, 1 for y-axis + + .. code-tab:: c++ + + fig.set_window_properties({50,50},{500,500}); // set the window position and size + fig.set_axes(axis(0,{-10,10}), axis(1,{-10,10})); // set the range of values on each axis : 0 for x-axis, 1 for y-axis \ No newline at end of file diff --git a/doc/manual/manual/visualization/functions.rst b/doc/manual/manual/visualization/functions.rst new file mode 100644 index 000000000..3451b92f2 --- /dev/null +++ b/doc/manual/manual/visualization/functions.rst @@ -0,0 +1,5 @@ +.. _sec-graphics-functions: + +Drawing functions +================= + diff --git a/doc/manual/manual/visualization/index.rst b/doc/manual/manual/visualization/index.rst index 79b3cce63..7b50c4644 100644 --- a/doc/manual/manual/visualization/index.rst +++ b/doc/manual/manual/visualization/index.rst @@ -5,8 +5,9 @@ Visualization .. toctree:: - colors.rst figures.rst + functions.rst + colors.rst vibes.rst ipe.rst 3d_visualization.rst \ No newline at end of file diff --git a/examples/00_graphics/CMakeLists.txt b/examples/00_graphics/CMakeLists.txt new file mode 100644 index 000000000..6219b4dab --- /dev/null +++ b/examples/00_graphics/CMakeLists.txt @@ -0,0 +1,34 @@ +# ================================================================== +# codac / basics example - cmake configuration file +# ================================================================== + + cmake_minimum_required(VERSION 3.0.2) + project(codac_example LANGUAGES CXX) + + set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Adding Codac + + # In case you installed Codac in a local directory, you need + # to specify its path with the CMAKE_PREFIX_PATH option. + # set(CMAKE_PREFIX_PATH "~/codac/build_install") + + find_package(CODAC REQUIRED) + message(STATUS "Found Codac version ${CODAC_VERSION}") + +# Initializating Ibex + + ibex_init_common() + +# Compilation + + if(FAST_RELEASE) + add_compile_definitions(FAST_RELEASE) + message(STATUS "You are running Codac in fast release mode. (option -DCMAKE_BUILD_TYPE=Release is required)") + endif() + + add_executable(${PROJECT_NAME} graphic_examples.cpp) + target_compile_options(${PROJECT_NAME} PUBLIC ${CODAC_CXX_FLAGS}) + target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CODAC_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} PUBLIC ${CODAC_LIBRARIES}) \ No newline at end of file diff --git a/examples/00_graphics/graphic_examples.cpp b/examples/00_graphics/graphic_examples.cpp new file mode 100644 index 000000000..1f69f70a8 --- /dev/null +++ b/examples/00_graphics/graphic_examples.cpp @@ -0,0 +1,94 @@ +#include + +using namespace std; +using namespace codac2; + +int main(){ + + // Graphics can be directly called without a Figure2D instanciation, using "DefaultView" + + DefaultView::set_window_properties({600,600},{300,300}); + DefaultView::draw_box({{2.2,2.5},{2.2,2.5}},{Color::black(),Color::yellow(0.5)}); + DefaultView::draw_AUV({1,1,3.14/2},1.,{Color::black(),Color::yellow()}); + DefaultView::draw_tank({2,1,3.14/2},1.,{Color::black(),Color::yellow()}); + DefaultView::draw_pie({2,2},{1.5,2.5},{(3*3.14/4)-0.5,(3*3.14/4)+0.5},{Color::blue(),Color::cyan()}); + DefaultView::draw_polyline({{2,-0.5},{4,0.5},{3,1.5},{4,2.5},{3,3}}, Color::red()); + DefaultView::draw_polygone({{2,4.5},{4,4.5},{4.2,3.5},{3.5,3}}, {Color::none(),Color::green(0.5)}); + DefaultView::draw_polyline({{-0.8,0},{0,1.5}}, 0.2, {Color::red(),Color::black(0.3)}); + + // Last argument corresponds to "StyleProperties" with one or two colors: edge color + (optional) fill color + // Predefined Color objects can be configured with a float parameter for opacity (1=opaque, 0=transparent) + + // Custom figures can also be created: + std::shared_ptr fig1 = std::make_shared("My Figure 1",GraphicOutput::VIBES|GraphicOutput::IPE); + + // Here, graphics will be rendered by two tools: both VIBES and IPE + // For VIBES, it requires the VIBes viewer to be launched prior to the execution + // For IPE, it generates a file named "My figure 1.xml" that can be edited with IPE, and converted to PDF + + fig1->set_window_properties({50,50},{500,500}); // position, window size + fig1->set_axes(axis(0,{-10,10}), axis(1,{-10,10})); // (axis_id,{range_of_values_on_this_axis}) + fig1->draw_box({{-1,1},{-1,1}},{Color::green(),Color::red(0.2)}); // drawing a green box with red opacity values inside + fig1->draw_circle({1,1},0.5,Color({255,155,5})); // drawing a circle at (1,1) of radius 0.5 with a custom RGB color + fig1->draw_ring({1,1},{4,6},Color::red()); // drawing a ring at (1,1) of radius {4,6} with a predefined red color + + std::shared_ptr fig2 = std::make_shared("My Figure 2",GraphicOutput::VIBES|GraphicOutput::IPE); + fig2->set_axes(axis(0,{-1,5}), axis(1,{-1,5})); + fig2->set_window_properties({250,250},{500,500}); + + // The previously declared figure "fig2" can now be used as a DefaultView + DefaultView::set(fig2); + DefaultView::draw_box({{2.2,2.5},{2.2,2.5}},{Color::black(),Color::green(0.8)}); + + DefaultView::set(fig1); + DefaultView::draw_box({{2.2,2.5},{2.2,2.5}},{Color::blue(),Color::cyan(0.8)}); + + fig2->draw_AUV({1,1,3.14/2},2.,{Color::black(),Color::yellow()}); + fig2->draw_tank({2,1,3.14/2},1.,{Color::black(),Color::yellow()}); + fig2->draw_pie({2,2},{1.5,2.5},{(3*3.14/4)-0.5,(3*3.14/4)+0.5},{Color::blue(),Color::cyan()}); + fig2->draw_polyline({{2,-0.5},{4,0.5},{3,1.5},{4,2.5},{3,3}}, Color::red()); + fig2->draw_polygone({{2,4.5},{4,4.5},{4.2,3.5},{3.5,3}}, {Color::none(),Color::green(0.5)}); + fig2->draw_polyline({{-0.8,0},{0,1.5}}, 0.2, {Color::red(),Color::black(0.3)}); + fig2->draw_ellipse({1,1},{0.5,2}, 0.2, {Color::blue(),Color::blue(0.3)}); + fig2->draw_line({1,1},{3,3}, Color::blue()); + fig2->draw_arrow({3,1},{2.2,2}, 0.2, {Color::red(),Color::black(0.3)}); + + // Colors + // predefined colors without and with opacity + fig2->draw_point({2,2}, {Color::red(),Color::yellow(0.5)}); + // HTML color without and with opacity + fig2->draw_box({{2.4,2.9},{2.4,2.9}},{Color("#da3907"),Color("#da390755")}); + // HSV color without and with opacity + fig2->draw_box({{2.6,3.1},{2.6,3.1}},{Color({108,90,78},Model::HSV),Color({108,90,78,20},Model::HSV)}); + + Figure2D fig3 ("My Figure 3",GraphicOutput::VIBES|GraphicOutput::IPE); + fig3.set_axes(axis(0,{-1,21}), axis(1,{-5.5,0.5})); + fig3.set_window_properties({800,250},{500,500}); + + ColorMap cmap_haxby = ColorMap::haxby(); + ColorMap cmap_default = ColorMap::basic(); + ColorMap cmap_blue_tube = ColorMap::blue_tube(); + ColorMap cmap_red_tube = ColorMap::red_tube(); + ColorMap cmap_rainbow = ColorMap::rainbow(); + + for (double i=0.; i<20; i++) + { + double ratio = i/20.; + fig3.draw_box({{i,i+1},{-1,0}},{Color::black(),cmap_haxby.color(ratio)}); + fig3.draw_box({{i,i+1},{-2,-1}},{Color::black(),cmap_default.color(ratio)}); + fig3.draw_box({{i,i+1},{-3,-2}},{Color::black(),cmap_blue_tube.color(ratio)}); + fig3.draw_box({{i,i+1},{-4,-3}},{Color::black(),cmap_red_tube.color(ratio)}); + fig3.draw_box({{i,i+1},{-5,-4}},{Color::black(),cmap_rainbow.color(ratio)}); + } + + Figure2D fig4 ("My Figure 4",GraphicOutput::VIBES); + + fig4.set_axes(axis(0,{-10,10}), axis(1,{-10,10})); + + double a=0.5; + ScalarVar t; + // Fermat's spiral + AnalyticFunction f1 ({t},{a*sqrt(t)*cos(t),a*sqrt(t)*sin(t)}); + AnalyticTraj traj4 (f1,{0,100}); + fig4.draw_trajectory(traj4,ColorMap::rainbow()); +} diff --git a/examples/00_graphics/graphic_examples.py b/examples/00_graphics/graphic_examples.py index f753ba5cc..d0a5b2538 100644 --- a/examples/00_graphics/graphic_examples.py +++ b/examples/00_graphics/graphic_examples.py @@ -75,14 +75,14 @@ fig3.draw_box([[i,i+1],[-4,-3]],[Color.black(),cmap_red_tube.color(ratio)]) fig3.draw_box([[i,i+1],[-5,-4]],[Color.black(),cmap_rainbow.color(ratio)]) -fig3 = Figure2D("My figure 3", GraphicOutput.VIBES) +fig4 = Figure2D("My figure 4", GraphicOutput.VIBES) -fig3.set_window_properties([500,50],[500,500]) -fig3.set_axes(axis(0,[-10,10]), axis(1,[-10,10])) +fig4.set_window_properties([500,50],[500,500]) +fig4.set_axes(axis(0,[-10,10]), axis(1,[-10,10])) a = 0.8 t=ScalarVar() # Fermat's spiral f1=AnalyticFunction([t], [a*sqrt(t)*cos(t),a*sqrt(t)*sin(t)]) -traj3=AnalyticTraj(f1, [0,100]) -fig3.draw_trajectory(traj3, ColorMap.rainbow()) \ No newline at end of file +traj4=AnalyticTraj(f1, [0,100]) +fig4.draw_trajectory(traj4, ColorMap.rainbow()) \ No newline at end of file diff --git a/examples/01_batman/CMakeLists.txt b/examples/01_batman/CMakeLists.txt index 314b49ffc..cf89b0f69 100644 --- a/examples/01_batman/CMakeLists.txt +++ b/examples/01_batman/CMakeLists.txt @@ -8,16 +8,6 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# Adding IBEX - - # In case you installed IBEX in a local directory, you need - # to specify its path with the CMAKE_PREFIX_PATH option. - # set(CMAKE_PREFIX_PATH "~/ibex-lib/build_install") - - find_package(IBEX REQUIRED) - ibex_init_common() # IBEX should have installed this function - message(STATUS "Found IBEX version ${IBEX_VERSION}") - # Adding Codac # In case you installed Codac in a local directory, you need @@ -27,6 +17,10 @@ find_package(CODAC REQUIRED) message(STATUS "Found Codac version ${CODAC_VERSION}") +# Initializating Ibex + + ibex_init_common() + # Compilation if(FAST_RELEASE) @@ -37,4 +31,4 @@ add_executable(${PROJECT_NAME} main.cpp) target_compile_options(${PROJECT_NAME} PUBLIC ${CODAC_CXX_FLAGS}) target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CODAC_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} PUBLIC ${CODAC_LIBRARIES} Ibex::ibex) \ No newline at end of file + target_link_libraries(${PROJECT_NAME} PUBLIC ${CODAC_LIBRARIES}) \ No newline at end of file diff --git a/examples/02_centered_form/CMakeLists.txt b/examples/02_centered_form/CMakeLists.txt index 314b49ffc..cf89b0f69 100644 --- a/examples/02_centered_form/CMakeLists.txt +++ b/examples/02_centered_form/CMakeLists.txt @@ -8,16 +8,6 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# Adding IBEX - - # In case you installed IBEX in a local directory, you need - # to specify its path with the CMAKE_PREFIX_PATH option. - # set(CMAKE_PREFIX_PATH "~/ibex-lib/build_install") - - find_package(IBEX REQUIRED) - ibex_init_common() # IBEX should have installed this function - message(STATUS "Found IBEX version ${IBEX_VERSION}") - # Adding Codac # In case you installed Codac in a local directory, you need @@ -27,6 +17,10 @@ find_package(CODAC REQUIRED) message(STATUS "Found Codac version ${CODAC_VERSION}") +# Initializating Ibex + + ibex_init_common() + # Compilation if(FAST_RELEASE) @@ -37,4 +31,4 @@ add_executable(${PROJECT_NAME} main.cpp) target_compile_options(${PROJECT_NAME} PUBLIC ${CODAC_CXX_FLAGS}) target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CODAC_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} PUBLIC ${CODAC_LIBRARIES} Ibex::ibex) \ No newline at end of file + target_link_libraries(${PROJECT_NAME} PUBLIC ${CODAC_LIBRARIES}) \ No newline at end of file diff --git a/examples/03_sivia/CMakeLists.txt b/examples/03_sivia/CMakeLists.txt index 314b49ffc..cf89b0f69 100644 --- a/examples/03_sivia/CMakeLists.txt +++ b/examples/03_sivia/CMakeLists.txt @@ -8,16 +8,6 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# Adding IBEX - - # In case you installed IBEX in a local directory, you need - # to specify its path with the CMAKE_PREFIX_PATH option. - # set(CMAKE_PREFIX_PATH "~/ibex-lib/build_install") - - find_package(IBEX REQUIRED) - ibex_init_common() # IBEX should have installed this function - message(STATUS "Found IBEX version ${IBEX_VERSION}") - # Adding Codac # In case you installed Codac in a local directory, you need @@ -27,6 +17,10 @@ find_package(CODAC REQUIRED) message(STATUS "Found Codac version ${CODAC_VERSION}") +# Initializating Ibex + + ibex_init_common() + # Compilation if(FAST_RELEASE) @@ -37,4 +31,4 @@ add_executable(${PROJECT_NAME} main.cpp) target_compile_options(${PROJECT_NAME} PUBLIC ${CODAC_CXX_FLAGS}) target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CODAC_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} PUBLIC ${CODAC_LIBRARIES} Ibex::ibex) \ No newline at end of file + target_link_libraries(${PROJECT_NAME} PUBLIC ${CODAC_LIBRARIES}) \ No newline at end of file diff --git a/examples/04_explored_area/CMakeLists.txt b/examples/04_explored_area/CMakeLists.txt index 314b49ffc..cf89b0f69 100644 --- a/examples/04_explored_area/CMakeLists.txt +++ b/examples/04_explored_area/CMakeLists.txt @@ -8,16 +8,6 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# Adding IBEX - - # In case you installed IBEX in a local directory, you need - # to specify its path with the CMAKE_PREFIX_PATH option. - # set(CMAKE_PREFIX_PATH "~/ibex-lib/build_install") - - find_package(IBEX REQUIRED) - ibex_init_common() # IBEX should have installed this function - message(STATUS "Found IBEX version ${IBEX_VERSION}") - # Adding Codac # In case you installed Codac in a local directory, you need @@ -27,6 +17,10 @@ find_package(CODAC REQUIRED) message(STATUS "Found Codac version ${CODAC_VERSION}") +# Initializating Ibex + + ibex_init_common() + # Compilation if(FAST_RELEASE) @@ -37,4 +31,4 @@ add_executable(${PROJECT_NAME} main.cpp) target_compile_options(${PROJECT_NAME} PUBLIC ${CODAC_CXX_FLAGS}) target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CODAC_INCLUDE_DIRS}) - target_link_libraries(${PROJECT_NAME} PUBLIC ${CODAC_LIBRARIES} Ibex::ibex) \ No newline at end of file + target_link_libraries(${PROJECT_NAME} PUBLIC ${CODAC_LIBRARIES}) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2a3f79a44..e18427a99 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -63,8 +63,10 @@ find_library(CODAC_UNSUPPORTED_LIBRARY NAMES ${PROJECT_NAME}-unsupported PATH_SUFFIXES lib) + find_package(IBEX REQUIRED) + set(CODAC_VERSION ${PROJECT_VERSION}) - set(CODAC_LIBRARIES \${CODAC_CORE_LIBRARY} \${CODAC_GRAPHICS_LIBRARY} \${CODAC_UNSUPPORTED_LIBRARY} \${CODAC_CORE_LIBRARY}) + set(CODAC_LIBRARIES \${CODAC_CORE_LIBRARY} \${CODAC_GRAPHICS_LIBRARY} \${CODAC_UNSUPPORTED_LIBRARY} Ibex::ibex) set(CODAC_INCLUDE_DIRS \${CODAC_CORE_INCLUDE_DIR}/../ \${CODAC_CORE_INCLUDE_DIR}/../eigen3/ \${CODAC_CORE_INCLUDE_DIR} \${CODAC_GRAPHICS_INCLUDE_DIR} \${CODAC_UNSUPPORTED_INCLUDE_DIR}) set(CODAC_C_FLAGS \"\") @@ -108,6 +110,10 @@ endif() + file(APPEND ${CODAC_CMAKE_CONFIG_FILE} " + set(CODAC_LIBRARIES \${CODAC_LIBRARIES} \${CODAC_GRAPHICS_LIBRARY} \${CODAC_CORE_LIBRARY}) + ") + install(FILES ${CODAC_CMAKE_CONFIG_FILE} DESTINATION ${CMAKE_INSTALL_CMAKE}) diff --git a/src/unsupported/CMakeLists.txt b/src/unsupported/CMakeLists.txt index efe341957..6d3bd2b25 100644 --- a/src/unsupported/CMakeLists.txt +++ b/src/unsupported/CMakeLists.txt @@ -52,7 +52,6 @@ # Generating the file codac-unsupported.h set(CODAC_UNSUPPORTED_MAIN_HEADER ${CMAKE_CURRENT_BINARY_DIR}/codac-unsupported.h) - set(CODAC_MAIN_SUBHEADERS ${CODAC_MAIN_SUBHEADERS} "codac-unsupported.h" PARENT_SCOPE) file(WRITE ${CODAC_UNSUPPORTED_MAIN_HEADER} "/* This file is generated by CMake */\n\n") file(APPEND ${CODAC_UNSUPPORTED_MAIN_HEADER} "#pragma once\n\n") foreach(header_path ${CODAC_UNSUPPORTED_HDR})