opengl:绘制球体
2017-05-03 09:53
260 查看
数学基础
球面参数方程
球面的参数曲线可以用球坐标表示,引入参数u,v,其中v是球面点与原点的连线与z轴正向的夹角,u表示连线在xy平面的投影与x轴正向的夹角,如下图所示:则球面参数方程可以表示为:
球面法向量
已知球面的参数方程以后,很容易求得给定点的法向量,分别对u和v方向求偏导数,然后对两个所得向量进行叉积即可:
实现细节
已知参数方程以后,需要进行离散,分别设定u和v的步长:ustep、vstep。然后通过不同的u和v,求得坐标系中点的实际坐标(x,y,z),在实现中有一点需要注意的是:u=0与u=v这两条线上点的是球体的两个上下极点,所以进行渲染时需要区分,其中如图中间段的离散点可以按照四边形进行渲染,而上下两段则需要按照三角形进行渲染。
代码描述:
这里只是绘制了球面,如果想绘制球体,只用在渲染时,加入点的法向量即可。
点的数据结构:
class Point { public: Point(){}; Point(double a,double b,double c):x(a),y(b),z(c){}; public: double x; double y; double z; };1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
参数坐标(u,v)转换成时机坐标(x,y,z)函数
Point getPoint(double u,double v) { double x = sin(PI*v)*cos(PI2*u); double y = sin(PI*v)*sin(PI2*u); double z = cos(PI*v); return Point(x,y,z); }1
2
3
4
5
6
7
1
2
3
4
5
6
7
绘制球面
void drawWire() { double ustep = 1/(double)uStepsNum, vstep = 1/(double)vStepNum; double u = 0,v = 0; //绘制下端三角形组 for(int i = 0;i<uStepsNum;i++) { glBegin(GL_LINE_LOOP); Point a = getPoint(0,0); glVertex3d(a.x,a.y,a.z); Point b = getPoint(u,vstep); glVertex3d(b.x,b.y,b.z); Point c = getPoint(u+ustep,vstep); glVertex3d(c.x,c.y,c.z); u += ustep; glEnd(); } //绘制中间四边形组 u = 0, v = vstep; for(int i=1;i<vStepNum-1;i++) { for(int j=0;j<uStepsNum;j++) { glBegin(GL_LINE_LOOP); Point a = getPoint(u,v); Point b = getPoint(u+ustep,v); Point c = getPoint(u+ustep,v+vstep); Point d = getPoint(u,v+vstep); glVertex3d(a.x,a.y,a.z); glVertex3d(b.x,b.y,b.z); glVertex3d(c.x,c.y,c.z); glVertex3d(d.x,d.y,d.z); u += ustep; glEnd(); } v += vstep; } //绘制下端三角形组 u = 0; for(int i=0;i<uStepsNum;i++) { glBegin(GL_LINE_LOOP); Point a = getPoint(0,1); Point b = getPoint(u,1-vstep); Point c = getPoint(u+ustep,1-vstep); glVertex3d(a.x,a.y,a.z); glVertex3d(b.x,b.y,b.z); glVertex3d(c.x,c.y,c.z); glEnd(); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
初始化设置与绘图函数
#define PI 3.14159265358979323846 #define PI2 6.28318530717958647692 GLsizei width = 600,height = 600; int uStepsNum = 50,vStepNum = 50;1
2
3
4
5
6
1
2
3
4
5
6
void init() { glClearColor(0,1,1,1); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0,1,1,1); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GLfloat light_position [ ] = { 1.0f, 1.0f, 1.0f, 0.0f }; GLfloat light_ambient [ ] = { 0.2f, 0.2f, 0.2f, 0.2f }; GLfloat light_diffuse [ ] = { 0.5f, 0.5f, 0.5f, 0.2f }; GLfloat light_specular [ ] = { 0.5f, 0.5f, 0.5f, 0.2f }; glLightfv(GL_LIGHT0, GL_POSITION, light_position); glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glEnable (GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable (GL_NORMALIZE); glEnable(GL_DEPTH_TEST); glDepthFunc (GL_LESS); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void displayFunc() { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glColor3f(1.0,0.0,0.0); glPointSize(1.0); glRotated(30,1,0,0); glRotated(60,0,1,0); glRotated(90,0,0,1); drawWire(); glutSwapBuffers(); }1
2
3
4
5
6
7
8
9
10
11
12
13
1
2
3
4
5
6
7
8
9
10
11
12
13
主函数
int main(int argc,char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); glutInitWindowPosition(100,100); glutInitWindowSize(width,height); glutCreateWindow("Sphere"); init(); glutDisplayFunc(displayFunc); glutMainLoop(); }1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
效果展示
相关文章推荐
- 在OpenGL中用参数方程绘制球体
- OpenGL绘制球体
- 用 OpenGL 固定流水线绘制球体的代码例子
- 利用OpenGL固定流水线绘制球体
- 利用OpenGL固定功能流水线绘制球体
- Opengl绘制我们的小屋(一)球体,立方体绘制
- opengl:绘制球体
- Android OpenGL绘制球体
- 在OpenGL中用参数方程绘制球体
- 用多边形近似球体表面(icosphere)的Mesh数据的生成并使用openGL绘制
- openGL之几何变换(绘制球体)---openGL学习笔记(六)
- OpenGL绘制球体
- 在OpenGL中用参数方程绘制球体
- OpenGL二次曲面绘制
- OpenGL学习笔记(7)多边形绘制
- 【OpenGL】理解GL_TRIANGLE_STRIP等绘制三角形序列的三种方式
- OpenGL实现多层绘制(Layered Rendering)
- OpenGL绘制简单的参数曲线(一)——三次Hermite曲线
- opengl绘制花托原理
- OpenGL3-绘制各种图元绘制