C语言OpenGL及大数阶乘文档格式.docx
《C语言OpenGL及大数阶乘文档格式.docx》由会员分享,可在线阅读,更多相关《C语言OpenGL及大数阶乘文档格式.docx(18页珍藏版)》请在冰豆网上搜索。
![C语言OpenGL及大数阶乘文档格式.docx](https://file1.bdocx.com/fileroot1/2023-1/2/b769b83d-1ce4-443e-980a-95d17536e370/b769b83d-1ce4-443e-980a-95d17536e3701.gif)
做出九个旋转图形,利用光影效果制作不同旋转。
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;
+'
slices++;
stacks++;
-'
if(slices>
3&
&
stacks>
3)
slices--;
stacks--;
}
glutPostRedisplay();
}
2.3函数实现
调用多个绘图函数,画出九个自动旋转图形。
改变各函数的不同数据,可以改变图形形状,图形颜色,图形旋转等功能。
绘图函数:
旋转自增:
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<
windows.h>
#ifdef__APPLE__
#include<
GLUT/glut.h>
#else
GL/glut.h>
#endif
stdlib.h>
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(0,3.6,-6);
glutSolidTorus(0.2,0.8,slices,stacks);
glTranslated(2.4,3.6,-6);
glutWireCube
(1);
glTranslated(-2.4,1.2,-6);
glutWireTeapot
(1);
glTranslated(0,1.2,-6);
glRotated(60,1,0,0);
glRotated(a,2,0,1);
glutWireOctahedron();
glTranslated(2.4,1.2,-6);
glutWireSphere(1,slices,stacks);
glTranslated(-2.4,-1.2,-6);
glutSolidTeapot
(1);
glTranslated(0,-1,-6);
glutSolidOctahedron();
glTranslated(2.4,-1.2,-6);
glutSolidSphere(1,slices,stacks);
glutSwapBuffers();
staticvoididle(void)
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.1设计题目
编写常用算法的演示程序
大数阶乘源码
Codeblocks
程序有三大部分组成,一部分是主函数,另两部分是另外两种函数。
主函数负责将n输入,并通过对另外两个函数的调用实现对n的阶乘的计算。
在计算大数阶乘的过程中,乘数一般不是一位数字,计算的时候可以稍作变通,将上次的进位加上本次的积得到数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[])
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+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次方。
2013-6-14开始着手此项工作,查找与此相关的知识
2013-6-14开始写程序,同时写实验报告
2013-6-1620:
35程序基本编写完成,进行调试
2013-6-1817:
43程序编写完成
2013-6-1819:
15实验报告完成
使用时输入要计算的n值,n值在10000以内均可运行成功。
如果单纯地使用乘法来计算阶乘后的结果,那么输入数据稍大一点时就会溢出,导致运算结果出错。
(当定义int型时,n>
12时,数据会溢出,如果改成定义为double型,n>
170时,数据也会溢出),所以要用数组储存阶乘得到的数据。
#include"
stdio.h"
stdlib.h"
memory.h"
math.h"
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;
for(j=tail;
j>
=head;
j--)
unsignedlongprod=arr[j]*i+c;
arr[j]=(char)(prod%10);
c=prod/10;
head--;
arr[head]=(char)(c%10);
c/=10;
="
for(i=head;
=tail;
arr[i]+'
0'
\n"
free(arr);
voidtestCalcFac()
intn;
while
(1)
n=?
"
scanf("
%ld"
&
n);
if(n==0)
calcFac(n);
testCalcFac();