/******************************************************** * ██████╗ ██████╗████████╗██╗ * ██╔════╝ ██╔════╝╚══██╔══╝██║ * ██║ ███╗██║ ██║ ██║ * ██║ ██║██║ ██║ ██║ * ╚██████╔╝╚██████╗ ██║ ███████╗ * ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝ * Geophysical Computational Tools & Library (GCTL) * * Copyright (c) 2023 Yi Zhang (yizhang-geo@zju.edu.cn) * * GCTL is distributed under a dual licensing scheme. You can redistribute * it and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either version 2 * of the License, or (at your option) any later version. You should have * received a copy of the GNU Lesser General Public License along with this * program. If not, see . * * If the terms and conditions of the LGPL v.2. would prevent you from using * the GCTL, please consider the option to obtain a commercial license for a * fee. These licenses are offered by the GCTL's original author. As a rule, * licenses are provided "as-is", unlimited in time for a one time fee. Please * send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget * to include some description of your company and the realm of its activities. * Also add information on how to contact you by electronic and paper mail. ******************************************************/ #ifndef _GCTL_CLIPLOT_H #define _GCTL_CLIPLOT_H #include #include #include #include #include #include #include #include "../utility/stream_t.h" namespace gctl { class cliplot { public: /** * @brief 构建一个新的画布对象 * * @param width 画布宽度(大于终端宽度则取终端宽度) * @param height 画布高度(大于终端高度则取终端高度) * @param xmin x轴最小值 * @param xmax x轴最大值 * @param ymin y轴最小值 * @param ymax y轴最大值 */ cliplot(size_t width, size_t height, double xmin, double xmax, double ymin, double ymax); virtual ~cliplot(); /** * @brief 清除画布数据 */ void clear(); /** * @brief 设置画布字符属性 * * @param w 字符列位置 * @param h 字符行位置 * @param sym 字符 * @param att 字符属性 */ void set(size_t w, size_t h, char sym, const std::string &att); void set_axis(int xt_num, int yt_num); void set_digs(int digs); void set_new_screen(bool new_screen); void set_wname(const std::string &wname); void set_hname(const std::string &hname); std::string axis_label(double num, int digs, int &odr); void plot_line(double x1, double x2, double y1, double y2, char s = '.', const std::string &t = GCTL_BOLDGREEN); template void plot_func(FuncOp func, char s = '.', const std::string &t = GCTL_BOLDGREEN); void plot_data(const std::vector &x, const std::vector &y, char s = '.', const std::string &t = GCTL_BOLDGREEN); void display(std::ostream &os = std::cout); private: bool new_screen_; int digs_; // 数字位数(包括小数点) int xl_num_; // x轴刻度数量 int yl_num_; // y轴刻度数量 double xmin_; // x轴最小值 double xmax_; // x轴最大值 double ymin_; // y轴最小值 double ymax_; // y轴最大值 double dx_, dy_; // x轴与y轴的刻度间隔 size_t w0_, h0_; // 原点的行与列位置 size_t width_; // 画布宽度 size_t height_; // 画布高度 std::vector sym_; // 画布字符 std::vector att_; // 画布字符属性 std::string wname_; std::string hname_; }; template void gctl::cliplot::plot_func(FuncOp func, char s, const std::string &t) { for (size_t w = w0_; w < width_; w++) { double y, x = xmin_ + (w - w0_)*(xmax_ - xmin_)/(width_ - 1 - w0_); y = func(x - 0.25*dx_); int h1 = round(h0_ - 1 - (y - ymin_)*(h0_ - 1)/(ymax_ - ymin_)); y = func(x + 0.25*dx_); int h2 = round(h0_ - 1 - (y - ymin_)*(h0_ - 1)/(ymax_ - ymin_)); if (h1 > h2) std::swap(h1, h2); for (size_t h = h1; h <= h2; h++) set(w, h, s, t); } return; } }; #endif // _GCTL_CLIPLOT_H