一.3D空间中的点

#include <gl/glut.h>
#include <math.h>#define GL_PI 3.1415fstatic GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;void RenderScene(void)
{GLfloat x, y, z, angle; // 存储坐标和角度// 用当前颜色清除窗口glClear(GL_COLOR_BUFFER_BIT);// 保存矩阵状态并进行旋转glPushMatrix();glRotatef(xRot, 1.0f, 0.0f, 0.0f);glRotatef(yRot, 0.0f, 1.0f, 0.0f);// 对所有剩余的点只调用一次glBegin(GL_POINTS);z = -50.0f;for(angle = 0.0f; angle <= (2.0*GL_PI)*3.0f; angle += 0.1f){x = 50.0f*sin(angle);y = 50.0f*cos(angle);// 指定点并稍稍变化Z值glVertex3f(x, y, z);z += 0.5f;}glEnd();// 恢复变换glPopMatrix();// 刷新绘图命令glutSwapBuffers();
}// 在渲染环境下进行初始化工作
void SetupRC()
{// 黑色背景glClearColor(0.0f, 0.0f, 0.0f, 1.0f);// 绘图颜色为绿色glColor3f(0.0f, 1.0f, 0.0f);
}// 键盘箭头键控制旋转图形
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();
}// 修改可视区域的视口,当窗口改变时被调用
void ChangeSize(int w, int h)
{GLfloat nRange = 100.0f;// 防止被0除if(h == 0)h = 1;// 将视口设置为窗口尺寸glViewport(0, 0, w, h);// 重置投影矩阵堆栈glMatrixMode(GL_PROJECTION);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();
}void main()
{glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutCreateWindow("Points Example");glutReshapeFunc(ChangeSize);glutSpecialFunc(SpecialKeys);glutDisplayFunc(RenderScene);SetupRC();glutMainLoop();
}

运行结果:
初始为一个由点组成的圆,这是因为从Z轴直接正面观察这张图。

通过键盘键上下左右键旋转这张图形:

设置3D画布

// 修改可视区域的视口,当窗口改变时被调用
void ChangeSize(int w, int h)
{GLfloat nRange = 100.0f;// 防止被0除if(h == 0)h = 1;// 将视口设置为窗口尺寸glViewport(0, 0, w, h);// 重置投影矩阵堆栈glMatrixMode(GL_PROJECTION);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();
}

如图为一个简单的可视区域,这个可视区域包围的区域就是一个笛卡尔坐标空间。在所有的3个轴(X,Y和Z)中,它们的范围都是从-100至+100,这个区域就是三维画布,可以用OpenGL命令和函数在上面进行绘图。

3D空间中的点:顶点

glVertex3f(50.0f,50.0f,0.0f)

这行代码就描绘了一个X轴上为50个单位,Y轴上为50个单位,Z轴上为0个单位的三维空间中的点。
接受2个参数的glVertex2f函数,则只指定X与Y的值,而默认Z坐标为0.0。
接受4个参数的glVertex4f函数,使用第四个坐标值W用来表示缩放度(一般默认为1.0)。

图元

图元是一组顶点的集合,她们构成了在屏幕上所绘制的形状,如图所示,OpenGL共有10种图元,从空间中的一个点到任意数量边的闭合多边形。

绘制图元的方式是使用glBegin命令告诉OpenGL开始对一组顶点进行解释,把它作为一个特定的图元,然后调用glEnd命令结束组成这个图元的列表。

// 绘制点
glBegin(GL_POINTS);    // 选择点作为图元glVertex3f(0.0f,0.0f,0.0f);  // 指定点glVertex3f(0.0f,0.0f,0.0f)  ;
glEnd( );       // 完成绘点

设置点的大小

当我们绘制一个点时,在默认情况下点的大小是一个像素,我们可以通过glPointSize函数修改点的大小。该函数接受一个参数,它用于指定被绘点的近似直径(以像素计),但是点的大小是存在限制的。可以通过以下代码实现:

GLfloat sizes[2];  // 存储受支持的点的大小范围
GLfloat step;  // 存储受支持的点的大小增量// 获得受支持的点的大小范围以及增量大小
glGetFloatv(GL_POINT_SIZE_RANGE,sizes);
glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);

