天天看點

Windows控制台下繪制簡單圖形

最近接觸到一個很有意思的問題,如何在Windows控制台下畫圖,翻遍了C的頭檔案也沒找到畫圖的函數,好吧,那就用Windows提供的API函數吧,看來想移植是沒戲了。先畫一個簡單的圖,類似心電圖那種吧,假設得到的資料是縱坐标的值,橫坐标預設從0開始,每隔512uS(微秒的那個符号不會打)得到一個縱坐标值,要求将所有縱坐标值連起來,就以這個簡單的程式為例吧。

  

<a target="_blank" href=""></a>

#include &lt;windows.h&gt;

#include &lt;stdio.h&gt;

#include &lt;conio.h&gt;

#include "data.h"  //聲明了名為point的二維數組,以及記錄數組元素個數的NUMBER常量

//

//下列X-Y坐标平面的值取決于控制台的尺寸,需要根據實際情況進行調整

//起始X坐标

#define X_START 10

//結束X坐标

#define X_END 650

//每個值的X坐标增量,相當于512uS

#define X_INC 10

//Y坐标

#define Y 250

int main()

{

HWND hwnd;

HDC hdc;

int i;

//擷取console的裝置上下文句柄

hwnd = GetConsoleWindow();

hdc = GetDC(hwnd);

//調整一下console背景顔色,否則看不清線條

system("color 3D");

//起始位置,Windows中視窗的坐标系相當于直角坐标系第一象限翻轉到第四象限

MoveToEx(hdc,X_START,Y,NULL);

//畫基準坐标線

LineTo(hdc,X_END,Y);

//開始繪圖

for (i = 0; i &lt; NUMBER; i++)

LineTo(hdc,point[i].x,point[i].y);

}

_getch();

return 0;

  但是這個程式存在一個問題,就是如果控制台被其它視窗遮住後,已經繪制的線條不會重繪,也就意味着那部分線條看不見了,隻能重新運作程式,這個問題怎麼解決呢?我也不知道,不過可以将整個函數包含一個while循環裡,如果自己是頂層視窗就重新繪制,隻是這樣似乎代價太大了,呵呵。

  來看一下這個程式繪制的圖形吧。

  既然能繪制出線條自然就可以會繪制出柱形圖之類的圖形,稍微修改一下就可以了,代碼就不貼了,效果如下圖。

  上面這些都比較好畫,那麼如果畫圓呢?

  我想到兩種方法,第一種方法是計算,首先分别計算出最大和最小的X、Y值(xmin,xmax,ymin,ymax),然後根據X^2+Y^2=R^2,在for (x = xmin; x &lt;= xmax; x++)内部計算Y值,最後畫點就是了;這個應該是比較簡單的。

  第二種方法是掃描,左上角(xmin,ymin)、右上角(xmax,ymin)、左下角(xmin,ymax)和右下角(xmax,ymax)這四個點确定一個正方形,對正方形内部對每個點進行運算,也是根據X^2+Y^2=R2,隻是現在根據X和Y算出R0,然後跟R對比而已,而且比第一種方法多了一個判斷——是否到達行末,若到達行末則跳到下一行,若已經到了最後一行的最後一列,那就跳出循環。不過這個方法顯然比較奢侈,如果半徑增大n倍的話,計算量增大了n^2倍。就貼這種方法的代碼吧。

void circle(POINT *center,int radius)

int xmin = center-&gt;x - radius;

int xmax = center-&gt;x + radius;

int ymin = center-&gt;y - radius;

int ymax = center-&gt;y + radius;

POINT point;

point.x = xmin;

point.y = ymin;

MoveToEx(hdc,center-&gt;x,center-&gt;y - radius,NULL);

while (TRUE)

if (fabs(sqrt(pow2(point.x - center-&gt;x) + pow2(point.y - center-&gt;y)) - radius) &lt;= 1)

DrawPoint(hdc,&amp;point);

//是否到達行末

if (point.x == xmax)

if (point.y == ymax)

break;

else

point.y++;

continue;

point.x++;

  繪制的圓如下圖:

繼續閱讀