Windows可以画直线、椭圆线(椭圆圆周上的曲线)和贝塞尔曲线。Windows 98支援的7个画线函数是:

LineTo 画直线。

Polyline和PolylineTo 画一系列相连的直线。

PolyPolyline 画多组相连的线。

Arc 画椭圆线。

PolyBezier和PolyBezierTo 画贝塞尔曲线。

另外,Windows NT还支持3种画线函数:

ArcTo和AngleArc 画椭圆线。

PolyDraw 画一系列相连的线以及贝塞尔曲线。

这三个函数Windows 98不支援。

在本章的后面我将介绍一些既画线也填入所画图形的封闭区域的函数,这些函数是:

Rectangle 画矩形。

Ellipse 画椭圆。

RoundRect 画带圆角的矩形。

Pie 画椭圆的一部分,使其看起来像一个扇形。

Chord 画椭圆的一部分,以呈弓形。

设备内容的五个属性影响着用这些函数所画线的外观:目前画笔的位置(仅用于LineTo、PolylineTo、PolyBezierTo和ArcTo )、画笔、背景方式、背景色和绘图模式。

画一条直线,必须呼叫两个函数。第一个函数指定了线的开始点,第二个函数指定了线的终点:

MoveToEx (hdc, xBeg, yBeg, NULL) ;

LineTo (hdc, xEnd, yEnd) ;

MoveToEx实际上不会画线,它只是设定了设备内容的「目前位置」属性。然后LineTo函数从目前的位置到它所指定的点画一条直线。目前位置只是用于其它几个GDI函数的开始点。在内定的设备内容中,目前位置最初设定在点(0,0)。如果在呼叫LineTo之前没有设定目前位置,那么它将从显示区域的左上角开始画线。

小历史:

Windows的16位版本中,用来改变目前位置的函数是MoveTo。该函数只调整三个参数-设备内容句柄、x和y坐标。函数通过两个16位数拼成的32位无正负号长整数传回先前的目前位置。然而,在Windows的32位版本中,坐标是32位的数值,而C的32位版本中又没有定义64位的整数数据型态,因此这种改变意味着MoveTo在其传回值中不再指出先前的目前位置。在实际的程序写作中,由MoveTo传回的值几乎从来不用,因此就需要一个新函数,这就是MoveToEx。

MoveToEx的最后一个参数是指向POINT结构的指针。从该函数传回后,POINT结构的x和y字段指出了先前的目前位置。如果您不需要这种信息(通常如此),可以简单地如上面的例子所示的那样将最后一个参数设定为NULL。

警告:

尽管Windows 98中的坐标值看起来是32位的,实际上却只用到了低16位,坐标值实际上被限制在-32,768到32,767之间。在Windows NT中,使用完整的32位值。

如果您需要目前位置,就可以通过以下呼叫获得:

GetCurrentPositionEx (hdc, &pt) ;

其中,pt是POINT结构的。

下面的程序代码从窗口的左上角开始,在显示区域中画一个网格,线与线之间相隔100个图素,其中hwnd是窗口句柄,hdc是设备内容句柄,而x和y是整数:

GetClientRect (hwnd, &rect) ;

for ( x = 0 ; x < rect.right ; x+= 100)

{

MoveToEx (hdc, x, 0, NULL) ;

LineTo (hdc, x, rect.bottom) ;

}

for (y = 0 ; y < rect.bottom ; y += 100)

{

MoveToEx (hdc, 0, y, NULL) ;

LineTo (hdc, rect.right, y) ;

}

虽然用两个函数来画一条直线显得有些麻烦,但是在希望画一组相连的直线时,目前画笔位置属性又会变得很有用。例如,您可能想定义一个包含5个点(10个值)的数组,来画一个矩形的边界框:

POINT apt[5] = { 100, 100, 200, 100, 200, 200, 100, 200, 100, 100 } ;

注意,最后一个点与第一个点相同。现在,只需要使用MoveToEx移到第一个点,并对后面的点使用LineTo:

MoveToEx (hdc, apt[0].x, apt[0].y, NULL) ;

for ( i = 1 ; i < 5 ; i++)

LineTo (hdc, apt[i].x, apt[i].y) ;

