C语言OpenGL及大数阶乘.docx
《C语言OpenGL及大数阶乘.docx》由会员分享,可在线阅读,更多相关《C语言OpenGL及大数阶乘.docx(18页珍藏版)》请在冰豆网上搜索。
C语言OpenGL及大数阶乘
学院
电子信息学院
班级
学号
姓名
摘要:
利用openGL绘制旋转图形,通过改变数据,改变图形颜色,形成不同光影效果,利用不同函数绘制大小,形状不同的实心或线框图形.
目录
1摘要3
1.1设计题目3
1.2设计内容3
1.3开发工具3
1.4应用平台3
2详细设计3
2.1程序结构3
2.2主要功能3
2.3函数实现4
2.4开发日志4
3程序调试及运行4
3.1程序运行结果4
3.2程序使用说明4
3.3程序开发总结5
4附件(源程序)5
/*在后面的文档编写中,请你不要修改各个标题的内容,从而确保报告内容和风格一致。
完成全部内容后,你只需要在上面的目录上右键“更新域”,选择“只更新页码”就可以更新正确的目录页码。
注意:
目录的左边距为6.5厘米。
*/
1摘要
1.1设计题目
OpenGL图形编程
1.2设计内容
做出九个旋转图形,利用光影效果制作不同旋转。
1.3开发工具
Codeblocks
1.4应用平台
Windows2000/XP32位
2详细设计
2.1程序结构
头文件,静态变量,函数定义,函数调用,主函数。
循环型数据结构。
2.2主要功能
绘出圆环,茶壶,球,正八面体,线框和实体,还有线框立方体以及自动旋转..改变各函数的不同数据,可以改变图形形状,图形颜色,图形旋转等功能。
原理:
glTranslated函数确定每个图形位置;glColor3d(0.6,0.3,0.7);//设置绘图颜色图函数,绘图函数:
glPushMatrix();//将当前矩阵压入堆栈
glTranslated(-2.4,3.6,-6);//坐标位置
glRotated(0,1,0,0);//旋转矩阵
glRotated(a,1,0,1);
glutWireTorus(0.2,0.8,slices,stacks);//线框圆环体
glPopMatrix();//将当前矩阵弹出堆栈
光影响效果函数:
constGLfloatlight_ambient[]={0.0f,0.0f,0.0f,1.0f};//环境光源
constGLfloatlight_diffuse[];//漫发射光
constGLfloatlight_specular[]//反射高光
constGLfloatlight_position[]
数据结构:
循环型
staticvoidkey(unsignedcharkey,intx,inty)
{
switch(key)
{
case27:
case'q':
exit(0);
break;
case'+':
slices++;
stacks++;
break;
case'-':
if(slices>3&&stacks>3)
{
slices--;
stacks--;
}
break;
}
glutPostRedisplay();
}
2.3函数实现
调用多个绘图函数,画出九个自动旋转图形。
改变各函数的不同数据,可以改变图形形状,图形颜色,图形旋转等功能。
绘图函数:
glPushMatrix();//将当前矩阵压入堆栈
glTranslated(-2.4,3.6,-6);//坐标位置
glRotated(0,1,0,0);//旋转矩阵
glRotated(a,1,0,1);
glutWireTorus(0.2,0.8,slices,stacks);//线框圆环体
glPopMatrix();//将当前矩阵弹出堆栈
旋转自增:
staticvoidkey(unsignedcharkey,intx,inty)
{
switch(key)
{
case27:
case'q':
exit(0);
break;
case'+':
slices++;
stacks++;
break;
case'-':
if(slices>3&&stacks>3)
{
slices--;
stacks--;
}
break;
}
glutPostRedisplay();
}
光影响效果函数:
constGLfloatlight_ambient[]={0.0f,0.0f,0.0f,1.0f};//环境光源
constGLfloatlight_diffuse[]={1.0f,1.0f,1.0f,1.0f};//漫发射光
constGLfloatlight_specular[]={1.0f,1.0f,1.0f,1.0f};//反射高光
constGLfloatlight_position[]={2.0f,5.0f,5.0f,0.0f};
}
2.4开发日志
2013-6-13(农历二〇一三年五月初六)16:
42程序修改完.
3程序调试及运行
3.1程序运行结果
九个不同图形自动旋转.
3.2程序使用说明
使用前必须将下载GLUT并放在指定位置
3.3程序开发总结
注意函数调用,合理安排每个图形的位置及大小,否则会出现图形重叠,交叉.合理安排图形旋转.谨慎处理数据。
4附件(源程序)
/*
*GLUTShapesDemo
*
*WrittenbyNigelStewartNovember2003
*
*Thisprogramistestharnessforthesphere,cone
*andtorusshapesinGLUT.
*
*Spinningwireframeandsmoothshadedshapesare
*displayeduntiltheESCorqkeyispressed.The
*numberofgeometrystacksandslicescanbeadjusted
*usingthe+and-keys.
*/
#include
#ifdef__APPLE__
#include
#else
#include
#endif
#include
staticintslices=8;
staticintstacks=8;
/*GLUTcallbackHandlers*/
staticvoidresize(intwidth,intheight)
{
constfloatar=(float)width/(float)height;
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);//指定投影矩阵定义修剪空间
glLoadIdentity();//加载单位矩阵
glFrustum(-ar,ar,-1.0,2.0,2.0,100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();//加载单位矩阵
}
staticvoiddisplay(void)
{
constdoublet=glutGet(GLUT_ELAPSED_TIME)/1000.0;
constdoublea=t*90.0;
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor3d(0.6,0.3,0.7);//设置绘图颜色
glPushMatrix();//将当前矩阵压入堆栈
glTranslated(-2.4,3.6,-6);//坐标位置
glRotated(0,1,0,0);//旋转矩阵
glRotated(a,1,0,1);
glutWireTorus(0.2,0.8,slices,stacks);//线框圆环体
glPopMatrix();//将当前矩阵弹出堆栈
glPushMatrix();
glTranslated(0,3.6,-6);
glRotated(0,1,0,0);
glRotated(a,1,0,1);
glutSolidTorus(0.2,0.8,slices,stacks);
glPopMatrix();
glPushMatrix();
glTranslated(2.4,3.6,-6);
glRotated(0,1,0,0);
glRotated(a,1,0,1);
glutWireCube
(1);
glPopMatrix();
glPushMatrix();
glTranslated(-2.4,1.2,-6);
glRotated(0,1,0,0);
glRotated(a,1,0,1);
glutWireTeapot
(1);
glPopMatrix();
glPushMatrix();
glTranslated(0,1.2,-6);
glRotated(60,1,0,0);
glRotated(a,2,0,1);
glutWireOctahedron();
glPopMatrix();
glPushMatrix();
glTranslated(2.4,1.2,-6);
glRotated(60,1,0,0);
glRotated(a,2,0,1);
glutWireSphere(1,slices,stacks);
glPopMatrix();
glPushMatrix();
glTranslated(-2.4,-1.2,-6);
glRotated(60,1,0,0);
glRotated(a,2,0,1);
glutSolidTeapot
(1);
glPopMatrix();
glPushMatrix();
glTranslated(0,-1,-6);
glRotated(60,1,0,0);
glRotated(a,1,0,1);
glutSolidOctahedron();
glPopMatrix();
glPushMatrix();
glTranslated(2.4,-1.2,-6);
glRotated(60,1,0,0);
glRotated(a,2,0,1);
glutSolidSphere(1,slices,stacks);
glPopMatrix();
glutSwapBuffers();
}
staticvoidkey(unsignedcharkey,intx,inty)
{
switch(key)
{
case27:
case'q':
exit(0);
break;
case'+':
slices++;
stacks++;
break;
case'-':
if(slices>3&&stacks>3)
{
slices--;
stacks--;
}
break;
}
glutPostRedisplay();
}
staticvoididle(void)
{
glutPostRedisplay();
}
constGLfloatlight_ambient[]={0.0f,0.0f,0.0f,1.0f};
constGLfloatlight_diffuse[]={1.0f,1.0f,1.0f,1.0f};
constGLfloatlight_specular[]={1.0f,1.0f,1.0f,1.0f};
constGLfloatlight_position[]={2.0f,5.0f,5.0f,0.0f};
constGLfloatmat_ambient[]={0.7f,0.7f,0.7f,1.0f};
constGLfloatmat_diffuse[]={0.8f,0.8f,0.8f,1.0f};
constGLfloatmat_specular[]={1.0f,1.0f,1.0f,1.0f};
constGLfloathigh_shininess[]={100.0f};
/*Programentrypoint*/
intmain(intargc,char*argv[])
{
glutInit(&argc,argv);
glutInitWindowSize(700,600);//视窗大小
glutInitWindowPosition(10,10);//视窗位置
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow("GLUTShapes");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutIdleFunc(idle);
glClearColor(1,1,1,1);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);
glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);
glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular);
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);
glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT,GL_SHININESS,high_shininess);
glutMainLoop();
returnEXIT_SUCCESS;
}
学院
电子信息学院
班级
学号
姓名
摘要:
编写大数阶乘源码。
目录
1摘要3
1.1设计题目3
1.2设计内容3
1.3开发工具3
1.4应用平台3
2详细设计3
2.1程序结构3
2.2主要功能3
2.3函数实现4
2.4开发日志4
3程序调试及运行4
3.1程序运行结果4
3.2程序使用说明4
3.3程序开发总结5
4附件(源程序)5
/*在后面的文档编写中,请你不要修改各个标题的内容,从而确保报告内容和风格一致。
完成全部内容后,你只需要在上面的目录上右键“更新域”,选择“只更新页码”就可以更新正确的目录页码。
注意:
目录的左边距为6.5厘米。
*/
1摘要
1.1设计题目
编写常用算法的演示程序
1.2设计内容
大数阶乘源码
1.3开发工具
Codeblocks
1.4应用平台
Windows2000/XP32位
2详细设计
2.1程序结构
程序有三大部分组成,一部分是主函数,另两部分是另外两种函数。
2.2主要功能
主函数负责将n输入,并通过对另外两个函数的调用实现对n的阶乘的计算。
2.3函数实现
在计算大数阶乘的过程中,乘数一般不是一位数字,计算的时候可以稍作变通,将上次的进位加上本次的积得到数P, 将P除以10的余数做为结果的本位,将P除以10的商作为进位。
当被乘数的所有数字都和乘数相乘完毕后,将进位C放在积的最前面即可。
根据此原理编写函数。
一个m位数乘以n位数,其结果为m+n-1,或者m+n位,所以需首先定义一个至少m+n个元素的数组,并置前n位为0。
计算一个m位的被乘数乘以一个n位的整数k,积仍存储于数组a
voidmul(unsignedchara[],unsignedlongk,intm,intn)
{
inti;
unsignedlongp;
unsignedlongc=0;
for(i=m+n-1;i>=n;i--)
{
p=a[i]*k+c;
a[i]=(unsignedchar)(p%10);
c=p/10;
}
while(c>0)
{
a[i]=(unsignedchar)(c%10);
i--;
c/=10;
}
}
intmain(intargc,char*argv[])
{
inti;
unsignedchara[]={0,0,0,2,3,4,5};
mul(a,678,4,3);
i=0;
while(a[i]==0)
i++;
for(;i<4+3;i++)
printf("%c",a[i]+’0’);//由于数a[i](0<=a[i]<=9)对应的可打印字任符为’0’到’9’,所以显示为i+’0’
return0;
}
从上面的例子可知,在做乘法之前,必须为数组保留足够的空间。
具体到计算n!
的阶乘时,必须准备一个能容纳的n!
的所有位数的数组或者内存块。
即数组采有静态分配或者动态分配。
前者代码简洁,但只适应于n小于一个固定的值,后者灵活性强,只要有足够的内存,可计算任意n的阶乘,我们这里讨论后一种情况,如何分配一块大小合适的内存。
n!
有多少位数呢?
我们给出一个近似的上限值:
n!
<(n+1)/2的n次方,下面是推导过程。
Caes1:
n是奇数,则中间的那个数mid=(n+1)/2,除了这个数外,我们可以将1到n之间的数分成n/2组,每组的两个数为mid-i和mid+i(i=1到mid-1),如1,2,3,4,5,6,7可以分为数4,和3对数,它们是(3,5),(2,6)和(1,7),容易知道,每对数的积都于小mid*mid,故n!
小于(n+1)/2的n的次方。
Case2:
n是个偶数,则中间的两个数(n-1)/2和(n+1)/2,我们将(n+1)/2记做mid,则其它的几对数是(mid-2,mid+1),(mid-3)(mid+2)等等,容易看出,n!
小于mid的n次方。
由以上两种情况可知,对于任意大于1的正整数n,n!
<(n+1)/2的n次方。
3程序调试及运行
2.4开发日志
2013-6-14开始着手此项工作,查找与此相关的知识
2013-6-14开始写程序,同时写实验报告
2013-6-1620:
35程序基本编写完成,进行调试
2013-6-1817:
43程序编写完成
2013-6-1819:
15实验报告完成
3.1程序运行结果
3.2程序使用说明
使用时输入要计算的n值,n值在10000以内均可运行成功。
3.3程序开发总结
如果单纯地使用乘法来计算阶乘后的结果,那么输入数据稍大一点时就会溢出,导致运算结果出错。
(当定义int型时,n>12时,数据会溢出,如果改成定义为double型,n>170时,数据也会溢出),所以要用数组储存阶乘得到的数据。
4附件(源程序)
#include"stdio.h"
#include"stdlib.h"
#include"memory.h"
#include"math.h"
#include"malloc.h"
voidcalcFac(unsignedlongn)
{
unsignedlongi,j,head,tail;
intblkLen=(int)(n*log10((n+1)/2));//计算n!
有数数字的个数
blkLen+=4;//保险起见,多加4位
if(n<=1)
{printf("%d!
=0/n",n);
return;}
char*arr=(char*)malloc(blkLen);
if(arr==NULL)
{printf("allocmemoryfail/n");return;}
memset(arr,0,sizeof(char)*blkLen);
head=tail=blkLen-1;
arr[tail]=1;
for(i=2;i<=n;i++)
{
unsignedlongc=0;
for(j=tail;j>=head;j--)
{
unsignedlongprod=arr[j]*i+c;
arr[j]=(char)(prod%10);
c=prod/10;
}
while(c>0)
{
head--;
arr[head]=(char)(c%10);
c/=10;
}
}
printf("%d!
=",n);
for(i=head;i<=tail;i++)
printf("%c",arr[i]+'0');
printf("\n");
free(arr);
}
voidtestCalcFac()
{
intn;
while
(1)
{
printf("n=?
");
scanf("%ld",&n);
if(n==0)
break;
calcFac(n);
}
}
intmain(intargc,char*argv[])
{
testCalcFac();
return0;
}