#include <windows.h> //1 
#include <stdio.h>  
#include <math.h>  
#include <time.h>  
#include <conio.h>    
SMALL_RECT SizeOfWindow(HANDLE hConsoleOutput)//2
{
    CONSOLE_SCREEN_BUFFER_INFO info;
    GetConsoleScreenBufferInfo(hConsoleOutput, &info);
    return info.srWindow;
} 
HANDLE CreateConsole(HANDLE handle_out)//3
{  
    CONSOLE_SCREEN_BUFFER_INFO info;   
    handle_out = GetStdHandle(STD_OUTPUT_HANDLE);    
    GetConsoleScreenBufferInfo(handle_out, &info);  
    SMALL_RECT rect =SizeOfWindow(handle_out); 
    COORD size={rect.Right+1,rect.Bottom+1};
    SetConsoleScreenBufferSize(handle_out, size);
    return handle_out;
}
void DrawSine(int Amp,int Fre,int Pha,COORD Cor,int WidScr)//4
{
    double *y;
    HDC hdc = 0;//5 
    HWND hwnd; 
    HPEN hPen, hPen2;//6  
    HPEN hPenOld;  
    TCHAR title[256];//7
    y = (double *)malloc(sizeof(double)*Fre);
    SetConsoleTitle("正弦波波形");
    GetConsoleTitle(title, 256);//8
    hwnd=FindWindow(0,title);//10 
    hdc = GetDC(hwnd);//9 
    hPen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0));//11
    hPen2 = CreatePen(PS_SOLID, 3, RGB(0, 0, 255));
    hPenOld = (HPEN)SelectObject(hdc, hPen);//12  
    while (!kbhit()||getch() != 0x1b)//13  
    {     
        hPenOld = (HPEN)SelectObject(hdc, hPen);
        for (int i = 0; i < Fre; i++)  //14
        {  
            y[i] = sin(0.1*i + Pha);//15
        }  
        #pragma warning (disable : 4244)
        MoveToEx(hdc, Cor.X, Cor.Y+y[0], NULL);//16 
        for (i = 0; i < Fre; i++)  
        {   
            #pragma warning (disable : 4244)
            LineTo(hdc,  i*(WidScr/Fre)  + Cor.X, 0.5 * Amp * y[i] + Cor.Y);//17  
        }           
        hPenOld = (HPEN)SelectObject(hdc, hPen2);//18 
        MoveToEx(hdc, Cor.X, Cor.Y, NULL);  
        LineTo(hdc, Cor.X + WidScr, Cor.Y);            
    } 
    DeleteObject(hPen);  
    DeleteObject(hPen2);
    ReleaseDC(hwnd,hdc);//19
    free(y);
}
  
int main()  
{  
    COORD Cor={0,200};//20
    int WidScr=1000;//21
    int Fre=500,Pha=0,Amp=300;//22
    HANDLE handle_out=0;
    CreateConsole(handle_out);
    DrawSine(Amp,Fre,Pha,Cor,WidScr);
    Fre=1000,Pha=0,Amp=300;
    DrawSine(Amp,Fre,Pha,Cor,WidScr);
    return 0;  
}

1---->引入Windows GDI图形函数

2---->获取窗口的尺寸

3---->创建无滚动条控制台窗口

4---->画正弦曲线,参数分别是幅度,频率,相位,屏幕分辨率

5---->HDC是WINDOWS的一种数据类型,是设备描述句柄,HWND是窗口句柄

6---->句柄类型,同样的还有 HBRUSH ,HFONT,HBITMAP,HPALETTE,HGRN等.句柄是由操作系统来定位对象的

      一种间接指针,操作系统可以用这个东西来定位到我们创建的对象

7---->TCHAR类似于char,只不过可以同时处理ANSI和UNICODE两种编码

8---->获取控制台窗口标题

9---->获取设备的设备环境。设备环境又叫设备描述表,它其实是GDI内部保存数据的一种数据结构。此结构中

      的属性内容与特定的输出设备(显示器、打印机等)相关,属性定义了GDI函数的工作细节。

10---->FindWindow获得一个顶层窗口的句柄,该窗口的类名和窗口名与给定的字符串相匹配

11---->建立画笔

12---->把一个对象(位图、画笔、画刷等)选入指定的设备描述表

13---->kbhit()获取键盘信息,键盘输入后返回指定字符,不输入返回0;getch()输入后返回指定字符,不输

       入不返回

14---->频率的本质是屏幕空间内总的采样点数,比如WidScr是屏幕包含的最大点数,那么Fre则是绘制曲线时

       的点数

15---->获取y坐标的值,系数0.1定义了曲线单周期内的采样点数,此时一个周期采样数为63个点

16---->将当前绘图位置移动到某个具体的点,同时也可获得之前位置的坐标,注意当前的坐标表示

17---->从当前位置连到一个指定的点。这个函数调用完毕,当前位置变成指定的点

18---->画坐标轴

19---->释放设备上下文环境(DC)供其他应用程序使用

20---->定义曲线的起始坐标

21---->定义整屏的可使用点数,分辨率,频率数值不能超过WidScr

22---->定义频率,相位和幅度,这些都是相对的

注意:如果动态数组的适用范围大于创建的范围,会出现DAMAGE: after Normal block的错误。举例double * a= new double [5],结果赋值的时候给a[5]=5。

问题:没有增加对于直流(频率为0)的处理;while循环或许可以去掉,不过偶尔会出现图像偏移;未加入颜色的控制。

结果:

2.png


点赞(2)
 

0.0分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 2 条评论

Lucien 6年前 回复TA

@验题君 嗯,我会补充的^-^

验题君 6年前 回复TA

能有截图和API的介绍用法,就更完美了!