www.pudn.com > VC++Delaunay.rar > DelaunayView.cpp


// DelaunayView.cpp : implementation of the CDelaunayView class 
// 
 
#include "stdafx.h" 
#include "Delaunay.h" 
 
#include "mainfrm.h" 
#include "pointpos.h" 
#include "triangle.h" 
 
#include "DelaunayDoc.h" 
#include "DelaunayView.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CDelaunayView 
 
IMPLEMENT_DYNCREATE(CDelaunayView, CView) 
 
BEGIN_MESSAGE_MAP(CDelaunayView, CView) 
	//{{AFX_MSG_MAP(CDelaunayView) 
	ON_WM_SIZE() 
	ON_WM_CREATE() 
	ON_WM_LBUTTONDOWN() 
	ON_WM_MOUSEMOVE() 
	ON_WM_DESTROY() 
	ON_WM_KEYDOWN() 
	ON_COMMAND(IDM_CORLOR, OnCorlorMaterial) 
	ON_UPDATE_COMMAND_UI(IDM_CORLOR, OnUpdateCorlorMaterial) 
	ON_UPDATE_COMMAND_UI(IDM_LIGHT, OnUpdateLight) 
	ON_COMMAND(IDM_LIGHT, OnLight) 
	ON_COMMAND(ID_BUTTON_TWO, OnButtonTwo) 
	ON_UPDATE_COMMAND_UI(ID_BUTTON_TWO, OnUpdateButtonTwo) 
	ON_COMMAND(ID_BUTTON_THREE, OnButtonThree) 
	ON_UPDATE_COMMAND_UI(ID_BUTTON_THREE, OnUpdateButtonThree) 
	ON_COMMAND(ID_BUTTON_HCT, OnButtonHct) 
	ON_UPDATE_COMMAND_UI(ID_BUTTON_HCT, OnUpdateButtonHct) 
	ON_COMMAND(ID_BUTTON_FILL, OnButtonFill) 
	ON_UPDATE_COMMAND_UI(ID_BUTTON_FILL, OnUpdateButtonFill) 
	ON_COMMAND(ID_BUTTON_LINE, OnButtonLine) 
	ON_UPDATE_COMMAND_UI(ID_BUTTON_LINE, OnUpdateButtonLine) 
	ON_COMMAND(ID_BUTTON_WNAG, OnButtonWnag) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CDelaunayView construction/destruction 
 
CDelaunayView::CDelaunayView() 
{ 
	// TODO: add construction code here 
 
} 
 
CDelaunayView::~CDelaunayView() 
{ 
} 
 
BOOL CDelaunayView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
    cs.style |=WS_CLIPCHILDREN |WS_CLIPSIBLINGS; 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CDelaunayView drawing 
 
void CDelaunayView::OnDraw(CDC* pDC) 
{ 
	CDelaunayDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	 
	DrawScene(); 
	SwapBuffers(pDC->m_hDC); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CDelaunayView diagnostics 
 
#ifdef _DEBUG 
void CDelaunayView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CDelaunayView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CDelaunayDoc* CDelaunayView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDelaunayDoc))); 
	return (CDelaunayDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
///////////////////////////////////////////////////////////////////////////// 
// CDelaunayView message handlers 
 
void CDelaunayView::OnSize(UINT nType, int cx, int cy)  
{ 
	CView::OnSize(nType, cx, cy); 
	if(cy>0) 
	{ 
		m_oldRect.right=cx; 
		m_oldRect.bottom=cy;		 
		glMatrixMode(GL_PROJECTION); 
		glLoadIdentity(); 
		glFrustum(-2.0,2.0,-2.0,2.0,0.0,20.0); 
		glLoadIdentity();//????不能不要,事关显示 
		//gluPerspective(40.0f,(GLdouble)cx/cy,1.0f,50.0f); 
		glMatrixMode(GL_MODELVIEW);		 
		glViewport(0,0,cx,cy); 
	} 
	 
} 
 
int CDelaunayView::OnCreate(LPCREATESTRUCT lpCreateStruct)  
{ 
	if (CView::OnCreate(lpCreateStruct) == -1) 
		return -1; 
	InitOpenGl(); 
	m_pDoc=this->GetDocument();	 
	m_ox=50;m_oy=50;m_len=400; 
	m_Dimension=DO_DRAW2; 
//m_HCT=DO_NO_HCT; 
	m_Draw_what=DO_LINE; 
//OpenGl/////////////////////////////	 
	m_translate_x=-1.0; 
	m_translate_y=-1.0; 
	m_translate_z=0; 
	m_rotate_angle=0; 
	m_gl_x=1.0;m_gl_y=1.0;m_gl_z=0.0; 
	eye.x=4.0;eye.y=5.0;eye.z=6.0; 
 
	m_colorRed=float(0.2);m_colorGreen=float(0.5);m_colorBlue=float(0.8); 
	m_bMaskRed=FALSE;m_bMaskGreen=FALSE;m_bMaskBlue=FALSE; 
 
	m_materialAmb[0]=0.2;m_materialAmb[1]=0.2;m_materialAmb[2]=0.2;m_materialAmb[3]=1.0; 
	m_materialDif[0]=0.8;m_materialDif[1]=0.8;m_materialDif[2]=0.8;m_materialDif[3]=1.0; 
	m_materialSpe[0]=0.0;m_materialSpe[1]=0.0;m_materialSpe[2]=0.0;m_materialSpe[3]=1.0; 
	m_materialEmi[0]=0.0;m_materialEmi[1]=0.0;m_materialEmi[2]=0.0;m_materialEmi[3]=1.0; 
	m_matshininess=0.0f; 
 
	m_lightAmb[0]=0.2;m_lightAmb[1]=0.2;m_lightAmb[2]=0.2;m_lightAmb[3]=1.0; 
	m_lightDif[0]=1.0;m_lightDif[1]=1.0;m_lightDif[2]=0.3;m_lightDif[3]=1.0; 
	m_lightSpe[0]=1.0;m_lightSpe[1]=1.0;m_lightSpe[2]=1.0;m_lightSpe[3]=1.0;	 
	m_lightPos[0]=1.0;m_lightPos[1]=1.0;m_lightPos[2]=1.0;m_lightPos[3]=0.0; 
//OpenGl///////////////////////////// 
	return 0; 
} 
 
void CDelaunayView::OnLButtonDown(UINT nFlags, CPoint point)  
{//////////////////////////////////////////// 
	ASSERT(m_pDoc!=NULL); 
	CPoint pos=point; 
	int m_plen;//当前节点个数 
	double s; 
	//ScreenToClient(&pos); 
	if(m_pDoc->m_DoWhat==DO_ADD) 
	{ 
				//'x' and 'y' are that to be stored in 'm_point' 
				double x,y; 
				x=double(pos.x)/double(m_oldRect.right); 
				y=double((m_oldRect.bottom-pos.y))/double(m_oldRect.bottom);				 
				//form the original convexity when 'm_plen' is smaller than 3 
				//the original convexity is a triangle 
				m_plen=m_pDoc->m_point.GetSize();//==1???? 
				switch(m_plen)  
				{ 
					case 0 : 
						m_pDoc->AddPoint(x,y);				 
						m_pDoc->m_con.SetAtGrow(0,0);				 
                        break; 
					case 1 : 
						if(m_pDoc->m_point[0]->m_x==x && 
						   m_pDoc->m_point[0]->m_y==y) 
						{ 
						  AfxMessageBox("The two point not suitable"); 
	                      break; 
							//please 输入节点,跳出 
						} 
						m_pDoc->AddPoint(x,y); 
						m_pDoc->m_con.SetAtGrow(1,1);						 
                        break; 
                    case 2 ://确保凸包顶点逆时针存储 
						m_pDoc->AddPoint(x,y); 
						s=m_pDoc->S(0,1,2); 
						if(s==0) 
						{						 
							AfxMessageBox("please 输入节点 again,因三点共线,跳出"); 
							m_pDoc->m_point.RemoveAt(2,1); 
                          //  m_pDoc->m_n.RemoveAt(2,1); 
						} 
						 
						m_plen=m_pDoc->m_point.GetSize(); 
						m_pDoc->m_con.SetAtGrow(m_plen-1,m_plen-1);                     
						if(s<0)  
						{ 
							m_pDoc->m_con[0]=1; 
							m_pDoc->m_con[1]=0;                           
						}																		 
						CTriangle* pTriangle; 
						pTriangle=new CTriangle(m_pDoc->m_con[0], 
							      m_pDoc->m_con[1],m_pDoc->m_con[2]); 
						m_pDoc->Center(pTriangle); 
						m_pDoc->BaryCenter(pTriangle); 
						m_pDoc->m_tri.AddHead(pTriangle);                    
                        break; 
	                default : 
						m_pDoc->AddPoint(x,y); 
                        m_plen=m_pDoc->m_point.GetSize();				 
                        int i=DelTriList(x,y,m_plen-1); 
						if(i==POS_ERROR){ 
							int k=m_pDoc->m_point.GetSize(); 
							m_pDoc->m_point.RemoveAt(k-1,1); 
						} 
                        break; 
				} 
				Invalidate(); 
	} 
//////////////////////////////////////////// 
	CView::OnLButtonDown(nFlags, point); 
} 
 
void CDelaunayView::OnMouseMove(UINT nFlags, CPoint point)  
{ 
	// TODO: Add your message handler code here and/or call default 
//	CClientDC dc(this); 
	double x,y; 
	double a,b; 
	a=double(point.x); 
	b=double(m_oldRect.right); 
	x=a/b; 
	y=double((m_oldRect.bottom-point.y))/double(m_oldRect.bottom); 
 
    CString str1; 
	str1.Empty(); 
	int i=m_pDoc->m_DoWhat; 
    str1.Format("%f;%f;%d;%d;%d;%d",x,y,i,m_Dimension,m_HCT,m_Draw_what); 
	CMainFrame *pFram=(CMainFrame *)(AfxGetApp()->GetMainWnd()); 
	pFram->m_wndStatusBar.SetPaneText(0,str1); 
	CView::OnMouseMove(nFlags, point); 
} 
 
 
array CDelaunayView::Wher(CPointPos *pos) 
{ 
	//Points and Convexity 
	/*return Value:a.a 
	POS_IN=1,a point  belong a triangle or convexity 
	POS_ON=2,a point belong a circle or on the edge of convexity 
	POS_OUT=0,a point out of a circle or convexity 
	a.b , a.c: record the point's mark in m_con */ 
	//1. get a ponit in convexity:p 
	array a; 
	int max=m_pDoc->m_con.GetSize(); 
	int z=max/2; 
	CPointPos *p1=new CPointPos(m_pDoc->m_point[m_pDoc->m_con[0]]->m_x, 
		m_pDoc->m_point[m_pDoc->m_con[0]]->m_y); 
    CPointPos *p2=new CPointPos(m_pDoc->m_point[m_pDoc->m_con[z]]->m_x, 
		m_pDoc->m_point[m_pDoc->m_con[z]]->m_y); 
    CPointPos *p3=new CPointPos(m_pDoc->m_point[m_pDoc->m_con[max-1]]->m_x, 
		m_pDoc->m_point[m_pDoc->m_con[max-1]]->m_y); 
	CPointPos *p=new CPointPos((p1->m_x+p2->m_x+p3->m_x)/3, 
		         (p1->m_y+p2->m_y+p3->m_y)/3); 
	p3->m_x=double(pos->m_x); 
	p3->m_y=double(pos->m_y); 
	//遍寻Convexity 
	double s1,s2,s; 
	for(int i=0;im_x=m_pDoc->m_point[m_pDoc->m_con[i]]->m_x; 
	    p1->m_y=m_pDoc->m_point[m_pDoc->m_con[i]]->m_y; 
     	p2->m_x=m_pDoc->m_point[m_pDoc->m_con[i+1]]->m_x; 
	    p2->m_y=m_pDoc->m_point[m_pDoc->m_con[i+1]]->m_y; 
         
		s1=m_pDoc->S(p3,p,p1); 
		s2=m_pDoc->S(p3,p,p2); 
		if(s1>0 && s2<0)//the point in the 扇形 con[i],con[i+1] and p formed 
		{ 
		  a.b=i; 
		  a.c=i+1; 
          s=m_pDoc->S(p1,p2,p3); 
		  if(s>0) 
		  { 
			  a.a=1;//POS_IN			  
		  } 
          if(s==0) 
		  { 
			  a.a=2;//POS_ON 
		  } 
		  if(s<0) 
		  { 
			  a.a=0;//POS_OUT 
		  } 
		  return a; 
		}         		 
	} 
    p1->m_x=m_pDoc->m_point[m_pDoc->m_con[i]]->m_x; 
	p1->m_y=m_pDoc->m_point[m_pDoc->m_con[i]]->m_y; 
    p2->m_x=m_pDoc->m_point[m_pDoc->m_con[0]]->m_x; 
	p2->m_y=m_pDoc->m_point[m_pDoc->m_con[0]]->m_y; 
	s1=m_pDoc->S(p3,p,p1); 
	s2=m_pDoc->S(p3,p,p2); 
		if(s1>0 && s2<0) 
		{ 
          a.b=i; 
		  a.c=0; 
          s=m_pDoc->S(p1,p2,p3); 
		  if(s>0) 
		  { 
			  a.a=1;//POS_IN			  
		  } 
          if(s==0) 
		  { 
			  a.a=2;//POS_ON 
		  } 
		  if(s<0) 
		  { 
			  a.a=0;//POS_OUT 
		  } 
		  return a; 
		}         		  
} 
 
void CDelaunayView::DrawTri(CTriangle *tri) 
{ 
	int i; 
	//POI normal; 
	int p1,p2,p3; 
	 
	p1=tri->m_p1; 
	p2=tri->m_p2; 
	p3=tri->m_p3; 
	GLfloat fLineWidth[2]; 
	glGetFloatv(GL_LINE_WIDTH_RANGE,fLineWidth); 
	if(m_Dimension==DO_DRAW2 && m_HCT!=DO_HCT) 
	{ 
		glColor4d(0.0,0.0,1.0,0.5);	 
	    glBegin(GL_TRIANGLES); 
		glVertex3d(m_pDoc->m_point[p1]->m_x,m_pDoc->m_point[p1]->m_y,0.0); 	 
    	glVertex3d(m_pDoc->m_point[p2]->m_x,m_pDoc->m_point[p2]->m_y,0.0);	 
    	glVertex3d(m_pDoc->m_point[p3]->m_x,m_pDoc->m_point[p3]->m_y,0.0); 
    	glEnd();	 
	} 
	if(m_Dimension==DO_DRAW3 && m_HCT!=DO_HCT) 
	{ 
		glPushMatrix(); 
		//glScaled(2,2,1.5); 
		glColor3f(1.0f,0.0f,0.0f);		         
		glBegin(GL_TRIANGLES); 
		glVertex3d(m_pDoc->m_point[p1]->m_x,m_pDoc->m_point[p1]->m_y,m_pDoc->m_point[p1]->m_z); 	 
    	glVertex3d(m_pDoc->m_point[p2]->m_x,m_pDoc->m_point[p2]->m_y,m_pDoc->m_point[p2]->m_z);	 
    	glVertex3d(m_pDoc->m_point[p3]->m_x,m_pDoc->m_point[p3]->m_y,m_pDoc->m_point[p3]->m_z); 
    	glEnd(); 
		glPopMatrix(); 
	} 
	if(m_Dimension==DO_DRAW3 && m_HCT==DO_HCT) 
	{		 
		m_pDoc->DrawTri(tri->m_p1,tri->m_p2,tri); 
		m_pDoc->DrawTri(tri->m_p2,tri->m_p3,tri); 
		m_pDoc->DrawTri(tri->m_p3,tri->m_p1,tri); 
		/*for(i=1;i<=3;i++) 
		{ 
			HCT(tri,i); 
			glColor4d(0.0,1.0,0.0,0.5); 
			if(i==2) 
			{ 
				glBegin(GL_TRIANGLES);//anticlock		    
				   normal=GetTriNormal(m_hct[0],m_hct[1],m_hct[2]); 
				   glNormal3d(normal.x,normal.y,normal.z); 
				   glVertex3d(m_hct[0].x,m_hct[0].y,m_hct[0].z); 	    	    
				   glVertex3d(m_hct[1].x,m_hct[1].y,m_hct[1].z); 
				   glVertex3d(m_hct[2].x,m_hct[2].y,m_hct[2].z); 
				    
				   normal=GetTriNormal(m_hct[1],m_hct[3],m_hct[2]); 
				   glNormal3d(normal.x,normal.y,normal.z); 
				   glVertex3d(m_hct[1].x,m_hct[1].y,m_hct[1].z); 
				   glVertex3d(m_hct[3].x,m_hct[3].y,m_hct[3].z); 
				   glVertex3d(m_hct[2].x,m_hct[2].y,m_hct[2].z); 
 
				   normal=GetTriNormal(m_hct[3],m_hct[1],m_hct[4]); 
				   glNormal3d(normal.x,normal.y,normal.z);		    
				   glVertex3d(m_hct[3].x,m_hct[3].y,m_hct[3].z); 
				   glVertex3d(m_hct[1].x,m_hct[1].y,m_hct[1].z); 
				   glVertex3d(m_hct[4].x,m_hct[4].y,m_hct[4].z); 
 
				   normal=GetTriNormal(m_hct[3],m_hct[4],m_hct[5]); 
				   glNormal3d(normal.x,normal.y,normal.z); 
				   glVertex3d(m_hct[3].x,m_hct[3].y,m_hct[3].z); 
				   glVertex3d(m_hct[4].x,m_hct[4].y,m_hct[4].z); 
				   glVertex3d(m_hct[5].x,m_hct[5].y,m_hct[5].z); 
				    
				   normal=GetTriNormal(m_hct[4],m_hct[6],m_hct[5]); 
				   glNormal3d(normal.x,normal.y,normal.z); 
				   glVertex3d(m_hct[4].x,m_hct[4].y,m_hct[4].z);	    
				   glVertex3d(m_hct[6].x,m_hct[6].y,m_hct[6].z); 
    			   glVertex3d(m_hct[5].x,m_hct[5].y,m_hct[5].z); 
 
				   normal=GetTriNormal(m_hct[8],m_hct[7],m_hct[9]); 
				   glNormal3d(normal.x,normal.y,normal.z); 
				   glVertex3d(m_hct[8].x,m_hct[8].y,m_hct[8].z); 	 
    			   glVertex3d(m_hct[7].x,m_hct[7].y,m_hct[7].z); 
				   glVertex3d(m_hct[9].x,m_hct[9].y,m_hct[9].z); 
 
				   normal=GetTriNormal(m_hct[8],m_hct[3],m_hct[7]); 
				   glNormal3d(normal.x,normal.y,normal.z); 
				   glVertex3d(m_hct[8].x,m_hct[8].y,m_hct[8].z);		 
				   glVertex3d(m_hct[3].x,m_hct[3].y,m_hct[3].z); 
				   glVertex3d(m_hct[7].x,m_hct[7].y,m_hct[7].z); 
 
				   normal=GetTriNormal(m_hct[3],m_hct[5],m_hct[7]); 
				   glNormal3d(normal.x,normal.y,normal.z); 
				   glVertex3d(m_hct[3].x,m_hct[3].y,m_hct[3].z); 
				   glVertex3d(m_hct[5].x,m_hct[5].y,m_hct[5].z); 
				   glVertex3d(m_hct[7].x,m_hct[7].y,m_hct[7].z);		 
    			 
				   normal=GetTriNormal(m_hct[2],m_hct[3],m_hct[8]); 
				   glNormal3d(normal.x,normal.y,normal.z); 
				   glVertex3d(m_hct[2].x,m_hct[2].y,m_hct[2].z); 	 
				   glVertex3d(m_hct[3].x,m_hct[3].y,m_hct[3].z); 
				   glVertex3d(m_hct[8].x,m_hct[8].y,m_hct[8].z); 
    			glEnd(); 
			} 
			else 
			{ 
			   glBegin(GL_TRIANGLES);//anticlock		    
			   normal=GetTriNormal(m_hct[0],m_hct[2],m_hct[1]); 
			   glNormal3d(normal.x,normal.y,normal.z); 
			   glVertex3d(m_hct[0].x,m_hct[0].y,m_hct[0].z); 	    	    
			   glVertex3d(m_hct[2].x,m_hct[2].y,m_hct[2].z); 
			   glVertex3d(m_hct[1].x,m_hct[1].y,m_hct[1].z); 
			    
			   normal=GetTriNormal(m_hct[1],m_hct[2],m_hct[3]); 
			   glNormal3d(normal.x,normal.y,normal.z); 
			   glVertex3d(m_hct[1].x,m_hct[1].y,m_hct[1].z); 
			   glVertex3d(m_hct[2].x,m_hct[2].y,m_hct[2].z); 
			   glVertex3d(m_hct[3].x,m_hct[3].y,m_hct[3].z); 
 
			   normal=GetTriNormal(m_hct[1],m_hct[3],m_hct[4]); 
			   glNormal3d(normal.x,normal.y,normal.z);		    
			   glVertex3d(m_hct[1].x,m_hct[1].y,m_hct[1].z); 
			   glVertex3d(m_hct[3].x,m_hct[3].y,m_hct[3].z); 
			   glVertex3d(m_hct[4].x,m_hct[4].y,m_hct[4].z); 
 
			   normal=GetTriNormal(m_hct[4],m_hct[3],m_hct[5]); 
			   glNormal3d(normal.x,normal.y,normal.z); 
			   glVertex3d(m_hct[4].x,m_hct[4].y,m_hct[4].z); 
			   glVertex3d(m_hct[3].x,m_hct[3].y,m_hct[3].z); 
			   glVertex3d(m_hct[5].x,m_hct[5].y,m_hct[5].z); 
			    
			   normal=GetTriNormal(m_hct[4],m_hct[5],m_hct[6]); 
			   glNormal3d(normal.x,normal.y,normal.z); 
			   glVertex3d(m_hct[4].x,m_hct[4].y,m_hct[4].z);	    
			   glVertex3d(m_hct[5].x,m_hct[5].y,m_hct[5].z); 
    		   glVertex3d(m_hct[6].x,m_hct[6].y,m_hct[6].z); 
 
			   normal=GetTriNormal(m_hct[7],m_hct[8],m_hct[9]); 
			   glNormal3d(normal.x,normal.y,normal.z); 
			   glVertex3d(m_hct[7].x,m_hct[7].y,m_hct[7].z); 	 
    		   glVertex3d(m_hct[8].x,m_hct[8].y,m_hct[8].z); 
			   glVertex3d(m_hct[9].x,m_hct[9].y,m_hct[9].z); 
 
			   normal=GetTriNormal(m_hct[3],m_hct[8],m_hct[7]); 
			   glNormal3d(normal.x,normal.y,normal.z); 
			   glVertex3d(m_hct[3].x,m_hct[3].y,m_hct[3].z);		 
			   glVertex3d(m_hct[8].x,m_hct[8].y,m_hct[8].z); 
			   glVertex3d(m_hct[7].x,m_hct[7].y,m_hct[7].z); 
 
			   normal=GetTriNormal(m_hct[3],m_hct[7],m_hct[5]); 
			   glNormal3d(normal.x,normal.y,normal.z); 
			   glVertex3d(m_hct[3].x,m_hct[3].y,m_hct[3].z); 
			   glVertex3d(m_hct[7].x,m_hct[7].y,m_hct[7].z); 
			   glVertex3d(m_hct[5].x,m_hct[5].y,m_hct[5].z);		 
    		 
			   normal=GetTriNormal(m_hct[3],m_hct[2],m_hct[8]); 
			   glNormal3d(normal.x,normal.y,normal.z); 
			   glVertex3d(m_hct[3].x,m_hct[3].y,m_hct[3].z); 	 
			   glVertex3d(m_hct[2].x,m_hct[2].y,m_hct[2].z); 
			   glVertex3d(m_hct[8].x,m_hct[8].y,m_hct[8].z); 
    			glEnd(); 
			}//if else 
		}//for*/ 
	}//if 
	if(m_Dimension==DO_DRAW2 && m_HCT==DO_HCT) 
	{ 
		for(i=1;i<=3;i++) 
		{ 
			HCT(tri,i); 
			glColor4d(0.0,0.0,1.0,0.5);	 
			glBegin(GL_TRIANGLES);//anticlock 
			   glVertex3d(m_hct[0].x,m_hct[0].y,0); 	    	    
			   glVertex3d(m_hct[1].x,m_hct[1].y,0); 
			   glVertex3d(m_hct[2].x,m_hct[2].y,0);  
			 
			   glVertex3d(m_hct[1].x,m_hct[1].y,0);  
			   glVertex3d(m_hct[2].x,m_hct[2].y,0);  
			   glVertex3d(m_hct[3].x,m_hct[3].y,0);  
 
			   glVertex3d(m_hct[3].x,m_hct[3].y,0);  
			   glVertex3d(m_hct[1].x,m_hct[1].y,0);  
			   glVertex3d(m_hct[4].x,m_hct[4].y,0);  
 
			   glVertex3d(m_hct[3].x,m_hct[3].y,0);  
			   glVertex3d(m_hct[4].x,m_hct[4].y,0);  
			   glVertex3d(m_hct[5].x,m_hct[5].y,0);  
 
			   glVertex3d(m_hct[4].x,m_hct[4].y,0);  
			   glVertex3d(m_hct[6].x,m_hct[6].y,0);  
    		   glVertex3d(m_hct[5].x,m_hct[5].y,0);  
 
			   glVertex3d(m_hct[7].x,m_hct[7].y,0);  	 
    		   glVertex3d(m_hct[8].x,m_hct[8].y,0);  
			   glVertex3d(m_hct[9].x,m_hct[9].y,0);  
 
			   glVertex3d(m_hct[8].x,m_hct[8].y,0); 	 
			   glVertex3d(m_hct[3].x,m_hct[3].y,0);  
			   glVertex3d(m_hct[7].x,m_hct[7].y,0);  
  
			   glVertex3d(m_hct[3].x,m_hct[3].y,0);  
			   glVertex3d(m_hct[5].x,m_hct[5].y,0);  
			   glVertex3d(m_hct[7].x,m_hct[7].y,0);  
     
			   glVertex3d(m_hct[2].x,m_hct[2].y,0);  
			   glVertex3d(m_hct[3].x,m_hct[3].y,0);  
			   glVertex3d(m_hct[8].x,m_hct[8].y,0);  
    		glEnd(); 
		} 
	} 
} 
 
int CDelaunayView::DelTriList(double x, double y,int p) 
{//record the position of triangles which are to be deleted 
	//'x' and 'y' are the coordinates of the insert point 
	//'p' is the mark or th insert point in 'm_point' 
		 
		CPointPos *point=new CPointPos(x,y); 
		int j=0,i=0,k=0,max=0; 
		array a; 
		// GetInitEdges : ransack each trangle to record it's edges 
		//when the piont belong it's circle 
	    k=m_pDoc->GetInitEdges(x,y,p);// the returned value 'k/2' is the number of cirecle the point belonged?? 
		if(k==POS_ERROR){ 
			return POS_ERROR; 
		} 
		//默认:插入点属于某个外接圆,且属于凸包 
          //judge a point belong to the convexity or not 
		  a=Wher(point); 
		  /*return Value:a.a 
	POS_IN=1,a point  belong a triangle or convexity 
	POS_ON=2,a point belong a circle or on the edge of convexity 
	POS_OUT=0,a point out of a circle or convexity 
	a.b , a.c: record the point's mark in m_con */ 
		   max=m_pDoc->m_con.GetSize(); 
		  if(0==a.a && k>=2)//插入点属于某个外接圆,但不属于凸包 
		  {  //delete an edge "belong to" the inserted polygon,the edge is also  
			 //belong  to the border of the convexity 
			 if (max==3){ 
				int t=m_pDoc->m_edge.GetSize();			       
				for(j=0;jm_edge[j]->m_p1==m_pDoc->m_con[a.b]) &  
					   (m_pDoc->m_edge[j]->m_p2==m_pDoc->m_con[a.c])) 
				   { 
					   m_pDoc->m_edge.RemoveAt(j,1); 
					   m_pDoc->m_con.InsertAt(a.c,p); 
					   break; 
				   } 
				} 
			 } 
			 else 
			 { 
			    CWordArray con_index;//save the point's mark can be saw on the con	 
			    for(i=0;im_edge.GetSize();			       
				   for(j=0;jm_edge[j]->m_p1==m_pDoc->m_con[i]) &  
					   (m_pDoc->m_edge[j]->m_p2==m_pDoc->m_con[i+1])) 
					  { 
						  bool y=m_pDoc->DelEdgeOrNot(m_pDoc->m_edge[j]->m_p1,m_pDoc->m_edge[j]->m_p2,p); 
                          if(y){ 
					              m_pDoc->m_edge.RemoveAt(j,1); 
					              con_index.Add(i); 
					              con_index.Add(i+1);					    
								  break; 
						  } 
					  } 
				   } 
				}//end for i 
                int t=m_pDoc->m_edge.GetSize();			       
			    for(j=0;jm_edge[j]->m_p1==m_pDoc->m_con[max-1]) &&  
					   (m_pDoc->m_edge[j]->m_p2==m_pDoc->m_con[0])) 
				   { 
					    bool y=m_pDoc->DelEdgeOrNot(m_pDoc->m_edge[j]->m_p1,m_pDoc->m_edge[j]->m_p2,p); 
                        if(y){ 
					              m_pDoc->m_edge.RemoveAt(j,1); 
					              con_index.Add(max-1); 
					              con_index.Add(0);					    
								  break; 
						}					 					   
				   }			 
				} 
				t=con_index.GetSize(); 
			    m_pDoc->EditCon(con_index[t-1],con_index[0],p);				 
             }	 
		  } 
		  if(k==0){//插入点不属于任意一个外接圆,显然也不属于凸包 
			  CBorder * m_border; 
			  m_border=new CBorder(m_pDoc->m_con[a.b],m_pDoc->m_con[a.c]); 
			  m_pDoc->m_edge.Add(m_border); 
			  m_pDoc->EditCon(a.c,a.b,p); 
		  }	 
		   //Delete triangles that have been marked 
		  m_pDoc->DelTriMarked(); 
		  //add new triangles 
	      m_pDoc->AddTriangle(p); 
		  max=m_pDoc->m_index.GetSize(); 
		  m_pDoc->m_index.RemoveAt(0,max);//RemoveAll : no use ??? 
		  m_pDoc->m_edge.RemoveAll(); 
} 
 
