diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index a305e855..ee4626e4 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -52,4 +52,53 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mathjax_stmaryrd.js endif() + endif() + +# User manual (Sphinx) + + find_package(Sphinx) + + if(NOT SPHINX_FOUND) + + message(STATUS "Sphinx not found, will not be able to generate the manual.") + + else() + + # Includes CMake commands in config file: + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/manual/conf.py.in ${CMAKE_CURRENT_BINARY_DIR}/manual/conf.py) + + set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/manual) + set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}/manual) + + # Copying _static files of Sphinx to build directories + foreach(static_file ${CMAKE_CURRENT_SOURCE_DIR}/manual/_static/) + file(COPY ${static_file} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/manual/_static/) + endforeach() + + # Copying tmp files + foreach(static_file ${CMAKE_CURRENT_SOURCE_DIR}/manual/tmp/) + file(COPY ${static_file} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/manual/tmp/) + endforeach() + + # todo: the SPHINX_EXECUTABLE is already set by FindSphinx.cmake: + # check that it works without the following overload for Win and Linux: + if(WIN32) + set(SPHINX_EXECUTABLE "sphinx-build") + else() + set(SPHINX_EXECUTABLE "python3" "-msphinx") + endif() + + add_custom_target(manual + COMMAND + ${SPHINX_EXECUTABLE} -b html + # Specifying path to conf.py generated by CMake: + -c ${CMAKE_CURRENT_BINARY_DIR}/manual/ + ${SPHINX_SOURCE} ${SPHINX_BUILD} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating the manual website using Sphinx") + + install(DIRECTORY ${SPHINX_BUILD}/ + DESTINATION share/manual/${CMAKE_PROJECT_NAME} + OPTIONAL) + endif() \ No newline at end of file diff --git a/doc/manual/_static/css/custom.css b/doc/manual/_static/css/custom.css new file mode 100644 index 00000000..bf36547f --- /dev/null +++ b/doc/manual/_static/css/custom.css @@ -0,0 +1,10 @@ +div.rst-content a:visited +{ + color: #2980b9; + text-decoration: none; +} + +div.rst-content li.toctree-l1 > a +{ + font-weight: bold; +} \ No newline at end of file diff --git a/doc/manual/_static/empty.txt b/doc/manual/_static/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/doc/manual/_templates/empty.txt b/doc/manual/_templates/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/doc/manual/conf.py.in b/doc/manual/conf.py.in new file mode 100644 index 00000000..e7d94dab --- /dev/null +++ b/doc/manual/conf.py.in @@ -0,0 +1,40 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'Codac' +copyright = 'Codac Team' +author = 'Codac Team' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + 'sphinx_rtd_theme', +] + +templates_path = ['_templates'] +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_static_path = ['_static'] +html_theme = "sphinx_rtd_theme" +html_logo = "_static/logos/logo_codac.svg" + +# These paths are either relative to html_static_path +# or fully qualified paths (eg. https://...) +html_css_files = [ + 'css/custom.css', +] + +html_theme_options = { + 'logo_only': True, + 'display_version': True, +} \ No newline at end of file diff --git a/doc/manual/index.rst b/doc/manual/index.rst new file mode 100644 index 00000000..460fb89b --- /dev/null +++ b/doc/manual/index.rst @@ -0,0 +1,51 @@ +Codac manual +============ + + +.. toctree:: + :caption: Overview of Codac + :maxdepth: 3 + + Constraint programming and IA + The Codac framework + Target audience + + +.. toctree:: + :caption: User manual + :maxdepth: 3 + + installation/index.rst + intervals/index.rst + linear/index.rst + functions/index.rst + tubes/index.rst + contractors/index.rst + separators/index.rst + pavers/index.rst + cn/index.rst + geometry/index.rst + ellipsoids/index.rst + topology/index.rst + visualization/index.rst + extensions/index.rst + seealso/index.rst + references/index.rst + + +.. toctree:: + :caption: How-to guides + :maxdepth: 3 + + howto/robotics/index.rst + howto/geometry/index.rst + howto/dynamical/index.rst + + +.. toctree:: + :caption: Development + :maxdepth: 3 + + Changelog + C++ API + Information for developers \ No newline at end of file diff --git a/doc/manual/tmp/empty.txt b/doc/manual/tmp/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/examples/00_graphics/graphic_examples.py b/examples/00_graphics/graphic_examples.py index ae9dcb45..b4089801 100644 --- a/examples/00_graphics/graphic_examples.py +++ b/examples/00_graphics/graphic_examples.py @@ -23,7 +23,7 @@ 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_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 fig2 = Figure2D("My figure 2", GraphicOutput.VIBES | GraphicOutput.IPE) @@ -44,5 +44,31 @@ 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)]) + +# Colors +# predefined colors without and with opacity fig2.draw_point([2,2], [Color.red(),Color.yellow(0.5)]) -fig2.draw_box([[2.4,2.9],[2.4,2.9]],[Color("#da3907"),Color("#da390755")]) \ No newline at end of file +# 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)]) +# RGB color auto cast from list without and with opacity +fig2.draw_box([[2.,2.3],[2.6,2.9]],[[255,0,255],[255,0,255,100]]) + +fig3 = Figure2D("ColorMap figure", 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]) + +cmap_haxby=ColorMap.haxby() +cmap_default=ColorMap.basic() +cmap_blue_tube=ColorMap.blue_tube() +cmap_red_tube=ColorMap.red_tube() +cmap_rainbow=ColorMap.rainbow() + +for i in range (20): + 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)]) \ No newline at end of file diff --git a/doc/doc/tutorial-set4most/01-examples/index.rst b/prev_versions/v1.5.2/doc/doc/tutorial-set4most/01-examples/index.rst similarity index 100% rename from doc/doc/tutorial-set4most/01-examples/index.rst rename to prev_versions/v1.5.2/doc/doc/tutorial-set4most/01-examples/index.rst diff --git a/doc/doc/tutorial-set4most/01-examples/range-only-loc.py b/prev_versions/v1.5.2/doc/doc/tutorial-set4most/01-examples/range-only-loc.py similarity index 100% rename from doc/doc/tutorial-set4most/01-examples/range-only-loc.py rename to prev_versions/v1.5.2/doc/doc/tutorial-set4most/01-examples/range-only-loc.py diff --git a/doc/doc/tutorial-set4most/01-examples/slam.py b/prev_versions/v1.5.2/doc/doc/tutorial-set4most/01-examples/slam.py similarity index 100% rename from doc/doc/tutorial-set4most/01-examples/slam.py rename to prev_versions/v1.5.2/doc/doc/tutorial-set4most/01-examples/slam.py diff --git a/doc/doc/tutorial-set4most/01-examples/triskelion.py b/prev_versions/v1.5.2/doc/doc/tutorial-set4most/01-examples/triskelion.py similarity index 100% rename from doc/doc/tutorial-set4most/01-examples/triskelion.py rename to prev_versions/v1.5.2/doc/doc/tutorial-set4most/01-examples/triskelion.py diff --git a/doc/doc/tutorial-set4most/01-examples/walls-loc.py b/prev_versions/v1.5.2/doc/doc/tutorial-set4most/01-examples/walls-loc.py similarity index 100% rename from doc/doc/tutorial-set4most/01-examples/walls-loc.py rename to prev_versions/v1.5.2/doc/doc/tutorial-set4most/01-examples/walls-loc.py diff --git a/doc/doc/tutorial-set4most/index.rst b/prev_versions/v1.5.2/doc/doc/tutorial-set4most/index.rst similarity index 100% rename from doc/doc/tutorial-set4most/index.rst rename to prev_versions/v1.5.2/doc/doc/tutorial-set4most/index.rst diff --git a/python/src/graphics/CMakeLists.txt b/python/src/graphics/CMakeLists.txt index 29bd2047..8b5add11 100644 --- a/python/src/graphics/CMakeLists.txt +++ b/python/src/graphics/CMakeLists.txt @@ -12,6 +12,7 @@ paver/codac2_py_drawwhilepaving.cpp styles/codac2_py_Color.cpp + styles/codac2_py_ColorMap.cpp styles/codac2_py_StyleProperties.cpp ) diff --git a/python/src/graphics/codac2_py_graphics.cpp b/python/src/graphics/codac2_py_graphics.cpp index 5ae28b1d..c5f9b520 100644 --- a/python/src/graphics/codac2_py_graphics.cpp +++ b/python/src/graphics/codac2_py_graphics.cpp @@ -22,6 +22,7 @@ void export_drawwhilepaving(py::module& m); // styles void export_Color(py::module& m); +void export_ColorMap(py::module& m); void export_StyleProperties(py::module& m); @@ -31,6 +32,7 @@ PYBIND11_MODULE(_graphics, m) // styles export_Color(m); + export_ColorMap(m); export_StyleProperties(m); // figures diff --git a/python/src/graphics/figures/codac2_py_Figure2D.cpp b/python/src/graphics/figures/codac2_py_Figure2D.cpp index d72d33c1..aedc6482 100644 --- a/python/src/graphics/figures/codac2_py_Figure2D.cpp +++ b/python/src/graphics/figures/codac2_py_Figure2D.cpp @@ -136,6 +136,16 @@ void export_Figure2D(py::module& m) VOID_FIGURE2D_DRAW_AUV_CONST_VECTOR_REF_FLOAT_CONST_STYLEPROPERTIES_REF, "x"_a, "size"_a, "s"_a=StyleProperties()) + // Pavings + + .def("draw_paving", (void(Figure2D::*)(const PavingOut&,const StyleProperties&,const StyleProperties&))&Figure2D::draw_paving, + VOID_FIGURE2D_DRAW_PAVING_CONST_PAVINGOUT_REF_CONST_STYLEPROPERTIES_REF_CONST_STYLEPROPERTIES_REF, + "p"_a, "boundary_style"_a=StyleProperties::boundary(), "outside_style"_a=StyleProperties::outside()) + + .def("draw_paving", (void(Figure2D::*)(const PavingInOut&,const StyleProperties&,const StyleProperties&,const StyleProperties&))&Figure2D::draw_paving, + VOID_FIGURE2D_DRAW_PAVING_CONST_PAVINGINOUT_REF_CONST_STYLEPROPERTIES_REF_CONST_STYLEPROPERTIES_REF_CONST_STYLEPROPERTIES_REF, + "p"_a, "boundary_style"_a=StyleProperties::boundary(), "outside_style"_a=StyleProperties::outside(), "inside_style"_a=StyleProperties::inside()) + ; py::class_ exported_default_view(m, "DefaultView", DEFAULTVIEW_MAIN); diff --git a/python/src/graphics/styles/codac2_py_Color.cpp b/python/src/graphics/styles/codac2_py_Color.cpp index 2227835e..d960b3ac 100644 --- a/python/src/graphics/styles/codac2_py_Color.cpp +++ b/python/src/graphics/styles/codac2_py_Color.cpp @@ -19,29 +19,60 @@ using namespace codac2; namespace py = pybind11; using namespace pybind11::literals; + void export_Color(py::module& m) { + + py::enum_(m, "Model") + .value("RGB", Model::RGB) + .value("HSV", Model::HSV) + ; + py::class_ exported_color(m, "Color", COLOR_MAIN); exported_color + + .def(py::init<>(),COLOR_COLOR) - .def_readwrite("r", &Color::r) - .def_readwrite("g", &Color::g) - .def_readwrite("b", &Color::b) - .def_readwrite("alpha", &Color::alpha) - .def_readwrite("hex_str", &Color::hex_str) + .def(py::init&,Model>(), + COLOR_COLOR_CONST_ARRAY_FLOAT3_REF_MODEL, + "xyz"_a, "m_"_a=Model::RGB) - .def(py::init(), - COLOR_COLOR_INT_INT_INT_INT, - "r"_a, "g"_a, "b"_a, "alpha"_a=255) - - .def(py::init(), - COLOR_COLOR_FLOAT_FLOAT_FLOAT_FLOAT, - "r"_a, "g"_a, "b"_a, "alpha"_a=1.) + .def(py::init&,Model>(), + COLOR_COLOR_CONST_ARRAY_FLOAT4_REF_MODEL, + "xyza"_a, "m_"_a=Model::RGB) .def(py::init(), COLOR_COLOR_CONST_STRING_REF, "hex_str"_a) + .def("model", &Color::model, + CONST_MODEL_REF_COLOR_MODEL_CONST) + + + // Other formats + + .def("hex_str", &Color::hex_str, + STRING_COLOR_HEX_STR_CONST) + + .def("vec", &Color::vec, + VECTOR_COLOR_VEC_CONST) + + // Conversions + + .def("rgb", &Color::rgb, + COLOR_COLOR_RGB_CONST) + + .def("hsv", &Color::hsv, + COLOR_COLOR_HSV_CONST) + + // Overload flux operator + + .def("__str__", [](const Color& c) { + std::ostringstream oss; + oss << c; + return oss.str(); + }) + // Predefined colors .def_static("none", &Color::none, @@ -79,4 +110,6 @@ void export_Color(py::module& m) STATIC_COLOR_COLOR_DARK_GRAY_FLOAT, "alpha"_a=1.) ; + + py::implicitly_convertible(); } \ No newline at end of file diff --git a/python/src/graphics/styles/codac2_py_ColorMap.cpp b/python/src/graphics/styles/codac2_py_ColorMap.cpp new file mode 100644 index 00000000..e127777e --- /dev/null +++ b/python/src/graphics/styles/codac2_py_ColorMap.cpp @@ -0,0 +1,55 @@ +/** + * Codac binding (core) + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou, Maël Godard + * \copyright Copyright 2024 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#include +#include +#include +#include +#include "codac2_py_ColorMap_docs.h" // Generated file from Doxygen XML (doxygen2docstring.py): + +using namespace std; +using namespace codac2; +namespace py = pybind11; +using namespace pybind11::literals; + +void export_ColorMap(py::module& m) +{ + py::class_ exported_colormap(m, "ColorMap", COLORMAP_MAIN); + exported_colormap + + .def(py::init(), + COLORMAP_COLORMAP_MODEL, + "m"_a=Model::RGB) + + .def("model", &ColorMap::model, + CONST_MODEL_REF_COLORMAP_MODEL_CONST) + + .def("color", &ColorMap::color, + COLOR_COLORMAP_COLOR_FLOAT_CONST, + "r"_a) + + // Predifined color maps + + .def_static("haxby", &ColorMap::haxby, + STATIC_COLORMAP_COLORMAP_HAXBY) + + .def_static("basic", &ColorMap::basic, + STATIC_COLORMAP_COLORMAP_BASIC) + + .def_static("blue_tube", &ColorMap::blue_tube, + STATIC_COLORMAP_COLORMAP_BLUE_TUBE) + + .def_static("red_tube", &ColorMap::red_tube, + STATIC_COLORMAP_COLORMAP_RED_TUBE) + + .def_static("rainbow", &ColorMap::rainbow, + STATIC_COLORMAP_COLORMAP_RAINBOW) + + ; +} \ No newline at end of file diff --git a/scripts/CMakeModules/FindSphinx.cmake b/scripts/CMakeModules/FindSphinx.cmake new file mode 100644 index 00000000..6190fa01 --- /dev/null +++ b/scripts/CMakeModules/FindSphinx.cmake @@ -0,0 +1,20 @@ +include(FindPackageHandleStandardArgs) + +# We are likely to find Sphinx near the Python interpreter +find_package(PythonInterp) +if(PYTHONINTERP_FOUND) + get_filename_component(_PYTHON_DIR "${PYTHON_EXECUTABLE}" DIRECTORY) + set( + _PYTHON_PATHS + "${_PYTHON_DIR}" + "${_PYTHON_DIR}/bin" + "${_PYTHON_DIR}/Scripts") +endif() + +find_program( + SPHINX_EXECUTABLE + NAMES sphinx-build sphinx-build.exe + HINTS ${_PYTHON_PATHS}) +mark_as_advanced(SPHINX_EXECUTABLE) + +find_package_handle_standard_args(Sphinx DEFAULT_MSG SPHINX_EXECUTABLE) \ No newline at end of file diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index a323bb92..986b0ed2 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -50,7 +50,6 @@ ${CMAKE_CURRENT_SOURCE_DIR}/domains/codac2_BoolInterval.h ${CMAKE_CURRENT_SOURCE_DIR}/domains/codac2_Domain.h - ${CMAKE_CURRENT_SOURCE_DIR}/domains/interval/codac2_Interval.cpp ${CMAKE_CURRENT_SOURCE_DIR}/domains/interval/codac2_Interval.h ${CMAKE_CURRENT_SOURCE_DIR}/domains/interval/codac2_Interval_operations.cpp ${CMAKE_CURRENT_SOURCE_DIR}/domains/interval/codac2_Interval_operations.h diff --git a/src/core/domains/interval/codac2_Interval.cpp b/src/core/domains/interval/codac2_Interval.cpp deleted file mode 100644 index 7f53d83b..00000000 --- a/src/core/domains/interval/codac2_Interval.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/** - * codac2_Interval.cpp - * - * This class reuses several functions developed for ibex::Interval. - * The original IBEX code is encapsulated in Codac for allowing inheritance - * to Codac classes and also for documentation, binding, and independency purposes. - * See ibex::Interval (IBEX lib, main author: Gilles Chabert) - * https://ibex-lib.readthedocs.io - * - * ---------------------------------------------------------------------------- - * \date 2024 - * \author Gilles Chabert, Simon Rohou - * \copyright Copyright 2024 Codac Team - * \license GNU Lesser General Public License (LGPL) - */ - -#include -#include -#include "codac2_Interval.h" -#include "codac2_assert.h" - -using namespace std; - -namespace codac2 -{ - Interval::Interval() - : ibex::Interval() - { } - - Interval::Interval(double a) - : ibex::Interval(a) - { } - - Interval::Interval(double a, double b) - : ibex::Interval(a,b) - { } - - Interval::Interval(const Interval& x) - : ibex::Interval(x) - { } - - Interval::Interval(array array) - : ibex::Interval(array) - { } - - Interval::Interval(array array) - : ibex::Interval(array) - { } - - Interval::Interval(std::initializer_list l) - : Interval() - { - init_from_list(l); - } - - Interval& Interval::init(const Interval& x) - { - *this = x; - return *this; - } - - Interval& Interval::init_from_list(const std::list& l) - { - assert_release((l.size() == 1 || l.size() == 2) - && "'Interval' can only be defined by one or two 'double' values."); - *this = Interval(*l.begin(),*std::prev(l.end())); - return *this; - } - - Interval& Interval::operator=(const Interval& x) - { - ibex::Interval::operator=(x); - return *this; - } - - bool Interval::operator==(const Interval& x) const - { - return ibex::Interval::operator==(x); - } - - bool Interval::operator!=(const Interval& x) const - { - return ibex::Interval::operator!=(x); - } - - double Interval::lb() const - { - return ibex::Interval::lb(); - } - - double Interval::ub() const - { - return ibex::Interval::ub(); - } - - double Interval::mid() const - { - return ibex::Interval::mid(); - } - - double Interval::mag() const - { - return ibex::Interval::mag(); - } - - double Interval::mig() const - { - return ibex::Interval::mig(); - } - - double Interval::rand() const - { - if(is_empty()) - return std::numeric_limits::quiet_NaN(); - - double a = max(next_float(-oo),lb()); - double b = min(previous_float(oo),ub()); - return a + (((double)std::rand())/(double)RAND_MAX)*(b-a); - } - - double Interval::rad() const - { - return ibex::Interval::rad(); - } - - double Interval::diam() const - { - return ibex::Interval::diam(); - } - - double Interval::volume() const - { - return ibex::Interval::diam(); - } - - Index Interval::size() const - { - return 1; - } - - void Interval::set_empty() - { - ibex::Interval::set_empty(); - } - - bool Interval::is_empty() const - { - return ibex::Interval::is_empty(); - } - - bool Interval::contains(const double& x) const - { - return ibex::Interval::contains(x); - } - - bool Interval::interior_contains(const double& x) const - { - return ibex::Interval::interior_contains(x); - } - - bool Interval::is_unbounded() const - { - return ibex::Interval::is_unbounded(); - } - - bool Interval::is_degenerated() const - { - return ibex::Interval::is_degenerated(); - } - - bool Interval::intersects(const Interval &x) const - { - return ibex::Interval::intersects(x); - } - - bool Interval::is_disjoint(const Interval& x) const - { - return ibex::Interval::is_disjoint(x); - } - - bool Interval::overlaps(const Interval& x) const - { - return ibex::Interval::overlaps(x); - } - - bool Interval::is_subset(const Interval& x) const - { - return ibex::Interval::is_subset(x); - } - - bool Interval::is_strict_subset(const Interval& x) const - { - return ibex::Interval::is_strict_subset(x); - } - - bool Interval::is_interior_subset(const Interval& x) const - { - return ibex::Interval::is_interior_subset(x); - } - - bool Interval::is_strict_interior_subset(const Interval& x) const - { - return ibex::Interval::is_strict_interior_subset(x); - } - - bool Interval::is_superset(const Interval& x) const - { - return ibex::Interval::is_superset(x); - } - - bool Interval::is_strict_superset(const Interval& x) const - { - return ibex::Interval::is_strict_superset(x); - } - - Interval& Interval::inflate(const double& rad) - { - ibex::Interval::inflate(rad); - return *this; - } - - bool Interval::is_bisectable() const - { - return ibex::Interval::is_bisectable(); - } - - pair Interval::bisect(float ratio) const - { - assert_release(Interval(0,1).interior_contains(ratio)); - auto p = ibex::Interval::bisect(ratio); - return { p.first, p.second }; - } - - vector Interval::complementary(bool compactness) const - { - if(is_empty() || (compactness && is_degenerated())) - return { {-oo,oo} }; - - vector l; - - if(lb() > -oo) - l.push_back({-oo,lb()}); - - if(ub() < oo) - l.push_back({ub(),oo}); - - return l; - } - - vector Interval::diff(const Interval& y, bool compactness) const - { - if(compactness && is_degenerated()) - { - if(is_empty() || y.contains(lb())) - return {}; - else - return { *this }; - } - - vector l; - for(const auto& li : y.complementary(compactness)) - { - Interval inter = li & *this; - if(!inter.is_degenerated()) - l.push_back(inter); - } - - return l; - } - - Interval& Interval::operator|=(const Interval& x) - { - ibex::Interval::operator|=(x); - return *this; - } - - Interval& Interval::operator&=(const Interval& x) - { - ibex::Interval::operator&=(x); - return *this; - } - - Interval& Interval::operator+=(double x) - { - ibex::Interval::operator+=(x); - return *this; - } - - Interval& Interval::operator+=(const Interval& x) - { - ibex::Interval::operator+=(x); - return *this; - } - - Interval Interval::operator-() const - { - return 0.-*this; - } - - Interval& Interval::operator-=(double x) - { - ibex::Interval::operator-=(x); - return *this; - } - - Interval& Interval::operator-=(const Interval& x) - { - ibex::Interval::operator-=(x); - return *this; - } - - Interval& Interval::operator*=(double x) - { - ibex::Interval::operator*=(x); - return *this; - } - - Interval& Interval::operator*=(const Interval& x) - { - ibex::Interval::operator*=(x); - return *this; - } - - Interval& Interval::operator/=(double x) - { - ibex::Interval::operator/=(x); - return *this; - } - - Interval& Interval::operator/=(const Interval& x) - { - ibex::Interval::operator/=(x); - return *this; - } - - Interval Interval::empty() - { - return ibex::Interval::empty_set(); - } - - Interval Interval::zero() - { - return ibex::Interval::zero(); - } - - Interval Interval::zeros() - { - return ibex::Interval::zero(); - } - - Interval Interval::one() - { - return ibex::Interval::one(); - } - - Interval Interval::ones() - { - return ibex::Interval::one(); - } - - Interval Interval::half_pi() - { - return ibex::Interval::half_pi(); - } - - Interval Interval::pi() - { - return ibex::Interval::pi(); - } - - Interval Interval::two_pi() - { - return ibex::Interval::two_pi(); - } - - ostream& operator<<(ostream& os, const Interval& x) - { - gaol::interval::precision(os.precision()); - ibex::operator<<(os,x); - return os; - } - - Interval::Interval(const ibex::Interval& x) - : ibex::Interval(x) - { } - - Interval operator""_i(long double x) - { - return Interval(x); - } - -} // namespace codac diff --git a/src/core/domains/interval/codac2_Interval.h b/src/core/domains/interval/codac2_Interval.h index aa6f69a0..80730c8c 100644 --- a/src/core/domains/interval/codac2_Interval.h +++ b/src/core/domains/interval/codac2_Interval.h @@ -21,6 +21,7 @@ #include #include "codac2_Index.h" #include "codac2_Domain.h" +#include "codac2_assert.h" namespace codac2 { @@ -511,44 +512,60 @@ namespace codac2 * * \return an empty set */ - static Interval empty(); + static Interval empty() + { + return ibex::Interval::empty_set(); + } /** * \brief Provides an interval for \f$[0]\f$ * * \return an interval containing \f$0\f$ */ - static Interval zero(); - static Interval zeros(); + static Interval zero() + { + return ibex::Interval::zero(); + } /** * \brief Provides an interval for \f$[1]\f$ * * \return an interval containing \f$1\f$ */ - static Interval one(); - static Interval ones(); + static Interval one() + { + return ibex::Interval::one(); + } /** * \brief Provides an interval for \f$[\frac{\pi}{2}]\f$ * * \return an interval containing \f$\frac{\pi}{2}\f$ */ - static Interval half_pi(); + static Interval half_pi() + { + return ibex::Interval::half_pi(); + } /** * \brief Provides an interval for \f$[\pi]\f$ * * \return an interval containing \f$\pi\f$ */ - static Interval pi(); + static Interval pi() + { + return ibex::Interval::pi(); + } /** * \brief Provides an interval for \f$[2\pi]\f$ * * \return an interval containing \f$2\pi\f$ */ - static Interval two_pi(); + static Interval two_pi() + { + return ibex::Interval::two_pi(); + } friend std::ostream& operator<<(std::ostream& os, const Interval& x); @@ -680,3 +697,374 @@ namespace codac2 return ibex::next_float(x); } } + +// Inline functions + +namespace codac2 +{ + inline Interval::Interval() + : ibex::Interval() + { } + + inline Interval::Interval(double a) + : ibex::Interval(a) + { } + + inline Interval::Interval(double a, double b) + : ibex::Interval(a,b) + { } + + inline Interval::Interval(const Interval& x) + : ibex::Interval(x) + { } + + inline Interval::Interval(std::array array) + : ibex::Interval(array) + { } + + inline Interval::Interval(std::array array) + : ibex::Interval(array) + { } + + inline Interval::Interval(std::initializer_list l) + : Interval() + { + init_from_list(l); + } + + inline Interval& Interval::init(const Interval& x) + { + *this = x; + return *this; + } + + inline Interval& Interval::init_from_list(const std::list& l) + { + assert_release((l.size() == 1 || l.size() == 2) + && "'Interval' can only be defined by one or two 'double' values."); + *this = Interval(*l.begin(),*std::prev(l.end())); + return *this; + } + + inline Interval& Interval::operator=(const Interval& x) + { + ibex::Interval::operator=(x); + return *this; + } + + inline bool Interval::operator==(const Interval& x) const + { + return ibex::Interval::operator==(x); + } + + inline bool Interval::operator!=(const Interval& x) const + { + return ibex::Interval::operator!=(x); + } + + inline double Interval::lb() const + { + return ibex::Interval::lb(); + } + + inline double Interval::ub() const + { + return ibex::Interval::ub(); + } + + inline double Interval::mid() const + { + return ibex::Interval::mid(); + } + + inline double Interval::mag() const + { + return ibex::Interval::mag(); + } + + inline double Interval::mig() const + { + return ibex::Interval::mig(); + } + + inline double Interval::rand() const + { + if(is_empty()) + return std::numeric_limits::quiet_NaN(); + + double a = std::max(next_float(-oo),lb()); + double b = std::min(previous_float(oo),ub()); + return a + (((double)std::rand())/(double)RAND_MAX)*(b-a); + } + + inline double Interval::rad() const + { + return ibex::Interval::rad(); + } + + inline double Interval::diam() const + { + return ibex::Interval::diam(); + } + + inline double Interval::volume() const + { + return ibex::Interval::diam(); + } + + inline Index Interval::size() const + { + return 1; + } + + inline void Interval::set_empty() + { + ibex::Interval::set_empty(); + } + + inline bool Interval::is_empty() const + { + return ibex::Interval::is_empty(); + } + + inline bool Interval::contains(const double& x) const + { + return ibex::Interval::contains(x); + } + + inline bool Interval::interior_contains(const double& x) const + { + return ibex::Interval::interior_contains(x); + } + + inline bool Interval::is_unbounded() const + { + return ibex::Interval::is_unbounded(); + } + + inline bool Interval::is_degenerated() const + { + return ibex::Interval::is_degenerated(); + } + + inline bool Interval::intersects(const Interval &x) const + { + return ibex::Interval::intersects(x); + } + + inline bool Interval::is_disjoint(const Interval& x) const + { + return ibex::Interval::is_disjoint(x); + } + + inline bool Interval::overlaps(const Interval& x) const + { + return ibex::Interval::overlaps(x); + } + + inline bool Interval::is_subset(const Interval& x) const + { + return ibex::Interval::is_subset(x); + } + + inline bool Interval::is_strict_subset(const Interval& x) const + { + return ibex::Interval::is_strict_subset(x); + } + + inline bool Interval::is_interior_subset(const Interval& x) const + { + return ibex::Interval::is_interior_subset(x); + } + + inline bool Interval::is_strict_interior_subset(const Interval& x) const + { + return ibex::Interval::is_strict_interior_subset(x); + } + + inline bool Interval::is_superset(const Interval& x) const + { + return ibex::Interval::is_superset(x); + } + + inline bool Interval::is_strict_superset(const Interval& x) const + { + return ibex::Interval::is_strict_superset(x); + } + + inline Interval& Interval::inflate(const double& rad) + { + ibex::Interval::inflate(rad); + return *this; + } + + inline bool Interval::is_bisectable() const + { + return ibex::Interval::is_bisectable(); + } + + inline std::pair Interval::bisect(float ratio) const + { + assert_release(Interval(0,1).interior_contains(ratio)); + auto p = ibex::Interval::bisect(ratio); + return { p.first, p.second }; + } + + inline std::vector Interval::complementary(bool compactness) const + { + if(is_empty() || (compactness && is_degenerated())) + return { {-oo,oo} }; + + std::vector l; + + if(lb() > -oo) + l.push_back({-oo,lb()}); + + if(ub() < oo) + l.push_back({ub(),oo}); + + return l; + } + + inline std::vector Interval::diff(const Interval& y, bool compactness) const + { + if(compactness && is_degenerated()) + { + if(is_empty() || y.contains(lb())) + return {}; + else + return { *this }; + } + + std::vector l; + for(const auto& li : y.complementary(compactness)) + { + Interval inter = li & *this; + if(!inter.is_degenerated()) + l.push_back(inter); + } + + return l; + } + + inline Interval& Interval::operator|=(const Interval& x) + { + ibex::Interval::operator|=(x); + return *this; + } + + inline Interval& Interval::operator&=(const Interval& x) + { + ibex::Interval::operator&=(x); + return *this; + } + + inline Interval& Interval::operator+=(double x) + { + ibex::Interval::operator+=(x); + return *this; + } + + inline Interval& Interval::operator+=(const Interval& x) + { + ibex::Interval::operator+=(x); + return *this; + } + + inline Interval Interval::operator-() const + { + return 0.-*this; + } + + inline Interval& Interval::operator-=(double x) + { + ibex::Interval::operator-=(x); + return *this; + } + + inline Interval& Interval::operator-=(const Interval& x) + { + ibex::Interval::operator-=(x); + return *this; + } + + inline Interval& Interval::operator*=(double x) + { + ibex::Interval::operator*=(x); + return *this; + } + + inline Interval& Interval::operator*=(const Interval& x) + { + ibex::Interval::operator*=(x); + return *this; + } + + inline Interval& Interval::operator/=(double x) + { + ibex::Interval::operator/=(x); + return *this; + } + + inline Interval& Interval::operator/=(const Interval& x) + { + ibex::Interval::operator/=(x); + return *this; + } + + /*static inline Interval Interval::empty() + { + return ibex::Interval::empty_set(); + } + + static inline Interval Interval::zero() + { + return ibex::Interval::zero(); + } + + static inline Interval Interval::zeros() + { + return ibex::Interval::zero(); + } + + static inline Interval Interval::one() + { + return ibex::Interval::one(); + } + + static inline Interval Interval::ones() + { + return ibex::Interval::one(); + } + + static inline Interval Interval::half_pi() + { + return ibex::Interval::half_pi(); + } + + static inline Interval Interval::pi() + { + return ibex::Interval::pi(); + } + + static inline Interval Interval::two_pi() + { + return ibex::Interval::two_pi(); + }*/ + + inline std::ostream& operator<<(std::ostream& os, const Interval& x) + { + gaol::interval::precision(os.precision()); + ibex::operator<<(os,x); + return os; + } + + inline Interval::Interval(const ibex::Interval& x) + : ibex::Interval(x) + { } + + inline Interval operator""_i(long double x) + { + return Interval(x); + } +} \ No newline at end of file diff --git a/src/core/domains/interval/codac2_Interval_operations.cpp b/src/core/domains/interval/codac2_Interval_operations.cpp index 9af5818a..8b1ce5ac 100644 --- a/src/core/domains/interval/codac2_Interval_operations.cpp +++ b/src/core/domains/interval/codac2_Interval_operations.cpp @@ -21,245 +21,13 @@ using namespace std; namespace codac2 { - const Interval& operator+(const Interval& x) + Interval operator-(double x, const Interval& y) { - return x; + return ibex::operator-(x, y); } - #define interval_arithm_op(f) \ - Interval f(const Interval& x, const Interval& y) \ - { \ - return ibex::f(x, y); \ - } \ - Interval f(double x, const Interval& y) \ - { \ - return ibex::f(x, y); \ - } \ - Interval f(const Interval& x, double y) \ - { \ - return ibex::f(x, y); \ - } \ - - interval_arithm_op(operator&) - interval_arithm_op(operator|) - interval_arithm_op(operator+) - interval_arithm_op(operator-) - interval_arithm_op(operator*) - interval_arithm_op(operator/) - - #define unary_interval_op(f) \ - Interval f(const Interval& x) \ - { \ - return ibex::f(x); \ - } \ - - #define binary_interval_op(f) \ - Interval f(const Interval& x, const Interval& y) \ - { \ - return ibex::f(x, y); \ - } \ - - unary_interval_op(sqr) - unary_interval_op(sqrt) - - Interval pow(const Interval& x, int n) - { - return ibex::pow(x, n); - } - - Interval pow(const Interval& x, double d) - { - return ibex::pow(x, d); - } - - binary_interval_op(pow) - - Interval root(const Interval& x, int n) - { - return ibex::root(x, n); - } - - unary_interval_op(exp) - unary_interval_op(log) - unary_interval_op(cos) - unary_interval_op(sin) - unary_interval_op(tan) - unary_interval_op(acos) - unary_interval_op(asin) - unary_interval_op(atan) - binary_interval_op(atan2) - unary_interval_op(cosh) - unary_interval_op(sinh) - unary_interval_op(tanh) - unary_interval_op(acosh) - unary_interval_op(asinh) - unary_interval_op(atanh) - unary_interval_op(abs) - binary_interval_op(min) - binary_interval_op(max) - unary_interval_op(sign) - unary_interval_op(integer) - unary_interval_op(floor) - unary_interval_op(ceil) - - void bwd_add(const Interval& y, Interval& x1, Interval& x2) - { - ibex::bwd_add(y,x1,x2); - } - - void bwd_sub(const Interval& y, Interval& x1, Interval& x2) - { - ibex::bwd_sub(y,x1,x2); - } - - void bwd_mul(const Interval& y, Interval& x1, Interval& x2) - { - ibex::bwd_mul(y,x1,x2); - } - - void bwd_div(const Interval& y, Interval& x1, Interval& x2) - { - ibex::bwd_div(y,x1,x2); - } - - void bwd_sqr(const Interval& y, Interval& x) - { - ibex::bwd_sqr(y,x); - } - - void bwd_sqrt(const Interval& y, Interval& x) - { - ibex::bwd_sqrt(y,x); - } - - void bwd_pow(const Interval& y, Interval& x, int p) - { - ibex::bwd_pow(y,p,x); - } - - void bwd_pow(const Interval& y, Interval& x, Interval& p) - { - assert(p.is_degenerated() && "bwd_power(y,x1,x2) (with x1 and x2 intervals) not implemented yet with Gaol"); - ibex::bwd_pow(y,p.mid(),x); - } - - void bwd_root(const Interval& y, Interval& x, int p) - { - ibex::bwd_root(y,p,x); - } - - void bwd_exp(const Interval& y, Interval& x) - { - ibex::bwd_exp(y,x); - } - - void bwd_log(const Interval& y, Interval& x) - { - ibex::bwd_log(y,x); - } - - void bwd_cos(const Interval& y, Interval& x) - { - ibex::bwd_cos(y,x); - } - - void bwd_sin(const Interval& y, Interval& x) - { - ibex::bwd_sin(y,x); - } - - void bwd_tan(const Interval& y, Interval& x) - { - ibex::bwd_tan(y,x); - } - - void bwd_acos(const Interval& y, Interval& x) - { - ibex::bwd_acos(y,x); - } - - void bwd_asin(const Interval& y, Interval& x) - { - ibex::bwd_asin(y,x); - } - - void bwd_atan(const Interval& y, Interval& x) - { - ibex::bwd_atan(y,x); - } - - void bwd_atan2(const Interval& y, Interval& x1, Interval& x2) - { - ibex::bwd_atan2(y,x1,x2); - } - - void bwd_cosh(const Interval& y, Interval& x) - { - ibex::bwd_cosh(y,x); - } - - void bwd_sinh(const Interval& y, Interval& x) - { - ibex::bwd_sinh(y,x); - } - - void bwd_tanh(const Interval& y, Interval& x) - { - ibex::bwd_tanh(y,x); - } - - void bwd_acosh(const Interval& y, Interval& x) - { - ibex::bwd_acosh(y,x); - } - - void bwd_asinh(const Interval& y, Interval& x) - { - ibex::bwd_asinh(y,x); - } - - void bwd_atanh(const Interval& y, Interval& x) - { - ibex::bwd_atanh(y,x); - } - - void bwd_abs(const Interval& y, Interval& x) - { - ibex::bwd_abs(y,x); - } - - void bwd_min(const Interval& y, Interval& x1, Interval& x2) - { - ibex::bwd_min(y,x1,x2); - } - - void bwd_max(const Interval& y, Interval& x1, Interval& x2) - { - ibex::bwd_max(y,x1,x2); - } - - void bwd_sign(const Interval& y, Interval& x) - { - ibex::bwd_sign(y,x); - } - - void bwd_floor(const Interval& y, Interval& x) - { - ibex::bwd_floor(y,x); - } - - void bwd_ceil(const Interval& y, Interval& x) - { - ibex::bwd_ceil(y,x); - } - - void bwd_saw(const Interval& y, Interval& x) - { - ibex::bwd_saw(y,x); - } - - void bwd_imod(Interval& x, Interval& y, double p) + Interval operator-(const Interval& x, double y) { - ibex::bwd_imod(x,y,p); + return ibex::operator-(x, y); } -} // namespace codac \ No newline at end of file +} \ No newline at end of file diff --git a/src/core/domains/interval/codac2_Interval_operations.h b/src/core/domains/interval/codac2_Interval_operations.h index 10cb3094..3a27fd10 100644 --- a/src/core/domains/interval/codac2_Interval_operations.h +++ b/src/core/domains/interval/codac2_Interval_operations.h @@ -29,7 +29,10 @@ namespace codac2 * \param y interval value * \return intersection result */ - Interval operator&(const Interval& x, const Interval& y); + inline Interval operator&(const Interval& x, const Interval& y) + { + return ibex::operator&(x,y); + } /** * \brief Returns the squared-union of two intervals: \f$[x]\sqcup[y]\f$ @@ -40,7 +43,10 @@ namespace codac2 * \param y interval value * \return squared-union result */ - Interval operator|(const Interval& x, const Interval& y); + inline Interval operator|(const Interval& x, const Interval& y) + { + return ibex::operator|(x,y); + } /** * \brief Returns this @@ -50,7 +56,10 @@ namespace codac2 * \param x interval value * \return the same interval */ - const Interval& operator+(const Interval& x); + inline const Interval& operator+(const Interval& x) + { + return x; + } /** * \brief Returns \f$[x]+y\f$ with \f$y\in\mathbb{R}\f$ @@ -59,7 +68,10 @@ namespace codac2 * \param y real value * \return the addition result */ - Interval operator+(const Interval& x, double y); + inline Interval operator+(const Interval& x, double y) + { + return ibex::operator+(x,y); + } /** * \brief Returns \f$x+[y]\f$ with \f$x\in\mathbb{R}\f$ @@ -68,7 +80,10 @@ namespace codac2 * \param y interval value * \return the addition result */ - Interval operator+(double x, const Interval& y); + inline Interval operator+(double x, const Interval& y) + { + return ibex::operator+(x,y); + } /** * \brief Returns \f$[x]+[y]\f$ @@ -77,7 +92,10 @@ namespace codac2 * \param y interval value * \return the addition result */ - Interval operator+(const Interval& x, const Interval& y); + inline Interval operator+(const Interval& x, const Interval& y) + { + return ibex::operator+(x,y); + } /** * \brief Returns \f$[x]-y\f$ with \f$y\in\mathbb{R}\f$ @@ -104,7 +122,10 @@ namespace codac2 * \param y interval value * \return the substraction result */ - Interval operator-(const Interval& x, const Interval& y); + inline Interval operator-(const Interval& x, const Interval& y) + { + return ibex::operator-(x, y); + } /** * \brief Returns \f$[x]*y\f$ with \f$y\in\mathbb{R}\f$ @@ -113,7 +134,10 @@ namespace codac2 * \param y real value * \return the multiplication result */ - Interval operator*(const Interval& x, double y); + inline Interval operator*(const Interval& x, double y) + { + return ibex::operator*(x,y); + } /** * \brief Returns \f$x*[y]\f$ with \f$x\in\mathbb{R}\f$ @@ -122,7 +146,10 @@ namespace codac2 * \param y interval value * \return the multiplication result */ - Interval operator*(double x, const Interval& y); + inline Interval operator*(double x, const Interval& y) + { + return ibex::operator*(x,y); + } /** * \brief Returns \f$[x]*[y]\f$ @@ -131,7 +158,10 @@ namespace codac2 * \param y interval value * \return the multiplication result */ - Interval operator*(const Interval& x, const Interval& y); + inline Interval operator*(const Interval& x, const Interval& y) + { + return ibex::operator*(x,y); + } /** * \brief Returns \f$[x]/y\f$ with \f$y\in\mathbb{R}\f$ @@ -140,7 +170,10 @@ namespace codac2 * \param y real value * \return the division result */ - Interval operator/(const Interval& x, double y); + inline Interval operator/(const Interval& x, double y) + { + return ibex::operator/(x,y); + } /** * \brief Returns \f$x/[y]\f$ with \f$x\in\mathbb{R}\f$ @@ -149,7 +182,10 @@ namespace codac2 * \param y interval value * \return the division result */ - Interval operator/(double x, const Interval& y); + inline Interval operator/(double x, const Interval& y) + { + return ibex::operator/(x,y); + } /** * \brief Returns \f$[x]/[y]\f$ @@ -158,7 +194,10 @@ namespace codac2 * \param y interval value * \return the division result */ - Interval operator/(const Interval& x, const Interval& y); + inline Interval operator/(const Interval& x, const Interval& y) + { + return ibex::operator/(x,y); + } /** * \brief Returns \f$[x]^2\f$ @@ -166,7 +205,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval sqr(const Interval& x); + inline Interval sqr(const Interval& x) + { + return ibex::sqr(x); + } /** * \brief Returns \f$\sqrt{[x]}\f$ @@ -174,7 +216,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval sqrt(const Interval& x); + inline Interval sqrt(const Interval& x) + { + return ibex::sqrt(x); + } /** * \brief Returns \f$[x]^n\f$, \f$n\in\mathbb{Z}\f$ @@ -183,7 +228,10 @@ namespace codac2 * \param n integer power value * \return the operation result */ - Interval pow(const Interval& x, int n); + inline Interval pow(const Interval& x, int n) + { + return ibex::pow(x,n); + } /** * \brief Returns \f$[x]^d\f$, \f$d\in\mathbb{R}\f$ @@ -192,7 +240,10 @@ namespace codac2 * \param d real power value * \return the operation result */ - Interval pow(const Interval& x, double d); + inline Interval pow(const Interval& x, double d) + { + return ibex::pow(x,d); + } /** * \brief Returns \f$[x]^{[y]}\f$, \f$y\in\mathbb{IR}\f$ @@ -201,7 +252,10 @@ namespace codac2 * \param y interval power value * \return the operation result */ - Interval pow(const Interval& x, const Interval& y); + inline Interval pow(const Interval& x, const Interval& y) + { + return ibex::pow(x,y); + } /** * \brief Returns the n-th root: \f$\sqrt[n]{[x]}\f$ @@ -210,7 +264,10 @@ namespace codac2 * \param n integer root * \return the operation result */ - Interval root(const Interval& x, int n); + inline Interval root(const Interval& x, int n) + { + return ibex::root(x,n); + } /** * \brief Returns \f$\exp([x])\f$ @@ -218,7 +275,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval exp(const Interval& x); + inline Interval exp(const Interval& x) + { + return ibex::exp(x); + } /** * \brief Returns \f$\log([x])\f$ @@ -226,7 +286,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval log(const Interval& x); + inline Interval log(const Interval& x) + { + return ibex::log(x); + } /** * \brief Returns \f$\cos([x])\f$ @@ -234,7 +297,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval cos(const Interval& x); + inline Interval cos(const Interval& x) + { + return ibex::cos(x); + } /** * \brief Returns \f$\sin([x])\f$ @@ -242,7 +308,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval sin(const Interval& x); + inline Interval sin(const Interval& x) + { + return ibex::sin(x); + } /** * \brief Returns \f$\tan([x])\f$ @@ -250,7 +319,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval tan(const Interval& x); + inline Interval tan(const Interval& x) + { + return ibex::tan(x); + } /** * \brief Returns \f$\acos([x])\f$ @@ -258,7 +330,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval acos(const Interval& x); + inline Interval acos(const Interval& x) + { + return ibex::acos(x); + } /** * \brief Returns \f$\asin([x])\f$ @@ -266,7 +341,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval asin(const Interval& x); + inline Interval asin(const Interval& x) + { + return ibex::asin(x); + } /** * \brief Returns \f$\atan([x])\f$ @@ -274,7 +352,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval atan(const Interval& x); + inline Interval atan(const Interval& x) + { + return ibex::atan(x); + } /** * \brief Returns \f$\mathrm{arctan2}([y],[x])\f$ @@ -283,7 +364,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval atan2(const Interval& y, const Interval& x); + inline Interval atan2(const Interval& y, const Interval& x) + { + return ibex::atan2(y,x); + } /** * \brief Returns \f$\cosh([x])\f$ @@ -291,7 +375,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval cosh(const Interval& x); + inline Interval cosh(const Interval& x) + { + return ibex::cosh(x); + } /** * \brief Returns \f$\sinh([x])\f$ @@ -299,7 +386,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval sinh(const Interval& x); + inline Interval sinh(const Interval& x) + { + return ibex::sinh(x); + } /** * \brief Returns \f$\tanh([x])\f$ @@ -307,7 +397,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval tanh(const Interval& x); + inline Interval tanh(const Interval& x) + { + return ibex::tanh(x); + } /** * \brief Returns \f$\acosh([x])\f$ @@ -315,7 +408,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval acosh(const Interval& x); + inline Interval acosh(const Interval& x) + { + return ibex::acosh(x); + } /** * \brief Returns \f$\asinh([x])\f$ @@ -323,7 +419,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval asinh(const Interval& x); + inline Interval asinh(const Interval& x) + { + return ibex::asinh(x); + } /** * \brief Returns \f$\atanh([x])\f$ @@ -331,7 +430,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval atanh(const Interval& x); + inline Interval atanh(const Interval& x) + { + return ibex::atanh(x); + } /** * \brief Returns \f$\mid[x]\mid = \left\{\mid x \mid, x\in[x]\right\}\f$ @@ -339,7 +441,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval abs(const Interval& x); + inline Interval abs(const Interval& x) + { + return ibex::abs(x); + } /** * \brief Returns \f$\min([x],[y])=\left\{\min(x,y), x\in[x], y\in[y]\right\}\f$ @@ -348,7 +453,10 @@ namespace codac2 * \param y interval value * \return the operation result */ - Interval min(const Interval& x, const Interval& y); + inline Interval min(const Interval& x, const Interval& y) + { + return ibex::min(x,y); + } /** * \brief Returns \f$\max([x],[y])=\left\{\max(x,y), x\in[x], y\in[y]\right\}\f$ @@ -357,7 +465,10 @@ namespace codac2 * \param y interval value * \return the operation result */ - Interval max(const Interval& x, const Interval& y); + inline Interval max(const Interval& x, const Interval& y) + { + return ibex::max(x,y); + } /** * \brief Returns \f$\sign([x])=\left[\left\{\sign(x), x\in[x]\right\}\right]\f$ @@ -367,7 +478,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval sign(const Interval& x); + inline Interval sign(const Interval& x) + { + return ibex::sign(x); + } /** * \brief Returns the largest integer interval included in \f$[x]\f$ @@ -375,7 +489,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval integer(const Interval& x); + inline Interval integer(const Interval& x) + { + return ibex::integer(x); + } /** * \brief Returns floor of \f$[x]\f$ @@ -383,7 +500,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval floor(const Interval& x); + inline Interval floor(const Interval& x) + { + return ibex::floor(x); + } /** * \brief Returns ceil of \f$[x]\f$ @@ -391,7 +511,10 @@ namespace codac2 * \param x interval value * \return the operation result */ - Interval ceil(const Interval& x); + inline Interval ceil(const Interval& x) + { + return ibex::ceil(x); + } /** * \brief Computes the backward (reverse) addition @@ -403,7 +526,10 @@ namespace codac2 * \param x1 prior value for \f$[x_1]\f$, may be contracted * \param x2 prior value for \f$[x_2]\f$, may be contracted */ - void bwd_add(const Interval& y, Interval& x1, Interval& x2); + inline void bwd_add(const Interval& y, Interval& x1, Interval& x2) + { + ibex::bwd_add(y,x1,x2); + } /** * \brief Computes the backward (reverse) substraction @@ -415,7 +541,10 @@ namespace codac2 * \param x1 prior value for \f$[x_1]\f$, may be contracted * \param x2 prior value for \f$[x_2]\f$, may be contracted */ - void bwd_sub(const Interval& y, Interval& x1, Interval& x2); + inline void bwd_sub(const Interval& y, Interval& x1, Interval& x2) + { + ibex::bwd_sub(y,x1,x2); + } /** * \brief Computes the backward (reverse) multiplication @@ -427,7 +556,10 @@ namespace codac2 * \param x1 prior value for \f$[x_1]\f$, may be contracted * \param x2 prior value for \f$[x_2]\f$, may be contracted */ - void bwd_mul(const Interval& y, Interval& x1, Interval& x2); + inline void bwd_mul(const Interval& y, Interval& x1, Interval& x2) + { + ibex::bwd_mul(y,x1,x2); + } /** * \brief Computes the backward (reverse) division @@ -439,7 +571,10 @@ namespace codac2 * \param x1 prior value for \f$[x_1]\f$, may be contracted * \param x2 prior value for \f$[x_2]\f$, may be contracted */ - void bwd_div(const Interval& y, Interval& x1, Interval& x2); + inline void bwd_div(const Interval& y, Interval& x1, Interval& x2) + { + ibex::bwd_div(y,x1,x2); + } /** * \brief Computes the backward (reverse) squared operation @@ -450,7 +585,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_sqr(const Interval& y, Interval& x); + inline void bwd_sqr(const Interval& y, Interval& x) + { + ibex::bwd_sqr(y,x); + } /** * \brief Computes the backward (reverse) squared-root operation @@ -461,7 +599,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_sqrt(const Interval& y, Interval& x); + inline void bwd_sqrt(const Interval& y, Interval& x) + { + ibex::bwd_sqrt(y,x); + } /** * \brief Computes the backward (reverse) power operation @@ -473,7 +614,10 @@ namespace codac2 * \param x prior value for \f$[x]\f$, may be contracted * \param p power integer value */ - void bwd_pow(const Interval& y, Interval& x, int p); + inline void bwd_pow(const Interval& y, Interval& x, int p) + { + ibex::bwd_pow(y,p,x); + } /** * \brief Computes the backward (reverse) power operation @@ -485,7 +629,11 @@ namespace codac2 * \param x prior value for \f$[x]\f$, may be contracted * \param p prior value for \f$[p]\f$, may be contracted */ - void bwd_pow(const Interval& y, Interval& x, Interval& p); + inline void bwd_pow(const Interval& y, Interval& x, Interval& p) + { + assert(p.is_degenerated() && "bwd_power(y,x1,x2) (with x1 and x2 intervals) not implemented yet with Gaol"); + ibex::bwd_pow(y,p.mid(),x); + } /** * \brief Computes the backward (reverse) root operation @@ -497,7 +645,10 @@ namespace codac2 * \param x prior value for \f$[x]\f$, may be contracted * \param p root integer value */ - void bwd_root(const Interval& y, Interval& x, int p); + inline void bwd_root(const Interval& y, Interval& x, int p) + { + ibex::bwd_root(y,p,x); + } /** * \brief Computes the backward (reverse) exponential operation @@ -508,7 +659,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_exp(const Interval& y, Interval& x); + inline void bwd_exp(const Interval& y, Interval& x) + { + ibex::bwd_exp(y,x); + } /** * \brief Computes the backward (reverse) logarithmic operation @@ -519,7 +673,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_log(const Interval& y, Interval& x); + inline void bwd_log(const Interval& y, Interval& x) + { + ibex::bwd_log(y,x); + } /** * \brief Computes the backward (reverse) cosine operation @@ -530,7 +687,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_cos(const Interval& y, Interval& x); + inline void bwd_cos(const Interval& y, Interval& x) + { + ibex::bwd_cos(y,x); + } /** * \brief Computes the backward (reverse) sine operation @@ -541,7 +701,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_sin(const Interval& y, Interval& x); + inline void bwd_sin(const Interval& y, Interval& x) + { + ibex::bwd_sin(y,x); + } /** * \brief Computes the backward (reverse) tangent operation @@ -552,7 +715,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_tan(const Interval& y, Interval& x); + inline void bwd_tan(const Interval& y, Interval& x) + { + ibex::bwd_tan(y,x); + } /** * \brief Computes the backward (reverse) arccos operation @@ -563,7 +729,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_acos(const Interval& y, Interval& x); + inline void bwd_acos(const Interval& y, Interval& x) + { + ibex::bwd_acos(y,x); + } /** * \brief Computes the backward (reverse) arcsin operation @@ -574,7 +743,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_asin(const Interval& y, Interval& x); + inline void bwd_asin(const Interval& y, Interval& x) + { + ibex::bwd_asin(y,x); + } /** * \brief Computes the backward (reverse) arctan operation @@ -585,7 +757,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_atan(const Interval& y, Interval& x); + inline void bwd_atan(const Interval& y, Interval& x) + { + ibex::bwd_atan(y,x); + } /** * \brief Computes the backward (reverse) arctan2 operation @@ -597,7 +772,10 @@ namespace codac2 * \param x1 prior value for \f$[x_1]\f$, may be contracted * \param x2 prior value for \f$[x_2]\f$, may be contracted */ - void bwd_atan2(const Interval& y, Interval& x1, Interval& x2); + inline void bwd_atan2(const Interval& y, Interval& x1, Interval& x2) + { + ibex::bwd_atan2(y,x1,x2); + } /** * \brief Computes the backward (reverse) hyperbolic cosine operation @@ -608,7 +786,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_cosh(const Interval& y, Interval& x); + inline void bwd_cosh(const Interval& y, Interval& x) + { + ibex::bwd_cosh(y,x); + } /** * \brief Computes the backward (reverse) hyperbolic sine operation @@ -619,7 +800,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_sinh(const Interval& y, Interval& x); + inline void bwd_sinh(const Interval& y, Interval& x) + { + ibex::bwd_sinh(y,x); + } /** * \brief Computes the backward (reverse) hyperbolic tangent operation @@ -630,7 +814,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_tanh(const Interval& y, Interval& x); + inline void bwd_tanh(const Interval& y, Interval& x) + { + ibex::bwd_tanh(y,x); + } /** * \brief Computes the backward (reverse) hyperbolic arccos operation @@ -641,7 +828,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_acosh(const Interval& y, Interval& x); + inline void bwd_acosh(const Interval& y, Interval& x) + { + ibex::bwd_acosh(y,x); + } /** * \brief Computes the backward (reverse) hyperbolic arcsin operation @@ -652,7 +842,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_asinh(const Interval& y, Interval& x); + inline void bwd_asinh(const Interval& y, Interval& x) + { + ibex::bwd_asinh(y,x); + } /** * \brief Computes the backward (reverse) hyperbolic arctan operation @@ -663,7 +856,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_atanh(const Interval& y, Interval& x); + inline void bwd_atanh(const Interval& y, Interval& x) + { + ibex::bwd_atanh(y,x); + } /** * \brief Computes the backward (reverse) absolute-value operation @@ -674,7 +870,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_abs(const Interval& y, Interval& x); + inline void bwd_abs(const Interval& y, Interval& x) + { + ibex::bwd_abs(y,x); + } /** * \brief Computes the backward (reverse) of the max operation @@ -686,7 +885,10 @@ namespace codac2 * \param x1 prior value for \f$[x_1]\f$, may be contracted * \param x2 prior value for \f$[x_2]\f$, may be contracted */ - void bwd_min(const Interval& y, Interval& x1, Interval& x2); + inline void bwd_min(const Interval& y, Interval& x1, Interval& x2) + { + ibex::bwd_min(y,x1,x2); + } /** * \brief Computes the backward (reverse) of the min operation @@ -698,7 +900,10 @@ namespace codac2 * \param x1 prior value for \f$[x_1]\f$, may be contracted * \param x2 prior value for \f$[x_2]\f$, may be contracted */ - void bwd_max(const Interval& y, Interval& x1, Interval& x2); + inline void bwd_max(const Interval& y, Interval& x1, Interval& x2) + { + ibex::bwd_max(y,x1,x2); + } /** * \brief Computes the backward (reverse) sign operation @@ -709,7 +914,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_sign(const Interval& y, Interval& x); + inline void bwd_sign(const Interval& y, Interval& x) + { + ibex::bwd_sign(y,x); + } /** * \brief Computes the backward (reverse) floor operation @@ -720,7 +928,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_floor(const Interval& y, Interval& x); + inline void bwd_floor(const Interval& y, Interval& x) + { + ibex::bwd_floor(y,x); + } /** * \brief Computes the backward (reverse) ceil operation @@ -731,7 +942,10 @@ namespace codac2 * \param y interval value (result of the forward operation) * \param x prior value for \f$[x]\f$, may be contracted */ - void bwd_ceil(const Interval& y, Interval& x); + inline void bwd_ceil(const Interval& y, Interval& x) + { + ibex::bwd_ceil(y,x); + } /** * \brief Contract \f$[x_1]\f$ and \f$[x_2]\f$ w.r.t. the fact that they are equivalent modulo the period \f$p\f$ @@ -740,6 +954,9 @@ namespace codac2 * \param x2 prior value for \f$[x_2]\f$, may be contracted * \param p period value */ - void bwd_imod(Interval& x1, Interval& x2, double p); + inline void bwd_imod(Interval& x1, Interval& x2, double p) + { + ibex::bwd_imod(x1,x2,p); + } } \ No newline at end of file diff --git a/src/core/paver/codac2_pave.cpp b/src/core/paver/codac2_pave.cpp index b1ee89e4..81c5cff1 100644 --- a/src/core/paver/codac2_pave.cpp +++ b/src/core/paver/codac2_pave.cpp @@ -14,6 +14,11 @@ using namespace codac2; namespace codac2 { + PavingOut pave(const IntervalVector& x, std::shared_ptr> c, double eps) + { + return pave(x, *c, eps); + } + PavingOut pave(const IntervalVector& x, const CtcBase& c, double eps) { assert_release(eps > 0.); @@ -48,6 +53,11 @@ namespace codac2 return p; } + PavingInOut pave(const IntervalVector& x, std::shared_ptr s, double eps) + { + return pave(x, *s, eps); + } + PavingInOut pave(const IntervalVector& x, const SepBase& s, double eps) { assert_release(eps > 0.); diff --git a/src/core/paver/codac2_pave.h b/src/core/paver/codac2_pave.h index 82f4ea44..0f8c890c 100644 --- a/src/core/paver/codac2_pave.h +++ b/src/core/paver/codac2_pave.h @@ -18,7 +18,9 @@ namespace codac2 { // eps: accuracy of the paving algorithm, the undefined boxes will have their max_diam <= eps + PavingOut pave(const IntervalVector& x, std::shared_ptr> c, double eps); PavingOut pave(const IntervalVector& x, const CtcBase& c, double eps); + PavingInOut pave(const IntervalVector& x, std::shared_ptr s, double eps); PavingInOut pave(const IntervalVector& x, const SepBase& s, double eps); template diff --git a/src/graphics/3rd/ipe/codac2_Figure2D_IPE.cpp b/src/graphics/3rd/ipe/codac2_Figure2D_IPE.cpp index 5dab8020..b9349c99 100644 --- a/src/graphics/3rd/ipe/codac2_Figure2D_IPE.cpp +++ b/src/graphics/3rd/ipe/codac2_Figure2D_IPE.cpp @@ -35,7 +35,7 @@ Figure2D_IPE::Figure2D_IPE(const Figure2D& fig) for(const auto& ci : codac_colors) // substr is needed to remove the "#" at the beginning of hex_str (deprecated by IPE) - _colors.emplace(ci.hex_str.substr(1), ci); + _colors.emplace(ci.hex_str().substr(1), ci); } Figure2D_IPE::~Figure2D_IPE() @@ -75,18 +75,28 @@ void Figure2D_IPE::center_viewbox([[maybe_unused]] const Vector& c, [[maybe_unus assert(r.min_coeff() > 0.); } +std::string ipe_str(const Color& c) +{ + return c.hex_str().substr(1); +} + +int ipe_opacity(const Color& c) +{ + return (int)(10.*round(10.*(c.model()==Model::RGB ? (c[3]/255.):(c[3]/100.)))); +} + void Figure2D_IPE::begin_path(const StyleProperties& s, bool tip=false) { // substr is needed to remove the "#" at the beginning of hex_str (deprecated by IPE) - _colors.emplace(s.stroke_color.hex_str.substr(1), s.stroke_color); - _colors.emplace(s.fill_color.hex_str.substr(1), s.fill_color); + _colors.emplace(ipe_str(s.stroke_color), s.stroke_color); + _colors.emplace(ipe_str(s.fill_color), s.fill_color); _f_temp_content << "\n \ "; } @@ -543,9 +553,12 @@ void Figure2D_IPE::print_header_page() \n \ \n"; - for(const auto& [k,c] : _colors) - _f << " \n"; + for(auto& [k,c] : _colors) + { + Color c_rgb = c.rgb(); + _f << " \n"; + } _f << " \n \ \n \ diff --git a/src/graphics/3rd/vibes/codac2_Figure2D_VIBes.cpp b/src/graphics/3rd/vibes/codac2_Figure2D_VIBes.cpp index 3b5a9d94..582e5a97 100644 --- a/src/graphics/3rd/vibes/codac2_Figure2D_VIBes.cpp +++ b/src/graphics/3rd/vibes/codac2_Figure2D_VIBes.cpp @@ -144,5 +144,5 @@ void Figure2D_VIBes::draw_AUV(const Vector& x, float size, const StyleProperties string Figure2D_VIBes::to_vibes_style(const StyleProperties& s) { - return s.stroke_color.hex_str + "[" + s.fill_color.hex_str + "]"; + return s.stroke_color.hex_str() + "[" + s.fill_color.hex_str() + "]"; } \ No newline at end of file diff --git a/src/graphics/CMakeLists.txt b/src/graphics/CMakeLists.txt index 7b38751b..c18ba4b8 100644 --- a/src/graphics/CMakeLists.txt +++ b/src/graphics/CMakeLists.txt @@ -22,6 +22,8 @@ ${CMAKE_CURRENT_SOURCE_DIR}/styles/codac2_Color.cpp ${CMAKE_CURRENT_SOURCE_DIR}/styles/codac2_Color.h + ${CMAKE_CURRENT_SOURCE_DIR}/styles/codac2_ColorMap.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/styles/codac2_ColorMap.h ${CMAKE_CURRENT_SOURCE_DIR}/styles/codac2_StyleProperties.cpp ${CMAKE_CURRENT_SOURCE_DIR}/styles/codac2_StyleProperties.h ) diff --git a/src/graphics/styles/codac2_Color.cpp b/src/graphics/styles/codac2_Color.cpp index 879e0c27..55b5860d 100644 --- a/src/graphics/styles/codac2_Color.cpp +++ b/src/graphics/styles/codac2_Color.cpp @@ -12,46 +12,146 @@ using namespace std; using namespace codac2; -Color::Color(float r_, float g_, float b_, float alpha_) - : r(r_), g(g_), b(b_), alpha(alpha_), - hex_str([&] - { - std::stringstream s; - s << std::hex << std::setfill('0'); - s << std::setw(2) << (int)(r*255) << std::setw(2) << (int)(g*255) << std::setw(2) << (int)(b*255); - if(alpha != 1.) - s << std::setw(2) << (int)(alpha*255); - return "#"+s.str(); - }()) -{ - assert(r_ >= 0. && r_ <= 1. && g_ >= 0. && g_ <= 1. && b_ >= 0. && b_ <= 1. && alpha_ >= 0. && alpha_ <= 1.); -} +Color::Color() + : Color({0.,0.,0.,0.}) +{ } -Color::Color(int r_, int g_, int b_, int alpha_) - : Color((float)(r_/255.), (float)(g_/255.), (float)(b_/255.), (float)(alpha_/255.)) +Color::Color(const std::array& xyz, Model m_) + : Color({xyz[0],xyz[1],xyz[2],(m_ == Model::RGB ? (float) 255. : (float) 100.)}, m_) +{ } + +Color::Color(const std::array& xyza, Model m_) + : std::array(xyza), m(m_) { - assert(r_ >= 0 && r_ <= 255 && g_ >= 0 && g_ <= 255 && b_ >= 0 && b_ <= 255 && alpha_ >= 0 && alpha_ <= 255); + if (m_==Model::RGB) + assert(xyza[0] >= 0. && xyza[0] <= 255. && xyza[1]>=0. && xyza[1] <= 255. && xyza[2]>=0. && xyza[2] <= 255. && xyza[3]>=0. && xyza[3] <= 255.); + else if (m_==Model::HSV) + assert(xyza[0] >= 0. && xyza[0] <= 360. && xyza[1]>=0. && xyza[1] <= 100. && xyza[2]>=0. && xyza[2] <= 100. && xyza[3]>=0. && xyza[3] <= 100.); } -Color::Color(const std::string& hex_str_) - : hex_str(hex_str_) +Color::Color(const std::initializer_list xyza, Model m_) + : Color(xyza.size() == 3 ? Color(to_array<3>(xyza), m_) : Color(to_array<4>(xyza), m_)) +{ } + +Color::Color(const std::string& hex_str) : m(Model::RGB) { - assert(hex_str_.size() == 7 || hex_str_.size() == 9); - assert(hex_str_[0] == '#'); + assert(hex_str.size() == 7 || hex_str.size() == 9); + assert(hex_str[0] == '#'); int red,green,blue,a; - std::istringstream(hex_str_.substr(1,2)) >> std::hex >> red; - std::istringstream(hex_str_.substr(3,2)) >> std::hex >> green; - std::istringstream(hex_str_.substr(5,2)) >> std::hex >> blue; - r = (float)red/255.; - g = (float)green/255.; - b = (float)blue/255.; + std::istringstream(hex_str.substr(1,2)) >> std::hex >> red; + std::istringstream(hex_str.substr(3,2)) >> std::hex >> green; + std::istringstream(hex_str.substr(5,2)) >> std::hex >> blue; + (*this)[0] = (float) (red); + (*this)[1] = (float) (green); + (*this)[2] = (float) (blue); // Alpha (transparency) component may be appended to the #hexa notation. - // Value is '1' (max opacity) by default. - if(hex_str_.size() == 9) + // Value is '255.' (max opacity) by default. + if(hex_str.size() == 9) + { + std::istringstream(hex_str.substr(7,2)) >> std::hex >> a; + (*this)[3] = (float) (a); + } + else + (*this)[3] = 255.; +} + +Color Color::rgb() const +{ + if (m==Model::RGB) + return *this; + else { - std::istringstream(hex_str_.substr(7,2)) >> std::hex >> a; - alpha = (float)a/255.; + float r = 0., g = 0., b = 0.; + + // Normalisation des valeurs + float h = (*this)[0] / 360.; // Hue normalisée (0 à 1) + float s = (*this)[1] / 100.; // Saturation normalisée (0 à 1) + float v = (*this)[2] / 100.; // Value normalisée (0 à 1) + + int i = static_cast(h * 6); + float f = (h * 6) - i; + i = i % 6; + + float p = v * (1 - s); + float q = v * (1 - f * s); + float t = v * (1 - (1 - f) * s); + + switch (i) { + case 0: r = v; g = t; b = p; break; + case 1: r = q; g = v; b = p; break; + case 2: r = p; g = v; b = t; break; + case 3: r = p; g = q; b = v; break; + case 4: r = t; g = p; b = v; break; + case 5: r = v; g = p; b = q; break; + } + + // Conversion vers l'échelle [0, 255] + r *= 255.; + g *= 255.; + b *= 255.; + + return Color({r, g, b,std::min(255.,((*this)[3]*2.55))},Model::RGB); } +} + +Color Color::hsv() const +{ + if (m==Model::HSV) + return *this; + else + { + float r = (*this)[0]/255.; + float g = (*this)[1]/255.; + float b = (*this)[2]/255.; + float c_max = std::max({r, g, b}); + float c_min = std::min({r, g, b}); + float delta = c_max - c_min; + + float h = 0.0; + if (delta != 0) { + if (c_max == r) { + h = fmod((g - b) / delta, 6.0); + } else if (c_max == g) { + h = (b - r) / delta + 2.0; + } else if (c_max == b) { + h = (r - g) / delta + 4.0; + } + h /= 6.0; + if (h < 0) { + h += 1.0; + } + } + + float s = (c_max == 0) ? 0 : (delta / c_max); + + float v = c_max; + + h*=360.; + s*=100.; + v*=100.; + + return Color({h, s, v,std::min(100.,((*this)[3]/2.55))},Model::HSV); + } +} + +std::string Color::hex_str() const +{ + if (m == Model::RGB) + { + std::stringstream s; + s << std::hex << std::setfill('0'); + s << std::setw(2) << (int)((*this)[0]) << std::setw(2) << (int)((*this)[1]) << std::setw(2) << (int)((*this)[2]); + if((*this)[3] != 1.) + s << std::setw(2) << (int)((*this)[3]); + return "#"+s.str(); + } + else + return rgb().hex_str(); +} + +codac2::Vector Color::vec() const +{ + return codac2::Vector({(*this)[0], (*this)[1], (*this)[2], (*this)[3]}); } \ No newline at end of file diff --git a/src/graphics/styles/codac2_Color.h b/src/graphics/styles/codac2_Color.h index 6d8a992c..a7ae40c6 100644 --- a/src/graphics/styles/codac2_Color.h +++ b/src/graphics/styles/codac2_Color.h @@ -11,36 +11,76 @@ #include #include +#include + #include"codac2_assert.h" +#include"codac2_Vector.h" namespace codac2 { - /** - * \struct Color - * \brief Represents an RGB value - */ - struct Color + + enum Model { RGB, HSV }; + + struct Color : public std::array { - float r; ///< red, value between 0. and 1. - float g; ///< green, value between 0. and 1. - float b; ///< blue, value between 0. and 1. - float alpha = 1.; ///< opacity, value between 0. (transparent) and 1. (opaque) - std::string hex_str; ///< represents an RGB value in a HTML standard - - explicit Color(float r, float g, float b, float alpha = 1.); - explicit Color(int r, int g, int b, int alpha = 255); - explicit Color(const std::string& hex_str); - - static Color none() { return Color(255, 255, 255, 0 ); }; - static Color black(float alpha = 1) { return Color(0, 0, 0, (int)(alpha*255)); }; - static Color white(float alpha = 1) { return Color(255, 255, 255, (int)(alpha*255)); }; - static Color green(float alpha = 1) { return Color(144, 242, 0, (int)(alpha*255)); }; - static Color blue(float alpha = 1) { return Color(0, 98, 198, (int)(alpha*255)); }; - static Color cyan(float alpha = 1) { return Color(75, 207, 250, (int)(alpha*255)); }; - static Color yellow(float alpha = 1) { return Color(255, 211, 42, (int)(alpha*255)); }; - static Color red(float alpha = 1) { return Color(209, 59, 0, (int)(alpha*255)); }; - static Color dark_gray(float alpha = 1) { return Color(112, 112, 112, (int)(alpha*255)); }; - static Color purple(float alpha = 1) { return Color(154, 0, 170, (int)(alpha*255)); }; - static Color dark_green(float alpha = 1) { return Color(94, 158, 0, (int)(alpha*255)); }; + protected: + Model m; + + public: + + // Constructors + + explicit Color(); + explicit Color(const std::array& xyz, Model m_ = Model::RGB); + explicit Color(const std::array& xyza, Model m_ = Model::RGB); + explicit Color(const std::initializer_list xyza, Model m_ = Model::RGB); + explicit Color(const std::string& hex_str); + + const Model& model() const { return m; } + + + // other formats + + std::string hex_str() const; + + codac2::Vector vec() const; + + // Conversions + + Color rgb() const; + Color hsv() const; + + // Overload flux operator + + friend std::ostream& operator<<(std::ostream& os, const Color& c) + { + if (c.m == Model::RGB) + os << "RGB Color (" << c[0] << "," << c[1] << "," << c[2] << "," << c[3] << ")"; + else if (c.m == Model::HSV) + os << "HSV Color (" << c[0] << "," << c[1] << "," << c[2] << "," << c[3] << ")"; + return os; + } + + // Predefined colors + + static Color none() { return Color({255., 255., 255., 0.}); }; + static Color black(float alpha = 1.) { return Color({0., 0., 0., (float) (alpha*255.)}); }; + static Color white(float alpha = 1.) { return Color({255., 255., 255., (float) (alpha*255.)}); }; + static Color green(float alpha = 1.) { return Color({144., 242., 0., (float) (alpha*255.)}); }; + static Color blue(float alpha = 1.) { return Color({0., 98., 198., (float) (alpha*255.)}); }; + static Color cyan(float alpha = 1.) { return Color({75., 207., 250., (float) (alpha*255.)}); }; + static Color yellow(float alpha = 1.) { return Color({255., 211., 42., (float) (alpha*255.)}); }; + static Color red(float alpha = 1.) { return Color({209., 59., 0., (float) (alpha*255.)}); }; + static Color dark_gray(float alpha = 1.) { return Color({112., 112., 112., (float) (alpha*255.)}); }; + static Color purple(float alpha = 1.) { return Color({154., 0., 170., (float) (alpha*255.)}); }; + static Color dark_green(float alpha = 1.) { return Color({94., 158., 0., (float) (alpha*255.)}); }; }; + + template + static std::array to_array(const std::initializer_list& list) { + assert(list.size() == N); + std::array arr; + std::copy(list.begin(), list.end(), arr.begin()); + return arr; + } } \ No newline at end of file diff --git a/src/graphics/styles/codac2_ColorMap.cpp b/src/graphics/styles/codac2_ColorMap.cpp new file mode 100644 index 00000000..728264b9 --- /dev/null +++ b/src/graphics/styles/codac2_ColorMap.cpp @@ -0,0 +1,62 @@ +/** + * codac2_ColorMap.cpp + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou, Maël Godard + * \copyright Copyright 2024 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#include "codac2_ColorMap.h" + +using namespace std; +using namespace codac2; + +ColorMap::ColorMap(Model m_) : + m(m_) +{ } + +Color ColorMap::color(float r) const +{ + assert (this->size() >= 2); + if(std::isnan(r)) // undefined ratio + return Color({0.5, 0.5, 0.5}); + assert(Interval(0.,1.).contains(r)); + + Interval map_domain = Interval(this->begin()->first,prev(this->end())->first); + float real_index = map_domain.lb() + r*map_domain.diam(); + + if(this->find(real_index) == this->end()) // color interpolation + { + typename map::const_iterator it_ub; + it_ub = this->lower_bound(real_index); + Color color_lb = prev(it_ub)->second; + Color color_ub = it_ub->second; + + // Interpolation according to the ColorMap model + + if (m == Model::RGB) + { + color_lb = color_lb.rgb(); + color_ub = color_ub.rgb(); + } + + else if (m == Model::HSV) + { + color_lb = color_lb.hsv(); + color_ub = color_ub.hsv(); + } + + + float local_ratio = (real_index - prev(it_ub)->first) / (it_ub->first - prev(it_ub)->first); + + return Color({(color_lb[0] + (color_ub[0] - color_lb[0]) * local_ratio), + (color_lb[1] + (color_ub[1] - color_lb[1]) * local_ratio), + (color_lb[2] + (color_ub[2] - color_lb[2]) * local_ratio), + (color_lb[3] + (color_ub[3] - color_lb[3]) * local_ratio)},color_lb.model()); + + } + + else // color key + return this->at(real_index); +} \ No newline at end of file diff --git a/src/graphics/styles/codac2_ColorMap.h b/src/graphics/styles/codac2_ColorMap.h new file mode 100644 index 00000000..c8d9e09a --- /dev/null +++ b/src/graphics/styles/codac2_ColorMap.h @@ -0,0 +1,126 @@ +/** + * \file codac2_ColorMap.h + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou, Maël Godard + * \copyright Copyright 2024 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#pragma once + +#include +#include +#include "codac2_Color.h" +#include "codac2_Interval.h" +#include"codac2_assert.h" + +namespace codac2 +{ + /** + * \struct ColorMap + * \brief Represents a set of RGB values + */ + struct ColorMap : public std::map + { + protected: + Model m; //RGB or HSV + + public: + + explicit ColorMap(Model m_ = Model::RGB); + + const Model& model() const { return m; } + + Color color (float r) const; + + static ColorMap haxby() + { + ColorMap cmap( Model::RGB ); + cmap[0]=Color({39.,90.,211.}); + cmap[1]=Color({40.,123.,245.}); + cmap[2]=Color({45.,155.,253.}); + cmap[3]=Color({73.,209.,255.}); + cmap[4]=Color({100.,230.,254.}); + cmap[5]=Color({118.,235.,226.}); + cmap[6]=Color({135.,236.,187.}); + cmap[7]=Color({194.,252.,165.}); + cmap[8]=Color({217.,251.,151.}); + cmap[9]=Color({233.,241.,131.}); + cmap[10]=Color({252.,201.,96.}); + cmap[11]=Color({255.,184.,84.}); + cmap[12]=Color({255.,170.,75.}); + cmap[13]=Color({255.,167.,83.}); + cmap[14]=Color({255.,200.,158.}); + cmap[15]=Color({255.,233.,217.}); + return cmap; + } + + static ColorMap basic() // Can't use default as name + { + ColorMap cmap( Model::RGB ); + cmap[0]=Color({10.,0.,121.}); + cmap[1]=Color({40.,0.,150.}); + cmap[2]=Color({20.,5.,175.}); + cmap[3]=Color({0.,10.,200.}); + cmap[4]=Color({0.,25.,212.}); + cmap[5]=Color({0.,40.,224.}); + cmap[6]=Color({26.,102.,240.}); + cmap[7]=Color({13.,129.,248.}); + cmap[8]=Color({25.,175.,255.}); + cmap[9]=Color({50.,190.,255.}); + cmap[10]=Color({68.,202.,255.}); + cmap[11]=Color({97.,225.,240.}); + cmap[12]=Color({106.,235.,225.}); + cmap[13]=Color({124.,235.,200.}); + cmap[14]=Color({138.,236.,174.}); + cmap[15]=Color({172.,245.,168.}); + cmap[16]=Color({205.,255.,162.}); + cmap[17]=Color({223.,245.,141.}); + cmap[18]=Color({240.,236.,121.}); + cmap[19]=Color({247.,215.,104.}); + cmap[20]=Color({255.,189.,87.}); + cmap[21]=Color({255.,160.,69.}); + cmap[22]=Color({244.,117.,75.}); + cmap[23]=Color({238.,80.,78.}); + cmap[24]=Color({255.,90.,90.}); + cmap[25]=Color({255.,124.,124.}); + cmap[26]=Color({255.,158.,158.}); + cmap[27]=Color({245.,179.,174.}); + cmap[28]=Color({255.,196.,196.}); + cmap[29]=Color({255.,215.,215.}); + cmap[30]=Color({255.,235.,235.}); + cmap[31]=Color({255.,254.,253.}); + return cmap; + } + + static ColorMap blue_tube() + { + ColorMap cmap( Model::RGB ); + cmap[0]=Color({76.,110.,127.}); + cmap[1]=Color({136.,197.,228.}); + return cmap; + } + + static ColorMap red_tube() + { + ColorMap cmap( Model::RGB ); + cmap[0]=Color({169.,55.,0.}); + cmap[1]=Color({241.,140.,54.}); + return cmap; + } + + static ColorMap rainbow() + { + ColorMap cmap( Model::HSV ); + int i = 0; + for(int h = 300 ; h > 0 ; h-=10) + { + cmap[i]=Color({(float)h,100.,100.},Model::HSV); + i++; + } + return cmap; + } + + }; +} \ No newline at end of file diff --git a/src/graphics/styles/codac2_StyleProperties.cpp b/src/graphics/styles/codac2_StyleProperties.cpp index 38e15389..d6b42b8b 100644 --- a/src/graphics/styles/codac2_StyleProperties.cpp +++ b/src/graphics/styles/codac2_StyleProperties.cpp @@ -20,9 +20,13 @@ StyleProperties::StyleProperties(const Color& stroke_color_) { } StyleProperties::StyleProperties(std::initializer_list colors) - : stroke_color(*colors.begin()), fill_color(*std::prev(colors.end())) + : stroke_color(*colors.begin()) { assert(colors.size() <= 2); + if (colors.size() == 1) + fill_color = Color::none(); + else + fill_color = *std::prev(colors.end()); } StyleProperties StyleProperties::inside() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 0ac83aa7..1b6c4607 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -78,6 +78,8 @@ list(APPEND SRC_TESTS # listing files without extension core/tools/codac2_tests_Approx + graphics/styles/codac2_tests_Color + ) diff --git a/tests/graphics/styles/codac2_tests_Color.cpp b/tests/graphics/styles/codac2_tests_Color.cpp new file mode 100644 index 00000000..8ae4e0dd --- /dev/null +++ b/tests/graphics/styles/codac2_tests_Color.cpp @@ -0,0 +1,87 @@ +/** + * Codac tests + * ---------------------------------------------------------------------------- + * \date 2024 + * \author Simon Rohou, Maël Godard + * \copyright Copyright 2024 Codac Team + * \license GNU Lesser General Public License (LGPL) + */ + +#include +#include +#include + +using namespace std; +using namespace codac2; + +TEST_CASE("Color") +{ + { + // Red + + std::array d_rgb{255., 0., 0.}; + std::array d_rgba{255., 0., 0., 255.}; + std::array d_hsv{0., 100., 100.}; + std::array d_hsva{0., 100., 100., 100.}; + + vector v{ + Color(d_rgb, Model::RGB), + Color(d_rgba, Model::RGB), + Color(d_hsv, Model::HSV), + Color(d_hsva, Model::HSV), + Color("#FF0000")}; + + for (const auto &c : v) + { + CHECK(Approx(c.rgb().vec(),1.) == Color({255., 0., 0.}).vec()); + CHECK(Approx(c.rgb().vec(),1.) == Color({255., 0., 0., 255.}).vec()); + CHECK(Approx(c.hsv().vec(),1.) == Color({0., 100., 100.}, Model::HSV).vec()); + CHECK(Approx(c.hsv().vec(),1.) == Color({0., 100., 100., 100.}, Model::HSV).vec()); + } + } + + { + // Pink full opacity + + float a = 255.; + std::array d_rgb{229., 128., 255.}; + std::array d_rgba{229., 128., 255., a}; + std::array d_hsv{288., 50., 100.}; + std::array d_hsva{288., 50., 100., 100.}; + + vector v{ + Color(d_rgb, Model::RGB), + Color(d_rgba, Model::RGB), + Color(d_hsv, Model::HSV), + Color(d_hsva, Model::HSV), + Color("#e580ff")}; + + for (const auto &c : v) + { + CHECK(Approx(c.rgb().vec(),1.) == Color({229., 128., 255.}).vec()); + CHECK(Approx(c.rgb().vec(),1.) == Color({229., 128., 255., a}).vec()); + CHECK(Approx(c.hsv().vec(),1.) == Color({288., 50., 100.}, Model::HSV).vec()); + CHECK(Approx(c.hsv().vec(),1.) == Color({288., 50., 100., 100.}, Model::HSV).vec()); + } + } + + { + // Pink 40% opacity + + float a = 0.4*255.; + std::array d_rgba { 229.,128.,255.,a }; + std::array d_hsva { 288.,50.,100.,40. }; + + vector v { + Color(d_rgba, Model::RGB), + Color(d_hsva, Model::HSV), + Color("#e580ff66") + }; + + for(const auto& c : v) + { + CHECK(Approx(c.rgb().vec(),1.) == Color({229.,128.,255.,a}).vec()); + CHECK(Approx(c.hsv().vec(),1.) == Color({288.,50.,100.,40.},Model::HSV).vec()); + } + } +} \ No newline at end of file diff --git a/tests/graphics/styles/codac2_tests_Color.py b/tests/graphics/styles/codac2_tests_Color.py new file mode 100644 index 00000000..bd9e4c8e --- /dev/null +++ b/tests/graphics/styles/codac2_tests_Color.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +# Codac tests +# ---------------------------------------------------------------------------- +# \date 2024 +# \author Simon Rohou, Maël Godard +# \copyright Copyright 2024 Codac Team +# \license GNU Lesser General Public License (LGPL) + +import unittest +from codac import * + + +class TestColor(unittest.TestCase): + + def test_Color(self): + # Red + + d_rgb = [255, 0, 0] + d_rgba = [255, 0, 0, 255] + d_hsv = [0, 100, 100] + d_hsva = [0, 100, 100, 100] + + + colors = [ + Color(d_rgb, Model.RGB), + Color(d_rgba, Model.RGB), + Color(d_hsv, Model.HSV), + Color(d_hsva, Model.HSV), + Color("#FF0000") + ] + + for c in colors: + self.assertTrue(Approx(c.rgb().vec(), 1.0)==Color([255, 0, 0]).rgb().vec()) + self.assertTrue(Approx(c.rgb().vec(), 1.0)==Color([255, 0, 0, 255]).rgb().vec()) + self.assertTrue(Approx(c.hsv().vec(), 1.0)==Color([0, 100, 100],Model.HSV).hsv().vec()) + self.assertTrue(Approx(c.hsv().vec(), 1.0)==Color([0, 100, 100, 100],Model.HSV).hsv().vec()) + + # Pink full opacity + + d_rgb = [229,128,255] + d_rgba = [229,128,255,255] + d_hsv = [288,50,100] + d_hsva = [288,50,100,100] + + colors = [ + Color(d_rgb, Model.RGB), + Color(d_rgba, Model.RGB), + Color(d_hsv, Model.HSV), + Color(d_hsva, Model.HSV), + Color("#E580FF") + ] + + for c in colors: + self.assertTrue(Approx(c.rgb().vec(), 1.0)==Color([229,128,255]).rgb().vec()) + self.assertTrue(Approx(c.rgb().vec(), 1.0)==Color([229,128,255,255]).rgb().vec()) + self.assertTrue(Approx(c.hsv().vec(), 1.0)==Color([288,50,100],Model.HSV).hsv().vec()) + self.assertTrue(Approx(c.hsv().vec(), 1.0)==Color([288,50,100,100],Model.HSV).hsv().vec()) + + # Pink 40% opacity + + a_rgb=102 + a_hsv=40 + d_rgba = [229,128,255,a_rgb] + d_hsva = [288,50,100,a_hsv] + + + colors = [ + Color(d_rgba, Model.RGB), + Color(d_hsva, Model.HSV), + Color("#E580FF66") + ] + for c in colors: + self.assertTrue(Approx(c.rgb().vec(), 1.0)==Color([229,128,255,a_rgb]).rgb().vec()) + self.assertTrue(Approx(c.hsv().vec(), 1.0)==Color([288,50,100,a_hsv],Model.HSV).hsv().vec()) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file