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

📄 图形学实验dlg.cpp

📁 按作业效益非增序输入作业的截止期限
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				}
				dc.FillSolidRect(0,30,500,530,RGB(255,255,255));
				int i,j;
				for (i = 0; i <= 500; i++)
				{
					for (j = 0; j<= 500; j++)
					{
						pointdata[i][j] = 0;						
					}
				}
				break;
			}
		case 7:
			{
				//利用双缓冲,先在内存中将多面体画好,然后再画到屏幕上
				if (isTimerOn)
				{
					KillTimer(1);
					isTimerOn = false;
				}
				//创建内存画步
				CDC mdc;
				mdc.CreateCompatibleDC(NULL);
				mybitmap.CreateCompatibleBitmap(GetDC(),500,500);
				mdc.SelectObject(&mybitmap);
				mdc.FillSolidRect(0,0,500,500,RGB(255,255,255));
				//显示提示信息
				mdc.TextOut(30,30,"按住键盘方向键可以");
				mdc.TextOut(30,50,"任意角度旋转");
				mdc.TextOut(30,70,"按一下 W,S,A,D 可以");
				mdc.TextOut(30,90,"自动旋转");
				mdc.TextOut(30,110,"按 T 可以停止旋转");
				//panduankejianmian()用来判断当前状态下三个点所在的面是否是可见的
				//如果可见就将其填充显示
				if (PanduanKejianmian(A[0],A[4],A[1]))
				{
 					CRgn rgn0;
					CPoint psz0[3];
					psz0[0] = ChangePoint(CPoint(A[0].x,A[0].y));
					psz0[1] = ChangePoint(CPoint(A[1].x,A[1].y));
					psz0[2] = ChangePoint(CPoint(A[4].x,A[4].y));
					rgn0.CreatePolygonRgn(psz0,3,WINDING);
					mdc.FillRgn(&rgn0,&mybrush[0]);

					mdc.MoveTo(ChangePoint(CPoint(A[0].x,A[0].y)));
					mdc.LineTo(ChangePoint(CPoint(A[4].x,A[4].y)));
					mdc.LineTo(ChangePoint(CPoint(A[1].x,A[1].y)));
					mdc.LineTo(ChangePoint(CPoint(A[0].x,A[0].y)));
				}
				if (PanduanKejianmian(A[3],A[2],A[1]))
				{
					CRgn rgn0;
					CPoint psz0[3];
					psz0[0] = ChangePoint(CPoint(A[2].x,A[2].y));
					psz0[1] = ChangePoint(CPoint(A[1].x,A[1].y));
					psz0[2] = ChangePoint(CPoint(A[3].x,A[3].y));
					rgn0.CreatePolygonRgn(psz0,3,WINDING);
					mdc.FillRgn(&rgn0,&mybrush[5]);
				
					mdc.MoveTo(ChangePoint(CPoint(A[3].x,A[3].y)));
					mdc.LineTo(ChangePoint(CPoint(A[2].x,A[2].y)));
					mdc.LineTo(ChangePoint(CPoint(A[1].x,A[1].y)));
					mdc.LineTo(ChangePoint(CPoint(A[3].x,A[3].y)));
				}
				if (PanduanKejianmian(A[0],A[2],A[3]))
				{
					CRgn rgn0;
					CPoint psz0[3];
					psz0[0] = ChangePoint(CPoint(A[0].x,A[0].y));
					psz0[1] = ChangePoint(CPoint(A[2].x,A[2].y));
					psz0[2] = ChangePoint(CPoint(A[3].x,A[3].y));
					rgn0.CreatePolygonRgn(psz0,3,WINDING);
					mdc.FillRgn(&rgn0,&mybrush[2]);

					mdc.MoveTo(ChangePoint(CPoint(A[0].x,A[0].y)));
					mdc.LineTo(ChangePoint(CPoint(A[2].x,A[2].y)));
					mdc.LineTo(ChangePoint(CPoint(A[3].x,A[3].y)));
					mdc.LineTo(ChangePoint(CPoint(A[0].x,A[0].y)));
				}
				if (PanduanKejianmian(A[0],A[1],A[2]))
				{
					CRgn rgn0;
					CPoint psz0[3];
					psz0[0] = ChangePoint(CPoint(A[0].x,A[0].y));
					psz0[1] = ChangePoint(CPoint(A[1].x,A[1].y));
					psz0[2] = ChangePoint(CPoint(A[2].x,A[2].y));
					rgn0.CreatePolygonRgn(psz0,3,WINDING);
					mdc.FillRgn(&rgn0,&mybrush[4]);

					mdc.MoveTo(ChangePoint(CPoint(A[0].x,A[0].y)));
					mdc.LineTo(ChangePoint(CPoint(A[1].x,A[1].y)));
					mdc.LineTo(ChangePoint(CPoint(A[2].x,A[2].y)));
					mdc.LineTo(ChangePoint(CPoint(A[0].x,A[0].y)));
				}
				if (PanduanKejianmian(A[0],A[3],A[4]))
				{
					CRgn rgn0;
					CPoint psz0[3];
					psz0[0] = ChangePoint(CPoint(A[0].x,A[0].y));
					psz0[1] = ChangePoint(CPoint(A[3].x,A[3].y));
					psz0[2] = ChangePoint(CPoint(A[4].x,A[4].y));
					rgn0.CreatePolygonRgn(psz0,3,WINDING);
					mdc.FillRgn(&rgn0,&mybrush[1]);				


					mdc.MoveTo(ChangePoint(CPoint(A[0].x,A[0].y)));
					mdc.LineTo(ChangePoint(CPoint(A[3].x,A[3].y)));
					mdc.LineTo(ChangePoint(CPoint(A[4].x,A[4].y)));
					mdc.LineTo(ChangePoint(CPoint(A[0].x,A[0].y)));
				}
				if (PanduanKejianmian(A[1],A[4],A[3]))
				{
					CRgn rgn0;
					CPoint psz0[3];
					psz0[0] = ChangePoint(CPoint(A[3].x,A[3].y));
					psz0[1] = ChangePoint(CPoint(A[1].x,A[1].y));
					psz0[2] = ChangePoint(CPoint(A[4].x,A[4].y));
					rgn0.CreatePolygonRgn(psz0,3,WINDING);
					mdc.FillRgn(&rgn0,&mybrush[3]);
					
					mdc.MoveTo(ChangePoint(CPoint(A[1].x,A[1].y)));
					mdc.LineTo(ChangePoint(CPoint(A[3].x,A[3].y)));
					mdc.LineTo(ChangePoint(CPoint(A[4].x,A[4].y)));
					mdc.LineTo(ChangePoint(CPoint(A[1].x,A[1].y)));
				}
			
				//画到屏幕上
				dc.BitBlt(0,30,500,500,&mdc,0,0,SRCCOPY);
				//画完之后清除内存画布
				mybitmap.DeleteObject();
				mdc.DeleteDC();
				break;

			}
		case 8:
			{
				//演示画家算法的思想
					CDC mdc;
					mdc.CreateCompatibleDC(NULL);
					mybitmap.CreateCompatibleBitmap(GetDC(),500,500);
					mdc.SelectObject(&mybitmap);
					mdc.FillSolidRect(0,0,500,500,RGB(255,255,255));
					mdc.TextOut(30,30,"画家算法由远及近地填充每个面");
					
					mdc.TextOut(30,50,"从而实现消隐");
					mdc.MoveTo(ChangePoint(CPoint(LastA[0].x,LastA[0].y)));
					mdc.LineTo(ChangePoint(CPoint(LastA[1].x,LastA[1].y)));
					mdc.LineTo(ChangePoint(CPoint(LastA[2].x,LastA[2].y)));
					mdc.LineTo(ChangePoint(CPoint(LastA[0].x,LastA[0].y)));
					mdc.LineTo(ChangePoint(CPoint(LastA[4].x,LastA[4].y)));
					mdc.LineTo(ChangePoint(CPoint(LastA[1].x,LastA[1].y)));
					mdc.LineTo(ChangePoint(CPoint(LastA[3].x,LastA[3].y)));
					mdc.LineTo(ChangePoint(CPoint(LastA[4].x,LastA[4].y)));
					mdc.MoveTo(ChangePoint(CPoint(LastA[0].x,LastA[0].y)));
					mdc.LineTo(ChangePoint(CPoint(LastA[3].x,LastA[3].y)));
					mdc.LineTo(ChangePoint(CPoint(LastA[2].x,LastA[2].y)));
										
				
					dc.BitBlt(0,30,500,500,&mdc,0,0,SRCCOPY);
					mybitmap.DeleteObject();
					mdc.DeleteDC();	
				
					pshuzu[0][0] =ChangePoint(CPoint(LastA[0].x,LastA[0].y+30));
					pshuzu[0][1] =ChangePoint(CPoint(LastA[1].x,LastA[1].y+30));
					pshuzu[0][2] =ChangePoint(CPoint(LastA[2].x,LastA[2].y+30));

					pshuzu[1][0] =ChangePoint(CPoint(LastA[0].x,LastA[0].y+30));
					pshuzu[1][1] =ChangePoint(CPoint(LastA[3].x,LastA[3].y+30));
					pshuzu[1][2] =ChangePoint(CPoint(LastA[2].x,LastA[2].y+30));

					pshuzu[2][0] =ChangePoint(CPoint(LastA[0].x,LastA[0].y+30));
					pshuzu[2][1] =ChangePoint(CPoint(LastA[4].x,LastA[4].y+30));
					pshuzu[2][2] =ChangePoint(CPoint(LastA[3].x,LastA[3].y+30));

					pshuzu[3][0] =ChangePoint(CPoint(LastA[1].x,LastA[1].y+30));
					pshuzu[3][1] =ChangePoint(CPoint(LastA[3].x,LastA[3].y+30));
					pshuzu[3][2] =ChangePoint(CPoint(LastA[2].x,LastA[2].y+30));

					pshuzu[4][0] =ChangePoint(CPoint(LastA[1].x,LastA[1].y+30));
					pshuzu[4][1] =ChangePoint(CPoint(LastA[4].x,LastA[4].y+30));
					pshuzu[4][2] =ChangePoint(CPoint(LastA[0].x,LastA[0].y+30));

					pshuzu[5][0] =ChangePoint(CPoint(LastA[3].x,LastA[3].y+30));
					pshuzu[5][1] =ChangePoint(CPoint(LastA[1].x,LastA[1].y+30));
					pshuzu[5][2] =ChangePoint(CPoint(LastA[4].x,LastA[4].y+30));
					
					
				
					
						myrgn[0].CreatePolygonRgn(pshuzu[0],3,WINDING);
					myrgn[1].CreatePolygonRgn(pshuzu[1],3,WINDING);
					myrgn[2].CreatePolygonRgn(pshuzu[2],3,WINDING);
					myrgn[3].CreatePolygonRgn(pshuzu[3],3,WINDING);
					myrgn[4].CreatePolygonRgn(pshuzu[4],3,WINDING);
					myrgn[5].CreatePolygonRgn(pshuzu[5],3,WINDING);
					
					

					


					for (int i =0; i < 6; i++)
					{
						dc.FillRgn(&myrgn[i],&mybrush[i]);
						Sleep(800);
					}
			}
		default:break;
		}
	
		CDialog::OnPaint();
	}
}