void CDelaunayView::OnDestroy()  
{ 
	HGLRC hrc; 
	hrc=::wglGetCurrentContext(); 
	::wglMakeCurrent(NULL,NULL); 
	if(m_pDC) 
		delete m_pDC; 
	CView::OnDestroy(); 
} 
 
void CDelaunayView::DrawScene() 
{	 
	glClearColor(1.0f,1.0f,1.0f,1.0f);//setup backcolor 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    //GL_COLOR_BUFFER_BIT 用当前设置的backcolor 第一次清除 color buffer 
	// GL_DEPTH_BUFFER_BIT清除 depth buffer,以便进行depth test and 消除隐藏面 
	glClearDepth(1.0f); 
	glDepthFunc(GL_LESS); 
	glEnable(GL_DEPTH_TEST); 
	if(m_bMaterial){ 
		CreateMaterial(); 
		CreateLights(); 
	} 
	glColorMask(!m_bMaskRed,!m_bMaskGreen,!m_bMaskBlue,GL_TRUE); 
	glColor3f(m_colorRed,m_colorGreen,m_colorBlue); 
	glMatrixMode(GL_MODELVIEW);	 
	glLoadIdentity(); 
	glTranslated(m_translate_x,m_translate_y,m_translate_z);	 
	if(m_rotate_angle!=0.0){ 
		glRotated(m_rotate_angle,m_gl_x,m_gl_y,m_gl_z); 
	} 
	glScaled(2,2,0); 
//	glScaled((cx-2*m_ox)/cx,(cy-2*m_oy)/cy,0.0); 
	if(m_Dimension==DO_DRAW3){ 
	//	glPushMatrix(); 
	    gluLookAt(10.0,11.0,12.0,0.0,0.0,0.0,0.0,0.0,1.0);//eye.x,eye.y,eye.z 
		 
	//	glPopMatrix(); 
	} 
	glBegin(GL_LINE_STRIP); 
           glVertex3d(0.0,0.0,0.0); 
		   glVertex3d(0.0,1.0,0.0); 
		   glVertex3d(1.0,1.0,0.0); 
		   glVertex3d(1.0,0.0,0.0); 
		   glVertex3d(0.0,0.0,0.0); 
    glEnd();  
	glPushMatrix(); 
	if(m_Dimension==DO_DRAW2) 
		DrawPoints(); 
	if(m_Draw_what==DO_WANG && m_Dimension==DO_DRAW3) 
		m_pDoc->Wang(); 
	else	 
        DrawTris(); 
	glPopMatrix(); 
	glTranslated(0.5,0.5,0.0); 
 
//	glPushMatrix(); 
 
//	auxSolidSphere(0.5); 
 
//	glPopMatrix(); 
 
	glDisable(GL_LIGHTING); 
	glDisable(GL_LIGHT0); 
	glDisable(GL_DEPTH_TEST); 
//	glFinish(); 
} 
 
