openGL学习笔记2

第一章第1题(如果助教一个一个百度代码网上是不是有,当然助教哥哥这么帅助教姐姐这么漂亮也不会有这么多时间,如果万一百度到这个代码,请相信这么烂的代码一定是自己写的然后贴上来的。。。。)

【题目描述】

编写一个程序,绘制一个用直线或多边形逼近表示的圆。一种方法是利用简单的三角形法计算出圆周上各点的位置。另外一种方法是将一个简单正多边形(如等边三角形)逐步细分为精细的多边形。

【分析】

可以通过三角函数计算出圆周上点的坐标,然后用LINELOOP连接起来,当点数很多的时候就会看着像圆形。

第二种分形的方法没想出来怎么做,请前辈指教。

【代码】

 1 /*三角函数法LINELOOP逼近圆 参数:半径0.5 边数:100 线宽:2.0*/
 2 #include<stdio.h>
 3 #include<GL/glut.h>
 4 #include<math.h>
 5 const double PI=3.14;
 6 
 7 void display()
 8 {
 9     int n=20,i=1;
10     double theta=360/n,x=0,y=0,r=0.5;//初始化半径1.5,并且把theta分成20份
11     glClear(GL_COLOR_BUFFER_BIT);
12     glLineWidth(2.0);//绘制线宽
13     glBegin(GL_LINE_LOOP);
14     for (;i*theta<=360;i++)
15     {
16         x=r*cos(i*theta*PI/180);//利用圆的三角表示
17         y=r*sin(i*theta*PI/180);
18         glVertex2f(x,y);
19     }
20     glEnd();
21     glFlush();
22 }
23 
24 void init()
25 {
26     glClearColor (1.0,1.0,1.0,0.0);
27     glColor3f(0.0,0.0,0.0);
28     glMatrixMode(GL_PROJECTION);
29     glLoadIdentity();
30     gluOrtho2D(-1.0,1.0,-1.0,1.0);
31 }
32 
33 int main(int argc,char** argv)
34 {
35     glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
36     glutInitWindowSize(500,500);
37     glutInitWindowPosition(0,0);
38     glutCreateWindow("");
39     glutDisplayFunc(display);
40     init();
41     glutMainLoop();
42 }

【效果】

第一章第3题(如果助教一个一个百度代码网上是不是有,当然助教哥哥这么帅助教姐姐这么漂亮也不会有这么多时间,如果万一百度到这个代码,请相信这么烂的代码一定是自己写的然后贴上来的。。。。)

【题目描述】

从一个底边与x轴平行,有三条线段构成的三角形开始,递归地对另外两条边进行细分,每次都将新顶点移动一个随机小量。最后形成的形状看起来应该像山脉的轮廓。

【分析】

开始没理解到山脉的轮廓是什么。百度了好久毛线资料没有,只能硬写了T_T

然后发现这题的意思应该是:先有一个三角形以一条底边为基础,对另外的两条边进行细分,得到两个新端点,将新得到的端点坐标移动一个随机小量,再分别与底边端点链接起来,得到两个新的三角形。不断对新三角形进行同样的操作,最后看起来就像远处的山的那种黑色影子(当然要开启多边形填充功能,使得得到的三角形都是填充的,也就是实心的)。

我最开始写的代码特别复杂,然后请教了下同学shaco,简化了一点点=。 =

【代码】

/*从一个底边与x轴平行,由三条线段构成的三角形开始,递归的对另外两边进行细分,每次都将新的
顶点移动一个随机小量。最后形成的形状看起来应该像山脉的轮廓*/
#include<stdio.h>
#include<GL/glut.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
#define DEEPMAX 15//递归深度
int ax=-1.0,ay=-1.0,bx=1.0,by=-1.0,cx=0.0,cy=1.0;//左底,右底,顶点

void devidetriangle(float x,float y,int deep)
{
    float lx,ly,rx,ry;
    if (deep==DEEPMAX)
        return;
    glBegin(GL_TRIANGLES);
      glVertex2f(ax,ay);
      glVertex2f(bx,by);
      glVertex2f(x,y);
    glEnd();
    lx=x-(x-ax)/10+(0.2*rand()/RAND_MAX-0.1);//每次从山顶向下走新距离的1/10,并移动-0.1~0.1
    ly=y-(y-ay)/10+(0.2*rand()/RAND_MAX-0.1);
    rx=x+(bx-x)/10+(0.2*rand()/RAND_MAX-0.1);
    ry=y-(y-by)/10+(0.2*rand()/RAND_MAX-0.1);
    lx=lx>ax?lx:ax;//边界判断,加了随机量后不超过边界,不然看着不像山脉
    ly=ly>ay?ly:ay;
    rx=rx<bx?rx:bx;
    ry=ry>by?ry:by;
    devidetriangle(lx,ly,deep+1);//对左边细分出的顶点递归
    devidetriangle(rx,ry,deep+1);//对右边细分出的顶点递归
}
void display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    srand((unsigned)(time(NULL)));//根据运行时间确定随机数种子
    devidetriangle(cx,cy,1);
    glFlush();
}

void init()
{
    glClearColor (1.0,1.0,1.0,0.0);
    glColor3f(0.0,0.0,0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-2.0,2.0,-2.0,2.0);
    glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);//设置为FILL填充
}
int main(int argc,char** argv)
{
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(0,0);
    glutCreateWindow("山脉");
    glutDisplayFunc(display);
    init();
    glutMainLoop();
}

【效果】

————————————————————下面是心得————————————————————

1.复习了rand()的用法,rand()/RAND_MAX能产生0~1的随机数,在之前要srand设置种子。

2.复习了PS的一些东西=。= 显示器RGB光的三原色RGB红绿蓝是加色,因此1.0 1.0 1.0 代表白色(而印刷CMYK的印刷三原色CMY青品黄100 100 100是黑色)

3.最开始的时候看不到任何东西是因为投影矩阵没设置好。gluortho2D能够很好地处理2D投影矩阵。

posted on 2014-04-05 17:22  BWB  阅读(1364)  评论(0编辑  收藏  举报

导航