⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 z_bufferview.cpp

📁 基于MFC的z-buffer算法实现
💻 CPP
字号:
// Z_BUFFERView.cpp : implementation of the CZ_BUFFERView class
//

#include "stdafx.h"
#include "Z_BUFFER.h"

#include "Z_BUFFERDoc.h"
#include "Z_BUFFERView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CZ_BUFFERView

IMPLEMENT_DYNCREATE(CZ_BUFFERView, CView)

BEGIN_MESSAGE_MAP(CZ_BUFFERView, CView)
	//{{AFX_MSG_MAP(CZ_BUFFERView)
	ON_COMMAND(ID_ONX, OnOnx)
	ON_COMMAND(ID_ONY, OnOny)
	ON_COMMAND(ID_ONZ, OnOnz)
	//}}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()

/////////////////////////////////////////////////////////////////////////////
// CZ_BUFFERView construction/destruction

CZ_BUFFERView::CZ_BUFFERView()
{
	for (int i=0;i<400;i++)
	{
		for (int j=0;j<400;++j)
		{
			color[i][j]=RGB(255,255,255);
			z_distance[i][j]=-1000;
		}
	}
	angle=double(3.14/3);
    n=0;
	point=new double[642*3];
	kao=FALSE;
}

CZ_BUFFERView::~CZ_BUFFERView()
{
	delete[] point;
}

BOOL CZ_BUFFERView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CZ_BUFFERView drawing

void CZ_BUFFERView::OnDraw(CDC* pDC)
{
	CZ_BUFFERDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
    BeginWaitCursor();
    CRect rect;
	GetClientRect(&rect);
	pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);
    bool flag;
	int x_min,y_min,x_max,y_max;
	int i,j,w;
	double x[3],y[3],z[3];
	int index1,index2,index3;
	double *vex;
	int *face;
	double distan;
	//byte r,g,b;
	flag=pDoc->getflag();
	x_min=y_min=1000;
	x_max=y_max=-1000;
	if (flag)
	{
		vex=pDoc->getvex();
		if (!kao)
		{
			for (i=0;i<642;i++)
			{
				point[i*3]=vex[i*3];
				point[i*3+1]=vex[i*3+1];
				point[i*3+2]=vex[i*3+2];
			}
		}
	
		face=pDoc->getface();
	
		for (w=0;w<1280;w++)
		{
			index1=face[w*3];
		    index2=face[w*3+1];
		    index3=face[w*3+2];
		    x[0]=point[(index1-1)*3];
		    y[0]=point[(index1-1)*3+1];
		    z[0]=point[(index1-1)*3+2];
		    x[1]=point[(index2-1)*3];
		    y[1]=point[(index2-1)*3+1];
		    z[1]=point[(index2-1)*3+2];
		    x[2]=point[(index3-1)*3];
	        y[2]=point[(index3-1)*3+1];
		    z[2]=point[(index3-1)*3+2];
		    for (i=0;i<3;i++)
			{
				if (x_min>x[i])
				{
					x_min=(int)x[i];
				}
			    if (x_max<x[i])
				{
					x_max=(int)x[i];
				}
			    if (y_min>y[i])
				{
					y_min=(int)y[i];
				}
			    if (y_max<y[i])
				{
					y_max=(int)y[i];
				} 
			}
	    	for (i=x_min;i<=x_max;i++)
			{
				for (j=y_min;j<=y_max;j++)
				{
					if (inside(x,y,i,j))
					{
						distan=Z_function(x,y,z,i,j);
					    if (distan>z_distance[i+200][j+200])
						{
							color[i+200][j+200]=pDoc->m_color[w];
						    z_distance[i+200][j+200]=distan;
						}

					}
				}
			}
			x_min=y_min=1000;
	        x_max=y_max=-1000;
		}
		for (i=-200;i<=199;++i)
		{
			for (j=-200;j<=199;++j)
			{
				pDC->SetPixel(i,j,color[i+200][j+200]);
			}
		}
		for (i=0;i<642;i++)
		{
			point[i*3]=vex[i*3];
			point[i*3+1]=vex[i*3+1];
			point[i*3+2]=vex[i*3+2];
		}
		for (int i=0;i<400;i++)
		{
			for (int j=0;j<400;++j)
			{
				color[i][j]=RGB(255,255,255);
				z_distance[i][j]=-1000;
			}
		}
		kao=FALSE;
	}
    

	

	
}

/////////////////////////////////////////////////////////////////////////////
// CZ_BUFFERView printing

BOOL CZ_BUFFERView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CZ_BUFFERView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CZ_BUFFERView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CZ_BUFFERView diagnostics

#ifdef _DEBUG
void CZ_BUFFERView::AssertValid() const
{
	CView::AssertValid();
}

