www.pudn.com > ProjectionTransformWork.rar > WorkView.cpp


// WorkView.cpp : implementation of the CWorkView class 
// 
 
#include "stdafx.h" 
#include "Work.h" 
 
#include "WorkDoc.h" 
#include "WorkView.h" 
 
#include "ParDlg.h" 
#include "Math.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CWorkView 
 
IMPLEMENT_DYNCREATE(CWorkView, CView) 
 
BEGIN_MESSAGE_MAP(CWorkView, CView) 
	//{{AFX_MSG_MAP(CWorkView) 
	ON_COMMAND(IDM_TOUYING, OnTouying) 
	//}}AFX_MSG_MAP 
	// Standard printing commands 
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint) 
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CWorkView construction/destruction 
 
CWorkView::CWorkView() 
{ 
	// TODO: add construction code here 
 
	////////////////////////////////////////////////////////////////////////// 
	//变量初始化 
	m_DrawType=-1; 
	 
	int i=0,j=0; 
	m_X[0]=0;m_Y[0]=0;m_Z[0]=0;m_C[0]=1;		//图形在世界坐标下的初始值 
	m_X[1]=100;m_Y[1]=0;m_Z[1]=0;m_C[1]=1; 
	m_X[2]=100;m_Y[2]=0;m_Z[2]=-130;m_C[2]=1; 
	m_X[3]=0;m_Y[3]=0;m_Z[3]=-130;m_C[3]=1; 
	m_X[4]=0;m_Y[4]=80;m_Z[4]=-130;m_C[4]=1; 
	m_X[5]=100;m_Y[5]=80;m_Z[5]=-130;m_C[5]=1; 
	m_X[6]=100;m_Y[6]=80;m_Z[6]=-90;m_C[6]=1; 
	m_X[7]=100;m_Y[7]=20;m_Z[7]=-90;m_C[7]=1; 
	m_X[8]=100;m_Y[8]=20;m_Z[8]=-0;m_C[8]=1; 
	m_X[9]=30;m_Y[9]=20;m_Z[9]=0;m_C[9]=1; 
	m_X[10]=30;m_Y[10]=20;m_Z[10]=-90;m_C[10]=1; 
	m_X[11]=30;m_Y[11]=80;m_Z[11]=-90;m_C[11]=1; 
	m_X[12]=30;m_Y[12]=80;m_Z[12]=0;m_C[12]=1; 
	m_X[13]=0;m_Y[13]=80;m_Z[13]=0;m_C[13]=1; 
	 
 
	for (i=0;i<4;i++) 
	{ 
		for (j=0;j<4;j++) 
		{ 
			m_Change[i][j]=0; 
			m_GraChange[i][j]=0; 
			 
		} 
	} 
} 
 
CWorkView::~CWorkView() 
{ 
} 
 
