Qt OpenGL - 网格式的直角坐标系
- 引言
- 一、绘制3D网格
- 1.1 绘制平行于y轴的线段
- 1.2 绘制平行于三个轴的线段
- 1.3 绘制不同的3D网格
- 二、网格式的直角坐标系
- 三、参考链接
引言
在OpenGL进行3D可视化,只绘制三条坐标轴略显单薄,而绘制网格形式的坐标系则能更清晰的展示所画图形位置,如上图所示。
OpenGL可视化须知1:https://blog.csdn.net/sinat_36772813/article/details/129338953 OpenGL中的坐标系
OpenGL三维坐标系例子-只有三个轴2:https://blog.csdn.net/qq_37996632/article/details/103178120 OpenGL画坐标系2
OpenGL三维坐标系例子-网格形式3:https://blog.csdn.net/qq_40004575/article/details/109547793 Qt+OpenGL绘制三维坐标系(动态曲线显示)
一、绘制3D网格
paintGL()
函数:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除屏幕和深度缓存glLoadIdentity();//旋转显示窗口glTranslatef(0, 0, -30);//glRotatef(45, 0, 1, 0);//画3D网格std::vector<float> p1 = {-4.0f, -4.0f, -4.0f}, p2 = {4.0f, 4.0f, 4.0f};GL3DGrid(p1, p2, 3);
1.1 绘制平行于y轴的线段
- 先绘制平行于y轴的线段,效果如上图,算法核心思想:
给定两个3D坐标,要通过其绘制平行于y轴的若干线段,保证每个线段首尾点的x和z坐标是一致的,首尾点的y坐标即两个3D坐标的y坐标。
void QtDraw3DCtrl::GL3DGrid(std::vector<float> p1, std::vector<float> p2, int num)
{if(p1.size() !=3 || p2.size() !=3){return; // 稳健}num = num -1;const float _xLen = (p2[0] - p1[0]) / num;const float _yLen = (p2[1] - p1[1]) / num;const float _zLen = (p2[2] - p1[2]) / num;// 绘制参数glLineWidth(0.1f);glBegin(GL_LINES);glEnable(GL_LINE_SMOOTH);// 绘制平行于某轴的线段 比如y轴 y坐标固定从p1到p2 x,z坐标变换(无脑遍历即可)for (int xi = 0; xi <= num; xi++) {float x = _xLen * xi + p1[0];for (int zi = 0; zi <= num; zi++) {float z = _zLen * zi + p1[2];glVertex3f(x, p1[1], z);glVertex3f(x, p2[1], z);}}glEnd();
}
1.2 绘制平行于三个轴的线段
- 绘制平行于三个轴的线段,如上图所示。增加绘制平行于x轴和z轴的线段,代码与绘制平行于y轴的线段类似,只是改几个参数。
void QopenGLDemo::GL3DGrid(std::vector<float> p1, std::vector<float> p2, int num)
{if(p1.size() !=3 || p2.size() !=3){return; // 稳健}num = num -1;const float _xLen = (p2[0] - p1[0]) / num;const float _yLen = (p2[1] - p1[1]) / num;const float _zLen = (p2[2] - p1[2]) / num;// 绘制参数glLineWidth(0.1f);glBegin(GL_LINES);glEnable(GL_LINE_SMOOTH);// 绘制平行y轴的线段 y坐标固定从p1到p2 x,z坐标变换(无脑遍历即可)for (int xi = 0; xi <= num; xi++) {float x = _xLen * xi + p1[0];for (int zi = 0; zi <= num; zi++) {float z = _zLen * zi + p1[2];glVertex3f(x, p1[1], z);glVertex3f(x, p2[1], z);}}// 绘制平行x轴的线段 x坐标固定从p1到p2 y,z坐标变换(无脑遍历即可)for (int yi = 0; yi <= num; yi++) {float y = _yLen * yi + p1[1];for (int zi = 0; zi <= num; zi++) {float z = _zLen * zi + p1[2];glVertex3f(p1[0], y, z);glVertex3f(p2[1], y, z);}}// 绘制平行z轴的线段 z坐标固定从p1到p2 x,y坐标变换(无脑遍历即可)for (int xi = 0; xi <= num; xi++) {float x = _xLen * xi + p1[0];for (int yi = 0; yi <= num; yi++) {float y = _yLen * yi + p1[1];glVertex3f(x, y, p1[2]);glVertex3f(x, y, p2[2]);}}// 结束绘制glEnd();
}
1.3 绘制不同的3D网格
- 修改
GL3DGrid
(p1, p2,3
)最后一个参数为4,6,10;
二、网格式的直角坐标系
- 由以上代码已可绘制3D网格,但如果在其中绘制目标模型会被遮挡。故,可绘制3个2D网格方便显示,效果如上图所示。(
写到这,发现一个bug,之前代码在绘制平行x轴的线段的时候,p2[1]应改为p2[0]
) 核心源码如下所示:
void QopenGLDemo::paintGL(){// 初始化glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除屏幕和深度缓存glLoadIdentity();//旋转显示窗口glTranslatef(0, 0, -30);//glRotatef(45, 0, 1, 0);//画3D直角坐标系std::vector<float> x1 = {-4.0f, -4.0f, -4.0f}, x2 = {-4.0f, 4.0f, 4.0f};GL3DGrid(x1, x2, 10);std::vector<float> y1 = {-4.0f, -4.0f, -4.0f}, y2 = {4.0f, -4.0f, 4.0f};GL3DGrid(y1, y2, 10);std::vector<float> z1 = {-4.0f, -4.0f, -4.0f}, z2 = {4.0f, 4.0f, -4.0f};GL3DGrid(z1, z2, 10);
}void QopenGLDemo::GL3DGrid(std::vector<float> p1, std::vector<float> p2, int num)
{if(p1.size() !=3 || p2.size() !=3){return; // 稳健}num = num -1;const float _xLen = (p2[0] - p1[0]) / num;const float _yLen = (p2[1] - p1[1]) / num;const float _zLen = (p2[2] - p1[2]) / num;// 绘制参数glLineWidth(0.1f);glBegin(GL_LINES);glEnable(GL_LINE_SMOOTH);// 绘制平行y轴的线段 y坐标固定从p1到p2 x,z坐标变换(无脑遍历即可)for (int xi = 0; xi <= num; xi++) {float x = _xLen * xi + p1[0];for (int zi = 0; zi <= num; zi++) {float z = _zLen * zi + p1[2];glVertex3f(x, p1[1], z);glVertex3f(x, p2[1], z);}}// 绘制平行x轴的线段 x坐标固定从p1到p2 y,z坐标变换(无脑遍历即可)for (int yi = 0; yi <= num; yi++) {float y = _yLen * yi + p1[1];for (int zi = 0; zi <= num; zi++) {float z = _zLen * zi + p1[2];glVertex3f(p1[0], y, z);glVertex3f(p2[0], y, z);}}// 绘制平行z轴的线段 z坐标固定从p1到p2 x,y坐标变换(无脑遍历即可)for (int xi = 0; xi <= num; xi++) {float x = _xLen * xi + p1[0];for (int yi = 0; yi <= num; yi++) {float y = _yLen * yi + p1[1];glVertex3f(x, y, p1[2]);glVertex3f(x, y, p2[2]);}}// 结束绘制glEnd();
}
三、参考链接
https://blog.csdn.net/sinat_36772813/article/details/129338953 OpenGL中的坐标系 ↩︎
https://blog.csdn.net/qq_37996632/article/details/103178120 OpenGL画坐标系2 ↩︎
https://blog.csdn.net/qq_40004575/article/details/109547793 Qt+OpenGL绘制三维坐标系(动态曲线显示) ↩︎