HCURSOR CMyDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

bool CMyDlg::PanduanKejianmian(LiTipoint a,LiTipoint b, LiTipoint c)
{
	//由于视线是沿Z轴方向观察多面体,所以可以
	//通过判断Ax+By+Cz+D=0方程中C的符号来判断
	//面是否是可见的
	double panduantiaojian;
	panduantiaojian = a.x*(b.y-c.y)+b.x*(c.y-a.y)+c.x*(a.y-b.y);
	if (panduantiaojian > 0.0)
	{
		//可见返回true
		return true;
	}
	else
	{
		return false;
	}
}

void CMyDlg::OnGuanyu() 
{
	//显示说明对话框

	CShoumingDlg dlg;
	dlg.DoModal();
}
//点
void CMyDlg::Onpoint() 
{
	//state赋值1,马上刷新
	state = 1;
	Invalidate();
}

void CMyDlg::changelitipoint(LiTipoint& a,char whichzhou,double cita)
{
	//将三维坐标系下的点a绕坐标轴旋转,得到新的坐标
	LiTipoint b ;
	b.x = a.x;
	b.y = a.y;
	b.z = a.z;
	switch(whichzhou)
	{
		//绕X轴旋转
	case 'x':
	case 'X':
		{
			a.y=b.y*cos(cita)-b.z*sin(cita);
			a.z=b.y*sin(cita)+b.z*cos(cita);
			break;
		}
		//Y轴
	case 'y':
	case 'Y':
		{
			a.x=b.z*sin(cita)+b.x*cos(cita);
			a.z=b.z*cos(cita)-b.x*sin(cita);
			break;
		}
		//Z轴
	case 'z':
	case 'Z':
		{
			a.x=b.x*cos(cita)-b.y*sin(cita);
			a.y=b.x*sin(cita)+b.y*cos(cita);
			break;
		}
	default:
		break;
	}
}

