Exemplo n.º 1
0
    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;
}