//----------------------------------------------------------------------- // Triangulation by insertion void Triangulator::delaunay(PointList& pointList, DelaunayTriangleBuffer& tbuffer) { // Compute super triangle float maxTriangleSize = 0.f; for (PointList::iterator it = pointList.begin(); it!=pointList.end();it++) { maxTriangleSize = std::max<float>(maxTriangleSize,fabs(it->x)); maxTriangleSize = std::max<float>(maxTriangleSize,fabs(it->y)); } int maxTriangleIndex=pointList.size(); pointList.push_back(Ogre::Vector2(-3*maxTriangleSize,-3*maxTriangleSize)); pointList.push_back(Ogre::Vector2(3*maxTriangleSize,-3*maxTriangleSize)); pointList.push_back(Ogre::Vector2(0.,3*maxTriangleSize)); Triangle superTriangle(&pointList, tbuffer.end()); superTriangle.i[0]= maxTriangleIndex; superTriangle.i[1]= maxTriangleIndex+1; superTriangle.i[2]= maxTriangleIndex+2; tbuffer.push_back(superTriangle); // Point insertion loop for (int i=0;i<pointList.size()-3;i++) { // Insert 1 point, find triangle containing it Vector2& p = pointList[i]; DelaunayTriangleBuffer::iterator triangle; for (DelaunayTriangleBuffer::iterator it = tbuffer.begin();it!=tbuffer.end();it++) { if (it->isPointInside(p)) triangle = it; } // Build 3 triangles and suppress old triangle //Triangle* subTri[3]; DelaunayTriangleBuffer::iterator subTri[3]; tbuffer.push_back(Triangle(&pointList, tbuffer.end())); subTri[0] = --tbuffer.end(); tbuffer.push_back(Triangle(&pointList, tbuffer.end())); subTri[1] = --tbuffer.end(); tbuffer.push_back(Triangle(&pointList, tbuffer.end())); subTri[2] = --tbuffer.end(); subTri[0]->setVertices(triangle->i[0],triangle->i[1],i); subTri[1]->setVertices(triangle->i[1],triangle->i[2],i); subTri[2]->setVertices(triangle->i[2],triangle->i[0],i); subTri[0]->setAdj(subTri[1],subTri[2],triangle->adj[2], subTri[0]); subTri[1]->setAdj(subTri[2],subTri[0],triangle->adj[0], subTri[1]); subTri[2]->setAdj(subTri[0],subTri[1],triangle->adj[1], subTri[2]); triangle = tbuffer.erase(triangle); for (int k=0;k<3;k++) { DelaunayTriangleBuffer::iterator tri0 = subTri[k]; //Check if new triangle is Delaunay Circle c(tri0->p(0), tri0->p(1), tri0->p(2)); bool isDelaunay = true; for (int j = 0;j<i+1;j++) { if (j!=tri0->i[0] && j!=tri0->i[1] && j!=tri0->i[2]) if (c.isPointInside(pointList[j])) { isDelaunay = false; break; } } // Flip edges where needed if (!isDelaunay && tri0->adj[2]!=tbuffer.end()) { DelaunayTriangleBuffer::iterator tri1 = tri0->adj[2]; tbuffer.push_back(Triangle(&pointList, tbuffer.end())); DelaunayTriangleBuffer::iterator newt0 = --tbuffer.end(); tbuffer.push_back(Triangle(&pointList, tbuffer.end())); DelaunayTriangleBuffer::iterator newt1 = --tbuffer.end(); int x = tri1->findSegNumber(tri0->i[0],tri0->i[1]);//opposite of common side for t1 newt0->setVertices(tri0->i[2],tri1->i[x],tri0->i[1]); newt1->setVertices(tri0->i[2],tri0->i[0],tri1->i[x]); newt0->setAdj(tri1->adj[(x+2)%3], tri0->adj[0], newt1, newt0); newt1->setAdj(tri1->adj[(x+1)%3], newt0,tri0->adj[1],newt1); tbuffer.erase(tri0); tbuffer.erase(tri1); } } } //Remove super triangle TouchSuperTriangle touchSuperTriangle(maxTriangleIndex, maxTriangleIndex+1,maxTriangleIndex+2); tbuffer.remove_if(touchSuperTriangle); pointList.pop_back(); pointList.pop_back(); pointList.pop_back(); }