Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ wheelhouse/

# Graphics files
examples/**/*.xml
examples/**/*.bmp
examples/**/*.png
examples/**/*.jpg
examples/**/*.svg
*.ipe

# Matlab files
Expand Down
1 change: 1 addition & 0 deletions doc/manual/manual/extensions/capd/capd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ To use CAPD with Codac, you first need to install the CAPD library. You can find

Note that as CAPD is a C++ only library, the content present in this page is **only available in C++**.

.. _subsec-extensions-capd-capd-install:

Installing the ``codac-capd`` extension
---------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion doc/manual/manual/extensions/capd/peibos_capd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ The PEIBOS function takes at least six arguments :
- The final time for the integration of the ODE.
- A timestep to get intermediate states.
- The inverse chart for the gnomonic atlas (an analytic function).
- The list of symmetries for the gnomonic atlas. Note that each symmetry is represented as a hyperoctahedral symmetry, see :ref:`sec-actions-octasym`.
- The list of symmetries for the gnomonic atlas. Note that each symmetry is represented as a hyperoctahedral symmetry, see :ref:`sec-tools-octasym`.
- A resolution :math:`\epsilon`. The initial box :math:`\left[-1,1\right]^m` will initiallly be splitted in boxes with a diameter smaller than :math:`\epsilon`.
- Eventually an offset vector can be specified if the initial set is not centered around the origin.
- Eventually a flag can be set to True to get the verbose.
Expand Down
3 changes: 2 additions & 1 deletion doc/manual/manual/functions/peibos/peibos.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Let us consider an initial set :math:`\mathbb{X}_0 \subset \mathbb{R}^n` with it
Considering a function :math:`\mathbf{f}:\mathbb{R}^n \to \mathbb{R}^p`, :math:`n \leq p`, the PEIBOS tool allows to compute the set :math:`\mathbf{Y}=\left\{ \mathbf{f}(\mathbf{x}) \mid \mathbf{x} \in \partial \mathbb{X}_0 \right\}`.

.. _subsec-functions-peibos-gnomonic-atals:

Gnomonic atlas
--------------

Expand Down Expand Up @@ -60,7 +61,7 @@ The PEIBOS function takes at least four arguments :

- The studied analytic function.
- The inverse chart for the gnomonic atlas (an analytic function).
- The list of symmetries for the gnomonic atlas. Note that each symmetry is represented as a hyperoctahedral symmetry, see :ref:`sec-actions-octasym`.
- The list of symmetries for the gnomonic atlas. Note that each symmetry is represented as a hyperoctahedral symmetry, see :ref:`sec-tools-octasym`.
- A resolution :math:`\epsilon`. The initial box :math:`\left[-1,1\right]^m` will initiallly be splitted in boxes with a diameter smaller than :math:`\epsilon`.
- Eventually an offset vector can be specified if the initial set is not centered around the origin.
- Eventually a flag can be set to True to get the verbose.
Expand Down
26 changes: 26 additions & 0 deletions doc/manual/manual/visualization/2d_example.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.. _sec-graphics-2d-example:

2D graphical example
====================

Below is an example covering a wide variety of drawing functions, colors, styles etc.

.. tabs::

.. group-tab:: Python

.. literalinclude:: 2d_example_src/src.py
:language: py
:dedent: 0

.. group-tab:: C++

.. literalinclude:: 2d_example_src/src.cpp
:language: c++
:dedent: 0

.. group-tab:: Matlab

.. literalinclude:: 2d_example_src/src.m
:language: matlab
:dedent: 0
124 changes: 124 additions & 0 deletions doc/manual/manual/visualization/2d_example_src/src.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#include <codac>
#include <filesystem>
#include <iostream>

using namespace std;
using namespace codac2;

