硬汉嵌入式论坛

 找回密码
 立即注册
查看: 2422|回复: 7
收起左侧

[emWin教程入门篇] 【emWin实战教程V2.0】第14章      2D图形库之绘制

[复制链接]

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
发表于 2017-1-7 16:30:39 | 显示全部楼层 |阅读模式
完整65章+12章附件教程下载地址:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=19834


第14章      2D图形库之绘制图形



    本期主要讲解2D图形库的图形绘制,包括绘制多边形,绘制圆,绘制椭圆,绘制弧线,绘制线图,绘制饼图。本章节的例子不用在开发板上面做调试,直接用emWin模拟器即可。
    学习本章节,务必保证已经学习了第6章和第8章。本章节提供的模拟器演示代码都是可以在模拟器上面运行的,使用方法是将GUIDEMO_Start.c文件里面的所有内容删掉并将本章节提供的代码复制到GUIDEMO_Start.c文件即可运行。

14.1初学者重要提示
14.2绘制多边形
14.3绘制圆
14.4显示屏绘制的圆为什么不圆
14.4绘制椭圆
14.5绘制弧线
14.6绘制线图
14.7绘制饼图
14.8 总结



14.1  初学者重要提示

1、2D函数的图形绘制就是一些API函数,从应用上来讲,基本没有什么难度,初学者多做练习,调用几次就熟练了。

2、2D绘图的所有API函数在emWin手册中都有讲解,下图是中文版手册里面API函数的位置

14.1.png


    下图是英文版手册里面API函数的位置:
14.2.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-7 16:34:17 | 显示全部楼层
14.2 绘制多边形


    当前emWin支持的多边形函数主要有以下5个:
14.3.png

    下面我们通过如下三个实例来讲解这几个API函数的用法。

14.2.1    例子一


    这个例子主要涉及到以下三个函数:
(1)void GUI_DrawPolygon(constGUI_POINT * pPoint, int NumPoints, int x, int y)
     根据用户设置的坐标点(x,y)位置,将点列表pPoint中的NumPoints个坐标点连接,最终绘制出一个闭合的多边形。
(2)voidGUI_EnlargePolygon(GUI_POINT * pDest, const GUI_POINT * pSrc, int NumPoints,int Len)
     将点列表pSrc中的NumPoints个坐标点按指定的像素个数Len全方位扩展,并将最终结果赋值给新的点列表pDest,这个新的点列表就是扩展后的多边形坐标点。
(3)voidGUI_FillPolygon(const GUI_POINT * pPoint, int NumPoints, int x, int y)
     根据用户设置的坐标点(x,y)位置,将点列表pPoint中的NumPoints个坐标点连接,最终绘制出一个填充的多边形。
下面是在模拟器上实际运行的例子:
  1. #include "GUI.h"
  2. /* 图形的原始坐标点 */
  3. const GUI_POINT aPoints[] = {
  4. { 40, 20},
  5. { 0, 20},
  6. { 20, 0}
  7. };
  8. /* 用于存储放大后的坐标点 */
  9. GUI_POINT aEnlargedPoints[GUI_COUNTOF(aPoints)];
  10. void Sample(void) {
  11.     int i;
  12.      /* 清屏 */
  13.     GUI_Clear();
  14.     /* 设置绘图模式 */
  15.     GUI_SetDrawMode(GUI_DM_XOR);
  16.    
  17.     /* 绘制多边形 */
  18.     GUI_FillPolygon(aPoints,              /* 指向要显示和填充的多边形 */
  19.                     GUI_COUNTOF(aPoints), /* 点列表中指定的点数量 */
  20.                     140,                  /* 原点的X位置 */
  21.                     110);                 /* 原点的Y位置 */
  22.     for (i = 1; i < 10; i++) {
  23.         GUI_EnlargePolygon(aEnlargedPoints,      /* 指向目标多边形 */
  24.                            aPoints,              /* 指向源多边形 */
  25.                            GUI_COUNTOF(aPoints), /* 点列表中指定的点数量 */
  26.                            i * 5);               /* 扩展多边形的长度 (像素) */
  27.         /* 绘制放大后的多边形 */
  28.         GUI_FillPolygon(aEnlargedPoints, GUI_COUNTOF(aPoints), 140, 110);
  29.     }
  30. }
  31. /*********************************************************************
  32. *
  33. *       MainTask
  34. */
  35. void MainTask(void) {
  36.   /* emWin初始化 */
  37.   GUI_Init();
  38.   /* 调用测试函数 */
  39.   Sample();
  40.   while (1)
  41.   {
  42.        GUI_Delay(10);
  43.   }
  44. }
