2013-03-15 37 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);