你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 图形图象处理与游戏编程
流动性蚂蚁线的设计(上)
 

  根据应用软件的需要,提出了蚂蚁线实现的功能需求,采用GDI++/GDI、多线程技术编程设计实现了蚂蚁线种类、绘制、属性管理类;讨论了GDI++/GDI实现方法的区别;采用线程同步、信号事件等技术实现的蚂蚁线易于扩展、运行稳定、可靠。

关键词 蚂蚁线;流动;GDI/GDI++;线程

 

一、引言

图形图像处理软件中经常要进行区域、图元的选择,以往都是一些静态的直线选择块,单一而且呆板。实现软件中的流动性选择线(框)可为软件增添不少光彩。流动性选择线(框),也称蚂蚁线,就是类似Photoshop软件中选取区域时候显示的线条,像蚂蚁一样不停地流动,如下图所示,某应用软件中选择对象后,“小蚂蚁”不停地爬动,


1 应用软件中的蚂蚁线

如下图所示,即黑色线段按照一定方向不停地移动(矩形为一个选择框)。


2 流动选择框(蚂蚁线

目前各种媒体上所见到的都是采用Delphi.NET C#(参见文献2)实现,尚不见Visual C的完整实现,本文通过分析相关商业软件,用Visual C++完全实现了商业软件中蚂蚁线的功能。

二、功能

1)同时管理多个蚂蚁线;

2)支持多种蚂蚁线,线、矩形、椭圆、曲线等;

3动态修改蚂蚁线的属性,如线型、颜色、宽度等;

4)支持线两端的属性,如圆形、矩形等;

5)使用方便、易于管理。

本文实现的蚂蚁线在某矢量图形系统中得到应用,实践证明运行稳定、可靠。

三、设计

为了实现以上功能,共设计了两种类:蚂蚁线种类类(CMarchingAntsType)和蚂蚁线管理类(CMarchingAntsManager)。如表1所示。

1 蚂蚁线类定义

CMarchingAntsType

蚂蚁线种类的基类

CMarchingAntsPolyLine

折线蚂蚁线类

CMarchingAntsPoints

点蚂蚁线类

CMarchingAntsManager

蚂蚁线管理类

为了实现不同种类的蚂蚁线,从CMarchingAntsType继承了两个类:CMarchingAntsPolyLine折线蚂蚁线类)和CMarchingAntsManager蚂蚁线管理类)。继承关系如图3所示。


3 继承关系

四、蚂蚁线种类类

1.蚂蚁线种类的基类CMarchingAntsType

为了方便实现不同的蚂蚁线,定义了一个基类CMarchingAntsType,这个基类定义了蚂蚁线的基本属性,绘制方法定义成虚函数virtual void Draw(Graphics *graphics)=0virtual void Draw(HDC hDC)=0),两个绘制函数分别对应GDI++GDI的绘制方法。这个类存在虚函数不能直接实例化。主要的属性如表2所示。

2蚂蚁线种类的基类属性

unsigned int width

线宽

float dash_length

虚线长度

float space_length

空线长度

unsigned int dash_color

虚线颜色

unsigned int space_color

空线颜色

unsigned int LineHeadType

线端点类型

unsigned int LineHeadSize

线端点矩形尺寸

float offst

偏移量

REAL m_DashOffset

虚线偏移量

int m_MaxDistance

最大距离

bool b_DirectionFlag

移动方向

CRITICAL_SECTION cs

互斥量

HDC m_hDC

绘图句柄

2. 折线蚂蚁线类(CMarchingAntsPolyLine

CMarchingAntsPolyLine实现了有关折线(由一系列线段组成)的蚂蚁线,存储了折线的坐标串Point *point//坐标数组)和unsigned int count//坐标数量),最为关键的是重载了绘制函数Draw(),实现了折线蚂蚁线的实质性绘制。

void Draw(Graphics *graphics)的关键代码如下:

//分别产生虚线和空线画笔、设置画笔属性

Pen m_DashPen(…);

Pen m_SpacePen((…);

m_DashPen.SetWidth(REAL(GetWidth()));

m_SpacePen.SetWidth(REAL(GetWidth()));

m_DashPen.SetDashStyle(DashStyleCustom);

REAL dashVals[4] = {

    REAL(GetDashLength()),   //虚线长度

    REAL(GetSpaceLength()),   //空线长度

    REAL(GetDashLength()),

    REAL(GetSpaceLength())};

//设置虚线和空线长度参数m_DashPen.SetDashPattern(dashVals, 4);

//设置开始到虚线的长度,这是实现蚂蚁

//爬动的关键步骤,通过不断修改这个值

//和重新绘制即可实现蚂蚁不断爬动

m_DashPen.SetDashOffset(m_DashOffset);

//绘制

graphics->DrawLines(&m_SpacePen,point,count);

graphics->DrawLines(&m_DashPen,point,count);

//绘制线的两端,如小矩形和椭圆等,可以进行扩展

Pen myPen(Color(0,0,0));

SolidBrush myBrush(Color(0,255,0));

unsigned int i;

switch(LineHeadType)

void Draw(HDC hDC)的关键代码如下:

unsigned int i=0;

int len=0;

//分别对每条线段处理

for(i=0;i<count-1;i++)

{

    ::LineDDA(…);

    len+=(int)sqrt(…);

}

if(len%((int)(GetDashLength()+GetSpaceLength()))==0)

    m_DashOffset++;

//绘制线的两端,如小矩形和椭圆等,可以进行扩展

HPEN hPen=CreatePen(PS_SOLID,1,RGB(0,0,0));

HPEN oldPen=(HPEN)SelectObject(hDC,hPen);

HBRUSH hBrush=CreateSolidBrush(RGB(0,255,0));

HBRUSH OldBrush=(HBRUSH)SelectObject(…);

GDI++GDI的实现的区别:是在GDI中没有设置虚线离开始点距离的SetDashOffset方法,需要利用LineDDA实现,效果也与GDI++有所区别。

LineDDA是一个32位的图形设备接口库函数调用,从如下所示的函数原形中可以看出其入口参数是一组线条坐标、一个回调函数的地址以及一个指向应用程序定义数据的指针:

BOOL LineDDA( int nXStart, // 线条起点的X坐标

int nYStart,        // 线条起点的Y坐标

int nXEnd,         // 线条终点的X坐标

int nYEnd,                 // 线条终点的Y坐标

LINEDDAPROC lpLineFunc,   // 回调函数的指针

LPARAM lpData              // 应用程序定义数据的指针

  由lpLineFunc指针指向的回调函数将在除终点外的线段的每个点上被调用,显然这里是实现蚂蚁线爬动的最佳地方。该回调函数在CMarchingAntsType类中定义为VOID CALLBACK MovingDots(int X,int Y,LPARAM lpData),主要代码如下:

//移动的量

int count =((int)(pType->m_DashOffset)) %((int)( ……));

    COLORREF vColor=RGB(0,0,0);

    if (count < pType->GetDashLength())

        vColor = pType->GetForeColor();

    else if (count < pType->GetDashLength()+pType->GetSpaceLength())

        vColor = pType->GetBackColor();

//在每点进行绘制

SetPixel(pType->m_hDC, X, Y, vColor);

//增加偏移量

    pType->m_DashOffset+=1;

3.点蚂蚁线类(CMarchingAntsPoints

  绘制点的蚂蚁线,实现与CMarchingAntsPolyLine类似,这里不再赘述。


 

  推荐精品文章

·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录
·2023年10月目录
·2023年9月目录 
·2023年8月目录 

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089