bool CTriangulation::Triangulate(vector<CEdgeLoop> &tri_faces, CRegion& region) { vector<CEdge> regionEdges; for(EdgeArray::iterator ol_it = region.OuterLoops.Edges.begin();ol_it != region.OuterLoops.Edges.end();ol_it++) { regionEdges.push_back(*ol_it); } for(vector<CEdgeLoop>::iterator il_it1 = region.InnerLoops.begin();il_it1 != region.InnerLoops.end();il_it1++) { CEdgeLoop currentInnerLoop = *il_it1; for(EdgeArray::iterator il_it2 = currentInnerLoop.Edges.begin();il_it2 != currentInnerLoop.Edges.end();il_it2++) { regionEdges.push_back(*il_it2); } } while(regionEdges.size() > 3) { vector<vec2> candidatePoints; for(int i = 1;i<regionEdges.size();i++) { if (CMathUtility::ToLeftExcludeOnLine(regionEdges[i].End,regionEdges[0])) { int k = 0; for(k = 1;k<regionEdges.size();k++) { CEdge edge1(regionEdges[0].Start,regionEdges[i].End); edge1.Commit(); CEdge edge2(regionEdges[0].End,regionEdges[i].End); edge2.Commit(); //??????? if(edge1.IsIntersectWith2(regionEdges[k]) || edge2.IsIntersectWith2(regionEdges[k])) { break; } } if(k == regionEdges.size()) { candidatePoints.push_back(regionEdges[i].End); } } } double minR = MAXDWORD; vec2 LO2; for(int j = 0;j<candidatePoints.size();j++) { double r =CMathUtility::MinR(regionEdges[0].Start,regionEdges[0].End,candidatePoints[j]); if(r < minR) { minR = r; LO2 = candidatePoints[j]; } } CEdgeLoop tmpTriangel; tmpTriangel.Edges.push_back(regionEdges[0]); CEdge tmpEdge1(regionEdges[0].End,LO2); tmpEdge1.Commit(); tmpTriangel.Edges.push_back(tmpEdge1); CEdge tmpEdge2(LO2,regionEdges[0].Start); tmpEdge2.Commit(); tmpTriangel.Edges.push_back(tmpEdge2); tmpTriangel.Commit(); vector<vec2> newCandidatePoints; for(int m = 0;m<candidatePoints.size();m++) { if(CMathUtility::IsCanExistInCircle(candidatePoints[m],tmpTriangel)) { newCandidatePoints.push_back(candidatePoints[m]); } } while (!newCandidatePoints.size() ==0) { minR=MAXDWORD; for(int m = 0;m < newCandidatePoints.size();m++) { double r=CMathUtility::MinR(regionEdges[0].Start,regionEdges[0].End,newCandidatePoints[m]); if(r < minR) { minR = r; LO2 = newCandidatePoints[m]; } } tmpTriangel.Edges.clear(); tmpTriangel.Edges.push_back(regionEdges[0]); tmpEdge1.Start = regionEdges[0].End; tmpEdge1.End = LO2; tmpTriangel.Edges.push_back(tmpEdge1); tmpEdge2.Start = LO2; tmpEdge2.End = regionEdges[0].Start; tmpTriangel.Edges.push_back(tmpEdge2); tmpTriangel.Commit(); newCandidatePoints.clear(); for (int j = 0;j<candidatePoints.size();j++) { if (CMathUtility::IsCanExistInCircle(candidatePoints[j],tmpTriangel)) { newCandidatePoints.push_back(candidatePoints[j]); } } } tri_faces.push_back(tmpTriangel); CEdge L11_LO2(regionEdges[0].Start,LO2); L11_LO2.isBoundEdge = false; L11_LO2.Commit(); CEdge L12_LO2(LO2,regionEdges[0].End); L12_LO2.isBoundEdge =false; L12_LO2.Commit(); int pos_m = 0; int pos_n = 0; if(CMathUtility::IsBoundEdge(regionEdges,L11_LO2,pos_m)) { L11_LO2.isBoundEdge = true; } if(CMathUtility::IsBoundEdge(regionEdges,L12_LO2,pos_n)) { L12_LO2.isBoundEdge = true; } if(!L11_LO2.isBoundEdge && !L12_LO2.isBoundEdge) { CEdge tmpEdge(L12_LO2.Start,L12_LO2.End); tmpEdge.Commit(); regionEdges.push_back(tmpEdge); regionEdges[0].End = LO2; regionEdges[0].Commit(); } if(L11_LO2.isBoundEdge && !L12_LO2.isBoundEdge) { regionEdges[0].Start = LO2; regionEdges[0].Commit(); regionEdges[pos_m] = regionEdges[regionEdges.size()-1]; regionEdges.pop_back(); } if(!L11_LO2.isBoundEdge && L12_LO2.isBoundEdge) { regionEdges[0].End = LO2; regionEdges[0].Commit(); regionEdges[pos_n] = regionEdges[regionEdges.size()-1]; regionEdges.pop_back(); } if(L11_LO2.isBoundEdge && L12_LO2.isBoundEdge) { if (pos_n>pos_m) { regionEdges[pos_n] = regionEdges[regionEdges.size()-1]; regionEdges.pop_back(); regionEdges[pos_m] = regionEdges[regionEdges.size()-1]; regionEdges.pop_back(); regionEdges[0] = regionEdges[regionEdges.size()-1]; regionEdges.pop_back(); } else { regionEdges[pos_m] = regionEdges[regionEdges.size()-1]; regionEdges.pop_back(); regionEdges[pos_n] = regionEdges[regionEdges.size()-1]; regionEdges.pop_back(); regionEdges[0] = regionEdges[regionEdges.size()-1]; regionEdges.pop_back(); } } } // TODO if(regionEdges.size()==3) { CEdgeLoop tmpTriangle; tmpTriangle.Edges.push_back(regionEdges[0]); tmpTriangle.Edges.push_back(regionEdges[1]); tmpTriangle.Edges.push_back(regionEdges[2]); tmpTriangle.Commit(); tri_faces.push_back(tmpTriangle); } return true; }
bool DivideAndConquerFor3DCH::RayTriangleIntersection( Ray r, TRIANGLE triangle, const vector<VERTEX*>* pVertex ) { VERTEX* pointOne = (*pVertex)[ triangle.p1.pointOneIndex ]; VERTEX* pointTwo = (*pVertex)[ triangle.p2.pointTwoIndex ]; VERTEX* pointThree = (*pVertex)[ triangle.p3.pointThreeIndex ]; D3DXVECTOR3 edge1( pointTwo->x - pointOne->x, pointTwo->y - pointOne->y, pointTwo->z - pointOne->z ); D3DXVECTOR3 edge2( pointThree->x - pointOne->x, pointThree->y - pointOne->y, pointThree->z - pointOne->z ); D3DXVECTOR3 triNormal; D3DXVec3Cross( &triNormal, &edge1, &edge2 ); D3DXVec3Normalize( &triNormal, &triNormal ); double denominator = D3DXVec3Dot( &triNormal, &r.direction ); // Ray parallels to the plane if( fabs( denominator ) < 0.000001 ) { return false; } double d = triNormal.x * pointOne->x + triNormal.y * pointOne->y + triNormal.z * pointOne->z; double t = ( d - D3DXVec3Dot( &triNormal, &r.position ) ) / denominator; // Trianle behine the ray if( t <= 0 ) { return false; } D3DXVECTOR3 intersectPoint = r.position + t * r.direction; //D3DXVECTOR3 tmp; //D3DXVec3Cross( &tmp, &edge1, &edge2 ); //double totalAmount = D3DXVec3Dot( &tmp, &triNormal ); //double totalArea = D3DXVec3Length( &tmp ) * 0.5; //VERTEX tmpV = pointThree - pointTwo; //D3DXVec3Cross( &tmp, &D3DXVECTOR3( tmpV.x, tmpV.y, tmpV.z ), &D3DXVECTOR3( intersectPoint.x - pointTwo.x, intersectPoint.y - pointTwo.y, intersectPoint.z - pointTwo.z ) ); //double alpha = D3DXVec3Length( &tmp ) * 0.5 / totalArea; // //tmpV = pointOne - pointThree; //D3DXVec3Cross( &tmp, &D3DXVECTOR3( tmpV.x, tmpV.y, tmpV.z ), &D3DXVECTOR3( intersectPoint.x - pointThree.x, intersectPoint.y - pointThree.y, intersectPoint.z - pointThree.z ) ); //double beta = D3DXVec3Length( &tmp ) * 0.5 / totalArea; //tmpV = pointTwo - pointOne; //D3DXVec3Cross( &tmp, &D3DXVECTOR3( tmpV.x, tmpV.y, tmpV.z ), &D3DXVECTOR3( intersectPoint.x - pointOne.x, intersectPoint.y - pointOne.y, intersectPoint.z - pointOne.z ) ); //double gamma = D3DXVec3Length( &tmp ) * 0.5 / totalArea; // if( alpha + beta + gamma > 1.00001 ) // { // return false; // } D3DXVECTOR3 tmpEdge( intersectPoint.x - pointOne->x, intersectPoint.y - pointOne->y, intersectPoint.z - pointOne->z ); D3DXVECTOR3 tmpCrossRes; D3DXVec3Cross( &tmpCrossRes, &edge1, &tmpEdge ); double alpha = D3DXVec3Dot( &triNormal, &tmpCrossRes ); if( alpha < 0.0f ) { return false; } tmpEdge = D3DXVECTOR3( intersectPoint.x - pointTwo->x, intersectPoint.y - pointTwo->y, intersectPoint.z - pointTwo->z); D3DXVECTOR3 tmpEdge2( pointThree->x - pointTwo->x, pointThree->y - pointTwo->y, pointThree->z - pointTwo->z ); D3DXVec3Cross( &tmpCrossRes, &tmpEdge2, &tmpEdge ); double beta = D3DXVec3Dot( &triNormal, &tmpCrossRes ); if( beta < 0.0f ) { return false; } tmpEdge = D3DXVECTOR3( intersectPoint.x - pointThree->x, intersectPoint.y - pointThree->y, intersectPoint.z - pointThree->z ); tmpEdge2 = D3DXVECTOR3( pointOne->x - pointThree->x, pointOne->y - pointThree->y, pointOne->z - pointThree->z ); D3DXVec3Cross( &tmpCrossRes, &tmpEdge2, &tmpEdge ); double gamma = D3DXVec3Dot( &triNormal, &tmpCrossRes ); if( gamma < 0.0f ) { return false; } return true; }