void CDelaunayView::InitOpenGl() 
{ 
	PIXELFORMATDESCRIPTOR pfd; 
    int n; 
	HGLRC hrc; 
	m_pDC=new CClientDC(this); 
	ASSERT(m_pDC!=NULL); 
	if(!bSetupPixelFormat()) return; 
	n=::GetPixelFormat(m_pDC->GetSafeHdc()); 
	::DescribePixelFormat(m_pDC->GetSafeHdc(),n,sizeof(pfd),&pfd); 
	hrc=wglCreateContext(m_pDC->GetSafeHdc()); 
	//create a instance of RC: hrc 
	wglMakeCurrent(m_pDC->GetSafeHdc(),hrc); 
	//make hrc a current Rendering context of a thread 
	GetClientRect(&m_oldRect);//get size of ClientRect 
} 
 
BOOL CDelaunayView::bSetupPixelFormat() 
{ 
	static PIXELFORMATDESCRIPTOR pfd={ 
		sizeof(PIXELFORMATDESCRIPTOR), 
			1, 
			PFD_DRAW_TO_WINDOW | 
			PFD_SUPPORT_OPENGL | 
			PFD_DOUBLEBUFFER, 
			PFD_TYPE_RGBA, 
			24,//24位真彩 
			0,0,0,0,0,0, 
			0, 
			0, 
			0, 
			0,0,0,0, 
			32,//32-bit z-buffer,可从物体中消除隐藏面 
			0, 
			0, 
			PFD_MAIN_PLANE,//选择主层面 
			0, 
			0,0,0 
	}; 
	int pixelformat; 
	 
	if((pixelformat=ChoosePixelFormat(m_pDC->GetSafeHdc(),&pfd))==0) 
	{ 
		MessageBox("ChoosePixelFormat failed"); 
		return FALSE; 
	} 
		 
	if(SetPixelFormat(m_pDC->GetSafeHdc(),pixelformat,&pfd)==FALSE) 
	{ 
		MessageBox("SetPixelFormat failed"); 
		return FALSE; 
	} 
		 
	return TRUE; 
	//CClientDC clientdc(this); 
	//int pf=ChoosePixelFormat(clientdc.m_hDC,&pfd); 
	//BOOL rt=SetPixelFormat(clientdc.m_hDC,pf,&pfd); 
	//hglrc=wglCreateContext(clientdc.m_hDC); 
} 
 
 
 