其中sizes数组将包含两个元素,分别表示glPointSize的最小和最大有效值,step表示点大小范围之内最小允许的步进值。

二. 3D空间中的线

#include <gl/glut.h>
#include <math.h>// 为PI的值定义一个常量
#define GL_PI 3.1415fstatic GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;// Called to draw scene
void RenderScene(void){GLfloat x,y,z,angle; // Storeage for coordinates and angles// Clear the window with current clearing colorglClear(GL_COLOR_BUFFER_BIT);// Save matrix state and do the rotationglPushMatrix();glRotatef(xRot, 1.0f, 0.0f, 0.0f);glRotatef(yRot, 0.0f, 1.0f, 0.0f);// Call only once for all remaining pointsglBegin(GL_LINES);z = 0.0f;for(angle = 0.0f; angle <= GL_PI; angle += (GL_PI / 20.0f)){// Top half of the circlex = 50.0f*sin(angle);y = 50.0f*cos(angle);glVertex3f(x, y, z);// Bottom half of the circlex = 50.0f*sin(angle+GL_PI);y = 50.0f*cos(angle+GL_PI);glVertex3f(x, y, z);    }// Done drawing pointsglEnd();// Restore transformationsglPopMatrix();// Flush drawing commandsglutSwapBuffers();}// This function does any needed initialization on the
// rendering context.
void SetupRC(){// Black backgroundglClearColor(0.0f, 0.0f, 0.0f, 1.0f );// Set drawing color to greenglColor3f(0.0f, 1.0f, 0.0f);}///////////////////////////////////////////////////////////
// Respond to arrow keys
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;// Refresh the WindowglutPostRedisplay();}///////////////////////////////////////////////////////////
// Window has changed size, recalculate projection
void ChangeSize(int w, int h){GLfloat nRange = 100.0f;// Prevent a divide by zeroif(h == 0)h = 1;// Set Viewport to window dimensionsglViewport(0, 0, w, h);// Reset coordinate systemglMatrixMode(GL_PROJECTION);glLoadIdentity();// Establish clipping volume (left, right, bottom, top, near, far)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();}///////////////////////////////////////////////////////////
// Main Program Entry Point
void main()
{glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize(800,600);glutCreateWindow("Lines Example");glutReshapeFunc(ChangeSize);glutSpecialFunc(SpecialKeys);glutDisplayFunc(RenderScene);SetupRC();glutMainLoop();
}

运行结果:

绘制直线

选择绘制直线的图元GL_LINES,指定两个顶点,在它们之间绘制一条直线。

glBegin(GL_LINES);    // 选择线作为图元glVertex3f(0.0f,0.0f,0.0f);  // 指定点glVertex3f(50.0f,50.0f,50.0f)   ;
glEnd( );       // 完成绘线

注意,这里用两个顶点指定了一个图元,每两个指定的顶点用于绘制一条直线。如果指定奇数个顶点,那么最后一个顶点会被忽略。

线带与线环

GL_LINE_STRIP:线带,它允许指定一个顶点列表,并绘制一条经过所有这些顶点的连续的线。
GL_LINE_LOOP:线环,它与线带非常类似,会在顶点列表的最后一个顶点和第一个顶点之间也绘制一条直线。因此会形成一个闭合的图形。

【学习OpenGL】(三)——3D空间中的点与线相关推荐

  1. 3D空间中的点坐标转化为屏幕二维点坐标(一)

    每个人在进入计算机图形学的世界中,都有一个同样的困惑,三维世界中的三维坐标是如何被转换成屏幕上的二维坐标的,我如何在屏幕上找到一个点(二维点)对应三维世界中的点(三维点)呢? 要理解其中的过程,对学习 ...

  2. 使3D空间中物体朝向和其速度方向一致的旋转矩阵计算方案

    在3D空间中的物体以某一速度运动,有时候需要这个物体的朝向和速度的方向一致, 为了实现这个目标我们一般借助旋转矩阵 M 来将物体旋转到对应的朝向. 例如速度方向矢量 spdV: Vector3D(1, ...

  3. 使用脑电图慢皮层电位重建3D空间中的手,肘和肩的实际和想象的轨迹

    导读 从神经活动中解码想象运动的运动学的能力对于开发可以帮助行动不便的人的假肢设备至关重要.当前采用脑电图(EEG)等无创记录方法解码实际和想象的手运动轨迹来控制神经运动假体,通常通过应用多维线性回归 ...

  4. 在3D空间中绘制四边形

    在3D空间中绘制四边形 四边形 GL_QUADS OpenGL的GL_QUADS图元用于绘制四边形,它根据每四个顶点绘制一个四边形. 注意,在使用四边形时,必需记住一个重要规则:一个四边形的四个角必须 ...

  5. 一般向量空间的基变换_向量几何--3-D空间中的基变换与坐标变换【转】 - 回到未来 - C++博客...

    <6>3-D空间中的基变换与坐标变换-Twinsen编写 -本人水平有限,疏忽错误在所难免,还请各位数学高手.编程高手不吝赐教 -我的Email-address:popyy@netease ...

  6. 2D平面上的变换和3D空间中的变换以及求无穷远点

    求两个平行线的无穷远点,最简单的方法(二维空间和三维空间都适用) 两个平行线的交点就是无穷远点.求解的方法就是把直线的方向向量(向量我们都用列向量表示)拿到,然后给最后一维加个0就是它们的交点(无穷远 ...

  7. 3D 空间中拟合曲线

    算法来源:C++/PCL:最小二乘拟合平面直线,平面多项式曲线,空间多项式曲线 以下是我改写的算法,未经验证正确性!!! // 3D 空间中拟合曲线 void fittingPolynomial3D( ...

  8. 用纯C语言实现3D空间中的点坐标转化为屏幕二维点坐标,包含主视图、侧视图、俯视图、正等轴投影

    要实现3D空间中的点坐标转换为屏幕二维点坐标,需要进行透视变换和投影变换.以下是一些基本的思路和示例代码,可以用于实现主视图.侧视图.俯视图.正等轴投影. 1. 主视图投影 主视图投影是指以一个点作为 ...

  9. 3d空间中球体的动量守恒

    其实,虽然说的是3d空间中的,但事实上一旦掌握原理,他可以用在任意维度的空间中: 为了简化代码,最好能够满足如下要求: 所有的空间属性都用矢量来表示:比如位置,速度,加速度(虽然这里涉及不到加速度): ...

最新文章

  1. iis thinkphp隐藏index.php,thinkphp 隐藏index.php iis apache nginx
  2. serial port 的操作
  3. 【转载】用Snort巧妙检测SQL注入和跨站脚本攻击
  4. 检查用户名是否存在的servlet代码怎么写_Servlet详解!!!
  5. 【转】基于Token的身份验证原理
  6. leetcode5 Longest Palindromic Substring 最长且为回数的子字符串
  7. cvAddWeighted 进行图片融合
  8. 汽车无人驾驶相应专业词汇
  9. powerdns 安装部署备忘
  10. 频繁默认网关不可用_电脑经常掉线提示默认网关不可用原因分析和解决办法
  11. Crazy bubbles
  12. 判断一个整数是否为素数。本题要求编写程序,判断一个给定的整数是否为素数。素数就是只能被1和自身整除的正整数,1不是素数,2是素数。
  13. 英特尔大师挑战赛燃爆斗鱼直播节,华硕ROG热血助阵
  14. 虚拟机 报错:Unmount and run xfs_repair
  15. 一整只烧鹅价格=烧鹅上庄价格+烧鹅下庄价格这个关系不因货币变掉而变
  16. 怎样在计算机上进行高级搜索,怎么用中国知网的高级检索才能准确找到自己想要的文献?...
  17. 【FCC】Build a Tribute Page(html+css+bootstrap)
  18. iOS10会带来哪些新变化?
  19. 华为java面试题目
  20. 基于 React video 视频打点

热门文章

  1. 2018青岛(重温经典)
  2. 计算机抖音怎么可以弄出音乐,抖音视频配音乐怎么弄 如何在手机上给视频添加背景音乐?...
  3. 如何用深度学习玩转图像处理
  4. Elasticsearch(四) - IK中文分词器
  5. 保养手机的常见小技巧
  6. 自动化测试的未来趋势
  7. 2023二建学天一本通电子版分享
  8. Avid.Sibelius.v7.1.3-DYNAMiCS
  9. 你能解释一下延迟加载吗?
  10. tomcat各版本的区别