From 3f94da0fce219777cbe7e875fb38ec8788cef04b Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Sun, 9 May 2010 23:00:00 +0000 Subject: Modification is the AGG plot class. Now you can turn on/off units. Simplified the C++ class implementation. --- agg-plot/Makefile | 2 +- agg-plot/c-drawables.cpp | 32 ++++---- agg-plot/c-drawables.h | 8 +- agg-plot/plot.h | 186 ++++++++++++++++++++++++++++++++++++++++++----- agg-plot/units-plot.cpp | 3 - agg-plot/units-plot.h | 170 ------------------------------------------- agg-plot/units.h | 84 ++------------------- examples/fft.lua | 6 +- examples/nlinfit.lua | 3 +- lua-plot.c | 43 +++++++++-- 10 files changed, 240 insertions(+), 297 deletions(-) delete mode 100644 agg-plot/units-plot.cpp delete mode 100644 agg-plot/units-plot.h diff --git a/agg-plot/Makefile b/agg-plot/Makefile index fb6b84df..eb7f3e16 100644 --- a/agg-plot/Makefile +++ b/agg-plot/Makefile @@ -47,7 +47,7 @@ endif INCLUDES += -I$(GSH_BASE_DIR) -I$(LUADIR)/src -I$(LUADIR)/etc -AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) utils.cpp c-drawables.cpp colors.cpp xwin-show.cpp +AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) utils.cpp units.cpp c-drawables.cpp colors.cpp xwin-show.cpp AGGPLOT_OBJ_FILES := $(AGGPLOT_SRC_FILES:%.cpp=%.o) diff --git a/agg-plot/c-drawables.cpp b/agg-plot/c-drawables.cpp index d5111c02..67cd7f62 100644 --- a/agg-plot/c-drawables.cpp +++ b/agg-plot/c-drawables.cpp @@ -2,7 +2,6 @@ #include "agg_color_rgba.h" #include "agg_math_stroke.h" -#include "units-plot.h" #include "plot.h" #include "trans.h" #include "vertex-source.h" @@ -28,19 +27,11 @@ struct property_reg line_join_properties[] = { typedef my::path path_type; CPLOT * -plot_new(int with_units) +plot_new(const char *title) { - plot_type *p; - - if (with_units) - p = new units_plot_type(); - else - p = new plot_type(); - -#ifdef DEBUG_PLOT - fprintf(stderr, "Creating plot: %p\n", p); -#endif - + plot_type *p = new plot_type(); + if (title) + p->set_title(title); return (CPLOT *) p; } @@ -141,6 +132,21 @@ const char * plot_get_title (CPLOT *_p) return p->get_title(); } +int +plot_use_units (CPLOT *_p) +{ + plot_type* p = (plot_type*) _p; + return p->use_units(); + +} + +void +plot_set_units (CPLOT *_p, int use_units) +{ + plot_type* p = (plot_type*) _p; + return p->set_units(use_units); +} + CPATH* path_new() { path_type* p = new path_type(); diff --git a/agg-plot/c-drawables.h b/agg-plot/c-drawables.h index 624a816d..3855f90b 100644 --- a/agg-plot/c-drawables.h +++ b/agg-plot/c-drawables.h @@ -10,10 +10,7 @@ #define CTEXT struct my_c_text #ifdef __cplusplus -#include "units-plot.h" - typedef plot plot_type; -typedef units_plot units_plot_type; #endif __BEGIN_DECLS @@ -25,7 +22,7 @@ CPLOT; CVERTSRC; CPATH; -extern CPLOT * plot_new (int with_units); +extern CPLOT * plot_new (const char *title); extern void plot_free (CPLOT *p); extern void plot_add (CPLOT *p, CVERTSRC *src, struct color *color, struct trans_spec *post, struct trans_spec *pre, @@ -33,6 +30,9 @@ extern void plot_add (CPLOT *p, CVERTSRC *src, struct color *color, extern void plot_set_title (CPLOT *p, const char *title); extern const char * plot_get_title (CPLOT *p); +extern int plot_use_units (CPLOT *p); +extern void plot_set_units (CPLOT *p, int use_units); + extern void vertex_source_ref (CVERTSRC *p); extern void vertex_source_unref (CVERTSRC *p); diff --git a/agg-plot/plot.h b/agg-plot/plot.h index 48849548..96a35570 100644 --- a/agg-plot/plot.h +++ b/agg-plot/plot.h @@ -13,10 +13,15 @@ #include "units.h" #include "resource-manager.h" +#include "agg_vcgen_markers_term.h" #include "agg_conv_transform.h" #include "agg_color_rgba.h" #include "agg_path_storage.h" #include "agg_array.h" +#include "agg_conv_stroke.h" +#include "agg_conv_dash.h" +#include "agg_gsv_text.h" + template class plot { @@ -45,18 +50,14 @@ class plot { }; public: - plot() : m_elements(), m_trans(), m_bbox_updated(true) { + plot() : m_elements(), m_trans(), m_bbox_updated(true), m_use_units(true) { m_title_size = 32; m_title = new char[m_title_size]; m_title[0] = 0; }; - virtual ~plot() + ~plot() { -#ifdef DEBUG_PLOT - fprintf(stderr, "freeing plot: %p\n", this); -#endif - for (unsigned j = 0; j < m_elements.size(); j++) { container& d = m_elements[j]; @@ -81,6 +82,9 @@ public: const char *get_title() const { return m_title; }; + bool use_units() const { return m_use_units; }; + void set_units(bool use_units) { m_use_units = use_units; }; + void add(VertexSource* vs, agg::rgba8 color, bool outline = false) { container d(vs, color, outline); @@ -89,13 +93,17 @@ public: resource_manager::acquire(vs); }; - virtual void draw(canvas &canvas); + void draw(canvas &canvas); -protected: +private: void draw_elements(canvas &canvas); void draw_title(canvas& canvas); + void draw_axis(canvas& can); + + void trans_matrix_update(); + void update_viewport_trans(); + void calc_bounding_box(); - virtual void trans_matrix_update(); static void viewport_scale(agg::trans_affine& trans); @@ -109,6 +117,9 @@ protected: char *m_title; unsigned int m_title_size; + + bool m_use_units; + units m_ux, m_uy; }; template @@ -116,6 +127,8 @@ void plot::draw(canvas &canvas) { trans_matrix_update(); draw_title(canvas); + if (m_use_units) + draw_axis(canvas); draw_elements(canvas); }; @@ -165,19 +178,48 @@ void plot::draw_elements(canvas &canvas) } template -void plot::trans_matrix_update() +void plot::update_viewport_trans() { - if (! m_bbox_updated) + double xi, yi, xs, ys; + + if (m_use_units) + { + int ixi, ixs, iyi, iys; + double xd, yd; + m_ux.limits(ixi, ixs, xd); + xi = ixi * xd; + xs = ixs * xd; + + m_uy.limits(iyi, iys, yd); + yi = iyi * yd; + ys = iys * yd; + } + else + { + xi = m_x1; + yi = m_y1; + xs = m_x2; + ys = m_y2; + } + + double fx = 1/(xs - xi), fy = 1/(ys - yi); + this->m_trans = agg::trans_affine(fx, 0.0, 0.0, fy, -xi*fx, -yi*fy); +} + +template +void plot::trans_matrix_update() { - calc_bounding_box(); + if (this->m_bbox_updated) + return; + + this->calc_bounding_box(); - double fx = m_x2 - m_x1, fy = m_y2 - m_y1; - m_trans.reset(); - m_trans.scale(1/fx, 1/fy); - m_trans.translate(-m_x1/fx, -m_y1/fy); - m_bbox_updated = true; + m_ux = units(this->m_x1, this->m_x2); + m_uy = units(this->m_y1, this->m_y2); + + this->update_viewport_trans(); + this->m_bbox_updated = true; } -} template void plot::calc_bounding_box() @@ -208,6 +250,114 @@ void plot::calc_bounding_box() } } +template +void plot::draw_axis(canvas &canvas) +{ + typedef agg::path_storage path_type; + typedef agg::conv_dash, agg::vcgen_markers_term> dash_type; + + agg::trans_affine m; + this->viewport_scale(m); + canvas.scale(m); + + agg::path_storage mark; + agg::conv_transform mark_tr(mark, m); + agg::conv_stroke> mark_stroke(mark_tr); + + agg::path_storage ln; + agg::conv_transform lntr(ln, m); + dash_type lndash(lntr); + agg::conv_stroke lns(lndash); + + { + int jinf = m_uy.begin(), jsup = m_uy.end(); + for (int j = jinf; j <= jsup; j++) + { + double y = double(j - jinf) / double(jsup - jinf); + agg::gsv_text lab; + agg::conv_stroke labs(lab); + char lab_text[32]; + double xlab = 0, ylab = y; + + lab.size(10.0); + m_uy.mark_label(lab_text, 32, j); + lab.text(lab_text); + labs.width(0.7); + + m.transform(&xlab, &ylab); + + xlab += -lab.text_width() - 8.0; + ylab += -10.0/2.0; + + lab.start_point(xlab, ylab); + canvas.draw(labs, agg::rgba(0, 0, 0)); + + mark.move_to(0.0, y); + mark.line_to(-0.01, y); + + if (j> jinf && j < jsup) + { + ln.move_to(0.0, y); + ln.line_to(1.0, y); + } + } + } + + { + int jinf = m_ux.begin(), jsup = m_ux.end(); + for (int j = jinf; j <= jsup; j++) + { + double x = double(j - jinf) / double(jsup - jinf); + agg::gsv_text lab; + agg::conv_stroke labs(lab); + char lab_text[32]; + double xlab = x, ylab = 0; + + lab.size(10.0); + m_ux.mark_label(lab_text, 32, j); + lab.text(lab_text); + labs.width(0.7); + + m.transform(&xlab, &ylab); + + xlab += -lab.text_width()/2.0; + ylab += -10.0 - 10.0; + + lab.start_point(xlab, ylab); + canvas.draw(labs, agg::rgba(0, 0, 0)); + + mark.move_to(x, 0.0); + mark.line_to(x, -0.01); + + if (j> jinf && j < jsup) + { + ln.move_to(x, 0.0); + ln.line_to(x, 1.0); + } + } + } + + lndash.add_dash(8.0, 4.0); + + lns.width(0.25); + canvas.draw(lns, agg::rgba(0.2, 0.2, 0.2)); + + mark_stroke.width(1.0); + canvas.draw(mark_stroke, agg::rgba8(0, 0, 0)); + + agg::path_storage box; + agg::conv_transform boxtr(box, m); + agg::conv_stroke> boxs(boxtr); + + box.move_to(0.0, 0.0); + box.line_to(0.0, 1.0); + box.line_to(1.0, 1.0); + box.line_to(1.0, 0.0); + box.close_polygon(); + + canvas.draw(boxs, agg::rgba8(0, 0, 0)); +}; + template void plot::viewport_scale(agg::trans_affine& m) { diff --git a/agg-plot/units-plot.cpp b/agg-plot/units-plot.cpp deleted file mode 100644 index f56baaad..00000000 --- a/agg-plot/units-plot.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "units-plot.h" - - diff --git a/agg-plot/units-plot.h b/agg-plot/units-plot.h deleted file mode 100644 index 0a5067d1..00000000 --- a/agg-plot/units-plot.h +++ /dev/null @@ -1,170 +0,0 @@ -#ifndef AGG_PLOT_UNITS_PLOT_H -#define AGG_PLOT_UNITS_PLOT_H - -#include "agg_vcgen_markers_term.h" -#include "agg_conv_stroke.h" -#include "agg_conv_dash.h" -#include "agg_gsv_text.h" - -#include "plot.h" -#include "units.h" - -template -class units_plot : public plot { - -public: - virtual void draw(canvas &canvas); - -private: - void draw_axis(canvas& can); - - virtual void trans_matrix_update() - { - if (this->m_bbox_updated) - return; - - this->calc_bounding_box(); - - m_ux = units(this->m_x1, this->m_x2); - m_uy = units(this->m_y1, this->m_y2); - - int ixi, ixs; - double xi, xs, xd; - m_ux.limits(ixi, ixs, xd); - xi = ixi * xd; - xs = ixs * xd; - - int iyi, iys; - double yi, ys, yd; - m_uy.limits(iyi, iys, yd); - yi = iyi * yd; - ys = iys * yd; - - double fx = 1/(xs - xi), fy = 1/(ys - yi); - this->m_trans = agg::trans_affine(fx, 0.0, 0.0, fy, -xi*fx, -yi*fy); - - this->m_bbox_updated = true; - } - - units m_ux; - units m_uy; -}; - -template -void units_plot::draw_axis(canvas &canvas) -{ - typedef agg::path_storage path_type; - typedef agg::conv_dash, agg::vcgen_markers_term> dash_type; - - agg::trans_affine m; - this->viewport_scale(m); - canvas.scale(m); - - agg::path_storage mark; - agg::conv_transform mark_tr(mark, m); - agg::conv_stroke> mark_stroke(mark_tr); - - agg::path_storage ln; - agg::conv_transform lntr(ln, m); - dash_type lndash(lntr); - agg::conv_stroke lns(lndash); - - { - int jinf = m_uy.begin(), jsup = m_uy.end(); - for (int j = jinf; j <= jsup; j++) - { - double y = double(j - jinf) / double(jsup - jinf); - agg::gsv_text lab; - agg::conv_stroke labs(lab); - char lab_text[32]; - double xlab = 0, ylab = y; - - lab.size(10.0); - m_uy.mark_label(lab_text, 32, j); - lab.text(lab_text); - labs.width(0.7); - - m.transform(&xlab, &ylab); - - xlab += -lab.text_width() - 8.0; - ylab += -10.0/2.0; - - lab.start_point(xlab, ylab); - canvas.draw(labs, agg::rgba(0, 0, 0)); - - mark.move_to(0.0, y); - mark.line_to(-0.01, y); - - if (j> jinf && j < jsup) - { - ln.move_to(0.0, y); - ln.line_to(1.0, y); - } - } - } - - { - int jinf = m_ux.begin(), jsup = m_ux.end(); - for (int j = jinf; j <= jsup; j++) - { - double x = double(j - jinf) / double(jsup - jinf); - agg::gsv_text lab; - agg::conv_stroke labs(lab); - char lab_text[32]; - double xlab = x, ylab = 0; - - lab.size(10.0); - m_ux.mark_label(lab_text, 32, j); - lab.text(lab_text); - labs.width(0.7); - - m.transform(&xlab, &ylab); - - xlab += -lab.text_width()/2.0; - ylab += -10.0 - 10.0; - - lab.start_point(xlab, ylab); - canvas.draw(labs, agg::rgba(0, 0, 0)); - - mark.move_to(x, 0.0); - mark.line_to(x, -0.01); - - if (j> jinf && j < jsup) - { - ln.move_to(x, 0.0); - ln.line_to(x, 1.0); - } - } - } - - lndash.add_dash(8.0, 4.0); - - lns.width(0.25); - canvas.draw(lns, agg::rgba(0.2, 0.2, 0.2)); - - mark_stroke.width(1.0); - canvas.draw(mark_stroke, agg::rgba8(0, 0, 0)); - - agg::path_storage box; - agg::conv_transform boxtr(box, m); - agg::conv_stroke> boxs(boxtr); - - box.move_to(0.0, 0.0); - box.line_to(0.0, 1.0); - box.line_to(1.0, 1.0); - box.line_to(1.0, 0.0); - box.close_polygon(); - - canvas.draw(boxs, agg::rgba8(0, 0, 0)); -}; - -template -void units_plot::draw(canvas &canvas) - { - trans_matrix_update(); - draw_axis(canvas); - this->draw_title(canvas); - this->draw_elements(canvas); - }; - -#endif diff --git a/agg-plot/units.h b/agg-plot/units.h index 73b0445a..94707e00 100644 --- a/agg-plot/units.h +++ b/agg-plot/units.h @@ -1,102 +1,34 @@ #ifndef AGGPLOT_UNITS_H #define AGGPLOT_UNITS_H -#include "utils.h" - -template class units { private: int m_major; int order; - T dmajor; // equal to (m_major * 10^order) + double dmajor; // equal to (m_major * 10^order) int m_inf, m_sup; // expressed in the base of (m_major * 10^order) int nb_decimals; - void init(T min, T max, T spacefact); + void init(double min, double max, double spacefact); public: units(): m_major(1), order(0), dmajor(1), m_inf(0), m_sup(1), nb_decimals(0) {}; - units (T min, T max, T spacefact = 5.0) - { init(min, max, spacefact); }; + units (double min, double max, double spacefact = 5.0) + { init(min, max, spacefact); }; int begin() const { return m_inf; }; int end() const { return m_sup; }; - void limits(int &start, int &fin, T &step) + void limits(int &start, int &fin, double &step) { start = m_inf; fin = m_sup; step = dmajor; }; - void mark_label (char *label, unsigned size, int mark) const; - T mark_value (int mark) const { return dmajor * mark; }; - T mark_scale(T x); + void mark_label (char *label, unsigned size, int mark) const; + double mark_value (int mark) const { return dmajor * mark; }; + double mark_scale(double x); }; -template -void units::init(T yinf, T ysup, T spacefact) -{ - T del; - - if (ysup == yinf) - ysup = yinf + 1.0; - - del = (ysup - yinf) / spacefact; - - order = (int) floor(log10(del)); - - T expf = pow(10, order); - T delr = del / expf; - - if (5 <= delr) - m_major = 5; - else if (2 <= delr) - m_major = 2; - else - m_major = 1; - - m_inf = (int) floor(yinf / (m_major * expf) + 1e-5); - m_sup = (int) ceil (ysup / (m_major * expf) - 1e-5); - - nb_decimals = (order < 0 ? -order : 0); - - dmajor = m_major * expf; -} - -template -void units::mark_label (char *lab, unsigned size, int mark) const -{ - bool minus = (m_inf < 0); - int asup = (minus ? -m_inf : m_sup); - char fmt[16]; - - if (size < 16) - return; - - if (nb_decimals == 0) - { - snprintf (lab, size, "%d", int(mark * dmajor)); - lab[size-1] = '0円'; - } - else - { - int dec = (nb_decimals < 10 ? nb_decimals : 9); - int base = (int) floor(asup * dmajor); - int space = dec + (base> 0 ? (int)log10(base): 0) + 1 \ - + (minus ? 1 : 0) + 1; - snprintf (fmt, 16, "%%%i.%if", space, dec); - fmt[15] = '0円'; - snprintf (lab, size, fmt, mark * dmajor); - lab[size-1] = '0円'; - } -} - -template -T units::mark_scale (T x) -{ - T xinf = m_inf * dmajor, xsup = m_sup * dmajor; - return (x - xinf) / (xsup - xinf); -} - #endif diff --git a/examples/fft.lua b/examples/fft.lua index 3b6c24fb..1d3161ce 100644 --- a/examples/fft.lua +++ b/examples/fft.lua @@ -26,23 +26,21 @@ function demo2() local bess = new(n, 1, |i| besselJ(order, xsmp(i))) - local p = plot() + local p = plot('Original signal / reconstructed') p:addline(ipath(sample(|i| bess[i], 1, n, n-1)), 'black') fft(bess) - fftplot = plot() + fftplot = plot('FFT power spectrum') bars = ibars(sample(|k| abs(bess:get(k)), 0, 60, 60)) fftplot:add(bars, 'darkblue') fftplot:addline(bars, 'black') - fftplot.title = 'FFT power spectrum' fftplot:show() for k=ncut, n/2 do bess:set(k,0) end fft_inv(bess) p:addline(ipath(sample(|i| bess[i], 1, n, n-1)), 'red', {{'dash', a=7, b=3}}) - p.title = 'Original signal / reconstructed' p:show() return p, fftplot diff --git a/examples/nlinfit.lua b/examples/nlinfit.lua index fcd5de2f..4b7f2ee7 100644 --- a/examples/nlinfit.lua +++ b/examples/nlinfit.lua @@ -82,7 +82,7 @@ function demo2() end end - pl = plot() + pl = plot('Non-linear fit / A * exp(a t) sin(w t)') pl:addline(ipath(sequence(function(k) return xs(k), y[k] end, n)), 'blue', {{'marker', size= 5}}) @@ -102,7 +102,6 @@ function demo2() print_state (s) pl:addline(fxline(|x| fmodel(s.x, x), 0, xs(n)), 'red') - pl.title = 'Non-linear fit / A * exp(a t) sin(w t)' pl:show() return pl diff --git a/lua-plot.c b/lua-plot.c index fb3cadfc..8d9af590 100644 --- a/lua-plot.c +++ b/lua-plot.c @@ -53,11 +53,13 @@ static int agg_plot_show (lua_State *L); static int agg_plot_add (lua_State *L); static int agg_plot_update (lua_State *L); static int agg_plot_add_line (lua_State *L); -static int agg_plot_title_set (lua_State *L); -static int agg_plot_title_get (lua_State *L); static int agg_plot_index (lua_State *L); static int agg_plot_newindex (lua_State *L); static int agg_plot_free (lua_State *L); +static int agg_plot_title_set (lua_State *L); +static int agg_plot_title_get (lua_State *L); +static int agg_plot_units_set (lua_State *L); +static int agg_plot_units_get (lua_State *L); static int agg_rgb_new (lua_State *L); static int agg_rgba_new (lua_State *L); @@ -105,11 +107,13 @@ static const struct luaL_Reg agg_plot_methods[] = { static const struct luaL_Reg agg_plot_properties_get[] = { {"title", agg_plot_title_get }, + {"units", agg_plot_units_get }, {NULL, NULL} }; static const struct luaL_Reg agg_plot_properties_set[] = { {"title", agg_plot_title_set }, + {"units", agg_plot_units_set }, {NULL, NULL} }; @@ -372,17 +376,17 @@ check_agg_plot (lua_State *L, int index) int agg_plot_new (lua_State *L) { - lua_Integer use_units = 1; struct agg_plot **pptr = lua_newuserdata (L, sizeof(void *)); struct agg_plot *p; + const char *title = NULL; - if (lua_isboolean (L, 1)) - use_units = lua_toboolean (L, 1); + if (lua_isstring (L, 1)) + title = lua_tostring (L, 1); p = emalloc (sizeof(struct agg_plot)); *pptr = p; - p->plot = plot_new (use_units); + p->plot = plot_new (title); p->lua_is_owner = 1; p->is_shown = 0; @@ -465,6 +469,33 @@ agg_plot_title_get (lua_State *L) return 1; } +int +agg_plot_units_set (lua_State *L) +{ + struct agg_plot *p = check_agg_plot (L, 1); + bool request = lua_toboolean (L, 2); + bool current = plot_use_units (p->plot); + + if (current != request) + { + pthread_mutex_lock (agg_mutex); + plot_set_units (p->plot, request); + if (p->window) + update_callback (p->window); + pthread_mutex_unlock (agg_mutex); + } + + return 0; +} + +int +agg_plot_units_get (lua_State *L) +{ + struct agg_plot *p = check_agg_plot (L, 1); + lua_pushboolean (L, plot_use_units (p->plot)); + return 1; +} + int agg_plot_newindex (lua_State *L) { -- cgit v1.2.3

AltStyle によって変換されたページ (->オリジナル) /