void Delaunay::computeDelaunay(Mesh &mesh) { int size = (int)mesh.getVerticesSize(); if (size == 0) { return; } mesh.computeVerticesNormals(); m_preSize = mesh.m_curIndex; TriangleSet triSet; // 依次遍历每个点,寻找最近邻,进行三角化 for (; mesh.m_curIndex < size; mesh.m_curIndex++) { Vertex v = mesh.getVertex(mesh.m_curIndex); if (v.m_isInner) { mesh.pushTriBeginIndex((int)triSet.size()); continue; } Vec3d normal = v.m_normal; int id = 2; // 判断法向量哪个不为0,z->y->x if (normal[2] != 0) // z { id = 2; } else if (normal[1] != 0)// y { id = 1; } else if (normal[0] != 0)// x { id = 0; } else // 法向量为(0, 0, 0), { mesh.pushTriBeginIndex((int)triSet.size()); continue; } double minDistance = -1; int cnt = v.m_neighbors[0]; // 最近邻数目 double dists[k]; for (int j = 1; j < cnt + 1; j++) { Vec3d dv = mesh.getVertex(v.m_neighbors[j]).m_xyz - v.m_xyz; dists[j] = dv.ddot(dv); } minDistance = dists[1]; VertexVector vVector, tmpvVector; // 将最近邻点投射到该点的切平面上 for (int j = 1; j < cnt + 1; j++) { Vertex tmpv = mesh.getVertex(v.m_neighbors[j]); if (dists[j] < u * minDistance || // 去除非常接近的点 (tmpv.m_index < v.m_index && tmpv.m_index >= m_preSize) || // 去除已遍历过的点 tmpv.m_isInner) // 去除内点 { continue; } Vec3d vv = tmpv.m_xyz - v.m_xyz; double dist2 = dists[j] * 0.75f; // sqrt double alpha = vv.dot(normal); alpha = alpha * alpha; if (alpha > dist2) // 去除与法向量夹角小于30度或大于150度的点 { continue; } Vec3d proj = tmpv.m_xyz - alpha * normal; // 投射到切平面 tmpvVector.push_back(Vertex(proj, v.m_neighbors[j])); } if (tmpvVector.size() < 3) // 少于3个不能构成三角形 { mesh.pushTriBeginIndex((int)triSet.size()); continue; } // 将切平面转换为x-y平面进行三角形计算 vVector.push_back(Vertex(Vec3d(0, 0, 0), mesh.m_curIndex)); // 原点 Vec3d vx = tmpvVector[0].m_xyz - v.m_xyz; // x轴 vx = normalize(vx); for (int j = 0; j < tmpvVector.size(); j++) { Vec3d vv = tmpvVector[j].m_xyz - v.m_xyz; double x = vv.dot(vx); double y = vx.cross(vv)[id] / normal[id]; Vec3d proj(x, y, 0); vVector.push_back(Vertex(proj, tmpvVector[j].m_index)); } TriangleVector tVector; computeDelaunay(vVector, tVector); // cout << vVector.size() << " " << tVector.size() << endl; // drawTrianglesOnPlane(tVector); for (int j = 0; j < tVector.size(); j++) { Triangle t = tVector[j]; t.m_vertices[0] = mesh.getVertex(t.m_vertices[0].m_index); t.m_vertices[1] = mesh.getVertex(t.m_vertices[1].m_index); t.m_vertices[2] = mesh.getVertex(t.m_vertices[2].m_index); triSet.insert(t); } mesh.pushTriBeginIndex((int)triSet.size()); } for (TriangleSet::iterator iter = triSet.begin(); iter != triSet.end(); iter++) { mesh.m_triangles.push_back(*iter); } }