-rw-r--r-- | agg-plot/Makefile | 2 | ||||
-rw-r--r-- | agg-plot/canvas.h | 9 | ||||
-rw-r--r-- | agg-plot/cplot.cpp | 123 | ||||
-rw-r--r-- | agg-plot/cplot.h | 22 | ||||
-rw-r--r-- | agg-plot/main.cpp | 99 | ||||
-rw-r--r-- | agg-plot/units.cpp | 9 | ||||
-rw-r--r-- | agg-plot/units.h | 80 | ||||
-rw-r--r-- | agg-plot/units_cplot.cpp | 99 | ||||
-rw-r--r-- | agg-plot/units_cplot.h | 47 | ||||
-rw-r--r-- | agg-plot/utils.cpp | 32 | ||||
-rw-r--r-- | agg-plot/utils.h | 13 | ||||
-rw-r--r-- | examples/bessel.lua | 44 | ||||
-rw-r--r-- | lua/src/lnum.h | 3 |
diff --git a/agg-plot/Makefile b/agg-plot/Makefile index 04deb7db..67f32c11 100644 --- a/agg-plot/Makefile +++ b/agg-plot/Makefile @@ -11,7 +11,7 @@ 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 +SRC_FILES = utils.cpp cplot.cpp units_cplot.cpp main.cpp OBJ_FILES := $(SRC_FILES:%.cpp=%.o) diff --git a/agg-plot/canvas.h b/agg-plot/canvas.h index 0a4aac22..424e5b14 100644 --- a/agg-plot/canvas.h +++ b/agg-plot/canvas.h @@ -7,15 +7,12 @@ #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" + +#include "utils.h" class canvas { typedef agg::pixfmt_bgr24 pixel_fmt; @@ -60,6 +57,8 @@ public: void clear() { rb->clear(bg_color); }; const agg::trans_affine& trans_matrix() const { return mtx; }; + void scale(agg::trans_affine& m) const { trans_affine_compose (m, mtx); }; + template<class VertexSource> void draw(VertexSource& vs, agg::rgba8 c) diff --git a/agg-plot/cplot.cpp b/agg-plot/cplot.cpp index 019959b3..7aa2e842 100644 --- a/agg-plot/cplot.cpp +++ b/agg-plot/cplot.cpp @@ -5,71 +5,96 @@ #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; +line& +cplot::new_line(agg::rgba8 color) +{ + int n = m_lines.size(); + m_lines.resize(n+1, color); + std::list<line>::iterator ln = -- m_lines.end(); + return *ln; } -void -cplot::add_line(line &ln) +bool +cplot::bbox_update() { - 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); + bool updated = false; - 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); + for (std::list<line>::iterator j = m_lines.begin(); j != m_lines.end(); j++) + { + line& ln = *j; + double x1, y1, x2, y2; + bounding_rect_single(ln.path, 0, &x1, &y1, &x2, &y2); + + if (! m_bbox_set) + { + m_x1 = x1; + m_x2 = x2; + m_y1 = y1; + m_y2 = y2; + + m_bbox_set = true; + updated = true; + continue; + } + + 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); + + updated = true; + } } + + return updated; } void -cplot::draw(canvas &canvas) +cplot::draw_lines(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 = this->trans(); + viewport_scale(m); + canvas.scale(m); - 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++) + for (std::list<line>::iterator 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); + agg::conv_transform<path_type> ptr(p, m); + agg::conv_stroke<agg::conv_transform<path_type> > ps(ptr); + canvas.draw(ps, ln.color); + } +} - pl.width(0.2); +void +cplot::draw(canvas &canvas) +{ + update(); + draw_lines(canvas); +} - canvas.draw(tr, ln.color); +bool +cplot::update() +{ + if (bbox_update()) + { + 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); + return true; } + return false; +} + +void +cplot::viewport_scale(agg::trans_affine& m) +{ + const double xoffs = 0.09375, yoffs = 0.09375; + static agg::trans_affine rsz(1-2*xoffs, 0.0, 0.0, 1-2*yoffs, xoffs, yoffs); + trans_affine_compose (m, rsz); } diff --git a/agg-plot/cplot.h b/agg-plot/cplot.h index d5702e83..4e81c7fb 100644 --- a/agg-plot/cplot.h +++ b/agg-plot/cplot.h @@ -8,6 +8,7 @@ #include <list> #include "canvas.h" +#include "units.h" #include "agg_conv_transform.h" #include "agg_color_rgba.h" @@ -23,17 +24,26 @@ public: class cplot { public: - void add_line(line &ln); - void draw(canvas &canvas); + line& new_line(agg::rgba8 color); + + const agg::trans_affine& trans() const { return m_trans; }; - cplot() : m_lines(), m_trans_matrix(), m_x1(0.0), m_y1(0.0), - m_x2(1.0), m_y2(1.0) {}; + virtual void draw(canvas &canvas); + + cplot() : m_lines(), m_trans(), m_bbox_set(false) {}; + +protected: + void draw_lines(canvas &canvas); + bool bbox_update(); + virtual bool update(); + + static void viewport_scale(agg::trans_affine& trans); -private: std::list<line> m_lines; - agg::trans_affine m_trans_matrix; + agg::trans_affine m_trans; // bounding box + bool m_bbox_set; double m_x1, m_y1; double m_x2, m_y2; }; diff --git a/agg-plot/main.cpp b/agg-plot/main.cpp index f5845420..c0442b5e 100644 --- a/agg-plot/main.cpp +++ b/agg-plot/main.cpp @@ -20,7 +20,7 @@ #include "platform/agg_platform_support.h" #include "canvas.h" -#include "cplot.h" +#include "units_cplot.h" enum flip_y_e { flip_y = true }; @@ -30,21 +30,86 @@ 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); + { + line& ln = m_plot.new_line(agg::rgba(0.7, 0, 0)); + agg::path_storage& p = ln.path; + const int npt = 512, ncycles = 12; + for (int j = 0; j < npt; j++) + { + double x = j * 2 * M_PI * ncycles / npt; + double y = exp(-0.05 * x) * sin(x) +3; + if (j == 0) + p.move_to(x, y); + else + p.line_to(x, y); + } + } + + { + line& ln = m_plot.new_line(agg::rgba(0, 0, 0.7)); + agg::path_storage& p = ln.path; + + const int npt = 512, ncycles = 12; + for (int j = 0; j < npt; j++) + { + double x = j * 2 * M_PI * ncycles / npt; + double y = 1.8 * exp(-0.1 * x); + if (j == 0) + p.move_to(x, y); + else + p.line_to(x, y); + } + } + + { + line& ln = m_plot.new_line(agg::rgba(0, 0.7, 0)); + agg::path_storage& p = ln.path; + + const int npt = 2, ncycles = 12; + for (int j = 0; j < npt; j++) + { + double x = j * 2 * M_PI * ncycles / npt; + double y = 1.8; + if (j == 0) + p.move_to(x, y); + else + p.line_to(x, y); + } + } + /* + + { + line& ln = m_plot.new_line(agg::rgba(0, 0.7, 0)); + agg::path_storage& p = ln.path; + + const int npt = 1; + for (int j = 0; j <= npt; j++) + { + double x = j * 1.0 / npt; + double y = 1.0; + if (j == 0) + p.move_to(x, y); + else + p.line_to(x, y); + } + } + + { + line& ln = m_plot.new_line(agg::rgba(0.7, 0, 0)); + agg::path_storage& p = ln.path; + + const int npt = 1; + for (int j = 0; j <= npt; j++) + { + double x = j * 1.0 / npt; + double y = 0.0; + if (j == 0) + p.move_to(x, y); + else + p.line_to(x, y); + } + } + */ }; virtual ~the_application() @@ -59,7 +124,7 @@ public: } private: - cplot m_plot; + units_cplot m_plot; }; int agg_main(int argc, char* argv[]) diff --git a/agg-plot/units.cpp b/agg-plot/units.cpp deleted file mode 100644 index 5a9a8a30..00000000 --- a/agg-plot/units.cpp +++ /dev/null @@ -1,9 +0,0 @@ -
-#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 index ad30f2c0..1a0e8714 100644 --- a/agg-plot/units.h +++ b/agg-plot/units.h @@ -9,57 +9,35 @@ #include <string>
#include <vector>
+#include "utils.h"
+
template<class num_type>
class units {
private:
- int major;
+ int m_major;
int order;
- num_type dmajor; // equal to (major * 10^order)
- int inf, sup; // expressed in the base of (major * 10^order)
+ num_type dmajor; // equal to (m_major * 10^order)
+ int m_inf, m_sup; // expressed in the base of (m_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(): m_major(1), order(0), dmajor(1), m_inf(0), m_sup(1), nb_decimals(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);
+ int begin() const { return m_inf; };
+ int end() const { return m_sup; };
-};
+ void limits(int &start, int &fin, num_type &step)
+ { start = m_inf; fin = m_sup; step = dmajor; };
+ void mark_label (std::string& label, int mark) const;
+ num_type mark_value (int mark) const { return dmajor * mark; };
-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;
- }
+ num_type mark_scale(num_type x);
};
template<class num_type>
@@ -78,33 +56,25 @@ void units<num_type>::init(num_type yinf, num_type ysup, num_type spacefact) num_type delr = del / expf;
if (5 <= delr)
- major = 5;
+ m_major = 5;
else if (2 <= delr)
- major = 2;
+ m_major = 2;
else
- major = 1;
+ m_major = 1;
- inf = (int) floor(yinf / (major * expf));
- sup = (int) ceil(ysup / (major * expf));
+ m_inf = (int) floor(yinf / (m_major * expf));
+ m_sup = (int) ceil(ysup / (m_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);
+ dmajor = m_major * expf;
}
template<class num_type>
-void units<num_type>::mark_label (std::string &lab, int mark) const
+void units<num_type>::mark_label (std::string& lab, int mark) const
{
- bool minus = (inf < 0);
- int asup = (minus ? -inf : sup);
+ bool minus = (m_inf < 0);
+ int asup = (minus ? -m_inf : m_sup);
char fmt[8];
if (nb_decimals == 0)
@@ -127,10 +97,8 @@ void units<num_type>::mark_label (std::string &lab, int mark) const 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);
+ num_type xinf = m_inf * dmajor, xsup = m_sup * dmajor;
+ return (x - xinf) / (xsup - xinf);
}
#endif
diff --git a/agg-plot/units_cplot.cpp b/agg-plot/units_cplot.cpp new file mode 100644 index 00000000..d3805396 --- /dev/null +++ b/agg-plot/units_cplot.cpp @@ -0,0 +1,99 @@ +#include "units_cplot.h" + +#include "agg_vcgen_markers_term.h" +#include "agg_conv_stroke.h" +#include "agg_conv_dash.h" +#include "agg_gsv_text.h" + +void +units_cplot::draw_axis(canvas &canvas) +{ + typedef agg::path_storage path_type; + typedef agg::conv_dash<agg::conv_transform<path_type>, agg::vcgen_markers_term> dash_type; + + agg::trans_affine m; + viewport_scale(m); + canvas.scale(m); + + agg::path_storage ln; + agg::conv_transform<path_type> lntr(ln, m); + dash_type lndash(lntr); + agg::conv_stroke<dash_type> 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<agg::gsv_text> labs(lab); + agg::conv_transform<agg::conv_stroke<agg::gsv_text> > labo(labs, m); + std::string lab_text; + + labs.line_join(agg::round_join); + labs.line_cap(agg::round_cap); + labs.approximation_scale(m.scale()); + + lab.size(0.03, 0.02); + labs.width(1.5 * 1/max(m.sx, m.sy)); + m_uy.mark_label(lab_text, j); + lab.text(lab_text.c_str()); + + lab.start_point(-0.01 - lab.text_width(), y - 0.015); + canvas.draw(labo, agg::rgba(0, 0, 0)); + + 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<agg::gsv_text> labs(lab); + agg::conv_transform<agg::conv_stroke<agg::gsv_text> > labo(labs, m); + std::string lab_text; + + labs.line_join(agg::round_join); + labs.line_cap(agg::round_cap); + labs.approximation_scale(m.scale()); + + lab.size(0.03, 0.02); + labs.width(1.5 * 1/max(m.sx, m.sy)); + m_ux.mark_label(lab_text, j); + lab.text(lab_text.c_str()); + + lab.start_point(x - lab.text_width()/2.0, -0.025 - 0.03); + canvas.draw(labo, agg::rgba(0, 0, 0)); + + 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::rgba8(0.8, 0.8, 0.8)); + + agg::path_storage box; + agg::conv_transform<path_type> boxtr(box, m); + agg::conv_stroke<agg::conv_transform<path_type> > 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)); +}; diff --git a/agg-plot/units_cplot.h b/agg-plot/units_cplot.h new file mode 100644 index 00000000..d6a8ed86 --- /dev/null +++ b/agg-plot/units_cplot.h @@ -0,0 +1,47 @@ + +#include "cplot.h" +#include "units.h" + +class units_cplot : public cplot { +public: + virtual void draw(canvas &canvas) + { + update(); + draw_axis(canvas); + draw_lines(canvas); + }; + +private: + void draw_axis(canvas& can); + + virtual bool update() + { + bool updated = bbox_update(); + + if (! updated) + return false; + + m_ux = units<double>(m_x1, m_x2); + m_uy = units<double>(m_y1, 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); + m_trans = agg::trans_affine(fx, 0.0, 0.0, fy, -xi/fx, -yi/fy); + + return true; + } + + units<double> m_ux; + units<double> m_uy; +}; diff --git a/agg-plot/utils.cpp b/agg-plot/utils.cpp index 6b834ee7..b74a4736 100644 --- a/agg-plot/utils.cpp +++ b/agg-plot/utils.cpp @@ -2,15 +2,39 @@ #include <stdlib.h> #include <limits.h> +#include <string> +#include <stdarg.h> + #include "utils.h" void trans_affine_compose (agg::trans_affine& a, const agg::trans_affine& b) { + double a_tx = a.tx, a_ty = a.ty; + 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; + a.tx = b.sx * a_tx + b.shx * a_ty + b.tx; + a.ty = b.shy * a_tx + b.sy * a_ty + b.ty; +} + +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/utils.h b/agg-plot/utils.h index f760da08..c7245d77 100644 --- a/agg-plot/utils.h +++ b/agg-plot/utils.h @@ -1,8 +1,21 @@ #ifndef AGGPLOT_UTILS_H #define AGGPLOT_UTILS_H +#include <string> #include "agg_trans_affine.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; +} + extern void trans_affine_compose (agg::trans_affine& a, const agg::trans_affine& b); +extern void string_printf (std::string &s, const char *fmt, ...); + #endif diff --git a/examples/bessel.lua b/examples/bessel.lua new file mode 100644 index 00000000..497cf6df --- /dev/null +++ b/examples/bessel.lua @@ -0,0 +1,44 @@ + +function bessJ(x, n) + local f = |t| cos(n*t - x*sin(t)) -- we define the function to integrate + return 1/pi * integ {f= f, points={0, pi}} +end + +function bessJext(x,alpha) + local f1 = |t| cos(alpha*t - x*sin(t)) + local f2 = |t| exp(-x*sinh(t)-alpha*t) + local t1 = 1/pi * integ {f= f1, points={0, pi}} + local t2 = -sin(alpha*pi)/pi * integ {f= f2, points={0, '+inf'}} + return t1 + t2 +end + +function fact(n) + local p = n > 1 and n or 1 + for i=2,n-1 do p = p * i end + return p +end + +function bessJseriev1(x,alpha,nmax) + local a, m = 0, nmax + local t = (x/2)^2 + local sign = 1 - 2*(m % 2) + local c = sign / (fact(m) * fact(m + alpha)) + for k=0,m do + a = (a * t + c) + c = - c * (m-k) * (m-k+alpha) + end + return a * (x/2)^alpha +end + +function bessJserie(x, alpha, eps) + local a, c, p = 0, 1/fact(alpha), 1 + local t = (x/2)^2 + for n = 0, 100 do + a = a + c * p + local r = (n + 1) * (n + alpha + 1) + p = p * t + c = - c / r + if t / r < eps then break end + end + return a * (x/2)^alpha +end diff --git a/lua/src/lnum.h b/lua/src/lnum.h index ba3db44a..2690d6c0 100644 --- a/lua/src/lnum.h +++ b/lua/src/lnum.h @@ -83,7 +83,8 @@ int br_int= (int)br; - if ( ai!=0 && bi==0 && br_int==br && br_int!=0 && br_int!=INT_MIN ) { +// if ( ai!=0 && bi==0 && br_int==br && br_int!=0 && br_int!=INT_MIN ) { + if ( ar==0 && ai!=0 && bi==0 && br_int==br && br_int!=0 && br_int!=INT_MIN ) { /* (a+bi)^N, N = { +-1,+-2, ... +-INT_MAX } */ lua_Number k= luai_numpow( _LF(sqrt) (ar*ar + ai*ai), br ); |