一、实验目的
- 基于点、线、面完成自己的创作
- 掌握MFC内置函数的运用
二、实验仪器
Windows 11、VS2022
三、实验思路
- 原理:金刚石图案是由一次连接位于圆上不同等分点的直线段构成,等分点越多,金刚石图案越复杂
- 实现方式:为了避免重复连接,就需要设计一个二重循环,进行连接。
四、实验步骤
- 新建文件->【单文档】->【MFC Standard】
- 【解决方案资源管理器】->【资源文件】->【Diamond.rc2】->【Menu】->【设 计菜单栏】
- 【Diamond.rc2】->【点击toolbar】->【设计绘图图标】(如图1)
- 【Diamond.rc2】->【右击Dialog】->【添加资源】->【设计对话框】->【保存】(如图2,3)
(图1) (图2) (图3)
- 【项目】->【类向导】->【CDiamondDlg】->【成员变量】进行设置(如图4)
(图4)
- 【解决方案资源管理器】->【CDiamondDlg.cpp】->【编写初始化】
CDiamondDlg::CDiamondDlg(CWnd* pParent /*=nullptr*/)
: CDialog(IDD_DIALOG1, pParent)
, m_n(0)
, m_r(0)
{//初始化
m_n = 30;//设置圆等分点为30
m_r = 300.0;//设置元的半径为300.0
}
- 设计“编辑框”的初始状态为选中状态
【项目】->【类向导】->【消息】->【ShowWindow】->【选中编辑代码】
void CDiamondDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
CDialog::OnShowWindow(bShow, nStatus);
// TODO: 在此处添加消息处理程序代码
GetDlgItem(IDC_EDIT1)->SetFocus();//将光标移动到控件1的编辑框中
((CEdit*)GetDlgItem(IDC_EDIT1))->SetSel(0, -1);//表示编辑控件中的全 部文本被选中
}
- 添加二维点
<1>【项目】->【添加类】->【类名:CP2】(如图5)
(图5)
<2>在CP2.h文件中:
#pragma once
class CP2
{//添加成员变量
public:
CP2(void);
~CP2(void);
public:
double x;
double y;
};
<3>在CP2.cpp文件中:
#include "pch.h"
#include "CP2.h"
CP2::CP2(void) {//初始化为0
x = 0;
y = 0;
}
CP2::~CP2(void) {
}
- 在Diamond.View.h中,添加成员变量与函数
<1>添加“CP2.h”文件
#include"CP2.h"
<2>添加成员变量
protected:
CP2* p;//动态数组p
int n;//等分点的个数
double r;//圆的半径
<3>添加绘制dianmond的函数
public:
void Diamond();
- 对菜单栏中的“绘图”选项添加“事件处理程序”,并编写代码
<1>右击菜单栏“绘图”中的“Diamond”->【添加事件处理程序】->【类列 表选择CDiamond】
<2>在函数中:
void CDiamondView::OnDiamond()
{
// TODO: 在此添加命令处理程序代码
CDiamondDlg dlg;//定义“CDiamondDlg”类(对话框)对象
if (IDOK == dlg.DoModal()) {//显示“模态对话框”
n = dlg.m_n;//将等分点和半径传入内部函数
r = dlg.m_r;
}
else
{
return;
}
RedrawWindow();//重绘窗口函数
p = new CP2[n];//创建一个动态一维数组
Diamond();//绘制金刚石函数
delete[]p;//将动态数组占用的空间释放
}
- 编写Diamond函数
void CDiamondView::Diamond() {
CDC* pDC = GetDC();
CRect rect;//创建一个矩形
GetClientRect(&rect);//将创建好的矩形作为参数传入
pDC->SetMapMode(MM_ANISOTROPIC);
//设置映射模式
pDC->SetWindowExt(rect.Width(), rect.Height());
//设置窗口的宽和高
pDC->SetViewportExt(rect.Width(), -rect.Height());
//设置视图的尺寸
pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);
//设置中心点位置
rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);
CPen NewPen, * pOldPen;//客户区与矩形重合
//定义了一个新画笔、一个旧画笔的指针
NewPen.CreatePen(PS_SOLID, 2, RGB(0, 169, 0));
//将新画笔选入设备上下文即显示在显示器上
pOldPen = pDC->SelectObject(&NewPen);
//定义两个变量,Theta:等分角的度数。Alpha:起始角
double Alpha, Theta;
Theta = 2 * PI / n;
Alpha = PI / 2 - Theta;
for (int i = 0; i < n; i++) {//依次找到所有等分点的x、y坐标
p[i].x = r * cos(i * Theta + Alpha);
p[i].y = r * sin(i * Theta + Alpha);
}
//依次将各个等分点与其他等分点连接
for (int i = 0; i <= n - 2; i++) {
for (int j = i + 1; j <= n - 1; j++) {
pDC->MoveTo(round(p[i].x), round(p[i].y));
//使用round函数时要添加一个头文件
pDC->LineTo(round(p[j].x), round(p[j].y)); }
}
pDC->SelectObject(pOldPen);//原来系统默认的画笔恢复
NewPen.DeleteObject();//删除新创建的画笔
ReleaseDC(pDC);//释放设备上下文占用的资源
}
五、实验结果