void CMyDlg::OnX30() 
{
	//绕X轴旋转30度
	if (state == 7)
	{
		zhou = 'x';
		for (int i = 0; i < 5; i++)
		{
			changelitipoint(A[i],zhou,PI/6.0);
		}
		Invalidate();
	}
}

void CMyDlg::On2Line() 
{
	//点击画线命令时,将state赋值为5,刷新屏幕,等待操作
	state = 5;
	Invalidate();
}

void CMyDlg::On2yuan() 
{
	//点击画圆命令时,state赋值为6,刷新屏幕,等待操作
	state = 6;
	Invalidate();
}

void CMyDlg::On3duomianti() 
{
	//显示多面体,state= 7
	state = 7;
	Invalidate();
	
}

void CMyDlg::OnClear() 
{
	//清屏
	state = 0;
	Invalidate();
}

void CMyDlg::OnKUAIda() 
{
	//显示大的方块,并实现用其画线
	state = 3;
	Invalidate();
}

void CMyDlg::OnKUAIxiao() 
{
	//显示小方块,用其作为图元
	state = 2;
	Invalidate();
}

void CMyDlg::OnX60() 
{
	//绕X轴旋转60度
	if (state == 7)
	{
		zhou = 'x';
		for (int i = 0 ; i < 5; i++)
		{
			changelitipoint(A[i],zhou,PI/3.0);
		}
		Invalidate();
	}
	
}

