#ifndef _TRIANGLE_POLYTRY_ #define _TRIANGLE_POLYTRY_ class Vector3F { public: Vector3F(float x=0.0f,float y=0.0f,float z=0.0f) { Set(x,y,z); } Vector3F(const Vector3F& point) { Set(point.m_v[0],point.m_v[1],point.m_v[2]); } // void Set(float x,float y,float z) { m_v[0]=x; m_v[1]=y; m_v[2]=z; } // float operator []( int i) const { return m_v[i]; } float& operator []( int i) { return m_v[i]; } // Vector3F& operator +=(const Vector3F& v) { m_v[0]+=v.m_v[0]; m_v[1]+=v.m_v[1]; m_v[2]+=v.m_v[2]; return *this; } Vector3F& operator -=(const Vector3F& v) { m_v[0]-=v.m_v[0]; m_v[1]-=v.m_v[1]; m_v[2]-=v.m_v[2]; return *this; } Vector3F& operator *=(const float d) { m_v[0]*=d; m_v[1]*=d; m_v[2]*=d; return *this; } // float Dot(const Vector3F& v) const { return (m_v[0]*v.m_v[0]+m_v[1]*v.m_v[1]+m_v[2]*v.m_v[2]); } void Vector(const Vector3F& b, Vector3F &c) const { c.m_v[0]= m_v[1] * b.m_v[2] - m_v[2] * b.m_v[1]; c.m_v[1]= m_v[2] * b.m_v[0] - m_v[0] * b.m_v[2]; c.m_v[2]= m_v[0] * b.m_v[1] - m_v[1] * b.m_v[0]; } float SquaredLenght() const { return Dot(*this); } float Lenght() const { return (float)sqrt(Dot(*this)); } // float m_v[3]; }; class CPolyTri { public: CPolyTri() { m_nIndex=NULL; m_nMaxPoints=0; } virtual ~CPolyTri() { if( m_nIndex ) delete [] m_nIndex; } // // Sel closed... // int Triangulate(const Vector3F* points,const Vector3F &normal,int nCount) { // // Alloca un vettore di interi ... // int nTriangle= 0; int nVertex = nCount; // AllocIndex(nCount); // bool bNoErrors = true; // while( nVertex > 3 && bNoErrors ){ // // tri to remove one vertex... // bNoErrors = false; // for( int i=0 , j=1 , k=2 ; k < nVertex ; ){ // switch( TriangleArea(points , m_nIndex[i] , m_nIndex[j] , m_nIndex[k] , normal ) ){ // // ok. flush face && remove vertex j // case convex : // // Testing containement // if( IsAnyPointInside(points,i,j,k,nVertex) ){ // // go ahead.. // i = j; j = k; k++; }else{ nTriangle++; AddFace(points,m_nIndex[i],m_nIndex[j],m_nIndex[k]); // // remove vertex j // nVertex = RemoveVertex( j,nVertex ); bNoErrors= true; } break; case concave : // // go ahead.. // i = j; j = k; k++; break; case degenerate : // // remove vertex j // nVertex = RemoveVertex( j,nVertex ); bNoErrors= true; break; } } } return nTriangle; } // // Utility Polygon Normal... // static void ComputeNormal(const Vector3F* points,int nPoints,Vector3F &normal) { // // Newell // normal[0]=normal[1]=normal[2]=0.0f; for( register int i=0 , j=1 ; j < nPoints ; i++ , j++ ){ normal[0]+= ( points[i][1] - points[j][1] ) * ( points[i][2] + points[j][2] ) ; normal[1]+= ( points[i][2] - points[j][2] ) * ( points[i][0] + points[j][0] ) ; normal[2]+= ( points[i][0] - points[j][0] ) * ( points[i][1] + points[j][1] ) ; } } // // Utility Test Polygon Convexity ... // static bool IsConvex(const Vector3F* points,int nPoints,const Vector3F &normal) { // // calcolo del versore se il poligono e' convesso // il prodotto vettoriale // Vector3F vi( points[1] ); vi-=points[0]; Vector3F vj,n; int nP=nPoints-1; // for( register int i=0 , j=1 , k ; j < nPoints ; i++ , j++ ){ k = (j+1) % nP; vj = points[k]; vj-= points[j]; // vi.Vector(vj,n); // if( (n[0]*normal[0]) < 0.0f || (n[1]*normal[1]) < 0.0f || (n[2]*normal[2]) < 0.0f ) break; vi = vj; } return ( j == nPoints ? true : false ); } protected: // int *m_nIndex; Vector3F m_e0 ; Vector3F m_e1 ; Vector3F m_N ; float m_A ; // 2 area // enum { convex = 1, degenerate = 0, concave = -1}; // int RemoveVertex( int j,int nVertex ) { while( ++j < nVertex ) m_nIndex[j-1]=m_nIndex[j]; return (nVertex-1); } // bool IsAnyPointInside(const Vector3F* points,int i,int j,int k,int nVertex) const { int ik=m_nIndex[k]; for( register int ip=0 ; ip < nVertex ; ip++ ) if( ( ip < i || ip > k ) && IsPointInside(points[m_nIndex[ip]],points[ik]) ){ return true; } return false; } // bool IsPointInside(const Vector3F point,const Vector3F q2) const { Vector3F pmq2 = point; pmq2 -= q2; // Vector3F ntmp; // float B0,B1; // pmq2.Vector(m_e1,ntmp); if( (B0=m_N.Dot(ntmp)) <= 0.0 ) return false; m_e0.Vector(pmq2,ntmp); if( (B1=m_N.Dot(ntmp)) <= 0.0 ) return false; return ( (m_A-B0-B1) > 0.0 ? true : false ); } // int TriangleArea(const Vector3F* points,int i,int j,int k,const Vector3F& normal) { m_e0=points[i]; m_e0-=points[k]; m_e1=points[j]; m_e1-=points[k]; // m_e0.Vector(m_e1,m_N); // m_A=m_N.SquaredLenght(); // // j is alligned from i to k ? // if( (-FLT_EPSILON) < m_A && m_A < FLT_EPSILON ) return degenerate; // // test convexity : // return ( m_N.Dot( normal ) < 0.0 ? concave : convex ); } // virtual void AddFace(const Vector3F* points,int i,int j,int k) {} private: int m_nMaxPoints; void AllocIndex(int nCount) { if( nCount > m_nMaxPoints ){ if( m_nIndex ) delete [] m_nIndex; m_nMaxPoints = nCount+2; m_nIndex = new int[m_nMaxPoints]; } for( register int i=0 ; i < nCount ; i++ ) m_nIndex[i] = i; } }; // class CTriDC : public CPolyTri { public: CTriDC(CDC* pDC) { m_pDC = pDC; } CDC* m_pDC; protected: // CPoint m_points[4]; // virtual void AddFace(const Vector3F* points,int i,int j,int k) { m_points[0].x =(int)points[i][0]; m_points[0].y =(int)points[i][1]; m_points[1].x =(int)points[j][0]; m_points[1].y =(int)points[j][1]; m_points[2].x =(int)points[k][0]; m_points[2].y =(int)points[k][1]; m_points[3] = m_points[0]; m_pDC->Polygon(m_points,4); } }; #define _TRIANGLE_POLYTRY_ #endif