void CDelaunayView::DrawPoint(int i) 
{ 
	double x,y,z; 
	x=m_pDoc->m_point[i]->m_x; 
	y=m_pDoc->m_point[i]->m_y; 
	z=m_pDoc->m_point[i]->m_z; 
    glBegin(GL_POINTS); 
	glVertex3d(m_pDoc->m_point[i]->m_x,m_pDoc->m_point[i]->m_y,0.0); 
    glEnd(); 
} 
 
void CDelaunayView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)  
{ 
	switch(nChar) 
	{ 
	case VK_LEFT: 
		m_translate_x=m_translate_x-0.2; 
		break; 
	case VK_RIGHT: 
	    m_translate_x=m_translate_x+0.2; 
		break; 
	case VK_UP: 
		m_translate_y=m_translate_y+0.1; 
        break; 
	case VK_DOWN: 
		m_translate_y=m_translate_y-0.2; 
		break; 
	case 88://x 
		if(m_gl_x==0.0){  
            m_gl_x=0.1; 
		} 
		else{ 
			m_gl_x=0.0; 
		} 
		break; 
	case 89://y 
		if(m_gl_y==0.0){  
            m_gl_y=0.1; 
		} 
		else{ 
			m_gl_y=0.0; 
		} 
		break; 
	case 90://z 
		if(m_gl_z==0.0){  
            m_gl_z=0.1; 
		} 
		else{ 
			m_gl_z=0.0; 
		} 
		break; 
	case 100://小键盘的left 
		m_rotate_angle=m_rotate_angle-10.0; 
		break; 
	case 102://小键盘的right 
		m_rotate_angle=m_rotate_angle+10.0; 
		break; 
	case 104://小键盘的up 
		m_rotate_angle=m_rotate_angle+90.0; 
		break; 
	case 98://小键盘的down 
		m_rotate_angle=m_rotate_angle-90.0; 
		break; 
	case 65://a 
		eye.x=eye.x+1.0; 
		break; 
    case 83://s 
		eye.y=eye.y+1.0; 
		break; 
    case 68://d 
		eye.z=eye.z+1.0; 
		break; 
	default: 
		break; 
	}	 
	CView::OnKeyDown(nChar, nRepCnt, nFlags); 
    Invalidate(); 
} 
 
