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

📄 图形学实验dlg.cpp

📁 按作业效益非增序输入作业的截止期限
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// 图形学实验Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "图形学实验.h"
#include "图形学实验Dlg.h"
#include "ShoumingDlg.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define PI 3.14159

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyDlg dialog

CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMyDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMyDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMyDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
	//{{AFX_MSG_MAP(CMyDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_COMMAND(IDM_GUANYU, OnGuanyu)
	ON_COMMAND(ID_point, Onpoint)
	ON_COMMAND(ID_X30, OnX30)
	ON_COMMAND(IDM_2Line, On2Line)
	ON_COMMAND(IDM_2yuan, On2yuan)
	ON_COMMAND(IDM_3duomianti, On3duomianti)
	ON_COMMAND(IDM_CLEAR, OnClear)
	ON_COMMAND(IDM_KUAIda, OnKUAIda)
	ON_COMMAND(IDM_KUAIxiao, OnKUAIxiao)
	ON_COMMAND(IDM_X60, OnX60)
	ON_COMMAND(IDM_X90, OnX90)
	ON_COMMAND(IDM_Y30, OnY30)
	ON_COMMAND(IDM_Y90, OnY90)
	ON_COMMAND(IDM_Y60, OnY60)
	ON_COMMAND(IDM_YUAN, OnYuan)
	ON_COMMAND(ID_EXIT, OnExit)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_ERASEBKGND()
	ON_WM_TIMER()
	ON_COMMAND(IDM_Z30, OnZ30)
	ON_COMMAND(IDM_Z60, OnZ60)
	ON_COMMAND(IDM_Z90, OnZ90)
	ON_COMMAND(ID_FUYUAN, OnFuyuan)
	ON_COMMAND(IDM_HUAJIA, OnHuajia)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyDlg message handlers

BOOL CMyDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.
	CenterWindow();
	
	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	if(!m_wndToolbar.Create(this) || !m_wndToolbar.LoadToolBar(IDR_TOOLBAR1)) 
	{
		TRACE0("Failed to Create Dialog Toolbar\n"); 
		EndDialog(IDCANCEL);
	}
	CRect rcClientOld; // 客户区RECT
	CRect rcClientNew; // 加入TOOLBAR后的CLIENT RECT
	GetClientRect(rcClientOld); //
// Called to reposition and resize control bars in the client area of a window 
// The reposQuery FLAG does not really traw the Toolbar. It only does the calculations. 
// And puts the new ClientRect values in rcClientNew so we can do the rest of the Math. 
//重新计算RECT大小 
	RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0,reposQuery,rcClientNew); 
// All of the Child Windows (Controls) now need to be moved so the Tollbar does not cover them up. 
//所有的子窗口将被移动,以免被TOOLBAR覆盖 
// Offest to move all child controls after adding Tollbar 
//计算移动的距离 
	CPoint ptOffset(rcClientNew.left-rcClientOld.left,
		rcClientNew.top-rcClientOld.top);
	CRect rcChild;
	CWnd* pwndChild = GetWindow(GW_CHILD); //得到子窗口 
	while(pwndChild) // 处理所有子窗口 
	{//移动所有子窗口 
		pwndChild->GetWindowRect(rcChild);
		ScreenToClient(rcChild);
		rcChild.OffsetRect(ptOffset);
		pwndChild->MoveWindow(rcChild,FALSE);
		pwndChild = pwndChild->GetNextWindow();
	}
	CRect rcWindow;
	GetWindowRect(rcWindow); // 得到对话框RECT 
	rcWindow.right += rcClientOld.Width() - rcClientNew.Width(); // 修改对话框尺寸 
	rcWindow.bottom += rcClientOld.Height() - rcClientNew.Height();
	MoveWindow(rcWindow,FALSE); // Redraw Window 
	RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); 
	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	int i,j;
	//初始屏幕各点数据,为0表示空白,1表示点不空白
	for (i = 0; i <= 500; i++)
	{
		for (j = 0; j<= 500; j++)
		{
			pointdata[i][j] = 0;			
		}
	}
	//a为多面体边长,可以扩充程序变成可以调节大小的
	a= 200;
	//A[]存储多面体顶点坐标
	A[0].x=-100; A[0].y=-57.735; A[0].z=0;
	A[1].x=100; A[1].y=-57.735; A[1].z=0;
	A[4].x=0; A[4].y=0; A[4].z=-141.4034;
	A[3].x=0; A[3].y=115.47; A[3].z=0;
	A[2].x=0; A[2].y=0; A[2].z=141.4034;
	//演示画家算法用到的
	for(i = 0; i < 5; i ++)
	{
		LastA[i].x = A[i].x;
		LastA[i].y = A[i].y;
		LastA[i].z = A[i].z;
	}
	mybrush[0].CreateSolidBrush(RGB(255,0,0));
	mybrush[1].CreateSolidBrush(RGB(255,255,0));
	mybrush[2].CreateSolidBrush(RGB(0,255,0));
	mybrush[3].CreateSolidBrush(RGB(0,255,255));
	mybrush[4].CreateSolidBrush(RGB(0,0,255));
	mybrush[5].CreateSolidBrush(RGB(255,0,255));
	//state初始为0,屏幕为空白
	state = 0;
	//计时器未启用
	isTimerOn = false;
	//方向没有选择
	fangxiang = 0;
	isfirstview = true;
	//设置窗口topmost属性
	::SetWindowPos(this->m_hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else if (nID == SC_CLOSE)
	{
		//退出时显示About 对话框
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
		CDialog::OnSysCommand(nID,lParam);
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

BOOL CMyDlg::PreTranslateMessage(MSG* pMsg) 
{

    // TODO: Add your specialized code here and/or call the base class

    //截获ESC和回车键,避免按下此键时关闭对话框

    if (pMsg->message == WM_KEYDOWN)
    {
		switch(pMsg->wParam)
		{
		case VK_ESCAPE:
			{
				CAboutDlg dlg;
				//显示About对话框,确定之后退出
				if(dlg.DoModal() == IDCANCEL)
					OnOK();
				return true;
			}
		case VK_UP:
			{
				//响应键盘向上方向键
				if (state == 7)
				{//如果是现在处在显示多面体的画面就执行
					for (int i = 0; i < 5; i++)
					{//将多面体绕x轴旋转 1 度之后刷新显示
						 zhou = 'x';
						changelitipoint(A[i],zhou,PI/-180);
					}
					Invalidate();
					break;
				}
			
			}
		case VK_DOWN:
			{
				//响应键盘向下方向键,与上面VK_UP响应类似,角度相反
				if (state == 7)
				{
					for (int i = 0; i < 5; i++)
					{
						 zhou = 'x';
						changelitipoint(A[i],zhou,PI/(180.0));
					}
					Invalidate();
					break;
				}
			}
		case VK_LEFT:
			{
				//响应键盘向左方向键,绕y轴旋转
				if (state == 7)
				{
					for (int i = 0; i < 5; i++)
					{
						 zhou = 'y';
						changelitipoint(A[i],zhou,PI/180);
					}
					Invalidate();
					break;
				}
			}
		case VK_RIGHT:
			{
				//类上
				if (state == 7)
				{
					for (int i = 0; i < 5; i++)
					{
						 zhou = 'y';
						changelitipoint(A[i],zhou,PI/-180);
					}
					Invalidate();
					break;
				}
			}
		case 'W':
			{
				//响应W按键,通过启动计时器,实现自动向上旋转效果
				if (!isTimerOn && state == 7)
				{//如果是多面体选项并且未启用计时器
					fangxiang = 1;
					SetTimer(1,50,NULL);
					isTimerOn = true;
					break;
				}
				if (state == 7 && isTimerOn)
				{	//如果是多面体选项并且已经启动计时器
					//如果多面体是向上旋转的,就直接返回,否则
					//先终止计时器,然后重新启动,使多面体向上旋转
					if (fangxiang == 1)
					{
						break;
					}
					else
					{
						KillTimer(1);
						fangxiang = 1;
						SetTimer(1,50,NULL);
						isTimerOn =	true;
						break;
					}
				}
			}
		case 'S':
			{
				//响应S按键消息,类似W消息处理
				if (!isTimerOn && state == 7)
				{
					fangxiang = 2;
					SetTimer(1,50,NULL);
					isTimerOn = true;
					break;
				}
				if (state == 7 && isTimerOn)
				{
					if (fangxiang == 2)
					{
						break;
					}
					else
					{
						KillTimer(1);
						fangxiang = 2;
						SetTimer(1,50,NULL);
						isTimerOn = true;
						break;
					}
				}
			}
		case 'A':
			{
				//类上
				if (!isTimerOn && state == 7)
				{
					fangxiang = 3;
					SetTimer(1,50,NULL);
					isTimerOn = true;
					break;
				}
				if (state == 7 && isTimerOn)
				{
					if (fangxiang == 3)
					{
						break;
					}
					else
					{
						KillTimer(1);
						fangxiang = 3;
						SetTimer(1,50,NULL);
						isTimerOn = true;
						break;
					}
				}
			}
		case 'D':
			{
				//类上
				if (!isTimerOn && state == 7)
				{
					fangxiang = 4;
					SetTimer(1,50,NULL);
					isTimerOn = true;
					break;
				}
				if (state == 7 && isTimerOn)
				{
					if (fangxiang == 4)
					{
						break;
					}
					else
					{
						KillTimer(1);
						fangxiang = 4;
						SetTimer(1,50,NULL);
						isTimerOn = true;
						break;
					}
				}
			}
		case 'T':
			{
				//如果已经启用计时器,将其终止
				if (state == 7 && isTimerOn)
				{
					KillTimer(1);
					isTimerOn = false;
					break;
				}
			}
		default:
			{
				//其它消息不做反应
				return true;
			}
		}
	}
    return CDialog::PreTranslateMessage(pMsg);
}


void CMyDlg::OnPaint() 
{
	//刷新屏幕,根据全局变量state的状态决定执行操作
	CPaintDC dc(this); // device context for painting
	if (IsIconic())
	{
		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		switch(state)
		{
		case 0:
			{
				//如果计时器启用,将其终止
				if (isTimerOn)
				{
					KillTimer(1);
					isTimerOn = false;
				}
				//显示空白屏幕
				dc.FillSolidRect(0,30,500,530,RGB(255,255,255));
				break;
			}
			
		case 1:
			{
				//同上
				if (isTimerOn)
				{
					KillTimer(1);
					isTimerOn = false;
				}
				//先清屏,然后在屏幕中心画点
				//就我创建的对话框而言,中心为(250,280)
				//可以用GetClientRect(&rect);得到屏幕的矩形大小再计算中心点
				//避免程序复杂,直接用数据,并且对话框是不支持改变其大小的,故可行
				dc.FillSolidRect(0,30,500,530,RGB(255,255,255));
				dc.SetPixelV(CPoint(250,280),RGB(0,0,255));
				break;
			}
		case 2:
			{
				//同上
				if (isTimerOn)
				{
					KillTimer(1);
					isTimerOn = false;
				}
				//清屏然后画小矩形块
				dc.FillSolidRect(0,30,500,530,RGB(255,255,255));
				CRect myrect(240,270,260,290);
				CBrush mybrush;
				mybrush.CreateSolidBrush(RGB(0,0,255));
				dc.FillRect(myrect,&mybrush);
				break;
			}
		case 3:
			{
				//同上
				if (isTimerOn)
				{
					KillTimer(1);
					isTimerOn = false;
				}
				//清屏然后画大矩形
				dc.FillSolidRect(0,30,500,530,RGB(255,255,255));
				CRect myrect(230,260,270,300);
				CBrush mybrush;
				mybrush.CreateSolidBrush(RGB(0,0,255));
				dc.FillRect(myrect,&mybrush);
				break;				
			}
		case 4:
			{
				//同上
				if (isTimerOn)
				{
					KillTimer(1);
					isTimerOn = false;
				}
				//清屏然后在中心画圆
				dc.FillSolidRect(0,30,500,530,RGB(255,255,255));
				CBrush mybrush;
				mybrush.CreateSolidBrush(RGB(0,0,255));
			
				CRgn myrgn;
				myrgn.CreateEllipticRgn(240,270,260,290);
				dc.FillRgn(&myrgn,&mybrush);
				break;
			}
		case 5:
			{
				//清屏然后等待用户画线
				//将屏幕的点的信息赋值为初始状态
				if (isTimerOn)
				{
					KillTimer(1);
					isTimerOn = false;
				}
				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 6:
			{
				//清屏然后等待用户画圆
				//同上
				if (isTimerOn)
				{
					KillTimer(1);
					isTimerOn = false;

⌨️ 快捷键说明

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