当前位置:文档之家› 软件编程课程设计

软件编程课程设计

软件编程课程设计
软件编程课程设计

软件编程课程设计

一.根据最小二乘原理,对给出两组观测数据分别作线性拟合曲线和一般多项式曲线。

1.线性拟合观测数据:

Xi:1 2 3 4 5

Yi:0 2 2 5 4

(1)程序设计流程图:

YES

NO

(2)(部分)源程序:

/*======================================================

Purpose:形如p(x) = a + bx形式的(x_i,y_i)的线性拟合

=======================================================*/

#include //标准的输入输出流头文件

#define MAX_N 25 //(x_i,y_i)的最大维数

typedefstructtagPOINT

{

double x;

double y;

} POINT; //建立结构体函数

int main()

{

int m; //输入m组数据

inti;

POINT points[MAX_N];

static double u11,u12,u21,u22,c1,c2; //设置变量

doublea,b;

cout<<"\nPlease Input m Value"<

cin>>m;

if (m > MAX_N)

{

cout<<"The input m is larger than MAX_N,please redefine the MAX_N."<

return 1;

}

if (m <= 0)

{

cout<<"Please input a number between 1 and " <

return 1;

}

cout<<"Now input the (x_i,y_i),i=,……,"<

for (i = 0; i< m; i++) //输入变量值,存入结构体函数

{

cin>>points[i].x;

cin>>points[i].y;

}

for (i = 0; i< m; i++) //列出方程U(a,b)' = c

{

u21 += points[i].x; //x的和

u22 += points[i].x * points[i].x; //x的平方和 c1 += points[i].y; //y的和

c2 += points[i].x * points[i].y; //x*y的和}

u12 = u21;

u11 = m;

//开始求解

a = (c1 * u22 - c2 * u12)/(u11 * u22 - u12 * u21); //求a

b = (c1 * u21 -c2 * u11)/(u21 * u12 - u22 * u11); //求b

cout<<"Solve: p(x) = "<

return 0;

}

(3)程序运行界面截图:

(4)调试中出现的问题及解决方法:

为了用最小二乘法计算拟合曲线的系数,一开始定义了许多变量,使程序显得很乱,不简洁。后来改用结构体变量,把要求的系数放在一个结构体变量中,精简了程序。

2.一般多项式观测数据:

Xi:-3 -2 -1 0 1 2 3

Yi:4 2 3 0 -1 -2 -5

(1)程序设计流程图:

(2)(部分)源程序:

#include "stdio.h"

#include "math.h"

#include "stdlib.h"

#include "windows.h"

//引用头文件

double sum(double * dNumarry,int n); //求和的函数

double MutilSum(double* dX,double *dY,int n); //求乘法的函数double RelatePow(double *dx,intn,int ex); //计算x的y次幂的

函数

double RelateMutiXY(double *dx,double*dy,intn,int ex); //关联xy

的函数

void EMatrix(double *dx,double*dy,intn,intex,double coefficient[]); //定义变量,确定多项式阶数

voidCalEquation(intexp,double coefficient[] );

double F(double c[],intl,int m);

doubleEm[10][10];

//所构造的多项式的系数

int main(intargc, char* argv[])

{

double arry1[7]={-3,-2,-1,0,1,2,3};

double arry2[7]={4,2,3,0,-1,-2,-5}; //写入观测值

double coefficient[10];

ZeroMemory(coefficient,sizeof(double)*10);

// double dSumarry1= sum(arry1,7);

// printf("darry1=%lf\n",dSumarry1);

//

// double dSumarry2=sum(arry2,7);

// printf("darry2=%lf\n",dSumarry2);

//

// double dMultiarry1=MutilSum(arry1,arry1,7);

// printf("dMultiarry1=%lf\n",dMultiarry1);

// double dMultiarry12=MutilSum(arry1,arry2,7);

//

printf("dMultiarry2=%lf\n",dMultiarry12);//,coefficient[4],coefficien

t[5]

//+ %lfx^3 + %lfx^4

EMatrix(arry1,arry2,7,3,coefficient); //给变量赋值,此处ex=3是拟合

二次多项式

printf("拟合方程为:y = %lf + %lfx + %lfx^2 \n",coefficient[1],coefficient[2],coefficient[3]);

return 0;

}

double sum(double * dNumarry,int n)

{

double *dTemp= new double[n];

doubledSum=0;

dTemp=dNumarry;

for (inti=0;i

{

dSum+=dTemp[i];

}

return dSum; //求和

}

doubleMutilSum(double* dX,double *dY,int n)

{

double * dXTemp= new double [n];

double * dYTemp= new double [n];

doubledMultiSum=0;

dXTemp=dX;

dYTemp=dY;

for (inti=0;i

{

dMultiSum += dX[i]*dY[i];

}

return dMultiSum; //求x和y的乘积

}

doubleRelatePow(double *dx,intn,int ex)

{

double * dTemp =new double[n];

doubleReSum=0;

dTemp=dx;

for (int j=0;j

{

ReSum+=pow(dTemp[j],ex);

}

return ReSum; //计算x的幂

}

doubleRelateMutiXY(double *dx,double*dy,intn,int ex)

{

double * dXTemp= new double [n];

double * dYTemp= new double [n];

doubledReMultiSum=0;

dXTemp=dx;

dYTemp=dy;

for (inti=0;i

{

dReMultiSum+=pow(dXTemp[i],ex)*dYTemp[i];

}

returndReMultiSum;

}

//计算方程组的增广矩阵

voidEMatrix(double *dx,double*dy,intn,intex,double coefficient[] ) {

double * dXTemp= new double [n];

double * dYTemp= new double [n];

dXTemp=dx;

dYTemp=dy;

for(inti=1;i<=ex;i++)

{

for(int j=1;j<=ex;j++)

{

Em[i][j]=RelatePow(dXTemp,n,i+j-2);

}

Em[i][ex+1]=RelateMutiXY(dXTemp,dYTemp,n,i-1);

}

Em[1][1]=n;

CalEquation(ex,coefficient); //x的系数

}

//求解方程

voidCalEquation(intexp,double coefficient[] )

{

for(int k=1;k

{

for(inti=k+1;i

{

double p1=0;

if(Em[k][k]!=0)

p1=Em[i][k]/Em[k][k];

for(int j=k;j

Em[i][j]=Em[i][j]-Em[k][j]*p1;

}

}

coefficient[exp]=Em[exp][exp+1]/Em[exp][exp];

for(int l=exp-1;l>=1;l--) //回代求解

coefficient[l]=(Em[l][exp+1]-F(coefficient,l+1,exp))/Em[l][l]; }

double F(double c[],intl,int m)//供CalEquation函数调用

{

double sum=0;

for(inti=l;i<=m;i++)

sum+=Em[l-1][i]*c[i];

return sum;

}

(3)程序运行界面截图:

(4)调试中出现的问题及解决方法:

通过网上资料查找首先了解什么是最小二乘法的多项式拟合。拟合过程中随着高阶逐渐增加拟合的曲线也会存在病态,所以有时候对比较高的高阶需要压缩后在拟合。这里是没有经过压缩的拟合,我会继续深入研究更高阶的曲线拟合。EMatrix这个函数的ex要加1,就是说如果要求四次就要ex要写5。

二.用OpenGL的图形库设计长方体。

1.长方体的六个面对应六张不同的图像,可以通过键盘进行上下左右旋转。

(1)程序设计流程图:

(2)(部分)源程序:

#include // Windows的头文件

#include // OpenGL32库的头文件

#include

#include

#pragma comment(lib, "glaux.lib") // GLaux连接库

#include // GLaux库的头文件

static GLfloatxRot = 0.0f; //建立x轴的坐标

static GLfloatyRot = 0.0f; //建立y轴的坐标

GLuint texture[6]; //纹理填充

AUX_RGBImageRec *LoadBMP(char *FileName) //加载.bmp图像,返回该图像的指针

{

FILE *File = NULL;

if(!FileName)

return NULL;

File = fopen(FileName,"r");

if (File)

{

fclose(File);

returnauxDIBImageLoad(FileName);

}

return NULL;

}

//载入.bmp格式的贴图纹理

intLoadGLTextures() // 载入位图(调用上面的代码)并转换成纹理

{

int Status = FALSE;

char *bmpFile[6] = {"1.bmp","2.bmp","3.bmp", //创建纹理的存储空间

"4.bmp","5.bmp","6.bmp"};

AUX_RGBImageRec *TextureImage[6] = {NULL,NULL,NULL,NULL,NULL,NULL}; for(inti = 0;i < 6;++i)

{

//memset(TextureImage[i],0,sizeof(void*) * 1);//set the point to NULL

if (TextureImage[i] = LoadBMP(bmpFile[i]))

{

Status = TRUE;

glGenTextures(1,&texture[i]); //命名纹理对象

glBindTexture(GL_TEXTURE_2D,texture[i]); //绑定纹理

glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,TextureImage[i]->sizeX, TextureImage[i]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,

TextureImage[i]->data); //指定纹理

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //指定过滤模式

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

}

if (TextureImage[i])

{

if (TextureImage[i]->data)

free(TextureImage[i]->data);

free(TextureImage[i]);

}

}

return Status;

}

voidRenderScene(void)

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnable(GL_DEPTH_TEST);

if(!LoadGLTextures());

glEnable(GL_TEXTURE_2D);

LoadGLTextures(); //载入纹理贴图

glPushMatrix();

glRotatef(xRot, 1.0f, 0.0f, 0.0f);

glRotatef(yRot, 0.0f, 1.0f, 0.0f);

glBindTexture(GL_TEXTURE_2D,texture[0]);

glBegin(GL_QUADS);

// glColor3f(1.0,0.0,0.0);//红色

glTexCoord2f(0.0f, 0.0f); glVertex3f( 10.0f, 10.0f,20.0f); //上面glTexCoord2f(1.0f, 0.0f); glVertex3f(-10.0f, 10.0f,20.0f);

glTexCoord2f(1.0f, 1.0f);glVertex3f(-10.0f,-10.0f,20.0f);

glTexCoord2f(0.0f, 1.0f); glVertex3f( 10.0f,-10.0f,20.0f);

glEnd();

glBindTexture(GL_TEXTURE_2D,texture[1]);

glBegin(GL_POLYGON);

// glColor3f(0.0,1.0,0.0); //绿色

glTexCoord2f(0.0f, 1.0f); glVertex3f(10.0, 10.0,-10.0); //右面glTexCoord2f(0.0f, 0.0f);glVertex3f(10.0, 10.0, 20.0);

glTexCoord2f(1.0f, 0.0f); glVertex3f(10.0,-10.0, 20.0);

glTexCoord2f(1.0f, 1.0f); glVertex3f(10.0,-10.0,-10.0);

glEnd();

glBindTexture(GL_TEXTURE_2D,texture[2]);

glBegin(GL_POLYGON);

// glColor3f(0.0,0.0,1.0);//蓝色

glTexCoord2f(1.0f, 0.0f); glVertex3f( 10.0,-10.0,-10.0); //下

glTexCoord2f(1.0f, 1.0f);glVertex3f(-10.0,-10.0,-10.0);

glTexCoord2f(0.0f, 1.0f); glVertex3f(-10.0, 10.0,-10.0);

glTexCoord2f(0.0f, 0.0f); glVertex3f( 10.0, 10.0,-10.0);

glEnd();

glBindTexture(GL_TEXTURE_2D,texture[3]);

glBegin(GL_POLYGON);

// glColor3f(1.0,1.0,0.0);// 黄色

glTexCoord2f(1.0f, 0.0f); glVertex3f(-10.0, 10.0, 20.0); //左面glTexCoord2f(1.0f, 1.0f); glVertex3f(-10.0, 10.0,-10.0);

glTexCoord2f(0.0f, 1.0f); glVertex3f(-10.0,-10.0,-10.0);

glTexCoord2f(0.0f, 0.0f); glVertex3f(-10.0,-10.0, 20.0);

glEnd();

glBindTexture(GL_TEXTURE_2D,texture[4]);

glBegin(GL_POLYGON);

//glColor3f(0.0,1.0,1.0);

glTexCoord2f(1.0f, 1.0f); glVertex3f( 10.0,10.0,-10.0); //后面glTexCoord2f(0.0f, 1.0f); glVertex3f(-10.0,10.0,-10.0);

glTexCoord2f(0.0f, 0.0f);glVertex3f(-10.0,10.0, 20.0);

glTexCoord2f(1.0f, 0.0f);glVertex3f( 10.0,10.0, 20.0);

glEnd();

glBindTexture(GL_TEXTURE_2D,texture[5]);

glBegin(GL_POLYGON);

// glColor3f(1.0,0.0,1.0);

glTexCoord2f(0.0f, 0.0f); glVertex3f( 10.0,-10.0, 20.0); //前面glTexCoord2f(1.0f, 0.0f); glVertex3f(-10.0,-10.0, 20.0);

glTexCoord2f(1.0f, 1.0f); glVertex3f(-10.0,-10.0,-10.0);

glTexCoord2f(0.0f, 1.0f); glVertex3f( 10.0,-10.0,-10.0);

glEnd();

glPopMatrix();

glutSwapBuffers();

}

/*void SetupRC()

{

//glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

glColor3f(0.0f, 1.0f, 0.0f);

glShadeModel(GL_FLAT);

//glFrontFace(GL_CW);

}*/

void SpecialKeys(int key, int x, int y) //设置键盘控制{

if(key == GLUT_KEY_UP)

xRot-= 5.0f;

if(key == GLUT_KEY_DOWN)

xRot += 5.0f;

if(key == GLUT_KEY_LEFT)

yRot -= 5.0f;

if(key == GLUT_KEY_RIGHT)

yRot += 5.0f;

if(key > 356.0f)

xRot = 0.0f;

if(key < -1.0f)

xRot = 355.0f;

if(key > 356.0f)

yRot = 0.0f;

if(key < -1.0f)

yRot = 355.0f;

glutPostRedisplay();

}

voidChangeSize(int w, int h)

{

GLfloatnRange = 25.0f;

if(h == 0)

{

h = 1;

}

glViewport(0, 0, w, h);

glMatrixMode(GL_PROJECTION); //设置下面的操作矩阵为GL_MODELVIEW

glLoadIdentity();

if (w <= h)

{

glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);

}

else

{

glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);

}

glMatrixMode(GL_MODELVIEW);

glLoadIdentity(); //空间的视觉范围设置

}

int main(intargc, char* argv[])

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

glutCreateWindow("按上下左右键旋转"); //创建窗口

glutReshapeFunc(ChangeSize);

glutSpecialFunc(SpecialKeys); //键盘控制

glutDisplayFunc(RenderScene); //显示绘图

// SetupRC();

glutMainLoop(); //主循环

return 0;

}

(3)程序运行界面截图:

(4)调试中出现的问题及解决方法:

1.长方体开始旋转时没有绕着自身旋转而是绕着原点旋转,经检查后发现glRotatef()函数和glTranslatef()顺序写错,应该先平移,后旋转,而不是先旋转后平移;

2.贴的图片一开始不显示,后发现图片大小设置错误,改成64乘64像素的就可以正常显示了。

2.两个长方体,可以分别对每个长方体进行旋转。

(1)程序设计流程图:

(2)(部分)源程序:

#include

GLfloat vertices[][3] = {{-1.0, -1.0, 1.0}, {-1.0, 1.0, 1.0}, //定义八个点;

{1.0, 1.0, 1.0}, {1.0, -1.0, 1.0}, {-1.0, -1.0, -1.0},

{-1.0, 1.0, -1.0}, {1.0, 1.0, -1.0}, {1.0, -1.0, -1.0}};

GLfloat colors[][3] = {{1.0, 0.0, 0.0}, {0.0, 1.0, 1.0}, //定义六种颜色;

{1.0, 1.0, 0.0}, {0.0, 1.0, 0.0},

{0.0, 0.0, 1.0}, {1.0, 0.0, 1.0}};

float xrot[2] = {0.0f}; //定义两组旋转参数;floatyrot[2] = {0.0f};

inti=0; //定义旋转参数的组号

void polygon(int a, int b, int c, int d) //绘制四边形函数;{

glBegin(GL_POLYGON);

glVertex3fv(vertices[a]);

glVertex3fv(vertices[b]);

glVertex3fv(vertices[c]);

glVertex3fv(vertices[d]);

glEnd();

}

void colorcube() //绘制立方体函数;

{

glColor3fv(colors[0]); //设置颜色;

polygon(0, 3, 2, 1); //绘制正方形;

glColor3fv(colors[1]);

polygon(2, 3, 7, 6);

glColor3fv(colors[2]);

polygon(3, 0, 4, 7);

glColor3fv(colors[3]);

polygon(1, 2, 6, 5);

glColor3fv(colors[4]);

polygon(4, 5, 6, 7);

glColor3fv(colors[5]);

polygon(5, 4, 0, 1);

}

void mymenu(int value) //菜单函数;

{

i=value; //根据菜单选项,选定当前的旋转操作组;

}

void init() //初始化函数;

{

glClearColor(0.0, 0.0, 0.0, 0.0); //清屏,屏幕为黑色;

glColor3f(1.0, 1.0, 1.0); //设置初始颜色为白色;

glutCreateMenu(mymenu); //创建菜单,注册菜单处理函数mymenu;

glutAddMenuEntry("left",0); //给菜单加一个名

为left的条目,并设置,当点击此条目传递给mymenu一个值:0(int型)glutAddMenuEntry("right",1); //给菜单加

一个名为right的条目,……

glutAttachMenu(GLUT_RIGHT_BUTTON); //绑定菜单到鼠标右击;

}

void display(void) //绘制函数;

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除颜色和深度缓冲;

glEnable(GL_DEPTH_TEST); //启用深度;

glMatrixMode(GL_MODELVIEW); //设置,以下的操作修改的是GL_MODELVIEW(模型视景矩阵)

/*GL_PROJECTION是对投影矩阵操作,

**GL_MODELVIEW是对模型视景矩阵操作,

**GL_TEXTURE是对纹理矩阵进行随后的操作

*/

glLoadIdentity(); //GL_MODELVIEW矩阵设置为单位矩阵,类似于还原为初始状态;

glTranslatef(-2.0,0,0); //矩阵左移2单位值;

glRotatef(xrot[0], 1.0, 0.0, 0.0); //设置矩阵的旋转值;

glRotatef(yrot[0], 0.0, 1.0, 0.0);

glScalef(1.0,1.5,.5); //设置矩阵拉伸值,也就是将正方体变为长方体;

colorcube(); //按照此矩阵,绘图;

glLoadIdentity(); //还原矩阵GL_MODELVIEW;

glTranslatef(2.0,0,0); //右移2单位值;

glRotatef(xrot[1], 1.0, 0.0, 0.0); //设置旋转值;

glRotatef(yrot[1], 0.0, 1.0, 0.0);

glScalef(1.0,0.5,0.5); //拉伸值;

colorcube(); //绘图;

glFlush(); //立即执行,不进入缓冲;

glutSwapBuffers(); //交换前后台;

}