复制代码
显示效果如下:
14.4.png


14.2.2  例子二


voidGUI_MagnifyPolygon(GUI_POINT * pDest, const GUI_POINT * pSrc, int NumPoints,int Mag);
    此函数可以按照用户设置的放大系数Mag放大多边形。另外请注意,扩展和放大多边形之间的区别,比如调用函数GUI_EnlargePolygon()(参数Len= 1)是将多边形的所有边扩展1像素,而调用GUI_MagnifyPolygon()(参数Mag= 1)则没有效果。

下面是在模拟器上面实际运行的例子:
  1. #include "GUI.h"
  2. /* 图形的原始坐标点 */
  3. const GUI_POINT aPoints[] = {
  4. { 0, 20},
  5. { 40, 20},
  6. { 20, 0}
  7. };
  8. /* 用于存储放大后的坐标点 */
  9. GUI_POINT aMagnifiedPoints[GUI_COUNTOF(aPoints)];
  10. void Sample(void) {
  11.     int Mag, y = 0, Count = 4;
  12.      /* 清屏 */
  13.     GUI_Clear();
  14.    
  15.      /* 设置前景色,即所绘制图形的颜色 */
  16.     GUI_SetColor(GUI_GREEN);
  17.     for (Mag = 1; Mag <= 4; Mag *= 2, Count /= 2) {
  18.         int i, x = 0;
  19.          /* 放大多边形 */
  20.         GUI_MagnifyPolygon(aMagnifiedPoints, aPoints, GUI_COUNTOF(aPoints), Mag);
  21.          /* 绘制填充的多边形 */
  22.         for (i = Count; i > 0; i--, x += 40 * Mag) {
  23.             GUI_FillPolygon(aMagnifiedPoints, GUI_COUNTOF(aPoints), x, y);
  24.         }
  25.         y += 20 * Mag;
  26.     }
  27. }
  28. /*********************************************************************
  29. *
  30. *       MainTask
  31. */
  32. void MainTask(void) {
  33.   /* emWin初始化 */
  34.   GUI_Init();
  35.   /* 调用测试函数 */
  36.   Sample();
  37.   while (1)
  38.   {
  39.        GUI_Delay(10);
  40.   }
  41. }
复制代码
实际显示效果如下:
14.5.png


14.2.3  例子三


    这个多边形的例子是官方提供的,例子所在的位置如下:
14.6.png

显示效果如下:
14.7.png
14.8.png
14.9.png

指出官方例子的所在位置和演示现象是为了方便用户以后做项目来参考。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-7 16:35:26 | 显示全部楼层
14.3   绘制圆


voidGUI_DrawCircle(int x0, int y0, int r);
    在当前窗口中的指定位置(x0, y0)绘制半径为r的圆圈。
下面是在模拟器上面实际运行的例子:
  1. #include "GUI.h"
  2. void ShowCircles(void)
  3. {
  4.     int i;
  5.      /* 绘制圆圈 */
  6.     for (i=10; i<50; i += 3)
  7.     GUI_DrawCircle(120, 60, i);
  8. }
  9. /*********************************************************************
  10. *
  11. *       MainTask
  12. */
  13. void MainTask(void) {
  14.   /* emWin初始化 */
  15.   GUI_Init();
  16.   /* 调用测试函数 */
  17.   ShowCircles();
  18.   while (1)
  19.   {
  20.        GUI_Delay(10);
  21.   }
  22. }
复制代码
实际显示效果如下:
14.10.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-7 16:36:12 | 显示全部楼层


14.4   显示屏绘制的圆为什么不圆

    这个问题经常有初学者会问,比如这个帖子:http://www.armbbs.cn/forum.php?mod=viewthread&tid=3899 。用户在显示屏上面绘制圆圈,显示出来的效果是这个样子的:
14.11.png
给人的感觉是圆圈不够圆,实际上是因为显示屏的每个像素点的长度和宽度不是1:1的,从而造成显示出来的效果有点扁。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-7 16:37:46 | 显示全部楼层
14.5   绘制椭圆



(1)void GUI_DrawEllipse(int x0, int y0, int rx, int ry)
    在当前窗口中的指定位置(x0,y0)绘制x轴方向半径为rx,y轴方向半径为ry的椭圆。
(2)void GUI_FillEllipse(int x0, int y0, int rx, int ry)
    在当前窗口中的指定位置(x0,y0)绘制x轴方向半径为rx,y轴方向半径为ry的填充的椭圆。
下面是在模拟器上面实际运行的例子:
  1. #include "GUI.h"
  2. /*********************************************************************
  3. *
  4. *       MainTask
  5. */
  6. void MainTask(void) {
  7.   /* emWin初始化 */
  8.   GUI_Init();
  9.   /* 绘制填充的椭圆 */
  10.   GUI_SetColor(GUI_RED);  
  11.   GUI_FillEllipse(100, 100, 50, 70);
  12.   /* 绘制椭圆 */
  13.   GUI_SetColor(GUI_GREEN);   
  14.   GUI_DrawEllipse(100, 100, 60, 80);
  15.    /* 绘制填充的椭圆 */
  16.   GUI_SetColor(GUI_BLACK);   
  17.   GUI_FillEllipse(100, 100, 10, 50);
  18.   while (1)
  19.   {
  20.        GUI_Delay(10);
  21.   }
  22. }
复制代码
实际现象效果如下:
14.12.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-7 16:39:09 | 显示全部楼层
14.6 绘制弧线


voidGUI_DrawArc(int xCenter, int yCenter, int rx, int ry, int a0, int a1)
    在当前窗口中的指定位置(xCenter,yCenter)绘制x轴方向半径为rx,y轴方向半径为ry,起始角度为a0,结束角度为a1的弧线。
    注意,当前参数ry未使用,是以rx代替的,也就是说绘制的弧线是圆弧。
下面是在模拟器上面实际运行的例子:
  1. #include "GUI.h"
  2. #include "math.h"
  3. #include "stdio.h"
  4. void DrawArcScale(void)
  5. {
  6.     int x0 = 160;
  7.     int y0 = 160;
  8.     int i;
  9.     char ac[4];
  10.    
  11.      /* 设置背景色为白色并清屏 */
  12.     GUI_SetBkColor(GUI_WHITE);
  13.     GUI_Clear();
  14.    
  15.      /* 设置画笔大小 */
  16.     GUI_SetPenSize( 5 );
  17.      /* 设置文本模式,字体和前景色 */
  18.     GUI_SetTextMode(GUI_TM_TRANS);
  19.     GUI_SetFont(&GUI_FontComic18B_ASCII);
  20.     GUI_SetColor(GUI_BLACK);
  21.      /* 绘制圆弧 */
  22.     GUI_DrawArc( x0,y0,150, 150,-30, 210 );
  23.      /* 在圆弧上面显示刻度和相应刻度的数值 */
  24.     for (i=0; i<= 23; i++) {
  25.         float a = (-30+i*10)*3.1415926/180;
  26.         int x = -141*cos(a)+x0;
  27.         int y = -141*sin(a)+y0;
  28.         if (i%2 == 0)
  29.         GUI_SetPenSize( 5 );
  30.         else
  31.         GUI_SetPenSize( 4 );
  32.         GUI_DrawPoint(x,y);
  33.         if (i%2 == 0) {
  34.             x = -123*cos(a)+x0;
  35.             y = -130*sin(a)+y0;
  36.             sprintf(ac, "%d", 10*i);
  37.             GUI_SetTextAlign(GUI_TA_VCENTER);
  38.             GUI_DispStringHCenterAt(ac,x,y);
  39.         }
  40.     }
  41. }
  42. /*********************************************************************
  43. *
  44. *       MainTask
  45. */
  46. void MainTask(void) {
  47.    /* 初始化emWin */
  48.    GUI_Init();
  49.    /* 绘制饼图 */
  50.    DrawArcScale();
  51.    while (1)
  52.    {
  53.        GUI_Delay(10);
  54.    }
  55. }
