MFC单文档应用程序
Edge.h#if !defined(AFX_EDGE_H__7A2836FC_0998_48C2_9107_57134BD7E4B1__INCLUDED_)
#define AFX_EDGE_H__7A2836FC_0998_48C2_9107_57134BD7E4B1__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif
class Edge
{
public:
Edge();
virtual ~Edge();
double x;
int yMax;
double k;
Edge *next;
};
#endif
Bucket.h#if !defined(AFX_BUCKET_H__A2F5FA20_BB33_4949_8C03_F82DE5D8454B__INCLUDED_)
#define AFX_BUCKET_H__A2F5FA20_BB33_4949_8C03_F82DE5D8454B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif
#include "Edge.h"
class Bucket
{
public:
Bucket();
virtual ~Bucket();
int ScanLine;
Edge *p;
Bucket *next;
};
#endif
MyView.h
#pragma once
#include "Edge.h"
#include "Bucket.h"
#define Number 4
struct MyPoint
{
int x;
int y;
double z;
};
struct CBox
{
MyPoint m_Point[8];
};
class CMyView : public CView
{
protected: // create from serialization only
CMyView();
DECLARE_DYNCREATE(CMyView)
// Attributes
public:
CMyDoc* GetDocument();public:
void ReadPoint();
void ReadColor();
void ReadFace();
void PolygonFill(CDC*);
void CreatBucket();
void Et();
void AddAet(Edge *);
void AetOrder();
bool m_Paint(CDC*);
void Angle();
void Sign(CDC* mdc);
void ZBuffer(CDC* MemDC);
public:
virtual void OnDraw(CDC* pDC);
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
public:
virtual ~CMyView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
MyPoint Point[4];
int F[6][5];
Bucket *CurrentB,*HeadB;
Edge E[Number],*CurrentE,*HeadE,*T1,*T2;
int m_AngleX,m_AngleY;
CBox m_Box;
CBox m_OldBox;
CDC Picture;
COLORREF RGB[6];
int Face;
double ZB[401][401];protected:
//{{AFX_MSG(CMyView)
afx_msg void OnMenuReset();
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
Edge.h#if !defined(AFX_EDGE_H__7A2836FC_0998_48C2_9107_57134BD7E4B1__INCLUDED_)
#define AFX_EDGE_H__7A2836FC_0998_48C2_9107_57134BD7E4B1__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif
class Edge
{
public:
Edge();
virtual ~Edge();
double x;
int yMax;
double k;
Edge *next;
};
#endif
Bucket.h#if !defined(AFX_BUCKET_H__A2F5FA20_BB33_4949_8C03_F82DE5D8454B__INCLUDED_)
#define AFX_BUCKET_H__A2F5FA20_BB33_4949_8C03_F82DE5D8454B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif
#include "Edge.h"
class Bucket
{
public:
Bucket();
virtual ~Bucket();
int ScanLine;
Edge *p;
Bucket *next;
};
#endif
MyView.h
#pragma once
#include "Edge.h"
#include "Bucket.h"
#define Number 4
struct MyPoint
{
int x;
int y;
double z;
};
struct CBox
{
MyPoint m_Point[8];
};
class CMyView : public CView
{
protected: // create from serialization only
CMyView();
DECLARE_DYNCREATE(CMyView)
// Attributes
public:
CMyDoc* GetDocument();public:
void ReadPoint();
void ReadColor();
void ReadFace();
void PolygonFill(CDC*);
void CreatBucket();
void Et();
void AddAet(Edge *);
void AetOrder();
bool m_Paint(CDC*);
void Angle();
void Sign(CDC* mdc);
void ZBuffer(CDC* MemDC);
public:
virtual void OnDraw(CDC* pDC);
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
public:
virtual ~CMyView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
MyPoint Point[4];
int F[6][5];
Bucket *CurrentB,*HeadB;
Edge E[Number],*CurrentE,*HeadE,*T1,*T2;
int m_AngleX,m_AngleY;
CBox m_Box;
CBox m_OldBox;
CDC Picture;
COLORREF RGB[6];
int Face;
double ZB[401][401];protected:
//{{AFX_MSG(CMyView)
afx_msg void OnMenuReset();
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
MyView.cpp#include "stdafx.h"
#include "MyApp.h"
#include "MyDoc.h"
#include "MyView.h"
#define ROUND(a) int(a+0.5)
#include "cmath"
#define PI 3.1415926#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endifIMPLEMENT_DYNCREATE(CMyView, CView)
BEGIN_MESSAGE_MAP(CMyView, CView)
//{{AFX_MSG_MAP(CMyView)
ON_COMMAND(ID_Z_BUFFER, OnMenuReset)
ON_WM_KEYDOWN()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
// Standard printing commandsEND_MESSAGE_MAP()CMyView::CMyView()
{
m_AngleX=0;
m_AngleY=0;
}
CMyView::~CMyView()
{
}
BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs)
{
return CView::PreCreateWindow(cs);
}BOOL CMyView::OnEraseBkgnd(CDC* pDC)
{
return true;
}
void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CRect Rect;
pDC->GetClipBox(Rect);
pDC->FillSolidRect(Rect,RGB(0,0,0));
ReadPoint();
ReadFace();
ReadColor();
ZBuffer(pDC);
}#ifdef _DEBUG
void CMyView::AssertValid() const
{
CView::AssertValid();
}
void CMyView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMyDoc* CMyView::GetDocument()
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyDoc)));
return (CMyDoc*)m_pDocument;
}
#endif
void CMyView::ZBuffer(CDC* MemDC)
{
CRect Rect;
GetClientRect(&Rect);
CClientDC dc(this);
dc.SetMapMode(MM_ANISOTROPIC);
dc.SetWindowExt(Rect.Width(),Rect.Height());
dc.SetViewportExt(Rect.right,-Rect.bottom);
dc.SetViewportOrg(Rect.right/2,Rect.bottom/2); MemDC->GetClipBox(Rect);
MemDC->FillSolidRect(Rect,RGB(0,0,0)); CBitmap Bitmap,*OldBitmap;
Bitmap.LoadBitmap(IDB_BIT2);
OldBitmap=MemDC->SelectObject(&Bitmap); m_Paint(MemDC); MemDC->SelectObject(OldBitmap);
}
void CMyView::OnMenuReset()
{
m_AngleX=m_AngleY=0;
Angle();
RedrawWindow();
}
void CMyView::ReadPoint()
{
m_OldBox.m_Point[0].x=-100;
m_OldBox.m_Point[0].y=-100;
m_OldBox.m_Point[0].z=+100; m_OldBox.m_Point[1].x=+100;
m_OldBox.m_Point[1].y=-100;
m_OldBox.m_Point[1].z=+100; m_OldBox.m_Point[2].x=+100;
m_OldBox.m_Point[2].y=-100;
m_OldBox.m_Point[2].z=-100; m_OldBox.m_Point[3].x=-100;
m_OldBox.m_Point[3].y=-100;
m_OldBox.m_Point[3].z=-100; m_OldBox.m_Point[4].x=-100;
m_OldBox.m_Point[4].y=+100;
m_OldBox.m_Point[4].z=+100; m_OldBox.m_Point[5].x=+100;
m_OldBox.m_Point[5].y=+100;
m_OldBox.m_Point[5].z=+100; m_OldBox.m_Point[6].x=+100;
m_OldBox.m_Point[6].y=+100;
m_OldBox.m_Point[6].z=-100; m_OldBox.m_Point[7].x=-100;
m_OldBox.m_Point[7].y=+100;
m_OldBox.m_Point[7].z=-100;
}
void CMyView::ReadFace()
{
F[0][0]=4;F[0][1]=0;F[0][2]=1;F[0][3]=2;F[0][4]=3;
F[1][0]=4;F[1][1]=0;F[1][2]=3;F[1][3]=7;F[1][4]=4;
F[2][0]=4;F[2][1]=0;F[2][2]=1;F[2][3]=5;F[2][4]=4;
F[3][0]=4;F[3][1]=1;F[3][2]=2;F[3][3]=6;F[3][4]=5;
F[4][0]=4;F[4][1]=4;F[4][2]=5;F[4][3]=6;F[4][4]=7;
F[5][0]=4;F[5][1]=3;F[5][2]=2;F[5][3]=6;F[5][4]=7;
}
void CMyView::ReadColor()
{
RGB[0]=RGB(255,255,0);
RGB[1]=RGB(0,255,255);
RGB[2]=RGB(0,0,255);
RGB[3]=RGB(0,255,0);
RGB[4]=RGB(255,0,0);
RGB[5]=RGB(255,0,255);
}
bool CMyView::m_Paint(CDC* mdc)
{
Sign(mdc);
Angle();
for(int i=0;i<=400;i++)
for(int j=0;j<=400;j++)
ZB[i][j]=-500;
for(Face=0;Face<6;Face++)
{
int TotalEdge=F[Face][0];
for(int edge=1;edge<=TotalEdge;edge++)
{
int PointNumber=F[Face][edge];
Point[edge-1]=m_Box.m_Point[PointNumber];
}
mdc->SelectObject (CBrush(RGB[Face]));
CreatBucket();
Et();
PolygonFill(mdc);
}
return true;
}
void CMyView::Angle()
{
for(int i=0;i<8;i++)
{
MyPoint TmpPoint; TmpPoint.x=m_OldBox.m_Point[i].x; TmpPoint.y=ROUND(m_OldBox.m_Point[i].y*cos(m_AngleX*PI/180)+m_OldBox.m_Point[i].z*sin(m_AngleX*PI/180)); TmpPoint.z=ROUND(-m_OldBox.m_Point[i].y*sin(m_AngleX*PI/180)+m_OldBox.m_Point[i].z*cos(m_AngleX*PI/180)); m_Box.m_Point[i].x=ROUND(-TmpPoint.z*sin(m_AngleY*PI/180)+TmpPoint.x*cos(m_AngleY*PI/180));
m_Box.m_Point[i].y=TmpPoint.y; m_Box.m_Point[i].z=TmpPoint.z*cos(m_AngleY*PI/180)+TmpPoint.x*sin(m_AngleY*PI/180);
}
}void CMyView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch(nChar)
{
case VK_UP:
m_AngleX+=1;
break;
case VK_DOWN:
m_AngleX-=1;
break;
case VK_LEFT:
m_AngleY+=1;
break;
case VK_RIGHT:
m_AngleY-=1;
break;
default:
break;
}
if (m_AngleX>=360)
{
m_AngleX-=360;
}
else if (m_AngleX<0)
{
m_AngleX=360+m_AngleX;
}
if (m_AngleY>=360)
{
m_AngleY-=360;
}
else if (m_AngleY<0)
{
m_AngleY=360+m_AngleY;
}
ZBuffer(GetDC());
CView::OnKeyDown(nChar,nRepCnt,nFlags);
}
void CMyView::Sign(CDC* mdc)
{
CPoint p1[4];
mdc->SetBkColor(RGB(0,0,0));
mdc->SetTextColor(RGB(255,255,255));
CBrush MyBrush,*OldBrush;
for(int i=0;i<6;i++)
{
MyBrush.CreateSolidBrush(RGB[i]);
OldBrush=mdc->SelectObject(&MyBrush);
p1[0].x=-450;p1[0].y=280-i*20;
p1[1].x=-430;p1[1].y=280-i*20;
p1[2].x=-430;p1[2].y=265-i*20;
p1[3].x=-450;p1[3].y=265-i*20;
mdc->Polygon(p1,4);
mdc->SelectObject(OldBrush);
MyBrush.DeleteObject();
}
}
{ double CurDeep=0.0;
double DeepStep=0.0;
double A=0.0;
double B=0.0;
double C=0.0;
double D=0.0;
A=(Point[1].y-Point[2].y)*(Point[1].z-Point[3].z)-(Point[1].y-Point[3].y)*(Point[1].z-Point[2].z);
B=(Point[1].x-Point[3].x)*(Point[1].z-Point[2].z)-(Point[1].z-Point[3].z)*(Point[1].x-Point[2].x);
C=(Point[1].x-Point[2].x)*(Point[1].y-Point[3].y)-(Point[1].x-Point[3].x)*(Point[1].y-Point[2].y);
D=-A*Point[1].x-B*Point[1].y-C*Point[1].z;
DeepStep=-A/C;
HeadE=NULL;
for(CurrentB=HeadB;CurrentB!=NULL;CurrentB=CurrentB->next)
{
for(CurrentE=CurrentB->p;CurrentE!=NULL;CurrentE=CurrentE->next)
{
Edge *TEdge=new Edge;
TEdge->x=CurrentE->x;
TEdge->yMax=CurrentE->yMax;
TEdge->k=CurrentE->k;
TEdge->next=NULL;
AddAet(TEdge);
}
AetOrder();
T1=HeadE;
if(T1==NULL)
{
return;
}
while(CurrentB->ScanLine>=T1->yMax)
{
T1=T1->next;
HeadE=T1;
if(HeadE==NULL)
{
return;
}
}
if(T1->next!=NULL)
{
T2=T1;
T1=T2->next;
}
while(T1!=NULL)
{
if(CurrentB->ScanLine>=T1->yMax)
{
T2->next=T1->next;
T1->next=NULL;
T1=T2->next;
}
else
{
T2=T1;
T1=T2->next;
}
}
BOOL In=false;
double xb,xe;
for(T1=HeadE;T1!=NULL;T1=T1->next)
{
if(In==false)
{
xb=T1->x;
CurDeep=-(xb*A+CurrentB->ScanLine*B+D)/C;
In=true;
}
else
{
xe=T1->x;
for(double x=xb;x<=xe;x++)
{
if(CurDeep>=ZB[ROUND(x)+200][CurrentB->ScanLine+200]) {
ZB[ROUND(x)+200][CurrentB->ScanLine+200]=CurDeep; mdc->SetPixel(ROUND(x+400),CurrentB->ScanLine+400,RGB[Face]);
}
CurDeep+=DeepStep;
}
In=false;
}
}
for(T1=HeadE;T1!=NULL;T1=T1->next)
{
T1->x=T1->x+T1->k;
}
}
delete HeadB;
delete CurrentB;
delete CurrentE;
delete HeadE;
}
\
void CMyView::CreatBucket()
{
int ScanMin,ScanMax;
ScanMax=ScanMin=Point[0].y;
for(int i=1;i<Number;i++)
{
if(Point[i].y<ScanMin)
{
ScanMin=Point[i].y;
}
if(Point[i].y>ScanMax)
{
ScanMax=Point[i].y;//
}
}
for(int i=ScanMin;i<=ScanMax;i++)//
{
if(ScanMin==i)
{
HeadB=new Bucket;
CurrentB=HeadB;
CurrentB->ScanLine=ScanMin;
CurrentB->p=NULL;
CurrentB->next=NULL;
}
else
{
CurrentB->next=new Bucket;
CurrentB=CurrentB->next;
CurrentB->ScanLine=i;
CurrentB->p=NULL;
CurrentB->next=NULL;
}
}
}