Win API绘制y = sinx函数图像

来源:互联网 发布:家庭网络布线公司 编辑:程序博客网 时间:2024/06/07 10:44

学习小甲鱼Win32 SDK 第17讲的时候,看到了正弦函数的绘制实现。觉得非常奇妙,这里非常感谢小甲鱼老师,另外附上详尽的备注代码。

#include <math.h>// 因为是使用折线绘画,所以当折线的顶点数量非常多的时候,我们就可以看到一条近似完美的曲线了!#define        NUM                1000                // 将 x 轴分成 1000 等份#define        TWOPI        (2 * 3.14159)        // 一个周期等于 2π……LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){        HDC hdc;        PAINTSTRUCT ps;        static int cxClient, cyClient;        POINT apt[NUM];        // 一千个点构成        int i;        switch (message)        {        /* 首先,我们需要让窗口在改变大小的时候,sin 函数的图形会跟着实时改变,所以我们这里需要响应 WM_SIZE 消息,            lParam 的低 16 位是客户区的宽,高 16 位是客户区的高。        */        case WM_SIZE:                cxClient = LOWORD(lParam);                cyClient = HIWORD(lParam);                return 0;        case WM_PAINT:                hdc = BeginPaint(hwnd, &ps);                // 先画一条 x 轴在客户区的 1/2 的位置                MoveToEx(hdc, 0, cyClient / 2, NULL);                LineTo(hdc, cxClient, cyClient / 2);                // 接着我们用一个循环,分别求出每个 x 对应的 y 值,然后把它画出来即可。                for (i = 0; i < NUM; i++)                {                        // 将 x 分为 1000 等份,然后将每一份的 x 坐标计算出来。                        apt[i].x = i * cxClient / NUM;                        /* 直接调用 sin 函数计算 y 值:api[i].y = (int)(sin(x))                            这里我们要显示一个周期(2π):api[i].y = (int)(sin(TWOPI * i / NUM))                            接下来是难点了:                            要把求得的 y 值显示在整个客户区内,正弦函数 y 值的取值范围是 -1 ~ 1,                            而我们的客户区是木有负数的范围,而且数学函数原点的位置跟客户区原点的位置不同,                            导致直接显示到客户区上的图像会倒过来。                            所以我们应该做一些转化:1 - sin(TWOPI * i / NUM)                            使得函数图像倒过来,并且 y 值的取值范围变成了 0 ~ 2,                            所以这里我们再乘上 cyClient / 2 即可完美显示!                        */                        apt[i].y = (int)(cyClient / 2 * (1 - sin(TWOPI * i / NUM)));                }                PolylineTo(hdc, apt, NUM);                EndPaint(hwnd, &ps);                return 0;        case WM_DESTROY:                PostQuitMessage(0);                return 0;        }        return DefWindowProc(hwnd, message, wParam, lParam);}

最后,再感谢下小甲鱼老师!!!

0 0
原创粉丝点击