void Delaunay::TrianglesToEdges(const TriangleSet& triangles, EdgeSet& edges) { for (cTriangleIterator iter = triangles.begin(); iter != triangles.end(); ++iter) { HandleEdge(iter->GetVertex(0), iter->GetVertex(1), edges); HandleEdge(iter->GetVertex(1), iter->GetVertex(2), edges); HandleEdge(iter->GetVertex(2), iter->GetVertex(0), edges); } }
Triangulation::~Triangulation() { TriangleSet outTriangles; triangles(&outTriangles); for(auto it = outTriangles.begin(); it != outTriangles.end(); it++) delete *it; mTlist->clear(); EdgeSet outEdges; edges(&outEdges); for(auto it = outEdges.begin(); it != outEdges.end(); it++) delete *it; VertexSet outVertices; vertices(&outVertices); for(auto it = outEdges.begin(); it != outEdges.end(); it++) delete *it; mV2VMap->clear(); }
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); } }
void Delaunay::Triangulate(const VertexSet& vertices, TriangleSet& output) { if (vertices.size() < 3) { return; } cVertexIterator iterVertex = vertices.begin(); double xMin = iterVertex->GetX(); double yMin = iterVertex->GetY(); double xMax = xMin; double yMax = yMin; ++iterVertex; for (; iterVertex != vertices.end(); ++iterVertex) { xMax = iterVertex->GetX(); double y = iterVertex->GetY(); if (y < yMin) { yMin = y; } if (y > yMax) { yMax = y; } } double dx = xMax - xMin; double dy = yMax - yMin; double ddx = dx * 0.01; double ddy = dy * 0.01; xMin -= ddx; xMax += ddx; dx += 2 * ddx; yMin -= ddy; yMax += ddy; dy += 2 * ddy; Vertex vSuper[3]; vSuper[0] = Vertex(xMin - dy * sqrt3 / 3.0, yMin); vSuper[1] = Vertex(xMax + dy * sqrt3 / 3.0, yMin); vSuper[2] = Vertex((xMin + xMax) * 0.5, yMax + dx * sqrt3 * 0.5); TriangleSet workset; workset.insert(Triangle(vSuper)); for (iterVertex = vertices.begin(); iterVertex != vertices.end(); ++iterVertex) { TriangleIsCompleted pred1(iterVertex, output, vSuper); TriangleSet::iterator iter = workset.begin(); while (iter != workset.end()) { if (pred1(*iter)) { iter = workset.erase(iter); } else { ++iter; } } EdgeSet edges; VertexIsInCircumstanceCircle pred2(iterVertex, edges); iter = workset.begin(); while (iter != workset.end()) { if (pred2(*iter)) { iter = workset.erase(iter); } else { ++iter; } } for (EdgeIterator edgeIter = edges.begin(); edgeIter != edges.end(); ++edgeIter) { workset.insert(Triangle(edgeIter->m_pv0, edgeIter->m_pv1, &(*iterVertex))); } } TriangleIterator where = output.begin(); TriangleHasVertex pred(vSuper); for (auto t : workset) { if (!pred(t)) { output.insert(output.begin(), t); } } }