BOOL CWorkView::PreCreateWindow(CREATESTRUCT& cs) 
{ 
	// TODO: Modify the Window class or styles here by modifying 
	//  the CREATESTRUCT cs 
 
	return CView::PreCreateWindow(cs); 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CWorkView drawing 
 
void CWorkView::OnDraw(CDC* pDC) 
{ 
	CWorkDoc* pDoc = GetDocument(); 
	ASSERT_VALID(pDoc); 
	// TODO: add draw code for native data here 
 
	////////////////////////////////////////////////////////////// 
	//输出所绘图形类型 
	if (m_DrawType==0) 
	{ 
		pDC->TextOut(100,100,"投影图1"); 
	} 
	else if (m_DrawType==1) 
	{ 
		pDC->TextOut(100,100,"俯视图"); 
	} 
	else if (m_DrawType==2) 
	{ 
		pDC->TextOut(100,100,"等轴测图"); 
	} 
	else if (m_DrawType==3) 
	{ 
			if (m_VPNx==0&&m_VPNy==0&&m_VPNz==1) 
				pDC->TextOut(100,100,"一点透视图"); 
			else if (m_VPNx==0&&m_VPNy==1&&m_VPNz==0) 
				pDC->TextOut(100,100,"一点透视图"); 
			else if (m_VPNx==1&&m_VPNy==0&&m_VPNz==0) 
				pDC->TextOut(100,100,"一点透视图"); 
			else if (m_VPNx==1&&m_VPNy==1&&m_VPNz==0) 
				pDC->TextOut(100,100,"两点透视图"); 
			else if (m_VPNx==0&&m_VPNy==1&&m_VPNz==1) 
				pDC->TextOut(100,100,"两点透视图"); 
			else if (m_VPNx==1&&m_VPNy==0&&m_VPNz==1) 
				pDC->TextOut(100,100,"两点透视图"); 
			else if (m_VPNx==1&&m_VPNy==1&&m_VPNz==1) 
				pDC->TextOut(100,100,"三点透视图"); 
	} 
	 
	 
	 
	DoGraphChange();		//调用投影变换函数 
	 
	////////////////////////////////////////////////// 
	//绘制图形 
 
	pDC->MoveTo(m_X1[0],m_Y1[0]); 
	for (int i=1;i<14;i++) 
	{ 
		pDC->LineTo(m_X1[i],m_Y1[i]); 
	} 
	 
	pDC->MoveTo(m_X1[0],m_Y1[0]); 
	pDC->LineTo(m_X1[3],m_Y1[3]); 
	pDC->MoveTo(m_X1[0],m_Y1[0]); 
	pDC->LineTo(m_X1[13],m_Y1[13]); 
	pDC->MoveTo(m_X1[1],m_Y1[1]); 
	pDC->LineTo(m_X1[8],m_Y1[8]); 
	pDC->MoveTo(m_X1[2],m_Y1[2]); 
	pDC->LineTo(m_X1[5],m_Y1[5]); 
	pDC->MoveTo(m_X1[4],m_Y1[4]); 
	pDC->LineTo(m_X1[13],m_Y1[13]); 
	pDC->MoveTo(m_X1[6],m_Y1[6]); 
	pDC->LineTo(m_X1[11],m_Y1[11]); 
	pDC->MoveTo(m_X1[7],m_Y1[7]); 
	pDC->LineTo(m_X1[10],m_Y1[10]); 
	pDC->MoveTo(m_X1[9],m_Y1[9]); 
	pDC->LineTo(m_X1[12],m_Y1[12]);	 
 
	 
 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CWorkView printing 
 
BOOL CWorkView::OnPreparePrinting(CPrintInfo* pInfo) 
{ 
	// default preparation 
	return DoPreparePrinting(pInfo); 
} 
 
void CWorkView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add extra initialization before printing 
} 
 
void CWorkView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) 
{ 
	// TODO: add cleanup after printing 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CWorkView diagnostics 
 
#ifdef _DEBUG 
void CWorkView::AssertValid() const 
{ 
	CView::AssertValid(); 
} 
 
void CWorkView::Dump(CDumpContext& dc) const 
{ 
	CView::Dump(dc); 
} 
 
CWorkDoc* CWorkView::GetDocument() // non-debug version is inline 
{ 
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWorkDoc))); 
	return (CWorkDoc*)m_pDocument; 
} 
#endif //_DEBUG 
 
 
void CWorkView::OnTouying()  
{ 
	// TODO: Add your command handler code here 
 
 
	////////////////////////////////////////////////////////////////////////// 
	//响应“投影变换”菜单项 
	 
	if (m_ParDlg.DoModal()==IDOK) 
 	{ 
		m_DrawType=m_ParDlg.m_DrawType;		//用CWorkView类的成员变量m_DrawType接收CParDlg类的成员变量m_DrawType,来判断投影类型 
		m_VRPx=m_ParDlg.m_VRPx;				//接收参数设置对话框传递的参数 
		m_VRPy=m_ParDlg.m_VRPy; 
		m_VRPz=m_ParDlg.m_VRPz; 
		m_VPNx=m_ParDlg.m_VPNx; 
		m_VPNy=m_ParDlg.m_VPNy; 
		m_VPNz=m_ParDlg.m_VPNz; 
		m_VUPx=m_ParDlg.m_VUPx; 
		m_VUPy=m_ParDlg.m_VUPy; 
		m_VUPz=m_ParDlg.m_VUPz; 
		m_PRPx=m_ParDlg.m_PRPx; 
		m_PRPy=m_ParDlg.m_PRPy; 
		m_PRPz=m_ParDlg.m_PRPz; 
		Invalidate(); 
 	} 
} 
 
void CWorkView::DoChange()	//	把图形在世界坐标系下的坐标转化到观察坐标系下 
{	 
	if (m_DrawType!=-1) 
	{ 
		///////////////////////////////////////////////////////////////////// 
		//根据对话框传递的参数计算坐标系变换矩阵m_Change[4][4] 
		double x=0,y=0,z=0,m=0; 
		m_Nx=m_VPNx/sqrt(m_VPNx*m_VPNx+m_VPNy*m_VPNy+m_VPNz*m_VPNz); 
		m_Ny=m_VPNy/sqrt(m_VPNx*m_VPNx+m_VPNy*m_VPNy+m_VPNz*m_VPNz); 
		m_Nz=m_VPNz/sqrt(m_VPNx*m_VPNx+m_VPNy*m_VPNy+m_VPNz*m_VPNz); 
 
		x=m_VUPy*m_VPNz-m_VUPz*m_VPNy; 
		y=m_VUPz*m_VPNx-m_VUPx*m_VPNz; 
		z=m_VUPx*m_VPNy-m_VUPy*m_VPNx; 
		m_Ux=x/sqrt(x*x+y*y+z*z); 
		m_Uy=y/sqrt(x*x+y*y+z*z); 
		m_Uz=z/sqrt(x*x+y*y+z*z); 
 
		m_Vx=m_Ny*m_Uz-m_Nz*m_Uy; 
		m_Vy=m_Nz*m_Ux-m_Nx*m_Uz; 
		m_Vz=m_Nx*m_Uy-m_Ny*m_Ux; 
 
		m_Change[0][0]=m_Ux; 
		m_Change[0][1]=m_Uy; 
		m_Change[0][2]=m_Uz; 
		m_Change[0][3]=-(m_Ux*m_VRPx+m_Uy*m_VRPy+m_Uz*m_VRPz); 
		 
		m_Change[1][0]=m_Vx; 
		m_Change[1][1]=m_Vy; 
		m_Change[1][2]=m_Vz; 
		m_Change[1][3]=-(m_Vx*m_VRPx+m_Vy*m_VRPy+m_Vz*m_VRPz); 
		 
		m_Change[2][0]=m_Nx; 
		m_Change[2][1]=m_Ny; 
		m_Change[2][2]=m_Nz; 
		m_Change[2][3]=-(m_Nx*m_VRPx+m_Ny*m_VRPy+m_Nz*m_VRPz); 
 
		m_Change[3][3]=1; 
 
		/////////////////////////////////////////////////////////////////////////// 
		//坐标系转换 
		 
		for (int i=0;i<14;i++) 
		{ 
			m_X1[i]=(int)(m_Change[0][0]*m_X[i]+m_Change[0][1]*m_Y[i]+m_Change[0][2]*m_Z[i]+m_Change[0][3]*m_C[i]); 
			m_Y1[i]=(int)(m_Change[1][0]*m_X[i]+m_Change[1][1]*m_Y[i]+m_Change[1][2]*m_Z[i]+m_Change[1][3]*m_C[i]); 
			m_Z1[i]=(int)(m_Change[2][0]*m_X[i]+m_Change[2][1]*m_Y[i]+m_Change[2][2]*m_Z[i]+m_Change[2][3]*m_C[i]); 
			m=m_Change[3][0]*m_X[i]+m_Change[3][1]*m_Y[i]+m_Change[3][2]*m_Z[i]+m_Change[3][3]*m_C[i]; 
 
			m_X1[i]=(int)(m_X1[i]/m); 
			m_Y1[i]=(int)(m_Y1[i]/m); 
			m_Z1[i]=(int)(m_Z1[i]/m); 
 
		} 
 
	} 
} 
 
void CWorkView::DoGraphChange()	//	进行图形的投影变换 
{	 
	DoChange(); 
	double K=0; 
	if (m_DrawType!=3)			//进行平行投影变换 
	{ 
		m_GraChange[0][0]=1; 
		m_GraChange[1][1]=1; 
		m_GraChange[3][3]=1; 
 
		for (int i=0;i<14;i++) 
	{ 
		m_X1[i]=(int)(m_GraChange[0][0]*m_X1[i]+m_GraChange[0][1]*m_Y1[i]+m_GraChange[0][2]*m_Z1[i]+m_GraChange[0][3]*m_C[i]); 
		m_Y1[i]=(int)(m_GraChange[1][0]*m_X1[i]+m_GraChange[1][1]*m_Y1[i]+m_GraChange[1][2]*m_Z1[i]+m_GraChange[1][3]*m_C[i]); 
		m_Z1[i]=(int)(m_GraChange[2][0]*m_X1[i]+m_GraChange[2][1]*m_Y1[i]+m_GraChange[2][2]*m_Z1[i]+m_GraChange[2][3]*m_C[i]); 
		K=(int)(m_GraChange[3][0]*m_X1[i]+m_GraChange[3][1]*m_Y1[i]+m_GraChange[3][2]*m_Z1[i]+m_GraChange[3][3]*m_C[i]); 
 
		m_X1[i]=(int)(m_X1[i]/K*2+300); 
		m_Y1[i]=(int)(-m_Y1[i]/K*2+300); 
		m_Z1[i]=(int)(m_Z1[i]/K*2+300); 
 
	} 
	} 
	else if (m_DrawType==3)			//进行透视投影变换 
	{ 
	/*	m_GraChange[0][0]=1; 
		m_GraChange[0][2]=-m_PRPx/m_PRPz; 
		m_GraChange[1][1]=1; 
		m_GraChange[1][2]=-m_PRPy/m_PRPz; 
		m_GraChange[3][2]=-1/m_PRPz;		 
		m_GraChange[3][3]=1; 
	*/ 
		for (int i=0;i<14;i++) 
		{ 
		 
			K=m_Z1[i]-m_PRPz;		//投影中心为(m_PRPx,m_PRPy,m_PRPz) 
			m_X1[i]=(int)((m_Z1[i]*m_PRPx-m_X1[i]*m_PRPz)/K); 
			m_Y1[i]=(int)((m_Z1[i]*m_PRPy-m_Y1[i]*m_PRPz)/K); 
 
			m_X1[i]=m_X1[i]*2+300; 
			m_Y1[i]=-m_Y1[i]*2+300; 
		} 
	} 
	 
 
}