再探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的三种设备坐标系统
这三个概念就不写出答案了,有心的人自然可以查出来,理解才是关键。

版权声明:本文为博主原创文章,未经博主允许不得转载哦 (ÒωÓױ)

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

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

利用Android的Canvas绘制正弦函数图像

一时兴起用android原生的基础绘制工具,绘制了一个正弦(余弦)函数图象,不多说,先上图: MainView.java类 package com.zhaofeng.main; import j...
  • u010982006
  • u010982006
  • 2013年11月15日 20:14
  • 4376

js实现正弦函数余弦函数图像

效果: 余弦图像 效果: 正弦图像 PS: 其实正弦与余弦道理完全一致(红点是div)以下是实现这个的代码 sin函数图像的实现 ...
  • zp1996323
  • zp1996323
  • 2015年09月21日 01:00
  • 1375

利用C语言绘制正弦函数

在已经会利用C语言绘制余弦函数的基础上,我们来进一步探索如何利用C语言绘制正弦函数。 问题分析:        很自然的,我们想到将acos(y)换成asin(y),不就可以把画余弦函数换...
  • ZM970307
  • ZM970307
  • 2017年04月25日 23:00
  • 1722

opencv图像映射

测试环境: win8 64 vs2008 opencv2.4.2 ================================================= 参考http://www...
  • XLcaoyi
  • XLcaoyi
  • 2016年05月07日 22:31
  • 607

ActionScript 正弦函数图像绘制

package { import flash.display.Sprite; import flash.text.TextField; import flash.text.TextFormat...
  • czh4869623
  • czh4869623
  • 2014年04月08日 15:00
  • 716

重温WIN32 API ------ 窗口上绘制位图文件

1 基本思路做界面仿真时,经常需要在窗口上贴图,随着图片数量的增多,通过资源文件中添加位图的方式会变得越来越不可控。所以本着“资源与程序分离“的原则,还是使用外部位图文件更加清晰明了。那么如何管理位图...
  • smstong
  • smstong
  • 2014年12月22日 18:49
  • 4427

MFC图形界面绘制坐标系及正弦曲线

本文介绍了如何利用MFC图形界面绘制坐标系及正弦曲线。
  • u010992313
  • u010992313
  • 2017年04月04日 12:14
  • 846

JAVA程序设计(15.2)----- 图形用户界面GUI 制作正玄曲线图

主要是练习界面设置 界面布局 添加组件 设置组件 接口 算出正弦曲线的横纵坐标然后一点一点连接 画出整个图形 package com.lovo.homework2; import java.aw...
  • Anubies
  • Anubies
  • 2014年11月08日 22:09
  • 1114

win32开发(绘制bitmap)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】    win32平台支持直接绘制bitmap图片,所以同学们可以从网上直接找一张图片来绘制。一般...
  • feixiaoxing
  • feixiaoxing
  • 2017年12月20日 21:35
  • 92
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:再探win32绘制正弦图像的另一种方法:指定映射模式
举报原因:
原因补充:

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