void CMyDlg::OnX90() 
{
	//绕X轴旋转90度
	if (state == 7)
	{
		zhou = 'x';
		for (int i = 0 ; i < 5; i++)
		{
			changelitipoint(A[i],zhou,PI/2.0);
		}
		Invalidate();
	}
}

void CMyDlg::OnY30() 
{
	//绕Y旋转30度
	if (state == 7)
	{
		zhou = 'y';
		for (int i = 0 ; i < 5; i++)
		{
			changelitipoint(A[i],zhou,PI/6.0);
		}
		Invalidate();
	}
}

void CMyDlg::OnY90() 
{
	//绕Y轴旋转90度
	if (state == 7)
	{
		zhou = 'y';
		for (int i = 0 ; i < 5; i++)
		{
			changelitipoint(A[i],zhou,PI/2.0);
		}
		Invalidate();
	}
}

void CMyDlg::OnY60() 
{
	//绕Y旋转60度
	if (state == 7)
	{
		zhou = 'y';
		for (int i = 0 ; i < 5; i++)
		{
			changelitipoint(A[i],zhou,PI/3.0);
		}
		Invalidate();
	}
}

void CMyDlg::OnYuan() 
{
	//显示圆,用其为图元
	state = 4;
	Invalidate();

}


void CMyDlg::OnExit() 
{
	// 计时器如果没终止,终止它
	if (isTimerOn)
	{
		KillTimer(1);
	}
	//显示About对话框
	CAboutDlg dlg;
	dlg.DoModal();
	CDialog::OnOK();
	
}

CPoint CMyDlg::ChangePoint(CPoint point)
{
	//将点坐标转换成屏幕坐标
	CPoint tempPoint ;
	tempPoint.x = point.x+250;
	tempPoint.y = point.y+280;
	return tempPoint;
}