void CZ_BUFFERView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CZ_BUFFERDoc* CZ_BUFFERView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CZ_BUFFERDoc)));
	return (CZ_BUFFERDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CZ_BUFFERView message handlers



int CZ_BUFFERView::inside(double xcoor[], double ycoor[], int x, int y)
{
	double a1,b1,a2,b2,a3,b3;
	int m=0;
	double x0=(xcoor[2]+(xcoor[0]+xcoor[1])/2)/2;
	double y0=(ycoor[2]+(ycoor[0]+ycoor[1])/2)/2;
    if (xcoor[0]==xcoor[1])
    {
		a2=(ycoor[2]-ycoor[1])/(xcoor[2]-xcoor[1]);
		b2=ycoor[1]-a2*xcoor[1];
		a3=(ycoor[2]-ycoor[0])/(xcoor[2]-xcoor[0]);
		b3=ycoor[0]-a3*xcoor[0];
		if (((a2*x+b2-y)*(a2*x0+b2-y0)>=0)&&((a3*x+b3-y)*(a3*x0+b3-y0)>=0))
		{
			if (xcoor[2]<xcoor[0])
			{
				if ((xcoor[2]<=x)&&(x<=xcoor[0]))
				{
					m=1;
				}
			} 
			else
			{
				if ((xcoor[0]<=x)&&(x<=xcoor[2]))
				{
					m=1;
				}
			}
		}
    } 
    else
    {
		if (xcoor[1]==xcoor[2])
		{
			a1=(ycoor[1]-ycoor[0])/(xcoor[1]-xcoor[0]);
			b1=ycoor[0]-a1*xcoor[0];
			a3=(ycoor[2]-ycoor[0])/(xcoor[2]-xcoor[0]);
		    b3=ycoor[0]-a3*xcoor[0];
			if (((a1*x+b1-y)*(a1*x0+b1-y0)>=0)&&((a3*x+b3-y)*(a3*x0+b3-y0)>=0))
			{
				if (xcoor[2]<xcoor[0])
				{
					if ((xcoor[2]<=x)&&(x<=xcoor[0]))
					{
						m=1;
					}
				} 
				else
				{
					if ((xcoor[0]<=x)&&(x<=xcoor[2]))
					{
						m=1;
					}
				}

			}
		} 
		else
		{
			if (xcoor[0]==xcoor[2])
			{
				a1=(ycoor[1]-ycoor[0])/(xcoor[1]-xcoor[0]);
			    b1=ycoor[0]-a1*xcoor[0];
				a2=(ycoor[2]-ycoor[1])/(xcoor[2]-xcoor[1]);
		        b2=ycoor[1]-a2*xcoor[1];
				if (((a1*x+b1-y)*(a1*x0+b1-y0)>=0)&&((a2*x+b2-y)*(a2*x0+b2-y0)>=0))
				{
					if (xcoor[1]<xcoor[0])
					{
						if ((xcoor[1]<x)&&(x<xcoor[0]))
						{
							m=1;
						}
					} 
					else
					{
						if ((xcoor[0]<x)&&(x<xcoor[1]))
						{
							m=1;
						}
					}
					
				}
			} 
			else
			{
				a1=(ycoor[1]-ycoor[0])/(xcoor[1]-xcoor[0]);
				b1=ycoor[0]-a1*xcoor[0];
				a3=(ycoor[2]-ycoor[0])/(xcoor[2]-xcoor[0]);
		        b3=ycoor[0]-a3*xcoor[0];
				a2=(ycoor[2]-ycoor[1])/(xcoor[2]-xcoor[1]);
	          	b2=ycoor[1]-a2*xcoor[1];
				if (((a1*x+b1-y)*(a1*x0+b1-y0)>=0)&&((a2*x+b2-y)*(a2*x0+b2-y0)>=0)&&((a3*x+b3-y)*(a3*x0+b3-y0)>=0))
				{
					m=1;
				}

			}
		}
    }
	return m;

}

double CZ_BUFFERView::Z_function(double xcoor[], double ycoor[], double zcoor[],int x, int y)
{
	double z;
    double A,B,C;
    double a1,b1,c1,a2,b2,c2;
	a1=xcoor[1]-xcoor[0];
	b1=ycoor[1]-ycoor[0];
	c1=zcoor[1]-zcoor[0];
	a2=xcoor[2]-xcoor[0];
	b2=ycoor[2]-ycoor[0];
	c2=zcoor[2]-zcoor[0];
	A=b1*c2-b2*c1;
	B=c1*a2-a1*c2;
	C=a1*b2-a2*b1;
	if ((C>-0.000001)&&(C<0.000001))
	{
		z=-1000;
	} 
	else
	{
		z=(A*(xcoor[0]-x)+B*(ycoor[0]-y))/C+zcoor[0];
	}
	return z;

}



void CZ_BUFFERView::OnOnx() 
{
	
	double A[16]={1,0,0,0,0,cos(angle),-sin(angle),0,0,sin(angle),cos(angle),0,0,0,0,1};
	Matrix MX(4,4,A,16);
	double B[16]={cos(angle),0,sin(angle),0,0,1,0,0,-sin(angle),0,cos(angle),0,0,0,0,1};
	Matrix MY(4,4,B,16);
	double C[16]={cos(angle),-sin(angle),0,0,sin(angle),cos(angle),0,0,0,0,1,0,0,0,0,1};
	Matrix MZ(4,4,C,16);
	double D[16]={1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
	Matrix M(4,4,D,16);
	double* temple;
	temple=new double[642*3];
	num[n]=1;
	for (int j=0;j<=n;++j)
	{
		if (num[j]==1)
		{
			M=MX*M;
		}
		if (num[j]==2)
		{
			M=MY*M;
		}
		if (num[j]==3)
		{
			M=MZ*M;
		}		
	}
	n++;
	for (int i=0;i<642;i++)
	{
		double x,y,z;
		x=M.p[0][0]*point[i*3]+M.p[0][1]*point[i*3+1]+M.p[0][2]*point[i*3+2]+M.p[0][3];
		y=M.p[1][0]*point[i*3]+M.p[1][1]*point[i*3+1]+M.p[1][2]*point[i*3+2]+M.p[1][3];
		z=M.p[2][0]*point[i*3]+M.p[2][1]*point[i*3+1]+M.p[2][2]*point[i*3+2]+M.p[2][3];
		temple[i*3]=x;
		temple[i*3+1]=y;
		temple[i*3+2]=z;
			
	}
	kao=TRUE;
    for (i=0;i<642;i++)
	{
		point[i*3]=temple[i*3];
		point[i*3+1]=temple[i*3+1];
		point[i*3+2]=temple[i*3+2];
	}
	delete[] temple;
	Invalidate();
}

void CZ_BUFFERView::OnOny() 
{
	double A[16]={1,0,0,0,0,cos(angle),-sin(angle),0,0,sin(angle),cos(angle),0,0,0,0,1};
	Matrix MX(4,4,A,16);
	double B[16]={cos(angle),0,sin(angle),0,0,1,0,0,-sin(angle),0,cos(angle),0,0,0,0,1};
	Matrix MY(4,4,B,16);
	double C[16]={cos(angle),-sin(angle),0,0,sin(angle),cos(angle),0,0,0,0,1,0,0,0,0,1};
	Matrix MZ(4,4,C,16);
	double D[16]={1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
	Matrix M(4,4,D,16);
	double* temple;
	temple=new double[642*3];
	num[n]=2;
	for (int j=0;j<=n;++j)
	{
		if (num[j]==1)
		{
			M=MX*M;
		}
		if (num[j]==2)
		{
			M=MY*M;
		}
		if (num[j]==3)
		{
			M=MZ*M;
		}		
	}
	n++;

	for (int i=0;i<642;++i)
	{
		double x,y,z;
		x=M.p[0][0]*point[i*3]+M.p[0][1]*point[i*3+1]+M.p[0][2]*point[i*3+2]+M.p[0][3];
		y=M.p[1][0]*point[i*3]+M.p[1][1]*point[i*3+1]+M.p[1][2]*point[i*3+2]+M.p[1][3];
		z=M.p[2][0]*point[i*3]+M.p[2][1]*point[i*3+1]+M.p[2][2]*point[i*3+2]+M.p[2][3];
		temple[i*3]=x;
		temple[i*3+1]=y;
		temple[i*3+2]=z;
	}
	kao=TRUE;
    for (i=0;i<642;i++)
	{
		point[i*3]=temple[i*3];
		point[i*3+1]=temple[i*3+1];
		point[i*3+2]=temple[i*3+2];
	}
	delete[] temple;
	Invalidate();
	
}

void CZ_BUFFERView::OnOnz() 
{
	double A[16]={1,0,0,0,0,cos(angle),-sin(angle),0,0,sin(angle),cos(angle),0,0,0,0,1};
	Matrix MX(4,4,A,16);
	double B[16]={cos(angle),0,sin(angle),0,0,1,0,0,-sin(angle),0,cos(angle),0,0,0,0,1};
	Matrix MY(4,4,B,16);
	double C[16]={cos(angle),-sin(angle),0,0,sin(angle),cos(angle),0,0,0,0,1,0,0,0,0,1};
	Matrix MZ(4,4,C,16);
	double D[16]={1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
	Matrix M(4,4,D,16);
	double* temple;
	temple=new double[642*3];
	num[n]=3;
	for (int j=0;j<=n;++j)
	{
		if (num[j]==1)
		{
			M=MX*M;
		}
		if (num[j]==2)
		{
			M=MY*M;
		}
		if (num[j]==3)
		{
			M=MZ*M;
		}		
	}
	n++;
	for (int i=0;i<642;++i)
	{
		double x,y,z;
		x=M.p[0][0]*point[i*3]+M.p[0][1]*point[i*3+1]+M.p[0][2]*point[i*3+2]+M.p[0][3];
		y=M.p[1][0]*point[i*3]+M.p[1][1]*point[i*3+1]+M.p[1][2]*point[i*3+2]+M.p[1][3];
		z=M.p[2][0]*point[i*3]+M.p[2][1]*point[i*3+1]+M.p[2][2]*point[i*3+2]+M.p[2][3];
		temple[i*3]=x;
		temple[i*3+1]=y;
		temple[i*3+2]=z;
	}
	kao=TRUE;
    for (i=0;i<642;i++)
	{
		point[i*3]=temple[i*3];
		point[i*3+1]=temple[i*3+1];
		point[i*3+2]=temple[i*3+2];
	}
	delete[] temple;
	Invalidate();
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -