2013-03-15 76 views
0

所以我在这里创建了这个图表绘图程序。但是我有一些小故障。首先我应该描述这个计划是如何工作的。基本上使用stdscr并创建一个新的胜利,我必须创建一个“函数发生器”程序。 Charcaters将被打印在屏幕上,以模拟正弦和余弦波形。随着字符向下滚动窗口,窗口将滚动。其中一个窗口将包含框架(标题,行,页脚)。另一个窗口将滚动并打印正弦和余弦波形。我现在一直在检查我的代码,无论它是什么样的错误,我都搞不明白。Sin和余弦图表绘图仪.....一些算法错误C++

如果您在设想程序时仍然遇到麻烦,请考虑pong ... 2条垂直线条的顶部和底部,然后是一条穿过中间的线条。在这个“法庭”/屏幕上,正弦和余弦波将被打印。

我的错误是,罪和余弦不是按我想要的方式打印......看起来他们正在走出Newwin窗口的边界。另外,将从1 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,"%s\n", 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); 
} 
+2

明确-3在你的代码后摆脱了行号。他们使我们身边的调试几乎不可能。 – WhozCraig 2013-03-15 16:31:40

+0

抱歉,编辑没有数字! – PresidentRFresh 2013-03-15 16:36:34

回答

0

部分溶液(简化后有助于OP和SO)

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

  2. 转换正双为int回合下来,负双为int轮向上。因此,避免在两侧的两倍于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);