int main(){

// Graphics can be directly called without a Figure2D instanciation, using "DefaultFigure"

DefaultFigure::set_window_properties({600,600},{300,300});
DefaultFigure::draw_box({{2.2,2.5},{2.2,2.5}},{Color::black(),Color::yellow(0.5)});
DefaultFigure::draw_AUV({1,1,3.14/2},1.,{{Color::black(),Color::yellow()}, "-.."});
DefaultFigure::draw_motor_boat({0,0,0}, 1., {Color::black(),Color::yellow()});
DefaultFigure::draw_tank({2,1,3.14/2},1.,{{Color::black(),Color::yellow()},"vehicles","-."});
DefaultFigure::draw_pie({2,2},{1.5,2.5},{(3*3.14/4)-0.5,(3*3.14/4)+0.5},{Color::blue(),Color::cyan()});
DefaultFigure::draw_polyline({{2,-0.5},{4,0.5},{3,1.5},{4,2.5},{3,3}}, Color::red());
DefaultFigure::draw_polygon({{2,4.5},{4,4.5},{4.2,3.5},{3.5,3}}, {Color::none(),Color::green(0.5)});
DefaultFigure::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<codac2::Figure2D> fig1 = std::make_shared<Figure2D>("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(IntervalVector::constant(2,{-10,10})); // bounding box
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<codac2::Figure2D> fig2 = std::make_shared<Figure2D>("My Figure 2",GraphicOutput::VIBES|GraphicOutput::IPE);
fig2->set_axes(axis(0,{-1,5}), axis(1,{-1,5})); // (axis_id,{range_of_values_on_this_axis})
fig2->set_window_properties({250,250},{500,500});

// The previously declared figure "fig2" can now be used as a DefaultFigure
DefaultFigure::set(fig2);
DefaultFigure::draw_box({{2.2,2.5},{2.2,2.5}},{Color::black(),Color::green(0.8)});

DefaultFigure::set(fig1);
DefaultFigure::draw_box({{2.2,2.5},{2.2,2.5}},{Color::blue(),Color::cyan(0.8)});

fig2->draw_circle({2.,2.},0.5,{{Color::red(),Color::red(0.2)}, "z:1."}); // will alway be on top despite being "drawn" first

fig2->draw_AUV({1,1,3.14/2},2.,{{Color::black(),Color::yellow()}, "w:0.1", "vehicles"});
fig2->draw_tank({2,1,3.14/2},1.5,{{Color::black(),Color::yellow()},"vehicles","w:0.1"});
fig2->draw_motor_boat({0,0,0}, 1., {{Color::black(),Color::yellow()},"vehicles"});
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_polygon({{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)});
fig2->draw_parallelepiped({{1.5,2.8},Matrix({{0.5,0.4},{0,0.2}})}, {{Color::red(),Color::green(0.5)}, "parallelepiped", "w:0.1"});

fig2->draw_zonotope({{4,1.5},
{{-0.2,-0.06,0.2,0.06,0.01,0.08,0},
{0.1,0.04,0.04,-0.04,-0.03,0.18,0}}},
{{Color::red(),Color::yellow(0.4)},"zonotope", "w:0.05"});

Parallelepiped p_3d ({1.2,3.5,2.2},Matrix({{0.5,0.4,0},{0,0.2,0.1},{0,0,0.3}}));
fig2->draw_zonotope(p_3d.proj({0,1}), {{Color::green(),Color::yellow(0.4)}, "zonotope"});

fig2->draw_text("Hello, World!",{-0.5,4.5},0.2, Color::blue());

std::filesystem::path p = __FILE__;
fig2->draw_raster(p.parent_path().string()+"/logo_codac.png", IntervalVector({{2.5,5},{-1,-0.4}}), StyleProperties("raster"));

fig2->draw_circle({0.5,0.5},0.5,{{Color::orange(),Color::orange(0.2)}, "z:-1."}); // will alway be in the bottom despite being "drawn" last

// 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 ("ColorMap figure",GraphicOutput::VIBES|GraphicOutput::IPE);
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();

ColorMap custom_map;
custom_map[0] = Color({255,0,0});
custom_map[0.5] = Color({0,255,0});
custom_map[1] = Color({0,0,255});

double subdivisions = 40.;
fig3.set_axes(axis(0,{-1,subdivisions+1}), axis(1,{-1.25,0.05}));
for (double i=0.; i<=subdivisions; i+=1.0)
{
double ratio = i/subdivisions;
fig3.draw_box({{i,i+1},{-1./5.,0}},{Color::black(),cmap_default.color(ratio)});
fig3.draw_box({{i,i+1},{-2./5.,-1./5.}},{Color::black(),cmap_haxby.color(ratio)});
fig3.draw_box({{i,i+1},{-3./5.,-2./5.}},{Color::black(),cmap_rainbow.color(ratio)});
fig3.draw_box({{i,i+1},{-4./5.,-3./5.}},{Color::black(),cmap_blue_tube.color(ratio)});
fig3.draw_box({{i,i+1},{-5/5.,-4./5.}},{Color::black(),cmap_red_tube.color(ratio)});
fig3.draw_box({{i,i+1},{-6./5.,-5./5.}},{Color::black(),custom_map.color(ratio)});
}

Figure2D fig4 ("My Figure 4",GraphicOutput::VIBES);

fig4.set_window_properties({500,50},{500,500});
fig4.set_axes(axis(0,{-10,10}), axis(1,{-10,10}));

double a=0.8;
ScalarVar t;
// Fermat's spiral
AnalyticFunction f1 ({t},{a*sqrt(t)*cos(t),a*sqrt(t)*sin(t)});
AnalyticTraj traj4 ({0,100},f1);
fig4.draw_trajectory(traj4,{ColorMap::rainbow(), ".."});
}
112 changes: 112 additions & 0 deletions doc/manual/manual/visualization/2d_example_src/src.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import py.codac4matlab.*

% Graphics can be directly called without a Figure2D instanciation, using "DefaultFigure":

DefaultFigure().set_window_properties(Vector({600,600}),Vector({300,300}));
DefaultFigure().draw_box(IntervalVector({{2.2,2.5},{2.2,2.5}}),StyleProperties({Color().black(),Color().yellow(0.5)}));
DefaultFigure().draw_AUV(Vector({1,1,3.14/2}),1.,StyleProperties({Color().black(),Color().yellow()},"-.."));
DefaultFigure().draw_motor_boat(Vector({0,0,0}),1.,StyleProperties({Color().black(),Color().yellow()}));
DefaultFigure().draw_tank(Vector({2,1,3.14/2}),1.,StyleProperties({Color().black(),Color().yellow()},"vehicles","-."));
DefaultFigure().draw_pie(Vector({2,2}),Interval(1.5,2.5),Interval((3*3.14/4)-0.5,(3*3.14/4)+0.5),StyleProperties({Color().blue(),Color().cyan()}));
DefaultFigure().draw_polyline({Vector({2,-0.5}),Vector({4,0.5}),Vector({3,1.5}),Vector({4,2.5}),Vector({3,3})},Color().red());
DefaultFigure().draw_polygon(Polygon({Vector({2,4.5}),Vector({4,4.5}),Vector({4.2,3.5}),Vector({3.5,3})}),StyleProperties({Color().none(),Color().green(0.5)}));
DefaultFigure().draw_polyline({Vector({-0.8,0}),Vector({0,1.5})},0.2,StyleProperties({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:

fig1 = Figure2D("My figure 1", GraphicOutput().VIBES.union(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(Vector({50,50}),Vector({500,500})); % position, window size
fig1.set_axes(IntervalVector().constant(2,Interval(-10,10))); % bounding box
fig1.draw_box(IntervalVector({{-1,1},{-1,1}}),StyleProperties({Color().green(),Color().red(0.2)})); % drawing a green box with red opacity values inside
fig1.draw_circle(Vector({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(Vector({1,1}),Interval(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.union(GraphicOutput().IPE));
fig2.set_axes(axis(1,Interval(-1,5)), axis(2,Interval(-1,5))); % (axis_id,[range_of_values_on_this_axis])
fig2.set_window_properties(Vector({250,250}),Vector({500,500}));

% The previously declared figure "fig2" can now be used as a DefaultFigure
DefaultFigure().set(fig2);
DefaultFigure().draw_box(IntervalVector({{2.2,2.5},{2.2,2.5}}),StyleProperties({Color().black(),Color().green(0.8)}));

DefaultFigure().set(fig1);
DefaultFigure().draw_box(IntervalVector({{2.2,2.5},{2.2,2.5}}),StyleProperties({Color().blue(),Color().cyan(0.8)}));

fig2.draw_circle(Vector({2,2}),0.5,StyleProperties({Color().red(),Color().red(0.2)},"z:1.")); % will alway be on top despite being "drawn" first

fig2.draw_AUV(Vector({1,1,3.14/2}),2.,StyleProperties({Color().black(),Color().yellow()},"w:0.1","vehicles"));
fig2.draw_tank(Vector({2,1,3.14/2}),1.5,StyleProperties({Color().black(),Color().yellow()},"vehicles","w:0.1"));
fig2.draw_motor_boat(Vector({0,0,0}),1.,StyleProperties({Color().black(),Color().yellow()},"vehicles"));
fig2.draw_pie(Vector({2,2}),Interval(1.5,2.5),Interval((3*3.14/4)-0.5,(3*3.14/4)+0.5),StyleProperties({Color().blue(),Color().cyan()}));
fig2.draw_polyline({Vector({2,-0.5}),Vector({4,0.5}),Vector({3,1.5}),Vector({4,2.5}),Vector({3,3})},StyleProperties(Color().red(),".."));
fig2.draw_polygon(Polygon({Vector({2,4.5}),Vector({4,4.5}),Vector({4.2,3.5}),Vector({3.5,3})}),StyleProperties({Color().none(),Color().green(0.5)}));
fig2.draw_polyline({Vector({-0.8,0}),Vector({0,1.5})},0.2,StyleProperties({Color().red(),Color().black(0.3)}));
fig2.draw_ellipse(Vector({1,1}),Vector({0.5,2.}),0.2,StyleProperties({Color().blue(),Color().blue(0.3)}));
fig2.draw_line(Vector({1,1}),Vector({3,3}),Color().blue());
fig2.draw_arrow(Vector({3,1}),Vector({2.2,2}),0.2,StyleProperties({Color().red(),Color().black(0.3)}));
fig2.draw_parallelepiped(Parallelepiped(Vector({1.5,2.8}),Matrix({{0.5,0.4},{0,0.2}})),StyleProperties({Color().red(),Color().green(0.5)},"parallelepiped","w:0.1"));

fig2.draw_zonotope(Zonotope(Vector({4,1.5}),Matrix({{-0.2,-0.06,0.2,0.06,0.01,0.08,0}, ...
{0.1,0.04,0.04,-0.04,-0.03,0.18,0}})),StyleProperties({Color().red(),Color().yellow(0.4)},"zonotope","w:0.05"));

p_3d = Parallelepiped(Vector({1.2,3.5,2.2}),Matrix({{0.5,0.4,0},{0,0.2,0.1},{0,0,0.3}}));
fig2.draw_zonotope(p_3d.proj({1,2}),StyleProperties({Color().green(),Color().yellow(0.4)},"zonotope"));

fig2.draw_text("Hello, World!",Vector({-0.5,4.5}),0.2, Color().blue());

fig2.draw_raster("logo_codac.png", IntervalVector({{2.5,5},{-1,-0.4}}),StyleProperties("raster"));

fig2.draw_circle(Vector({0.5,0.5}),0.5,StyleProperties({Color().orange(),Color().orange(0.2)},"z:-1.")); % will alway be in the bottom despite being "drawn" last

% Colors
% predefined colors without and with opacity
fig2.draw_point(Vector({2,2}), StyleProperties({Color().red(),Color().yellow(0.5)}));
% HTML color without and with opacity
fig2.draw_box(IntervalVector({{2.4,2.9},{2.4,2.9}}),StyleProperties({Color("#da3907"),Color("#da390755")}));
% HSV color without and with opacity
fig2.draw_box(IntervalVector({{2.6,3.1},{2.6,3.1}}),StyleProperties({Color({108,90,78},Model().HSV),Color({108,90,78,20},Model().HSV)}));

fig3 = Figure2D("ColorMap figure", GraphicOutput().VIBES.union(GraphicOutput().IPE));
fig3.set_window_properties(Vector({800,250}),Vector({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();

custom_map = ColorMap(Model().RGB);
custom_map.set_item(0,Color({255,0,0}));
custom_map.set_item(0.5,Color({0,255,0}));
custom_map.set_item(1,Color({0,0,255}));

subdivisions = 40;
fig3.set_axes(axis(1,Interval(-1,subdivisions+1)), axis(2,Interval(-1.25,0.05)));

for i = 0:(subdivisions)
ratio = i / subdivisions;
fig3.draw_box(IntervalVector({{i,i+1},{-1./5.,0}}),StyleProperties({Color().black(),cmap_default.color(ratio)}));
fig3.draw_box(IntervalVector({{i,i+1},{-2./5.,-1./5.}}),StyleProperties({Color().black(),cmap_haxby.color(ratio)}));
fig3.draw_box(IntervalVector({{i,i+1},{-3./5.,-2./5.}}),StyleProperties({Color().black(),cmap_rainbow.color(ratio)}));
fig3.draw_box(IntervalVector({{i,i+1},{-4./5.,-3./5.}}),StyleProperties({Color().black(),cmap_blue_tube.color(ratio)}));
fig3.draw_box(IntervalVector({{i,i+1},{-5./5.,-4./5.}}),StyleProperties({Color().black(),cmap_red_tube.color(ratio)}));
fig3.draw_box(IntervalVector({{i,i+1},{-6./5.,-5./5.}}),StyleProperties({Color().black(),custom_map.color(ratio)}));
end

fig4 = Figure2D("My Figure 4", GraphicOutput().VIBES);
fig4.set_window_properties(Vector({500,50}),Vector({500,500}));
fig4.set_axes(axis(1,Interval(-10,10)), axis(2,Interval(-10,10)));

a= 0.8;
t = ScalarVar();
% Fermat's spiral
f1 = AnalyticFunction({t},vec(a*sqrt(t)*cos(t),a*sqrt(t)*sin(t)));
traj4 = AnalyticTraj(Interval(0,100),f1);
fig4.draw_trajectory(traj4, StyleGradientProperties(ColorMap().rainbow(), ".."));
Loading
Loading