void reshape(int w, int h) //重绘函数(参数为新窗口的长宽);

{

glViewport(0, 0, w, h); //窗口左下角为(0,0),窗口右上角为(w,h);

glMatrixMode(GL_PROJECTION); //设置下面的操作矩阵为GL_PROJECTION;

glLoadIdentity(); //设置矩阵为单位矩阵;

glOrtho(-4.0, 4.0, -4.0, 4.0, -4.0, 4.0); //空间的视觉范围设置;(left, right, bottom, top, near, far)

}

void keyboard(intkey,intx,int y) //按键响应函数;

{

if(key==GLUT_KEY_UP) //根据按键,设置当前旋转值,每次加5度或减5度(角度);

xrot[i]+=5.0;

if(key==GLUT_KEY_DOWN)

xrot[i]+=355.0;

if(key==GLUT_KEY_LEFT)

yrot[i]+=5.0;

if(key==GLUT_KEY_RIGHT)

yrot[i]+=355.0;

if(xrot[i]>=360) //使旋转值保持在360度以内;

xrot[i]-=360;

if(yrot[i]>=360)

yrot[i]-=360;

glutPostRedisplay(); //当前窗口需要重新绘制;

}

int main(intargc, char **argv)

{

glutInit(&argc, argv); //初始化;glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); //设置显示方式,[颜色,双缓存,深度缓存]

/*使用双缓存是为了把完整图画一次性显示在窗口上,

以避免把计算机作图的过程都表现出来;

**使用深度缓存是为了只看到所画图形的外表**/

glutInitWindowSize(400, 400); //设置窗口大小;

glutInitWindowPosition(200, 200); //设置窗口在屏幕中的位置;

glutCreateWindow("OpenGL"); //创建窗口,并命名标题为OpenGL;

glutDisplayFunc(display); //注册一个绘图函数display,操作系统在必要时刻就会用display对窗体进行重新绘制操作;

glutReshapeFunc(reshape); //注册重绘函数reshape,当窗口被拉动时候(也就是窗口大小改变),调用reshape;

glutSpecialFunc(keyboard); //注册一个特殊键盘按键响应函数keyboard,当用户输入特殊字符时,程序调用keyboard函数;

init(); //初始设置;

glutMainLoop(); //让系统陷入死循环,也就是程序永远运行;

}

(3)程序运行界面截图:

相关主题
文本预览
相关文档 最新文档