由于LineTo从目前位置画到(但不包括)LineTo函数中给出的点,所以这段程序代码没有在任何坐标处画两次。虽然在显示器上多输出几次不存在问题,但是在绘图机上或者在其它绘图方式(下面马上会讲到)下,视觉效果就不太好了。

当您要将数组中的点连接成线时,使用Polyline函数要简单得多。下面这条叙述画出与上面一段程序代码相同的矩形:

Polyline (hdc, apt, 5) ;

最后一个参数是点的数目。我们还可以使用(sizeof (apt) / sizeof (POINT))来表示这个值。Polyline与一个MoveToEx函数后面加几个LineTo函数的效果相同,但是,Polyline既不使用也不改变目前位置。PolylineTo有些不同,这个函数使用目前位置作为开始点,并将目前位置设定为最后一根线的终点。下面的程序代码画出与上面所示一样的矩形:

MoveToEx (hdc, apt[0].x, apt[0].y, NULL) ;

PolylineTo (hdc, apt + 1, 4) ;

您可以对几条线使用Polyline和PolylineTo,这些函数在绘制复杂曲线最有用了。您使用由几百甚至几千条线组成的极短线段,把它们连在一起就像一条曲线一样。例如,画正弦波就是这样的,程序5-2所示的SINEWAVE程序显示了如何做到这一点。

程序5-2 SINEWAVE

SINEWAVE.C

/*-------------------------------------------------------------------

SINEWAVE.C -- Sine Wave Using Polyline

(c) Charles Petzold, 1998

---------------------------------------------------------------------*/

#include

#include

#define NUM 1000

#define TWOPI (2 * 3.14159)

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

static TCHAR szAppName[] = TEXT ("SineWave") ;

HWND hwnd ;

MSG msg ;

WNDCLASS wndclass ;

wndclass.style = CS_HREDRAW | CS_VREDRAW ;

wndclass.lpfnWndProc= WndProc ;

wndclass.cbClsExtra = 0 ;

wndclass.cbWndExtra = 0 ;

wndclass.hInstance = hInstance ;

wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;

wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ;

wndclass.lpszMenuName = NULL ;

wndclass.lpszClassName = szAppName ;

if (!RegisterClass (&wndclass))

{

MessageBox ( NULL, TEXT ("Program requires Windows NT!"),

szAppName, MB_ICONERROR) ;

return 0 ;

}

hwnd = CreateWindow ( szAppName, TEXT ("Sine Wave Using Polyline"),

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT,

NULL, NULL, hInstance, NULL) ;

ShowWindow (hwnd, iCmdShow) ;

UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

static int cxClient, cyClient ;

HDC hdc ;

int i ;

PAINTSTRUCT ps ;

POINT apt [NUM] ;

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) ;

for (i = 0 ; i < NUM ; i++)

{

apt[i].x = i * cxClient / NUM ;

apt[i].y = (int) (cyClient / 2 * (1 - sin (TWOPI * i / NUM))) ;

}

Polyline (hdc, apt, NUM) ;

return 0 ;

case WM_DESTROY:

PostQuitMessage (0) ;

return 0 ;

}

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

}

这个程序有一个含有1000个POINT结构的数组。随着for循环从0增加到999,结构的x成员设定为从0递增到数值cxClient。结构的y成员设定为一个周期的正弦曲线值,并被放大以填满显示区域。整个曲线的绘制仅仅使用了一个Polyline呼叫。因为Polyline函数是在设备驱动程序层次上实作的,因此它要比呼叫1000次LineTo快得多,结果如图5-5所示。

