opengl三维几何变换实例

引言

> 接上一篇

  • 要在opengl中显示三维物体需要将投影模式设置为透视 如gluPerspective(45, 1, 0, 100);
    第一个参数为fov角,第二个参数是宽高比,后两个参数分别是最近可视距离和最远可视距离
#include<glut.h>
int main(int argc, char** argv)
{    
    
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(500, 500);
    glutInitWindowSize(500, 500);
    glutCreateWindow("title");
    init();
    glutDisplayFunc(display);
    glutMainLoop();

}
void display()
{

}
void init()
{
    glClearColor(1, 1, 1, 1);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, 1, 0, 100);
}

以下例子加入到display方法中即可运行



opengl三维平移变换

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(-1, 0, -10);
	glColor3f(1, 0, 0);
	glutWireCube(1);

	glTranslatef(3, 0, 0);
	glColor3f(0, 1, 0);
	glutWireCube(1);

  • opengl使用glTranslatef构建平移矩阵,参数分别为朝x,y,z轴移动的方向,三维和二维变换区别不大,二维只要填前两个参数第三个参数置为0即可。
    上面先在(-1,0,-10)处绘制了一个红色的线框立方体,然后使用glTranslatef向右平移三个单位,绘制一个绿色的线框立方体

在这里插入图片描述



opengl三维缩放变换

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(-1, 0, -10);
	glColor3f(1, 0, 0);
	glutWireCube(1);
	
	glScalef(1.5, 1.5, 1.5);
	glColor3f(0, 1, 0);
	glutWireCube(1);
  • opengl使用
    glScalef函数构建缩放矩阵。有三个参数,分别是沿x,y,z轴的缩放参数,大于1代表扩大,小于1代表缩小。三维变换和二维差不多,要构建二维缩放矩阵只要把第三个参数设为1即可,代表在z轴上不发生变化。
    缩放变化同时还需要一个缩放参照点,因为缩放变化不仅改变自身大小,也改变了自身到缩放点的距离。
    opengl默认使用原点作为缩放变换的参照点。 这个例子先创建一个绿色的线框立方体,然后再创建了一个放大版的绿色线框立方体

在这里插入图片描述



绕平行于坐标轴的一条轴旋转

  • 三维缩放和平移都仅仅是二维缩放和平移的简单扩充,只要加上一个参数代表新增加的一条轴即可。而三维旋转比二维旋转要复杂的多,这是因为在二维旋转中往往注意不到旋转轴的存在。二维旋转中旋转轴可以说是始终垂直于显示平面,而在三维旋转中,需要始终意识到旋转轴的存在。
  • 在三维中进行一次旋转需要确定旋转轴和旋转角度,其中旋转轴即三维空间中的一条直线,需要同时用一个三维点和一个三维方向向量来确定,或者使用两个三维点来确定一条直线。所以需要六个参数来确定一条旋转轴。而opengl没有一个单独的函数来完成绕指定旋转轴的旋转。opengl的旋转轴默认经过原点,只能指定朝向,因此只需要三个参数。想要完成绕任意旋转轴旋转需要复合平移变换。
  • 在三维旋转中,如果要绕平行于坐标轴的一条轴旋转,只能先平移旋转轴和某条坐标轴重合,旋转之后进行逆平移即可。
	//opengl三维旋转(绕平行于坐标轴的轴旋转)
	//此例为原点绕经过(0,0,-5)垂直于xz平面的旋转轴进行旋转
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	//为了方便查看效果,将整体向z轴负向平移10个单位
	glTranslatef(0, 0, -10);
	for (int i = 0; i < 18; i++)
	{
		//进行逆平移
		glTranslatef(0, 0, -5);
		//进行所需的旋转
		glRotatef(20, 0, 1, 0);
		//将坐标轴平移至与y轴重合
		glTranslatef(0, 0, 5);
		glColor3f(1, 0, 0);
		glutWireCube(1);
	}
  • opengl使用
    glRotatef函数构建旋转矩阵。一共有四个参数。第一个参数为旋转角度,后面三个参数确定旋转轴的朝向,此轴默认经过原点。在二维变换中,需要注意的是第一个参数为角度而不是弧度,许多其他图形系统的API都为弧度。
    以上这个例子是处于原点的立方体绕经过(0,0,-5)垂直于xz平面的旋转轴进行循环旋转,此时该轴平行于y轴,所以将其平移至与y轴重合之后调用glRotatef绕y轴旋转,之后再做逆平移
    (为了方便查看效果,将整体向z轴负向平移了10个单位)

在这里插入图片描述



绕任意轴旋转

  • 在三维旋转中最困难的就是绕任意轴旋转,此旋转轴可能与三条坐标轴分别成某个角度。因此需要先将该轴平移通过原点,再进行两次旋转变换,使其与任意一条坐标轴重合,然后再调用旋转方法,最后使用逆变换。
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(-1, -1, -20);
	glColor3f(0, 1, 0);
	glBegin(GL_LINES);
	//绘制出旋转轴
	glVertex3f(-25, -30, -25);
	glVertex3f(20, 15, 20);
	glEnd();
	glColor3f(1, 0, 0);
	for (int i = 0; i < 36; i++)
	{
		//逆变换
		glTranslatef(5, 0, 5);
		glRotatef(-45, 0, 0, 1);
		glRotatef(45, 1, 0, 0);
		glRotatef(10, 0, 1, 0);
		//再绕x轴顺时针旋转45度使旋转轴与y轴重合
		glRotatef(-45, 1, 0, 0);
		//先绕z轴逆时针旋转45度使旋转轴位于yz平面上
		glRotatef(45, 0, 0, 1);
		//先将旋转轴平移至经过原点
		glTranslatef(-5, 0, -5);
		glutWireCube(1);
	}
  • 上面这个例子是原点绕经过(-25, -30, -25),(20, 15, 20)两点的直线进行循环旋转。
    我们目标是将其重合于y轴,当然也可以选择z轴和x轴。
    从下往上看,最下方是首先应用的矩阵,首先经过简单的数学计算可以知道该直线经过(5,0,5)点,所以调用glTranslatef(-5,
    0, -5)使其经过原点。
    接下来先绕z轴逆时针旋转45度使旋转轴位于yz平面上,再绕x轴顺时针旋转45度使旋转轴与y轴重合。之后调用glRotatef(10,
    0, 1, 0);绕y轴旋转,最后进行逆变换即可
    这个角度的计算也很简单,例如求某条轴与xz平面所成的角度,只要求该轴投影至yz平面上与x轴所成的角度即可。投影至yz平面,也只要设置x坐标为0即可,接下来根据正弦和余弦值调用反三角函数就可得出角度。
    此例中为了简易起见,将该旋转轴简单设置成与三个平面都成45度角。 (为了方便查看效果,调用glTranslatef(-1, -1,
    -20);对整体进行了平移)

在这里插入图片描述



  • 4
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值