参数方程绘制球面、椭球面、环面_OpenGL

效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

球面坐标取法

在这里插入图片描述
选用经度角的余角更为方便,绘制整个球面是0到π
用经度角绘制整个球面,是从-π/2到π/2
其实没什么差别啦
在这里插入图片描述

然后椭球面和环面同理。(书上有错~)
在这里插入图片描述

关于曲面

整个曲面是由许多小的平面组成的,这里用的是四边形。
所以只要知道这些平面的坐标,便能绘制相应的曲面。
程序里要做的是,获取球面上数个点的坐标,然后用这些坐标绘制平面。
所以不同曲面在程序中的不同,也只是取点啦。

int getPoint(GLfloat radius, GLfloat a, GLfloat b, point &p) {//半径,经度角补角a,纬度角b
	p.x = radius * sin(a*pi / 180.0)*cos(b*pi / 180.0);
	p.y = radius * sin(a*pi / 180.0)*sin(b*pi / 180.0);
	p.z = radius * cos(a*pi / 180.0);
	return 1;
}
int getPoint_Oval(GLfloat rx, GLfloat ry, GLfloat rz, GLfloat a, GLfloat b, point &p) {//半径,经度角补角a,纬度角b
	p.x = rx * sin(a*pi / 180.0)*cos(b*pi / 180.0);
	p.y = ry * sin(a*pi / 180.0)*sin(b*pi / 180.0);
	p.z = rz * cos(a*pi / 180.0);
	return 1;
}
int getPoint_Ring(GLfloat radius, GLfloat rHollow, GLfloat a, GLfloat b, point &p) {//外径,内径,经度角补角a,纬度角b
	p.x = (rHollow + (radius - rHollow) * sin(a*pi / 180.0))*cos(b*pi / 180.0);
	p.y = (rHollow + (radius - rHollow) * sin(a*pi / 180.0))*sin(b*pi / 180.0);
	p.z = (radius - rHollow) * cos(a*pi / 180.0);
	return 1;
}

代码

从这里复制的代码,OpenGL 参数方程绘制球
https://blog.csdn.net/guanmjie/article/details/6369924
然后稍做修改,添加了椭球面和环面的取点函数…
懒得考虑重用了,仅有传递的参数不一样也直接复制了整个函数。

#pragma once

// Windows Header Files
#include <windows.h>

// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
#include <math.h>
#include<gl/glut.h>


#define pi 3.1415926
#define SOLID 3000
#define WIRE  3001

typedef int SPHERE_MODE;

typedef struct Point3f {
	GLfloat x;
	GLfloat y;
	GLfloat z;
}point;

void drawSlice(point &p1, point &p2, point &p3, point &p4, SPHERE_MODE mode) {//绘制四边形
	switch (mode) {//实面或网格
	case SOLID:
		glBegin(GL_QUADS);
		break;
	case WIRE:
		glBegin(GL_LINE_LOOP);
		break;
	}
	glVertex3f(p1.x, p1.y, p1.z);
	glVertex3f(p2.x, p2.y, p2.z);
	glVertex3f(p3.x, p3.y, p3.z);
	glVertex3f(p4.x, p4.y, p4.z);
	glEnd();
}

#pragma region 球面
int getPoint(GLfloat radius, GLfloat a, GLfloat b, point &p) {//半径,经度角补角a,纬度角b
	p.x = radius * sin(a*pi / 180.0)*cos(b*pi / 180.0);
	p.y = radius * sin(a*pi / 180.0)*sin(b*pi / 180.0);
	p.z = radius * cos(a*pi / 180.0);
	return 1;
}
point* getPointMatrix(GLfloat radius, GLint slices) {
	int i, j, w = 2 * slices, h = slices;
	float a = 0.0, b = 0.0;
	float hStep = 180.0 / (h - 1);//均分整个球
	float wStep = 360.0 / w;
	int length = w * h;
	point *matrix;
	matrix = (point *)malloc(length * sizeof(point));
	if (!matrix)return NULL;
	for (a = 0.0, i = 0; i < h; i++, a += hStep)//*************用经度角,则从-pi/2  均分,直接利用绘制数量做结束条件
		for (b = 0.0, j = 0; j < w; j++, b += wStep)
			getPoint(radius, a, b, matrix[i*w + j]);//[i][j]
	return matrix;
}
int drawSphere(GLfloat radius, GLint slices, SPHERE_MODE mode) {
	int i = 0, j = 0, w = 2 * slices, h = slices;
	point *mx;
	mx = getPointMatrix(radius, slices);
	if (!mx)return 0;
	for (; i < h - 1; i++) {
		for (j = 0; j < w - 1; j++)
			drawSlice(mx[i*w + j], mx[i*w + j + 1], mx[(i + 1)*w + j + 1], mx[(i + 1)*w + j], mode);
		drawSlice(mx[i*w + j], mx[i*w], mx[(i + 1)*w], mx[(i + 1)*w + j], mode);
	}
	free(mx);
	return 1;
}
#pragma endregion

