206 lines
6.6 KiB
C++
206 lines
6.6 KiB
C++
/********************************************************
|
|
* ██████╗ ██████╗████████╗██╗
|
|
* ██╔════╝ ██╔════╝╚══██╔══╝██║
|
|
* ██║ ███╗██║ ██║ ██║
|
|
* ██║ ██║██║ ██║ ██║
|
|
* ╚██████╔╝╚██████╗ ██║ ███████╗
|
|
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
*
|
|
* 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 <sys/ioctl.h>
|
|
#include <unistd.h>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <iomanip>
|
|
#include <random>
|
|
#include <algorithm>
|
|
|
|
#include "../io/term_io.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);
|
|
|
|
/**
|
|
* @brief 设置坐标轴刻度数量
|
|
*
|
|
* @param xt_num x轴刻度数量
|
|
* @param yt_num y轴刻度数量
|
|
*/
|
|
void set_axis(int xt_num, int yt_num);
|
|
|
|
/**
|
|
* @brief 设置坐标轴刻度数字位数
|
|
*
|
|
* @param digs 数字位数
|
|
*/
|
|
void set_digs(int digs);
|
|
|
|
/**
|
|
* @brief 设置是否使用新的屏幕显示画布
|
|
*
|
|
* @param new_screen 是否使用新的屏幕显示画布
|
|
*/
|
|
void set_new_screen(bool new_screen);
|
|
|
|
/**
|
|
* @brief 设置坐标轴名称
|
|
*
|
|
* @param wname x轴名称
|
|
*/
|
|
void set_wname(const std::string &wname);
|
|
|
|
/**
|
|
* @brief 设置坐标轴名称
|
|
*
|
|
* @param hname y轴名称
|
|
*/
|
|
void set_hname(const std::string &hname);
|
|
|
|
/**
|
|
* @brief 绘制直线
|
|
*
|
|
* @param x1 直线起点x坐标
|
|
* @param x2 直线终点x坐标
|
|
* @param y1 直线起点y坐标
|
|
* @param y2 直线终点y坐标
|
|
* @param s 直线字符
|
|
* @param t 直线字符属性
|
|
*/
|
|
void plot_line(double x1, double x2, double y1, double y2, char s = '.', const std::string &t = GCTL_BOLDGREEN);
|
|
|
|
/**
|
|
* @brief 绘制函数
|
|
*
|
|
* @param func 函数
|
|
* @param s 函数字符
|
|
* @param t 函数字符属性
|
|
*/
|
|
template <typename FuncOp>
|
|
void plot_func(FuncOp func, char s = '.', const std::string &t = GCTL_BOLDGREEN);
|
|
|
|
/**
|
|
* @brief 绘制数据
|
|
*
|
|
* @param x x坐标
|
|
* @param y y坐标
|
|
* @param s 数据点字符
|
|
* @param t 数据点字符属性
|
|
*/
|
|
void plot_data(const std::vector<double> &x, const std::vector<double> &y, char s = '.', const std::string &t = GCTL_BOLDGREEN);
|
|
|
|
/**
|
|
* @brief 显示画布
|
|
*
|
|
* @param os 输出流
|
|
*/
|
|
void display(std::ostream &os = std::cout);
|
|
|
|
private:
|
|
/**
|
|
* @brief 计算坐标轴刻度标签
|
|
*
|
|
* @param num 数值
|
|
* @param digs 数字位数
|
|
* @param odr 数值的10的幂次
|
|
* @return std::string 坐标轴刻度标签
|
|
*/
|
|
std::string axis_label(double num, int digs, int &odr);
|
|
|
|
/**
|
|
* @brief 绘制坐标轴
|
|
*/
|
|
void plot_axis();
|
|
|
|
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<char> sym_; // 画布字符
|
|
std::vector<std::string> att_; // 画布字符属性
|
|
std::string wname_;
|
|
std::string hname_;
|
|
};
|
|
|
|
template <typename FuncOp>
|
|
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
|