使用C语言计算与模拟足球射门.docx
《使用C语言计算与模拟足球射门.docx》由会员分享,可在线阅读,更多相关《使用C语言计算与模拟足球射门.docx(15页珍藏版)》请在冰豆网上搜索。
使用C语言计算与模拟足球射门
使用C语言计算与模拟足球射门【4】
1引言
C语言是近年来在国内外得到迅速推广应用的一种计算机语言。
C语言功能丰富、使用灵活方便、应用面广、目标程序效率高、可移植性好,既有高级语言的优点,又有低级语言的许多特点。
【1】TurboC是在微机上广泛使用的编译程序。
它具有方便、直观、易用的界面和丰富的库函数。
它向用户提供一个集成环境,把程序的编辑、编译、连接和运行等操作全部集中在一个界面上进行,使用十分方便。
采用C语言编写的程序易懂,较为直观,对硬件要求比较低【1】。
计算机模拟是在计算机上通过系统模型模拟一个实际存在或正在设计中的真实系统,以再现(实现可视化)或分析(数值计算)真实系统的本质特征,并以证明实际问题的可信性。
【6】【7】动画可突出并强化要表达的事物特征,生动形象的模拟事物的运动等。
用C语言提供的各种实现方法来制作动画都各有其优点,本文利用改变图像坐标的方法来模拟足球射门。
使用该方法编写的源程序比较通俗易懂。
2C语言制图与计算机动画技术
2.1C语言制图简介
TurboC中有丰富的图形函数,它支持CGA,EGA,UGA等多种显卡及多种图形显示模式,提供了画点、线、圆、椭圆、多边形等绘图功能,还提供了颜色控制、图形填充和线条模式等功能。
可以利用C语言提供的许多图形函数来方便、快速的实现动画,且动画效果另人满意。
在TurboC语言中实现动画的方法有很多种,如目标移动方法、显示页和编辑页交替变化方法、画面存储和再重放方法等等【2】。
目标移动方法是利用C语言提供的多种画图函数将图形画好以后,在时间上取间隔非常小的时间段来不断改变图象的在屏幕上的坐标以达动画效果。
显示页和编辑页交替变化方法是将当前显示页和编辑页分开,在编辑页上画好图形后,立即令该页变为显示页显示。
然后再上次的显示页上(现在变为编辑页)进行画图,画好后又再次进行交换。
如此编辑页和显示页反复交换,在观察者的视觉中,就出现了动画的效果。
画面存储和再重放方法如同制作幻灯片一样,将整个动画过程变成一个个片段,然后存储到显示缓冲区,当把它们按顺序重放到屏幕上时,就出现了动画效果。
【2】
2.2计算机动画技术
计算机动画是借助计算机生成一系列动态演示的图形、图像的技术。
动画的实现过程是:
首先在屏幕的当前未知画对象并保持一定的时间;接着从屏幕的当前未知删除对象;然后在屏幕上新位置上画对象,这样就产生了动画效果【2】。
由于动画具有直观,形象,生动等特点,故采用动画技术,可突出并强化要表达的事物特征,生动形象的模拟事物的运动等。
随着计算机动画技术的迅速发展,它的应用领域日益扩大,制作计算机动画使用的工具也日益繁多。
比如:
Flash,3DStudio,3DMAX等。
3使用C语言描述抛体运动
3.1抛物运动
抛体运动是发生在竖直平面内的二维空间的运动。
在抛体运动中,被抛物体主要受重力和空气摩擦力影响,在这里,忽略空气的影响,假设物体以初速度SPEED沿与水平方向成θ0角的方向被抛出。
程序中,初速度用SPEED表示,角度用Angle表示,足球射出点与球门的距离用LONGS表示,球门高度用H表示。
3.2动画原理
在利用TurboC来编写图形代码时,要能够准确的确定图形在显示器上的坐标。
显示器的屏幕如同一张坐标纸,可用x,y坐标值表示图形上任一点的位置。
显示屏的坐标从左上角(0,0)开始,正x轴向右延伸,正y轴想下延伸,为一个倒置的直角坐标系。
x和y均为大与0的数值,其最大值由显示器的类型和模式决定。
【2】
利用人的视觉暂留这一生理特点(即对动态的图象变化,仅能分辨出时间间隔为25毫秒左右的变化,若太快,则不能分辨出来)。
将一个图象分解成不同时间出现的图象,然后一张张快速的呈现在屏幕上。
从视觉效果上看,就如同这些画面在连续的改变,因而给人以动的视觉效果。
【2】
本设计中,在利用画图函数(fillpoly(intnumpoints,intfar*polypoints))画出所需要的组合图形以后,以足够小的时间间隔(本设计中取0.0005S为单位)来刷新和改变图象位置。
由于刷新的速率比人视觉能分辨的要小,呈现在屏幕上的也就成了动的视觉效果。
4源程序解析
4.1头文件
#include"stdio.h"
#include"math.h"
#include"conio.h"
#include"stdlib.h"
#include"graphics.h"
#include"alloc.h"
stdio.h中标准文件输出,是专门用与DOS的标准输出设备(一般为显示器的),在调用参数中不需要再指定文件名,它们的输出可以在运行时重定向到一个普通的文件上去。
【2】
math.h文件库包含了所有关于数学计算的公式(如pow函数、三角函数、cos函数、sin函数等等)、内部变量的定义和各函数返回值及其参数类型的定义。
对文本的屏幕输出函数都包含在conio.h头文件中。
【3】
TurboC提供的系统函数都包含在头文件graphics.h中,它说明了制图函数的原形及其参数、功能等。
4.2编译预处理
定义了在程序中常用到且易于改变的常量,这样使程序显得明快易懂,且不会因为修改遗漏而出现程序出错。
#defineSPEED20.00
#defineLONGS25.00
#defineHIGHT3.44
#defineG9.80
#definePI3.1415926
#defineCONSBL40.00/3.44/*实际图形与模拟图形的大小比例*/
SPEED表示足球被射出时的初试速度,LONGS表示射球点到球门的距离,HIGHT表示球门的高度。
4.3图形系统初始化
编制图形程序时,首先要在程序中对使用的图形系统初始化,对屏幕颜色进行设置和清屏等。
【2】
图形系统的初始化是指确定要使用什么类型的图形显示适配器驱动程序,采用什么模式的图形方式(也就是相应程序的入口地址),以及该适配器驱动程序的路径名。
所使用系统的显示适配器一定要支持所选用的显示模式,否则将会出错。
【2】
voidInit()
{
intgraphmode;/*图形设备驱动*/
intgraphdriver;/*图形模式值*/
intErrorcode;/*出错代码*/
graphdriver=DETECT;/*自动检测显示设备类型*/
initgraph(&graphdriver,&graphmode,"C:
\\tc20");
Errorcode=graphresult();/*读取初始化的结果*/
/*如果在初始化过程中出现错误*/
if(Errorcode!
=grOk)
{
printf("GraphicsSystemError:
%s\n",grapherrormsg(Errorcode));exit
(1);
}
cleardevice();
}
参数graphmode用表
(1)所示的模式号或标号符定义。
参数graphdriver是一个显示器驱动程序的枚举变量,它属于下面所示的枚举类型:
emungraphics_driver{DETECT,CGA,MCGA,EGA,EGA64,EGAMONO,IBM8514,
HERCMONO,ATT400,VGA,PC3270};[2]其中驱动程序目录路径为空字符“”时,表示就在当前目录下,否则为TurboC软件所在的目录路径。
【2】
上面初始化过程中,由DETECT检测所用适配器的类型,将当前目录下相应的驱动程序装入,并采用最高分辨率显示模式作为graphmode的值。
【2】
4.4doubleGetAngle()函数
doubleGetAngle()
{
doubleAngle;
printf("\n\nPleaseinputtheAngleoftext:
Angle(0.00—90.00)=");
scanf("%lf",&Angle);
while
(1)
{
if(Angle<=0.00||Angle>=90.00)
{
printf("Sorry,TheAngleoftextiserror!
Pleaseinputagain!
Angle(0.00—90.00)=");
scanf("%lf",&Angle);
}
else
{returnAngle;break;}
}
}
在运行程序时屏幕会出现字符串提示,当键盘有输入以后并对从键盘接收的角度(Angle)进行判断。
如果角度不在需要测试的范围内将在出现提示并再需要重新输入角度,直到测试角度在测试范围以内。
4.5voidText()函数
调用函数GetAngle()获得一个所需要测试的角度以后就可以进行模拟。
voidText()
{
doublei,j;
doublet;
doublex,y;
doublex1,y1,hudu;
hudu=GetAngle()*PI/180.00;
x1=cos(hudu);
y1=LONGS/SPEED;
t=y1/x1;
for(i=0;i<=t;i=i+0.001)
{
cleardevice();
MakeGraph();
x=SPEED*i*cos(hudu);
y=SPEED*i*sin(hudu)-1.00/2.00*G*i*i;
setfillstyle(1,15);
circle(450-(int)(x*CONSBL),(int)300-(y*CONSBL),5);
for(j=0;j<=500000;j++)
{
;
}
}
}
setfillstyle函数的原型为:
voidfarsetfillstyle(intpattern,intcolor)【3】。
函数的功能是为下面需要画出的图形设置填充模式和填充颜色。
pattern指定要设置的填充模式,color指定要设置的填充颜色。
【2】
4.6MakeGraph()函数
MakeGraph()函数中调用fillpoly()函数来画出多边行,在多次的调用后得到了现实中的球门。
该函数的实现代码如下:
voidMakeGraph()
{
setbkcolor(BLUE);/*设置背景颜色*/
setcolor(RED);/*设置绘画颜色*/
setlinestyle(0,0,1);/*线型为实线,线宽为3个像素*/
line(70,250,125,165);
line(125,165,125,125);
line(125,125,70,210);
line(70,210,70,250);
setlinestyle(0,0,1);
line(10,250,70,250);
line(10,250,60,210);
line(60,210,70,210);
line(70,250,70,210);
line(60,210,115,125);
line(115,125,125,125);
setlinestyle(3,0,1);/*线型为点画线,线宽为一个像素*/
line(10,250,65,165);
line(65,165,125,165);
line(65,165,115,125);
}
setbkcolor函数的原型为:
voidfarsetbkcolor(intcolor)。
该函数的功能是设置背景颜色,其color指定要设置的颜色值。
【3】
setcolor函数的原型为:
voidfarsetcolor(intcolor)。
函数的功能是设置当前的绘图颜色,其color指定要设置的颜色值。
【3】
setlinestyle函数的原型为:
voidfarsetlinestyle(intlinestyle,intupattern,intthickness)。
该函数的功能是设置当前线条的类型、宽度或填充模式。
参数linestyle说明以何种线型来绘画以后的线条(如用实线、点线、中心线或者破折线),不影响画圆、圆弧、椭圆和扇形。
参数thickness指定以后画出的线条的粗细。
参数upattern:
只有当linestyle是USERBIT_LINE(4)时才起作用,在这种情况下,只要模式字里有一个为是1,则线中的对应点像素点就用当前颜色点绘画出来。
如果参数linestyle不是USERBIT_LINE(4),则参upattern仍要给出,只是被忽略而不起作用。
【3】
5程序运行结果
该程序在TurboC环境下运行,首先在屏幕上出现一个提示字符串,如图
(一)所示。
如果所输入的角度不在测试范围以后,将再出现字符串提示,如图
(二)所示。
当输入角度在测试范围以后的时候,在蓝色背景下将出现在未射球时的原始图象,如图(三)所示。
在敲击任意键以后,程序将进入到对所测试角度的模拟,其运动图象如图(四)、(五)、(六)所示。
6结语
在本程序设计中,通过TurboC提供的各种图形函数的使用,实现了对足球射门的模拟。
在模拟的过程中,忽略了空气阻力和足球本身重力的影响。
这就造成了理论模拟轨迹与实际运动轨迹产生一定的误差,但并不会对模拟的可信性有很大影响。
在实际中,足球在被射出以后的轨迹由于空气阻力和自身重力的影响,并不能达到理论中远度和高度。
C语言中还提供了目标移动、背景移动、活动页面等方法实现动画效果,无论何种方法都是对C语言中函数的灵活运用。
本文只对固定距离和固定初速度的正射门作研究,在改变三者中的任何一个或者两个条件都可以再进行研究。
在进行动画演示的过程中,屏幕出现一定的抖动,这对动画的效果产生了一定的影响,是本设计的一个不足之处。
参考文献
【1】谭浩强,C语言程序设计(第二版)[M],清华大学出版社,1999年12月第二版.
【2】王为青、刘变红,C语言高级编程及实例剖析,人民邮电出版社,2007年3月第一版,98-184
【3】郭立山、张曜、吴天,C语言函数实用手册,冶金工业出版社,2003年10月出版,26-27,212-246,252
【4】赵丽萍、王婕.物理学学习指南与思考题、习题全解,机械工业出版社,2007.3
【5】谭明金、俞海英.C语言程序设计实例精粹,电子工业出版社,2007.1
【6】
【7】
致谢
在此首先向我的指导老师黄文卿副教授表示感谢。
从论文的选题、初稿的完成到修改、定稿,他给了我诚恳的指导。
在修改源程序的过程中,我遇到了很多的问题,黄老师都给我耐心的讲解和帮助,在此,也让我学到了很多的东西,包括一些书本知识和很多为人的道理。
另外,在论文的写作过程中,对参考文献的所有作者表示衷心的感谢。
附录1:
表
(1)TurboC支持的适配器和图形模式【2】
适配器
Driver
模式
Mode
分辨率
(象素)
颜色数
页数
标记符
CGA
0
1
2
3
4
320*200
320*200
320*200
320*200
640*200
4
4
4
4
2
1
1
1
1
CGAC0
CGAC1
CGAC2
CGAC3
CGAC4
EGA
0
1
640*200
640*350
16
16
4
2
EGALO
EGAHI
EGA64
0
1
640*200
640*350
16
4
4
1
EGA64LO
EGA64HI
EGAMONO
0
640*350
2
1
EGAMONOHI
VGA
0
1
2
640*200
640*350
640*480
16
16
16
2
2
1
VGALO
VGAMED
VGAHI
MCGA
0
1
2
3
4
5
320*200
320*200
320*200
320*200
640*200
640*480
4
4
4
4
2
2
1
1
1
1
1
MCGA0
MCGA1
MCGA2
MCGA3
MCGAMED
MCGAHI
HERC
0
720*348
2
1
HERCMONOHI
ATT400
0
1
2
3
4
5
320*200
320*200
320*200
320*200
640*200
640*400
4
4
4
4
2
2
1
1
1
1
1
1
ATT400C0
ATT400C1
ATT400C2
ATT400C3
ATT400MED
ATT400HI
PC3270
0
720*350
2
1
PC3270HI
IBM8514
0
1
640*480
1024*768
256
256
IBM8514LO
IBM8514HI
附录2:
本文源程序:
#include"stdio.h"
#include"math.h"
#include"conio.h"
#include"stdlib.h"
#include"graphics.h"
#include"alloc.h"
#defineSPEED20.00
#defineLONGS25.00
#defineHIGHT3.44
#defineG9.80
#definePI3.1415926
#defineCONSBL40.00/3.44/*实际图形与模拟图形的大小比例*/
/*初始化图形系统*/
voidInit()
{
intgraphmode;/*图形设备驱动*/
intgraphdriver;/*图形模式值*/
intErrorcode;/*出错代码*/
graphdriver=DETECT;/*自动检测显示设备类型*/
initgraph(&graphdriver,&graphmode,"C:
\\WINLibTC");
Errorcode=graphresult();/*读取初始化的结果*/
/*如果在初始化过程中出现错误*/
if(Errorcode!
=grOk)
{
printf("GraphicsSystemError:
%s\n",grapherrormsg(Errorcode));
exit
(1);
}
cleardevice();
}
voidMakeGraph()
{
setbkcolor(BLUE);/*设置背景颜色*/
setcolor(RED);/*设置绘画颜色*/
setlinestyle(0,0,1);/*线型为实线,线宽为3个像素*/
line(70,250,125,165);
line(125,165,125,125);
line(125,125,70,210);
line(70,210,70,250);
setlinestyle(0,0,1);
line(10,250,70,250);
line(10,250,60,210);
line(60,210,70,210);
line(70,250,70,210);
line(60,210,115,125);
line(115,125,125,125);
setlinestyle(3,0,1);/*线型为点画线,线宽为一个像素*/
line(10,250,65,165);
line(65,165,125,165);
line(65,165,115,125);
}
/*对从键盘接收的角度判断*/
doubleGetAngle()
{
doubleAngle;
printf("\n\nPleaseinputtheAngleoftext(0--90):
Angle=");
scanf("%lf",&Angle);
while
(1)
{
if(Angle<=0.00||Angle>=90.00)
{
printf("Sorry,TheAngleoftextiserror!
Pleaseinputagain!
Angle(0.00~90.00)=");
scanf("%lf",&Angle);
}
else
{returnAngle;break;}
}
}
/*对从键盘接收的角度进行模拟*/
voidText()
{
doublei,j,t,x,y,x1,y1,hudu;
hudu=GetAngle()*PI/180.00;
x1=cos(hudu);
y1=LONGS/SPEED;
t=y1/x1;
for(i=0;i<=t;i=i+0.01)
{
cleardevice();
MakeGraph();
x=SPEED*i*(double)cos(hudu);
y=SPEED*i*(double)sin(hudu)-1.00/2.00*G*i*i;
setfillstyle(1,14);
circle(396-(x*CONSBL),205-(y*CONSBL),8);
for(j=0;j<=800000;j++)
{
;
}
}
}
voidmain()
{
Init();/*调用初始化函数*/
Text();/*调用测试函数*/
}
附录3:
背景色值与对应的颜色名【2】
颜色值
颜色名
颜色
颜色值
颜色名
颜色
0
BLACK
黑
DARDGRAY
8
深灰
1
BLUE
蓝
LIGHTBLUE
9
淡蓝
2
GREEN
绿
LIGHTGREEN
10
淡绿
3
CYAN
青
LIGHTCYAN
11
淡青
4
RED
红
LIGHTRED
12
淡红
5
MAGENTA
洋红
LIGHTMAGENTA
13
淡洋红
6
BWOWN
棕
YELLOW
14
黄
7
LIGHTGRAY
浅灰
WHITTE
15
白
线宽(thickness)【2】
符号名
值
含义
NORM_WIDTH
1
一个像素宽
THICD_WIDTH
3
3个像素宽
直线的形状(linsetyle)【2】
符号名
值
含义
SOLID_LINE
0
实线
DOTD_LINE
1
点线
CENTER_LINE