#pragma region 椭球面
int getPoint_Oval(GLfloat rx, GLfloat ry, GLfloat rz, GLfloat a, GLfloat b, point &p) {//半径,经度角补角a,纬度角b
	p.x = rx * sin(a*pi / 180.0)*cos(b*pi / 180.0);
	p.y = ry * sin(a*pi / 180.0)*sin(b*pi / 180.0);
	p.z = rz * cos(a*pi / 180.0);
	return 1;
}
point* getPointMatrix_Oval(GLfloat rx, GLfloat ry, GLfloat rz, GLint slices) {
	int i, j, w = 2 * slices, h = slices;
	float a = 0.0, b = 0.0;
	float hStep = 180.0 / (h - 1);
	float wStep = 360.0 / w;
	int length = w * h;
	point *matrix;
	matrix = (point *)malloc(length * sizeof(point));
	if (!matrix)return NULL;
	for (a = 0.0, i = 0; i < h; i++, a += hStep)//*************若是用经度角,则从-pi/2开始  均分,直接利用绘制数量做结束条件
		for (b = 0.0, j = 0; j < w; j++, b += wStep)
			getPoint_Oval(rx, ry, rz, a, b, matrix[i*w + j]);//[i][j]
	return matrix;
}
int drawEllipsoid(GLfloat rx, GLfloat ry, GLfloat rz, GLint slices, SPHERE_MODE mode) {
	int i = 0, j = 0, w = 2 * slices, h = slices;
	point *mx;
	mx = getPointMatrix_Oval(rx, ry, rz, slices);
	if (!mx)return 0;
	for (; i < h - 1; i++) {
		for (j = 0; j < w - 1; j++)
			drawSlice(mx[i*w + j], mx[i*w + j + 1], mx[(i + 1)*w + j + 1], mx[(i + 1)*w + j], mode);
		drawSlice(mx[i*w + j], mx[i*w], mx[(i + 1)*w], mx[(i + 1)*w + j], mode);
	}
	free(mx);
	return 1;
}
#pragma endregion

#pragma region 环面
int getPoint_Ring(GLfloat radius, GLfloat rHollow, GLfloat a, GLfloat b, point &p) {//外径,内径,经度角补角a,纬度角b
	p.x = (rHollow + (radius - rHollow) * sin(a*pi / 180.0))*cos(b*pi / 180.0);
	p.y = (rHollow + (radius - rHollow) * sin(a*pi / 180.0))*sin(b*pi / 180.0);
	p.z = (radius - rHollow) * cos(a*pi / 180.0);
	return 1;
}
point* getPointMatrix_Ring(GLfloat r, GLfloat rHollow, GLint slices) {
	int i, j, w = 2 * slices, h = slices;
	float a = 0.0, b = 0.0;
	float hStep = 180.0 / (h - 1);
	float wStep = 360.0 / w;
	int length = w * h;
	point *matrix;
	matrix = (point *)malloc(length * sizeof(point));
	if (!matrix)return NULL;
	for (a = 0.0, i = 0; i < h; i++, a += hStep)//*************若是用经度角,则从-pi/2开始  均分,直接利用绘制数量做结束条件
		for (b = 0.0, j = 0; j < w; j++, b += wStep)
			getPoint_Ring(r, rHollow, a, b, matrix[i*w + j]);//[i][j]
	return matrix;
}
int drawRing(GLfloat r, GLfloat rHollow, GLint slices, SPHERE_MODE mode) {
	int i = 0, j = 0, w = 2 * slices, h = slices;
	point *mx;
	mx = getPointMatrix_Ring(r, rHollow, slices);
	if (!mx)return 0;
	for (; i < h - 1; i++) {
		for (j = 0; j < w - 1; j++)
			drawSlice(mx[i*w + j], mx[i*w + j + 1], mx[(i + 1)*w + j + 1], mx[(i + 1)*w + j], mode);
		drawSlice(mx[i*w + j], mx[i*w], mx[(i + 1)*w], mx[(i + 1)*w + j], mode);
	}
	free(mx);
	return 1;
}
#pragma endregion

