再探win32绘制正弦图像的另一种方法:指定映射模式

原创 2017年04月09日 14:36:19

一、引言

之前我就转载过一篇博文,内容大概就是如何利用win32 SDK函数绘制出正弦图像。其中绘制的思路大概是这样的,因为windows默认的设备坐标系统是客户区坐标,即按照客户区左上角为原点(0, 0),以x轴向右,y轴向下,来计算坐标位置的。这样与我们熟悉的数学坐标系不一致,导致了我们费了九牛二虎之力才将不同坐标系之间的坐标进行了转换。想了解这种方法绘制正弦图像的,可以点击这里Win API绘制y = sinx函数图像

那么究竟可不可以在windows的窗口里,直接按照我们熟悉的数学坐标系,即原点居中,x轴向右,y轴向下来绘制我们的正弦图像呢?答案当然是可以的。

二、认识SetMapMode

Win32 SDK中有一个SetMapMode()函数,可以用来设置映射模式。那么什么叫做映射模式呢?

映射模式定义了页面空间单位到设备空间单位的转换,还定义了x轴和y轴的方向

也就是说,我们可以通过这个函数,来实现我们所思考着的(逻辑空间单位也就是虚拟坐标系)和实际我们看到的屏幕(设备空间单位也就是实实在在的设备显示)的坐标进行映射。比如我们想要把我们想象的虚拟坐标系的坐标原点与屏幕上的哪个点对应起来,就对应起来。

三、使用SetViewportOrgEx

使用这个函数,可以指定我们逻辑空间中的原点的位置与实际的窗口上的哪个点对应起来。

SetViewportOrgEx函数指定映射到窗口原点(0, 0)的设备原点的坐标。

四、开始写代码吧

这里将我写出来的代码粘贴如下,思路非常简单,看注释即可

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    RECT rect;
    static int cxClient, cyClient;

    switch (message)
    {
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        return 0;

    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        // 绘制辅助线
        MoveToEx(hdc, 0, cyClient / 2, NULL);
        LineTo(hdc, cxClient, cyClient / 2);
        MoveToEx(hdc, cxClient / 2, 0, NULL);
        LineTo(hdc, cxClient / 2, cyClient);

        // 设置当前映射模式为 MM_LOMETRIC,即每个逻辑单位映射为0.1毫米,x轴向右,y轴向上
        // 这样将窗口的映射模式类同于数学中的坐标系模式
        SetMapMode(hdc, MM_LOMETRIC);
        // 指定映射到窗口原点(0, 0)的设备原点的坐标,即指定哪个设备原点将映射到逻辑原点(0, 0)
        // 这里是指定的窗口的最左侧居中的位置为我们的逻辑原点(0, 0)在实际的设备上的映射
        // 这里指定的是窗口中心为坐标系原点位置,符合数学习惯
        SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, NULL);
        // 这里从最左边居中的位置开始绘制正弦图像
        MoveToEx(hdc, -cxClient / 2, 0, NULL);
        for (double x = -cxClient / 2; x < cxClient / 2; x += 0.01) {
            // 这里的两个坐标都进行了一部分的放大,其中x += 0.01 是为了细分曲线
            LineTo(hdc, x * 200, sin(x) * 300);
        }

        EndPaint(hwnd, &ps);
        return 0;

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

五、总结

写出这个代码很简单,重点是要理解windows的以下几个概念:
1. 逻辑单位和设备单位
2. 逻辑坐标和设备坐标
3. windows的三种设备坐标系统
这三个概念就不写出答案了,有心的人自然可以查出来,理解才是关键。

版权声明:本文为博主原创文章,未经博主允许不得转载哦 (ÒωÓױ) https://blog.csdn.net/u012814856/article/details/69815549

windows 下如何使用 Lua 语言绘制正弦函数图像?代码

Programming in lua 一书中第6章 再论函数,写了一个lua 实现绘制正弦函数的例子,但最后却说,“要想让这个例子正确的运行,你必须调整你的终端类型和代码中的控制符一致”,网上查了一下...
  • sinat_23079759
  • sinat_23079759
  • 2017-03-02 10:21:41
  • 438

<em>正弦</em>曲线的vb程序代码和exe完整文件

提供vb<em>中正弦</em>曲线图形的绘制,程序简洁易懂 ...gowine 2016-03-22 09:27:04 以为是.Net写的,...<em>Win32</em>程序基本概念.rar 立即下载 上传者: 老崇尚...
  • 2018年03月20日 00:00

再探win32绘制正弦图像的最优雅方法:DPtoLP

一、引言前面已经讨论了两种win32绘制正弦图像的方法,这里在学习小甲鱼的win32 SDK教程第27课时,看到了更加优雅的方法。使用设备坐标向逻辑坐标的转换。二、讨论三种绘制方案这里附上我之前讨论过...
  • u012814856
  • u012814856
  • 2017-04-09 15:18:47
  • 318

Android的Canvas绘制正弦函数图像

package com.baozilichao.test009; import android.graphics.Canvas; import android.graphics.Color; impo...
  • baozilichao
  • baozilichao
  • 2016-07-11 18:32:33
  • 421

win32窗口机制之CreateWindowEX

CreateWindow     函数功能:该函数创建一个重叠式窗口、弹出式窗口或子窗口。它指定窗口类,窗口标题,窗口   风格,以及窗口的初始位置及大小(可选的)。该函数也指定该窗口的父窗口或...
  • bladeandmaster88
  • bladeandmaster88
  • 2016-11-03 19:54:31
  • 1121

win32强化练习4.6_自定义图标或图像的工具栏

只有进行过充分的练习,才能够真正掌握一门技能!通过进行或单项或综合的知识点强化训练,巩固和提高自己的windows程序设计的技能水平!...
  • baidu_24190413
  • baidu_24190413
  • 2016-11-26 23:40:00
  • 760

C#画正余弦函数图像的简单例子

 float pi = 3.1415f;            Graphics g = e.Graphics;            g.PageUnit = GraphicsUnit.Inch; ...
  • lockepeak
  • lockepeak
  • 2008-05-26 11:45:00
  • 2412

用Java画的正弦函数 源代码

  • 2009年03月11日 18:08
  • 3KB
  • 下载

Win32/C++程序员面试考试题

一、单项选择题:(共12题,每题2分,共24分) 1. 下面哪一个不是C++的标准数据类型?              ( ) A. int                              ...
  • cmgg
  • cmgg
  • 2007-06-27 09:24:00
  • 1624

windows程序设计——绘制和更新

绘制和更新 WM_PAINT 大多数Windows 程式在WinMain 中进入讯息回圈之前的初始化期间都要呼叫函式UpdateWindow。Windows 利用这个机会给视窗讯息处理程式发送第一个W...
  • CSDNwei
  • CSDNwei
  • 2015-04-01 08:20:27
  • 354
收藏助手
不良信息举报
您举报文章:再探win32绘制正弦图像的另一种方法:指定映射模式
举报原因:
原因补充:

(最多只允许输入30个字)