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