c语言坐标画直线函数,三、Windows图像处理—画点和线(直线)相关推荐

  1. 求图像边界点坐标c语言,三、Windows图像处理—画点和线(边框函数)

    下面我想讨论的是Arc函数,它绘制椭圆曲线.然而,如果不先讨论一下Ellipse函数,那么Arc函数将难以理解:而如果不先讨论Rectangle函数,那么Ellipse函数又将难以理解:而如果讨论El ...

  2. html根据坐标画圆,Canvas三种动态画圆实现方法说明(小结)

    前言 canvas是HTML5出来的绘图API容器,对于图形的处理非常强大,下面使用canvas配合JavaScript来做一下动态画圆效果.可以用它来做圆形进度条来使用. 这里我个人总结了3种实现方 ...

  3. 转:C语言面试题大汇总 (图像处理方向)

    C语言面试题大汇总 (图像处理方向) C语言面试题大汇总 1.局部变量能否和全局变量重名? 答:能,局部会屏蔽全局.要用全局变量,需要使用"::" ;局部变量可以与全局变量同名,在 ...

  4. [Python从零到壹] 三十三.图像处理基础篇之什么是图像处理和OpenCV配置

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  5. Java 从零开始实现一个画图板、以及图像处理功能,代码可复现

    Java 从零开始实现一个画图板.以及图像处理功能,代码可复现 这是一个学习分享博客,带你从零开始实现一个画图板.图像处理的小项目,为了降低阅读难度,本博客将画图板的一步步迭代优化过程展示给读者,篇幅 ...

  6. Windows DC 画线

    好久没搞MFC,复习下知识. CPaintDC .CWindowDC. CClientDC. CDC 关系图: 一句话概括: CPaintDC            无效区dc,      相当于Be ...

  7. C语言程序设计(第三版)何钦铭著 习题5-3

    C语言程序设计(第三版)何钦铭著 习题5-3 习题一览表 1. C语言程序设计(第三版)何钦铭著 习题2-1 2.C语言程序设计(第三版)何钦铭著 习题2-2 3.C语言程序设计(第三版)何钦铭著 习 ...

  8. 五、C语言创建桌面程序:画笔和画刷

    一.画笔画刷的概念 画笔和画刷都用来在画布上绘图.画布就是用来绘画的一块背景,可以有颜色,也可以没有,也可以有图案(比如条纹.网格等):画布可以理解为我们平时作图时使用的纸. 画笔用来画线,可以是封闭 ...

  9. 迹美 java_三款图像处理软件人像美容效果大比拼

    面对电脑中超级多的个人照片,你知道该如何对它们进行后期处理,使之更加具有赏心悦目的效果吗?下面我们选择美图秀秀.iSee图片专家和光影魔术手三款图像处理软件,针对单纯的人像美容效果进行比较,看看哪一款 ...

最新文章

  1. 查服务器的作用有哪些,云服务器优点和功能有哪些,可以看看这些或许你会明白...
  2. WPF 基础到企业应用系列1——开篇故意
  3. Java官方操纵byte数组的方式
  4. 金九银十专供 | 175 道 Go 工程师必考面试题 + 详细解答
  5. python接口自动化(三十七)-封装与调用--读取excel 数据(详解)
  6. 关于写程序时「对数据库操作」的一些总结。
  7. 计算机网络的各层及其协议,计算机网络的体系结构 (architecture) 是计算机网络的各层及其协议的集合...
  8. python自动化办公都能做什么-用 Python 自动化办公,我与大神之间的差距一下就...
  9. 阿里云 Link ID² 标准项目获浙江省标准创新重大贡献奖
  10. windows 端口被System进程占用怎么解决?
  11. Spring ldap ODM
  12. oracle数据库什么情况下创建索引比较好
  13. 震为雷:始于足下;艮为山:红灯刹车
  14. 新手如何学习Java以及学习java的步骤
  15. 大数据量查询解决方案
  16. 台达plc 某系统的温控模块和模拟量输入模块
  17. 围棋的分数计算机,围棋比赛积分规则
  18. 深耕技术的同时,别忘了走出自己的舒适区
  19. omv 网站服务器,折腾篇 篇一:小白也爱折腾 篇一:N1全小白装NAS(omv)
  20. 健身课Day03-单侧臀腿力量训练

热门文章

  1. Android 三星手机拍照,从图库选择照片旋转问题完美解决
  2. 鸟哥的Linux私房菜(基础篇)- 第十章、vim 程序编辑器
  3. Linux 简单配置
  4. 【时事摘抄】邵氏弃儿:生命处境的残酷寓言
  5. csol什么时间服务器维护,01月21日服务器例行维护公告发布时间:2020-01-20
  6. 《探索着传说》(The Sword of Truth改编) 偶喜欢的奇幻剧(小说) 简介
  7. 中关村计算机配置学生,中关村电脑对比参数 电脑如何配置比较好
  8. 《职来职往》里那点儿震惊无数大学生的语言
  9. 整理的,复仇者联盟里的彩蛋
  10. Centos安装NextCloud