复制代码
实际显示效果如下:
14.13.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-7 16:40:20 | 显示全部楼层
14.7 绘制曲线


voidGUI_DrawGraph(I16 * paY, int NumPoints, int x0, int y0)
    根据用户设置的起始坐标(x0,y0),依次将NumPoints个点坐标
(x0+0,  y0+*(paY +0)))
(x0+1,  y0+*(paY +1)))
(x0+2,  y0+*(paY +2)))
(x0+3,  y0+*(paY +3)))
…………
(x0+NumPoints-2,  y0+*(paY+NumPoints-2)))
(x0+NumPoints-1,  y0+*(paY+NumPoints-1)))
     连接起来绘制成曲线。
下面是在模拟器上面实际运行的例子
  1. #include "GUI.h"
  2. #include <stdlib.h>
  3. I16 aY[200];
  4. /*********************************************************************
  5. *
  6. *       MainTask
  7. */
  8. void MainTask(void) {
  9.   int i;
  10.   /* 初始化emWin */
  11.   GUI_Init();
  12.   /* 获取随机数 */
  13.   for (i = 0; i < GUI_COUNTOF(aY); i++)
  14.   {
  15.      aY[i] = rand() % 50;
  16.   }
  17.   /* 绘制波形 */
  18.   GUI_SetColor(GUI_YELLOW);
  19.   GUI_DrawGraph(aY, GUI_COUNTOF(aY), 0, 0);
  20.   while (1)
  21.   {
  22.        GUI_Delay(10);
  23.   }
  24. }
复制代码
实际显示效果如下:
14.14.png
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2017-1-7 16:41:35 | 显示全部楼层


14.8   绘制饼图

voidGUI_DrawPie(int x0, int y0, int r, int a0, int a1, int Type)
    绘制圆形扇区。
    在当前窗口中的指定位置(x0,y0)绘制以r为半径,起始角度为a0,结束角度为a1的圆形扇区。
下面是在模拟器上面实际运行的例子:
  1. #include "GUI.h"
  2. /* 变量 */
  3. int i, a0, a1;
  4. const unsigned aValues[] = { 100, 135, 190, 240, 340, 360};
  5. const GUI_COLOR aColors[] = { GUI_BLUE, GUI_GREEN, GUI_RED,
  6.                               GUI_CYAN, GUI_MAGENTA, GUI_YELLOW };
  7. /*********************************************************************
  8. *
  9. *       MainTask
  10. */
  11. void MainTask(void) {
  12.   int i;
  13.   /* 初始化emWin */
  14.   GUI_Init();
  15.   /* 绘制饼图 */
  16.   for (i = 0; i < GUI_COUNTOF(aValues); i++) {
  17.      a0 = (i == 0) ?0 :aValues[i - 1];
  18.      a1 = aValues[i];
  19.      GUI_SetColor(aColors[i]);
  20.      GUI_DrawPie(100, 100, 50, a0, a1, 0);
  21.   }
  22.   while (1)
  23.   {
  24.        GUI_Delay(10);
  25.   }
  26. }
复制代码
实际显示效果如下:
14.15.png


14.9 总结

    关于2D图形库的绘图部分就跟大家讲这么多,还是那句话,多多练习,熟能生巧。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-16 17:02 , Processed in 0.416586 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表