Delphi如何使用基本的绘图函数绘制统计图
若以下回答无法解决问题,邀请你更新回答
2018-06-21 · 百度认证:云南新华电脑职业培训学校官方账号
云南新华电脑学校
云南新华电脑学校是经云南省教育厅批准成立的省(部)级重点计算机专业学校,采用三元化管理模式,教学设备先进,师资雄厚学生毕业即就业,学院引进了电商企业入驻,创建心为电商创业园区,实现在校即创业
向TA提问
关注
展开全部
delphi如何使用基本的绘图函数绘制统计图
一个windows自带的画图工具是无论如何也不能满足我们的画图需要的,很多效果都需要我们在另外的工具中来实现。这些高级的功能是如何实现的呢,如何操纵一些基本的属性和函数,让它们最终能作出我们想要的效果呢?这里我们以绘制统计图来说明这些问题。
解决思路――
这里,我们暂且先撇开具体的问题,综合地一下讨论画图的问题。
画图工具是基本元素的具体实现,对于我们初学者来说,还是有很好的参考价值的,在delphi 5中有一个自带的工程例子“……borland\delphi5\demos\doc\graphex”,这个例子可以实现一些基本的绘图功能。对这个例子多加修改,一定会有所收获的。这里就不列出它的详细代码了,有心的读者可以自己找到这个例子。我这里只是想综合地讨论这方面的问题。使用delphi编写绘图软件的灵魂就在于操作画布,画笔和刷子,尽可能地挖掘它们的属性和相关参数的设置。
(一)画布
画布,画笔和刷子之间的关系很明了.其实,画笔和刷子都是画布的一个属性.而画布也只是tform,timage,tshape等组件对象的一个属性,专门负责与图象相关的信息打交道.它的主要作用可以概括如下几点:
1.指定使用画笔,刷子和字体的使用类型;
2.绘制和填充指定形状的线或图形;
3.修饰和改变图象;
画布的主要属性有:
brush--指定填充图形和背景的样式
canvasorientation--指定画布的定位类型,有colefttoright, corighttoleft两个属性;
cliprect--指定剪切矩形的边界;
copymode--指定图形图象的复制模式;
font--指定画布上使用的字体;
handle--为画布指定窗口gdi对象的设备描述表;
lockcount--指定画布被别的线程锁定的次数;
pen--指定画布上使用的画笔,具体见下面描述;
penpos--指定画笔当前的位置;
pixels--指定当前剪切矩形的象素颜色;
textflags--指定字体在画布上的显示方式,有eto_clipped,eto_opaque,eto_rtlreading, eto_glyph_index,eto_ignorelanguage,eto_numericslocaleto_numericslatin等值可选;
画布相关的api函数及其注释如下:
arc--按指定方式画一条弧;
brushcopy--把位图复制到指定的画布的矩形中,用画布刷子颜色替换位图的颜色;
chord--按指定方式画弦;
copyrect--从一个矩形区域复制部分图象到另一个矩形区域;
draw--用指定参数在指定位置画图;
drawfocusrect--按指定焦点风格,通过异或操作来绘制一焦点矩形;
ellipse--按指定参数画一椭圆;
fillrect--按指定的刷子填充一矩形;
floodfill--使用当前选定的刷子填充指定设备描述表中的一块区域;
framerect--使用指定的方式画一矩形的边框;
lineto--使用当前画笔从当前位置到指定点画一条直线;
lock--防止其它线程在画布上绘图;
moveto--指定一新的当前画笔位置;
pie--按指定方式画饼状图;
polybezier--按指定方式画多条贝塞尔线;
polybezierto--按指定方式画多条贝塞尔线并更新当前的画笔位置值;
polygon--绘制一个由多个顶点的任意序列组成 的多边形;
polyline--使用当前画笔画一系列的多边形;
rectangle--绘制矩形;
roundrect--绘制圆角矩形;
stretchdraw--在指定的矩形区域通过指定的绘图参数来绘制图形;
textextent--返回使用当前字体设置的字符的象素宽度和高度等参数;
textheight--返回使用当前字体设置的字符的象素高度;
textout--在指定位置绘制文本,并更新画笔的当前位置;
textrect--在一剪切矩形区域中绘制文本;
textwidth--返回使用当前字体设置的字符的象素宽度;
trylock--对当前没加锁的画布进行加锁;
unlock--对当前加锁的画布进行解锁;
例如以下是两个小例子:
procedure tform1.button2click(sender: tobject);
var
arect: trect;
begin //实现了剪切效果;
with image1.canvas do
begin
copymode := cmwhiteness; //设置复制模式;
arect := rect(0, 0, image1.width, image1.height);
copyrect(arect, image1.canvas, arect);
copymode := cmsrccopy; //恢复复制模式;
end;
end;
procedure tform1.button3click(sender: tobject);
var
w: word;
begin //在窗口中画一条彩线;
for w := 10 to 200 do
canvas.pixels[w, 10] :=rgb(random(255),random(255),random(255));;
end;
灵活使用这些函数及其内部参数会让我们得到意想不到的效果;
(二) 画笔
画笔是一个gdi对象,定义了绘制直线或轮廓形状的方法.
画笔内部共有五种属性:颜色,句柄,模式,风格和宽度.
color--决定指定直线或轮廓形状的rgb颜色。
handle--指向了窗口画笔对象句柄。
mode--指定了画笔以何种方式在画布(canvas)上画线,在帮助文档中的该定义是(全部以pm_开头):
type tpenmode =( pmblack, //总是黑色;
pmwhite, //总是白色;
pmnop, //颜色不变;
pmnot, //画布颜色取反;
pmcopy, //颜色属性中指定的画笔颜色;
pmnotcopy, //画笔颜色取反;
pmmergepennot, //画笔颜色和画布背景色取反后颜色的结合;
pmmaskpennot, //画笔颜色和画笔背景色取反后颜色共同色的结合;
pmmergenotpen, //画笔颜色取反后和画布背景色的结合;
pmmasknotpen, //画布颜色和画笔颜色取反后颜色共同色的结合;
pmmerge, //画笔和画布背景色的结合;
pmnotmerge, //画笔颜色和画布背景色的结合;
pmmask, //画笔和画布背景色共同色的结合;
pmnotmask, //pmmask取反,画笔和画布背景色共同色的结合;
pmxor, //取画笔或画布背景中的任一种颜色;
pmnotxor //pmxor取反,取画笔或画布背景中的任一种颜色;
);
style--则指定了画笔操作的风格,在线文档中的定义是(全部以ps_开头):
type tpenstyle=( pssolid, //画笔是───
psdash, //画笔是------
psdot, //画笔是......
psdashdot, //画笔是_._._.
psdashdotdot, //画笔是_.._..
psclear, //画笔是透明色
psinsideframe //画笔是实线,但设置大于1时会抖动;
);
另外,在windows.pas中还有其他扩展的画笔风格定义,只在特殊的支持设备上
才有效,如ps_endcap_round, ps_join_round等;
width--指定了待使用画笔的宽度,单位是象素.
和画笔相关的函数有:
createpen--用指定风格创建画笔;
createpenindirect--根据logpen数据结构创建一画笔;
extcreatepen-- 创建带指定风格,宽度和刷子属性的几何画笔;
(三)刷子
刷子定义了区域填充的gdi对象,刷子是一个8×8象素的区域,它可以被绘制在指定的设
备上.刷子不仅可以是纯色的,也可以由不同的位图图案组成.
刷子的属性有位图,颜色,句柄和风格四种:
bitmap--是指定一个外部位图文件来填充指定的区域.如果指定的图象比填充的区域大,
则只有左上角与填充区域等大的部分有效,其余的被自动裁减了.
color--指定了刷子的颜色.当刷子风格为bsclear时,该属性无效.
handle--指向指定设备窗口.
style--则指定了当前刷子的填充风格,在线文档中的定义是(都以bs_开头):
type tbrushstyle=( bssolid, //填充格式为实体填充
bsclear, //填充格式为透明填充
bshorizontal, //填充格式为------
bsvertical, // 填充格式为|||||
bsfdiagonal, // 填充格式为/////
bsbdiagonal, // 填充格式为\\\\\
bscross, // 填充格式为+++++
bsdiagcross // 填充格式为xxxxx
);
和刷子有关的api函数有:
createbrushindirect--根据logbrush创建一刷子;
createdibpatternbrushpt--使用设备无关位图来创建刷子,以便指定刷子的模式;
createhatchbrush--创建一带有阴影模式的刷子,阴影模式为以hs_开头的常数;
createpatternbrush--用位图来创建刷子,以便指定刷子的模式;
createsolidbrush--创建一实体颜色刷子;
getbrushorgex--获取指定设备描述表中当前选择刷子的原点;
getsyscolorbrush--获取和指定颜色索引相关的逻辑刷子的句柄;
setbrushorgex--设置指定设备描述表中当前选择刷子的原点;
(四)画图和填充相关的api函数;
beginpaint--准备在指定窗口绘画或对指定区域进行填充;
drawanimatedrects--nt支持函数,画一环有游动边框的矩形;
drawcaption--nt支持函数,为指定窗口的标题赋值;
drawedge--为指定矩形画一道或多道边框;
drawfocusrect--画焦点矩形;
drawframecontrol--画一指定类型和风格的边框控件;
drawstate--nt支持函数,为图象画一可视效果标明其状态;
drawstateproc--nt支持函数,调用为图象画一可视效果标明其状态的函数;
drawtextex--nt支持函数,在指定区域输出格式化文本;
endpaint--结束绘画;
excludeupdatergn--将窗口无效部分(更新区域)从裁剪区中排除掉;
gdiflush--使当前gdi闪烁;
gdigetbatchlimit--获取缓冲gdi函数数量;
gdisetbatchlimit--设置缓冲gdi函数数量;
getbkcolor--获取背景颜色;
getbkmode--获取背景模式;
getboundsrect--获取边界矩形;
getrop2--获取当前绘图模式;
getupdaterect--获取指定窗口最小的矩形;
getupdatergn--获取描述窗口中无效区的区域;
getwindowdc--获取窗口dc;
getwindowrgn--获取窗口区域;
graystring--在指定位置画灰色文本;
invalidaterect--使dc指定的矩形无效;
invalidatergn--使dc指定的矩形无效;
lockwindowupdate--禁止或允许在指定窗口中绘画;
outputproc--调用输出进程,向graystring输送文本;
paintdesktop--nt支持函数,在指定的窗口区域用指定的桌面颜色或墙纸填充裁剪区;
redrawwindow--更新客户区的指定区域或矩形;
setbkcolor--设置背景颜色;
setbkmode--设置背景模式;
setboundsrect--设置边界矩形;
setrectrgn--设置矩形区域;
setrop2--设置当前绘图模式;
setwindowrgn--设置窗口区域;
updatewindow--更新窗口;
validaterect--使客户区中指定矩形有效;
validatergn--使客户区中的指定区域有效;
windowfromdc--获取和指定窗口相关的句柄;
具体实现――
1.本例以常见的统计图来说明问题。该例能实现对统计图的动态绘制,并且可以自定义设置统计图的形状和颜色。在说明问题之前,来了解程序用到的一些比较复杂的函数或算法:
函数――
1.polygon(points: array of tpoint)
用于绘出指定的多边形。括号内是预定点的集合,该集合可以在使用之前定义,也可以在使用时同时定义,本例属于后者;
2.pie(x1, y1, x2, y2, x3, y3, x4, y4: longint)
用于绘制饼状图,饼状图其实就是椭圆的一部分。在这些参数中,其中(x1, y1)和(x2, y2)定义了框住饼状图的矩形,而从椭圆中心发出的射线经过(x3, y3)和(x4, y4)两点,就把一个饼状图截出来了。
3.formatfloat(const format: string; value: extended)
函数的意义是按指定方式格式化字符串,format指定了格式化的方式,value则指定了要格式化的文本或其他数据。下面列举了一些范例,可供我们学习时参考:
格式化符号(format) 1234 -1234 0.5 0
1234 -1234 0.5 0
0 1234 -1234 1 0
0.00 1234.00 -1234.00 0.50 0.00
#.## 1234 -1234 .5
#,##0.00 1,234.00 -1,234.00 0.50 0.00
#,##0.00;(#,##0.00) 1,234.00 (1,234.00) 0.50 0.00
#,##0.00;;zero 1,234.00 -1,234.00 0.50 zero
0.000e+00 1.234e+03 -1.234e+03 5.000e-01 0.000e+00
#.###e-0 1.234e3 -1.234e3 5e-1 0e0
该例是在小数点后保留两位小数,因此用"##.##",具体见程序代码中。
算法――
本例的实现依赖一定的算法。这里介绍主要的两点:
1)在连接多边形各点时,我们要注意那几个点一定要构成一个闭合的图形,这就要保证最后一个点要和第一个点重合。至于其他的点怎么布局,则要有一定的空间感。
我们先画一个矩形,然后再根据平行关系确定其他的点:
rectangle(50,x,70,220); //画主视面;
canvas.polygon([point(50, x), point(70,x-10),point(90,x-10), point(70, x),point(50, x)]);//画顶面;
canvas.polygon([point(90,x-10), point(70, x),point(70,220),point(90,210),point(90,x-10)]); //画侧面;
2)确定圆上指定角度的边与圆的交点
在该例中画饼状图时,我们要按照一定的比例画扇形,这就要确定扇形的起始点和终止点。我们把起始点设为一个定点,而终止点则根据实际情况设置,如图:
――饼状图的数学原理――
假设画图时已知一个比例数是k,则在饼状图中的角度是θ=(k*360),根据图中的关系(y轴向下符合屏幕坐标系定义),可以用三角函数知识求得px,py:
px=op*cosθ
py=op*sinθ
上述式子的前提条件是o点是原点,op是圆的半径。如果o点不是原点,而是坐标系中的一个点(x0,y0),则此时的p点坐标是
px=x0+op*cosθ
py=y0+op*sinθ
3.本例的界面布局可以参考程序运行的结果图,其中代表“刷子类型”的combobox1的items的属性设置如图。该例实现的主要代码如下:
procedure tform1.button1click(sender: tobject);
var
x,i,j:integer;
k:real;
begin
refresh;
//标明写上“y”轴;
label4.left:=25;
label4.top:=2;
label4.caption:='y';
label4.transparent:=true;
//标明写上“x”轴;
label5.left:=395;
label5.top:=227;
label5.caption:='x';
label5.transparent:=true;
x:=220-round(strtofloat(edit1.text)/strtofloat(edit2.text)*200);
with form1.canvas do
begin
pen.width:=strtoint(edit3.text); //设置画笔宽度;
case combobox1.items.indexof(combobox1.text) of //设置刷子的填充风格;
0: brush.style:=bssolid;
1: brush.style:=bsclear;
2: brush.style:=bshorizontal;
3: brush.style:=bsvertical;
4: brush.style:=bsfdiagonal;
5: brush.style:=bsbdiagonal;
6: brush.style:=bscross;
7: brush.style:=bsdiagcross;
end;
//画出x轴;
moveto(2,220);
lineto(400,220);
//画出y轴;
moveto(20,5);
lineto(20,230);
//画出y轴的箭头方向"∧";
moveto(20,5);
lineto(15,12);
moveto(20,5);
lineto(25,12);
//画出x轴的箭头方向"∧";
moveto(400,220);
lineto(395,213);
moveto(400,220);
lineto(395,227);
if checkbox1.checked then //绘制立体的直方柱图;
begin
//画正面的矩形图;,可以根据实际情况动态定义它的高度;
rectangle(50,x,70,220);
//画顶面,随着正面矩形的高度变化而变化;
canvas.polygon([point(50, x), point(70,x-10),point(90,x-10), point(70, x),point(50, x)]);
//画侧面,随着正面矩形的高度变化而变化;
canvas.polygon([point(90,x-10), point(70, x),point(70,220),point(90,210),point(90,x-10)]);
end
else
rectangle(50,x,70,220); //如果没有选中要以立体形式绘制,则以平面形式绘制的直方柱图;
//画饼状统计图
k:=(strtofloat(edit1.text)/strtofloat(edit2.text))*360; //将数据按比例转换成;
i:=round(250+100*cos(k*3.14159/180));
j:=round(120+100*sin(k*3.14159/180));
pie(150,20,350,220,i,j,350,120);
label3.caption:='比例是'+formatfloat('##.##',(k/360)*100)+'%'; //设置比例的函数;
end;
end;
procedure tform1.shape1mousedown(sender: tobject; button: tmousebutton;
shift: tshiftstate; x, y: integer);
begin
if colordialog1.execute then //设置窗口背景颜色;
shape1.brush.color:=colordialog1.color;
form1.color:=colordialog1.color;
end;
procedure tform1.shape2mousedown(sender: tobject; button: tmousebutton;
shift: tshiftstate; x, y: integer);
begin
if colordialog2.execute then //设置刷子颜色;
shape2.brush.color:=colordialog2.color;
form1.canvas.brush.color:=colordialog2.color;
end;
procedure tform1.shape3mousedown(sender: tobject; button: tmousebutton;
shift: tshiftstate; x, y: integer);
begin
if colordialog3.execute then //设置画笔颜色;
shape3.brush.color:=colordialog3.color;
form1.canvas.pen.color:=colordialog3.color;
end;
一个windows自带的画图工具是无论如何也不能满足我们的画图需要的,很多效果都需要我们在另外的工具中来实现。这些高级的功能是如何实现的呢,如何操纵一些基本的属性和函数,让它们最终能作出我们想要的效果呢?这里我们以绘制统计图来说明这些问题。
解决思路――
这里,我们暂且先撇开具体的问题,综合地一下讨论画图的问题。
画图工具是基本元素的具体实现,对于我们初学者来说,还是有很好的参考价值的,在delphi 5中有一个自带的工程例子“……borland\delphi5\demos\doc\graphex”,这个例子可以实现一些基本的绘图功能。对这个例子多加修改,一定会有所收获的。这里就不列出它的详细代码了,有心的读者可以自己找到这个例子。我这里只是想综合地讨论这方面的问题。使用delphi编写绘图软件的灵魂就在于操作画布,画笔和刷子,尽可能地挖掘它们的属性和相关参数的设置。
(一)画布
画布,画笔和刷子之间的关系很明了.其实,画笔和刷子都是画布的一个属性.而画布也只是tform,timage,tshape等组件对象的一个属性,专门负责与图象相关的信息打交道.它的主要作用可以概括如下几点:
1.指定使用画笔,刷子和字体的使用类型;
2.绘制和填充指定形状的线或图形;
3.修饰和改变图象;
画布的主要属性有:
brush--指定填充图形和背景的样式
canvasorientation--指定画布的定位类型,有colefttoright, corighttoleft两个属性;
cliprect--指定剪切矩形的边界;
copymode--指定图形图象的复制模式;
font--指定画布上使用的字体;
handle--为画布指定窗口gdi对象的设备描述表;
lockcount--指定画布被别的线程锁定的次数;
pen--指定画布上使用的画笔,具体见下面描述;
penpos--指定画笔当前的位置;
pixels--指定当前剪切矩形的象素颜色;
textflags--指定字体在画布上的显示方式,有eto_clipped,eto_opaque,eto_rtlreading, eto_glyph_index,eto_ignorelanguage,eto_numericslocaleto_numericslatin等值可选;
画布相关的api函数及其注释如下:
arc--按指定方式画一条弧;
brushcopy--把位图复制到指定的画布的矩形中,用画布刷子颜色替换位图的颜色;
chord--按指定方式画弦;
copyrect--从一个矩形区域复制部分图象到另一个矩形区域;
draw--用指定参数在指定位置画图;
drawfocusrect--按指定焦点风格,通过异或操作来绘制一焦点矩形;
ellipse--按指定参数画一椭圆;
fillrect--按指定的刷子填充一矩形;
floodfill--使用当前选定的刷子填充指定设备描述表中的一块区域;
framerect--使用指定的方式画一矩形的边框;
lineto--使用当前画笔从当前位置到指定点画一条直线;
lock--防止其它线程在画布上绘图;
moveto--指定一新的当前画笔位置;
pie--按指定方式画饼状图;
polybezier--按指定方式画多条贝塞尔线;
polybezierto--按指定方式画多条贝塞尔线并更新当前的画笔位置值;
polygon--绘制一个由多个顶点的任意序列组成 的多边形;
polyline--使用当前画笔画一系列的多边形;
rectangle--绘制矩形;
roundrect--绘制圆角矩形;
stretchdraw--在指定的矩形区域通过指定的绘图参数来绘制图形;
textextent--返回使用当前字体设置的字符的象素宽度和高度等参数;
textheight--返回使用当前字体设置的字符的象素高度;
textout--在指定位置绘制文本,并更新画笔的当前位置;
textrect--在一剪切矩形区域中绘制文本;
textwidth--返回使用当前字体设置的字符的象素宽度;
trylock--对当前没加锁的画布进行加锁;
unlock--对当前加锁的画布进行解锁;
例如以下是两个小例子:
procedure tform1.button2click(sender: tobject);
var
arect: trect;
begin //实现了剪切效果;
with image1.canvas do
begin
copymode := cmwhiteness; //设置复制模式;
arect := rect(0, 0, image1.width, image1.height);
copyrect(arect, image1.canvas, arect);
copymode := cmsrccopy; //恢复复制模式;
end;
end;
procedure tform1.button3click(sender: tobject);
var
w: word;
begin //在窗口中画一条彩线;
for w := 10 to 200 do
canvas.pixels[w, 10] :=rgb(random(255),random(255),random(255));;
end;
灵活使用这些函数及其内部参数会让我们得到意想不到的效果;
(二) 画笔
画笔是一个gdi对象,定义了绘制直线或轮廓形状的方法.
画笔内部共有五种属性:颜色,句柄,模式,风格和宽度.
color--决定指定直线或轮廓形状的rgb颜色。
handle--指向了窗口画笔对象句柄。
mode--指定了画笔以何种方式在画布(canvas)上画线,在帮助文档中的该定义是(全部以pm_开头):
type tpenmode =( pmblack, //总是黑色;
pmwhite, //总是白色;
pmnop, //颜色不变;
pmnot, //画布颜色取反;
pmcopy, //颜色属性中指定的画笔颜色;
pmnotcopy, //画笔颜色取反;
pmmergepennot, //画笔颜色和画布背景色取反后颜色的结合;
pmmaskpennot, //画笔颜色和画笔背景色取反后颜色共同色的结合;
pmmergenotpen, //画笔颜色取反后和画布背景色的结合;
pmmasknotpen, //画布颜色和画笔颜色取反后颜色共同色的结合;
pmmerge, //画笔和画布背景色的结合;
pmnotmerge, //画笔颜色和画布背景色的结合;
pmmask, //画笔和画布背景色共同色的结合;
pmnotmask, //pmmask取反,画笔和画布背景色共同色的结合;
pmxor, //取画笔或画布背景中的任一种颜色;
pmnotxor //pmxor取反,取画笔或画布背景中的任一种颜色;
);
style--则指定了画笔操作的风格,在线文档中的定义是(全部以ps_开头):
type tpenstyle=( pssolid, //画笔是───
psdash, //画笔是------
psdot, //画笔是......
psdashdot, //画笔是_._._.
psdashdotdot, //画笔是_.._..
psclear, //画笔是透明色
psinsideframe //画笔是实线,但设置大于1时会抖动;
);
另外,在windows.pas中还有其他扩展的画笔风格定义,只在特殊的支持设备上
才有效,如ps_endcap_round, ps_join_round等;
width--指定了待使用画笔的宽度,单位是象素.
和画笔相关的函数有:
createpen--用指定风格创建画笔;
createpenindirect--根据logpen数据结构创建一画笔;
extcreatepen-- 创建带指定风格,宽度和刷子属性的几何画笔;
(三)刷子
刷子定义了区域填充的gdi对象,刷子是一个8×8象素的区域,它可以被绘制在指定的设
备上.刷子不仅可以是纯色的,也可以由不同的位图图案组成.
刷子的属性有位图,颜色,句柄和风格四种:
bitmap--是指定一个外部位图文件来填充指定的区域.如果指定的图象比填充的区域大,
则只有左上角与填充区域等大的部分有效,其余的被自动裁减了.
color--指定了刷子的颜色.当刷子风格为bsclear时,该属性无效.
handle--指向指定设备窗口.
style--则指定了当前刷子的填充风格,在线文档中的定义是(都以bs_开头):
type tbrushstyle=( bssolid, //填充格式为实体填充
bsclear, //填充格式为透明填充
bshorizontal, //填充格式为------
bsvertical, // 填充格式为|||||
bsfdiagonal, // 填充格式为/////
bsbdiagonal, // 填充格式为\\\\\
bscross, // 填充格式为+++++
bsdiagcross // 填充格式为xxxxx
);
和刷子有关的api函数有:
createbrushindirect--根据logbrush创建一刷子;
createdibpatternbrushpt--使用设备无关位图来创建刷子,以便指定刷子的模式;
createhatchbrush--创建一带有阴影模式的刷子,阴影模式为以hs_开头的常数;
createpatternbrush--用位图来创建刷子,以便指定刷子的模式;
createsolidbrush--创建一实体颜色刷子;
getbrushorgex--获取指定设备描述表中当前选择刷子的原点;
getsyscolorbrush--获取和指定颜色索引相关的逻辑刷子的句柄;
setbrushorgex--设置指定设备描述表中当前选择刷子的原点;
(四)画图和填充相关的api函数;
beginpaint--准备在指定窗口绘画或对指定区域进行填充;
drawanimatedrects--nt支持函数,画一环有游动边框的矩形;
drawcaption--nt支持函数,为指定窗口的标题赋值;
drawedge--为指定矩形画一道或多道边框;
drawfocusrect--画焦点矩形;
drawframecontrol--画一指定类型和风格的边框控件;
drawstate--nt支持函数,为图象画一可视效果标明其状态;
drawstateproc--nt支持函数,调用为图象画一可视效果标明其状态的函数;
drawtextex--nt支持函数,在指定区域输出格式化文本;
endpaint--结束绘画;
excludeupdatergn--将窗口无效部分(更新区域)从裁剪区中排除掉;
gdiflush--使当前gdi闪烁;
gdigetbatchlimit--获取缓冲gdi函数数量;
gdisetbatchlimit--设置缓冲gdi函数数量;
getbkcolor--获取背景颜色;
getbkmode--获取背景模式;
getboundsrect--获取边界矩形;
getrop2--获取当前绘图模式;
getupdaterect--获取指定窗口最小的矩形;
getupdatergn--获取描述窗口中无效区的区域;
getwindowdc--获取窗口dc;
getwindowrgn--获取窗口区域;
graystring--在指定位置画灰色文本;
invalidaterect--使dc指定的矩形无效;
invalidatergn--使dc指定的矩形无效;
lockwindowupdate--禁止或允许在指定窗口中绘画;
outputproc--调用输出进程,向graystring输送文本;
paintdesktop--nt支持函数,在指定的窗口区域用指定的桌面颜色或墙纸填充裁剪区;
redrawwindow--更新客户区的指定区域或矩形;
setbkcolor--设置背景颜色;
setbkmode--设置背景模式;
setboundsrect--设置边界矩形;
setrectrgn--设置矩形区域;
setrop2--设置当前绘图模式;
setwindowrgn--设置窗口区域;
updatewindow--更新窗口;
validaterect--使客户区中指定矩形有效;
validatergn--使客户区中的指定区域有效;
windowfromdc--获取和指定窗口相关的句柄;
具体实现――
1.本例以常见的统计图来说明问题。该例能实现对统计图的动态绘制,并且可以自定义设置统计图的形状和颜色。在说明问题之前,来了解程序用到的一些比较复杂的函数或算法:
函数――
1.polygon(points: array of tpoint)
用于绘出指定的多边形。括号内是预定点的集合,该集合可以在使用之前定义,也可以在使用时同时定义,本例属于后者;
2.pie(x1, y1, x2, y2, x3, y3, x4, y4: longint)
用于绘制饼状图,饼状图其实就是椭圆的一部分。在这些参数中,其中(x1, y1)和(x2, y2)定义了框住饼状图的矩形,而从椭圆中心发出的射线经过(x3, y3)和(x4, y4)两点,就把一个饼状图截出来了。
3.formatfloat(const format: string; value: extended)
函数的意义是按指定方式格式化字符串,format指定了格式化的方式,value则指定了要格式化的文本或其他数据。下面列举了一些范例,可供我们学习时参考:
格式化符号(format) 1234 -1234 0.5 0
1234 -1234 0.5 0
0 1234 -1234 1 0
0.00 1234.00 -1234.00 0.50 0.00
#.## 1234 -1234 .5
#,##0.00 1,234.00 -1,234.00 0.50 0.00
#,##0.00;(#,##0.00) 1,234.00 (1,234.00) 0.50 0.00
#,##0.00;;zero 1,234.00 -1,234.00 0.50 zero
0.000e+00 1.234e+03 -1.234e+03 5.000e-01 0.000e+00
#.###e-0 1.234e3 -1.234e3 5e-1 0e0
该例是在小数点后保留两位小数,因此用"##.##",具体见程序代码中。
算法――
本例的实现依赖一定的算法。这里介绍主要的两点:
1)在连接多边形各点时,我们要注意那几个点一定要构成一个闭合的图形,这就要保证最后一个点要和第一个点重合。至于其他的点怎么布局,则要有一定的空间感。
我们先画一个矩形,然后再根据平行关系确定其他的点:
rectangle(50,x,70,220); //画主视面;
canvas.polygon([point(50, x), point(70,x-10),point(90,x-10), point(70, x),point(50, x)]);//画顶面;
canvas.polygon([point(90,x-10), point(70, x),point(70,220),point(90,210),point(90,x-10)]); //画侧面;
2)确定圆上指定角度的边与圆的交点
在该例中画饼状图时,我们要按照一定的比例画扇形,这就要确定扇形的起始点和终止点。我们把起始点设为一个定点,而终止点则根据实际情况设置,如图:
――饼状图的数学原理――
假设画图时已知一个比例数是k,则在饼状图中的角度是θ=(k*360),根据图中的关系(y轴向下符合屏幕坐标系定义),可以用三角函数知识求得px,py:
px=op*cosθ
py=op*sinθ
上述式子的前提条件是o点是原点,op是圆的半径。如果o点不是原点,而是坐标系中的一个点(x0,y0),则此时的p点坐标是
px=x0+op*cosθ
py=y0+op*sinθ
3.本例的界面布局可以参考程序运行的结果图,其中代表“刷子类型”的combobox1的items的属性设置如图。该例实现的主要代码如下:
procedure tform1.button1click(sender: tobject);
var
x,i,j:integer;
k:real;
begin
refresh;
//标明写上“y”轴;
label4.left:=25;
label4.top:=2;
label4.caption:='y';
label4.transparent:=true;
//标明写上“x”轴;
label5.left:=395;
label5.top:=227;
label5.caption:='x';
label5.transparent:=true;
x:=220-round(strtofloat(edit1.text)/strtofloat(edit2.text)*200);
with form1.canvas do
begin
pen.width:=strtoint(edit3.text); //设置画笔宽度;
case combobox1.items.indexof(combobox1.text) of //设置刷子的填充风格;
0: brush.style:=bssolid;
1: brush.style:=bsclear;
2: brush.style:=bshorizontal;
3: brush.style:=bsvertical;
4: brush.style:=bsfdiagonal;
5: brush.style:=bsbdiagonal;
6: brush.style:=bscross;
7: brush.style:=bsdiagcross;
end;
//画出x轴;
moveto(2,220);
lineto(400,220);
//画出y轴;
moveto(20,5);
lineto(20,230);
//画出y轴的箭头方向"∧";
moveto(20,5);
lineto(15,12);
moveto(20,5);
lineto(25,12);
//画出x轴的箭头方向"∧";
moveto(400,220);
lineto(395,213);
moveto(400,220);
lineto(395,227);
if checkbox1.checked then //绘制立体的直方柱图;
begin
//画正面的矩形图;,可以根据实际情况动态定义它的高度;
rectangle(50,x,70,220);
//画顶面,随着正面矩形的高度变化而变化;
canvas.polygon([point(50, x), point(70,x-10),point(90,x-10), point(70, x),point(50, x)]);
//画侧面,随着正面矩形的高度变化而变化;
canvas.polygon([point(90,x-10), point(70, x),point(70,220),point(90,210),point(90,x-10)]);
end
else
rectangle(50,x,70,220); //如果没有选中要以立体形式绘制,则以平面形式绘制的直方柱图;
//画饼状统计图
k:=(strtofloat(edit1.text)/strtofloat(edit2.text))*360; //将数据按比例转换成;
i:=round(250+100*cos(k*3.14159/180));
j:=round(120+100*sin(k*3.14159/180));
pie(150,20,350,220,i,j,350,120);
label3.caption:='比例是'+formatfloat('##.##',(k/360)*100)+'%'; //设置比例的函数;
end;
end;
procedure tform1.shape1mousedown(sender: tobject; button: tmousebutton;
shift: tshiftstate; x, y: integer);
begin
if colordialog1.execute then //设置窗口背景颜色;
shape1.brush.color:=colordialog1.color;
form1.color:=colordialog1.color;
end;
procedure tform1.shape2mousedown(sender: tobject; button: tmousebutton;
shift: tshiftstate; x, y: integer);
begin
if colordialog2.execute then //设置刷子颜色;
shape2.brush.color:=colordialog2.color;
form1.canvas.brush.color:=colordialog2.color;
end;
procedure tform1.shape3mousedown(sender: tobject; button: tmousebutton;
shift: tshiftstate; x, y: integer);
begin
if colordialog3.execute then //设置画笔颜色;
shape3.brush.color:=colordialog3.color;
form1.canvas.pen.color:=colordialog3.color;
end;
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询