void init(void) {
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glClearDepth(1);
	glShadeModel(GL_SMOOTH);
	GLfloat _ambient[] = { 1.0,1.0,1.0,1.0 };
	GLfloat _diffuse[] = { 1.0,1.0,1.0,1.0 };
	GLfloat _specular[] = { 1.0,1.0,1.0,1.0 };
	GLfloat _position[] = { 200,200,200,0 };
	glLightfv(GL_LIGHT0, GL_AMBIENT, _ambient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, _diffuse);
	glLightfv(GL_LIGHT0, GL_SPECULAR, _specular);
	glLightfv(GL_LIGHT0, GL_POSITION, _position);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_DEPTH_TEST);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}
void reshape(int w, int h) {
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0, 500, 0.0, 500, -500, 500);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}
void display(void) {
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glTranslated(250, 250, 0);
	glRotated(30, 1, 0, 0);
	glRotated(60, 0, 1, 0);
	//glRotated(90, 0, 0, 1);
	glColor3f(1.0, 1.0, 1.0);

	drawSphere(200, 20, WIRE);
	//drawEllipsoid(200, 100, 50, 20, WIRE);
	//drawRing(200, 180, 20, WIRE);

	glFlush();
}
int main(int argc, char **argv) {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(500, 500);
	glutInitWindowPosition(100, 100);
	glutCreateWindow("Revolution");
	init();
	glutReshapeFunc(reshape);
	glutDisplayFunc(display);
	glutMainLoop();
	return 0;
}

从这里复制的主体代码,OpenGL 参数方程绘制球
https://blog.csdn.net/guanmjie/article/details/6369924

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是圆锥面、圆环面椭球面球面参数化表达: 1. 圆锥面: x(u, v) = v * cos(u) y(u, v) = v * sin(u) z(u, v) = h - v 这里,u和v是定义曲面上点的参数,h是锥体的高度。 这个参数化表达式定义了一个以原点为顶点、以z轴为轴线的圆锥体。u参数控制了曲面上的角度变化,从0到2π,对应于一个完整的圆周。v参数控制了曲面沿着z轴方向的变化,从0到h,对应于圆锥体的高度。 2. 圆环面: x(u, v) = (R + r * cos(u)) * cos(v) y(u, v) = (R + r * cos(u)) * sin(v) z(u, v) = r * sin(u) 这里,u和v是定义曲面上点的参数,R是大圆半径,r是小圆半径。 这个参数化表达式定义了一个以原点为中心、以z轴为轴线的圆环面。u参数控制了曲面上的角度变化,从0到2π,对应于一个完整的大圆周。v参数控制了曲面沿着z轴方向的变化,从0到2π,对应于一个完整的小圆周。 3. 椭球面: x(u, v) = a * cos(u) * cos(v) y(u, v) = b * cos(u) * sin(v) z(u, v) = c * sin(u) 这里,u和v是定义曲面上点的参数,a、b和c是椭球的轴长度。 这个参数化表达式定义了一个以原点为中心、以x、y、z轴为轴线的椭球面。u参数控制了曲面上的纬度变化,从0到π,对应于从南极到北极的范围。v参数控制了曲面上的经度变化,从0到2π,对应于一个完整的经度圈。 4. 球面: x(u, v) = R * sin(u) * cos(v) y(u, v) = R * sin(u) * sin(v) z(u, v) = R * cos(u) 这里,u和v是定义曲面上点的参数,R是球的半径。 这个参数化表达式定义了一个以原点为中心、以x、y、z轴为轴线的球面。u参数控制了曲面上的纬度变化,从0到π,对应于从南极到北极的范围。v参数控制了曲面上的经度变化,从0到2π,对应于一个完整的经度圈。 希望上述参数化表达式对您有帮助!如果您还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值