-rw-r--r-- | agg-plot/Makefile | 29 | ||||
-rw-r--r-- | agg-plot/canvas.h | 76 | ||||
-rw-r--r-- | agg-plot/cplot.cpp | 75 | ||||
-rw-r--r-- | agg-plot/cplot.h | 41 | ||||
-rw-r--r-- | agg-plot/main.cpp | 75 | ||||
-rw-r--r-- | agg-plot/string_printf.cpp | 24 | ||||
-rw-r--r-- | agg-plot/string_printf.h | 6 | ||||
-rw-r--r-- | agg-plot/units.cpp | 9 | ||||
-rw-r--r-- | agg-plot/units.h | 136 | ||||
-rw-r--r-- | agg-plot/utils.cpp | 16 | ||||
-rw-r--r-- | agg-plot/utils.h | 8 |
diff --git a/agg-plot/Makefile b/agg-plot/Makefile new file mode 100644 index 00000000..04deb7db --- /dev/null +++ b/agg-plot/Makefile @@ -0,0 +1,29 @@ + +CXX = g++ +CXXFLAGS = -g -Wall + +AGG_CFLAGS = -I/usr/include/agg2 +AGG_LIBS = -lagg -laggplatformX11 -lX11 + +CXXCOMPILE = $(CXX) $(CXXFLAGS) + +AGG_HOME = /home/francesco/src/agg-2.5 + +AGG_TRANS_AFFINE = $(AGG_HOME)/src/agg_trans_affine.o + +SRC_FILES = utils.cpp cplot.cpp main.cpp + +OBJ_FILES := $(SRC_FILES:%.cpp=%.o) + +.PHONY: clean all + +all: test.exe + +%.o: %.cpp + $(CXXCOMPILE) -c $< $(AGG_CFLAGS) + +test.exe: $(OBJ_FILES) + $(CXX) -o $@ $(OBJ_FILES) $(AGG_TRANS_AFFINE) $(AGG_LIBS) + +clean: + rm *.o *.exe diff --git a/agg-plot/canvas.h b/agg-plot/canvas.h new file mode 100644 index 00000000..0a4aac22 --- /dev/null +++ b/agg-plot/canvas.h @@ -0,0 +1,76 @@ +#ifndef AGGPLOT_CANVAS_H +#define AGGPLOT_CANVAS_H + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "agg_rendering_buffer.h" +#include "agg_rasterizer_scanline_aa.h" +// #include "agg_ellipse.h" +// #include "agg_trans_affine.h" +// #include "agg_conv_transform.h" +// #include "agg_conv_stroke.h" +#include "agg_pixfmt_rgb.h" +#include "agg_scanline_p.h" +#include "agg_renderer_scanline.h" +#include "agg_trans_viewport.h" +// #include "agg_image_filters.h" + +class canvas { + typedef agg::pixfmt_bgr24 pixel_fmt; + typedef agg::renderer_base<pixel_fmt> renderer_base; + typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid; + + pixel_fmt *pixf; + renderer_base *rb; + renderer_solid *rs; + + agg::rasterizer_scanline_aa<> ras; + agg::scanline_p8 sl; + + agg::rgba bg_color; + + agg::trans_affine mtx; + + double m_width; + double m_height; + +public: + canvas(agg::rendering_buffer& ren_buf, double width, double height, + agg::rgba bgcol): + ras(), sl(), bg_color(bgcol), mtx(), m_width(width), m_height(height) + { + pixf = new pixel_fmt(ren_buf); + rb = new renderer_base(*pixf); + rs = new renderer_solid(*rb); + + mtx.scale(width, height); + }; + + ~canvas() { + free (rs); + free (rb); + free (pixf); + }; + + double width() const { return m_width; }; + double height() const { return m_height; }; + + void clear() { rb->clear(bg_color); }; + + const agg::trans_affine& trans_matrix() const { return mtx; }; + + template<class VertexSource> + void draw(VertexSource& vs, agg::rgba8 c) + { + if (rs == NULL) + return; + + ras.add_path(vs); + rs->color(c); + agg::render_scanlines(ras, sl, *rs); + }; +}; + +#endif diff --git a/agg-plot/cplot.cpp b/agg-plot/cplot.cpp new file mode 100644 index 00000000..019959b3 --- /dev/null +++ b/agg-plot/cplot.cpp @@ -0,0 +1,75 @@ + +#include "utils.h" +#include "cplot.h" + +#include "agg_conv_stroke.h" +#include "agg_bounding_rect.h" + +template <class T> +T max (T a, T b) { + return (b < a) ? a : b; +} + +template <class T> +T min (T a, T b) { + return (b > a) ? a : b; +} + +void +cplot::add_line(line &ln) +{ + double x1, y1, x2, y2; + m_lines.push_back(ln); + bounding_rect_single(ln.path, 0, &x1, &y1, &x2, &y2); + if (x2 > m_x2 || x1 < m_x1 || y2 > m_y2 || y1 < m_y1) + { + m_x1 = min(x1, m_x1); + m_y1 = min(y1, m_y1); + m_x2 = max(x2, m_x2); + m_y2 = max(y2, m_y2); + + double fx = m_x2 - m_x1, fy = m_y2 - m_y1; + m_trans_matrix.reset(); + m_trans_matrix.scale(1/fx, 1/fy); + m_trans_matrix.translate(-m_x1/fx, -m_y1/fy); + } +} + +void +cplot::draw(canvas &canvas) +{ + typedef agg::path_storage path_type; + + std::list<line>::iterator j; + + agg::path_storage box; + agg::conv_stroke<agg::path_storage> boxl(box); + agg::conv_transform<agg::conv_stroke<agg::path_storage> > boxtr(boxl, canvas.trans_matrix()); + + box.move_to(0.1, 0.1); + box.line_to(0.1, 0.9); + box.line_to(0.9, 0.9); + box.line_to(0.9, 0.1); + box.close_polygon(); + + boxl.width(0.001); + + canvas.draw(boxtr, agg::rgba8(0, 0, 0)); + + agg::trans_affine m = m_trans_matrix; + agg::trans_affine resize(0.8, 0.0, 0.0, 0.8, 0.1, 0.1); + trans_affine_compose (m, resize); + trans_affine_compose (m, canvas.trans_matrix()); + + for (j = m_lines.begin(); j != m_lines.end(); j++) + { + line& ln = *j; + path_type& p = ln.path; + agg::conv_stroke<path_type> pl(p); + agg::conv_transform<agg::conv_stroke<path_type> > tr(pl, m); + + pl.width(0.2); + + canvas.draw(tr, ln.color); + } +} diff --git a/agg-plot/cplot.h b/agg-plot/cplot.h new file mode 100644 index 00000000..d5702e83 --- /dev/null +++ b/agg-plot/cplot.h @@ -0,0 +1,41 @@ +#ifndef AGGPLOT_CPLOT_H +#define AGGPLOT_CPLOT_H + +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include <list> + +#include "canvas.h" + +#include "agg_conv_transform.h" +#include "agg_color_rgba.h" +#include "agg_path_storage.h" + +class line { +public: + line(agg::rgba8 c) : path(), color(c) {}; + + agg::path_storage path; + agg::rgba8 color; +}; + +class cplot { +public: + void add_line(line &ln); + void draw(canvas &canvas); + + cplot() : m_lines(), m_trans_matrix(), m_x1(0.0), m_y1(0.0), + m_x2(1.0), m_y2(1.0) {}; + +private: + std::list<line> m_lines; + agg::trans_affine m_trans_matrix; + + // bounding box + double m_x1, m_y1; + double m_x2, m_y2; +}; + +#endif diff --git a/agg-plot/main.cpp b/agg-plot/main.cpp new file mode 100644 index 00000000..f5845420 --- /dev/null +++ b/agg-plot/main.cpp @@ -0,0 +1,75 @@ +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <time.h> +#include <limits.h> + +#include "agg_rendering_buffer.h" +#include "agg_rasterizer_scanline_aa.h" +#include "agg_ellipse.h" +#include "agg_trans_affine.h" +#include "agg_conv_transform.h" +#include "agg_conv_stroke.h" +#include "agg_pixfmt_rgb.h" +#include "agg_scanline_p.h" +#include "agg_renderer_scanline.h" +#include "agg_image_filters.h" +#include "ctrl/agg_slider_ctrl.h" +#include "ctrl/agg_rbox_ctrl.h" +#include "ctrl/agg_cbox_ctrl.h" +#include "platform/agg_platform_support.h" + +#include "canvas.h" +#include "cplot.h" + +enum flip_y_e { flip_y = true }; + +class the_application : public agg::platform_support +{ +public: + the_application(agg::pix_format_e format, bool flip_y) : + agg::platform_support(format, flip_y), m_plot() + { + line ln(agg::rgba(0.7, 0, 0)); + agg::path_storage& p = ln.path; + p.move_to(0, 0); + + const int npt = 512, ncycles = 12; + for (int j = 1; j < npt; j++) + { + double x = j * 2 * M_PI * ncycles / npt; + double y = 70 * exp(-0.05 * x) * sin(x); + p.line_to(x, y); + } + +#warning A copy of the line is done! +#warning The interface should be changed to avoid copying + m_plot.add_line(ln); + }; + + virtual ~the_application() + { + } + + virtual void on_draw() + { + canvas can(rbuf_window(), width(), height(), agg::rgba(1.0, 1.0, 1.0)); + can.clear(); + m_plot.draw(can); + } + +private: + cplot m_plot; +}; + +int agg_main(int argc, char* argv[]) +{ + the_application app(agg::pix_format_bgr24, flip_y); + app.caption("My damn test"); + + if(app.init(780, 400, agg::window_resize)) + { + return app.run(); + } + return 0; +} diff --git a/agg-plot/string_printf.cpp b/agg-plot/string_printf.cpp new file mode 100644 index 00000000..884550bd --- /dev/null +++ b/agg-plot/string_printf.cpp @@ -0,0 +1,24 @@ + +#include <string> +#include <stdarg.h> + +void +string_printf (std::string &s, const char *fmt, ...) +{ + va_list ap; + char *buf; + int n; + + va_start (ap, fmt); + + n = vasprintf (&buf, fmt, ap); + if (n <= 0) + { + s = ""; + return; + } + + s = (const char *) buf; + free (buf); + va_end (ap); +} diff --git a/agg-plot/string_printf.h b/agg-plot/string_printf.h new file mode 100644 index 00000000..6991cfee --- /dev/null +++ b/agg-plot/string_printf.h @@ -0,0 +1,6 @@ +#ifndef STRING_PRINTF_H +#define STRING_PRINTF_H + + +#endif + diff --git a/agg-plot/units.cpp b/agg-plot/units.cpp new file mode 100644 index 00000000..5a9a8a30 --- /dev/null +++ b/agg-plot/units.cpp @@ -0,0 +1,9 @@ +
+#include <math.h>
+#include <stdio.h>
+
+#include <vector>
+
+#include "units.h"
+
+using namespace std;
diff --git a/agg-plot/units.h b/agg-plot/units.h new file mode 100644 index 00000000..ad30f2c0 --- /dev/null +++ b/agg-plot/units.h @@ -0,0 +1,136 @@ +
+/*
+ $Id$
+*/
+
+#ifndef AGGPLOT_UNITS_H
+#define AGGPLOT_UNITS_H
+
+#include <string>
+#include <vector>
+
+template<class num_type>
+class units {
+private:
+ int major;
+ int order;
+ num_type dmajor; // equal to (major * 10^order)
+ int inf, sup; // expressed in the base of (major * 10^order)
+ int nb_decimals;
+
+ private:
+ void init(num_type min, num_type max, num_type spacefact);
+
+public:
+ units (std::vector<num_type> &x, num_type spacefact = 5.0);
+ units (num_type min, num_type max, num_type spacefact = 5.0)
+ { init(min, max, spacefact); };
+
+ void limits(int &start, int &fin) { start = inf; fin = sup; };
+ void limits(int &start, int &fin, num_type &step)
+ { start = inf; fin = sup; step = dmajor; };
+
+ int decimals () const { return nb_decimals; };
+ void mark_label (std::string &label, int mark) const;
+ num_type mark_value (int mark) const { return dmajor * mark; };
+ num_type mark_scale(num_type x);
+
+ static void get_limits (std::vector<num_type> &x, num_type &inf, num_type &sup);
+
+};
+
+
+template<class num_type>
+void units<num_type>::get_limits (std::vector<num_type> &x, num_type &inf, num_type &sup)
+{
+ typename vector<num_type>::iterator j = x.begin();
+
+ if (j == x.end())
+ return;
+
+ inf = x[j];
+ sup = x[j];
+ j++;
+
+ for ( ; j != x.end(); j++)
+ {
+ num_type v = x[j];
+ if (inf > v)
+ inf = v;
+ if (sup < v)
+ sup = v;
+ }
+};
+
+template<class num_type>
+void units<num_type>::init(num_type yinf, num_type ysup, num_type spacefact)
+{
+ num_type del;
+
+ if (ysup == yinf)
+ ysup = yinf + 1.0;
+
+ del = (ysup - yinf) / spacefact;
+
+ order = (int) floor(log10(del));
+
+ num_type expf = pow(10, order);
+ num_type delr = del / expf;
+
+ if (5 <= delr)
+ major = 5;
+ else if (2 <= delr)
+ major = 2;
+ else
+ major = 1;
+
+ inf = (int) floor(yinf / (major * expf));
+ sup = (int) ceil(ysup / (major * expf));
+
+ nb_decimals = (order < 0 ? -order : 0);
+
+ dmajor = major * expf;
+}
+
+template<class num_type>
+units<num_type>::units (std::vector<num_type> &x, num_type spacefact)
+{
+ num_type yinf, ysup;
+ units::get_limits (x, yinf, ysup);
+ init (yinf, ysup, spacefact);
+}
+
+template<class num_type>
+void units<num_type>::mark_label (std::string &lab, int mark) const
+{
+ bool minus = (inf < 0);
+ int asup = (minus ? -inf : sup);
+ char fmt[8];
+
+ if (nb_decimals == 0)
+ {
+ int space = (int)log10(asup * dmajor) + (minus ? 1 : 0) + 1;
+ sprintf (fmt, "%%%id", space);
+ string_printf (lab, fmt, (int) (mark * dmajor));
+ }
+ else
+ {
+ int dec = (nb_decimals < 10 ? nb_decimals : 9);
+ int base = floor(asup * dmajor);
+ int space = dec + (base > 0 ? (int)log10(base): 0) + 1 \
+ + (minus ? 1 : 0) + 1;
+ sprintf (fmt, "%%%i.%if", space, dec);
+ string_printf (lab, fmt, mark * dmajor);
+ }
+}
+
+template<class num_type>
+num_type units<num_type>::mark_scale (num_type x)
+{
+ int inf, sup;
+ num_type ef;
+ limits(inf, sup, ef);
+ return (x - inf * ef) / ((sup - inf) * ef);
+}
+
+#endif
diff --git a/agg-plot/utils.cpp b/agg-plot/utils.cpp new file mode 100644 index 00000000..6b834ee7 --- /dev/null +++ b/agg-plot/utils.cpp @@ -0,0 +1,16 @@ +#include <stdio.h> +#include <stdlib.h> +#include <limits.h> + +#include "utils.h" + +void +trans_affine_compose (agg::trans_affine& a, const agg::trans_affine& b) +{ + a.premultiply(b); + + double a_tx = b.sx * a.tx + b.shx * a.ty + b.tx; + double a_ty = b.shy * a.tx + b.sy * a.ty + b.ty; + a.tx = a_tx; + a.ty = a_ty; +} diff --git a/agg-plot/utils.h b/agg-plot/utils.h new file mode 100644 index 00000000..f760da08 --- /dev/null +++ b/agg-plot/utils.h @@ -0,0 +1,8 @@ +#ifndef AGGPLOT_UTILS_H +#define AGGPLOT_UTILS_H + +#include "agg_trans_affine.h" + +extern void trans_affine_compose (agg::trans_affine& a, const agg::trans_affine& b); + +#endif |