void CMyDlg::OnMouseMove(UINT nFlags, CPoint point) 
{
	//设置光标形状
	::SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR1));
	if (nFlags == MK_LBUTTON)
	{
		//如果鼠标移动的同时左键按下的话,执行操作
		CClientDC dc(this);
		switch(state)
		{
		case 1:
			{
				//以点为图元画线
				dc.SetPixelV(point,RGB(0,0,255));
				break;
			}
		case 2:
			{
				//以小方块为图元画线,需判断边界条件
				int adjusty = point.y-10;
				if (point.y-10<30)
				{
					adjusty = 30;
				}
				CRect myrect(point.x-10,adjusty,point.x+10,point.y+10);
				CBrush mybrush;
				mybrush.CreateSolidBrush(RGB(0,0,255));
				dc.FillRect(myrect,&mybrush);
				break;
			}
		case 3:
			{
				//以大方块为图元画线,需判断边界条件
				int adjusty = point.y-20;
				if (point.y-20<30)
				{
					adjusty = 30;
				}
				CRect myrect(point.x-20,adjusty,point.x+20,point.y+20);
				CBrush mybrush;
				mybrush.CreateSolidBrush(RGB(0,0,255));
				dc.FillRect(myrect,&mybrush);
				break;
			}
		case 4:
			{
				//以圆为图元画线,判断边界条件
				int adjusty = point.y-10;
				if (point.y-10<30)
				{
					adjusty = 30;
				}
				CBrush mybrush;
				mybrush.CreateSolidBrush(RGB(0,0,255));
				CRgn myrgn;
				myrgn.CreateEllipticRgn(point.x-10,adjusty,point.x+10,point.y+10);
				dc.FillRgn(&myrgn,&mybrush);
				break;
			}
		case 5:
			{	
				//DDA画线,用到双缓冲技术,避免画面闪烁
				CDC memdc;
				memdc.CreateCompatibleDC(NULL);
				mybitmap.CreateCompatibleBitmap(GetDC(),500,500);
				memdc.SelectObject(&mybitmap);
				memdc.FillSolidRect(0,0,500,500,RGB(255,255,255));
				//擦去上一次移动时画的线
				lineDDA(pointBegin.x,pointBegin.y,pointEnd.x,pointEnd.y,RGB(255,255,255));
				//恢复屏幕显示图形,避免上一步擦除了不该擦除的点
				int i,j;
				for (i = 0; i <= 500; i++)
				{
					for (j = 0; j<= 500; j++)
					{
						if (pointdata[i][j] == 1)
						{
							memdc.SetPixelV(CPoint(i,j),RGB(0,0,255));
						}
					}
				}
						
				dc.BitBlt(0,30,500,500,&memdc,0,0,SRCCOPY);
				mybitmap.DeleteObject();
				memdc.DeleteDC();
				//重新画线
				pointEnd = point;
				lineDDA(pointBegin.x,pointBegin.y,pointEnd.x,pointEnd.y,RGB(0,0,255));
				break;
			}
		case 6:
			{
				//与5类似,实现DDA画圆
				CDC memdc;
				memdc.CreateCompatibleDC(NULL);
				mybitmap.CreateCompatibleBitmap(GetDC(),500,500);
				memdc.SelectObject(&mybitmap);
				memdc.FillSolidRect(0,0,500,500,RGB(255,255,255));
				

				
				CPoint mypoint((CircleBeginPoint.x+CircleEndPoint.x)/2,(CircleBeginPoint.y+CircleEndPoint.y)/2);
				int r;
				r=sqrt((point.x-mypoint.x)*(point.x-mypoint.x)+(point.y-mypoint.y)*(point.y-mypoint.y));
				CircleDDA(mypoint.x,mypoint.y,r,RGB(0,0,255));
				
				int i,j;
				for (i = 0; i <= 500; i++)
				{
					for (j = 0; j<= 500; j++)
					{
						if (pointdata[i][j] == 1)
						{
							memdc.SetPixelV(CPoint(i,j),RGB(0,0,255));
						}
					}
				}
						
				dc.BitBlt(0,30,500,500,&memdc,0,0,SRCCOPY);
				mybitmap.DeleteObject();
				memdc.DeleteDC();
				
				CircleEndPoint = point;
				CPoint mypoint2((CircleBeginPoint.x+CircleEndPoint.x)/2,(CircleBeginPoint.y+CircleEndPoint.y)/2);
			
				r=sqrt((point.x-mypoint2.x)*(point.x-mypoint2.x)+(point.y-mypoint2.y)*(point.y-mypoint2.y));

⌨️ 快捷键说明

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