void CDelaunayView::DrawTris() 
{ 
	POSITION POS; 
	CTriangle* pTriangle; 
	POS = m_pDoc->m_tri.GetHeadPosition(); 
	if(m_Draw_what==DO_LINE) 
		glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 
    else{  
	    glPolygonMode(GL_FRONT,GL_FILL); 
	    glPolygonMode(GL_BACK,GL_FILL); 
	} 
	while(POS != NULL ){	 
		  DrawTri(m_pDoc->m_tri.GetAt(POS));	 
	      pTriangle=m_pDoc->m_tri.GetNext(POS); 
	}    
} 
 
void CDelaunayView::DrawPoints() 
{ 
	int max=m_pDoc->m_point.GetSize(); 
	glPointSize(6.0);	 
	for(int i=0;iSetCheck(1); 
	else  
		pCmdUI->SetCheck(0);	 
} 
 
void CDelaunayView::OnButtonThree()  
{ 
	m_Dimension=DO_DRAW3; 
	Invalidate(); 
} 
 
void CDelaunayView::OnUpdateButtonThree(CCmdUI* pCmdUI)  
{ 
    if(m_Dimension==DO_DRAW3) 
		pCmdUI->SetCheck(1); 
	else  
		pCmdUI->SetCheck(0); 
} 
 
void CDelaunayView::HCT(CTriangle *temp, int p) 
{//每次处理1/3三角形 
	m_hct[6].x=temp->m_x;//重心 
	m_hct[6].y=temp->m_y; 
	m_hct[6].z=temp->o; 
	if(p==3){ 
	    m_hct[0].x=m_pDoc->m_point[temp->m_p1]->m_x;//f1 
	    m_hct[0].y=m_pDoc->m_point[temp->m_p1]->m_y; 
	    m_hct[0].z=m_pDoc->m_point[temp->m_p1]->m_z; 
		 
		m_hct[9].x=m_pDoc->m_point[temp->m_p2]->m_x;//f2 
	    m_hct[9].y=m_pDoc->m_point[temp->m_p2]->m_y; 
	    m_hct[9].z=m_pDoc->m_point[temp->m_p2]->m_z;	 
 
	    m_hct[1]=PointOnEdge_3(m_hct[0].x,m_hct[0].y,m_hct[6].x,m_hct[6].y);//c1 
	    m_hct[1].z=temp->c1;//c1 
	    m_hct[2]=PointOnEdge_3(m_hct[0].x,m_hct[0].y,m_hct[9].x,m_hct[9].y);//d31 
        m_hct[2].z=temp->d31;//d31 
        m_hct[4]=PointOnEdge_3(m_hct[6].x,m_hct[6].y,m_hct[0].x,m_hct[0].y);//b1 
        m_hct[4].z=temp->b1;//b1 
        m_hct[3]=BaryCenter(m_hct[0].x,m_hct[0].y,0,m_hct[9].x,m_hct[9].y,0, 
							 m_hct[6].x,m_hct[6].y,0);//e3 
        m_hct[3].z=temp->e3;//e3 
        m_hct[5]=PointOnEdge_3(m_hct[6].x,m_hct[6].y,m_hct[9].x,m_hct[9].y);//b2 
        m_hct[5].z=temp->b2;//b2 
		m_hct[7]=PointOnEdge_3(m_hct[9].x,m_hct[9].y,m_hct[6].x,m_hct[6].y);//c2 
        m_hct[7].z=temp->c2;//c2 
		m_hct[8]=PointOnEdge_3(m_hct[9].x,m_hct[9].y,m_hct[0].x,m_hct[0].y);//d32 
        m_hct[8].z=temp->d32;//d32 
	} 
 
	if(p==2){ 
	    m_hct[0].x=m_pDoc->m_point[temp->m_p1]->m_x;//f1 
	    m_hct[0].y=m_pDoc->m_point[temp->m_p1]->m_y; 
	    m_hct[0].z=m_pDoc->m_point[temp->m_p1]->m_z; 
		m_hct[9].x=m_pDoc->m_point[temp->m_p3]->m_x;//f3 
	    m_hct[9].y=m_pDoc->m_point[temp->m_p3]->m_y; 
	    m_hct[9].z=m_pDoc->m_point[temp->m_p3]->m_z; 
 
	    m_hct[1]=PointOnEdge_3(m_hct[0].x,m_hct[0].y,m_hct[6].x,m_hct[6].y);//c1 
	    m_hct[1].z=temp->c1;//c1 
	    m_hct[2]=PointOnEdge_3(m_hct[0].x,m_hct[0].y,m_hct[9].x,m_hct[9].y);//d21 
        m_hct[2].z=temp->d21; 
        
		m_hct[4]=PointOnEdge_3(m_hct[6].x,m_hct[6].y,m_hct[0].x,m_hct[0].y);//b1 
        m_hct[4].z=temp->b1;//b1 
        m_hct[3]=BaryCenter(m_hct[0].x,m_hct[0].y,0,m_hct[6].x,m_hct[6].y,0, 
							 m_hct[9].x,m_hct[9].y,0);//e2 
        m_hct[3].z=temp->e2;//e2 
        
		m_hct[5]=PointOnEdge_3(m_hct[6].x,m_hct[6].y,m_hct[9].x,m_hct[9].y);//b3 
        m_hct[5].z=temp->b3;//b3 
		m_hct[7]=PointOnEdge_3(m_hct[9].x,m_hct[9].y,m_hct[6].x,m_hct[6].y);//c3 
        m_hct[7].z=temp->c3;//c3 
		m_hct[8]=PointOnEdge_3(m_hct[9].x,m_hct[9].y,m_hct[0].x,m_hct[0].y);//d23 
        m_hct[8].z=temp->d23;//d23 
	} 
	if(p==1){ 
	    m_hct[0].x=m_pDoc->m_point[temp->m_p2]->m_x;//f2 
	    m_hct[0].y=m_pDoc->m_point[temp->m_p2]->m_y; 
	    m_hct[0].z=m_pDoc->m_point[temp->m_p2]->m_z; 
		m_hct[9].x=m_pDoc->m_point[temp->m_p3]->m_x;//f3 
	    m_hct[9].y=m_pDoc->m_point[temp->m_p3]->m_y; 
	    m_hct[9].z=m_pDoc->m_point[temp->m_p3]->m_z; 
	 
	    m_hct[1]=PointOnEdge_3(m_hct[0].x,m_hct[0].y,m_hct[6].x,m_hct[6].y);//c2 
	    m_hct[1].z=temp->c2;//c2 
	    m_hct[2]=PointOnEdge_3(m_hct[0].x,m_hct[0].y,m_hct[9].x,m_hct[9].y);//d12 
        m_hct[2].z=temp->d12;//d12 
        
		m_hct[4]=PointOnEdge_3(m_hct[6].x,m_hct[6].y,m_hct[0].x,m_hct[0].y);//b2 
        m_hct[4].z=temp->b2;//b2 
        m_hct[3]=BaryCenter(m_hct[0].x,m_hct[0].y,0,m_hct[9].x,m_hct[9].y,0, 
							 m_hct[6].x,m_hct[6].y,0);//e1 
        m_hct[3].z=temp->e1;//e1 
         
		m_hct[5]=PointOnEdge_3(m_hct[6].x,m_hct[6].y,m_hct[9].x,m_hct[9].y);//b3 
        m_hct[5].z=temp->b3;//b3 
		m_hct[7]=PointOnEdge_3(m_hct[9].x,m_hct[9].y,m_hct[6].x,m_hct[6].y);//c3 
        m_hct[7].z=temp->c3;//c3 
		m_hct[8]=PointOnEdge_3(m_hct[9].x,m_hct[9].y,m_hct[0].x,m_hct[0].y);//d13 
        m_hct[8].z=temp->d13;//d13 
	} 
	b[0][0][3]=m_hct[6].z;b[0][3][0]=m_hct[9].z;b[3][0][0]=m_hct[0].z; 
		 
	b[0][1][2]=m_hct[5].z;b[0][2][1]=m_hct[7].z; 
		 
	b[1][0][2]=m_hct[4].z;b[2][0][1]=m_hct[1].z; 
		 
	b[2][1][0]=m_hct[2].z;b[1][2][0]=m_hct[8].z;b[1][1][1]=m_hct[3].z; 
     
	for(int i=1;i<9;i++){ 
		if(i!=6){ 
			m_hct[i].z=Bezier(m_hct[i]);//得到所有细分点的z值 
		} 
	} 
} 
 
POI CDelaunayView::BaryCenter(double x1, double y1,double z1,double x2, double y2,double z2,double x3, double y3,double z3) 
{//平面上三角形重心 
	POI temp; 
    temp.x=(x1+x2+x3)/double(3); 
	temp.y=(y1+y2+y3)/double(3); 
	temp.z=(z1+z2+z3)/double(3); 
    return temp; 
} 
 
POI CDelaunayView::PointOnEdge_3(double x1, double y1, double x2, double y2) 
{ 
	POI temp; 
	temp.x=x1+(x2-x1)/double(3); 
	temp.y=y1+(y2-y1)/double(3); 
	return temp; 
} 
 
void CDelaunayView::OnButtonHct()  
{ 
	if(m_HCT==DO_HCT) 
	    m_HCT=-1; 
	else 
		m_HCT=DO_HCT; 
} 
 
void CDelaunayView::OnUpdateButtonHct(CCmdUI* pCmdUI)  
{ 
     
} 
 
void CDelaunayView::OnButtonFill()  
{ 
    m_Draw_what=DO_FILL;	 
} 
 
void CDelaunayView::OnUpdateButtonFill(CCmdUI* pCmdUI)  
{ 
	if(m_Draw_what==DO_FILL) 
		pCmdUI->SetCheck(1); 
	else  
		pCmdUI->SetCheck(0); 
	 
} 
 
void CDelaunayView::OnButtonLine()  
{ 
	m_Draw_what=DO_LINE; 
} 
 
void CDelaunayView::OnUpdateButtonLine(CCmdUI* pCmdUI)  
{ 
    if(m_Draw_what==DO_LINE) 
		pCmdUI->SetCheck(1); 
	else  
		pCmdUI->SetCheck(0); 
} 
 
POI CDelaunayView::GetTriNormal(POI p1, POI p2, POI p3) 
{	//得到三角片的单位法向 
	POI vector1,vector2,Normal; 
    /*POI p; 
	double s; 
	s=S(p1,p2,p3); 
	if(s<0){ 
		p=p2;p2=p3;p3=p; 
	}*/ 
	vector1.x=p2.x-p1.x; 
	vector1.y=p2.y-p1.y; 
	vector1.z=p2.z-p1.z; 
	vector2.x=p3.x-p1.x; 
	vector2.y=p3.y-p1.y; 
	vector2.z=p3.z-p1.z; 
    //get the normal n=a*b(外积) 
	Normal=m_pDoc->VectorProduct(vector1.x,vector1.y,vector1.z,vector2.x,vector2.y,vector2.z); 
	//单位化 normal 
	Normal=m_pDoc->Unitization(Normal); 
    return Normal; 
} 
 
 
double CDelaunayView::S(POI p1, POI p2, POI p3) 
{	//求三角形面积,以右下角为原点时,s>0为逆时针(左转), 
  	//s=0为三点重合 
  	double s; 
  	s=p1.x*p2.y+p2.x*p3.y+p1.y*p3.x-p2.y*p3.x-p1.y*p2.x-p1.x*p3.y; 
  	s=s/2.0; 
  	return s; 
} 
 
int CDelaunayView::Factorial(int n) 
{//阶乘 
	int x=n; 
	if(n==0 ||n==1)  
		return 1; 
	else{		 
		for(int i=1;i