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;
}
}
}