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

解决方案 »

  1.   


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

  2.   

    void CMyView::PolygonFill(CDC* mdc)
    {         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;                                   
                       }
             }
    }