void Delaunay::addBounding( const VertexVector &verSet, TriangleVector &triSet ) { double max_x = -100000, max_y = -100000; double min_x = 100000, min_y = 100000; for (int i = 0; i < verSet.size(); i++) { Vec3d v = verSet[i].m_xyz; max_x = max_x < v[0] ? v[0] : max_x; min_x = min_x > v[0] ? v[0] : min_x; max_y = max_y < v[1] ? v[1] : max_y; min_y = min_y > v[1] ? v[1] : min_y; } // 将矩形区域的外接三角形作为边界 double dx = max_x - min_x; double dy = max_y - min_y; double mid_x = (min_x + max_x) / 2; double mid_y = (min_y + max_y) / 2; // 为了去除边界方便讲边界点的索引置为负数 Vertex v0(Vec3d(mid_x, max_y + dy, 0.0f), -1); Vertex v1(Vec3d(mid_x - dx, min_y, 0.0f), -2); Vertex v2(Vec3d(mid_x + dx, min_y, 0.0f), -3); triSet.push_back(Triangle(v0, v1, v2)); }
void Delaunay::removeBounding( TriangleVector inSet, TriangleVector &outSet, const int &index ) { for (TriangleVector::iterator iter = inSet.begin(); iter != inSet.end(); iter++) { if (iter->m_vertices[0].m_index >= 0 && iter->m_vertices[1].m_index >= 0 && iter->m_vertices[2].m_index >= 0 && iter->isVertex(index) && iter->angleCriterion(m_minAngle, m_maxAngle)) { outSet.push_back(*iter); } } }
bool Delaunay::flipTest( TriangleVector &triSet, Triangle t ) { bool flipped = false; Vertex a = t.m_vertices[0]; Vertex b = t.m_vertices[1]; Vertex c = t.m_vertices[2]; TriangleVector tSet; for (TriangleVector::iterator iter = triSet.begin(); iter != triSet.end();) { Vertex d; d.m_index = -100; // 寻找拥有相同边ab的三角形 int satisfy[3] = {0, 0, 0}; for (int j = 0, k = 1; j < Triangle::Vertex_Size; j++, k *= 2) { if (iter->m_vertices[j].m_index == a.m_index || iter->m_vertices[j].m_index == b.m_index) { satisfy[j] = k; } } switch (satisfy[0] | satisfy[1] | satisfy[2]) { case 3: // v2 if (Vertex::cross(a, c, iter->m_vertices[2]) != 0 && Vertex::cross(b, c, iter->m_vertices[2]) != 0) { d = iter->m_vertices[2]; } break; case 5: // v1 if (Vertex::cross(a, c, iter->m_vertices[1]) != 0 && Vertex::cross(b, c, iter->m_vertices[1]) != 0) { d = iter->m_vertices[1]; } break; case 6: // v0 if (Vertex::cross(a, c, iter->m_vertices[0]) != 0 && Vertex::cross(b, c, iter->m_vertices[0]) != 0) { d = iter->m_vertices[0]; } break; default: break; } if (d.m_index != -100) { if (inCircle(a, b, c, d)) // 判断d是否在三角形abc的外接圆内 { flipped = true; Triangle t0(a, d, c); Triangle t1(d, b, c); tSet.push_back(t0); tSet.push_back(t1); iter = triSet.erase(iter); break; } else { iter++; } } else { iter++; } } for (int i = 0; i < tSet.size(); i++) { if (!flipTest(triSet, tSet[i])) { triSet.push_back(tSet[i]); } } return flipped; }
void Delaunay::insertVertex( TriangleVector &triSet, const Vertex &v ) { TriangleVector tmp; for (TriangleVector::iterator iter = triSet.begin(); iter != triSet.end();) { int r = iter->inTriangle(v); // 判断点是否在三角形内 // cout << iter->m_vertices[0].m_xyz // << iter->m_vertices[1].m_xyz // << iter->m_vertices[2].m_xyz << endl; switch (r) { case 0: // in { Triangle t0(iter->m_vertices[0], iter->m_vertices[1], v); Triangle t1(iter->m_vertices[1], iter->m_vertices[2], v); Triangle t2(iter->m_vertices[2], iter->m_vertices[0], v); tmp.push_back(t0); tmp.push_back(t1); tmp.push_back(t2); iter = triSet.erase(iter); } break; case -1: // on v0v1 { Triangle t0(iter->m_vertices[1], iter->m_vertices[2], v); Triangle t1(iter->m_vertices[2], iter->m_vertices[0], v); tmp.push_back(t0); tmp.push_back(t1); iter = triSet.erase(iter); } break; case -2: // on v1v2 { Triangle t0(iter->m_vertices[0], iter->m_vertices[1], v); Triangle t1(iter->m_vertices[2], iter->m_vertices[0], v); tmp.push_back(t0); tmp.push_back(t1); iter = triSet.erase(iter); } break; case -3: // on v2v0 { Triangle t0(iter->m_vertices[0], iter->m_vertices[1], v); Triangle t1(iter->m_vertices[1], iter->m_vertices[2], v); tmp.push_back(t0); tmp.push_back(t1); iter = triSet.erase(iter); } break; default: iter++; break; } if (r <= 0) { break; } } for (int i = 0; i < tmp.size(); i++) { if (!flipTest(triSet, tmp[i])) // 优化delaunay三角 { triSet.push_back(tmp[i]); } /* drawTrianglesOnPlane(triSet);*/ } }