#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "MFC3DApp.h"
#endif
#include "MFC3DAppDoc.h"
#include "MFC3DAppView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMFC3DAppView
IMPLEMENT_DYNCREATE(CMFC3DAppView, CView)
BEGIN_MESSAGE_MAP(CMFC3DAppView, CView)
// 标准打印命令
ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CMFC3DAppView::OnFilePrintPreview)
ON_WM_CONTEXTMENU()
ON_WM_RBUTTONUP()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
END_MESSAGE_MAP()
// CMFC3DAppView 构造/析构
CMFC3DAppView::~CMFC3DAppView()
{
}
BOOL CMFC3DAppView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或样式
return CView::PreCreateWindow(cs);
}
// CMFC3DAppView 绘制
void CMFC3DAppView::OnDraw(CDC* pDC)
{
CMFC3DAppDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
for (const auto& cube : m_cubes)
{
TwoXiece(cube, pDC);
}
}
void CMFC3DAppView::TwoXiece(const std::array<float, 8 * 3>& vertices, CDC* pDC)
{
// 获取客户区域
CRect clientRect;
GetClientRect(&clientRect);
// 计算中心点
int centerX = clientRect.Width() / 2;
int centerY = clientRect.Height() / 2;
// 投影后的顶点坐标
CPoint projected[8];
double cosTheta = cos(m_b);
double sinTheta = sin(m_b);
for (int i = 0; i < 8; ++i)
{
double x = vertices[i * 3 + 0];
double y = vertices[i * 3 + 1];
double z = vertices[i * 3 + 2];
// 斜二测投影公式
double px = x + z * m_t * cosTheta;
double py = y + z * m_t * sinTheta;
// 转换为屏幕坐标(中心点偏移)
projected[i].x = centerX + (int)(px);
projected[i].y = centerY - (int)(py);
}
CPen pen(PS_SOLID, 1, RGB(0, 0, 0));
CPen* pOldPen = pDC->SelectObject(&pen);
// 立方体边的索引对
static int edges[12][2] = {
{0, 1}, {1, 2}, {2, 3}, {3, 0},
{4, 5}, {5, 6}, {6, 7}, {7, 4},
{0, 4}, {1, 5}, {2, 6}, {3, 7}
};
// 绘制立方体边
for (int i = 0; i < 12; ++i)
{
int a = edges[i][0];
int b = edges[i][1];
pDC->MoveTo(projected[a]);
pDC->LineTo(projected[b]);
}
pDC->SelectObject(pOldPen);
}
// CMFC3DAppView 打印
void CMFC3DAppView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
AFXPrintPreview(this);
#endif
}
BOOL CMFC3DAppView::OnPreparePrinting(CPrintInfo* pInfo)
{
// 默认准备
return DoPreparePrinting(pInfo);
}
void CMFC3DAppView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: 添加额外的打印前进行的初始化过程
}
void CMFC3DAppView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: 添加打印后进行的清理过程
}
void CMFC3DAppView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
ClientToScreen(&point);
OnContextMenu(this, point);
}
void CMFC3DAppView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}
void CMFC3DAppView::OnLButtonDown(UINT nFlags, CPoint point)
{
CView::OnLButtonDown(nFlags, point);
m_startPoint = point;
}
void CMFC3DAppView::OnLButtonUp(UINT nFlags, CPoint point)
{
CView::OnLButtonUp(nFlags, point);
m_endPoint = point;
// 固定大小的正方体
float size = 50.0f; // 固定大小
// 使用起点作为正方体的中心点
float centerX = m_startPoint.x;
float centerY = m_startPoint.y;
// 创建新的正方体顶点
std::array<float, 8 * 3> newCube = {
centerX - size, centerY - size, 0, centerX + size, centerY - size, 0,
centerX + size, centerY + size, 0, centerX - size, centerY + size, 0,
centerX - size, centerY - size, size * 2, centerX + size, centerY - size, size * 2,
centerX + size, centerY + size, size * 2, centerX - size, centerY + size, size * 2
};
// 添加新正方体到列表
m_cubes.push_back(newCube);
// 刷新视图
Invalidate();
}
#ifdef _DEBUG
void CMFC3DAppView::AssertValid() const
{
CView::AssertValid();
}
void CMFC3DAppView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMFC3DAppDoc* CMFC3DAppView::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMFC3DAppDoc)));
return (CMFC3DAppDoc*)m_pDocument;
}
#endif //_DEBUG
这些代码完成一个正方体的斜二侧投影吗?