c++通过离散点利用插值法生成不规则三角格网并绘制出来
时间: 2024-06-08 08:08:59 浏览: 96
C++写的 离散点画Tin三角网程序,有源文件,有安装文件
4星 · 用户满意度95%
生成不规则三角格网可以使用Delaunay三角剖分算法,插值法可以使用双线性插值或者三次样条插值。以下是一个基于OpenGL库的示例程序,可以通过输入一组离散点,利用Delaunay三角剖分算法生成不规则三角格网,并通过三次样条插值法对每个三角形内部进行插值,最终绘制出来。
```cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <GL/glut.h>
#include <glm/glm.hpp>
#include <glm/gtx/spline.hpp>
#include "triangle/triangle.h"
using namespace std;
using namespace glm;
// 离散点
vector<vec2> points;
// 三角形顶点索引
vector<int> triangles;
// 插值后的网格顶点数据
vector<vec3> meshVertices;
// 绘制三角形网格
void drawTriangles()
{
glBegin(GL_TRIANGLES);
for (int i = 0; i < triangles.size() / 3; i++)
{
int v1 = triangles[3 * i];
int v2 = triangles[3 * i + 1];
int v3 = triangles[3 * i + 2];
glVertex3f(meshVertices[v1].x, meshVertices[v1].y, meshVertices[v1].z);
glVertex3f(meshVertices[v2].x, meshVertices[v2].y, meshVertices[v2].z);
glVertex3f(meshVertices[v3].x, meshVertices[v3].y, meshVertices[v3].z);
}
glEnd();
}
// 绘制离散点
void drawPoints()
{
glBegin(GL_POINTS);
for (int i = 0; i < points.size(); i++)
{
glVertex3f(points[i].x, points[i].y, 0.0f);
}
glEnd();
}
// 绘制函数图形
void drawFunction()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
// 平移坐标系,使图形在屏幕中心
glTranslatef(-0.5f, -0.5f, -3.0f);
// 绘制三角形网格
glColor3f(0.0f, 1.0f, 0.0f);
drawTriangles();
// 绘制离散点
glColor3f(1.0f, 0.0f, 0.0f);
drawPoints();
glPopMatrix();
glutSwapBuffers();
}
// 初始化OpenGL
void initOpenGL(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("Irregular Grid");
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 1.0, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glutDisplayFunc(drawFunction);
}
int main(int argc, char* argv[])
{
// 添加离散点
points.push_back(vec2(0.1f, 0.1f));
points.push_back(vec2(0.3f, 0.7f));
points.push_back(vec2(0.7f, 0.4f));
points.push_back(vec2(0.9f, 0.2f));
points.push_back(vec2(0.5f, 0.1f));
points.push_back(vec2(0.5f, 0.5f));
points.push_back(vec2(0.3f, 0.3f));
points.push_back(vec2(0.7f, 0.7f));
// 使用Triangle库生成三角形网格
triangulateio in, out;
in.numberofpoints = points.size();
in.pointlist = (REAL*)malloc(points.size() * 2 * sizeof(REAL));
for (int i = 0; i < points.size(); i++)
{
in.pointlist[2 * i] = points[i].x;
in.pointlist[2 * i + 1] = points[i].y;
}
out.numberofpoints = in.numberofpoints;
out.pointlist = in.pointlist;
out.numberofpointattributes = 0;
out.trianglelist = NULL;
out.numberofcorners = 3;
out.numberoftriangles = 0;
out.numberoftriangleattributes = 0;
triangulate("pz", &in, &out, NULL);
triangles.resize(out.numberoftriangles * 3);
for (int i = 0; i < out.numberoftriangles; i++)
{
triangles[3 * i] = out.trianglelist[3 * i];
triangles[3 * i + 1] = out.trianglelist[3 * i + 1];
triangles[3 * i + 2] = out.trianglelist[3 * i + 2];
}
// 计算插值后的网格顶点数据
meshVertices.resize(points.size());
for (int i = 0; i < triangles.size() / 3; i++)
{
int v1 = triangles[3 * i];
int v2 = triangles[3 * i + 1];
int v3 = triangles[3 * i + 2];
for (int j = 0; j < 3; j++)
{
vec2 p = vec2(out.pointlist[2 * triangles[3 * i + j]], out.pointlist[2 * triangles[3 * i + j] + 1]);
float z = sin(p.x * 10.0f) * cos(p.y * 10.0f); // 这里使用一个简单的函数进行插值
meshVertices[triangles[3 * i + j]] = vec3(p, z);
}
}
// 初始化OpenGL
initOpenGL(argc, argv);
// 进入消息循环
glutMainLoop();
return 0;
}
```
需要注意的是,这里使用的是Triangle库进行Delaunay三角剖分,需要在编译时将Triangle库链接进来。可以从Triangle库的官网(https://www.cs.cmu.edu/~quake/triangle.html)下载源代码并编译生成libtriangle.a或libtriangle.so库文件。在Linux环境下,可以使用以下命令编译生成可执行文件:
```
g++ main.cpp -o main -lGL -lGLU -lglut -lm -L/path/to/lib -ltriangle
```
阅读全文