Sin和cos图表绘图仪…c++的一些算法错误

Sin and Cosine chart plotter.....some algorithm errors C++

本文关键字:算法 错误 c++ cos 绘图仪 Sin      更新时间:2023-10-16

我在这里创建了这个图表绘制程序。然而,我有一些小故障与它。首先,我应该描述一下这个程序是如何工作的。基本上使用stdscr和创建一个新的胜利,我必须创建一个"函数生成器"程序。字符将被打印在屏幕上,这将模拟正弦和余弦波形。当字符滚动窗口时,窗口将滚动。其中一个窗口将包含框架(页眉,行,页脚)。另一个窗口将滚动并打印正弦和余弦波形。我已经检查了我的代码很长一段时间了,无论我的错误是什么,我都不能弄清楚。

如果你仍然无法想象这个程序,想想pong…上下两条竖线,然后中间一条线穿过。在这个"法庭"/屏幕上,将打印正弦和余弦波。

我的错误是sin和cos没有打印我想要的方式…看来他们要走出纽温窗口的边界了。此外,脚将从10 0 -1指定将不会移动到我想要它在脚的位置。

#include <curses.h>
#include <math.h>
#include "fmttime.h"
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
enum colors
        {
        BLACK,
        RED,
        GREEN,
        YELLOW,
        BLUE,
        MAGENTA,
        CYAN,
        WHITE,
        };
void Sim_Advance(int degrees);          // Function prototype declarations
double Sim_Cos();
double Sim_Sin();
void frame(const char* title, int gridcolor, int labelcolor);
void mark(WINDOW* window, char ch, int color, double value);
static const double PI = (3.1415927/180); // Degrees to radian factor
static double PA = 0;                   // Phase angle
static int x;                           // X dimension of screen
static int y;                           // Y dimension of screen
static int delay1 = 300000;             // 300ms Delay
struct timeval tv;                      // Timeval object declaration
int main(void)
{
    initscr();                          // Curses.h initilizations
    cbreak();
    nodelay(stdscr, TRUE);
    noecho();

    int keyhit;
    int ctr = 1;                        // Exit flag
    int degrees = 10;                   // Interval to be added to phase
    int tempcounter = 1;
    char buf[32];                       // Buffer being sent to formattime
    size_t len = sizeof(buf);           // Size of buffer being passed
    gettimeofday(&tv, NULL);            // calling function for epoch time
    formatTime(&tv, buf, len);          // Calling formaTime for timestamp
    getmaxyx(stdscr,y,x);
    WINDOW* Window = newwin(y-4, x-2, 2, 5);
    scrollok(Window, TRUE);
    char cTitle[] = {"Real time Sine/ Cosine Plot"};  // Title string for plot

        while (ctr == 1)                // This will run the program till
        {                               // exit is detected (CTRL-X)
            usleep(delay1/6);           // Delays program execution
            keyhit = getch();
            mark(Window,'C', WHITE, Sim_Cos());

            mark(Window,'S', RED, Sim_Sin());
            Sim_Advance(degrees);       // Advances PA by "degrees" value (10)
                if (tempcounter == 1)
                {
                    frame(cTitle, WHITE, RED);  // Prints out the frame once
                    --tempcounter;
                }
                if (keyhit == 24)
                {
                    ctr = 0;            // Exit flag set
                }
        }
    endwin();
    return 0;
}
// Function will advance the Phase angle by assigned value of degrees
// The value of degrees must be an int and must be in radians
void Sim_Advance(int degrees)
{
    PA = PA + degrees;
    if (PA >=  360)
    {
        PA = PA - 360;
    }
}
// Calculates the Cos of the Phase angle and returns value to main
double Sim_Cos()
{
    double PARad;                       // Need to convert degrees into Radian
    PARad = (PA*PI);
    return cos(PARad);
}
// Calculates the Sin of the Phase angle and returns value to main
double Sim_Sin()
{
    double PARad2;                      // Variable to hold radian value
    PARad2 = (PA*PI);
    return sin(PARad2);
}
// Will print the grid and Axis of the display as well as a title for the display
// with variable background and/or foreground colors
void frame(const char* title, int gridcolor, int labelcolor)
{
    int offset = 27/2;                  // Middle of string
    int col = 0;
    int row = 0;
    int botline = 0;
    start_color();
    init_pair(0, labelcolor, BLACK);
    init_pair(1, gridcolor, BLACK);
    wmove(stdscr, 0, (x / 2)- offset);

    wprintw(stdscr,"%sn", title);
    wrefresh(stdscr);
    while (row != x)                    // This prints the top line
    {
        attrset(COLOR_PAIR(1));
        wprintw(stdscr,"-");
        wrefresh(stdscr);
        ++row;
    }
    while (col != y-4)                  // This prints the middle line
    {
        wmove(stdscr, col + 2, x/2);
        wprintw(stdscr, "|n");
        wrefresh(stdscr);
        ++col;
    }
    while (botline != x)                // Prints the bottom line
    {
        wprintw(stdscr, "-");
        wrefresh(stdscr);
        ++botline;
    }
    attrset(COLOR_PAIR(0));
    wmove(stdscr, y, 0);                // These three things commands
    wprintw(stdscr, "-1");              // Will print out the proper footer
    wrefresh(stdscr);

    wmove(stdscr, y, x/2);
    wprintw(stdscr, "0");
    wrefresh(stdscr);

    wmove(stdscr, y, x);
    wprintw(stdscr, "1");
    wrefresh(stdscr);
}
// Will print out the characters passed to it in the designated
// window to which it points to.
void mark(WINDOW* window, char ch, int color, double value)
{
    int cursep = (((x/2) * value) + (x/2)); // Prints character from middle
    int currenty = getcury(window);         // of screen
    wmove(window, currenty+1, cursep-3);    // Moves cursor to desired location
    wrefresh(window);
    usleep(delay1);
    waddch(window, ch);
    wrefresh(window);
}

部分解决方案(简化的帖子将有助于OP和SO)

  1. 使用double PI = (M_PI/ 180);或3.141592653589793/180

  2. 将正双精度转换为整型向下舍入,将负双精度转换为整型向上舍入。因此避免在0的两边都使用double to int

  3. 宽度为x。把屏幕想象成横跨的x盒子。第0框的中心的值为-1.0。框x-1的中心值为+1.0。因此,中心到中心的距离为x-1个方框。

改变
int cursep = (((x / 2) * value) + (x / 2));

void mark() {
...
// value = -1.0 --> cursep = 0
// value = +1.0 --> cursep = x - 1
// ** Adjust these 4 vars as needed to re-map your translation **
double val_min = -1.0;
double val_max = +1.0;
int  cur_min = 0;
int  cur_max = x - 1;
//  y = (y1-y0)/(x1-x0)*(x-x0) + y0
double cur_d = (cur_max - cur_min)/(val_max - val_min)*(value - val_min) + cur_min;
int cursep = floor(cur_d + 0.5);

4 wmove(window, currenty + 1, cursep - 3);-3不清楚